From 0cf338bfd98a5ea269da5aeccb6426a532172ac3 Mon Sep 17 00:00:00 2001 From: gabe Date: Thu, 2 Aug 2012 16:09:56 -0700 Subject: [PATCH] initial commit --- CC | 64 + GPL | 339 + INSTALL | 15 + LICENSE | 8 + Makefile | 32 + SVMUtil.cpp | 377 + SVMUtil.h | 46 + bin/SVMUtil.o | Bin 0 -> 278216 bytes bin/parametersearch.o | Bin 0 -> 304232 bytes bin/stupidfilter | Bin 0 -> 293439 bytes bin/stupidfilter.o | Bin 0 -> 34456 bytes bin/svm.o | Bin 0 -> 115016 bytes classify.sh | 13 + data/c_rbf.mod | 12023 ++++++++++++++++ data/c_rbf.sf | 9 + parameterresult.h | 70 + parametersearch.cpp | 217 + parametersearch.h | 119 + stupidfilter.cpp | 1996 +++ thirdparty/boost/LICENSE_1_0.txt | 23 + thirdparty/boost/algorithm/minmax.hpp | 47 + thirdparty/boost/algorithm/minmax_element.hpp | 551 + thirdparty/boost/algorithm/string.hpp | 30 + .../boost/algorithm/string/case_conv.hpp | 176 + .../boost/algorithm/string/classification.hpp | 312 + thirdparty/boost/algorithm/string/compare.hpp | 199 + thirdparty/boost/algorithm/string/concept.hpp | 83 + thirdparty/boost/algorithm/string/config.hpp | 28 + .../boost/algorithm/string/constants.hpp | 36 + .../algorithm/string/detail/case_conv.hpp | 112 + .../string/detail/classification.hpp | 198 + .../algorithm/string/detail/find_format.hpp | 193 + .../string/detail/find_format_all.hpp | 263 + .../string/detail/find_format_store.hpp | 71 + .../algorithm/string/detail/find_iterator.hpp | 87 + .../boost/algorithm/string/detail/finder.hpp | 646 + .../algorithm/string/detail/finder_regex.hpp | 122 + .../algorithm/string/detail/formatter.hpp | 94 + .../string/detail/formatter_regex.hpp | 61 + .../algorithm/string/detail/predicate.hpp | 77 + .../string/detail/replace_storage.hpp | 159 + .../algorithm/string/detail/sequence.hpp | 200 + .../boost/algorithm/string/detail/trim.hpp | 95 + .../boost/algorithm/string/detail/util.hpp | 106 + thirdparty/boost/algorithm/string/erase.hpp | 844 ++ thirdparty/boost/algorithm/string/find.hpp | 334 + .../boost/algorithm/string/find_format.hpp | 269 + .../boost/algorithm/string/find_iterator.hpp | 387 + thirdparty/boost/algorithm/string/finder.hpp | 270 + .../boost/algorithm/string/formatter.hpp | 103 + .../boost/algorithm/string/iter_find.hpp | 190 + thirdparty/boost/algorithm/string/join.hpp | 145 + .../boost/algorithm/string/predicate.hpp | 475 + .../algorithm/string/predicate_facade.hpp | 42 + thirdparty/boost/algorithm/string/regex.hpp | 646 + .../algorithm/string/regex_find_format.hpp | 90 + thirdparty/boost/algorithm/string/replace.hpp | 928 ++ .../algorithm/string/sequence_traits.hpp | 193 + thirdparty/boost/algorithm/string/split.hpp | 163 + .../algorithm/string/std/list_traits.hpp | 85 + .../algorithm/string/std/rope_traits.hpp | 101 + .../algorithm/string/std/slist_traits.hpp | 85 + .../algorithm/string/std/string_traits.hpp | 52 + .../string/std_containers_traits.hpp | 26 + thirdparty/boost/algorithm/string/trim.hpp | 398 + .../boost/algorithm/string/yes_no_type.hpp | 33 + thirdparty/boost/algorithm/string_regex.hpp | 23 + thirdparty/boost/aligned_storage.hpp | 170 + thirdparty/boost/any.hpp | 235 + thirdparty/boost/archive/add_facet.hpp | 55 + .../boost/archive/archive_exception.hpp | 115 + thirdparty/boost/archive/array/iarchive.hpp | 132 + thirdparty/boost/archive/array/oarchive.hpp | 130 + thirdparty/boost/archive/basic_archive.hpp | 120 + .../boost/archive/basic_binary_iarchive.hpp | 125 + .../boost/archive/basic_binary_iprimitive.hpp | 192 + .../boost/archive/basic_binary_oarchive.hpp | 127 + .../boost/archive/basic_binary_oprimitive.hpp | 173 + .../archive/basic_streambuf_locale_saver.hpp | 61 + .../boost/archive/basic_text_iarchive.hpp | 94 + .../boost/archive/basic_text_iprimitive.hpp | 130 + .../boost/archive/basic_text_oarchive.hpp | 134 + .../boost/archive/basic_text_oprimitive.hpp | 167 + .../boost/archive/basic_xml_archive.hpp | 102 + .../boost/archive/basic_xml_iarchive.hpp | 118 + .../boost/archive/basic_xml_oarchive.hpp | 137 + thirdparty/boost/archive/binary_iarchive.hpp | 92 + .../boost/archive/binary_iarchive_impl.hpp | 87 + thirdparty/boost/archive/binary_oarchive.hpp | 54 + .../boost/archive/binary_oarchive_impl.hpp | 87 + thirdparty/boost/archive/binary_wiarchive.hpp | 92 + thirdparty/boost/archive/binary_woarchive.hpp | 60 + thirdparty/boost/archive/codecvt_null.hpp | 93 + .../boost/archive/detail/abi_prefix.hpp | 20 + .../boost/archive/detail/abi_suffix.hpp | 19 + .../detail/archive_pointer_iserializer.hpp | 92 + .../detail/archive_pointer_oserializer.hpp | 67 + .../archive/detail/auto_link_archive.hpp | 47 + .../archive/detail/auto_link_warchive.hpp | 47 + .../archive/detail/basic_archive_impl.hpp | 48 + .../boost/archive/detail/basic_config.hpp | 45 + .../boost/archive/detail/basic_iarchive.hpp | 108 + .../archive/detail/basic_iserializer.hpp | 87 + .../boost/archive/detail/basic_oarchive.hpp | 105 + .../archive/detail/basic_oserializer.hpp | 83 + .../detail/basic_pointer_iserializer.hpp | 64 + .../detail/basic_pointer_oserializer.hpp | 62 + .../boost/archive/detail/basic_serializer.hpp | 51 + .../archive/detail/basic_serializer_map.hpp | 69 + .../boost/archive/detail/common_iarchive.hpp | 77 + .../boost/archive/detail/common_oarchive.hpp | 78 + thirdparty/boost/archive/detail/decl.hpp | 79 + .../detail/dynamically_initialized.hpp | 45 + .../archive/detail/interface_iarchive.hpp | 80 + .../archive/detail/interface_oarchive.hpp | 85 + .../boost/archive/detail/iserializer.hpp | 597 + .../boost/archive/detail/oserializer.hpp | 572 + .../detail/polymorphic_iarchive_dispatch.hpp | 197 + .../detail/polymorphic_oarchive_dispatch.hpp | 185 + .../boost/archive/detail/register_archive.hpp | 47 + .../archive/detail/utf8_codecvt_facet.hpp | 21 + thirdparty/boost/archive/dinkumware.hpp | 224 + .../impl/archive_pointer_iserializer.ipp | 65 + .../impl/archive_pointer_oserializer.ipp | 63 + .../archive/impl/basic_binary_iarchive.ipp | 80 + .../archive/impl/basic_binary_iprimitive.ipp | 190 + .../archive/impl/basic_binary_oarchive.ipp | 46 + .../archive/impl/basic_binary_oprimitive.ipp | 160 + .../archive/impl/basic_text_iarchive.ipp | 80 + .../archive/impl/basic_text_iprimitive.ipp | 123 + .../archive/impl/basic_text_oarchive.ipp | 62 + .../archive/impl/basic_text_oprimitive.ipp | 103 + .../boost/archive/impl/basic_xml_grammar.hpp | 191 + .../boost/archive/impl/basic_xml_iarchive.ipp | 111 + .../boost/archive/impl/basic_xml_oarchive.ipp | 269 + .../boost/archive/impl/text_iarchive_impl.ipp | 127 + .../boost/archive/impl/text_oarchive_impl.ipp | 124 + .../archive/impl/text_wiarchive_impl.ipp | 118 + .../archive/impl/text_woarchive_impl.ipp | 85 + .../boost/archive/impl/xml_iarchive_impl.ipp | 199 + .../boost/archive/impl/xml_oarchive_impl.ipp | 117 + .../boost/archive/impl/xml_wiarchive_impl.ipp | 202 + .../boost/archive/impl/xml_woarchive_impl.ipp | 159 + .../archive/iterators/base64_exception.hpp | 68 + .../archive/iterators/base64_from_binary.hpp | 105 + .../archive/iterators/binary_from_base64.hpp | 120 + .../boost/archive/iterators/dataflow.hpp | 104 + .../archive/iterators/dataflow_exception.hpp | 80 + thirdparty/boost/archive/iterators/escape.hpp | 114 + .../boost/archive/iterators/head_iterator.hpp | 81 + .../archive/iterators/insert_linebreaks.hpp | 101 + .../archive/iterators/istream_iterator.hpp | 94 + .../boost/archive/iterators/mb_from_wchar.hpp | 136 + .../archive/iterators/ostream_iterator.hpp | 83 + .../archive/iterators/remove_whitespace.hpp | 169 + .../archive/iterators/transform_width.hpp | 168 + .../boost/archive/iterators/unescape.hpp | 94 + .../boost/archive/iterators/wchar_from_mb.hpp | 129 + .../boost/archive/iterators/xml_escape.hpp | 125 + .../boost/archive/iterators/xml_unescape.hpp | 118 + .../iterators/xml_unescape_exception.hpp | 49 + .../archive/polymorphic_binary_iarchive.hpp | 45 + .../archive/polymorphic_binary_oarchive.hpp | 43 + .../boost/archive/polymorphic_iarchive.hpp | 177 + .../boost/archive/polymorphic_oarchive.hpp | 154 + .../archive/polymorphic_text_iarchive.hpp | 45 + .../archive/polymorphic_text_oarchive.hpp | 39 + .../archive/polymorphic_text_wiarchive.hpp | 44 + .../archive/polymorphic_text_woarchive.hpp | 44 + .../archive/polymorphic_xml_iarchive.hpp | 45 + .../archive/polymorphic_xml_oarchive.hpp | 39 + .../archive/polymorphic_xml_wiarchive.hpp | 44 + .../archive/polymorphic_xml_woarchive.hpp | 44 + .../boost/archive/shared_ptr_helper.hpp | 149 + thirdparty/boost/archive/text_iarchive.hpp | 123 + thirdparty/boost/archive/text_oarchive.hpp | 101 + thirdparty/boost/archive/text_wiarchive.hpp | 122 + thirdparty/boost/archive/text_woarchive.hpp | 128 + thirdparty/boost/archive/tmpdir.hpp | 49 + thirdparty/boost/archive/wcslen.hpp | 56 + thirdparty/boost/archive/xml_iarchive.hpp | 132 + thirdparty/boost/archive/xml_oarchive.hpp | 114 + thirdparty/boost/archive/xml_wiarchive.hpp | 137 + thirdparty/boost/archive/xml_woarchive.hpp | 127 + thirdparty/boost/array.hpp | 321 + thirdparty/boost/asio.hpp | 73 + .../boost/asio/basic_datagram_socket.hpp | 805 ++ .../boost/asio/basic_deadline_timer.hpp | 383 + thirdparty/boost/asio/basic_io_object.hpp | 91 + thirdparty/boost/asio/basic_socket.hpp | 1051 ++ .../boost/asio/basic_socket_acceptor.hpp | 826 ++ .../boost/asio/basic_socket_iostream.hpp | 150 + .../boost/asio/basic_socket_streambuf.hpp | 286 + thirdparty/boost/asio/basic_stream_socket.hpp | 720 + thirdparty/boost/asio/basic_streambuf.hpp | 202 + thirdparty/boost/asio/buffer.hpp | 805 ++ .../boost/asio/buffered_read_stream.hpp | 416 + .../boost/asio/buffered_read_stream_fwd.hpp | 31 + thirdparty/boost/asio/buffered_stream.hpp | 252 + thirdparty/boost/asio/buffered_stream_fwd.hpp | 31 + .../boost/asio/buffered_write_stream.hpp | 370 + .../boost/asio/buffered_write_stream_fwd.hpp | 31 + .../boost/asio/completion_condition.hpp | 147 + .../boost/asio/datagram_socket_service.hpp | 325 + thirdparty/boost/asio/deadline_timer.hpp | 39 + .../boost/asio/deadline_timer_service.hpp | 170 + thirdparty/boost/asio/detail/bind_handler.hpp | 351 + .../boost/asio/detail/buffer_resize_guard.hpp | 72 + .../asio/detail/buffered_stream_storage.hpp | 129 + thirdparty/boost/asio/detail/call_stack.hpp | 92 + .../asio/detail/const_buffers_iterator.hpp | 153 + .../boost/asio/detail/consuming_buffers.hpp | 207 + .../asio/detail/deadline_timer_service.hpp | 201 + .../boost/asio/detail/dev_poll_reactor.hpp | 649 + .../asio/detail/dev_poll_reactor_fwd.hpp | 42 + .../boost/asio/detail/epoll_reactor.hpp | 656 + .../boost/asio/detail/epoll_reactor_fwd.hpp | 49 + thirdparty/boost/asio/detail/event.hpp | 52 + .../boost/asio/detail/fd_set_adapter.hpp | 43 + .../asio/detail/handler_alloc_helpers.hpp | 258 + .../asio/detail/handler_invoke_helpers.hpp | 47 + .../boost/asio/detail/handler_queue.hpp | 221 + thirdparty/boost/asio/detail/hash_map.hpp | 211 + thirdparty/boost/asio/detail/io_control.hpp | 139 + .../boost/asio/detail/kqueue_reactor.hpp | 654 + .../boost/asio/detail/kqueue_reactor_fwd.hpp | 43 + .../asio/detail/local_free_on_block_exit.hpp | 61 + thirdparty/boost/asio/detail/mutex.hpp | 52 + thirdparty/boost/asio/detail/noncopyable.hpp | 57 + thirdparty/boost/asio/detail/null_event.hpp | 73 + thirdparty/boost/asio/detail/null_mutex.hpp | 68 + .../boost/asio/detail/null_signal_blocker.hpp | 65 + thirdparty/boost/asio/detail/null_thread.hpp | 70 + thirdparty/boost/asio/detail/null_tss_ptr.hpp | 72 + .../boost/asio/detail/old_win_sdk_compat.hpp | 337 + .../asio/detail/pipe_select_interrupter.hpp | 116 + thirdparty/boost/asio/detail/pop_options.hpp | 88 + thirdparty/boost/asio/detail/posix_event.hpp | 106 + .../asio/detail/posix_fd_set_adapter.hpp | 79 + thirdparty/boost/asio/detail/posix_mutex.hpp | 109 + .../asio/detail/posix_signal_blocker.hpp | 92 + thirdparty/boost/asio/detail/posix_thread.hpp | 131 + .../boost/asio/detail/posix_tss_ptr.hpp | 90 + thirdparty/boost/asio/detail/push_options.hpp | 112 + .../asio/detail/reactive_socket_service.hpp | 1578 ++ .../boost/asio/detail/reactor_op_queue.hpp | 391 + .../boost/asio/detail/resolver_service.hpp | 359 + thirdparty/boost/asio/detail/scoped_lock.hpp | 93 + .../boost/asio/detail/select_interrupter.hpp | 43 + .../boost/asio/detail/select_reactor.hpp | 471 + .../boost/asio/detail/select_reactor_fwd.hpp | 33 + thirdparty/boost/asio/detail/service_base.hpp | 51 + thirdparty/boost/asio/detail/service_id.hpp | 39 + .../boost/asio/detail/service_registry.hpp | 202 + .../asio/detail/service_registry_fwd.hpp | 32 + .../boost/asio/detail/signal_blocker.hpp | 52 + thirdparty/boost/asio/detail/signal_init.hpp | 53 + .../boost/asio/detail/socket_holder.hpp | 97 + thirdparty/boost/asio/detail/socket_ops.hpp | 1879 +++ .../boost/asio/detail/socket_option.hpp | 311 + .../asio/detail/socket_select_interrupter.hpp | 189 + thirdparty/boost/asio/detail/socket_types.hpp | 201 + .../boost/asio/detail/strand_service.hpp | 527 + .../boost/asio/detail/task_io_service.hpp | 421 + .../boost/asio/detail/task_io_service_fwd.hpp | 33 + thirdparty/boost/asio/detail/thread.hpp | 60 + thirdparty/boost/asio/detail/throw_error.hpp | 46 + thirdparty/boost/asio/detail/timer_queue.hpp | 397 + .../boost/asio/detail/timer_queue_base.hpp | 64 + thirdparty/boost/asio/detail/tss_ptr.hpp | 67 + thirdparty/boost/asio/detail/win_event.hpp | 105 + .../boost/asio/detail/win_fd_set_adapter.hpp | 90 + .../boost/asio/detail/win_iocp_io_service.hpp | 707 + .../asio/detail/win_iocp_io_service_fwd.hpp | 52 + .../asio/detail/win_iocp_socket_service.hpp | 2093 +++ thirdparty/boost/asio/detail/win_mutex.hpp | 151 + .../boost/asio/detail/win_signal_blocker.hpp | 69 + thirdparty/boost/asio/detail/win_thread.hpp | 127 + thirdparty/boost/asio/detail/win_tss_ptr.hpp | 97 + thirdparty/boost/asio/detail/wince_thread.hpp | 126 + thirdparty/boost/asio/detail/winsock_init.hpp | 122 + .../boost/asio/detail/wrapped_handler.hpp | 195 + thirdparty/boost/asio/error.hpp | 439 + thirdparty/boost/asio/handler_alloc_hook.hpp | 90 + thirdparty/boost/asio/handler_invoke_hook.hpp | 71 + thirdparty/boost/asio/impl/io_service.ipp | 226 + thirdparty/boost/asio/impl/read.ipp | 316 + thirdparty/boost/asio/impl/read_until.ipp | 758 + thirdparty/boost/asio/impl/write.ipp | 281 + thirdparty/boost/asio/io_service.hpp | 521 + thirdparty/boost/asio/ip/address.hpp | 279 + thirdparty/boost/asio/ip/address_v4.hpp | 290 + thirdparty/boost/asio/ip/address_v6.hpp | 408 + thirdparty/boost/asio/ip/basic_endpoint.hpp | 370 + thirdparty/boost/asio/ip/basic_resolver.hpp | 247 + .../boost/asio/ip/basic_resolver_entry.hpp | 97 + .../boost/asio/ip/basic_resolver_iterator.hpp | 156 + .../boost/asio/ip/basic_resolver_query.hpp | 151 + .../boost/asio/ip/detail/socket_option.hpp | 580 + thirdparty/boost/asio/ip/host_name.hpp | 64 + thirdparty/boost/asio/ip/multicast.hpp | 183 + .../boost/asio/ip/resolver_query_base.hpp | 109 + thirdparty/boost/asio/ip/resolver_service.hpp | 142 + thirdparty/boost/asio/ip/tcp.hpp | 160 + thirdparty/boost/asio/ip/udp.hpp | 118 + thirdparty/boost/asio/ip/unicast.hpp | 72 + thirdparty/boost/asio/ip/v6_only.hpp | 70 + thirdparty/boost/asio/is_read_buffered.hpp | 64 + thirdparty/boost/asio/is_write_buffered.hpp | 64 + thirdparty/boost/asio/placeholders.hpp | 109 + thirdparty/boost/asio/read.hpp | 518 + thirdparty/boost/asio/read_until.hpp | 454 + .../boost/asio/socket_acceptor_service.hpp | 227 + thirdparty/boost/asio/socket_base.hpp | 517 + thirdparty/boost/asio/ssl.hpp | 26 + thirdparty/boost/asio/ssl/basic_context.hpp | 436 + thirdparty/boost/asio/ssl/context.hpp | 37 + thirdparty/boost/asio/ssl/context_base.hpp | 166 + thirdparty/boost/asio/ssl/context_service.hpp | 177 + .../ssl/detail/openssl_context_service.hpp | 381 + .../boost/asio/ssl/detail/openssl_init.hpp | 145 + .../asio/ssl/detail/openssl_operation.hpp | 521 + .../ssl/detail/openssl_stream_service.hpp | 533 + .../boost/asio/ssl/detail/openssl_types.hpp | 31 + thirdparty/boost/asio/ssl/stream.hpp | 505 + thirdparty/boost/asio/ssl/stream_base.hpp | 62 + thirdparty/boost/asio/ssl/stream_service.hpp | 188 + thirdparty/boost/asio/strand.hpp | 188 + .../boost/asio/stream_socket_service.hpp | 288 + thirdparty/boost/asio/streambuf.hpp | 33 + thirdparty/boost/asio/time_traits.hpp | 80 + thirdparty/boost/asio/version.hpp | 23 + thirdparty/boost/asio/write.hpp | 517 + thirdparty/boost/assert.hpp | 50 + thirdparty/boost/assign.hpp | 24 + .../boost/assign/assignment_exception.hpp | 43 + thirdparty/boost/assign/list_inserter.hpp | 404 + thirdparty/boost/assign/list_of.hpp | 593 + thirdparty/boost/assign/ptr_list_inserter.hpp | 164 + thirdparty/boost/assign/ptr_list_of.hpp | 195 + thirdparty/boost/assign/ptr_map_inserter.hpp | 103 + thirdparty/boost/assign/std.hpp | 27 + thirdparty/boost/assign/std/deque.hpp | 38 + thirdparty/boost/assign/std/list.hpp | 38 + thirdparty/boost/assign/std/map.hpp | 45 + thirdparty/boost/assign/std/queue.hpp | 45 + thirdparty/boost/assign/std/set.hpp | 44 + thirdparty/boost/assign/std/slist.hpp | 45 + thirdparty/boost/assign/std/stack.hpp | 37 + thirdparty/boost/assign/std/vector.hpp | 37 + thirdparty/boost/bimap.hpp | 19 + thirdparty/boost/bimap/bimap.hpp | 430 + .../associative_container_adaptor.hpp | 287 + .../container_adaptor/container_adaptor.hpp | 291 + .../detail/comparison_adaptor.hpp | 101 + .../container_adaptor/detail/functor_bag.hpp | 100 + .../detail/identity_converters.hpp | 191 + .../detail/key_extractor.hpp | 45 + .../detail/non_unique_container_helper.hpp | 62 + .../bimap/container_adaptor/list_adaptor.hpp | 249 + .../container_adaptor/list_map_adaptor.hpp | 282 + .../bimap/container_adaptor/map_adaptor.hpp | 131 + .../container_adaptor/multimap_adaptor.hpp | 109 + .../container_adaptor/multiset_adaptor.hpp | 103 + .../ordered_associative_container_adaptor.hpp | 312 + .../sequence_container_adaptor.hpp | 355 + .../bimap/container_adaptor/set_adaptor.hpp | 100 + .../support/iterator_facade_converters.hpp | 77 + ...nordered_associative_container_adaptor.hpp | 293 + .../unordered_map_adaptor.hpp | 132 + .../unordered_multimap_adaptor.hpp | 110 + .../unordered_multiset_adaptor.hpp | 102 + .../unordered_set_adaptor.hpp | 98 + .../container_adaptor/vector_adaptor.hpp | 142 + .../container_adaptor/vector_map_adaptor.hpp | 103 + thirdparty/boost/bimap/detail/bimap_core.hpp | 520 + .../boost/bimap/detail/concept_tags.hpp | 97 + .../boost/bimap/detail/debug/static_error.hpp | 36 + .../bimap/detail/generate_index_binder.hpp | 125 + .../bimap/detail/generate_relation_binder.hpp | 88 + .../bimap/detail/generate_view_binder.hpp | 58 + .../boost/bimap/detail/is_set_type_of.hpp | 66 + .../detail/manage_additional_parameters.hpp | 243 + .../boost/bimap/detail/manage_bimap_key.hpp | 84 + .../boost/bimap/detail/map_view_base.hpp | 552 + .../boost/bimap/detail/map_view_iterator.hpp | 200 + .../boost/bimap/detail/modifier_adaptor.hpp | 89 + .../bimap/detail/non_unique_views_helper.hpp | 71 + .../boost/bimap/detail/set_view_base.hpp | 330 + .../boost/bimap/detail/set_view_iterator.hpp | 193 + .../bimap/detail/test/check_metadata.hpp | 113 + .../bimap/detail/user_interface_config.hpp | 24 + thirdparty/boost/bimap/list_of.hpp | 181 + thirdparty/boost/bimap/multiset_of.hpp | 205 + .../boost/bimap/property_map/set_support.hpp | 55 + .../property_map/unordered_set_support.hpp | 55 + .../bimap/relation/detail/access_builder.hpp | 170 + .../detail/metadata_access_builder.hpp | 103 + .../boost/bimap/relation/detail/mutant.hpp | 83 + .../relation/detail/static_access_builder.hpp | 105 + .../detail/to_mutable_relation_functor.hpp | 102 + thirdparty/boost/bimap/relation/member_at.hpp | 72 + .../boost/bimap/relation/mutant_relation.hpp | 430 + .../boost/bimap/relation/pair_layout.hpp | 72 + .../boost/bimap/relation/structured_pair.hpp | 508 + .../bimap/relation/support/data_extractor.hpp | 109 + .../boost/bimap/relation/support/get.hpp | 140 + .../relation/support/get_pair_functor.hpp | 85 + .../relation/support/is_tag_of_member_at.hpp | 181 + .../relation/support/member_with_tag.hpp | 180 + .../bimap/relation/support/opposite_tag.hpp | 61 + .../boost/bimap/relation/support/pair_by.hpp | 120 + .../bimap/relation/support/pair_type_by.hpp | 62 + .../bimap/relation/support/value_type_of.hpp | 91 + .../boost/bimap/relation/symmetrical_base.hpp | 97 + thirdparty/boost/bimap/set_of.hpp | 206 + .../boost/bimap/support/data_type_by.hpp | 73 + .../boost/bimap/support/iterator_type_by.hpp | 228 + .../boost/bimap/support/key_type_by.hpp | 64 + thirdparty/boost/bimap/support/lambda.hpp | 46 + thirdparty/boost/bimap/support/map_by.hpp | 132 + .../boost/bimap/support/map_type_by.hpp | 65 + .../boost/bimap/support/value_type_by.hpp | 65 + .../tags/support/apply_to_value_type.hpp | 70 + .../bimap/tags/support/default_tagged.hpp | 73 + .../boost/bimap/tags/support/is_tagged.hpp | 64 + .../bimap/tags/support/overwrite_tagged.hpp | 73 + .../boost/bimap/tags/support/tag_of.hpp | 75 + .../bimap/tags/support/value_type_of.hpp | 74 + thirdparty/boost/bimap/tags/tagged.hpp | 107 + .../boost/bimap/unconstrained_set_of.hpp | 150 + .../boost/bimap/unordered_multiset_of.hpp | 233 + thirdparty/boost/bimap/unordered_set_of.hpp | 230 + thirdparty/boost/bimap/vector_of.hpp | 186 + .../boost/bimap/views/list_map_view.hpp | 182 + .../boost/bimap/views/list_set_view.hpp | 108 + thirdparty/boost/bimap/views/map_view.hpp | 156 + .../boost/bimap/views/multimap_view.hpp | 123 + .../boost/bimap/views/multiset_view.hpp | 110 + thirdparty/boost/bimap/views/set_view.hpp | 106 + .../bimap/views/unconstrained_map_view.hpp | 44 + .../bimap/views/unconstrained_set_view.hpp | 42 + .../boost/bimap/views/unordered_map_view.hpp | 174 + .../bimap/views/unordered_multimap_view.hpp | 136 + .../bimap/views/unordered_multiset_view.hpp | 83 + .../boost/bimap/views/unordered_set_view.hpp | 78 + .../boost/bimap/views/vector_map_view.hpp | 306 + .../boost/bimap/views/vector_set_view.hpp | 279 + thirdparty/boost/bind.hpp | 1689 +++ thirdparty/boost/bind/apply.hpp | 74 + thirdparty/boost/bind/arg.hpp | 62 + thirdparty/boost/bind/bind_cc.hpp | 117 + thirdparty/boost/bind/bind_mf_cc.hpp | 227 + thirdparty/boost/bind/bind_template.hpp | 345 + thirdparty/boost/bind/make_adaptable.hpp | 187 + thirdparty/boost/bind/mem_fn_cc.hpp | 103 + thirdparty/boost/bind/mem_fn_template.hpp | 1020 ++ thirdparty/boost/bind/mem_fn_vw.hpp | 130 + thirdparty/boost/bind/placeholders.hpp | 68 + thirdparty/boost/bind/protect.hpp | 144 + thirdparty/boost/bind/storage.hpp | 475 + thirdparty/boost/blank.hpp | 100 + thirdparty/boost/blank_fwd.hpp | 22 + thirdparty/boost/call_traits.hpp | 24 + thirdparty/boost/cast.hpp | 107 + thirdparty/boost/cerrno.hpp | 331 + thirdparty/boost/checked_delete.hpp | 69 + thirdparty/boost/circular_buffer.hpp | 74 + thirdparty/boost/circular_buffer/base.hpp | 2617 ++++ thirdparty/boost/circular_buffer/debug.hpp | 227 + thirdparty/boost/circular_buffer/details.hpp | 519 + .../boost/circular_buffer/space_optimized.hpp | 1422 ++ thirdparty/boost/circular_buffer_fwd.hpp | 43 + .../boost/compatibility/cpp_c_headers/cassert | 10 + .../boost/compatibility/cpp_c_headers/cctype | 26 + .../boost/compatibility/cpp_c_headers/cerrno | 10 + .../boost/compatibility/cpp_c_headers/cfloat | 10 + .../boost/compatibility/cpp_c_headers/climits | 10 + .../boost/compatibility/cpp_c_headers/clocale | 16 + .../boost/compatibility/cpp_c_headers/cmath | 35 + .../boost/compatibility/cpp_c_headers/csetjmp | 15 + .../boost/compatibility/cpp_c_headers/csignal | 16 + .../boost/compatibility/cpp_c_headers/cstdarg | 14 + .../boost/compatibility/cpp_c_headers/cstddef | 15 + .../boost/compatibility/cpp_c_headers/cstdio | 57 + .../boost/compatibility/cpp_c_headers/cstdlib | 43 + .../boost/compatibility/cpp_c_headers/cstring | 36 + .../boost/compatibility/cpp_c_headers/ctime | 26 + .../boost/compatibility/cpp_c_headers/cwchar | 156 + .../boost/compatibility/cpp_c_headers/cwctype | 39 + thirdparty/boost/compressed_pair.hpp | 24 + thirdparty/boost/concept/assert.hpp | 46 + thirdparty/boost/concept/detail/borland.hpp | 29 + .../boost/concept/detail/concept_def.hpp | 51 + .../boost/concept/detail/concept_undef.hpp | 5 + thirdparty/boost/concept/detail/general.hpp | 66 + .../boost/concept/detail/has_constraints.hpp | 48 + thirdparty/boost/concept/detail/msvc.hpp | 92 + thirdparty/boost/concept/requires.hpp | 78 + thirdparty/boost/concept/usage.hpp | 43 + thirdparty/boost/concept_archetype.hpp | 669 + thirdparty/boost/concept_check.hpp | 988 ++ thirdparty/boost/concept_check/borland.hpp | 25 + thirdparty/boost/concept_check/general.hpp | 82 + .../boost/concept_check/has_constraints.hpp | 31 + thirdparty/boost/concept_check/msvc.hpp | 90 + thirdparty/boost/config.hpp | 70 + .../boost/config/abi/borland_prefix.hpp | 27 + .../boost/config/abi/borland_suffix.hpp | 12 + thirdparty/boost/config/abi/msvc_prefix.hpp | 8 + thirdparty/boost/config/abi/msvc_suffix.hpp | 8 + thirdparty/boost/config/abi_prefix.hpp | 25 + thirdparty/boost/config/abi_suffix.hpp | 26 + thirdparty/boost/config/auto_link.hpp | 368 + thirdparty/boost/config/compiler/borland.hpp | 209 + thirdparty/boost/config/compiler/comeau.hpp | 59 + .../boost/config/compiler/common_edg.hpp | 62 + .../boost/config/compiler/compaq_cxx.hpp | 19 + .../boost/config/compiler/digitalmars.hpp | 67 + thirdparty/boost/config/compiler/gcc.hpp | 149 + thirdparty/boost/config/compiler/gcc_xml.hpp | 30 + .../boost/config/compiler/greenhills.hpp | 28 + thirdparty/boost/config/compiler/hp_acc.hpp | 95 + thirdparty/boost/config/compiler/intel.hpp | 162 + thirdparty/boost/config/compiler/kai.hpp | 35 + .../boost/config/compiler/metrowerks.hpp | 111 + thirdparty/boost/config/compiler/mpw.hpp | 51 + thirdparty/boost/config/compiler/pgi.hpp | 25 + .../boost/config/compiler/sgi_mipspro.hpp | 28 + .../boost/config/compiler/sunpro_cc.hpp | 98 + thirdparty/boost/config/compiler/vacpp.hpp | 60 + thirdparty/boost/config/compiler/visualc.hpp | 191 + thirdparty/boost/config/no_tr1/complex.hpp | 28 + thirdparty/boost/config/no_tr1/functional.hpp | 28 + thirdparty/boost/config/no_tr1/memory.hpp | 28 + thirdparty/boost/config/no_tr1/utility.hpp | 28 + thirdparty/boost/config/platform/aix.hpp | 33 + thirdparty/boost/config/platform/amigaos.hpp | 15 + thirdparty/boost/config/platform/beos.hpp | 26 + thirdparty/boost/config/platform/bsd.hpp | 73 + thirdparty/boost/config/platform/cygwin.hpp | 51 + thirdparty/boost/config/platform/hpux.hpp | 84 + thirdparty/boost/config/platform/irix.hpp | 31 + thirdparty/boost/config/platform/linux.hpp | 98 + thirdparty/boost/config/platform/macos.hpp | 78 + thirdparty/boost/config/platform/qnxnto.hpp | 31 + thirdparty/boost/config/platform/solaris.hpp | 21 + thirdparty/boost/config/platform/win32.hpp | 58 + thirdparty/boost/config/posix_features.hpp | 95 + thirdparty/boost/config/requires_threads.hpp | 92 + .../boost/config/select_compiler_config.hpp | 115 + .../boost/config/select_platform_config.hpp | 90 + .../boost/config/select_stdlib_config.hpp | 68 + thirdparty/boost/config/stdlib/dinkumware.hpp | 106 + thirdparty/boost/config/stdlib/libcomo.hpp | 46 + thirdparty/boost/config/stdlib/libstdcpp3.hpp | 73 + thirdparty/boost/config/stdlib/modena.hpp | 30 + thirdparty/boost/config/stdlib/msl.hpp | 59 + thirdparty/boost/config/stdlib/roguewave.hpp | 153 + thirdparty/boost/config/stdlib/sgi.hpp | 111 + thirdparty/boost/config/stdlib/stlport.hpp | 201 + thirdparty/boost/config/stdlib/vacpp.hpp | 18 + thirdparty/boost/config/suffix.hpp | 566 + thirdparty/boost/config/user.hpp | 124 + thirdparty/boost/crc.hpp | 1106 ++ thirdparty/boost/cregex.hpp | 39 + thirdparty/boost/cstdint.hpp | 446 + thirdparty/boost/cstdlib.hpp | 41 + thirdparty/boost/current_function.hpp | 67 + thirdparty/boost/date_time.hpp | 17 + .../boost/date_time/adjust_functors.hpp | 178 + .../boost/date_time/c_local_time_adjustor.hpp | 64 + thirdparty/boost/date_time/c_time.hpp | 91 + .../boost/date_time/compiler_config.hpp | 149 + .../boost/date_time/constrained_value.hpp | 98 + thirdparty/boost/date_time/date.hpp | 197 + .../boost/date_time/date_clock_device.hpp | 77 + thirdparty/boost/date_time/date_defs.hpp | 26 + thirdparty/boost/date_time/date_duration.hpp | 147 + .../boost/date_time/date_duration_types.hpp | 269 + thirdparty/boost/date_time/date_facet.hpp | 775 + .../boost/date_time/date_format_simple.hpp | 159 + .../boost/date_time/date_formatting.hpp | 127 + .../date_time/date_formatting_limited.hpp | 121 + .../date_time/date_formatting_locales.hpp | 233 + .../date_time/date_generator_formatter.hpp | 263 + .../boost/date_time/date_generator_parser.hpp | 329 + .../boost/date_time/date_generators.hpp | 509 + thirdparty/boost/date_time/date_iterator.hpp | 101 + thirdparty/boost/date_time/date_names_put.hpp | 320 + thirdparty/boost/date_time/date_parsing.hpp | 299 + thirdparty/boost/date_time/dst_rules.hpp | 391 + .../date_time/dst_transition_generators.hpp | 75 + .../boost/date_time/filetime_functions.hpp | 78 + .../boost/date_time/format_date_parser.hpp | 731 + .../boost/date_time/gregorian/conversion.hpp | 73 + .../boost/date_time/gregorian/formatters.hpp | 162 + .../gregorian/formatters_limited.hpp | 81 + .../date_time/gregorian/greg_calendar.hpp | 47 + .../boost/date_time/gregorian/greg_date.hpp | 135 + .../boost/date_time/gregorian/greg_day.hpp | 57 + .../date_time/gregorian/greg_day_of_year.hpp | 38 + .../date_time/gregorian/greg_duration.hpp | 38 + .../gregorian/greg_duration_types.hpp | 34 + .../boost/date_time/gregorian/greg_facet.hpp | 351 + .../boost/date_time/gregorian/greg_month.hpp | 105 + .../date_time/gregorian/greg_serialize.hpp | 489 + .../date_time/gregorian/greg_weekday.hpp | 66 + .../boost/date_time/gregorian/greg_year.hpp | 53 + .../boost/date_time/gregorian/greg_ymd.hpp | 33 + .../boost/date_time/gregorian/gregorian.hpp | 38 + .../date_time/gregorian/gregorian_io.hpp | 777 + .../date_time/gregorian/gregorian_types.hpp | 109 + .../boost/date_time/gregorian/parsers.hpp | 91 + .../boost/date_time/gregorian_calendar.hpp | 70 + .../boost/date_time/gregorian_calendar.ipp | 219 + thirdparty/boost/date_time/int_adapter.hpp | 507 + thirdparty/boost/date_time/iso_format.hpp | 303 + .../boost/date_time/local_time/conversion.hpp | 35 + .../date_time/local_time/custom_time_zone.hpp | 169 + .../local_time/date_duration_operators.hpp | 115 + .../local_time/dst_transition_day_rules.hpp | 77 + .../date_time/local_time/local_date_time.hpp | 525 + .../boost/date_time/local_time/local_time.hpp | 24 + .../date_time/local_time/local_time_io.hpp | 118 + .../date_time/local_time/local_time_types.hpp | 52 + .../date_time/local_time/posix_time_zone.hpp | 443 + .../date_time/local_time/tz_database.hpp | 32 + .../boost/date_time/local_time_adjustor.hpp | 213 + .../boost/date_time/local_timezone_defs.hpp | 193 + thirdparty/boost/date_time/locale_config.hpp | 31 + .../boost/date_time/microsec_time_clock.hpp | 205 + .../boost/date_time/parse_format_base.hpp | 29 + thirdparty/boost/date_time/period.hpp | 377 + .../boost/date_time/period_formatter.hpp | 196 + thirdparty/boost/date_time/period_parser.hpp | 196 + .../boost/date_time/posix_time/conversion.hpp | 93 + .../posix_time/date_duration_operators.hpp | 114 + .../boost/date_time/posix_time/posix_time.hpp | 39 + .../posix_time/posix_time_config.hpp | 178 + .../posix_time/posix_time_duration.hpp | 82 + .../date_time/posix_time/posix_time_io.hpp | 246 + .../posix_time/posix_time_legacy_io.hpp | 153 + .../posix_time/posix_time_system.hpp | 68 + .../date_time/posix_time/posix_time_types.hpp | 55 + .../boost/date_time/posix_time/ptime.hpp | 65 + .../date_time/posix_time/time_formatters.hpp | 289 + .../posix_time/time_formatters_limited.hpp | 211 + .../date_time/posix_time/time_parsers.hpp | 44 + .../date_time/posix_time/time_period.hpp | 29 + .../date_time/posix_time/time_serialize.hpp | 200 + thirdparty/boost/date_time/special_defs.hpp | 25 + .../date_time/special_values_formatter.hpp | 96 + .../boost/date_time/special_values_parser.hpp | 159 + thirdparty/boost/date_time/string_convert.hpp | 33 + .../boost/date_time/string_parse_tree.hpp | 278 + .../boost/date_time/strings_from_facet.hpp | 123 + thirdparty/boost/date_time/testfrmwk.hpp | 66 + thirdparty/boost/date_time/time.hpp | 190 + thirdparty/boost/date_time/time_clock.hpp | 83 + thirdparty/boost/date_time/time_defs.hpp | 33 + thirdparty/boost/date_time/time_duration.hpp | 281 + thirdparty/boost/date_time/time_facet.hpp | 1263 ++ .../date_time/time_formatting_streams.hpp | 119 + thirdparty/boost/date_time/time_iterator.hpp | 52 + thirdparty/boost/date_time/time_parsing.hpp | 321 + .../date_time/time_resolution_traits.hpp | 140 + .../boost/date_time/time_system_counted.hpp | 254 + .../boost/date_time/time_system_split.hpp | 213 + thirdparty/boost/date_time/time_zone_base.hpp | 99 + .../boost/date_time/time_zone_names.hpp | 98 + thirdparty/boost/date_time/tz_db_base.hpp | 376 + thirdparty/boost/date_time/wrapping_int.hpp | 163 + thirdparty/boost/date_time/year_month_day.hpp | 45 + thirdparty/boost/detail/algorithm.hpp | 222 + .../boost/detail/allocator_utilities.hpp | 193 + thirdparty/boost/detail/atomic_count.hpp | 124 + thirdparty/boost/detail/atomic_count_gcc.hpp | 68 + .../boost/detail/atomic_count_gcc_x86.hpp | 84 + .../boost/detail/atomic_count_pthreads.hpp | 96 + .../boost/detail/atomic_count_solaris.hpp | 59 + thirdparty/boost/detail/atomic_count_sync.hpp | 57 + .../boost/detail/atomic_count_win32.hpp | 63 + thirdparty/boost/detail/bad_weak_ptr.hpp | 59 + thirdparty/boost/detail/binary_search.hpp | 216 + thirdparty/boost/detail/call_traits.hpp | 164 + thirdparty/boost/detail/catch_exceptions.hpp | 146 + thirdparty/boost/detail/compressed_pair.hpp | 443 + thirdparty/boost/detail/dynamic_bitset.hpp | 176 + thirdparty/boost/detail/endian.hpp | 73 + .../boost/detail/has_default_constructor.hpp | 29 + thirdparty/boost/detail/identifier.hpp | 89 + thirdparty/boost/detail/indirect_traits.hpp | 487 + thirdparty/boost/detail/interlocked.hpp | 130 + .../boost/detail/is_function_ref_tester.hpp | 135 + thirdparty/boost/detail/is_incrementable.hpp | 124 + thirdparty/boost/detail/is_xxx.hpp | 61 + thirdparty/boost/detail/iterator.hpp | 494 + thirdparty/boost/detail/lcast_precision.hpp | 184 + thirdparty/boost/detail/lightweight_mutex.hpp | 42 + thirdparty/boost/detail/lightweight_test.hpp | 75 + thirdparty/boost/detail/limits.hpp | 449 + thirdparty/boost/detail/lwm_nop.hpp | 37 + thirdparty/boost/detail/lwm_pthreads.hpp | 86 + thirdparty/boost/detail/lwm_win32_cs.hpp | 104 + .../boost/detail/named_template_params.hpp | 177 + .../boost/detail/no_exceptions_support.hpp | 87 + thirdparty/boost/detail/none_t.hpp | 28 + thirdparty/boost/detail/numeric_traits.hpp | 191 + thirdparty/boost/detail/ob_call_traits.hpp | 168 + .../boost/detail/ob_compressed_pair.hpp | 510 + thirdparty/boost/detail/quick_allocator.hpp | 198 + thirdparty/boost/detail/reference_content.hpp | 141 + thirdparty/boost/detail/select_type.hpp | 36 + thirdparty/boost/detail/shared_array_nmt.hpp | 151 + thirdparty/boost/detail/shared_count.hpp | 375 + thirdparty/boost/detail/shared_ptr_nmt.hpp | 182 + thirdparty/boost/detail/sp_counted_base.hpp | 81 + .../boost/detail/sp_counted_base_acc_ia64.hpp | 150 + .../boost/detail/sp_counted_base_cw_ppc.hpp | 170 + .../boost/detail/sp_counted_base_cw_x86.hpp | 158 + .../boost/detail/sp_counted_base_gcc_ia64.hpp | 157 + .../boost/detail/sp_counted_base_gcc_ppc.hpp | 181 + .../detail/sp_counted_base_gcc_sparc.hpp | 166 + .../boost/detail/sp_counted_base_gcc_x86.hpp | 173 + .../boost/detail/sp_counted_base_nt.hpp | 107 + .../boost/detail/sp_counted_base_pt.hpp | 135 + .../boost/detail/sp_counted_base_solaris.hpp | 113 + .../boost/detail/sp_counted_base_sync.hpp | 151 + .../boost/detail/sp_counted_base_w32.hpp | 130 + thirdparty/boost/detail/sp_counted_impl.hpp | 231 + thirdparty/boost/detail/sp_typeinfo.hpp | 83 + thirdparty/boost/detail/templated_streams.hpp | 74 + .../boost/detail/utf8_codecvt_facet.hpp | 197 + thirdparty/boost/detail/workaround.hpp | 202 + thirdparty/boost/dynamic_bitset.hpp | 21 + thirdparty/boost/dynamic_bitset/config.hpp | 82 + .../boost/dynamic_bitset/dynamic_bitset.hpp | 1731 +++ thirdparty/boost/dynamic_bitset_fwd.hpp | 29 + thirdparty/boost/dynamic_property_map.hpp | 370 + thirdparty/boost/enable_shared_from_this.hpp | 73 + thirdparty/boost/filesystem.hpp | 20 + thirdparty/boost/filesystem/config.hpp | 113 + thirdparty/boost/filesystem/convenience.hpp | 286 + thirdparty/boost/filesystem/exception.hpp | 9 + thirdparty/boost/filesystem/fstream.hpp | 584 + thirdparty/boost/filesystem/operations.hpp | 1119 ++ thirdparty/boost/filesystem/path.hpp | 1432 ++ thirdparty/boost/foreach.hpp | 893 ++ thirdparty/boost/format.hpp | 59 + thirdparty/boost/format/alt_sstream.hpp | 176 + thirdparty/boost/format/alt_sstream_impl.hpp | 303 + .../format/detail/compat_workarounds.hpp | 86 + .../boost/format/detail/config_macros.hpp | 97 + .../format/detail/msvc_disambiguater.hpp | 56 + .../boost/format/detail/unset_macros.hpp | 34 + .../format/detail/workarounds_gcc-2_95.hpp | 162 + .../format/detail/workarounds_stlport.hpp | 42 + thirdparty/boost/format/exceptions.hpp | 103 + thirdparty/boost/format/feed_args.hpp | 277 + thirdparty/boost/format/format_class.hpp | 143 + thirdparty/boost/format/format_fwd.hpp | 49 + .../boost/format/format_implementation.hpp | 288 + thirdparty/boost/format/free_funcs.hpp | 70 + thirdparty/boost/format/group.hpp | 684 + thirdparty/boost/format/internals.hpp | 201 + thirdparty/boost/format/internals_fwd.hpp | 60 + thirdparty/boost/format/parsing.hpp | 503 + thirdparty/boost/function.hpp | 66 + .../function/detail/function_iterate.hpp | 16 + .../function/detail/gen_maybe_include.pl | 37 + .../boost/function/detail/maybe_include.hpp | 267 + thirdparty/boost/function/detail/prologue.hpp | 25 + thirdparty/boost/function/function0.hpp | 12 + thirdparty/boost/function/function1.hpp | 12 + thirdparty/boost/function/function10.hpp | 12 + thirdparty/boost/function/function2.hpp | 12 + thirdparty/boost/function/function3.hpp | 12 + thirdparty/boost/function/function4.hpp | 12 + thirdparty/boost/function/function5.hpp | 12 + thirdparty/boost/function/function6.hpp | 12 + thirdparty/boost/function/function7.hpp | 12 + thirdparty/boost/function/function8.hpp | 12 + thirdparty/boost/function/function9.hpp | 12 + thirdparty/boost/function/function_base.hpp | 762 + .../boost/function/function_template.hpp | 969 ++ thirdparty/boost/function/gen_function_N.pl | 26 + thirdparty/boost/function_equal.hpp | 28 + thirdparty/boost/function_output_iterator.hpp | 56 + .../boost/function_types/components.hpp | 431 + .../boost/function_types/config/cc_names.hpp | 31 + .../boost/function_types/config/compiler.hpp | 116 + .../boost/function_types/config/config.hpp | 59 + .../function_types/detail/class_transform.hpp | 62 + .../function_types/detail/classifier.hpp | 82 + .../detail/classifier_impl/arity10_0.hpp | 55 + .../detail/classifier_impl/arity10_1.hpp | 52 + .../detail/classifier_impl/arity20_0.hpp | 53 + .../detail/classifier_impl/arity20_1.hpp | 53 + .../detail/classifier_impl/arity30_0.hpp | 53 + .../detail/classifier_impl/arity30_1.hpp | 53 + .../detail/classifier_impl/arity40_0.hpp | 53 + .../detail/classifier_impl/arity40_1.hpp | 53 + .../detail/classifier_impl/arity50_0.hpp | 53 + .../detail/classifier_impl/arity50_1.hpp | 52 + .../detail/classifier_impl/master.hpp | 33 + .../detail/components_as_mpl_sequence.hpp | 138 + .../detail/components_impl/arity10_0.hpp | 132 + .../detail/components_impl/arity10_1.hpp | 122 + .../detail/components_impl/arity20_0.hpp | 123 + .../detail/components_impl/arity20_1.hpp | 123 + .../detail/components_impl/arity30_0.hpp | 123 + .../detail/components_impl/arity30_1.hpp | 123 + .../detail/components_impl/arity40_0.hpp | 123 + .../detail/components_impl/arity40_1.hpp | 123 + .../detail/components_impl/arity50_0.hpp | 123 + .../detail/components_impl/arity50_1.hpp | 123 + .../detail/components_impl/master.hpp | 61 + .../boost/function_types/detail/cv_traits.hpp | 134 + .../detail/encoding/aliases_def.hpp | 16 + .../detail/encoding/aliases_undef.hpp | 16 + .../function_types/detail/encoding/def.hpp | 51 + .../function_types/detail/encoding/undef.hpp | 38 + .../function_types/detail/pp_arity_loop.hpp | 149 + .../detail/pp_cc_loop/master.hpp | 136 + .../detail/pp_cc_loop/preprocessed.hpp | 120 + .../boost/function_types/detail/pp_loop.hpp | 80 + .../detail/pp_retag_default_cc/master.hpp | 103 + .../pp_retag_default_cc/preprocessed.hpp | 59 + .../function_types/detail/pp_tags/cc_tag.hpp | 17 + .../function_types/detail/pp_tags/master.hpp | 126 + .../detail/pp_tags/preprocessed.hpp | 77 + .../detail/pp_variate_loop/master.hpp | 152 + .../detail/pp_variate_loop/preprocessed.hpp | 283 + .../detail/retag_default_cc.hpp | 23 + .../function_types/detail/synthesize.hpp | 79 + .../detail/synthesize_impl/arity10_0.hpp | 334 + .../detail/synthesize_impl/arity10_1.hpp | 326 + .../detail/synthesize_impl/arity20_0.hpp | 517 + .../detail/synthesize_impl/arity20_1.hpp | 527 + .../detail/synthesize_impl/arity30_0.hpp | 717 + .../detail/synthesize_impl/arity30_1.hpp | 727 + .../detail/synthesize_impl/arity40_0.hpp | 917 ++ .../detail/synthesize_impl/arity40_1.hpp | 927 ++ .../detail/synthesize_impl/arity50_0.hpp | 1117 ++ .../detail/synthesize_impl/arity50_1.hpp | 1127 ++ .../detail/synthesize_impl/master.hpp | 87 + .../function_types/detail/to_sequence.hpp | 47 + .../boost/function_types/function_arity.hpp | 38 + .../boost/function_types/function_pointer.hpp | 32 + .../function_types/function_reference.hpp | 32 + .../boost/function_types/function_type.hpp | 29 + .../function_types/is_callable_builtin.hpp | 35 + .../boost/function_types/is_function.hpp | 34 + .../function_types/is_function_pointer.hpp | 34 + .../function_types/is_function_reference.hpp | 34 + .../is_member_function_pointer.hpp | 33 + .../is_member_object_pointer.hpp | 34 + .../function_types/is_member_pointer.hpp | 34 + .../is_nonmember_callable_builtin.hpp | 35 + .../member_function_pointer.hpp | 33 + .../function_types/member_object_pointer.hpp | 34 + .../boost/function_types/parameter_types.hpp | 55 + .../boost/function_types/property_tags.hpp | 149 + .../boost/function_types/result_type.hpp | 50 + thirdparty/boost/functional.hpp | 548 + .../boost/functional/detail/container_fwd.hpp | 95 + .../functional/detail/float_functions.hpp | 154 + .../boost/functional/detail/hash_float.hpp | 196 + thirdparty/boost/functional/hash.hpp | 10 + thirdparty/boost/functional/hash/deque.hpp | 27 + thirdparty/boost/functional/hash/hash.hpp | 693 + thirdparty/boost/functional/hash/list.hpp | 27 + thirdparty/boost/functional/hash/map.hpp | 27 + thirdparty/boost/functional/hash/pair.hpp | 27 + thirdparty/boost/functional/hash/set.hpp | 27 + thirdparty/boost/functional/hash/vector.hpp | 27 + thirdparty/boost/functional/hash_fwd.hpp | 40 + thirdparty/boost/fusion/adapted.hpp | 17 + thirdparty/boost/fusion/adapted/array.hpp | 22 + .../fusion/adapted/array/array_iterator.hpp | 107 + .../fusion/adapted/array/detail/at_impl.hpp | 45 + .../adapted/array/detail/begin_impl.hpp | 40 + .../adapted/array/detail/category_of_impl.hpp | 35 + .../fusion/adapted/array/detail/end_impl.hpp | 40 + .../adapted/array/detail/is_sequence_impl.hpp | 31 + .../adapted/array/detail/is_view_impl.hpp | 32 + .../fusion/adapted/array/detail/size_impl.hpp | 29 + .../adapted/array/detail/value_at_impl.hpp | 32 + .../boost/fusion/adapted/array/tag_of.hpp | 39 + .../boost/fusion/adapted/boost_tuple.hpp | 20 + .../boost_tuple/boost_tuple_iterator.hpp | 149 + .../adapted/boost_tuple/detail/at_impl.hpp | 50 + .../adapted/boost_tuple/detail/begin_impl.hpp | 39 + .../boost_tuple/detail/category_of_impl.hpp | 32 + .../adapted/boost_tuple/detail/end_impl.hpp | 54 + .../boost_tuple/detail/is_sequence_impl.hpp | 30 + .../boost_tuple/detail/is_view_impl.hpp | 30 + .../adapted/boost_tuple/detail/size_impl.hpp | 31 + .../boost_tuple/detail/value_at_impl.hpp | 30 + .../fusion/adapted/boost_tuple/tag_of.hpp | 63 + thirdparty/boost/fusion/adapted/mpl.hpp | 21 + .../fusion/adapted/mpl/detail/at_impl.hpp | 40 + .../fusion/adapted/mpl/detail/begin_impl.hpp | 45 + .../adapted/mpl/detail/category_of_impl.hpp | 54 + .../fusion/adapted/mpl/detail/empty_impl.hpp | 28 + .../fusion/adapted/mpl/detail/end_impl.hpp | 45 + .../adapted/mpl/detail/has_key_impl.hpp | 31 + .../adapted/mpl/detail/is_sequence_impl.hpp | 31 + .../adapted/mpl/detail/is_view_impl.hpp | 32 + .../fusion/adapted/mpl/detail/size_impl.hpp | 31 + .../adapted/mpl/detail/value_at_impl.hpp | 31 + .../boost/fusion/adapted/mpl/mpl_iterator.hpp | 113 + thirdparty/boost/fusion/adapted/std_pair.hpp | 70 + .../adapted/std_pair/detail/at_impl.hpp | 71 + .../adapted/std_pair/detail/begin_impl.hpp | 40 + .../std_pair/detail/category_of_impl.hpp | 35 + .../adapted/std_pair/detail/end_impl.hpp | 40 + .../std_pair/detail/is_sequence_impl.hpp | 31 + .../adapted/std_pair/detail/is_view_impl.hpp | 32 + .../adapted/std_pair/detail/size_impl.hpp | 31 + .../adapted/std_pair/detail/value_at_impl.hpp | 43 + .../adapted/std_pair/std_pair_iterator.hpp | 127 + .../boost/fusion/adapted/std_pair/tag_of.hpp | 29 + thirdparty/boost/fusion/adapted/struct.hpp | 28 + .../adapted/struct/adapt_assoc_struct.hpp | 94 + .../fusion/adapted/struct/adapt_struct.hpp | 75 + .../fusion/adapted/struct/detail/at_impl.hpp | 63 + .../adapted/struct/detail/at_key_impl.hpp | 54 + .../adapted/struct/detail/begin_impl.hpp | 40 + .../struct/detail/category_of_impl.hpp | 35 + .../fusion/adapted/struct/detail/end_impl.hpp | 48 + .../adapted/struct/detail/has_key_impl.hpp | 40 + .../struct/detail/is_sequence_impl.hpp | 31 + .../adapted/struct/detail/is_view_impl.hpp | 32 + .../adapted/struct/detail/size_impl.hpp | 37 + .../adapted/struct/detail/value_at_impl.hpp | 47 + .../struct/detail/value_at_key_impl.hpp | 39 + .../boost/fusion/adapted/struct/extension.hpp | 68 + .../fusion/adapted/struct/struct_iterator.hpp | 103 + thirdparty/boost/fusion/algorithm.hpp | 14 + .../boost/fusion/algorithm/iteration.hpp | 14 + .../fusion/algorithm/iteration/accumulate.hpp | 40 + .../algorithm/iteration/detail/fold.hpp | 278 + .../algorithm/iteration/detail/for_each.hpp | 130 + .../algorithm/iteration/ext_/for_each_s.hpp | 91 + .../boost/fusion/algorithm/iteration/fold.hpp | 48 + .../fusion/algorithm/iteration/for_each.hpp | 43 + thirdparty/boost/fusion/algorithm/query.hpp | 18 + .../boost/fusion/algorithm/query/all.hpp | 34 + .../boost/fusion/algorithm/query/any.hpp | 35 + .../boost/fusion/algorithm/query/count.hpp | 35 + .../boost/fusion/algorithm/query/count_if.hpp | 35 + .../fusion/algorithm/query/detail/all.hpp | 127 + .../fusion/algorithm/query/detail/any.hpp | 130 + .../algorithm/query/detail/assoc_find.hpp | 35 + .../fusion/algorithm/query/detail/count.hpp | 68 + .../algorithm/query/detail/count_if.hpp | 170 + .../fusion/algorithm/query/detail/find_if.hpp | 252 + .../fusion/algorithm/query/ext_/find_if_s.hpp | 222 + .../boost/fusion/algorithm/query/find.hpp | 75 + .../boost/fusion/algorithm/query/find_if.hpp | 69 + .../boost/fusion/algorithm/query/none.hpp | 33 + .../boost/fusion/algorithm/transformation.hpp | 28 + .../fusion/algorithm/transformation/clear.hpp | 32 + .../transformation/detail/replace.hpp | 73 + .../transformation/detail/replace_if.hpp | 73 + .../fusion/algorithm/transformation/erase.hpp | 108 + .../algorithm/transformation/erase_key.hpp | 37 + .../algorithm/transformation/filter.hpp | 34 + .../algorithm/transformation/filter_if.hpp | 32 + .../algorithm/transformation/insert.hpp | 63 + .../algorithm/transformation/insert_range.hpp | 55 + .../fusion/algorithm/transformation/join.hpp | 33 + .../algorithm/transformation/pop_back.hpp | 43 + .../algorithm/transformation/pop_front.hpp | 43 + .../algorithm/transformation/push_back.hpp | 39 + .../algorithm/transformation/push_front.hpp | 39 + .../algorithm/transformation/remove.hpp | 35 + .../algorithm/transformation/remove_if.hpp | 35 + .../algorithm/transformation/replace.hpp | 35 + .../algorithm/transformation/replace_if.hpp | 37 + .../algorithm/transformation/reverse.hpp | 32 + .../algorithm/transformation/transform.hpp | 51 + .../fusion/algorithm/transformation/zip.hpp | 86 + thirdparty/boost/fusion/container.hpp | 17 + thirdparty/boost/fusion/container/deque.hpp | 15 + .../container/deque/back_extended_deque.hpp | 37 + .../boost/fusion/container/deque/convert.hpp | 48 + .../boost/fusion/container/deque/deque.hpp | 93 + .../fusion/container/deque/deque_fwd.hpp | 24 + .../fusion/container/deque/deque_iterator.hpp | 106 + .../container/deque/detail/as_deque.hpp | 102 + .../fusion/container/deque/detail/at_impl.hpp | 59 + .../container/deque/detail/begin_impl.hpp | 46 + .../container/deque/detail/convert_impl.hpp | 45 + .../deque/detail/deque_forward_ctor.hpp | 31 + .../deque/detail/deque_initial_size.hpp | 33 + .../deque/detail/deque_keyed_values.hpp | 75 + .../deque/detail/deque_keyed_values_call.hpp | 38 + .../container/deque/detail/end_impl.hpp | 46 + .../container/deque/detail/keyed_element.hpp | 111 + .../container/deque/detail/value_at_impl.hpp | 43 + .../container/deque/front_extended_deque.hpp | 39 + .../boost/fusion/container/deque/limits.hpp | 15 + .../boost/fusion/container/ext_/tree.hpp | 130 + .../boost/fusion/container/generation.hpp | 20 + .../fusion/container/generation/cons_tie.hpp | 43 + .../fusion/container/generation/deque_tie.hpp | 79 + .../fusion/container/generation/ignore.hpp | 32 + .../fusion/container/generation/list_tie.hpp | 79 + .../fusion/container/generation/make_cons.hpp | 43 + .../container/generation/make_deque.hpp | 98 + .../fusion/container/generation/make_list.hpp | 91 + .../fusion/container/generation/make_map.hpp | 106 + .../fusion/container/generation/make_set.hpp | 93 + .../container/generation/make_vector.hpp | 91 + .../fusion/container/generation/map_tie.hpp | 110 + .../fusion/container/generation/pair_tie.hpp | 43 + .../container/generation/vector_tie.hpp | 78 + thirdparty/boost/fusion/container/list.hpp | 17 + .../boost/fusion/container/list/cons.hpp | 143 + .../fusion/container/list/cons_iterator.hpp | 85 + .../boost/fusion/container/list/convert.hpp | 56 + .../fusion/container/list/detail/at_impl.hpp | 79 + .../container/list/detail/begin_impl.hpp | 49 + .../container/list/detail/build_cons.hpp | 57 + .../container/list/detail/convert_impl.hpp | 51 + .../container/list/detail/deref_impl.hpp | 52 + .../container/list/detail/empty_impl.hpp | 37 + .../fusion/container/list/detail/end_impl.hpp | 51 + .../container/list/detail/equal_to_impl.hpp | 39 + .../list/detail/list_forward_ctor.hpp | 47 + .../container/list/detail/list_to_cons.hpp | 49 + .../list/detail/list_to_cons_call.hpp | 43 + .../container/list/detail/next_impl.hpp | 59 + .../container/list/detail/value_at_impl.hpp | 42 + .../container/list/detail/value_of_impl.hpp | 36 + .../boost/fusion/container/list/limits.hpp | 19 + .../boost/fusion/container/list/list.hpp | 68 + .../boost/fusion/container/list/list_fwd.hpp | 24 + thirdparty/boost/fusion/container/map.hpp | 15 + .../boost/fusion/container/map/convert.hpp | 47 + .../fusion/container/map/detail/as_map.hpp | 101 + .../container/map/detail/at_key_impl.hpp | 49 + .../container/map/detail/begin_impl.hpp | 56 + .../container/map/detail/convert_impl.hpp | 45 + .../fusion/container/map/detail/end_impl.hpp | 53 + .../container/map/detail/lookup_key.hpp | 99 + .../container/map/detail/map_forward_ctor.hpp | 38 + .../container/map/detail/map_lookup.hpp | 128 + .../map/detail/value_at_key_impl.hpp | 33 + .../boost/fusion/container/map/limits.hpp | 25 + thirdparty/boost/fusion/container/map/map.hpp | 71 + .../boost/fusion/container/map/map_fwd.hpp | 24 + thirdparty/boost/fusion/container/set.hpp | 15 + .../boost/fusion/container/set/convert.hpp | 47 + .../fusion/container/set/detail/as_set.hpp | 101 + .../container/set/detail/at_key_impl.hpp | 49 + .../container/set/detail/begin_impl.hpp | 56 + .../container/set/detail/convert_impl.hpp | 45 + .../fusion/container/set/detail/end_impl.hpp | 53 + .../container/set/detail/lookup_key.hpp | 93 + .../container/set/detail/set_forward_ctor.hpp | 39 + .../container/set/detail/set_lookup.hpp | 128 + .../set/detail/value_at_key_impl.hpp | 35 + .../boost/fusion/container/set/limits.hpp | 25 + thirdparty/boost/fusion/container/set/set.hpp | 71 + .../boost/fusion/container/set/set_fwd.hpp | 24 + thirdparty/boost/fusion/container/vector.hpp | 21 + .../boost/fusion/container/vector/convert.hpp | 47 + .../container/vector/detail/advance_impl.hpp | 42 + .../container/vector/detail/as_vector.hpp | 101 + .../container/vector/detail/at_impl.hpp | 49 + .../container/vector/detail/begin_impl.hpp | 39 + .../container/vector/detail/convert_impl.hpp | 45 + .../container/vector/detail/deref_impl.hpp | 53 + .../container/vector/detail/distance_impl.hpp | 41 + .../container/vector/detail/end_impl.hpp | 40 + .../container/vector/detail/equal_to_impl.hpp | 39 + .../container/vector/detail/next_impl.hpp | 43 + .../container/vector/detail/prior_impl.hpp | 43 + .../container/vector/detail/value_at_impl.hpp | 33 + .../container/vector/detail/value_of_impl.hpp | 37 + .../vector/detail/vector_forward_ctor.hpp | 39 + .../container/vector/detail/vector_n.hpp | 150 + .../vector/detail/vector_n_chooser.hpp | 99 + .../boost/fusion/container/vector/limits.hpp | 19 + .../boost/fusion/container/vector/vector.hpp | 151 + .../fusion/container/vector/vector10.hpp | 66 + .../fusion/container/vector/vector20.hpp | 50 + .../fusion/container/vector/vector30.hpp | 50 + .../fusion/container/vector/vector40.hpp | 50 + .../fusion/container/vector/vector50.hpp | 50 + .../fusion/container/vector/vector_fwd.hpp | 25 + .../container/vector/vector_iterator.hpp | 46 + thirdparty/boost/fusion/functional.hpp | 17 + .../boost/fusion/functional/adapter.hpp | 18 + .../functional/adapter/detail/access.hpp | 41 + .../adapter/detail/pow2_explode.hpp | 118 + .../functional/adapter/detail/pt_def.hpp | 71 + .../functional/adapter/detail/pt_undef.hpp | 23 + .../boost/fusion/functional/adapter/fused.hpp | 85 + .../adapter/fused_function_object.hpp | 90 + .../functional/adapter/fused_procedure.hpp | 70 + .../fusion/functional/adapter/limits.hpp | 39 + .../functional/adapter/unfused_generic.hpp | 175 + .../adapter/unfused_lvalue_args.hpp | 136 + .../adapter/unfused_rvalue_args.hpp | 137 + .../functional/adapter/unfused_typed.hpp | 155 + .../boost/fusion/functional/generation.hpp | 19 + .../generation/detail/gen_make_adapter.hpp | 44 + .../functional/generation/make_fused.hpp | 18 + .../generation/make_fused_function_object.hpp | 18 + .../generation/make_fused_procedure.hpp | 18 + .../generation/make_unfused_generic.hpp | 18 + .../generation/make_unfused_lvalue_args.hpp | 18 + .../generation/make_unfused_rvalue_args.hpp | 18 + .../boost/fusion/functional/invocation.hpp | 16 + .../functional/invocation/detail/that_ptr.hpp | 87 + .../fusion/functional/invocation/invoke.hpp | 306 + .../invocation/invoke_function_object.hpp | 177 + .../invocation/invoke_procedure.hpp | 171 + .../fusion/functional/invocation/limits.hpp | 23 + .../boost/fusion/include/accumulate.hpp | 12 + .../boost/fusion/include/adapt_struct.hpp | 12 + thirdparty/boost/fusion/include/adapted.hpp | 12 + thirdparty/boost/fusion/include/adapter.hpp | 12 + thirdparty/boost/fusion/include/advance.hpp | 12 + thirdparty/boost/fusion/include/algorithm.hpp | 12 + thirdparty/boost/fusion/include/all.hpp | 12 + thirdparty/boost/fusion/include/any.hpp | 12 + thirdparty/boost/fusion/include/array.hpp | 12 + thirdparty/boost/fusion/include/as_deque.hpp | 12 + thirdparty/boost/fusion/include/as_list.hpp | 12 + thirdparty/boost/fusion/include/as_map.hpp | 12 + thirdparty/boost/fusion/include/as_set.hpp | 12 + thirdparty/boost/fusion/include/as_vector.hpp | 12 + thirdparty/boost/fusion/include/at.hpp | 12 + thirdparty/boost/fusion/include/at_key.hpp | 12 + thirdparty/boost/fusion/include/back.hpp | 12 + thirdparty/boost/fusion/include/begin.hpp | 12 + .../boost/fusion/include/boost_tuple.hpp | 12 + .../boost/fusion/include/category_of.hpp | 12 + thirdparty/boost/fusion/include/clear.hpp | 12 + .../boost/fusion/include/comparison.hpp | 12 + thirdparty/boost/fusion/include/cons.hpp | 12 + thirdparty/boost/fusion/include/cons_tie.hpp | 12 + thirdparty/boost/fusion/include/container.hpp | 12 + thirdparty/boost/fusion/include/convert.hpp | 12 + thirdparty/boost/fusion/include/count.hpp | 12 + thirdparty/boost/fusion/include/count_if.hpp | 12 + thirdparty/boost/fusion/include/deduce.hpp | 12 + .../boost/fusion/include/deduce_sequence.hpp | 12 + thirdparty/boost/fusion/include/deque.hpp | 12 + thirdparty/boost/fusion/include/deque_fwd.hpp | 12 + thirdparty/boost/fusion/include/deque_tie.hpp | 13 + thirdparty/boost/fusion/include/deref.hpp | 12 + thirdparty/boost/fusion/include/distance.hpp | 12 + thirdparty/boost/fusion/include/empty.hpp | 12 + thirdparty/boost/fusion/include/end.hpp | 12 + thirdparty/boost/fusion/include/equal_to.hpp | 13 + thirdparty/boost/fusion/include/erase.hpp | 12 + thirdparty/boost/fusion/include/erase_key.hpp | 12 + thirdparty/boost/fusion/include/filter.hpp | 12 + thirdparty/boost/fusion/include/filter_if.hpp | 12 + .../boost/fusion/include/filter_view.hpp | 12 + thirdparty/boost/fusion/include/find.hpp | 12 + thirdparty/boost/fusion/include/find_if.hpp | 12 + thirdparty/boost/fusion/include/fold.hpp | 12 + thirdparty/boost/fusion/include/for_each.hpp | 12 + thirdparty/boost/fusion/include/front.hpp | 12 + .../boost/fusion/include/functional.hpp | 12 + thirdparty/boost/fusion/include/fused.hpp | 12 + .../fusion/include/fused_function_object.hpp | 12 + .../boost/fusion/include/fused_procedure.hpp | 12 + .../boost/fusion/include/generation.hpp | 13 + thirdparty/boost/fusion/include/greater.hpp | 12 + .../boost/fusion/include/greater_equal.hpp | 12 + thirdparty/boost/fusion/include/has_key.hpp | 12 + thirdparty/boost/fusion/include/ignore.hpp | 13 + thirdparty/boost/fusion/include/in.hpp | 12 + thirdparty/boost/fusion/include/insert.hpp | 12 + .../boost/fusion/include/insert_range.hpp | 12 + thirdparty/boost/fusion/include/intrinsic.hpp | 12 + .../boost/fusion/include/invocation.hpp | 12 + thirdparty/boost/fusion/include/invoke.hpp | 12 + .../fusion/include/invoke_function_object.hpp | 12 + .../boost/fusion/include/invoke_procedure.hpp | 12 + thirdparty/boost/fusion/include/io.hpp | 12 + .../boost/fusion/include/is_iterator.hpp | 12 + .../boost/fusion/include/is_sequence.hpp | 12 + thirdparty/boost/fusion/include/is_view.hpp | 12 + thirdparty/boost/fusion/include/iteration.hpp | 12 + thirdparty/boost/fusion/include/iterator.hpp | 12 + .../boost/fusion/include/iterator_base.hpp | 12 + .../boost/fusion/include/iterator_facade.hpp | 12 + .../boost/fusion/include/iterator_range.hpp | 12 + thirdparty/boost/fusion/include/join.hpp | 12 + .../boost/fusion/include/joint_view.hpp | 12 + thirdparty/boost/fusion/include/less.hpp | 12 + .../boost/fusion/include/less_equal.hpp | 12 + thirdparty/boost/fusion/include/list.hpp | 12 + thirdparty/boost/fusion/include/list_fwd.hpp | 12 + thirdparty/boost/fusion/include/list_tie.hpp | 13 + thirdparty/boost/fusion/include/make_cons.hpp | 12 + .../boost/fusion/include/make_deque.hpp | 12 + .../boost/fusion/include/make_fused.hpp | 12 + .../include/make_fused_function_object.hpp | 12 + .../fusion/include/make_fused_procedure.hpp | 12 + thirdparty/boost/fusion/include/make_list.hpp | 12 + thirdparty/boost/fusion/include/make_map.hpp | 12 + thirdparty/boost/fusion/include/make_set.hpp | 12 + .../boost/fusion/include/make_tuple.hpp | 12 + .../fusion/include/make_unfused_generic.hpp | 12 + .../include/make_unfused_lvalue_args.hpp | 12 + .../include/make_unfused_rvalue_args.hpp | 12 + .../boost/fusion/include/make_vector.hpp | 12 + thirdparty/boost/fusion/include/map.hpp | 12 + thirdparty/boost/fusion/include/map_fwd.hpp | 12 + thirdparty/boost/fusion/include/map_tie.hpp | 12 + thirdparty/boost/fusion/include/mpl.hpp | 13 + thirdparty/boost/fusion/include/next.hpp | 12 + thirdparty/boost/fusion/include/none.hpp | 12 + .../boost/fusion/include/not_equal_to.hpp | 13 + thirdparty/boost/fusion/include/out.hpp | 12 + thirdparty/boost/fusion/include/pair.hpp | 12 + thirdparty/boost/fusion/include/pair_tie.hpp | 12 + thirdparty/boost/fusion/include/pop_back.hpp | 12 + thirdparty/boost/fusion/include/pop_front.hpp | 12 + thirdparty/boost/fusion/include/prior.hpp | 12 + thirdparty/boost/fusion/include/push_back.hpp | 12 + .../boost/fusion/include/push_front.hpp | 12 + thirdparty/boost/fusion/include/query.hpp | 12 + thirdparty/boost/fusion/include/remove.hpp | 12 + thirdparty/boost/fusion/include/remove_if.hpp | 12 + .../boost/fusion/include/repetetive_view.hpp | 12 + thirdparty/boost/fusion/include/replace.hpp | 12 + .../boost/fusion/include/replace_if.hpp | 12 + thirdparty/boost/fusion/include/reverse.hpp | 12 + .../boost/fusion/include/reverse_view.hpp | 12 + thirdparty/boost/fusion/include/sequence.hpp | 12 + .../boost/fusion/include/sequence_base.hpp | 12 + .../boost/fusion/include/sequence_facade.hpp | 12 + thirdparty/boost/fusion/include/set.hpp | 12 + thirdparty/boost/fusion/include/set_fwd.hpp | 12 + .../boost/fusion/include/single_view.hpp | 12 + thirdparty/boost/fusion/include/size.hpp | 12 + thirdparty/boost/fusion/include/std_pair.hpp | 12 + thirdparty/boost/fusion/include/struct.hpp | 12 + thirdparty/boost/fusion/include/support.hpp | 12 + thirdparty/boost/fusion/include/swap.hpp | 12 + thirdparty/boost/fusion/include/tag_of.hpp | 12 + .../boost/fusion/include/tag_of_fwd.hpp | 12 + thirdparty/boost/fusion/include/transform.hpp | 12 + .../boost/fusion/include/transform_view.hpp | 12 + .../boost/fusion/include/transformation.hpp | 12 + thirdparty/boost/fusion/include/tuple.hpp | 12 + thirdparty/boost/fusion/include/tuple_fwd.hpp | 12 + thirdparty/boost/fusion/include/tuple_tie.hpp | 12 + .../boost/fusion/include/unfused_generic.hpp | 12 + .../fusion/include/unfused_lvalue_args.hpp | 12 + .../fusion/include/unfused_rvalue_args.hpp | 12 + .../boost/fusion/include/unfused_typed.hpp | 12 + thirdparty/boost/fusion/include/unused.hpp | 12 + thirdparty/boost/fusion/include/value_at.hpp | 12 + .../boost/fusion/include/value_at_key.hpp | 12 + thirdparty/boost/fusion/include/value_of.hpp | 12 + thirdparty/boost/fusion/include/vector.hpp | 12 + thirdparty/boost/fusion/include/vector10.hpp | 12 + thirdparty/boost/fusion/include/vector20.hpp | 12 + thirdparty/boost/fusion/include/vector30.hpp | 12 + thirdparty/boost/fusion/include/vector40.hpp | 12 + thirdparty/boost/fusion/include/vector50.hpp | 12 + .../boost/fusion/include/vector_fwd.hpp | 12 + .../boost/fusion/include/vector_tie.hpp | 12 + thirdparty/boost/fusion/include/view.hpp | 12 + thirdparty/boost/fusion/include/void.hpp | 12 + thirdparty/boost/fusion/include/zip.hpp | 12 + thirdparty/boost/fusion/include/zip_view.hpp | 12 + thirdparty/boost/fusion/iterator.hpp | 20 + thirdparty/boost/fusion/iterator/advance.hpp | 92 + thirdparty/boost/fusion/iterator/deref.hpp | 72 + .../iterator/detail/adapt_deref_traits.hpp | 34 + .../iterator/detail/adapt_value_traits.hpp | 28 + .../boost/fusion/iterator/detail/advance.hpp | 102 + .../boost/fusion/iterator/detail/distance.hpp | 64 + thirdparty/boost/fusion/iterator/distance.hpp | 81 + thirdparty/boost/fusion/iterator/equal_to.hpp | 93 + .../boost/fusion/iterator/iterator_facade.hpp | 50 + thirdparty/boost/fusion/iterator/mpl.hpp | 13 + .../fusion/iterator/mpl/convert_iterator.hpp | 58 + .../fusion/iterator/mpl/fusion_iterator.hpp | 57 + thirdparty/boost/fusion/iterator/next.hpp | 63 + thirdparty/boost/fusion/iterator/prior.hpp | 63 + thirdparty/boost/fusion/iterator/value_of.hpp | 57 + thirdparty/boost/fusion/mpl.hpp | 32 + thirdparty/boost/fusion/mpl/at.hpp | 33 + thirdparty/boost/fusion/mpl/back.hpp | 32 + thirdparty/boost/fusion/mpl/begin.hpp | 31 + thirdparty/boost/fusion/mpl/clear.hpp | 33 + thirdparty/boost/fusion/mpl/detail/clear.hpp | 46 + thirdparty/boost/fusion/mpl/empty.hpp | 26 + thirdparty/boost/fusion/mpl/end.hpp | 31 + thirdparty/boost/fusion/mpl/erase.hpp | 39 + thirdparty/boost/fusion/mpl/erase_key.hpp | 39 + thirdparty/boost/fusion/mpl/front.hpp | 28 + thirdparty/boost/fusion/mpl/has_key.hpp | 27 + thirdparty/boost/fusion/mpl/insert.hpp | 39 + thirdparty/boost/fusion/mpl/insert_range.hpp | 39 + thirdparty/boost/fusion/mpl/pop_back.hpp | 39 + thirdparty/boost/fusion/mpl/pop_front.hpp | 39 + thirdparty/boost/fusion/mpl/push_back.hpp | 39 + thirdparty/boost/fusion/mpl/push_front.hpp | 39 + thirdparty/boost/fusion/mpl/size.hpp | 26 + thirdparty/boost/fusion/sequence.hpp | 16 + .../boost/fusion/sequence/comparison.hpp | 17 + .../comparison/detail/enable_comparison.hpp | 38 + .../sequence/comparison/detail/equal_to.hpp | 60 + .../sequence/comparison/detail/greater.hpp | 50 + .../comparison/detail/greater_equal.hpp | 49 + .../sequence/comparison/detail/less.hpp | 50 + .../sequence/comparison/detail/less_equal.hpp | 49 + .../comparison/detail/not_equal_to.hpp | 60 + .../fusion/sequence/comparison/equal_to.hpp | 46 + .../fusion/sequence/comparison/greater.hpp | 52 + .../sequence/comparison/greater_equal.hpp | 52 + .../boost/fusion/sequence/comparison/less.hpp | 43 + .../fusion/sequence/comparison/less_equal.hpp | 80 + .../sequence/comparison/not_equal_to.hpp | 55 + thirdparty/boost/fusion/sequence/convert.hpp | 48 + .../boost/fusion/sequence/intrinsic.hpp | 22 + .../boost/fusion/sequence/intrinsic/at.hpp | 106 + .../fusion/sequence/intrinsic/at_key.hpp | 77 + .../boost/fusion/sequence/intrinsic/back.hpp | 42 + .../boost/fusion/sequence/intrinsic/begin.hpp | 74 + .../boost/fusion/sequence/intrinsic/empty.hpp | 60 + .../boost/fusion/sequence/intrinsic/end.hpp | 74 + .../sequence/intrinsic/ext_/segments.hpp | 56 + .../fusion/sequence/intrinsic/ext_/size_s.hpp | 57 + .../boost/fusion/sequence/intrinsic/front.hpp | 41 + .../fusion/sequence/intrinsic/has_key.hpp | 72 + .../boost/fusion/sequence/intrinsic/size.hpp | 74 + .../boost/fusion/sequence/intrinsic/swap.hpp | 59 + .../fusion/sequence/intrinsic/value_at.hpp | 67 + .../sequence/intrinsic/value_at_key.hpp | 59 + thirdparty/boost/fusion/sequence/io.hpp | 13 + .../boost/fusion/sequence/io/detail/in.hpp | 85 + .../boost/fusion/sequence/io/detail/manip.hpp | 316 + .../boost/fusion/sequence/io/detail/out.hpp | 85 + thirdparty/boost/fusion/sequence/io/in.hpp | 42 + thirdparty/boost/fusion/sequence/io/out.hpp | 44 + .../boost/fusion/sequence/sequence_facade.hpp | 27 + thirdparty/boost/fusion/support.hpp | 22 + .../boost/fusion/support/category_of.hpp | 112 + thirdparty/boost/fusion/support/deduce.hpp | 105 + .../boost/fusion/support/deduce_sequence.hpp | 44 + .../boost/fusion/support/detail/access.hpp | 55 + .../support/detail/as_fusion_element.hpp | 47 + .../fusion/support/detail/category_of.hpp | 19 + .../fusion/support/detail/is_mpl_sequence.hpp | 27 + .../boost/fusion/support/detail/is_view.hpp | 19 + .../support/detail/mpl_iterator_category.hpp | 66 + .../fusion/support/detail/unknown_key.hpp | 16 + .../fusion/support/ext_/is_segmented.hpp | 48 + .../boost/fusion/support/is_iterator.hpp | 20 + .../boost/fusion/support/is_sequence.hpp | 65 + thirdparty/boost/fusion/support/is_view.hpp | 63 + .../boost/fusion/support/iterator_base.hpp | 31 + thirdparty/boost/fusion/support/pair.hpp | 102 + .../boost/fusion/support/sequence_base.hpp | 45 + thirdparty/boost/fusion/support/tag_of.hpp | 110 + .../boost/fusion/support/tag_of_fwd.hpp | 20 + thirdparty/boost/fusion/support/unused.hpp | 62 + thirdparty/boost/fusion/support/void.hpp | 15 + thirdparty/boost/fusion/tuple.hpp | 15 + .../tuple/detail/tuple_forward_ctor.hpp | 39 + thirdparty/boost/fusion/tuple/make_tuple.hpp | 56 + thirdparty/boost/fusion/tuple/tuple.hpp | 72 + thirdparty/boost/fusion/tuple/tuple_fwd.hpp | 24 + thirdparty/boost/fusion/tuple/tuple_tie.hpp | 49 + thirdparty/boost/fusion/view.hpp | 17 + .../view/detail/strictest_traversal.hpp | 68 + .../boost/fusion/view/ext_/multiple_view.hpp | 178 + .../fusion/view/ext_/segmented_iterator.hpp | 425 + .../view/ext_/segmented_iterator_range.hpp | 537 + thirdparty/boost/fusion/view/filter_view.hpp | 13 + .../view/filter_view/detail/begin_impl.hpp | 45 + .../view/filter_view/detail/deref_impl.hpp | 29 + .../view/filter_view/detail/end_impl.hpp | 44 + .../view/filter_view/detail/equal_to_impl.hpp | 34 + .../view/filter_view/detail/next_impl.hpp | 64 + .../view/filter_view/detail/size_impl.hpp | 38 + .../view/filter_view/detail/value_of_impl.hpp | 29 + .../fusion/view/filter_view/filter_view.hpp | 51 + .../view/filter_view/filter_view_iterator.hpp | 48 + .../boost/fusion/view/iterator_range.hpp | 12 + .../view/iterator_range/detail/at_impl.hpp | 44 + .../view/iterator_range/detail/begin_impl.hpp | 39 + .../view/iterator_range/detail/end_impl.hpp | 39 + .../iterator_range/detail/value_at_impl.hpp | 38 + .../view/iterator_range/iterator_range.hpp | 50 + thirdparty/boost/fusion/view/joint_view.hpp | 13 + .../view/joint_view/detail/begin_impl.hpp | 66 + .../view/joint_view/detail/deref_impl.hpp | 29 + .../view/joint_view/detail/end_impl.hpp | 40 + .../view/joint_view/detail/next_impl.hpp | 70 + .../view/joint_view/detail/value_of_impl.hpp | 29 + .../fusion/view/joint_view/joint_view.hpp | 61 + .../view/joint_view/joint_view_iterator.hpp | 52 + .../boost/fusion/view/repetitive_view.hpp | 15 + .../repetitive_view/detail/begin_impl.hpp | 49 + .../repetitive_view/detail/deref_impl.hpp | 44 + .../view/repetitive_view/detail/end_impl.hpp | 49 + .../view/repetitive_view/detail/next_impl.hpp | 90 + .../repetitive_view/detail/value_of_impl.hpp | 34 + .../view/repetitive_view/repetitive_view.hpp | 48 + .../repetitive_view/repetitive_view_fwd.hpp | 19 + .../repetitive_view_iterator.hpp | 51 + thirdparty/boost/fusion/view/reverse_view.hpp | 13 + .../view/reverse_view/detail/advance_impl.hpp | 47 + .../view/reverse_view/detail/begin_impl.hpp | 42 + .../view/reverse_view/detail/deref_impl.hpp | 48 + .../reverse_view/detail/distance_impl.hpp | 45 + .../view/reverse_view/detail/end_impl.hpp | 42 + .../view/reverse_view/detail/next_impl.hpp | 47 + .../view/reverse_view/detail/prior_impl.hpp | 47 + .../reverse_view/detail/value_of_impl.hpp | 42 + .../fusion/view/reverse_view/reverse_view.hpp | 58 + .../reverse_view/reverse_view_iterator.hpp | 49 + thirdparty/boost/fusion/view/single_view.hpp | 13 + .../view/single_view/detail/begin_impl.hpp | 42 + .../view/single_view/detail/deref_impl.hpp | 43 + .../view/single_view/detail/end_impl.hpp | 42 + .../view/single_view/detail/next_impl.hpp | 47 + .../view/single_view/detail/value_of_impl.hpp | 34 + .../fusion/view/single_view/single_view.hpp | 54 + .../view/single_view/single_view_iterator.hpp | 47 + .../boost/fusion/view/transform_view.hpp | 13 + .../transform_view/detail/advance_impl.hpp | 75 + .../detail/apply_transform_result.hpp | 37 + .../view/transform_view/detail/at_impl.hpp | 63 + .../view/transform_view/detail/begin_impl.hpp | 68 + .../view/transform_view/detail/deref_impl.hpp | 76 + .../transform_view/detail/distance_impl.hpp | 59 + .../view/transform_view/detail/end_impl.hpp | 68 + .../transform_view/detail/equal_to_impl.hpp | 42 + .../view/transform_view/detail/next_impl.hpp | 74 + .../view/transform_view/detail/prior_impl.hpp | 73 + .../transform_view/detail/value_at_impl.hpp | 53 + .../transform_view/detail/value_of_impl.hpp | 63 + .../view/transform_view/transform_view.hpp | 107 + .../transform_view/transform_view_fwd.hpp | 22 + .../transform_view_iterator.hpp | 69 + thirdparty/boost/fusion/view/zip_view.hpp | 14 + .../view/zip_view/detail/advance_impl.hpp | 69 + .../fusion/view/zip_view/detail/at_impl.hpp | 92 + .../view/zip_view/detail/begin_impl.hpp | 92 + .../view/zip_view/detail/deref_impl.hpp | 83 + .../view/zip_view/detail/distance_impl.hpp | 82 + .../fusion/view/zip_view/detail/end_impl.hpp | 103 + .../view/zip_view/detail/equal_to_impl.hpp | 62 + .../fusion/view/zip_view/detail/next_impl.hpp | 83 + .../view/zip_view/detail/prior_impl.hpp | 83 + .../fusion/view/zip_view/detail/size_impl.hpp | 35 + .../view/zip_view/detail/value_at_impl.hpp | 61 + .../view/zip_view/detail/value_of_impl.hpp | 61 + .../boost/fusion/view/zip_view/zip_view.hpp | 115 + .../view/zip_view/zip_view_iterator.hpp | 47 + .../view/zip_view/zip_view_iterator_fwd.hpp | 22 + thirdparty/boost/generator_iterator.hpp | 80 + thirdparty/boost/get_pointer.hpp | 29 + thirdparty/boost/gil/algorithm.hpp | 1014 ++ .../boost/gil/bit_aligned_pixel_iterator.hpp | 191 + .../boost/gil/bit_aligned_pixel_reference.hpp | 302 + thirdparty/boost/gil/channel.hpp | 643 + thirdparty/boost/gil/channel_algorithm.hpp | 469 + thirdparty/boost/gil/cmyk.hpp | 66 + thirdparty/boost/gil/color_base.hpp | 410 + thirdparty/boost/gil/color_base_algorithm.hpp | 696 + thirdparty/boost/gil/color_convert.hpp | 314 + thirdparty/boost/gil/deprecated.hpp | 77 + thirdparty/boost/gil/device_n.hpp | 96 + .../gil/extension/dynamic_image/algorithm.hpp | 173 + .../gil/extension/dynamic_image/any_image.hpp | 125 + .../dynamic_image/any_image_view.hpp | 115 + .../dynamic_image/apply_operation.hpp | 61 + .../dynamic_image/apply_operation_base.hpp | 162 + .../extension/dynamic_image/dynamic_at_c.hpp | 130 + .../dynamic_image/dynamic_image_all.hpp | 32 + .../dynamic_image/image_view_factory.hpp | 212 + .../gil/extension/dynamic_image/reduce.hpp | 789 + .../gil/extension/dynamic_image/variant.hpp | 194 + .../boost/gil/extension/io/dynamic_io.hpp | 79 + .../boost/gil/extension/io/io_error.hpp | 51 + .../gil/extension/io/jpeg_dynamic_io.hpp | 130 + thirdparty/boost/gil/extension/io/jpeg_io.hpp | 202 + .../gil/extension/io/jpeg_io_private.hpp | 225 + .../boost/gil/extension/io/png_dynamic_io.hpp | 141 + thirdparty/boost/gil/extension/io/png_io.hpp | 214 + .../boost/gil/extension/io/png_io_private.hpp | 359 + .../gil/extension/io/tiff_dynamic_io.hpp | 135 + thirdparty/boost/gil/extension/io/tiff_io.hpp | 491 + thirdparty/boost/gil/gil_all.hpp | 46 + thirdparty/boost/gil/gil_concept.hpp | 2187 +++ thirdparty/boost/gil/gil_config.hpp | 50 + thirdparty/boost/gil/gray.hpp | 45 + thirdparty/boost/gil/image.hpp | 288 + thirdparty/boost/gil/image_view.hpp | 223 + thirdparty/boost/gil/image_view_factory.hpp | 537 + thirdparty/boost/gil/iterator_from_2d.hpp | 175 + thirdparty/boost/gil/locator.hpp | 362 + thirdparty/boost/gil/metafunctions.hpp | 494 + thirdparty/boost/gil/packed_pixel.hpp | 193 + thirdparty/boost/gil/pixel.hpp | 212 + thirdparty/boost/gil/pixel_iterator.hpp | 156 + .../boost/gil/pixel_iterator_adaptor.hpp | 208 + .../boost/gil/planar_pixel_iterator.hpp | 227 + .../boost/gil/planar_pixel_reference.hpp | 186 + thirdparty/boost/gil/position_iterator.hpp | 121 + thirdparty/boost/gil/rgb.hpp | 70 + thirdparty/boost/gil/rgba.hpp | 63 + thirdparty/boost/gil/step_iterator.hpp | 320 + thirdparty/boost/gil/typedefs.hpp | 196 + thirdparty/boost/gil/utilities.hpp | 331 + thirdparty/boost/gil/virtual_locator.hpp | 136 + thirdparty/boost/graph/adj_list_serialize.hpp | 114 + thirdparty/boost/graph/adjacency_iterator.hpp | 102 + thirdparty/boost/graph/adjacency_list.hpp | 564 + thirdparty/boost/graph/adjacency_list_io.hpp | 408 + thirdparty/boost/graph/adjacency_matrix.hpp | 1278 ++ thirdparty/boost/graph/astar_search.hpp | 407 + thirdparty/boost/graph/bandwidth.hpp | 83 + thirdparty/boost/graph/bc_clustering.hpp | 164 + .../graph/bellman_ford_shortest_paths.hpp | 241 + .../boost/graph/betweenness_centrality.hpp | 597 + .../boost/graph/biconnected_components.hpp | 415 + .../boost/graph/boyer_myrvold_planar_test.hpp | 322 + .../boost/graph/breadth_first_search.hpp | 293 + .../boost/graph/chrobak_payne_drawing.hpp | 270 + thirdparty/boost/graph/circle_layout.hpp | 55 + .../graph/compressed_sparse_row_graph.hpp | 801 + .../boost/graph/connected_components.hpp | 101 + thirdparty/boost/graph/copy.hpp | 450 + .../boost/graph/create_condensation_graph.hpp | 83 + .../boost/graph/cuthill_mckee_ordering.hpp | 190 + thirdparty/boost/graph/dag_shortest_paths.hpp | 157 + thirdparty/boost/graph/depth_first_search.hpp | 365 + .../graph/detail/adj_list_edge_iterator.hpp | 117 + .../boost/graph/detail/adjacency_list.hpp | 2844 ++++ .../boost/graph/detail/array_binary_tree.hpp | 182 + .../graph/detail/connected_components.hpp | 208 + thirdparty/boost/graph/detail/edge.hpp | 124 + .../boost/graph/detail/incidence_iterator.hpp | 79 + .../graph/detail/incremental_components.hpp | 141 + .../boost/graph/detail/indexed_properties.hpp | 180 + thirdparty/boost/graph/detail/is_same.hpp | 40 + thirdparty/boost/graph/detail/list_base.hpp | 220 + thirdparty/boost/graph/detail/permutation.hpp | 205 + .../graph/detail/read_graphviz_spirit.hpp | 610 + .../boost/graph/detail/self_avoiding_walk.hpp | 418 + thirdparty/boost/graph/detail/set_adaptor.hpp | 117 + .../boost/graph/detail/shadow_iterator.hpp | 139 + .../boost/graph/detail/sparse_ordering.hpp | 198 + .../boost/graph/dijkstra_shortest_paths.hpp | 347 + thirdparty/boost/graph/dominator_tree.hpp | 488 + thirdparty/boost/graph/edge_connectivity.hpp | 181 + thirdparty/boost/graph/edge_list.hpp | 304 + .../boost/graph/edmunds_karp_max_flow.hpp | 250 + .../boost/graph/erdos_renyi_generator.hpp | 228 + thirdparty/boost/graph/exception.hpp | 44 + thirdparty/boost/graph/filtered_graph.hpp | 507 + .../boost/graph/floyd_warshall_shortest.hpp | 251 + .../boost/graph/fruchterman_reingold.hpp | 420 + thirdparty/boost/graph/graph_archetypes.hpp | 290 + thirdparty/boost/graph/graph_as_tree.hpp | 154 + thirdparty/boost/graph/graph_concepts.hpp | 510 + thirdparty/boost/graph/graph_selectors.hpp | 38 + thirdparty/boost/graph/graph_test.hpp | 382 + thirdparty/boost/graph/graph_traits.hpp | 168 + thirdparty/boost/graph/graph_utility.hpp | 425 + thirdparty/boost/graph/graphml.hpp | 332 + thirdparty/boost/graph/graphviz.hpp | 783 + thirdparty/boost/graph/gursoy_atun_layout.hpp | 631 + thirdparty/boost/graph/howard_cycle_ratio.hpp | 611 + .../boost/graph/incremental_components.hpp | 170 + .../boost/graph/is_kuratowski_subgraph.hpp | 332 + .../boost/graph/is_straight_line_drawing.hpp | 232 + thirdparty/boost/graph/isomorphism.hpp | 467 + thirdparty/boost/graph/iteration_macros.hpp | 129 + .../boost/graph/iteration_macros_undef.hpp | 22 + .../graph/johnson_all_pairs_shortest.hpp | 205 + .../graph/kamada_kawai_spring_layout.hpp | 542 + thirdparty/boost/graph/king_ordering.hpp | 320 + .../boost/graph/kolmogorov_max_flow.hpp | 807 ++ .../boost/graph/kruskal_min_spanning_tree.hpp | 155 + thirdparty/boost/graph/leda_graph.hpp | 952 ++ .../boost/graph/make_biconnected_planar.hpp | 121 + thirdparty/boost/graph/make_connected.hpp | 99 + .../boost/graph/make_maximal_planar.hpp | 275 + thirdparty/boost/graph/matrix_as_graph.hpp | 127 + .../boost/graph/max_cardinality_matching.hpp | 883 ++ .../boost/graph/minimum_degree_ordering.hpp | 655 + .../boost/graph/named_function_params.hpp | 795 + thirdparty/boost/graph/neighbor_bfs.hpp | 323 + thirdparty/boost/graph/page_rank.hpp | 153 + .../boost/graph/planar_canonical_ordering.hpp | 211 + .../graph/planar_detail/add_edge_visitors.hpp | 59 + .../planar_detail/boyer_myrvold_impl.hpp | 2010 +++ .../boost/graph/planar_detail/bucket_sort.hpp | 144 + .../graph/planar_detail/face_handles.hpp | 497 + .../graph/planar_detail/face_iterators.hpp | 375 + .../boost/graph/planar_face_traversal.hpp | 210 + thirdparty/boost/graph/plod_generator.hpp | 161 + .../graph/prim_minimum_spanning_tree.hpp | 91 + thirdparty/boost/graph/profile.hpp | 43 + thirdparty/boost/graph/properties.hpp | 389 + .../boost/graph/property_iter_range.hpp | 118 + .../boost/graph/push_relabel_max_flow.hpp | 727 + thirdparty/boost/graph/random.hpp | 205 + thirdparty/boost/graph/random_layout.hpp | 49 + thirdparty/boost/graph/read_dimacs.hpp | 277 + thirdparty/boost/graph/relax.hpp | 77 + thirdparty/boost/graph/reverse_graph.hpp | 324 + .../graph/sequential_vertex_coloring.hpp | 124 + thirdparty/boost/graph/simple_point.hpp | 23 + thirdparty/boost/graph/sloan_ordering.hpp | 448 + .../boost/graph/small_world_generator.hpp | 114 + .../boost/graph/smallest_last_ordering.hpp | 122 + thirdparty/boost/graph/stanford_graph.hpp | 565 + thirdparty/boost/graph/strong_components.hpp | 334 + thirdparty/boost/graph/subgraph.hpp | 872 ++ thirdparty/boost/graph/topological_sort.hpp | 76 + thirdparty/boost/graph/transitive_closure.hpp | 370 + thirdparty/boost/graph/transpose_graph.hpp | 40 + thirdparty/boost/graph/tree_traits.hpp | 43 + thirdparty/boost/graph/two_bit_color_map.hpp | 90 + thirdparty/boost/graph/undirected_dfs.hpp | 250 + thirdparty/boost/graph/vector_as_graph.hpp | 332 + thirdparty/boost/graph/visitors.hpp | 279 + thirdparty/boost/graph/wavefront.hpp | 135 + thirdparty/boost/graph/write_dimacs.hpp | 72 + thirdparty/boost/implicit_cast.hpp | 29 + thirdparty/boost/indirect_reference.hpp | 43 + thirdparty/boost/integer.hpp | 127 + thirdparty/boost/integer/integer_mask.hpp | 93 + thirdparty/boost/integer/static_log2.hpp | 132 + thirdparty/boost/integer/static_min_max.hpp | 55 + thirdparty/boost/integer_fwd.hpp | 152 + thirdparty/boost/integer_traits.hpp | 236 + .../interprocess/allocators/adaptive_pool.hpp | 451 + .../allocators/allocation_type.hpp | 55 + .../interprocess/allocators/allocator.hpp | 301 + .../allocators/cached_adaptive_pool.hpp | 353 + .../allocators/cached_node_allocator.hpp | 323 + .../allocators/detail/adaptive_node_pool.hpp | 617 + .../allocators/detail/allocator_common.hpp | 760 + .../allocators/detail/node_pool.hpp | 420 + .../allocators/detail/node_tools.hpp | 50 + .../allocators/node_allocator.hpp | 434 + .../allocators/private_adaptive_pool.hpp | 448 + .../allocators/private_node_allocator.hpp | 632 + .../boost/interprocess/containers/deque.hpp | 1561 ++ .../containers/detail/flat_tree.hpp | 743 + .../containers/detail/node_alloc_holder.hpp | 401 + .../interprocess/containers/detail/tree.hpp | 950 ++ .../interprocess/containers/flat_map.hpp | 1273 ++ .../interprocess/containers/flat_set.hpp | 1082 ++ .../boost/interprocess/containers/list.hpp | 1328 ++ .../boost/interprocess/containers/map.hpp | 1241 ++ .../boost/interprocess/containers/set.hpp | 1043 ++ .../boost/interprocess/containers/slist.hpp | 1471 ++ .../boost/interprocess/containers/string.hpp | 2489 ++++ .../boost/interprocess/containers/vector.hpp | 1879 +++ .../boost/interprocess/creation_tags.hpp | 57 + .../boost/interprocess/detail/algorithms.hpp | 129 + .../boost/interprocess/detail/atomic.hpp | 472 + .../boost/interprocess/detail/cast_tags.hpp | 29 + .../interprocess/detail/config_begin.hpp | 33 + .../boost/interprocess/detail/config_end.hpp | 8 + .../interprocess/detail/file_wrapper.hpp | 213 + .../detail/in_place_interface.hpp | 72 + .../detail/interprocess_tester.hpp | 31 + .../boost/interprocess/detail/iterators.hpp | 475 + .../detail/managed_memory_impl.hpp | 731 + .../detail/managed_open_or_create_impl.hpp | 419 + .../interprocess/detail/math_functions.hpp | 87 + .../boost/interprocess/detail/min_max.hpp | 40 + thirdparty/boost/interprocess/detail/move.hpp | 147 + .../interprocess/detail/move_iterator.hpp | 138 + thirdparty/boost/interprocess/detail/mpl.hpp | 129 + .../boost/interprocess/detail/named_proxy.hpp | 279 + .../interprocess/detail/os_file_functions.hpp | 367 + .../detail/os_thread_functions.hpp | 84 + .../interprocess/detail/pointer_type.hpp | 74 + .../detail/posix_time_types_wrk.hpp | 43 + .../boost/interprocess/detail/ptime_wrk.hpp | 33 + .../detail/segment_manager_helper.hpp | 495 + .../interprocess/detail/tmp_dir_helpers.hpp | 78 + .../boost/interprocess/detail/type_traits.hpp | 189 + .../boost/interprocess/detail/utilities.hpp | 763 + .../interprocess/detail/version_type.hpp | 89 + .../boost/interprocess/detail/win32_api.hpp | 414 + .../boost/interprocess/detail/workaround.hpp | 134 + thirdparty/boost/interprocess/errors.hpp | 229 + thirdparty/boost/interprocess/exceptions.hpp | 145 + .../boost/interprocess/file_mapping.hpp | 173 + .../interprocess/indexes/flat_map_index.hpp | 78 + .../boost/interprocess/indexes/iset_index.hpp | 150 + .../indexes/iunordered_set_index.hpp | 367 + .../boost/interprocess/indexes/map_index.hpp | 100 + .../boost/interprocess/indexes/null_index.hpp | 68 + .../indexes/unordered_map_index.hpp | 109 + .../boost/interprocess/interprocess_fwd.hpp | 474 + .../boost/interprocess/ipc/message_queue.hpp | 618 + .../interprocess/managed_external_buffer.hpp | 109 + .../interprocess/managed_heap_memory.hpp | 149 + .../interprocess/managed_mapped_file.hpp | 170 + .../interprocess/managed_shared_memory.hpp | 168 + .../managed_windows_shared_memory.hpp | 146 + .../boost/interprocess/mapped_region.hpp | 561 + .../mem_algo/detail/mem_algo_common.hpp | 654 + .../mem_algo/detail/simple_seq_fit_impl.hpp | 1098 ++ .../interprocess/mem_algo/rbtree_best_fit.hpp | 1353 ++ .../interprocess/mem_algo/simple_seq_fit.hpp | 56 + thirdparty/boost/interprocess/offset_ptr.hpp | 478 + .../boost/interprocess/segment_manager.hpp | 1297 ++ .../interprocess/shared_memory_object.hpp | 349 + .../boost/interprocess/smart_ptr/deleter.hpp | 61 + .../smart_ptr/detail/bad_weak_ptr.hpp | 44 + .../smart_ptr/detail/shared_count.hpp | 315 + .../smart_ptr/detail/sp_counted_base.hpp | 7 + .../detail/sp_counted_base_atomic.hpp | 92 + .../smart_ptr/detail/sp_counted_impl.hpp | 117 + .../smart_ptr/enable_shared_from_this.hpp | 76 + .../interprocess/smart_ptr/intrusive_ptr.hpp | 293 + .../interprocess/smart_ptr/scoped_ptr.hpp | 167 + .../interprocess/smart_ptr/shared_ptr.hpp | 353 + .../interprocess/smart_ptr/unique_ptr.hpp | 617 + .../boost/interprocess/smart_ptr/weak_ptr.hpp | 255 + .../interprocess/streams/bufferstream.hpp | 444 + .../interprocess/streams/vectorstream.hpp | 593 + .../sync/emulation/interprocess_barrier.hpp | 46 + .../sync/emulation/interprocess_condition.hpp | 193 + .../sync/emulation/interprocess_mutex.hpp | 77 + .../interprocess_recursive_mutex.hpp | 108 + .../sync/emulation/interprocess_semaphore.hpp | 71 + .../sync/emulation/named_creation_functor.hpp | 68 + .../boost/interprocess/sync/file_lock.hpp | 319 + .../sync/interprocess_barrier.hpp | 111 + .../sync/interprocess_condition.hpp | 167 + .../interprocess/sync/interprocess_mutex.hpp | 133 + .../sync/interprocess_recursive_mutex.hpp | 131 + .../sync/interprocess_semaphore.hpp | 119 + .../sync/interprocess_upgradable_mutex.hpp | 643 + .../boost/interprocess/sync/lock_options.hpp | 57 + .../boost/interprocess/sync/mutex_family.hpp | 56 + .../interprocess/sync/named_condition.hpp | 328 + .../boost/interprocess/sync/named_mutex.hpp | 220 + .../sync/named_recursive_mutex.hpp | 167 + .../interprocess/sync/named_semaphore.hpp | 228 + .../sync/named_upgradable_mutex.hpp | 348 + .../boost/interprocess/sync/null_mutex.hpp | 147 + .../sync/posix/interprocess_barrier.hpp | 44 + .../sync/posix/interprocess_condition.hpp | 81 + .../sync/posix/interprocess_mutex.hpp | 106 + .../posix/interprocess_recursive_mutex.hpp | 107 + .../sync/posix/interprocess_semaphore.hpp | 43 + .../sync/posix/pthread_helpers.hpp | 168 + .../sync/posix/ptime_to_timespec.hpp | 38 + .../sync/posix/semaphore_wrapper.hpp | 274 + .../boost/interprocess/sync/scoped_lock.hpp | 468 + .../boost/interprocess/sync/sharable_lock.hpp | 367 + .../interprocess/sync/upgradable_lock.hpp | 375 + .../interprocess/windows_shared_memory.hpp | 243 + thirdparty/boost/intrusive/avl_set.hpp | 2069 +++ thirdparty/boost/intrusive/avl_set_hook.hpp | 273 + thirdparty/boost/intrusive/avltree.hpp | 1439 ++ .../boost/intrusive/avltree_algorithms.hpp | 985 ++ thirdparty/boost/intrusive/bs_set_hook.hpp | 288 + .../intrusive/circular_list_algorithms.hpp | 406 + .../intrusive/circular_slist_algorithms.hpp | 404 + .../intrusive/derivation_value_traits.hpp | 56 + thirdparty/boost/intrusive/detail/assert.hpp | 35 + .../boost/intrusive/detail/avltree_node.hpp | 179 + .../detail/common_slist_algorithms.hpp | 95 + .../boost/intrusive/detail/config_begin.hpp | 50 + .../boost/intrusive/detail/config_end.hpp | 15 + .../intrusive/detail/ebo_functor_holder.hpp | 71 + .../boost/intrusive/detail/generic_hook.hpp | 200 + .../boost/intrusive/detail/hashtable_node.hpp | 216 + .../boost/intrusive/detail/list_node.hpp | 185 + thirdparty/boost/intrusive/detail/mpl.hpp | 297 + .../detail/no_exceptions_support.hpp | 28 + .../intrusive/detail/parent_from_member.hpp | 61 + .../intrusive/detail/pointer_to_other.hpp | 65 + .../boost/intrusive/detail/rbtree_node.hpp | 177 + .../boost/intrusive/detail/slist_node.hpp | 161 + .../intrusive/detail/transform_iterator.hpp | 173 + .../intrusive/detail/tree_algorithms.hpp | 1581 ++ .../boost/intrusive/detail/tree_node.hpp | 192 + .../boost/intrusive/detail/utilities.hpp | 557 + thirdparty/boost/intrusive/hashtable.hpp | 1979 +++ thirdparty/boost/intrusive/intrusive_fwd.hpp | 345 + .../intrusive/linear_slist_algorithms.hpp | 326 + thirdparty/boost/intrusive/link_mode.hpp | 46 + thirdparty/boost/intrusive/list.hpp | 1443 ++ thirdparty/boost/intrusive/list_hook.hpp | 264 + .../boost/intrusive/member_value_traits.hpp | 65 + thirdparty/boost/intrusive/options.hpp | 513 + .../boost/intrusive/pointer_plus_2_bits.hpp | 82 + .../boost/intrusive/pointer_plus_bit.hpp | 78 + thirdparty/boost/intrusive/rbtree.hpp | 1439 ++ .../boost/intrusive/rbtree_algorithms.hpp | 841 ++ thirdparty/boost/intrusive/set.hpp | 2070 +++ thirdparty/boost/intrusive/set_hook.hpp | 274 + thirdparty/boost/intrusive/sg_set.hpp | 2147 +++ thirdparty/boost/intrusive/sgtree.hpp | 1648 +++ .../boost/intrusive/sgtree_algorithms.hpp | 704 + thirdparty/boost/intrusive/slist.hpp | 1858 +++ thirdparty/boost/intrusive/slist_hook.hpp | 268 + thirdparty/boost/intrusive/splay_set.hpp | 2221 +++ thirdparty/boost/intrusive/splay_set_hook.hpp | 266 + thirdparty/boost/intrusive/splaytree.hpp | 1518 ++ .../boost/intrusive/splaytree_algorithms.hpp | 855 ++ .../boost/intrusive/trivial_value_traits.hpp | 43 + thirdparty/boost/intrusive/unordered_set.hpp | 1953 +++ .../boost/intrusive/unordered_set_hook.hpp | 318 + thirdparty/boost/intrusive_ptr.hpp | 284 + thirdparty/boost/io/ios_state.hpp | 431 + thirdparty/boost/io_fwd.hpp | 67 + thirdparty/boost/iostreams/categories.hpp | 175 + thirdparty/boost/iostreams/chain.hpp | 585 + thirdparty/boost/iostreams/char_traits.hpp | 73 + .../boost/iostreams/checked_operations.hpp | 151 + thirdparty/boost/iostreams/close.hpp | 260 + thirdparty/boost/iostreams/code_converter.hpp | 422 + thirdparty/boost/iostreams/combine.hpp | 249 + thirdparty/boost/iostreams/compose.hpp | 490 + thirdparty/boost/iostreams/concepts.hpp | 129 + thirdparty/boost/iostreams/constants.hpp | 42 + thirdparty/boost/iostreams/copy.hpp | 252 + .../boost/iostreams/detail/absolute_path.hpp | 46 + .../boost/iostreams/detail/access_control.hpp | 87 + .../detail/adapter/concept_adapter.hpp | 278 + .../detail/adapter/device_adapter.hpp | 67 + .../detail/adapter/direct_adapter.hpp | 280 + .../detail/adapter/filter_adapter.hpp | 69 + .../iostreams/detail/adapter/mode_adapter.hpp | 123 + .../detail/adapter/non_blocking_adapter.hpp | 59 + .../adapter/output_iterator_adapter.hpp | 41 + .../detail/adapter/range_adapter.hpp | 183 + .../boost/iostreams/detail/add_facet.hpp | 49 + .../boost/iostreams/detail/bool_trait_def.hpp | 49 + .../broken_overload_resolution/forward.hpp | 31 + .../broken_overload_resolution/stream.hpp | 185 + .../stream_buffer.hpp | 189 + thirdparty/boost/iostreams/detail/buffer.hpp | 200 + .../boost/iostreams/detail/call_traits.hpp | 32 + .../boost/iostreams/detail/char_traits.hpp | 63 + .../boost/iostreams/detail/codecvt_helper.hpp | 238 + .../boost/iostreams/detail/codecvt_holder.hpp | 63 + .../iostreams/detail/config/auto_link.hpp | 49 + .../boost/iostreams/detail/config/bzip2.hpp | 48 + .../boost/iostreams/detail/config/codecvt.hpp | 80 + .../detail/config/disable_warnings.hpp | 27 + .../iostreams/detail/config/dyn_link.hpp | 37 + .../detail/config/enable_warnings.hpp | 18 + .../boost/iostreams/detail/config/fpos.hpp | 31 + .../boost/iostreams/detail/config/gcc.hpp | 24 + .../boost/iostreams/detail/config/limits.hpp | 19 + .../detail/config/overload_resolution.hpp | 32 + .../boost/iostreams/detail/config/rtl.hpp | 68 + .../iostreams/detail/config/wide_streams.hpp | 55 + .../iostreams/detail/config/windows_posix.hpp | 25 + .../boost/iostreams/detail/config/zlib.hpp | 50 + .../boost/iostreams/detail/counted_array.hpp | 64 + .../iostreams/detail/current_directory.hpp | 60 + .../boost/iostreams/detail/default_arg.hpp | 25 + .../boost/iostreams/detail/dispatch.hpp | 41 + .../boost/iostreams/detail/double_object.hpp | 114 + .../iostreams/detail/enable_if_stream.hpp | 32 + thirdparty/boost/iostreams/detail/error.hpp | 45 + thirdparty/boost/iostreams/detail/execute.hpp | 135 + thirdparty/boost/iostreams/detail/forward.hpp | 102 + thirdparty/boost/iostreams/detail/fstream.hpp | 33 + .../boost/iostreams/detail/functional.hpp | 189 + thirdparty/boost/iostreams/detail/ios.hpp | 66 + .../boost/iostreams/detail/iostream.hpp | 34 + .../iostreams/detail/is_dereferenceable.hpp | 85 + .../iostreams/detail/is_iterator_range.hpp | 42 + thirdparty/boost/iostreams/detail/newline.hpp | 32 + .../boost/iostreams/detail/optional.hpp | 114 + .../boost/iostreams/detail/param_type.hpp | 27 + thirdparty/boost/iostreams/detail/push.hpp | 154 + .../boost/iostreams/detail/push_params.hpp | 21 + thirdparty/boost/iostreams/detail/resolve.hpp | 234 + .../boost/iostreams/detail/restrict_impl.hpp | 474 + thirdparty/boost/iostreams/detail/select.hpp | 86 + .../boost/iostreams/detail/select_by_size.hpp | 160 + .../boost/iostreams/detail/streambuf.hpp | 34 + .../iostreams/detail/streambuf/chainbuf.hpp | 116 + .../detail/streambuf/direct_streambuf.hpp | 306 + .../detail/streambuf/indirect_streambuf.hpp | 430 + .../detail/streambuf/linked_streambuf.hpp | 114 + .../boost/iostreams/detail/system_failure.hpp | 83 + .../iostreams/detail/template_params.hpp | 26 + .../iostreams/detail/translate_int_type.hpp | 62 + .../boost/iostreams/detail/vc6/close.hpp | 129 + .../boost/iostreams/detail/vc6/read.hpp | 238 + .../boost/iostreams/detail/vc6/write.hpp | 159 + .../boost/iostreams/detail/wrap_unwrap.hpp | 127 + thirdparty/boost/iostreams/device/array.hpp | 144 + .../boost/iostreams/device/back_inserter.hpp | 41 + thirdparty/boost/iostreams/device/file.hpp | 183 + .../iostreams/device/file_descriptor.hpp | 186 + .../boost/iostreams/device/mapped_file.hpp | 285 + thirdparty/boost/iostreams/device/null.hpp | 66 + .../boost/iostreams/filter/aggregate.hpp | 168 + thirdparty/boost/iostreams/filter/bzip2.hpp | 397 + thirdparty/boost/iostreams/filter/counter.hpp | 82 + thirdparty/boost/iostreams/filter/gzip.hpp | 604 + thirdparty/boost/iostreams/filter/line.hpp | 220 + thirdparty/boost/iostreams/filter/newline.hpp | 441 + thirdparty/boost/iostreams/filter/regex.hpp | 98 + thirdparty/boost/iostreams/filter/stdio.hpp | 84 + .../boost/iostreams/filter/symmetric.hpp | 304 + thirdparty/boost/iostreams/filter/test.hpp | 278 + thirdparty/boost/iostreams/filter/zlib.hpp | 416 + .../boost/iostreams/filtering_stream.hpp | 166 + .../boost/iostreams/filtering_streambuf.hpp | 70 + thirdparty/boost/iostreams/flush.hpp | 125 + thirdparty/boost/iostreams/get.hpp | 17 + thirdparty/boost/iostreams/imbue.hpp | 82 + thirdparty/boost/iostreams/input_sequence.hpp | 72 + thirdparty/boost/iostreams/invert.hpp | 166 + thirdparty/boost/iostreams/operations.hpp | 26 + thirdparty/boost/iostreams/operations_fwd.hpp | 41 + .../boost/iostreams/optimal_buffer_size.hpp | 87 + .../boost/iostreams/output_sequence.hpp | 72 + thirdparty/boost/iostreams/pipeline.hpp | 128 + thirdparty/boost/iostreams/positioning.hpp | 115 + thirdparty/boost/iostreams/put.hpp | 17 + thirdparty/boost/iostreams/putback.hpp | 17 + thirdparty/boost/iostreams/read.hpp | 247 + thirdparty/boost/iostreams/restrict.hpp | 26 + thirdparty/boost/iostreams/seek.hpp | 180 + thirdparty/boost/iostreams/skip.hpp | 111 + thirdparty/boost/iostreams/slice.hpp | 28 + thirdparty/boost/iostreams/stream.hpp | 152 + thirdparty/boost/iostreams/stream_buffer.hpp | 114 + thirdparty/boost/iostreams/tee.hpp | 173 + thirdparty/boost/iostreams/traits.hpp | 364 + thirdparty/boost/iostreams/traits_fwd.hpp | 111 + thirdparty/boost/iostreams/write.hpp | 171 + thirdparty/boost/is_placeholder.hpp | 31 + thirdparty/boost/iterator.hpp | 59 + .../boost/iterator/counting_iterator.hpp | 215 + .../iterator/detail/any_conversion_eater.hpp | 19 + .../boost/iterator/detail/config_def.hpp | 135 + .../boost/iterator/detail/config_undef.hpp | 25 + .../boost/iterator/detail/enable_if.hpp | 86 + .../detail/facade_iterator_category.hpp | 200 + .../iterator/detail/minimum_category.hpp | 116 + thirdparty/boost/iterator/filter_iterator.hpp | 135 + .../boost/iterator/indirect_iterator.hpp | 139 + thirdparty/boost/iterator/interoperable.hpp | 50 + .../boost/iterator/is_lvalue_iterator.hpp | 150 + .../boost/iterator/is_readable_iterator.hpp | 108 + .../boost/iterator/iterator_adaptor.hpp | 366 + .../boost/iterator/iterator_archetypes.hpp | 515 + .../boost/iterator/iterator_categories.hpp | 188 + .../boost/iterator/iterator_concepts.hpp | 284 + thirdparty/boost/iterator/iterator_facade.hpp | 879 ++ thirdparty/boost/iterator/iterator_traits.hpp | 92 + .../boost/iterator/new_iterator_tests.hpp | 264 + .../boost/iterator/permutation_iterator.hpp | 72 + .../boost/iterator/reverse_iterator.hpp | 69 + .../boost/iterator/transform_iterator.hpp | 188 + thirdparty/boost/iterator/zip_iterator.hpp | 585 + thirdparty/boost/iterator_adaptors.hpp | 13 + thirdparty/boost/lambda/algorithm.hpp | 1377 ++ thirdparty/boost/lambda/bind.hpp | 19 + thirdparty/boost/lambda/casts.hpp | 219 + thirdparty/boost/lambda/closures.hpp | 274 + thirdparty/boost/lambda/construct.hpp | 237 + .../boost/lambda/control_structures.hpp | 22 + thirdparty/boost/lambda/core.hpp | 79 + thirdparty/boost/lambda/detail/actions.hpp | 174 + thirdparty/boost/lambda/detail/arity_code.hpp | 110 + .../boost/lambda/detail/bind_functions.hpp | 1879 +++ .../detail/control_constructs_common.hpp | 50 + .../lambda/detail/control_structures_impl.hpp | 550 + .../boost/lambda/detail/function_adaptors.hpp | 640 + .../boost/lambda/detail/is_instance_of.hpp | 104 + .../boost/lambda/detail/lambda_config.hpp | 48 + .../lambda/detail/lambda_functor_base.hpp | 599 + .../boost/lambda/detail/lambda_functors.hpp | 275 + thirdparty/boost/lambda/detail/lambda_fwd.hpp | 74 + .../boost/lambda/detail/lambda_traits.hpp | 527 + thirdparty/boost/lambda/detail/member_ptr.hpp | 737 + .../boost/lambda/detail/operator_actions.hpp | 139 + .../detail/operator_lambda_func_base.hpp | 271 + .../detail/operator_return_type_traits.hpp | 942 ++ thirdparty/boost/lambda/detail/operators.hpp | 370 + thirdparty/boost/lambda/detail/ret.hpp | 325 + .../lambda/detail/return_type_traits.hpp | 284 + .../boost/lambda/detail/select_functions.hpp | 74 + thirdparty/boost/lambda/exceptions.hpp | 1740 +++ thirdparty/boost/lambda/if.hpp | 462 + thirdparty/boost/lambda/lambda.hpp | 34 + thirdparty/boost/lambda/loops.hpp | 505 + thirdparty/boost/lambda/numeric.hpp | 119 + thirdparty/boost/lambda/switch.hpp | 502 + thirdparty/boost/last_value.hpp | 54 + thirdparty/boost/lexical_cast.hpp | 1205 ++ thirdparty/boost/limits.hpp | 146 + thirdparty/boost/logic/tribool.hpp | 460 + thirdparty/boost/logic/tribool_fwd.hpp | 15 + thirdparty/boost/logic/tribool_io.hpp | 348 + thirdparty/boost/math/bindings/rr.hpp | 707 + thirdparty/boost/math/common_factor.hpp | 16 + thirdparty/boost/math/common_factor_ct.hpp | 188 + thirdparty/boost/math/common_factor_rt.hpp | 512 + thirdparty/boost/math/complex.hpp | 32 + thirdparty/boost/math/complex/acos.hpp | 235 + thirdparty/boost/math/complex/acosh.hpp | 34 + thirdparty/boost/math/complex/asin.hpp | 245 + thirdparty/boost/math/complex/asinh.hpp | 32 + thirdparty/boost/math/complex/atan.hpp | 36 + thirdparty/boost/math/complex/atanh.hpp | 245 + thirdparty/boost/math/complex/details.hpp | 104 + thirdparty/boost/math/complex/fabs.hpp | 23 + .../boost/math/concepts/distributions.hpp | 204 + .../boost/math/concepts/real_concept.hpp | 388 + .../boost/math/concepts/std_real_concept.hpp | 356 + thirdparty/boost/math/constants/constants.hpp | 75 + thirdparty/boost/math/distributions.hpp | 42 + .../boost/math/distributions/bernoulli.hpp | 325 + thirdparty/boost/math/distributions/beta.hpp | 544 + .../boost/math/distributions/binomial.hpp | 724 + .../boost/math/distributions/cauchy.hpp | 347 + .../boost/math/distributions/chi_squared.hpp | 326 + .../boost/math/distributions/complement.hpp | 195 + .../detail/common_error_handling.hpp | 103 + .../detail/derived_accessors.hpp | 163 + .../detail/inv_discrete_quantile.hpp | 481 + .../boost/math/distributions/exponential.hpp | 259 + .../math/distributions/extreme_value.hpp | 260 + .../math/distributions/find_location.hpp | 146 + .../boost/math/distributions/find_scale.hpp | 211 + .../boost/math/distributions/fisher_f.hpp | 385 + thirdparty/boost/math/distributions/fwd.hpp | 94 + thirdparty/boost/math/distributions/gamma.hpp | 348 + .../boost/math/distributions/lognormal.hpp | 310 + .../math/distributions/negative_binomial.hpp | 588 + .../boost/math/distributions/normal.hpp | 308 + .../boost/math/distributions/pareto.hpp | 443 + .../boost/math/distributions/poisson.hpp | 587 + .../boost/math/distributions/rayleigh.hpp | 293 + .../boost/math/distributions/students_t.hpp | 374 + .../boost/math/distributions/triangular.hpp | 521 + .../boost/math/distributions/uniform.hpp | 375 + .../boost/math/distributions/weibull.hpp | 382 + thirdparty/boost/math/octonion.hpp | 4754 ++++++ .../boost/math/policies/error_handling.hpp | 518 + thirdparty/boost/math/policies/policy.hpp | 843 ++ thirdparty/boost/math/quaternion.hpp | 1924 +++ thirdparty/boost/math/special_functions.hpp | 51 + .../boost/math/special_functions/acosh.hpp | 112 + .../boost/math/special_functions/asinh.hpp | 112 + .../boost/math/special_functions/atanh.hpp | 122 + .../boost/math/special_functions/bessel.hpp | 484 + .../boost/math/special_functions/beta.hpp | 1350 ++ .../boost/math/special_functions/binomial.hpp | 75 + .../boost/math/special_functions/cbrt.hpp | 72 + .../boost/math/special_functions/cos_pi.hpp | 64 + .../special_functions/detail/bessel_i0.hpp | 96 + .../special_functions/detail/bessel_i1.hpp | 99 + .../special_functions/detail/bessel_ik.hpp | 331 + .../special_functions/detail/bessel_j0.hpp | 147 + .../special_functions/detail/bessel_j1.hpp | 152 + .../special_functions/detail/bessel_jn.hpp | 86 + .../special_functions/detail/bessel_jy.hpp | 361 + .../detail/bessel_jy_asym.hpp | 297 + .../special_functions/detail/bessel_k0.hpp | 116 + .../special_functions/detail/bessel_k1.hpp | 112 + .../special_functions/detail/bessel_kn.hpp | 69 + .../special_functions/detail/bessel_y0.hpp | 177 + .../special_functions/detail/bessel_y1.hpp | 150 + .../special_functions/detail/bessel_yn.hpp | 79 + .../math/special_functions/detail/erf_inv.hpp | 464 + .../special_functions/detail/gamma_inva.hpp | 228 + .../special_functions/detail/ibeta_inv_ab.hpp | 319 + .../detail/ibeta_inverse.hpp | 934 ++ .../detail/igamma_inverse.hpp | 466 + .../special_functions/detail/igamma_large.hpp | 764 + .../special_functions/detail/lgamma_small.hpp | 507 + .../detail/simple_complex.hpp | 167 + .../detail/t_distribution_inv.hpp | 509 + .../detail/unchecked_factorial.hpp | 397 + .../boost/math/special_functions/digamma.hpp | 445 + .../boost/math/special_functions/ellint_1.hpp | 182 + .../boost/math/special_functions/ellint_2.hpp | 163 + .../boost/math/special_functions/ellint_3.hpp | 327 + .../math/special_functions/ellint_rc.hpp | 110 + .../math/special_functions/ellint_rd.hpp | 125 + .../math/special_functions/ellint_rf.hpp | 127 + .../math/special_functions/ellint_rj.hpp | 174 + .../boost/math/special_functions/erf.hpp | 858 ++ .../boost/math/special_functions/expm1.hpp | 269 + .../math/special_functions/factorials.hpp | 224 + .../math/special_functions/fpclassify.hpp | 240 + .../boost/math/special_functions/gamma.hpp | 1471 ++ .../boost/math/special_functions/hermite.hpp | 71 + .../boost/math/special_functions/hypot.hpp | 81 + .../boost/math/special_functions/laguerre.hpp | 134 + .../boost/math/special_functions/lanczos.hpp | 1231 ++ .../boost/math/special_functions/legendre.hpp | 189 + .../boost/math/special_functions/log1p.hpp | 277 + .../boost/math/special_functions/math_fwd.hpp | 912 ++ .../boost/math/special_functions/powm1.hpp | 56 + .../boost/math/special_functions/sign.hpp | 38 + .../boost/math/special_functions/sin_pi.hpp | 64 + .../boost/math/special_functions/sinc.hpp | 172 + .../boost/math/special_functions/sinhc.hpp | 163 + .../special_functions/spherical_harmonic.hpp | 199 + .../boost/math/special_functions/sqrt1pm1.hpp | 43 + thirdparty/boost/math/tools/config.hpp | 246 + .../tools/detail/polynomial_horner1_10.hpp | 84 + .../tools/detail/polynomial_horner1_11.hpp | 90 + .../tools/detail/polynomial_horner1_12.hpp | 96 + .../tools/detail/polynomial_horner1_13.hpp | 102 + .../tools/detail/polynomial_horner1_14.hpp | 108 + .../tools/detail/polynomial_horner1_15.hpp | 114 + .../tools/detail/polynomial_horner1_16.hpp | 120 + .../tools/detail/polynomial_horner1_17.hpp | 126 + .../tools/detail/polynomial_horner1_18.hpp | 132 + .../tools/detail/polynomial_horner1_19.hpp | 138 + .../tools/detail/polynomial_horner1_2.hpp | 36 + .../tools/detail/polynomial_horner1_20.hpp | 144 + .../tools/detail/polynomial_horner1_3.hpp | 42 + .../tools/detail/polynomial_horner1_4.hpp | 48 + .../tools/detail/polynomial_horner1_5.hpp | 54 + .../tools/detail/polynomial_horner1_6.hpp | 60 + .../tools/detail/polynomial_horner1_7.hpp | 66 + .../tools/detail/polynomial_horner1_8.hpp | 72 + .../tools/detail/polynomial_horner1_9.hpp | 78 + .../tools/detail/polynomial_horner2_10.hpp | 90 + .../tools/detail/polynomial_horner2_11.hpp | 97 + .../tools/detail/polynomial_horner2_12.hpp | 104 + .../tools/detail/polynomial_horner2_13.hpp | 111 + .../tools/detail/polynomial_horner2_14.hpp | 118 + .../tools/detail/polynomial_horner2_15.hpp | 125 + .../tools/detail/polynomial_horner2_16.hpp | 132 + .../tools/detail/polynomial_horner2_17.hpp | 139 + .../tools/detail/polynomial_horner2_18.hpp | 146 + .../tools/detail/polynomial_horner2_19.hpp | 153 + .../tools/detail/polynomial_horner2_2.hpp | 48 + .../tools/detail/polynomial_horner2_20.hpp | 160 + .../tools/detail/polynomial_horner2_3.hpp | 48 + .../tools/detail/polynomial_horner2_4.hpp | 48 + .../tools/detail/polynomial_horner2_5.hpp | 55 + .../tools/detail/polynomial_horner2_6.hpp | 62 + .../tools/detail/polynomial_horner2_7.hpp | 69 + .../tools/detail/polynomial_horner2_8.hpp | 76 + .../tools/detail/polynomial_horner2_9.hpp | 83 + .../tools/detail/polynomial_horner3_10.hpp | 156 + .../tools/detail/polynomial_horner3_11.hpp | 181 + .../tools/detail/polynomial_horner3_12.hpp | 208 + .../tools/detail/polynomial_horner3_13.hpp | 237 + .../tools/detail/polynomial_horner3_14.hpp | 268 + .../tools/detail/polynomial_horner3_15.hpp | 301 + .../tools/detail/polynomial_horner3_16.hpp | 336 + .../tools/detail/polynomial_horner3_17.hpp | 373 + .../tools/detail/polynomial_horner3_18.hpp | 412 + .../tools/detail/polynomial_horner3_19.hpp | 453 + .../tools/detail/polynomial_horner3_2.hpp | 48 + .../tools/detail/polynomial_horner3_20.hpp | 496 + .../tools/detail/polynomial_horner3_3.hpp | 48 + .../tools/detail/polynomial_horner3_4.hpp | 48 + .../tools/detail/polynomial_horner3_5.hpp | 61 + .../tools/detail/polynomial_horner3_6.hpp | 76 + .../tools/detail/polynomial_horner3_7.hpp | 93 + .../tools/detail/polynomial_horner3_8.hpp | 112 + .../tools/detail/polynomial_horner3_9.hpp | 133 + .../math/tools/detail/rational_horner1_10.hpp | 138 + .../math/tools/detail/rational_horner1_11.hpp | 150 + .../math/tools/detail/rational_horner1_12.hpp | 162 + .../math/tools/detail/rational_horner1_13.hpp | 174 + .../math/tools/detail/rational_horner1_14.hpp | 186 + .../math/tools/detail/rational_horner1_15.hpp | 198 + .../math/tools/detail/rational_horner1_16.hpp | 210 + .../math/tools/detail/rational_horner1_17.hpp | 222 + .../math/tools/detail/rational_horner1_18.hpp | 234 + .../math/tools/detail/rational_horner1_19.hpp | 246 + .../math/tools/detail/rational_horner1_2.hpp | 42 + .../math/tools/detail/rational_horner1_20.hpp | 258 + .../math/tools/detail/rational_horner1_3.hpp | 54 + .../math/tools/detail/rational_horner1_4.hpp | 66 + .../math/tools/detail/rational_horner1_5.hpp | 78 + .../math/tools/detail/rational_horner1_6.hpp | 90 + .../math/tools/detail/rational_horner1_7.hpp | 102 + .../math/tools/detail/rational_horner1_8.hpp | 114 + .../math/tools/detail/rational_horner1_9.hpp | 126 + .../math/tools/detail/rational_horner2_10.hpp | 144 + .../math/tools/detail/rational_horner2_11.hpp | 160 + .../math/tools/detail/rational_horner2_12.hpp | 176 + .../math/tools/detail/rational_horner2_13.hpp | 192 + .../math/tools/detail/rational_horner2_14.hpp | 208 + .../math/tools/detail/rational_horner2_15.hpp | 224 + .../math/tools/detail/rational_horner2_16.hpp | 240 + .../math/tools/detail/rational_horner2_17.hpp | 256 + .../math/tools/detail/rational_horner2_18.hpp | 272 + .../math/tools/detail/rational_horner2_19.hpp | 288 + .../math/tools/detail/rational_horner2_2.hpp | 48 + .../math/tools/detail/rational_horner2_20.hpp | 304 + .../math/tools/detail/rational_horner2_3.hpp | 48 + .../math/tools/detail/rational_horner2_4.hpp | 48 + .../math/tools/detail/rational_horner2_5.hpp | 64 + .../math/tools/detail/rational_horner2_6.hpp | 80 + .../math/tools/detail/rational_horner2_7.hpp | 96 + .../math/tools/detail/rational_horner2_8.hpp | 112 + .../math/tools/detail/rational_horner2_9.hpp | 128 + .../math/tools/detail/rational_horner3_10.hpp | 396 + .../math/tools/detail/rational_horner3_11.hpp | 482 + .../math/tools/detail/rational_horner3_12.hpp | 576 + .../math/tools/detail/rational_horner3_13.hpp | 678 + .../math/tools/detail/rational_horner3_14.hpp | 788 + .../math/tools/detail/rational_horner3_15.hpp | 906 ++ .../math/tools/detail/rational_horner3_16.hpp | 1032 ++ .../math/tools/detail/rational_horner3_17.hpp | 1166 ++ .../math/tools/detail/rational_horner3_18.hpp | 1308 ++ .../math/tools/detail/rational_horner3_19.hpp | 1458 ++ .../math/tools/detail/rational_horner3_2.hpp | 48 + .../math/tools/detail/rational_horner3_20.hpp | 1616 +++ .../math/tools/detail/rational_horner3_3.hpp | 48 + .../math/tools/detail/rational_horner3_4.hpp | 48 + .../math/tools/detail/rational_horner3_5.hpp | 86 + .../math/tools/detail/rational_horner3_6.hpp | 132 + .../math/tools/detail/rational_horner3_7.hpp | 186 + .../math/tools/detail/rational_horner3_8.hpp | 248 + .../math/tools/detail/rational_horner3_9.hpp | 318 + thirdparty/boost/math/tools/fraction.hpp | 259 + thirdparty/boost/math/tools/minima.hpp | 147 + thirdparty/boost/math/tools/polynomial.hpp | 234 + thirdparty/boost/math/tools/precision.hpp | 235 + thirdparty/boost/math/tools/promotion.hpp | 120 + thirdparty/boost/math/tools/rational.hpp | 206 + thirdparty/boost/math/tools/real_cast.hpp | 24 + thirdparty/boost/math/tools/remez.hpp | 662 + thirdparty/boost/math/tools/roots.hpp | 522 + thirdparty/boost/math/tools/series.hpp | 171 + thirdparty/boost/math/tools/solve.hpp | 74 + thirdparty/boost/math/tools/stats.hpp | 83 + thirdparty/boost/math/tools/test.hpp | 242 + thirdparty/boost/math/tools/test_data.hpp | 755 + thirdparty/boost/math/tools/toms748_solve.hpp | 579 + thirdparty/boost/math/tools/traits.hpp | 106 + thirdparty/boost/math/tools/user.hpp | 92 + thirdparty/boost/math/tools/workaround.hpp | 33 + thirdparty/boost/math_fwd.hpp | 101 + thirdparty/boost/mem_fn.hpp | 389 + thirdparty/boost/mpi.hpp | 35 + thirdparty/boost/mpi/allocator.hpp | 210 + thirdparty/boost/mpi/collectives.hpp | 545 + .../boost/mpi/collectives/all_gather.hpp | 85 + .../boost/mpi/collectives/all_reduce.hpp | 102 + .../boost/mpi/collectives/all_to_all.hpp | 153 + .../boost/mpi/collectives/broadcast.hpp | 145 + thirdparty/boost/mpi/collectives/gather.hpp | 147 + thirdparty/boost/mpi/collectives/reduce.hpp | 357 + thirdparty/boost/mpi/collectives/scan.hpp | 168 + thirdparty/boost/mpi/collectives/scatter.hpp | 161 + thirdparty/boost/mpi/collectives_fwd.hpp | 23 + thirdparty/boost/mpi/communicator.hpp | 1725 +++ thirdparty/boost/mpi/config.hpp | 102 + thirdparty/boost/mpi/datatype.hpp | 300 + thirdparty/boost/mpi/datatype_fwd.hpp | 32 + thirdparty/boost/mpi/detail/broadcast_sc.hpp | 41 + .../boost/mpi/detail/communicator_sc.hpp | 96 + .../boost/mpi/detail/computation_tree.hpp | 86 + .../boost/mpi/detail/content_oarchive.hpp | 65 + .../boost/mpi/detail/forward_iprimitive.hpp | 72 + .../boost/mpi/detail/forward_oprimitive.hpp | 73 + .../mpi/detail/forward_skeleton_iarchive.hpp | 78 + .../mpi/detail/forward_skeleton_oarchive.hpp | 79 + .../boost/mpi/detail/ignore_iprimitive.hpp | 61 + .../boost/mpi/detail/ignore_oprimitive.hpp | 62 + .../mpi/detail/ignore_skeleton_oarchive.hpp | 70 + .../boost/mpi/detail/mpi_datatype_cache.hpp | 110 + .../mpi/detail/mpi_datatype_oarchive.hpp | 47 + .../mpi/detail/mpi_datatype_primitive.hpp | 128 + .../boost/mpi/detail/packed_iprimitive.hpp | 119 + .../boost/mpi/detail/packed_oprimitive.hpp | 115 + .../boost/mpi/detail/point_to_point.hpp | 52 + .../mpi/detail/text_skeleton_oarchive.hpp | 50 + thirdparty/boost/mpi/environment.hpp | 201 + thirdparty/boost/mpi/exception.hpp | 104 + thirdparty/boost/mpi/graph_communicator.hpp | 575 + thirdparty/boost/mpi/group.hpp | 340 + thirdparty/boost/mpi/intercommunicator.hpp | 165 + thirdparty/boost/mpi/nonblocking.hpp | 732 + thirdparty/boost/mpi/operations.hpp | 322 + thirdparty/boost/mpi/packed_iarchive.hpp | 94 + thirdparty/boost/mpi/packed_oarchive.hpp | 89 + thirdparty/boost/mpi/python.hpp | 79 + thirdparty/boost/mpi/python/config.hpp | 47 + thirdparty/boost/mpi/python/serialize.hpp | 539 + .../boost/mpi/python/skeleton_and_content.hpp | 209 + thirdparty/boost/mpi/request.hpp | 102 + thirdparty/boost/mpi/skeleton_and_content.hpp | 388 + .../boost/mpi/skeleton_and_content_fwd.hpp | 31 + thirdparty/boost/mpi/status.hpp | 105 + thirdparty/boost/mpi/timer.hpp | 91 + thirdparty/boost/mpl/O1_size.hpp | 40 + thirdparty/boost/mpl/O1_size_fwd.hpp | 24 + thirdparty/boost/mpl/accumulate.hpp | 39 + thirdparty/boost/mpl/advance.hpp | 76 + thirdparty/boost/mpl/advance_fwd.hpp | 28 + thirdparty/boost/mpl/alias.hpp | 21 + thirdparty/boost/mpl/always.hpp | 39 + thirdparty/boost/mpl/and.hpp | 60 + thirdparty/boost/mpl/apply.hpp | 225 + thirdparty/boost/mpl/apply_fwd.hpp | 107 + thirdparty/boost/mpl/apply_wrap.hpp | 200 + thirdparty/boost/mpl/arg.hpp | 131 + thirdparty/boost/mpl/arg_fwd.hpp | 28 + thirdparty/boost/mpl/arithmetic.hpp | 25 + thirdparty/boost/mpl/as_sequence.hpp | 38 + thirdparty/boost/mpl/assert.hpp | 370 + thirdparty/boost/mpl/at.hpp | 52 + thirdparty/boost/mpl/at_fwd.hpp | 24 + thirdparty/boost/mpl/aux_/O1_size_impl.hpp | 87 + thirdparty/boost/mpl/aux_/adl_barrier.hpp | 48 + .../boost/mpl/aux_/advance_backward.hpp | 124 + thirdparty/boost/mpl/aux_/advance_forward.hpp | 123 + thirdparty/boost/mpl/aux_/apply_1st.hpp | 35 + thirdparty/boost/mpl/aux_/arg_typedef.hpp | 31 + thirdparty/boost/mpl/aux_/arithmetic_op.hpp | 92 + thirdparty/boost/mpl/aux_/arity.hpp | 39 + thirdparty/boost/mpl/aux_/arity_spec.hpp | 67 + thirdparty/boost/mpl/aux_/at_impl.hpp | 45 + thirdparty/boost/mpl/aux_/back_impl.hpp | 43 + thirdparty/boost/mpl/aux_/basic_bind.hpp | 21 + thirdparty/boost/mpl/aux_/begin_end_impl.hpp | 101 + thirdparty/boost/mpl/aux_/clear_impl.hpp | 35 + .../boost/mpl/aux_/common_name_wknd.hpp | 34 + thirdparty/boost/mpl/aux_/comparison_op.hpp | 83 + thirdparty/boost/mpl/aux_/config/adl.hpp | 40 + thirdparty/boost/mpl/aux_/config/arrays.hpp | 30 + thirdparty/boost/mpl/aux_/config/bind.hpp | 33 + thirdparty/boost/mpl/aux_/config/compiler.hpp | 64 + thirdparty/boost/mpl/aux_/config/ctps.hpp | 30 + .../boost/mpl/aux_/config/dependent_nttp.hpp | 35 + .../mpl/aux_/config/dmc_ambiguous_ctps.hpp | 27 + thirdparty/boost/mpl/aux_/config/dtp.hpp | 46 + thirdparty/boost/mpl/aux_/config/eti.hpp | 47 + .../boost/mpl/aux_/config/forwarding.hpp | 27 + thirdparty/boost/mpl/aux_/config/gcc.hpp | 23 + .../boost/mpl/aux_/config/has_apply.hpp | 32 + thirdparty/boost/mpl/aux_/config/has_xxx.hpp | 33 + thirdparty/boost/mpl/aux_/config/integral.hpp | 38 + thirdparty/boost/mpl/aux_/config/intel.hpp | 21 + thirdparty/boost/mpl/aux_/config/lambda.hpp | 32 + thirdparty/boost/mpl/aux_/config/msvc.hpp | 21 + .../boost/mpl/aux_/config/msvc_typename.hpp | 26 + thirdparty/boost/mpl/aux_/config/nttp.hpp | 41 + .../boost/mpl/aux_/config/operators.hpp | 33 + .../mpl/aux_/config/overload_resolution.hpp | 29 + .../boost/mpl/aux_/config/pp_counter.hpp | 26 + .../boost/mpl/aux_/config/preprocessor.hpp | 39 + .../boost/mpl/aux_/config/static_constant.hpp | 25 + thirdparty/boost/mpl/aux_/config/ttp.hpp | 41 + thirdparty/boost/mpl/aux_/config/typeof.hpp | 38 + .../mpl/aux_/config/use_preprocessed.hpp | 19 + .../boost/mpl/aux_/config/workaround.hpp | 19 + thirdparty/boost/mpl/aux_/contains_impl.hpp | 61 + thirdparty/boost/mpl/aux_/count_args.hpp | 105 + thirdparty/boost/mpl/aux_/count_impl.hpp | 44 + thirdparty/boost/mpl/aux_/empty_impl.hpp | 43 + thirdparty/boost/mpl/aux_/erase_impl.hpp | 69 + thirdparty/boost/mpl/aux_/erase_key_impl.hpp | 32 + thirdparty/boost/mpl/aux_/filter_iter.hpp | 140 + thirdparty/boost/mpl/aux_/find_if_pred.hpp | 31 + thirdparty/boost/mpl/aux_/fold_impl.hpp | 43 + thirdparty/boost/mpl/aux_/fold_impl_body.hpp | 365 + thirdparty/boost/mpl/aux_/fold_op.hpp | 37 + thirdparty/boost/mpl/aux_/fold_pred.hpp | 37 + thirdparty/boost/mpl/aux_/front_impl.hpp | 41 + thirdparty/boost/mpl/aux_/full_lambda.hpp | 350 + thirdparty/boost/mpl/aux_/has_apply.hpp | 32 + thirdparty/boost/mpl/aux_/has_begin.hpp | 23 + thirdparty/boost/mpl/aux_/has_key_impl.hpp | 34 + thirdparty/boost/mpl/aux_/has_rebind.hpp | 99 + thirdparty/boost/mpl/aux_/has_size.hpp | 23 + thirdparty/boost/mpl/aux_/has_tag.hpp | 23 + thirdparty/boost/mpl/aux_/has_type.hpp | 23 + .../boost/mpl/aux_/include_preprocessed.hpp | 42 + thirdparty/boost/mpl/aux_/insert_impl.hpp | 68 + .../boost/mpl/aux_/insert_range_impl.hpp | 77 + .../boost/mpl/aux_/inserter_algorithm.hpp | 159 + .../boost/mpl/aux_/integral_wrapper.hpp | 93 + thirdparty/boost/mpl/aux_/is_msvc_eti_arg.hpp | 64 + thirdparty/boost/mpl/aux_/iter_apply.hpp | 47 + .../boost/mpl/aux_/iter_fold_if_impl.hpp | 210 + thirdparty/boost/mpl/aux_/iter_fold_impl.hpp | 42 + thirdparty/boost/mpl/aux_/iter_push_front.hpp | 36 + thirdparty/boost/mpl/aux_/joint_iter.hpp | 120 + .../boost/mpl/aux_/lambda_arity_param.hpp | 25 + thirdparty/boost/mpl/aux_/lambda_no_ctps.hpp | 193 + thirdparty/boost/mpl/aux_/lambda_spec.hpp | 49 + thirdparty/boost/mpl/aux_/lambda_support.hpp | 169 + thirdparty/boost/mpl/aux_/largest_int.hpp | 63 + thirdparty/boost/mpl/aux_/logical_op.hpp | 165 + thirdparty/boost/mpl/aux_/msvc_dtw.hpp | 68 + thirdparty/boost/mpl/aux_/msvc_eti_base.hpp | 77 + thirdparty/boost/mpl/aux_/msvc_is_class.hpp | 58 + thirdparty/boost/mpl/aux_/msvc_never_true.hpp | 34 + thirdparty/boost/mpl/aux_/msvc_type.hpp | 62 + thirdparty/boost/mpl/aux_/na.hpp | 95 + thirdparty/boost/mpl/aux_/na_assert.hpp | 34 + thirdparty/boost/mpl/aux_/na_fwd.hpp | 31 + thirdparty/boost/mpl/aux_/na_spec.hpp | 175 + .../boost/mpl/aux_/nested_type_wknd.hpp | 48 + thirdparty/boost/mpl/aux_/nttp_decl.hpp | 35 + .../boost/mpl/aux_/numeric_cast_utils.hpp | 77 + thirdparty/boost/mpl/aux_/numeric_op.hpp | 311 + thirdparty/boost/mpl/aux_/order_impl.hpp | 76 + thirdparty/boost/mpl/aux_/overload_names.hpp | 48 + thirdparty/boost/mpl/aux_/partition_op.hpp | 58 + thirdparty/boost/mpl/aux_/pop_back_impl.hpp | 34 + thirdparty/boost/mpl/aux_/pop_front_impl.hpp | 44 + .../preprocessed/bcc/advance_backward.hpp | 97 + .../aux_/preprocessed/bcc/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/bcc/and.hpp | 69 + .../boost/mpl/aux_/preprocessed/bcc/apply.hpp | 169 + .../mpl/aux_/preprocessed/bcc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/bcc/apply_wrap.hpp | 456 + .../boost/mpl/aux_/preprocessed/bcc/arg.hpp | 117 + .../mpl/aux_/preprocessed/bcc/basic_bind.hpp | 300 + .../boost/mpl/aux_/preprocessed/bcc/bind.hpp | 397 + .../mpl/aux_/preprocessed/bcc/bind_fwd.hpp | 46 + .../mpl/aux_/preprocessed/bcc/bitand.hpp | 147 + .../boost/mpl/aux_/preprocessed/bcc/bitor.hpp | 147 + .../mpl/aux_/preprocessed/bcc/bitxor.hpp | 147 + .../boost/mpl/aux_/preprocessed/bcc/deque.hpp | 323 + .../mpl/aux_/preprocessed/bcc/divides.hpp | 146 + .../mpl/aux_/preprocessed/bcc/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/bcc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/bcc/full_lambda.hpp | 558 + .../mpl/aux_/preprocessed/bcc/greater.hpp | 94 + .../aux_/preprocessed/bcc/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/bcc/inherit.hpp | 139 + .../preprocessed/bcc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/bcc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/bcc/lambda_no_ctps.hpp | 229 + .../boost/mpl/aux_/preprocessed/bcc/less.hpp | 94 + .../mpl/aux_/preprocessed/bcc/less_equal.hpp | 94 + .../boost/mpl/aux_/preprocessed/bcc/list.hpp | 323 + .../mpl/aux_/preprocessed/bcc/list_c.hpp | 328 + .../boost/mpl/aux_/preprocessed/bcc/map.hpp | 323 + .../boost/mpl/aux_/preprocessed/bcc/minus.hpp | 146 + .../mpl/aux_/preprocessed/bcc/modulus.hpp | 101 + .../aux_/preprocessed/bcc/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/bcc/or.hpp | 69 + .../aux_/preprocessed/bcc/placeholders.hpp | 105 + .../boost/mpl/aux_/preprocessed/bcc/plus.hpp | 146 + .../boost/mpl/aux_/preprocessed/bcc/quote.hpp | 11 + .../preprocessed/bcc/reverse_fold_impl.hpp | 295 + .../bcc/reverse_iter_fold_impl.hpp | 295 + .../boost/mpl/aux_/preprocessed/bcc/set.hpp | 323 + .../boost/mpl/aux_/preprocessed/bcc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/bcc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/bcc/shift_right.hpp | 99 + .../aux_/preprocessed/bcc/template_arity.hpp | 40 + .../boost/mpl/aux_/preprocessed/bcc/times.hpp | 146 + .../mpl/aux_/preprocessed/bcc/unpack_args.hpp | 97 + .../mpl/aux_/preprocessed/bcc/vector.hpp | 323 + .../mpl/aux_/preprocessed/bcc/vector_c.hpp | 309 + .../preprocessed/bcc551/advance_backward.hpp | 97 + .../preprocessed/bcc551/advance_forward.hpp | 97 + .../mpl/aux_/preprocessed/bcc551/and.hpp | 69 + .../mpl/aux_/preprocessed/bcc551/apply.hpp | 169 + .../aux_/preprocessed/bcc551/apply_fwd.hpp | 52 + .../aux_/preprocessed/bcc551/apply_wrap.hpp | 456 + .../mpl/aux_/preprocessed/bcc551/arg.hpp | 123 + .../aux_/preprocessed/bcc551/basic_bind.hpp | 306 + .../mpl/aux_/preprocessed/bcc551/bind.hpp | 403 + .../mpl/aux_/preprocessed/bcc551/bind_fwd.hpp | 46 + .../mpl/aux_/preprocessed/bcc551/bitand.hpp | 147 + .../mpl/aux_/preprocessed/bcc551/bitor.hpp | 147 + .../mpl/aux_/preprocessed/bcc551/bitxor.hpp | 147 + .../mpl/aux_/preprocessed/bcc551/deque.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/divides.hpp | 146 + .../mpl/aux_/preprocessed/bcc551/equal_to.hpp | 94 + .../aux_/preprocessed/bcc551/fold_impl.hpp | 180 + .../aux_/preprocessed/bcc551/full_lambda.hpp | 558 + .../mpl/aux_/preprocessed/bcc551/greater.hpp | 94 + .../preprocessed/bcc551/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/bcc551/inherit.hpp | 141 + .../preprocessed/bcc551/iter_fold_if_impl.hpp | 133 + .../preprocessed/bcc551/iter_fold_impl.hpp | 180 + .../preprocessed/bcc551/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/bcc551/less.hpp | 94 + .../aux_/preprocessed/bcc551/less_equal.hpp | 94 + .../mpl/aux_/preprocessed/bcc551/list.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/list_c.hpp | 328 + .../mpl/aux_/preprocessed/bcc551/map.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/minus.hpp | 146 + .../mpl/aux_/preprocessed/bcc551/modulus.hpp | 101 + .../aux_/preprocessed/bcc551/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/bcc551/or.hpp | 69 + .../aux_/preprocessed/bcc551/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/bcc551/plus.hpp | 146 + .../mpl/aux_/preprocessed/bcc551/quote.hpp | 11 + .../preprocessed/bcc551/reverse_fold_impl.hpp | 295 + .../bcc551/reverse_iter_fold_impl.hpp | 295 + .../mpl/aux_/preprocessed/bcc551/set.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/set_c.hpp | 328 + .../aux_/preprocessed/bcc551/shift_left.hpp | 99 + .../aux_/preprocessed/bcc551/shift_right.hpp | 99 + .../preprocessed/bcc551/template_arity.hpp | 40 + .../mpl/aux_/preprocessed/bcc551/times.hpp | 146 + .../aux_/preprocessed/bcc551/unpack_args.hpp | 97 + .../mpl/aux_/preprocessed/bcc551/vector.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/vector_c.hpp | 309 + .../preprocessed/dmc/advance_backward.hpp | 97 + .../aux_/preprocessed/dmc/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/dmc/and.hpp | 69 + .../boost/mpl/aux_/preprocessed/dmc/apply.hpp | 169 + .../mpl/aux_/preprocessed/dmc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/dmc/apply_wrap.hpp | 84 + .../boost/mpl/aux_/preprocessed/dmc/arg.hpp | 123 + .../mpl/aux_/preprocessed/dmc/basic_bind.hpp | 406 + .../boost/mpl/aux_/preprocessed/dmc/bind.hpp | 515 + .../mpl/aux_/preprocessed/dmc/bind_fwd.hpp | 53 + .../mpl/aux_/preprocessed/dmc/bitand.hpp | 147 + .../boost/mpl/aux_/preprocessed/dmc/bitor.hpp | 147 + .../mpl/aux_/preprocessed/dmc/bitxor.hpp | 147 + .../boost/mpl/aux_/preprocessed/dmc/deque.hpp | 323 + .../mpl/aux_/preprocessed/dmc/divides.hpp | 146 + .../mpl/aux_/preprocessed/dmc/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/dmc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/dmc/full_lambda.hpp | 536 + .../mpl/aux_/preprocessed/dmc/greater.hpp | 94 + .../aux_/preprocessed/dmc/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/dmc/inherit.hpp | 141 + .../preprocessed/dmc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/dmc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/dmc/lambda_no_ctps.hpp | 229 + .../boost/mpl/aux_/preprocessed/dmc/less.hpp | 94 + .../mpl/aux_/preprocessed/dmc/less_equal.hpp | 94 + .../boost/mpl/aux_/preprocessed/dmc/list.hpp | 323 + .../mpl/aux_/preprocessed/dmc/list_c.hpp | 328 + .../boost/mpl/aux_/preprocessed/dmc/map.hpp | 323 + .../boost/mpl/aux_/preprocessed/dmc/minus.hpp | 146 + .../mpl/aux_/preprocessed/dmc/modulus.hpp | 101 + .../aux_/preprocessed/dmc/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/dmc/or.hpp | 69 + .../aux_/preprocessed/dmc/placeholders.hpp | 105 + .../boost/mpl/aux_/preprocessed/dmc/plus.hpp | 146 + .../boost/mpl/aux_/preprocessed/dmc/quote.hpp | 123 + .../preprocessed/dmc/reverse_fold_impl.hpp | 231 + .../dmc/reverse_iter_fold_impl.hpp | 231 + .../boost/mpl/aux_/preprocessed/dmc/set.hpp | 323 + .../boost/mpl/aux_/preprocessed/dmc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/dmc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/dmc/shift_right.hpp | 99 + .../aux_/preprocessed/dmc/template_arity.hpp | 11 + .../boost/mpl/aux_/preprocessed/dmc/times.hpp | 146 + .../mpl/aux_/preprocessed/dmc/unpack_args.hpp | 94 + .../mpl/aux_/preprocessed/dmc/vector.hpp | 323 + .../mpl/aux_/preprocessed/dmc/vector_c.hpp | 309 + .../preprocessed/gcc/advance_backward.hpp | 97 + .../aux_/preprocessed/gcc/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/gcc/and.hpp | 69 + .../boost/mpl/aux_/preprocessed/gcc/apply.hpp | 169 + .../mpl/aux_/preprocessed/gcc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/gcc/apply_wrap.hpp | 84 + .../boost/mpl/aux_/preprocessed/gcc/arg.hpp | 123 + .../mpl/aux_/preprocessed/gcc/basic_bind.hpp | 440 + .../boost/mpl/aux_/preprocessed/gcc/bind.hpp | 561 + .../mpl/aux_/preprocessed/gcc/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/gcc/bitand.hpp | 147 + .../boost/mpl/aux_/preprocessed/gcc/bitor.hpp | 147 + .../mpl/aux_/preprocessed/gcc/bitxor.hpp | 147 + .../boost/mpl/aux_/preprocessed/gcc/deque.hpp | 323 + .../mpl/aux_/preprocessed/gcc/divides.hpp | 146 + .../mpl/aux_/preprocessed/gcc/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/gcc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/gcc/full_lambda.hpp | 558 + .../mpl/aux_/preprocessed/gcc/greater.hpp | 94 + .../aux_/preprocessed/gcc/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/gcc/inherit.hpp | 141 + .../preprocessed/gcc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/gcc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/gcc/lambda_no_ctps.hpp | 229 + .../boost/mpl/aux_/preprocessed/gcc/less.hpp | 94 + .../mpl/aux_/preprocessed/gcc/less_equal.hpp | 94 + .../boost/mpl/aux_/preprocessed/gcc/list.hpp | 323 + .../mpl/aux_/preprocessed/gcc/list_c.hpp | 328 + .../boost/mpl/aux_/preprocessed/gcc/map.hpp | 323 + .../boost/mpl/aux_/preprocessed/gcc/minus.hpp | 146 + .../mpl/aux_/preprocessed/gcc/modulus.hpp | 101 + .../aux_/preprocessed/gcc/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/gcc/or.hpp | 69 + .../aux_/preprocessed/gcc/placeholders.hpp | 105 + .../boost/mpl/aux_/preprocessed/gcc/plus.hpp | 146 + .../boost/mpl/aux_/preprocessed/gcc/quote.hpp | 123 + .../preprocessed/gcc/reverse_fold_impl.hpp | 231 + .../gcc/reverse_iter_fold_impl.hpp | 231 + .../boost/mpl/aux_/preprocessed/gcc/set.hpp | 323 + .../boost/mpl/aux_/preprocessed/gcc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/gcc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/gcc/shift_right.hpp | 99 + .../aux_/preprocessed/gcc/template_arity.hpp | 101 + .../boost/mpl/aux_/preprocessed/gcc/times.hpp | 146 + .../mpl/aux_/preprocessed/gcc/unpack_args.hpp | 94 + .../mpl/aux_/preprocessed/gcc/vector.hpp | 323 + .../mpl/aux_/preprocessed/gcc/vector_c.hpp | 309 + .../preprocessed/msvc60/advance_backward.hpp | 132 + .../preprocessed/msvc60/advance_forward.hpp | 132 + .../mpl/aux_/preprocessed/msvc60/and.hpp | 73 + .../mpl/aux_/preprocessed/msvc60/apply.hpp | 166 + .../aux_/preprocessed/msvc60/apply_fwd.hpp | 46 + .../aux_/preprocessed/msvc60/apply_wrap.hpp | 247 + .../mpl/aux_/preprocessed/msvc60/arg.hpp | 123 + .../aux_/preprocessed/msvc60/basic_bind.hpp | 328 + .../mpl/aux_/preprocessed/msvc60/bind.hpp | 432 + .../mpl/aux_/preprocessed/msvc60/bind_fwd.hpp | 46 + .../mpl/aux_/preprocessed/msvc60/bitand.hpp | 149 + .../mpl/aux_/preprocessed/msvc60/bitor.hpp | 149 + .../mpl/aux_/preprocessed/msvc60/bitxor.hpp | 149 + .../mpl/aux_/preprocessed/msvc60/deque.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/divides.hpp | 148 + .../mpl/aux_/preprocessed/msvc60/equal_to.hpp | 102 + .../aux_/preprocessed/msvc60/fold_impl.hpp | 293 + .../aux_/preprocessed/msvc60/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/msvc60/greater.hpp | 102 + .../preprocessed/msvc60/greater_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc60/inherit.hpp | 166 + .../preprocessed/msvc60/iter_fold_if_impl.hpp | 133 + .../preprocessed/msvc60/iter_fold_impl.hpp | 293 + .../preprocessed/msvc60/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/msvc60/less.hpp | 102 + .../aux_/preprocessed/msvc60/less_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc60/list.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/list_c.hpp | 534 + .../mpl/aux_/preprocessed/msvc60/map.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/minus.hpp | 148 + .../mpl/aux_/preprocessed/msvc60/modulus.hpp | 115 + .../aux_/preprocessed/msvc60/not_equal_to.hpp | 102 + .../boost/mpl/aux_/preprocessed/msvc60/or.hpp | 73 + .../aux_/preprocessed/msvc60/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/msvc60/plus.hpp | 148 + .../mpl/aux_/preprocessed/msvc60/quote.hpp | 11 + .../preprocessed/msvc60/reverse_fold_impl.hpp | 343 + .../msvc60/reverse_iter_fold_impl.hpp | 343 + .../mpl/aux_/preprocessed/msvc60/set.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/set_c.hpp | 534 + .../aux_/preprocessed/msvc60/shift_left.hpp | 114 + .../aux_/preprocessed/msvc60/shift_right.hpp | 114 + .../preprocessed/msvc60/template_arity.hpp | 46 + .../mpl/aux_/preprocessed/msvc60/times.hpp | 148 + .../aux_/preprocessed/msvc60/unpack_args.hpp | 109 + .../mpl/aux_/preprocessed/msvc60/vector.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/vector_c.hpp | 534 + .../preprocessed/msvc70/advance_backward.hpp | 97 + .../preprocessed/msvc70/advance_forward.hpp | 97 + .../mpl/aux_/preprocessed/msvc70/and.hpp | 71 + .../mpl/aux_/preprocessed/msvc70/apply.hpp | 160 + .../aux_/preprocessed/msvc70/apply_fwd.hpp | 46 + .../aux_/preprocessed/msvc70/apply_wrap.hpp | 138 + .../mpl/aux_/preprocessed/msvc70/arg.hpp | 123 + .../aux_/preprocessed/msvc70/basic_bind.hpp | 328 + .../mpl/aux_/preprocessed/msvc70/bind.hpp | 432 + .../mpl/aux_/preprocessed/msvc70/bind_fwd.hpp | 46 + .../mpl/aux_/preprocessed/msvc70/bitand.hpp | 151 + .../mpl/aux_/preprocessed/msvc70/bitor.hpp | 151 + .../mpl/aux_/preprocessed/msvc70/bitxor.hpp | 151 + .../mpl/aux_/preprocessed/msvc70/deque.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/divides.hpp | 150 + .../mpl/aux_/preprocessed/msvc70/equal_to.hpp | 102 + .../aux_/preprocessed/msvc70/fold_impl.hpp | 245 + .../aux_/preprocessed/msvc70/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/msvc70/greater.hpp | 102 + .../preprocessed/msvc70/greater_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc70/inherit.hpp | 166 + .../preprocessed/msvc70/iter_fold_if_impl.hpp | 133 + .../preprocessed/msvc70/iter_fold_impl.hpp | 245 + .../preprocessed/msvc70/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/msvc70/less.hpp | 102 + .../aux_/preprocessed/msvc70/less_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc70/list.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/list_c.hpp | 534 + .../mpl/aux_/preprocessed/msvc70/map.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/minus.hpp | 150 + .../mpl/aux_/preprocessed/msvc70/modulus.hpp | 115 + .../aux_/preprocessed/msvc70/not_equal_to.hpp | 102 + .../boost/mpl/aux_/preprocessed/msvc70/or.hpp | 71 + .../aux_/preprocessed/msvc70/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/msvc70/plus.hpp | 150 + .../mpl/aux_/preprocessed/msvc70/quote.hpp | 116 + .../preprocessed/msvc70/reverse_fold_impl.hpp | 295 + .../msvc70/reverse_iter_fold_impl.hpp | 295 + .../mpl/aux_/preprocessed/msvc70/set.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/set_c.hpp | 534 + .../aux_/preprocessed/msvc70/shift_left.hpp | 114 + .../aux_/preprocessed/msvc70/shift_right.hpp | 114 + .../preprocessed/msvc70/template_arity.hpp | 46 + .../mpl/aux_/preprocessed/msvc70/times.hpp | 150 + .../aux_/preprocessed/msvc70/unpack_args.hpp | 109 + .../mpl/aux_/preprocessed/msvc70/vector.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/vector_c.hpp | 534 + .../preprocessed/mwcw/advance_backward.hpp | 97 + .../preprocessed/mwcw/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/mwcw/and.hpp | 69 + .../mpl/aux_/preprocessed/mwcw/apply.hpp | 169 + .../mpl/aux_/preprocessed/mwcw/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/mwcw/apply_wrap.hpp | 456 + .../boost/mpl/aux_/preprocessed/mwcw/arg.hpp | 123 + .../mpl/aux_/preprocessed/mwcw/basic_bind.hpp | 440 + .../boost/mpl/aux_/preprocessed/mwcw/bind.hpp | 561 + .../mpl/aux_/preprocessed/mwcw/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/mwcw/bitand.hpp | 147 + .../mpl/aux_/preprocessed/mwcw/bitor.hpp | 147 + .../mpl/aux_/preprocessed/mwcw/bitxor.hpp | 147 + .../mpl/aux_/preprocessed/mwcw/deque.hpp | 323 + .../mpl/aux_/preprocessed/mwcw/divides.hpp | 146 + .../mpl/aux_/preprocessed/mwcw/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/fold_impl.hpp | 180 + .../aux_/preprocessed/mwcw/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/mwcw/greater.hpp | 94 + .../aux_/preprocessed/mwcw/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/inherit.hpp | 141 + .../preprocessed/mwcw/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/mwcw/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/mwcw/lambda_no_ctps.hpp | 229 + .../boost/mpl/aux_/preprocessed/mwcw/less.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/less_equal.hpp | 94 + .../boost/mpl/aux_/preprocessed/mwcw/list.hpp | 323 + .../mpl/aux_/preprocessed/mwcw/list_c.hpp | 328 + .../boost/mpl/aux_/preprocessed/mwcw/map.hpp | 323 + .../mpl/aux_/preprocessed/mwcw/minus.hpp | 146 + .../mpl/aux_/preprocessed/mwcw/modulus.hpp | 101 + .../aux_/preprocessed/mwcw/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/mwcw/or.hpp | 69 + .../aux_/preprocessed/mwcw/placeholders.hpp | 105 + .../boost/mpl/aux_/preprocessed/mwcw/plus.hpp | 146 + .../mpl/aux_/preprocessed/mwcw/quote.hpp | 123 + .../preprocessed/mwcw/reverse_fold_impl.hpp | 231 + .../mwcw/reverse_iter_fold_impl.hpp | 231 + .../boost/mpl/aux_/preprocessed/mwcw/set.hpp | 323 + .../mpl/aux_/preprocessed/mwcw/set_c.hpp | 328 + .../mpl/aux_/preprocessed/mwcw/shift_left.hpp | 99 + .../aux_/preprocessed/mwcw/shift_right.hpp | 99 + .../aux_/preprocessed/mwcw/template_arity.hpp | 11 + .../mpl/aux_/preprocessed/mwcw/times.hpp | 146 + .../aux_/preprocessed/mwcw/unpack_args.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/vector.hpp | 323 + .../mpl/aux_/preprocessed/mwcw/vector_c.hpp | 309 + .../preprocessed/no_ctps/advance_backward.hpp | 97 + .../preprocessed/no_ctps/advance_forward.hpp | 97 + .../mpl/aux_/preprocessed/no_ctps/and.hpp | 73 + .../mpl/aux_/preprocessed/no_ctps/apply.hpp | 268 + .../aux_/preprocessed/no_ctps/apply_fwd.hpp | 50 + .../aux_/preprocessed/no_ctps/apply_wrap.hpp | 78 + .../mpl/aux_/preprocessed/no_ctps/arg.hpp | 123 + .../aux_/preprocessed/no_ctps/basic_bind.hpp | 486 + .../mpl/aux_/preprocessed/no_ctps/bind.hpp | 590 + .../aux_/preprocessed/no_ctps/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/no_ctps/bitand.hpp | 134 + .../mpl/aux_/preprocessed/no_ctps/bitor.hpp | 134 + .../mpl/aux_/preprocessed/no_ctps/bitxor.hpp | 134 + .../mpl/aux_/preprocessed/no_ctps/deque.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/divides.hpp | 133 + .../aux_/preprocessed/no_ctps/equal_to.hpp | 94 + .../aux_/preprocessed/no_ctps/fold_impl.hpp | 245 + .../aux_/preprocessed/no_ctps/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/no_ctps/greater.hpp | 94 + .../preprocessed/no_ctps/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/no_ctps/inherit.hpp | 166 + .../no_ctps/iter_fold_if_impl.hpp | 133 + .../preprocessed/no_ctps/iter_fold_impl.hpp | 245 + .../preprocessed/no_ctps/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/no_ctps/less.hpp | 94 + .../aux_/preprocessed/no_ctps/less_equal.hpp | 94 + .../mpl/aux_/preprocessed/no_ctps/list.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/list_c.hpp | 534 + .../mpl/aux_/preprocessed/no_ctps/map.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/minus.hpp | 133 + .../mpl/aux_/preprocessed/no_ctps/modulus.hpp | 101 + .../preprocessed/no_ctps/not_equal_to.hpp | 94 + .../mpl/aux_/preprocessed/no_ctps/or.hpp | 73 + .../preprocessed/no_ctps/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/no_ctps/plus.hpp | 133 + .../mpl/aux_/preprocessed/no_ctps/quote.hpp | 116 + .../no_ctps/reverse_fold_impl.hpp | 295 + .../no_ctps/reverse_iter_fold_impl.hpp | 295 + .../mpl/aux_/preprocessed/no_ctps/set.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/set_c.hpp | 534 + .../aux_/preprocessed/no_ctps/shift_left.hpp | 99 + .../aux_/preprocessed/no_ctps/shift_right.hpp | 99 + .../preprocessed/no_ctps/template_arity.hpp | 40 + .../mpl/aux_/preprocessed/no_ctps/times.hpp | 133 + .../aux_/preprocessed/no_ctps/unpack_args.hpp | 109 + .../mpl/aux_/preprocessed/no_ctps/vector.hpp | 556 + .../aux_/preprocessed/no_ctps/vector_c.hpp | 534 + .../preprocessed/no_ttp/advance_backward.hpp | 97 + .../preprocessed/no_ttp/advance_forward.hpp | 97 + .../mpl/aux_/preprocessed/no_ttp/and.hpp | 69 + .../mpl/aux_/preprocessed/no_ttp/apply.hpp | 169 + .../aux_/preprocessed/no_ttp/apply_fwd.hpp | 52 + .../aux_/preprocessed/no_ttp/apply_wrap.hpp | 84 + .../mpl/aux_/preprocessed/no_ttp/arg.hpp | 123 + .../aux_/preprocessed/no_ttp/basic_bind.hpp | 369 + .../mpl/aux_/preprocessed/no_ttp/bind.hpp | 466 + .../mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/no_ttp/bitand.hpp | 157 + .../mpl/aux_/preprocessed/no_ttp/bitor.hpp | 157 + .../mpl/aux_/preprocessed/no_ttp/bitxor.hpp | 157 + .../mpl/aux_/preprocessed/no_ttp/deque.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/divides.hpp | 156 + .../mpl/aux_/preprocessed/no_ttp/equal_to.hpp | 98 + .../aux_/preprocessed/no_ttp/fold_impl.hpp | 180 + .../aux_/preprocessed/no_ttp/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/no_ttp/greater.hpp | 98 + .../preprocessed/no_ttp/greater_equal.hpp | 98 + .../mpl/aux_/preprocessed/no_ttp/inherit.hpp | 141 + .../preprocessed/no_ttp/iter_fold_if_impl.hpp | 133 + .../preprocessed/no_ttp/iter_fold_impl.hpp | 180 + .../preprocessed/no_ttp/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/no_ttp/less.hpp | 98 + .../aux_/preprocessed/no_ttp/less_equal.hpp | 98 + .../mpl/aux_/preprocessed/no_ttp/list.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/list_c.hpp | 328 + .../mpl/aux_/preprocessed/no_ttp/map.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/minus.hpp | 156 + .../mpl/aux_/preprocessed/no_ttp/modulus.hpp | 111 + .../aux_/preprocessed/no_ttp/not_equal_to.hpp | 98 + .../boost/mpl/aux_/preprocessed/no_ttp/or.hpp | 69 + .../aux_/preprocessed/no_ttp/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/no_ttp/plus.hpp | 156 + .../mpl/aux_/preprocessed/no_ttp/quote.hpp | 11 + .../preprocessed/no_ttp/reverse_fold_impl.hpp | 231 + .../no_ttp/reverse_iter_fold_impl.hpp | 231 + .../mpl/aux_/preprocessed/no_ttp/set.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/set_c.hpp | 328 + .../aux_/preprocessed/no_ttp/shift_left.hpp | 110 + .../aux_/preprocessed/no_ttp/shift_right.hpp | 110 + .../preprocessed/no_ttp/template_arity.hpp | 40 + .../mpl/aux_/preprocessed/no_ttp/times.hpp | 156 + .../aux_/preprocessed/no_ttp/unpack_args.hpp | 94 + .../mpl/aux_/preprocessed/no_ttp/vector.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/vector_c.hpp | 309 + .../preprocessed/plain/advance_backward.hpp | 97 + .../preprocessed/plain/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/plain/and.hpp | 64 + .../mpl/aux_/preprocessed/plain/apply.hpp | 139 + .../mpl/aux_/preprocessed/plain/apply_fwd.hpp | 52 + .../aux_/preprocessed/plain/apply_wrap.hpp | 84 + .../boost/mpl/aux_/preprocessed/plain/arg.hpp | 123 + .../aux_/preprocessed/plain/basic_bind.hpp | 440 + .../mpl/aux_/preprocessed/plain/bind.hpp | 561 + .../mpl/aux_/preprocessed/plain/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/plain/bitand.hpp | 142 + .../mpl/aux_/preprocessed/plain/bitor.hpp | 142 + .../mpl/aux_/preprocessed/plain/bitxor.hpp | 142 + .../mpl/aux_/preprocessed/plain/deque.hpp | 323 + .../mpl/aux_/preprocessed/plain/divides.hpp | 141 + .../mpl/aux_/preprocessed/plain/equal_to.hpp | 92 + .../mpl/aux_/preprocessed/plain/fold_impl.hpp | 180 + .../aux_/preprocessed/plain/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/plain/greater.hpp | 92 + .../aux_/preprocessed/plain/greater_equal.hpp | 92 + .../mpl/aux_/preprocessed/plain/inherit.hpp | 125 + .../preprocessed/plain/iter_fold_if_impl.hpp | 133 + .../preprocessed/plain/iter_fold_impl.hpp | 180 + .../preprocessed/plain/lambda_no_ctps.hpp | 228 + .../mpl/aux_/preprocessed/plain/less.hpp | 92 + .../aux_/preprocessed/plain/less_equal.hpp | 92 + .../mpl/aux_/preprocessed/plain/list.hpp | 323 + .../mpl/aux_/preprocessed/plain/list_c.hpp | 328 + .../boost/mpl/aux_/preprocessed/plain/map.hpp | 323 + .../mpl/aux_/preprocessed/plain/minus.hpp | 141 + .../mpl/aux_/preprocessed/plain/modulus.hpp | 99 + .../aux_/preprocessed/plain/not_equal_to.hpp | 92 + .../boost/mpl/aux_/preprocessed/plain/or.hpp | 64 + .../aux_/preprocessed/plain/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/plain/plus.hpp | 141 + .../mpl/aux_/preprocessed/plain/quote.hpp | 123 + .../preprocessed/plain/reverse_fold_impl.hpp | 231 + .../plain/reverse_iter_fold_impl.hpp | 231 + .../boost/mpl/aux_/preprocessed/plain/set.hpp | 323 + .../mpl/aux_/preprocessed/plain/set_c.hpp | 328 + .../aux_/preprocessed/plain/shift_left.hpp | 97 + .../aux_/preprocessed/plain/shift_right.hpp | 97 + .../preprocessed/plain/template_arity.hpp | 11 + .../mpl/aux_/preprocessed/plain/times.hpp | 141 + .../aux_/preprocessed/plain/unpack_args.hpp | 94 + .../mpl/aux_/preprocessed/plain/vector.hpp | 323 + .../mpl/aux_/preprocessed/plain/vector_c.hpp | 309 + .../boost/mpl/aux_/preprocessor/add.hpp | 65 + .../mpl/aux_/preprocessor/def_params_tail.hpp | 105 + .../mpl/aux_/preprocessor/default_params.hpp | 67 + .../boost/mpl/aux_/preprocessor/enum.hpp | 62 + .../mpl/aux_/preprocessor/ext_params.hpp | 78 + .../mpl/aux_/preprocessor/filter_params.hpp | 28 + .../boost/mpl/aux_/preprocessor/is_seq.hpp | 54 + .../boost/mpl/aux_/preprocessor/params.hpp | 65 + .../aux_/preprocessor/partial_spec_params.hpp | 32 + .../boost/mpl/aux_/preprocessor/range.hpp | 23 + .../boost/mpl/aux_/preprocessor/repeat.hpp | 51 + .../boost/mpl/aux_/preprocessor/sub.hpp | 65 + .../mpl/aux_/preprocessor/token_equal.hpp | 56 + .../boost/mpl/aux_/preprocessor/tuple.hpp | 29 + thirdparty/boost/mpl/aux_/ptr_to_ref.hpp | 46 + thirdparty/boost/mpl/aux_/push_back_impl.hpp | 55 + thirdparty/boost/mpl/aux_/push_front_impl.hpp | 56 + thirdparty/boost/mpl/aux_/range_c/O1_size.hpp | 31 + thirdparty/boost/mpl/aux_/range_c/back.hpp | 34 + thirdparty/boost/mpl/aux_/range_c/empty.hpp | 37 + thirdparty/boost/mpl/aux_/range_c/front.hpp | 33 + .../boost/mpl/aux_/range_c/iterator.hpp | 106 + thirdparty/boost/mpl/aux_/range_c/size.hpp | 37 + thirdparty/boost/mpl/aux_/range_c/tag.hpp | 24 + .../boost/mpl/aux_/reverse_fold_impl.hpp | 44 + .../boost/mpl/aux_/reverse_fold_impl_body.hpp | 412 + .../boost/mpl/aux_/reverse_iter_fold_impl.hpp | 43 + .../boost/mpl/aux_/sequence_wrapper.hpp | 292 + thirdparty/boost/mpl/aux_/shift_op.hpp | 87 + .../boost/mpl/aux_/single_element_iter.hpp | 118 + thirdparty/boost/mpl/aux_/size_impl.hpp | 52 + thirdparty/boost/mpl/aux_/sort_impl.hpp | 121 + thirdparty/boost/mpl/aux_/static_cast.hpp | 27 + thirdparty/boost/mpl/aux_/template_arity.hpp | 189 + .../boost/mpl/aux_/template_arity_fwd.hpp | 23 + thirdparty/boost/mpl/aux_/test.hpp | 32 + thirdparty/boost/mpl/aux_/test/assert.hpp | 29 + thirdparty/boost/mpl/aux_/test/data.hpp | 25 + thirdparty/boost/mpl/aux_/test/test_case.hpp | 21 + .../boost/mpl/aux_/traits_lambda_spec.hpp | 56 + thirdparty/boost/mpl/aux_/transform_iter.hpp | 123 + thirdparty/boost/mpl/aux_/type_wrapper.hpp | 47 + thirdparty/boost/mpl/aux_/unwrap.hpp | 47 + thirdparty/boost/mpl/aux_/value_wknd.hpp | 89 + thirdparty/boost/mpl/aux_/yes_no.hpp | 58 + thirdparty/boost/mpl/back.hpp | 39 + thirdparty/boost/mpl/back_fwd.hpp | 24 + thirdparty/boost/mpl/back_inserter.hpp | 34 + thirdparty/boost/mpl/base.hpp | 35 + thirdparty/boost/mpl/begin.hpp | 19 + thirdparty/boost/mpl/begin_end.hpp | 57 + thirdparty/boost/mpl/begin_end_fwd.hpp | 27 + thirdparty/boost/mpl/bind.hpp | 547 + thirdparty/boost/mpl/bind_fwd.hpp | 99 + thirdparty/boost/mpl/bitand.hpp | 23 + thirdparty/boost/mpl/bitor.hpp | 23 + thirdparty/boost/mpl/bitwise.hpp | 24 + thirdparty/boost/mpl/bitxor.hpp | 23 + thirdparty/boost/mpl/bool.hpp | 39 + thirdparty/boost/mpl/bool_fwd.hpp | 33 + thirdparty/boost/mpl/clear.hpp | 39 + thirdparty/boost/mpl/clear_fwd.hpp | 24 + thirdparty/boost/mpl/comparison.hpp | 24 + thirdparty/boost/mpl/contains.hpp | 41 + thirdparty/boost/mpl/contains_fwd.hpp | 25 + thirdparty/boost/mpl/copy.hpp | 58 + thirdparty/boost/mpl/copy_if.hpp | 96 + thirdparty/boost/mpl/count.hpp | 40 + thirdparty/boost/mpl/count_fwd.hpp | 24 + thirdparty/boost/mpl/count_if.hpp | 79 + thirdparty/boost/mpl/deque.hpp | 58 + thirdparty/boost/mpl/deref.hpp | 41 + thirdparty/boost/mpl/distance.hpp | 78 + thirdparty/boost/mpl/distance_fwd.hpp | 28 + thirdparty/boost/mpl/divides.hpp | 21 + thirdparty/boost/mpl/empty.hpp | 39 + thirdparty/boost/mpl/empty_base.hpp | 59 + thirdparty/boost/mpl/empty_fwd.hpp | 24 + thirdparty/boost/mpl/empty_sequence.hpp | 42 + thirdparty/boost/mpl/end.hpp | 19 + thirdparty/boost/mpl/equal.hpp | 112 + thirdparty/boost/mpl/equal_to.hpp | 21 + thirdparty/boost/mpl/erase.hpp | 42 + thirdparty/boost/mpl/erase_fwd.hpp | 24 + thirdparty/boost/mpl/erase_key.hpp | 41 + thirdparty/boost/mpl/erase_key_fwd.hpp | 24 + thirdparty/boost/mpl/eval_if.hpp | 71 + thirdparty/boost/mpl/filter_view.hpp | 46 + thirdparty/boost/mpl/find.hpp | 38 + thirdparty/boost/mpl/find_if.hpp | 50 + thirdparty/boost/mpl/fold.hpp | 48 + thirdparty/boost/mpl/for_each.hpp | 112 + thirdparty/boost/mpl/front.hpp | 39 + thirdparty/boost/mpl/front_fwd.hpp | 24 + thirdparty/boost/mpl/front_inserter.hpp | 33 + thirdparty/boost/mpl/greater.hpp | 21 + thirdparty/boost/mpl/greater_equal.hpp | 21 + thirdparty/boost/mpl/has_key.hpp | 41 + thirdparty/boost/mpl/has_key_fwd.hpp | 25 + thirdparty/boost/mpl/has_xxx.hpp | 272 + thirdparty/boost/mpl/identity.hpp | 45 + thirdparty/boost/mpl/if.hpp | 135 + thirdparty/boost/mpl/index_if.hpp | 60 + thirdparty/boost/mpl/index_of.hpp | 39 + thirdparty/boost/mpl/inherit.hpp | 229 + thirdparty/boost/mpl/inherit_linearly.hpp | 39 + thirdparty/boost/mpl/insert.hpp | 41 + thirdparty/boost/mpl/insert_fwd.hpp | 24 + thirdparty/boost/mpl/insert_range.hpp | 41 + thirdparty/boost/mpl/insert_range_fwd.hpp | 24 + thirdparty/boost/mpl/inserter.hpp | 32 + thirdparty/boost/mpl/int.hpp | 22 + thirdparty/boost/mpl/int_fwd.hpp | 27 + thirdparty/boost/mpl/integral_c.hpp | 51 + thirdparty/boost/mpl/integral_c_fwd.hpp | 32 + thirdparty/boost/mpl/integral_c_tag.hpp | 26 + thirdparty/boost/mpl/is_placeholder.hpp | 67 + thirdparty/boost/mpl/is_sequence.hpp | 112 + thirdparty/boost/mpl/iter_fold.hpp | 49 + thirdparty/boost/mpl/iter_fold_if.hpp | 117 + thirdparty/boost/mpl/iterator_category.hpp | 35 + thirdparty/boost/mpl/iterator_range.hpp | 42 + thirdparty/boost/mpl/iterator_tags.hpp | 27 + thirdparty/boost/mpl/joint_view.hpp | 65 + thirdparty/boost/mpl/key_type.hpp | 42 + thirdparty/boost/mpl/key_type_fwd.hpp | 25 + thirdparty/boost/mpl/lambda.hpp | 29 + thirdparty/boost/mpl/lambda_fwd.hpp | 57 + thirdparty/boost/mpl/less.hpp | 21 + thirdparty/boost/mpl/less_equal.hpp | 21 + thirdparty/boost/mpl/limits/arity.hpp | 21 + thirdparty/boost/mpl/limits/list.hpp | 21 + thirdparty/boost/mpl/limits/map.hpp | 21 + thirdparty/boost/mpl/limits/set.hpp | 21 + thirdparty/boost/mpl/limits/unrolling.hpp | 21 + thirdparty/boost/mpl/limits/vector.hpp | 21 + thirdparty/boost/mpl/list.hpp | 57 + thirdparty/boost/mpl/list/aux_/O1_size.hpp | 33 + thirdparty/boost/mpl/list/aux_/begin_end.hpp | 44 + thirdparty/boost/mpl/list/aux_/clear.hpp | 34 + thirdparty/boost/mpl/list/aux_/empty.hpp | 34 + thirdparty/boost/mpl/list/aux_/front.hpp | 33 + .../mpl/list/aux_/include_preprocessed.hpp | 35 + thirdparty/boost/mpl/list/aux_/item.hpp | 55 + thirdparty/boost/mpl/list/aux_/iterator.hpp | 76 + thirdparty/boost/mpl/list/aux_/numbered.hpp | 68 + thirdparty/boost/mpl/list/aux_/numbered_c.hpp | 71 + thirdparty/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 + thirdparty/boost/mpl/list/aux_/push_back.hpp | 36 + thirdparty/boost/mpl/list/aux_/push_front.hpp | 39 + thirdparty/boost/mpl/list/aux_/size.hpp | 33 + thirdparty/boost/mpl/list/aux_/tag.hpp | 24 + thirdparty/boost/mpl/list/list0.hpp | 42 + thirdparty/boost/mpl/list/list0_c.hpp | 31 + thirdparty/boost/mpl/list/list10.hpp | 43 + thirdparty/boost/mpl/list/list10_c.hpp | 43 + thirdparty/boost/mpl/list/list20.hpp | 43 + thirdparty/boost/mpl/list/list20_c.hpp | 43 + thirdparty/boost/mpl/list/list30.hpp | 43 + thirdparty/boost/mpl/list/list30_c.hpp | 43 + thirdparty/boost/mpl/list/list40.hpp | 43 + thirdparty/boost/mpl/list/list40_c.hpp | 43 + thirdparty/boost/mpl/list/list50.hpp | 43 + thirdparty/boost/mpl/list/list50_c.hpp | 43 + thirdparty/boost/mpl/list_c.hpp | 60 + thirdparty/boost/mpl/logical.hpp | 21 + thirdparty/boost/mpl/long.hpp | 22 + thirdparty/boost/mpl/long_fwd.hpp | 27 + thirdparty/boost/mpl/lower_bound.hpp | 143 + thirdparty/boost/mpl/map.hpp | 57 + thirdparty/boost/mpl/map/aux_/at_impl.hpp | 144 + .../boost/mpl/map/aux_/begin_end_impl.hpp | 50 + thirdparty/boost/mpl/map/aux_/clear_impl.hpp | 35 + .../boost/mpl/map/aux_/contains_impl.hpp | 43 + thirdparty/boost/mpl/map/aux_/empty_impl.hpp | 34 + thirdparty/boost/mpl/map/aux_/erase_impl.hpp | 41 + .../boost/mpl/map/aux_/erase_key_impl.hpp | 53 + .../boost/mpl/map/aux_/has_key_impl.hpp | 44 + .../mpl/map/aux_/include_preprocessed.hpp | 53 + thirdparty/boost/mpl/map/aux_/insert_impl.hpp | 72 + thirdparty/boost/mpl/map/aux_/item.hpp | 138 + thirdparty/boost/mpl/map/aux_/iterator.hpp | 169 + .../boost/mpl/map/aux_/key_type_impl.hpp | 36 + thirdparty/boost/mpl/map/aux_/map0.hpp | 74 + thirdparty/boost/mpl/map/aux_/numbered.hpp | 110 + .../map/aux_/preprocessed/no_ctps/map10.hpp | 350 + .../map/aux_/preprocessed/no_ctps/map20.hpp | 370 + .../map/aux_/preprocessed/no_ctps/map30.hpp | 390 + .../map/aux_/preprocessed/no_ctps/map40.hpp | 410 + .../map/aux_/preprocessed/no_ctps/map50.hpp | 430 + .../mpl/map/aux_/preprocessed/plain/map10.hpp | 290 + .../mpl/map/aux_/preprocessed/plain/map20.hpp | 310 + .../mpl/map/aux_/preprocessed/plain/map30.hpp | 330 + .../mpl/map/aux_/preprocessed/plain/map40.hpp | 350 + .../mpl/map/aux_/preprocessed/plain/map50.hpp | 370 + .../aux_/preprocessed/typeof_based/map10.hpp | 150 + .../aux_/preprocessed/typeof_based/map20.hpp | 170 + .../aux_/preprocessed/typeof_based/map30.hpp | 190 + .../aux_/preprocessed/typeof_based/map40.hpp | 210 + .../aux_/preprocessed/typeof_based/map50.hpp | 230 + thirdparty/boost/mpl/map/aux_/size_impl.hpp | 33 + thirdparty/boost/mpl/map/aux_/tag.hpp | 24 + .../boost/mpl/map/aux_/value_type_impl.hpp | 36 + thirdparty/boost/mpl/map/map0.hpp | 36 + thirdparty/boost/mpl/map/map10.hpp | 44 + thirdparty/boost/mpl/map/map20.hpp | 44 + thirdparty/boost/mpl/map/map30.hpp | 44 + thirdparty/boost/mpl/map/map40.hpp | 44 + thirdparty/boost/mpl/map/map50.hpp | 44 + thirdparty/boost/mpl/math/fixed_c.hpp | 36 + thirdparty/boost/mpl/math/is_even.hpp | 54 + thirdparty/boost/mpl/math/rational_c.hpp | 37 + thirdparty/boost/mpl/max.hpp | 19 + thirdparty/boost/mpl/max_element.hpp | 72 + thirdparty/boost/mpl/min.hpp | 19 + thirdparty/boost/mpl/min_element.hpp | 40 + thirdparty/boost/mpl/min_max.hpp | 46 + thirdparty/boost/mpl/minus.hpp | 21 + thirdparty/boost/mpl/modulus.hpp | 22 + thirdparty/boost/mpl/multiplies.hpp | 53 + .../boost/mpl/multiset/aux_/count_impl.hpp | 82 + .../boost/mpl/multiset/aux_/insert_impl.hpp | 34 + thirdparty/boost/mpl/multiset/aux_/item.hpp | 114 + .../boost/mpl/multiset/aux_/multiset0.hpp | 34 + thirdparty/boost/mpl/multiset/aux_/tag.hpp | 23 + thirdparty/boost/mpl/multiset/multiset0.hpp | 36 + thirdparty/boost/mpl/negate.hpp | 81 + thirdparty/boost/mpl/next.hpp | 19 + thirdparty/boost/mpl/next_prior.hpp | 49 + thirdparty/boost/mpl/not.hpp | 51 + thirdparty/boost/mpl/not_equal_to.hpp | 21 + thirdparty/boost/mpl/numeric_cast.hpp | 41 + thirdparty/boost/mpl/or.hpp | 61 + thirdparty/boost/mpl/order.hpp | 41 + thirdparty/boost/mpl/order_fwd.hpp | 25 + thirdparty/boost/mpl/pair.hpp | 70 + thirdparty/boost/mpl/pair_view.hpp | 169 + thirdparty/boost/mpl/partition.hpp | 53 + thirdparty/boost/mpl/placeholders.hpp | 100 + thirdparty/boost/mpl/plus.hpp | 21 + thirdparty/boost/mpl/pop_back.hpp | 39 + thirdparty/boost/mpl/pop_back_fwd.hpp | 24 + thirdparty/boost/mpl/pop_front.hpp | 39 + thirdparty/boost/mpl/pop_front_fwd.hpp | 24 + thirdparty/boost/mpl/print.hpp | 74 + thirdparty/boost/mpl/prior.hpp | 19 + thirdparty/boost/mpl/protect.hpp | 55 + thirdparty/boost/mpl/push_back.hpp | 53 + thirdparty/boost/mpl/push_back_fwd.hpp | 24 + thirdparty/boost/mpl/push_front.hpp | 52 + thirdparty/boost/mpl/push_front_fwd.hpp | 24 + thirdparty/boost/mpl/quote.hpp | 140 + thirdparty/boost/mpl/range_c.hpp | 48 + thirdparty/boost/mpl/remove.hpp | 52 + thirdparty/boost/mpl/remove_if.hpp | 83 + thirdparty/boost/mpl/replace.hpp | 55 + thirdparty/boost/mpl/replace_if.hpp | 88 + thirdparty/boost/mpl/reverse.hpp | 38 + thirdparty/boost/mpl/reverse_fold.hpp | 50 + thirdparty/boost/mpl/reverse_iter_fold.hpp | 56 + thirdparty/boost/mpl/same_as.hpp | 55 + thirdparty/boost/mpl/sequence_tag.hpp | 124 + thirdparty/boost/mpl/sequence_tag_fwd.hpp | 26 + thirdparty/boost/mpl/set.hpp | 57 + thirdparty/boost/mpl/set/aux_/at_impl.hpp | 40 + .../boost/mpl/set/aux_/begin_end_impl.hpp | 43 + thirdparty/boost/mpl/set/aux_/clear_impl.hpp | 35 + thirdparty/boost/mpl/set/aux_/empty_impl.hpp | 34 + thirdparty/boost/mpl/set/aux_/erase_impl.hpp | 41 + .../boost/mpl/set/aux_/erase_key_impl.hpp | 53 + .../boost/mpl/set/aux_/has_key_impl.hpp | 60 + .../mpl/set/aux_/include_preprocessed.hpp | 42 + thirdparty/boost/mpl/set/aux_/insert_impl.hpp | 65 + thirdparty/boost/mpl/set/aux_/item.hpp | 80 + thirdparty/boost/mpl/set/aux_/iterator.hpp | 98 + .../boost/mpl/set/aux_/key_type_impl.hpp | 34 + thirdparty/boost/mpl/set/aux_/numbered.hpp | 48 + thirdparty/boost/mpl/set/aux_/numbered_c.hpp | 48 + .../mpl/set/aux_/preprocessed/plain/set10.hpp | 140 + .../set/aux_/preprocessed/plain/set10_c.hpp | 145 + .../mpl/set/aux_/preprocessed/plain/set20.hpp | 168 + .../set/aux_/preprocessed/plain/set20_c.hpp | 154 + .../mpl/set/aux_/preprocessed/plain/set30.hpp | 195 + .../set/aux_/preprocessed/plain/set30_c.hpp | 164 + .../mpl/set/aux_/preprocessed/plain/set40.hpp | 221 + .../set/aux_/preprocessed/plain/set40_c.hpp | 174 + .../mpl/set/aux_/preprocessed/plain/set50.hpp | 250 + .../set/aux_/preprocessed/plain/set50_c.hpp | 184 + thirdparty/boost/mpl/set/aux_/set0.hpp | 69 + thirdparty/boost/mpl/set/aux_/size_impl.hpp | 33 + thirdparty/boost/mpl/set/aux_/tag.hpp | 24 + .../boost/mpl/set/aux_/value_type_impl.hpp | 34 + thirdparty/boost/mpl/set/set0.hpp | 35 + thirdparty/boost/mpl/set/set0_c.hpp | 32 + thirdparty/boost/mpl/set/set10.hpp | 44 + thirdparty/boost/mpl/set/set10_c.hpp | 45 + thirdparty/boost/mpl/set/set20.hpp | 44 + thirdparty/boost/mpl/set/set20_c.hpp | 45 + thirdparty/boost/mpl/set/set30.hpp | 44 + thirdparty/boost/mpl/set/set30_c.hpp | 45 + thirdparty/boost/mpl/set/set40.hpp | 44 + thirdparty/boost/mpl/set/set40_c.hpp | 45 + thirdparty/boost/mpl/set/set50.hpp | 44 + thirdparty/boost/mpl/set/set50_c.hpp | 45 + thirdparty/boost/mpl/set_c.hpp | 60 + thirdparty/boost/mpl/shift_left.hpp | 22 + thirdparty/boost/mpl/shift_right.hpp | 22 + thirdparty/boost/mpl/single_view.hpp | 38 + thirdparty/boost/mpl/size.hpp | 42 + thirdparty/boost/mpl/size_fwd.hpp | 24 + thirdparty/boost/mpl/size_t.hpp | 25 + thirdparty/boost/mpl/size_t_fwd.hpp | 28 + thirdparty/boost/mpl/sizeof.hpp | 36 + thirdparty/boost/mpl/sort.hpp | 27 + thirdparty/boost/mpl/stable_partition.hpp | 75 + thirdparty/boost/mpl/switch.hpp | 49 + thirdparty/boost/mpl/tag.hpp | 52 + thirdparty/boost/mpl/times.hpp | 21 + thirdparty/boost/mpl/transform.hpp | 145 + thirdparty/boost/mpl/transform_view.hpp | 46 + thirdparty/boost/mpl/unique.hpp | 85 + thirdparty/boost/mpl/unpack_args.hpp | 146 + thirdparty/boost/mpl/upper_bound.hpp | 141 + thirdparty/boost/mpl/value_type.hpp | 42 + thirdparty/boost/mpl/value_type_fwd.hpp | 25 + thirdparty/boost/mpl/vector.hpp | 57 + thirdparty/boost/mpl/vector/aux_/O1_size.hpp | 56 + thirdparty/boost/mpl/vector/aux_/at.hpp | 116 + thirdparty/boost/mpl/vector/aux_/back.hpp | 59 + .../boost/mpl/vector/aux_/begin_end.hpp | 49 + thirdparty/boost/mpl/vector/aux_/clear.hpp | 55 + thirdparty/boost/mpl/vector/aux_/empty.hpp | 68 + thirdparty/boost/mpl/vector/aux_/front.hpp | 56 + .../mpl/vector/aux_/include_preprocessed.hpp | 55 + thirdparty/boost/mpl/vector/aux_/item.hpp | 103 + thirdparty/boost/mpl/vector/aux_/iterator.hpp | 130 + thirdparty/boost/mpl/vector/aux_/numbered.hpp | 218 + .../boost/mpl/vector/aux_/numbered_c.hpp | 77 + thirdparty/boost/mpl/vector/aux_/pop_back.hpp | 40 + .../boost/mpl/vector/aux_/pop_front.hpp | 40 + .../aux_/preprocessed/no_ctps/vector10.hpp | 1528 ++ .../aux_/preprocessed/no_ctps/vector10_c.hpp | 149 + .../aux_/preprocessed/no_ctps/vector20.hpp | 1804 +++ .../aux_/preprocessed/no_ctps/vector20_c.hpp | 195 + .../aux_/preprocessed/no_ctps/vector30.hpp | 2124 +++ .../aux_/preprocessed/no_ctps/vector30_c.hpp | 238 + .../aux_/preprocessed/no_ctps/vector40.hpp | 2444 ++++ .../aux_/preprocessed/no_ctps/vector40_c.hpp | 281 + .../aux_/preprocessed/no_ctps/vector50.hpp | 2764 ++++ .../aux_/preprocessed/no_ctps/vector50_c.hpp | 325 + .../aux_/preprocessed/plain/vector10.hpp | 829 ++ .../aux_/preprocessed/plain/vector10_c.hpp | 149 + .../aux_/preprocessed/plain/vector20.hpp | 1144 ++ .../aux_/preprocessed/plain/vector20_c.hpp | 195 + .../aux_/preprocessed/plain/vector30.hpp | 1464 ++ .../aux_/preprocessed/plain/vector30_c.hpp | 238 + .../aux_/preprocessed/plain/vector40.hpp | 1784 +++ .../aux_/preprocessed/plain/vector40_c.hpp | 281 + .../aux_/preprocessed/plain/vector50.hpp | 2104 +++ .../aux_/preprocessed/plain/vector50_c.hpp | 325 + .../preprocessed/typeof_based/vector10.hpp | 139 + .../preprocessed/typeof_based/vector10_c.hpp | 154 + .../preprocessed/typeof_based/vector20.hpp | 159 + .../preprocessed/typeof_based/vector20_c.hpp | 163 + .../preprocessed/typeof_based/vector30.hpp | 179 + .../preprocessed/typeof_based/vector30_c.hpp | 173 + .../preprocessed/typeof_based/vector40.hpp | 199 + .../preprocessed/typeof_based/vector40_c.hpp | 183 + .../preprocessed/typeof_based/vector50.hpp | 219 + .../preprocessed/typeof_based/vector50_c.hpp | 193 + .../boost/mpl/vector/aux_/push_back.hpp | 40 + .../boost/mpl/vector/aux_/push_front.hpp | 40 + thirdparty/boost/mpl/vector/aux_/size.hpp | 49 + thirdparty/boost/mpl/vector/aux_/tag.hpp | 32 + thirdparty/boost/mpl/vector/aux_/vector0.hpp | 52 + thirdparty/boost/mpl/vector/vector0.hpp | 34 + thirdparty/boost/mpl/vector/vector0_c.hpp | 31 + thirdparty/boost/mpl/vector/vector10.hpp | 45 + thirdparty/boost/mpl/vector/vector10_c.hpp | 46 + thirdparty/boost/mpl/vector/vector20.hpp | 45 + thirdparty/boost/mpl/vector/vector20_c.hpp | 46 + thirdparty/boost/mpl/vector/vector30.hpp | 45 + thirdparty/boost/mpl/vector/vector30_c.hpp | 47 + thirdparty/boost/mpl/vector/vector40.hpp | 45 + thirdparty/boost/mpl/vector/vector40_c.hpp | 46 + thirdparty/boost/mpl/vector/vector50.hpp | 45 + thirdparty/boost/mpl/vector/vector50_c.hpp | 46 + thirdparty/boost/mpl/vector_c.hpp | 60 + thirdparty/boost/mpl/void.hpp | 76 + thirdparty/boost/mpl/void_fwd.hpp | 26 + thirdparty/boost/mpl/zip_view.hpp | 64 + thirdparty/boost/multi_array.hpp | 499 + thirdparty/boost/multi_array/algorithm.hpp | 103 + thirdparty/boost/multi_array/base.hpp | 482 + .../boost/multi_array/collection_concept.hpp | 62 + .../boost/multi_array/concept_checks.hpp | 215 + thirdparty/boost/multi_array/copy_array.hpp | 68 + thirdparty/boost/multi_array/extent_gen.hpp | 75 + thirdparty/boost/multi_array/extent_range.hpp | 49 + thirdparty/boost/multi_array/index_gen.hpp | 81 + thirdparty/boost/multi_array/index_range.hpp | 188 + thirdparty/boost/multi_array/iterator.hpp | 170 + .../boost/multi_array/multi_array_ref.hpp | 633 + thirdparty/boost/multi_array/range_list.hpp | 70 + .../boost/multi_array/storage_order.hpp | 125 + thirdparty/boost/multi_array/subarray.hpp | 399 + thirdparty/boost/multi_array/types.hpp | 38 + thirdparty/boost/multi_array/view.hpp | 472 + .../boost/multi_index/composite_key.hpp | 1315 ++ .../multi_index/detail/access_specifier.hpp | 55 + .../boost/multi_index/detail/adl_swap.hpp | 44 + .../detail/archive_constructed.hpp | 79 + .../boost/multi_index/detail/auto_space.hpp | 95 + .../boost/multi_index/detail/base_type.hpp | 87 + .../detail/bidir_node_iterator.hpp | 113 + .../boost/multi_index/detail/bucket_array.hpp | 211 + .../boost/multi_index/detail/converter.hpp | 52 + .../boost/multi_index/detail/copy_map.hpp | 140 + .../detail/duplicates_iterator.hpp | 120 + .../boost/multi_index/detail/has_tag.hpp | 42 + .../multi_index/detail/hash_index_args.hpp | 105 + .../detail/hash_index_iterator.hpp | 111 + .../multi_index/detail/hash_index_node.hpp | 165 + .../multi_index/detail/header_holder.hpp | 50 + .../boost/multi_index/detail/index_base.hpp | 185 + .../boost/multi_index/detail/index_loader.hpp | 138 + .../multi_index/detail/index_matcher.hpp | 248 + .../multi_index/detail/index_node_base.hpp | 135 + .../boost/multi_index/detail/index_saver.hpp | 135 + .../multi_index/detail/invariant_assert.hpp | 21 + .../multi_index/detail/is_index_list.hpp | 40 + .../boost/multi_index/detail/iter_adaptor.hpp | 325 + .../multi_index/detail/modify_key_adaptor.hpp | 49 + .../detail/msvc_index_specifier.hpp | 69 + .../multi_index/detail/no_duplicate_tags.hpp | 97 + .../boost/multi_index/detail/node_type.hpp | 79 + .../multi_index/detail/ord_index_args.hpp | 83 + .../multi_index/detail/ord_index_node.hpp | 650 + .../multi_index/detail/ord_index_ops.hpp | 147 + .../boost/multi_index/detail/prevent_eti.hpp | 60 + .../multi_index/detail/rnd_index_loader.hpp | 176 + .../multi_index/detail/rnd_index_node.hpp | 281 + .../multi_index/detail/rnd_index_ops.hpp | 206 + .../detail/rnd_index_ptr_array.hpp | 143 + .../multi_index/detail/rnd_node_iterator.hpp | 139 + .../multi_index/detail/safe_ctr_proxy.hpp | 105 + .../boost/multi_index/detail/safe_mode.hpp | 568 + .../boost/multi_index/detail/scope_guard.hpp | 277 + .../multi_index/detail/seq_index_node.hpp | 223 + .../multi_index/detail/seq_index_ops.hpp | 200 + .../boost/multi_index/detail/uintptr_type.hpp | 76 + .../boost/multi_index/detail/unbounded.hpp | 83 + .../multi_index/detail/value_compare.hpp | 53 + thirdparty/boost/multi_index/global_fun.hpp | 188 + thirdparty/boost/multi_index/hashed_index.hpp | 1167 ++ .../boost/multi_index/hashed_index_fwd.hpp | 58 + thirdparty/boost/multi_index/identity.hpp | 147 + thirdparty/boost/multi_index/identity_fwd.hpp | 26 + thirdparty/boost/multi_index/indexed_by.hpp | 72 + .../boost/multi_index/key_extractors.hpp | 22 + thirdparty/boost/multi_index/mem_fun.hpp | 212 + thirdparty/boost/multi_index/member.hpp | 269 + .../boost/multi_index/ordered_index.hpp | 1390 ++ .../boost/multi_index/ordered_index_fwd.hpp | 124 + .../boost/multi_index/random_access_index.hpp | 1008 ++ .../multi_index/random_access_index_fwd.hpp | 91 + .../boost/multi_index/safe_mode_errors.hpp | 48 + .../boost/multi_index/sequenced_index.hpp | 922 ++ .../boost/multi_index/sequenced_index_fwd.hpp | 91 + thirdparty/boost/multi_index/tag.hpp | 92 + thirdparty/boost/multi_index_container.hpp | 1083 ++ .../boost/multi_index_container_fwd.hpp | 121 + thirdparty/boost/next_prior.hpp | 51 + thirdparty/boost/non_type.hpp | 27 + thirdparty/boost/noncopyable.hpp | 36 + thirdparty/boost/nondet_random.hpp | 64 + thirdparty/boost/none.hpp | 28 + thirdparty/boost/none_t.hpp | 24 + .../boost/numeric/conversion/bounds.hpp | 24 + thirdparty/boost/numeric/conversion/cast.hpp | 51 + .../numeric/conversion/conversion_traits.hpp | 39 + .../boost/numeric/conversion/converter.hpp | 68 + .../numeric/conversion/converter_policies.hpp | 186 + .../numeric/conversion/detail/bounds.hpp | 58 + .../conversion/detail/conversion_traits.hpp | 97 + .../numeric/conversion/detail/converter.hpp | 602 + .../conversion/detail/int_float_mixture.hpp | 72 + .../conversion/detail/is_subranged.hpp | 234 + .../boost/numeric/conversion/detail/meta.hpp | 120 + .../conversion/detail/old_numeric_cast.hpp | 339 + .../conversion/detail/sign_mixture.hpp | 72 + .../conversion/detail/udt_builtin_mixture.hpp | 69 + .../numeric/conversion/int_float_mixture.hpp | 30 + .../conversion/int_float_mixture_enum.hpp | 29 + .../boost/numeric/conversion/is_subranged.hpp | 27 + .../boost/numeric/conversion/sign_mixture.hpp | 30 + .../numeric/conversion/sign_mixture_enum.hpp | 29 + .../conversion/udt_builtin_mixture.hpp | 28 + .../conversion/udt_builtin_mixture_enum.hpp | 26 + thirdparty/boost/numeric/interval.hpp | 32 + thirdparty/boost/numeric/interval/arith.hpp | 305 + thirdparty/boost/numeric/interval/arith2.hpp | 305 + thirdparty/boost/numeric/interval/arith3.hpp | 69 + .../boost/numeric/interval/checking.hpp | 130 + thirdparty/boost/numeric/interval/compare.hpp | 19 + .../numeric/interval/compare/certain.hpp | 113 + .../numeric/interval/compare/explicit.hpp | 248 + .../interval/compare/lexicographic.hpp | 122 + .../numeric/interval/compare/possible.hpp | 113 + .../boost/numeric/interval/compare/set.hpp | 101 + .../numeric/interval/compare/tribool.hpp | 138 + .../boost/numeric/interval/constants.hpp | 85 + .../detail/alpha_rounding_control.hpp | 113 + .../interval/detail/bcc_rounding_control.hpp | 57 + .../boost/numeric/interval/detail/bugs.hpp | 79 + .../interval/detail/c99_rounding_control.hpp | 47 + .../detail/c99sub_rounding_control.hpp | 43 + .../numeric/interval/detail/division.hpp | 194 + .../interval/detail/ia64_rounding_control.hpp | 83 + .../interval/detail/interval_prototype.hpp | 41 + .../interval/detail/msvc_rounding_control.hpp | 91 + .../interval/detail/ppc_rounding_control.hpp | 99 + .../detail/sparc_rounding_control.hpp | 112 + .../numeric/interval/detail/test_input.hpp | 76 + .../interval/detail/x86_rounding_control.hpp | 108 + .../detail/x86gcc_rounding_control.hpp | 51 + .../boost/numeric/interval/ext/integer.hpp | 70 + .../ext/x86_fast_rounding_control.hpp | 70 + .../boost/numeric/interval/hw_rounding.hpp | 70 + .../boost/numeric/interval/interval.hpp | 450 + thirdparty/boost/numeric/interval/io.hpp | 41 + thirdparty/boost/numeric/interval/limits.hpp | 51 + .../boost/numeric/interval/policies.hpp | 75 + .../boost/numeric/interval/rounded_arith.hpp | 120 + .../boost/numeric/interval/rounded_transc.hpp | 140 + .../boost/numeric/interval/rounding.hpp | 101 + thirdparty/boost/numeric/interval/transc.hpp | 232 + thirdparty/boost/numeric/interval/utility.hpp | 337 + thirdparty/boost/numeric/ublas/banded.hpp | 2024 +++ thirdparty/boost/numeric/ublas/blas.hpp | 296 + .../boost/numeric/ublas/detail/concepts.hpp | 1490 ++ .../boost/numeric/ublas/detail/config.hpp | 290 + .../numeric/ublas/detail/definitions.hpp | 212 + .../numeric/ublas/detail/documentation.hpp | 33 + .../boost/numeric/ublas/detail/duff.hpp | 56 + .../boost/numeric/ublas/detail/iterator.hpp | 1436 ++ .../numeric/ublas/detail/matrix_assign.hpp | 1628 +++ thirdparty/boost/numeric/ublas/detail/raw.hpp | 878 ++ .../ublas/detail/returntype_deduction.hpp | 174 + .../boost/numeric/ublas/detail/temporary.hpp | 33 + .../numeric/ublas/detail/vector_assign.hpp | 571 + thirdparty/boost/numeric/ublas/exception.hpp | 296 + .../boost/numeric/ublas/expression_types.hpp | 488 + thirdparty/boost/numeric/ublas/functional.hpp | 2059 +++ thirdparty/boost/numeric/ublas/fwd.hpp | 212 + thirdparty/boost/numeric/ublas/hermitian.hpp | 2426 ++++ thirdparty/boost/numeric/ublas/io.hpp | 249 + thirdparty/boost/numeric/ublas/lu.hpp | 340 + thirdparty/boost/numeric/ublas/matrix.hpp | 4180 ++++++ .../boost/numeric/ublas/matrix_expression.hpp | 4948 +++++++ .../boost/numeric/ublas/matrix_proxy.hpp | 5093 +++++++ .../boost/numeric/ublas/matrix_sparse.hpp | 5353 +++++++ thirdparty/boost/numeric/ublas/operation.hpp | 851 ++ .../boost/numeric/ublas/operation_blocked.hpp | 266 + .../boost/numeric/ublas/operation_sparse.hpp | 198 + thirdparty/boost/numeric/ublas/storage.hpp | 1915 +++ .../boost/numeric/ublas/storage_sparse.hpp | 562 + thirdparty/boost/numeric/ublas/symmetric.hpp | 2130 +++ thirdparty/boost/numeric/ublas/traits.hpp | 506 + thirdparty/boost/numeric/ublas/triangular.hpp | 2561 ++++ thirdparty/boost/numeric/ublas/vector.hpp | 1739 +++ .../boost/numeric/ublas/vector_expression.hpp | 1663 +++ .../boost/numeric/ublas/vector_of_vector.hpp | 1258 ++ .../boost/numeric/ublas/vector_proxy.hpp | 1566 ++ .../boost/numeric/ublas/vector_sparse.hpp | 2065 +++ thirdparty/boost/operators.hpp | 943 ++ thirdparty/boost/optional.hpp | 18 + thirdparty/boost/optional/optional.hpp | 922 ++ thirdparty/boost/optional/optional_fwd.hpp | 22 + thirdparty/boost/optional/optional_io.hpp | 84 + thirdparty/boost/parameter.hpp | 21 + thirdparty/boost/parameter/aux_/arg_list.hpp | 464 + thirdparty/boost/parameter/aux_/cast.hpp | 129 + thirdparty/boost/parameter/aux_/default.hpp | 67 + thirdparty/boost/parameter/aux_/maybe.hpp | 98 + thirdparty/boost/parameter/aux_/overloads.hpp | 88 + .../parameter/aux_/parameter_requirements.hpp | 25 + .../parameter/aux_/parenthesized_type.hpp | 119 + .../parameter/aux_/preprocessor/flatten.hpp | 115 + .../parameter/aux_/preprocessor/for_each.hpp | 103 + .../boost/parameter/aux_/python/invoker.hpp | 131 + .../parameter/aux_/python/invoker_iterate.hpp | 93 + .../boost/parameter/aux_/result_of0.hpp | 36 + thirdparty/boost/parameter/aux_/set.hpp | 65 + thirdparty/boost/parameter/aux_/tag.hpp | 38 + .../boost/parameter/aux_/tagged_argument.hpp | 187 + .../boost/parameter/aux_/template_keyword.hpp | 47 + .../parameter/aux_/unwrap_cv_reference.hpp | 97 + thirdparty/boost/parameter/aux_/void.hpp | 29 + thirdparty/boost/parameter/aux_/yesno.hpp | 26 + thirdparty/boost/parameter/binding.hpp | 106 + thirdparty/boost/parameter/config.hpp | 14 + thirdparty/boost/parameter/keyword.hpp | 152 + thirdparty/boost/parameter/macros.hpp | 98 + thirdparty/boost/parameter/match.hpp | 55 + thirdparty/boost/parameter/name.hpp | 156 + thirdparty/boost/parameter/parameters.hpp | 931 ++ thirdparty/boost/parameter/preprocessor.hpp | 1169 ++ thirdparty/boost/parameter/python.hpp | 735 + thirdparty/boost/parameter/value_type.hpp | 108 + thirdparty/boost/pending/bucket_sorter.hpp | 134 + thirdparty/boost/pending/container_traits.hpp | 425 + thirdparty/boost/pending/cstddef.hpp | 16 + thirdparty/boost/pending/ct_if.hpp | 43 + .../boost/pending/detail/disjoint_sets.hpp | 88 + .../boost/pending/detail/int_iterator.hpp | 74 + thirdparty/boost/pending/detail/property.hpp | 160 + thirdparty/boost/pending/disjoint_sets.hpp | 220 + .../boost/pending/fenced_priority_queue.hpp | 152 + thirdparty/boost/pending/fibonacci_heap.hpp | 271 + thirdparty/boost/pending/indirect_cmp.hpp | 86 + thirdparty/boost/pending/integer_log2.hpp | 116 + thirdparty/boost/pending/integer_range.hpp | 59 + thirdparty/boost/pending/is_heap.hpp | 62 + .../boost/pending/iterator_adaptors.hpp | 6 + thirdparty/boost/pending/iterator_tests.hpp | 268 + thirdparty/boost/pending/lowest_bit.hpp | 41 + thirdparty/boost/pending/mutable_heap.hpp | 64 + thirdparty/boost/pending/mutable_queue.hpp | 135 + thirdparty/boost/pending/property.hpp | 132 + .../boost/pending/property_serialize.hpp | 28 + thirdparty/boost/pending/queue.hpp | 118 + thirdparty/boost/pending/relaxed_heap.hpp | 644 + thirdparty/boost/pending/stringtok.hpp | 116 + thirdparty/boost/pfto.hpp | 74 + thirdparty/boost/pointee.hpp | 74 + thirdparty/boost/pointer_cast.hpp | 45 + thirdparty/boost/pointer_to_other.hpp | 55 + thirdparty/boost/pool/detail/ct_gcd_lcm.hpp | 104 + thirdparty/boost/pool/detail/for.m4 | 107 + thirdparty/boost/pool/detail/gcd_lcm.hpp | 58 + thirdparty/boost/pool/detail/guard.hpp | 40 + thirdparty/boost/pool/detail/mutex.hpp | 147 + .../boost/pool/detail/pool_construct.bat | 24 + .../boost/pool/detail/pool_construct.inc | 853 ++ .../boost/pool/detail/pool_construct.m4 | 84 + .../boost/pool/detail/pool_construct.sh | 11 + .../pool/detail/pool_construct_simple.bat | 25 + .../pool/detail/pool_construct_simple.inc | 43 + .../pool/detail/pool_construct_simple.m4 | 73 + .../pool/detail/pool_construct_simple.sh | 11 + thirdparty/boost/pool/detail/singleton.hpp | 107 + thirdparty/boost/pool/object_pool.hpp | 157 + thirdparty/boost/pool/pool.hpp | 584 + thirdparty/boost/pool/pool_alloc.hpp | 221 + thirdparty/boost/pool/poolfwd.hpp | 73 + .../boost/pool/simple_segregated_storage.hpp | 265 + thirdparty/boost/pool/singleton_pool.hpp | 119 + thirdparty/boost/preprocessor.hpp | 19 + thirdparty/boost/preprocessor/arithmetic.hpp | 25 + .../boost/preprocessor/arithmetic/add.hpp | 51 + .../boost/preprocessor/arithmetic/dec.hpp | 288 + .../arithmetic/detail/div_base.hpp | 61 + .../boost/preprocessor/arithmetic/div.hpp | 39 + .../boost/preprocessor/arithmetic/inc.hpp | 288 + .../boost/preprocessor/arithmetic/mod.hpp | 39 + .../boost/preprocessor/arithmetic/mul.hpp | 53 + .../boost/preprocessor/arithmetic/sub.hpp | 50 + thirdparty/boost/preprocessor/array.hpp | 27 + thirdparty/boost/preprocessor/array/data.hpp | 28 + thirdparty/boost/preprocessor/array/elem.hpp | 29 + .../boost/preprocessor/array/insert.hpp | 55 + .../boost/preprocessor/array/pop_back.hpp | 37 + .../boost/preprocessor/array/pop_front.hpp | 38 + .../boost/preprocessor/array/push_back.hpp | 33 + .../boost/preprocessor/array/push_front.hpp | 33 + .../boost/preprocessor/array/remove.hpp | 54 + .../boost/preprocessor/array/replace.hpp | 49 + .../boost/preprocessor/array/reverse.hpp | 29 + thirdparty/boost/preprocessor/array/size.hpp | 28 + thirdparty/boost/preprocessor/assert_msg.hpp | 17 + thirdparty/boost/preprocessor/cat.hpp | 35 + thirdparty/boost/preprocessor/comma.hpp | 17 + thirdparty/boost/preprocessor/comma_if.hpp | 17 + thirdparty/boost/preprocessor/comparison.hpp | 24 + .../boost/preprocessor/comparison/equal.hpp | 34 + .../boost/preprocessor/comparison/greater.hpp | 38 + .../preprocessor/comparison/greater_equal.hpp | 38 + .../boost/preprocessor/comparison/less.hpp | 46 + .../preprocessor/comparison/less_equal.hpp | 39 + .../preprocessor/comparison/not_equal.hpp | 814 ++ .../boost/preprocessor/config/config.hpp | 70 + .../boost/preprocessor/config/limits.hpp | 29 + thirdparty/boost/preprocessor/control.hpp | 22 + .../boost/preprocessor/control/deduce_d.hpp | 22 + .../preprocessor/control/detail/dmc/while.hpp | 536 + .../preprocessor/control/detail/edg/while.hpp | 534 + .../control/detail/msvc/while.hpp | 277 + .../preprocessor/control/detail/while.hpp | 536 + .../boost/preprocessor/control/expr_if.hpp | 30 + .../boost/preprocessor/control/expr_iif.hpp | 31 + thirdparty/boost/preprocessor/control/if.hpp | 30 + thirdparty/boost/preprocessor/control/iif.hpp | 34 + .../boost/preprocessor/control/while.hpp | 312 + thirdparty/boost/preprocessor/debug.hpp | 18 + .../boost/preprocessor/debug/assert.hpp | 44 + thirdparty/boost/preprocessor/debug/error.hpp | 33 + thirdparty/boost/preprocessor/debug/line.hpp | 35 + thirdparty/boost/preprocessor/dec.hpp | 17 + .../boost/preprocessor/detail/auto_rec.hpp | 293 + .../boost/preprocessor/detail/check.hpp | 48 + .../preprocessor/detail/dmc/auto_rec.hpp | 286 + .../boost/preprocessor/detail/is_binary.hpp | 30 + .../boost/preprocessor/detail/is_nullary.hpp | 30 + .../boost/preprocessor/detail/is_unary.hpp | 30 + thirdparty/boost/preprocessor/detail/null.hpp | 17 + .../boost/preprocessor/detail/split.hpp | 35 + thirdparty/boost/preprocessor/empty.hpp | 17 + thirdparty/boost/preprocessor/enum.hpp | 17 + thirdparty/boost/preprocessor/enum_params.hpp | 17 + .../enum_params_with_a_default.hpp | 17 + .../enum_params_with_defaults.hpp | 17 + .../boost/preprocessor/enum_shifted.hpp | 17 + .../preprocessor/enum_shifted_params.hpp | 17 + thirdparty/boost/preprocessor/expand.hpp | 17 + thirdparty/boost/preprocessor/expr_if.hpp | 17 + thirdparty/boost/preprocessor/facilities.hpp | 21 + .../boost/preprocessor/facilities/apply.hpp | 34 + .../boost/preprocessor/facilities/empty.hpp | 21 + .../boost/preprocessor/facilities/expand.hpp | 28 + .../preprocessor/facilities/identity.hpp | 23 + .../preprocessor/facilities/intercept.hpp | 277 + .../boost/preprocessor/facilities/is_1.hpp | 23 + .../preprocessor/facilities/is_empty.hpp | 43 + .../preprocessor/facilities/is_empty_or_1.hpp | 30 + thirdparty/boost/preprocessor/for.hpp | 17 + thirdparty/boost/preprocessor/identity.hpp | 17 + thirdparty/boost/preprocessor/if.hpp | 17 + thirdparty/boost/preprocessor/inc.hpp | 17 + thirdparty/boost/preprocessor/iterate.hpp | 17 + thirdparty/boost/preprocessor/iteration.hpp | 19 + .../iteration/detail/bounds/lower1.hpp | 99 + .../iteration/detail/bounds/lower2.hpp | 99 + .../iteration/detail/bounds/lower3.hpp | 99 + .../iteration/detail/bounds/lower4.hpp | 99 + .../iteration/detail/bounds/lower5.hpp | 99 + .../iteration/detail/bounds/upper1.hpp | 99 + .../iteration/detail/bounds/upper2.hpp | 99 + .../iteration/detail/bounds/upper3.hpp | 99 + .../iteration/detail/bounds/upper4.hpp | 99 + .../iteration/detail/bounds/upper5.hpp | 99 + .../preprocessor/iteration/detail/finish.hpp | 99 + .../iteration/detail/iter/forward1.hpp | 1342 ++ .../iteration/detail/iter/forward2.hpp | 1338 ++ .../iteration/detail/iter/forward3.hpp | 1338 ++ .../iteration/detail/iter/forward4.hpp | 1338 ++ .../iteration/detail/iter/forward5.hpp | 1338 ++ .../iteration/detail/iter/reverse1.hpp | 1296 ++ .../iteration/detail/iter/reverse2.hpp | 1296 ++ .../iteration/detail/iter/reverse3.hpp | 1296 ++ .../iteration/detail/iter/reverse4.hpp | 1296 ++ .../iteration/detail/iter/reverse5.hpp | 1296 ++ .../preprocessor/iteration/detail/local.hpp | 812 ++ .../preprocessor/iteration/detail/rlocal.hpp | 782 + .../preprocessor/iteration/detail/self.hpp | 21 + .../preprocessor/iteration/detail/start.hpp | 99 + .../boost/preprocessor/iteration/iterate.hpp | 82 + .../boost/preprocessor/iteration/local.hpp | 26 + .../boost/preprocessor/iteration/self.hpp | 19 + thirdparty/boost/preprocessor/library.hpp | 34 + thirdparty/boost/preprocessor/limits.hpp | 17 + thirdparty/boost/preprocessor/list.hpp | 35 + thirdparty/boost/preprocessor/list/adt.hpp | 73 + thirdparty/boost/preprocessor/list/append.hpp | 40 + thirdparty/boost/preprocessor/list/at.hpp | 39 + thirdparty/boost/preprocessor/list/cat.hpp | 42 + .../list/detail/dmc/fold_left.hpp | 279 + .../list/detail/edg/fold_left.hpp | 536 + .../list/detail/edg/fold_right.hpp | 794 + .../preprocessor/list/detail/fold_left.hpp | 279 + .../preprocessor/list/detail/fold_right.hpp | 277 + thirdparty/boost/preprocessor/list/enum.hpp | 41 + thirdparty/boost/preprocessor/list/filter.hpp | 54 + .../boost/preprocessor/list/first_n.hpp | 58 + .../boost/preprocessor/list/fold_left.hpp | 303 + .../boost/preprocessor/list/fold_right.hpp | 40 + .../boost/preprocessor/list/for_each.hpp | 49 + .../boost/preprocessor/list/for_each_i.hpp | 65 + .../preprocessor/list/for_each_product.hpp | 141 + thirdparty/boost/preprocessor/list/rest_n.hpp | 55 + .../boost/preprocessor/list/reverse.hpp | 40 + thirdparty/boost/preprocessor/list/size.hpp | 58 + .../boost/preprocessor/list/to_tuple.hpp | 38 + .../boost/preprocessor/list/transform.hpp | 49 + thirdparty/boost/preprocessor/logical.hpp | 29 + thirdparty/boost/preprocessor/logical/and.hpp | 30 + .../boost/preprocessor/logical/bitand.hpp | 38 + .../boost/preprocessor/logical/bitnor.hpp | 38 + .../boost/preprocessor/logical/bitor.hpp | 38 + .../boost/preprocessor/logical/bitxor.hpp | 38 + .../boost/preprocessor/logical/bool.hpp | 288 + .../boost/preprocessor/logical/compl.hpp | 36 + thirdparty/boost/preprocessor/logical/nor.hpp | 30 + thirdparty/boost/preprocessor/logical/not.hpp | 30 + thirdparty/boost/preprocessor/logical/or.hpp | 30 + thirdparty/boost/preprocessor/logical/xor.hpp | 30 + thirdparty/boost/preprocessor/max.hpp | 17 + thirdparty/boost/preprocessor/min.hpp | 17 + thirdparty/boost/preprocessor/punctuation.hpp | 20 + .../boost/preprocessor/punctuation/comma.hpp | 21 + .../preprocessor/punctuation/comma_if.hpp | 31 + .../boost/preprocessor/punctuation/paren.hpp | 23 + .../preprocessor/punctuation/paren_if.hpp | 38 + thirdparty/boost/preprocessor/repeat.hpp | 17 + thirdparty/boost/preprocessor/repeat_2nd.hpp | 17 + thirdparty/boost/preprocessor/repeat_3rd.hpp | 17 + .../boost/preprocessor/repeat_from_to.hpp | 17 + .../boost/preprocessor/repeat_from_to_2nd.hpp | 17 + .../boost/preprocessor/repeat_from_to_3rd.hpp | 17 + thirdparty/boost/preprocessor/repetition.hpp | 32 + .../preprocessor/repetition/deduce_r.hpp | 22 + .../preprocessor/repetition/deduce_z.hpp | 22 + .../repetition/detail/dmc/for.hpp | 536 + .../repetition/detail/edg/for.hpp | 534 + .../preprocessor/repetition/detail/for.hpp | 536 + .../repetition/detail/msvc/for.hpp | 277 + .../boost/preprocessor/repetition/enum.hpp | 66 + .../repetition/enum_binary_params.hpp | 54 + .../preprocessor/repetition/enum_params.hpp | 41 + .../repetition/enum_params_with_a_default.hpp | 25 + .../repetition/enum_params_with_defaults.hpp | 24 + .../preprocessor/repetition/enum_shifted.hpp | 68 + .../repetition/enum_shifted_binary_params.hpp | 51 + .../repetition/enum_shifted_params.hpp | 44 + .../preprocessor/repetition/enum_trailing.hpp | 63 + .../enum_trailing_binary_params.hpp | 53 + .../repetition/enum_trailing_params.hpp | 38 + .../boost/preprocessor/repetition/for.hpp | 306 + .../boost/preprocessor/repetition/repeat.hpp | 825 ++ .../repetition/repeat_from_to.hpp | 87 + thirdparty/boost/preprocessor/selection.hpp | 18 + .../boost/preprocessor/selection/max.hpp | 39 + .../boost/preprocessor/selection/min.hpp | 39 + thirdparty/boost/preprocessor/seq.hpp | 41 + thirdparty/boost/preprocessor/seq/cat.hpp | 48 + .../boost/preprocessor/seq/detail/split.hpp | 284 + thirdparty/boost/preprocessor/seq/elem.hpp | 304 + thirdparty/boost/preprocessor/seq/enum.hpp | 288 + thirdparty/boost/preprocessor/seq/filter.hpp | 54 + thirdparty/boost/preprocessor/seq/first_n.hpp | 30 + .../boost/preprocessor/seq/fold_left.hpp | 1070 ++ .../boost/preprocessor/seq/fold_right.hpp | 288 + .../boost/preprocessor/seq/for_each.hpp | 60 + .../boost/preprocessor/seq/for_each_i.hpp | 61 + .../preprocessor/seq/for_each_product.hpp | 126 + thirdparty/boost/preprocessor/seq/insert.hpp | 28 + .../boost/preprocessor/seq/pop_back.hpp | 29 + .../boost/preprocessor/seq/pop_front.hpp | 27 + .../boost/preprocessor/seq/push_back.hpp | 19 + .../boost/preprocessor/seq/push_front.hpp | 19 + thirdparty/boost/preprocessor/seq/remove.hpp | 29 + thirdparty/boost/preprocessor/seq/replace.hpp | 29 + thirdparty/boost/preprocessor/seq/rest_n.hpp | 30 + thirdparty/boost/preprocessor/seq/reverse.hpp | 39 + thirdparty/boost/preprocessor/seq/seq.hpp | 44 + thirdparty/boost/preprocessor/seq/size.hpp | 548 + thirdparty/boost/preprocessor/seq/subseq.hpp | 28 + .../boost/preprocessor/seq/to_array.hpp | 28 + .../boost/preprocessor/seq/to_tuple.hpp | 27 + .../boost/preprocessor/seq/transform.hpp | 48 + thirdparty/boost/preprocessor/slot.hpp | 17 + .../boost/preprocessor/slot/counter.hpp | 25 + .../preprocessor/slot/detail/counter.hpp | 269 + .../boost/preprocessor/slot/detail/def.hpp | 49 + .../boost/preprocessor/slot/detail/shared.hpp | 247 + .../boost/preprocessor/slot/detail/slot1.hpp | 267 + .../boost/preprocessor/slot/detail/slot2.hpp | 267 + .../boost/preprocessor/slot/detail/slot3.hpp | 267 + .../boost/preprocessor/slot/detail/slot4.hpp | 267 + .../boost/preprocessor/slot/detail/slot5.hpp | 267 + thirdparty/boost/preprocessor/slot/slot.hpp | 32 + thirdparty/boost/preprocessor/stringize.hpp | 33 + thirdparty/boost/preprocessor/tuple.hpp | 24 + thirdparty/boost/preprocessor/tuple/eat.hpp | 57 + thirdparty/boost/preprocessor/tuple/elem.hpp | 385 + thirdparty/boost/preprocessor/tuple/rem.hpp | 72 + .../boost/preprocessor/tuple/reverse.hpp | 62 + .../boost/preprocessor/tuple/to_list.hpp | 62 + .../boost/preprocessor/tuple/to_seq.hpp | 60 + thirdparty/boost/preprocessor/while.hpp | 17 + thirdparty/boost/preprocessor/wstringize.hpp | 29 + thirdparty/boost/program_options.hpp | 25 + thirdparty/boost/program_options/cmdline.hpp | 85 + thirdparty/boost/program_options/config.hpp | 55 + .../boost/program_options/detail/cmdline.hpp | 136 + .../program_options/detail/config_file.hpp | 182 + .../boost/program_options/detail/convert.hpp | 107 + .../boost/program_options/detail/parsers.hpp | 144 + .../detail/utf8_codecvt_facet.hpp | 25 + .../program_options/detail/value_semantic.hpp | 208 + .../program_options/environment_iterator.hpp | 51 + .../boost/program_options/eof_iterator.hpp | 97 + thirdparty/boost/program_options/errors.hpp | 146 + thirdparty/boost/program_options/option.hpp | 60 + .../program_options/options_description.hpp | 241 + thirdparty/boost/program_options/parsers.hpp | 229 + .../program_options/positional_options.hpp | 65 + .../boost/program_options/value_semantic.hpp | 390 + .../boost/program_options/variables_map.hpp | 199 + thirdparty/boost/program_options/version.hpp | 19 + thirdparty/boost/progress.hpp | 143 + thirdparty/boost/property_map.hpp | 568 + thirdparty/boost/property_map_iterator.hpp | 113 + .../boost/ptr_container/clone_allocator.hpp | 86 + .../detail/associative_ptr_container.hpp | 247 + .../ptr_container/detail/default_deleter.hpp | 69 + .../ptr_container/detail/is_convertible.hpp | 73 + .../ptr_container/detail/map_iterator.hpp | 87 + .../boost/ptr_container/detail/move.hpp | 44 + .../detail/reversible_ptr_container.hpp | 660 + .../ptr_container/detail/scoped_deleter.hpp | 121 + .../detail/serialize_ptr_map_adapter.hpp | 86 + .../detail/serialize_reversible_cont.hpp | 91 + .../detail/serialize_xml_names.hpp | 26 + .../ptr_container/detail/static_move_ptr.hpp | 211 + .../ptr_container/detail/throw_exception.hpp | 33 + .../detail/void_ptr_iterator.hpp | 229 + thirdparty/boost/ptr_container/exception.hpp | 58 + .../boost/ptr_container/indirect_fun.hpp | 133 + thirdparty/boost/ptr_container/nullable.hpp | 73 + thirdparty/boost/ptr_container/ptr_array.hpp | 245 + .../boost/ptr_container/ptr_container.hpp | 27 + thirdparty/boost/ptr_container/ptr_deque.hpp | 69 + thirdparty/boost/ptr_container/ptr_list.hpp | 94 + thirdparty/boost/ptr_container/ptr_map.hpp | 151 + .../boost/ptr_container/ptr_map_adapter.hpp | 679 + .../ptr_container/ptr_sequence_adapter.hpp | 669 + thirdparty/boost/ptr_container/ptr_set.hpp | 137 + .../boost/ptr_container/ptr_set_adapter.hpp | 565 + thirdparty/boost/ptr_container/ptr_vector.hpp | 77 + .../ptr_container/serialize_ptr_array.hpp | 47 + .../ptr_container/serialize_ptr_container.hpp | 16 + .../ptr_container/serialize_ptr_deque.hpp | 27 + .../ptr_container/serialize_ptr_list.hpp | 27 + .../boost/ptr_container/serialize_ptr_map.hpp | 33 + .../boost/ptr_container/serialize_ptr_set.hpp | 33 + .../ptr_container/serialize_ptr_vector.hpp | 40 + thirdparty/boost/python.hpp | 73 + thirdparty/boost/python/arg_from_python.hpp | 76 + thirdparty/boost/python/args.hpp | 175 + thirdparty/boost/python/args_fwd.hpp | 52 + thirdparty/boost/python/back_reference.hpp | 102 + thirdparty/boost/python/base_type_traits.hpp | 43 + thirdparty/boost/python/bases.hpp | 68 + thirdparty/boost/python/borrowed.hpp | 21 + thirdparty/boost/python/call.hpp | 79 + thirdparty/boost/python/call_method.hpp | 79 + thirdparty/boost/python/cast.hpp | 106 + thirdparty/boost/python/class.hpp | 654 + thirdparty/boost/python/class_fwd.hpp | 24 + .../python/converter/arg_from_python.hpp | 336 + .../boost/python/converter/arg_to_python.hpp | 261 + .../python/converter/arg_to_python_base.hpp | 32 + .../converter/as_to_python_function.hpp | 49 + .../python/converter/builtin_converters.hpp | 153 + .../python/converter/constructor_function.hpp | 17 + .../converter/context_result_converter.hpp | 17 + .../python/converter/convertible_function.hpp | 14 + .../boost/python/converter/from_python.hpp | 41 + .../boost/python/converter/implicit.hpp | 46 + .../converter/obj_mgr_arg_from_python.hpp | 121 + .../boost/python/converter/object_manager.hpp | 230 + .../python/converter/pointer_type_id.hpp | 68 + .../python/converter/pyobject_traits.hpp | 44 + .../boost/python/converter/pyobject_type.hpp | 37 + .../python/converter/pytype_function.hpp | 132 + .../converter/pytype_object_mgr_traits.hpp | 42 + .../boost/python/converter/registered.hpp | 111 + .../python/converter/registered_pointee.hpp | 62 + .../boost/python/converter/registrations.hpp | 99 + .../boost/python/converter/registry.hpp | 55 + .../python/converter/return_from_python.hpp | 162 + .../converter/rvalue_from_python_data.hpp | 140 + .../python/converter/shared_ptr_deleter.hpp | 22 + .../converter/shared_ptr_from_python.hpp | 59 + .../python/converter/shared_ptr_to_python.hpp | 28 + .../converter/to_python_function_type.hpp | 19 + .../boost/python/copy_const_reference.hpp | 43 + .../boost/python/copy_non_const_reference.hpp | 43 + thirdparty/boost/python/data_members.hpp | 316 + thirdparty/boost/python/def.hpp | 114 + thirdparty/boost/python/def_visitor.hpp | 86 + .../boost/python/default_call_policies.hpp | 91 + .../boost/python/detail/aix_init_module.hpp | 26 + .../boost/python/detail/api_placeholder.hpp | 15 + .../boost/python/detail/borrowed_ptr.hpp | 111 + thirdparty/boost/python/detail/caller.hpp | 259 + thirdparty/boost/python/detail/config.hpp | 141 + thirdparty/boost/python/detail/construct.hpp | 42 + .../boost/python/detail/convertible.hpp | 38 + .../python/detail/copy_ctor_mutates_rhs.hpp | 21 + .../boost/python/detail/cv_category.hpp | 36 + thirdparty/boost/python/detail/dealloc.hpp | 17 + .../boost/python/detail/decorated_type_id.hpp | 76 + .../boost/python/detail/decref_guard.hpp | 21 + thirdparty/boost/python/detail/def_helper.hpp | 212 + .../boost/python/detail/def_helper_fwd.hpp | 17 + .../boost/python/detail/defaults_def.hpp | 291 + .../boost/python/detail/defaults_gen.hpp | 388 + thirdparty/boost/python/detail/dependent.hpp | 27 + thirdparty/boost/python/detail/destroy.hpp | 106 + thirdparty/boost/python/detail/enable_if.hpp | 72 + .../boost/python/detail/exception_handler.hpp | 48 + .../boost/python/detail/force_instantiate.hpp | 32 + thirdparty/boost/python/detail/if_else.hpp | 116 + .../boost/python/detail/indirect_traits.hpp | 13 + thirdparty/boost/python/detail/invoke.hpp | 100 + .../boost/python/detail/is_auto_ptr.hpp | 30 + .../boost/python/detail/is_shared_ptr.hpp | 17 + thirdparty/boost/python/detail/is_wrapper.hpp | 29 + thirdparty/boost/python/detail/is_xxx.hpp | 13 + .../python/detail/make_keyword_range_fn.hpp | 72 + thirdparty/boost/python/detail/make_tuple.hpp | 32 + thirdparty/boost/python/detail/map_entry.hpp | 43 + thirdparty/boost/python/detail/mpl_lambda.hpp | 12 + .../boost/python/detail/msvc_typeinfo.hpp | 75 + thirdparty/boost/python/detail/none.hpp | 20 + .../boost/python/detail/not_specified.hpp | 14 + .../detail/nullary_function_adaptor.hpp | 46 + .../boost/python/detail/operator_id.hpp | 56 + .../boost/python/detail/overloads_fwd.hpp | 18 + thirdparty/boost/python/detail/pointee.hpp | 35 + thirdparty/boost/python/detail/prefix.hpp | 16 + .../boost/python/detail/preprocessor.hpp | 66 + .../boost/python/detail/python22_fixed.h | 152 + .../boost/python/detail/python_type.hpp | 37 + .../boost/python/detail/raw_pyobject.hpp | 32 + .../boost/python/detail/referent_storage.hpp | 76 + thirdparty/boost/python/detail/result.hpp | 131 + thirdparty/boost/python/detail/scope.hpp | 16 + thirdparty/boost/python/detail/sfinae.hpp | 13 + thirdparty/boost/python/detail/signature.hpp | 106 + .../boost/python/detail/string_literal.hpp | 88 + thirdparty/boost/python/detail/target.hpp | 82 + .../python/detail/translate_exception.hpp | 67 + thirdparty/boost/python/detail/type_list.hpp | 39 + .../boost/python/detail/type_list_impl.hpp | 57 + .../python/detail/type_list_impl_no_pts.hpp | 107 + .../boost/python/detail/unwind_type.hpp | 170 + .../boost/python/detail/unwrap_type_id.hpp | 31 + .../boost/python/detail/unwrap_wrapper.hpp | 34 + thirdparty/boost/python/detail/value_arg.hpp | 27 + .../python/detail/value_is_shared_ptr.hpp | 17 + .../boost/python/detail/value_is_xxx.hpp | 62 + thirdparty/boost/python/detail/void_ptr.hpp | 35 + .../boost/python/detail/void_return.hpp | 42 + .../boost/python/detail/wrap_python.hpp | 192 + .../boost/python/detail/wrapper_base.hpp | 90 + thirdparty/boost/python/dict.hpp | 152 + thirdparty/boost/python/docstring_options.hpp | 127 + thirdparty/boost/python/enum.hpp | 104 + thirdparty/boost/python/errors.hpp | 55 + .../boost/python/exception_translator.hpp | 27 + thirdparty/boost/python/exec.hpp | 40 + thirdparty/boost/python/extract.hpp | 261 + thirdparty/boost/python/handle.hpp | 264 + thirdparty/boost/python/handle_fwd.hpp | 16 + .../boost/python/has_back_reference.hpp | 24 + thirdparty/boost/python/implicit.hpp | 36 + thirdparty/boost/python/import.hpp | 22 + thirdparty/boost/python/init.hpp | 421 + thirdparty/boost/python/instance_holder.hpp | 63 + thirdparty/boost/python/iterator.hpp | 127 + thirdparty/boost/python/list.hpp | 142 + thirdparty/boost/python/long.hpp | 68 + .../boost/python/lvalue_from_pytype.hpp | 116 + thirdparty/boost/python/make_constructor.hpp | 290 + thirdparty/boost/python/make_function.hpp | 153 + thirdparty/boost/python/manage_new_object.hpp | 41 + thirdparty/boost/python/module.hpp | 13 + thirdparty/boost/python/module_init.hpp | 53 + thirdparty/boost/python/numeric.hpp | 242 + thirdparty/boost/python/object.hpp | 27 + .../boost/python/object/add_to_namespace.hpp | 23 + thirdparty/boost/python/object/class.hpp | 64 + .../boost/python/object/class_detail.hpp | 19 + .../boost/python/object/class_metadata.hpp | 297 + .../boost/python/object/class_wrapper.hpp | 51 + thirdparty/boost/python/object/enum_base.hpp | 36 + .../boost/python/object/find_instance.hpp | 21 + thirdparty/boost/python/object/forward.hpp | 194 + thirdparty/boost/python/object/function.hpp | 80 + .../python/object/function_doc_signature.hpp | 36 + .../boost/python/object/function_handle.hpp | 44 + .../boost/python/object/function_object.hpp | 40 + .../boost/python/object/inheritance.hpp | 132 + .../boost/python/object/inheritance_query.hpp | 17 + thirdparty/boost/python/object/instance.hpp | 51 + thirdparty/boost/python/object/iterator.hpp | 254 + .../boost/python/object/iterator_core.hpp | 17 + .../boost/python/object/life_support.hpp | 15 + .../boost/python/object/make_holder.hpp | 105 + .../boost/python/object/make_instance.hpp | 75 + .../boost/python/object/make_ptr_instance.hpp | 72 + .../boost/python/object/pickle_support.hpp | 124 + .../boost/python/object/pointer_holder.hpp | 208 + .../boost/python/object/py_function.hpp | 172 + .../boost/python/object/stl_iterator_core.hpp | 27 + .../boost/python/object/value_holder.hpp | 166 + .../boost/python/object/value_holder_fwd.hpp | 16 + thirdparty/boost/python/object_attributes.hpp | 68 + thirdparty/boost/python/object_call.hpp | 23 + thirdparty/boost/python/object_core.hpp | 488 + thirdparty/boost/python/object_fwd.hpp | 18 + thirdparty/boost/python/object_items.hpp | 89 + thirdparty/boost/python/object_operators.hpp | 132 + thirdparty/boost/python/object_protocol.hpp | 88 + .../boost/python/object_protocol_core.hpp | 53 + thirdparty/boost/python/object_slices.hpp | 142 + .../boost/python/opaque_pointer_converter.hpp | 200 + thirdparty/boost/python/operators.hpp | 366 + thirdparty/boost/python/other.hpp | 114 + thirdparty/boost/python/overloads.hpp | 13 + thirdparty/boost/python/override.hpp | 144 + thirdparty/boost/python/pointee.hpp | 43 + thirdparty/boost/python/proxy.hpp | 101 + thirdparty/boost/python/ptr.hpp | 128 + thirdparty/boost/python/pure_virtual.hpp | 124 + thirdparty/boost/python/raw_function.hpp | 61 + thirdparty/boost/python/refcount.hpp | 41 + .../python/reference_existing_object.hpp | 46 + .../boost/python/register_ptr_to_python.hpp | 31 + thirdparty/boost/python/return_arg.hpp | 110 + thirdparty/boost/python/return_by_value.hpp | 31 + .../python/return_internal_reference.hpp | 43 + .../boost/python/return_opaque_pointer.hpp | 47 + .../boost/python/return_value_policy.hpp | 21 + thirdparty/boost/python/scope.hpp | 78 + thirdparty/boost/python/self.hpp | 33 + thirdparty/boost/python/signature.hpp | 179 + thirdparty/boost/python/slice.hpp | 266 + thirdparty/boost/python/slice_nil.hpp | 44 + thirdparty/boost/python/ssize_t.hpp | 29 + thirdparty/boost/python/stl_iterator.hpp | 61 + thirdparty/boost/python/str.hpp | 414 + .../python/suite/indexing/container_utils.hpp | 52 + .../indexing/detail/indexing_suite_detail.hpp | 759 + .../python/suite/indexing/indexing_suite.hpp | 299 + .../suite/indexing/map_indexing_suite.hpp | 181 + .../suite/indexing/vector_indexing_suite.hpp | 242 + thirdparty/boost/python/tag.hpp | 18 + .../boost/python/to_python_converter.hpp | 99 + .../boost/python/to_python_indirect.hpp | 113 + thirdparty/boost/python/to_python_value.hpp | 176 + thirdparty/boost/python/tuple.hpp | 70 + thirdparty/boost/python/type_id.hpp | 191 + .../boost/python/with_custodian_and_ward.hpp | 124 + thirdparty/boost/python/wrapper.hpp | 35 + thirdparty/boost/random.hpp | 72 + thirdparty/boost/random/additive_combine.hpp | 125 + .../boost/random/bernoulli_distribution.hpp | 80 + .../boost/random/binomial_distribution.hpp | 81 + .../boost/random/cauchy_distribution.hpp | 89 + thirdparty/boost/random/detail/const_mod.hpp | 359 + .../boost/random/detail/iterator_mixin.hpp | 45 + .../random/detail/pass_through_engine.hpp | 98 + thirdparty/boost/random/detail/ptr_helper.hpp | 94 + .../random/detail/signed_unsigned_tools.hpp | 164 + .../boost/random/detail/uniform_int_float.hpp | 84 + thirdparty/boost/random/discard_block.hpp | 121 + .../boost/random/exponential_distribution.hpp | 81 + .../boost/random/gamma_distribution.hpp | 133 + .../boost/random/geometric_distribution.hpp | 97 + .../boost/random/inversive_congruential.hpp | 128 + thirdparty/boost/random/lagged_fibonacci.hpp | 464 + .../boost/random/linear_congruential.hpp | 258 + .../boost/random/linear_feedback_shift.hpp | 145 + .../boost/random/lognormal_distribution.hpp | 114 + thirdparty/boost/random/mersenne_twister.hpp | 302 + .../boost/random/normal_distribution.hpp | 111 + .../boost/random/poisson_distribution.hpp | 99 + .../boost/random/random_number_generator.hpp | 56 + thirdparty/boost/random/ranlux.hpp | 50 + thirdparty/boost/random/shuffle_output.hpp | 175 + .../boost/random/subtract_with_carry.hpp | 445 + .../boost/random/triangle_distribution.hpp | 101 + thirdparty/boost/random/uniform_01.hpp | 97 + thirdparty/boost/random/uniform_int.hpp | 161 + thirdparty/boost/random/uniform_on_sphere.hpp | 86 + thirdparty/boost/random/uniform_real.hpp | 83 + thirdparty/boost/random/uniform_smallint.hpp | 236 + thirdparty/boost/random/variate_generator.hpp | 133 + thirdparty/boost/random/xor_combine.hpp | 130 + thirdparty/boost/range.hpp | 33 + thirdparty/boost/range/as_array.hpp | 45 + thirdparty/boost/range/as_literal.hpp | 131 + thirdparty/boost/range/atl.hpp | 733 + thirdparty/boost/range/begin.hpp | 132 + thirdparty/boost/range/category.hpp | 29 + thirdparty/boost/range/concepts.hpp | 140 + thirdparty/boost/range/config.hpp | 54 + thirdparty/boost/range/const_iterator.hpp | 64 + .../boost/range/const_reverse_iterator.hpp | 32 + thirdparty/boost/range/detail/as_literal.hpp | 33 + thirdparty/boost/range/detail/begin.hpp | 92 + .../boost/range/detail/collection_traits.hpp | 266 + .../range/detail/collection_traits_detail.hpp | 621 + thirdparty/boost/range/detail/common.hpp | 117 + .../boost/range/detail/const_iterator.hpp | 71 + thirdparty/boost/range/detail/detail_str.hpp | 376 + .../boost/range/detail/difference_type.hpp | 121 + thirdparty/boost/range/detail/empty.hpp | 120 + thirdparty/boost/range/detail/end.hpp | 98 + .../range/detail/implementation_help.hpp | 99 + thirdparty/boost/range/detail/iterator.hpp | 78 + thirdparty/boost/range/detail/microsoft.hpp | 931 ++ .../boost/range/detail/remove_extent.hpp | 157 + thirdparty/boost/range/detail/sfinae.hpp | 77 + thirdparty/boost/range/detail/size.hpp | 159 + thirdparty/boost/range/detail/size_type.hpp | 70 + thirdparty/boost/range/detail/sizer.hpp | 35 + thirdparty/boost/range/detail/str_types.hpp | 38 + thirdparty/boost/range/detail/value_type.hpp | 72 + thirdparty/boost/range/detail/vc6/end.hpp | 170 + thirdparty/boost/range/detail/vc6/size.hpp | 166 + thirdparty/boost/range/difference_type.hpp | 29 + thirdparty/boost/range/distance.hpp | 34 + thirdparty/boost/range/empty.hpp | 34 + thirdparty/boost/range/end.hpp | 131 + thirdparty/boost/range/functions.hpp | 27 + thirdparty/boost/range/iterator.hpp | 72 + thirdparty/boost/range/iterator_range.hpp | 643 + thirdparty/boost/range/metafunctions.hpp | 30 + thirdparty/boost/range/mfc.hpp | 984 ++ thirdparty/boost/range/mutable_iterator.hpp | 64 + thirdparty/boost/range/pointer.hpp | 29 + thirdparty/boost/range/rbegin.hpp | 65 + thirdparty/boost/range/reference.hpp | 29 + thirdparty/boost/range/rend.hpp | 65 + thirdparty/boost/range/result_iterator.hpp | 33 + thirdparty/boost/range/reverse_iterator.hpp | 40 + .../boost/range/reverse_result_iterator.hpp | 32 + thirdparty/boost/range/size.hpp | 36 + thirdparty/boost/range/size_type.hpp | 78 + thirdparty/boost/range/sub_range.hpp | 167 + thirdparty/boost/range/value_type.hpp | 34 + thirdparty/boost/rational.hpp | 598 + thirdparty/boost/ref.hpp | 178 + thirdparty/boost/regex.h | 100 + thirdparty/boost/regex.hpp | 37 + thirdparty/boost/regex/concepts.hpp | 870 ++ thirdparty/boost/regex/config.hpp | 417 + thirdparty/boost/regex/config/borland.hpp | 72 + thirdparty/boost/regex/config/cwchar.hpp | 207 + thirdparty/boost/regex/icu.hpp | 1017 ++ thirdparty/boost/regex/mfc.hpp | 190 + thirdparty/boost/regex/pattern_except.hpp | 100 + .../boost/regex/pending/object_cache.hpp | 163 + .../boost/regex/pending/static_mutex.hpp | 184 + .../boost/regex/pending/unicode_iterator.hpp | 691 + thirdparty/boost/regex/regex_traits.hpp | 35 + thirdparty/boost/regex/user.hpp | 90 + thirdparty/boost/regex/v4/basic_regex.hpp | 652 + .../boost/regex/v4/basic_regex_creator.hpp | 1319 ++ .../boost/regex/v4/basic_regex_parser.hpp | 2114 +++ thirdparty/boost/regex/v4/c_regex_traits.hpp | 211 + .../boost/regex/v4/char_regex_traits.hpp | 81 + .../boost/regex/v4/cpp_regex_traits.hpp | 1057 ++ thirdparty/boost/regex/v4/cregex.hpp | 329 + thirdparty/boost/regex/v4/error_type.hpp | 58 + thirdparty/boost/regex/v4/fileiter.hpp | 455 + thirdparty/boost/regex/v4/instances.hpp | 206 + .../boost/regex/v4/iterator_category.hpp | 87 + thirdparty/boost/regex/v4/iterator_traits.hpp | 135 + thirdparty/boost/regex/v4/match_flags.hpp | 138 + thirdparty/boost/regex/v4/match_results.hpp | 427 + thirdparty/boost/regex/v4/mem_block_cache.hpp | 99 + thirdparty/boost/regex/v4/perl_matcher.hpp | 550 + .../boost/regex/v4/perl_matcher_common.hpp | 971 ++ .../regex/v4/perl_matcher_non_recursive.hpp | 1389 ++ .../boost/regex/v4/perl_matcher_recursive.hpp | 854 ++ .../boost/regex/v4/primary_transform.hpp | 146 + thirdparty/boost/regex/v4/protected_call.hpp | 81 + thirdparty/boost/regex/v4/regbase.hpp | 176 + thirdparty/boost/regex/v4/regex.hpp | 202 + thirdparty/boost/regex/v4/regex_format.hpp | 654 + thirdparty/boost/regex/v4/regex_fwd.hpp | 73 + thirdparty/boost/regex/v4/regex_grep.hpp | 155 + thirdparty/boost/regex/v4/regex_iterator.hpp | 201 + thirdparty/boost/regex/v4/regex_match.hpp | 382 + thirdparty/boost/regex/v4/regex_merge.hpp | 93 + .../boost/regex/v4/regex_raw_buffer.hpp | 210 + thirdparty/boost/regex/v4/regex_replace.hpp | 122 + thirdparty/boost/regex/v4/regex_search.hpp | 217 + thirdparty/boost/regex/v4/regex_split.hpp | 172 + .../boost/regex/v4/regex_token_iterator.hpp | 342 + thirdparty/boost/regex/v4/regex_traits.hpp | 189 + .../boost/regex/v4/regex_traits_defaults.hpp | 331 + .../boost/regex/v4/regex_workaround.hpp | 202 + thirdparty/boost/regex/v4/states.hpp | 290 + thirdparty/boost/regex/v4/sub_match.hpp | 509 + thirdparty/boost/regex/v4/syntax_type.hpp | 102 + .../boost/regex/v4/u32regex_iterator.hpp | 193 + .../regex/v4/u32regex_token_iterator.hpp | 377 + .../boost/regex/v4/w32_regex_traits.hpp | 731 + thirdparty/boost/regex_fwd.hpp | 33 + thirdparty/boost/scoped_array.hpp | 135 + thirdparty/boost/scoped_ptr.hpp | 157 + thirdparty/boost/serialization/access.hpp | 130 + thirdparty/boost/serialization/array.hpp | 107 + .../boost/serialization/base_object.hpp | 103 + .../boost/serialization/binary_object.hpp | 98 + .../serialization/collection_size_type.hpp | 20 + .../boost/serialization/collection_traits.hpp | 86 + .../serialization/collections_load_imp.hpp | 142 + .../serialization/collections_save_imp.hpp | 68 + thirdparty/boost/serialization/complex.hpp | 84 + thirdparty/boost/serialization/config.hpp | 74 + thirdparty/boost/serialization/deque.hpp | 75 + .../boost/serialization/detail/get_data.hpp | 55 + .../serialization/detail/shared_count_132.hpp | 567 + .../serialization/detail/shared_ptr_132.hpp | 482 + .../detail/shared_ptr_nmt_132.hpp | 182 + .../detail/stack_constructor.hpp | 73 + thirdparty/boost/serialization/ephemeral.hpp | 79 + thirdparty/boost/serialization/export.hpp | 207 + .../serialization/extended_type_info.hpp | 94 + .../extended_type_info_no_rtti.hpp | 133 + .../extended_type_info_typeid.hpp | 138 + .../boost/serialization/force_include.hpp | 61 + .../hash_collections_load_imp.hpp | 58 + .../hash_collections_save_imp.hpp | 66 + thirdparty/boost/serialization/hash_map.hpp | 175 + thirdparty/boost/serialization/hash_set.hpp | 178 + .../boost/serialization/is_abstract.hpp | 45 + .../serialization/is_bitwise_serializable.hpp | 46 + thirdparty/boost/serialization/level.hpp | 120 + thirdparty/boost/serialization/level_enum.hpp | 55 + thirdparty/boost/serialization/list.hpp | 77 + thirdparty/boost/serialization/map.hpp | 118 + thirdparty/boost/serialization/nvp.hpp | 143 + thirdparty/boost/serialization/optional.hpp | 112 + thirdparty/boost/serialization/scoped_ptr.hpp | 58 + .../boost/serialization/serialization.hpp | 179 + thirdparty/boost/serialization/set.hpp | 120 + thirdparty/boost/serialization/shared_ptr.hpp | 158 + .../boost/serialization/shared_ptr_132.hpp | 222 + thirdparty/boost/serialization/slist.hpp | 94 + thirdparty/boost/serialization/split_free.hpp | 93 + .../boost/serialization/split_member.hpp | 86 + thirdparty/boost/serialization/string.hpp | 91 + thirdparty/boost/serialization/tracking.hpp | 112 + .../boost/serialization/tracking_enum.hpp | 41 + thirdparty/boost/serialization/traits.hpp | 65 + .../type_info_implementation.hpp | 86 + thirdparty/boost/serialization/utility.hpp | 55 + thirdparty/boost/serialization/valarray.hpp | 74 + thirdparty/boost/serialization/variant.hpp | 161 + thirdparty/boost/serialization/vector.hpp | 187 + thirdparty/boost/serialization/version.hpp | 87 + thirdparty/boost/serialization/void_cast.hpp | 226 + .../boost/serialization/void_cast_fwd.hpp | 34 + thirdparty/boost/serialization/weak_ptr.hpp | 58 + thirdparty/boost/serialization/wrapper.hpp | 63 + thirdparty/boost/shared_array.hpp | 193 + .../boost/shared_container_iterator.hpp | 62 + thirdparty/boost/shared_ptr.hpp | 619 + thirdparty/boost/signal.hpp | 358 + thirdparty/boost/signals.hpp | 10 + thirdparty/boost/signals/connection.hpp | 213 + thirdparty/boost/signals/detail/config.hpp | 54 + .../boost/signals/detail/gen_signal_N.pl | 132 + .../boost/signals/detail/named_slot_map.hpp | 193 + .../boost/signals/detail/signal_base.hpp | 159 + .../boost/signals/detail/signals_common.hpp | 162 + .../signals/detail/slot_call_iterator.hpp | 95 + thirdparty/boost/signals/signal0.hpp | 37 + thirdparty/boost/signals/signal1.hpp | 37 + thirdparty/boost/signals/signal10.hpp | 37 + thirdparty/boost/signals/signal2.hpp | 37 + thirdparty/boost/signals/signal3.hpp | 37 + thirdparty/boost/signals/signal4.hpp | 37 + thirdparty/boost/signals/signal5.hpp | 37 + thirdparty/boost/signals/signal6.hpp | 37 + thirdparty/boost/signals/signal7.hpp | 37 + thirdparty/boost/signals/signal8.hpp | 37 + thirdparty/boost/signals/signal9.hpp | 37 + thirdparty/boost/signals/signal_template.hpp | 410 + thirdparty/boost/signals/slot.hpp | 157 + thirdparty/boost/signals/trackable.hpp | 173 + thirdparty/boost/smart_cast.hpp | 298 + thirdparty/boost/smart_ptr.hpp | 25 + thirdparty/boost/spirit.hpp | 75 + thirdparty/boost/spirit/actor.hpp | 114 + .../boost/spirit/actor/assign_actor.hpp | 96 + .../boost/spirit/actor/assign_key_actor.hpp | 92 + thirdparty/boost/spirit/actor/clear_actor.hpp | 58 + .../boost/spirit/actor/decrement_actor.hpp | 56 + thirdparty/boost/spirit/actor/erase_actor.hpp | 85 + .../boost/spirit/actor/increment_actor.hpp | 56 + .../boost/spirit/actor/insert_at_actor.hpp | 117 + .../boost/spirit/actor/insert_key_actor.hpp | 93 + .../boost/spirit/actor/push_back_actor.hpp | 97 + .../boost/spirit/actor/push_front_actor.hpp | 87 + thirdparty/boost/spirit/actor/ref_actor.hpp | 65 + .../spirit/actor/ref_const_ref_actor.hpp | 73 + .../actor/ref_const_ref_const_ref_a.hpp | 82 + .../actor/ref_const_ref_value_actor.hpp | 73 + .../boost/spirit/actor/ref_value_actor.hpp | 65 + thirdparty/boost/spirit/actor/swap_actor.hpp | 81 + thirdparty/boost/spirit/actor/typeof.hpp | 70 + thirdparty/boost/spirit/attribute.hpp | 38 + thirdparty/boost/spirit/attribute/closure.hpp | 1079 ++ .../spirit/attribute/closure_context.hpp | 51 + .../boost/spirit/attribute/closure_fwd.hpp | 65 + .../boost/spirit/attribute/parametric.hpp | 140 + thirdparty/boost/spirit/attribute/typeof.hpp | 64 + thirdparty/boost/spirit/core.hpp | 74 + thirdparty/boost/spirit/core/assert.hpp | 39 + .../boost/spirit/core/composite/actions.hpp | 123 + .../spirit/core/composite/alternative.hpp | 134 + .../boost/spirit/core/composite/composite.hpp | 138 + .../spirit/core/composite/difference.hpp | 137 + .../spirit/core/composite/directives.hpp | 603 + .../boost/spirit/core/composite/epsilon.hpp | 272 + .../spirit/core/composite/exclusive_or.hpp | 138 + .../core/composite/impl/alternative.ipp | 86 + .../spirit/core/composite/impl/difference.ipp | 86 + .../spirit/core/composite/impl/directives.ipp | 370 + .../core/composite/impl/exclusive_or.ipp | 86 + .../core/composite/impl/intersection.ipp | 86 + .../core/composite/impl/kleene_star.ipp | 30 + .../boost/spirit/core/composite/impl/list.ipp | 89 + .../spirit/core/composite/impl/optional.ipp | 30 + .../spirit/core/composite/impl/positive.ipp | 30 + .../spirit/core/composite/impl/sequence.ipp | 86 + .../core/composite/impl/sequential_and.ipp | 86 + .../core/composite/impl/sequential_or.ipp | 86 + .../spirit/core/composite/intersection.hpp | 138 + .../spirit/core/composite/kleene_star.hpp | 96 + .../boost/spirit/core/composite/list.hpp | 69 + .../spirit/core/composite/no_actions.hpp | 163 + .../boost/spirit/core/composite/operators.hpp | 26 + .../boost/spirit/core/composite/optional.hpp | 90 + .../boost/spirit/core/composite/positive.hpp | 99 + .../boost/spirit/core/composite/sequence.hpp | 129 + .../spirit/core/composite/sequential_and.hpp | 72 + .../spirit/core/composite/sequential_or.hpp | 150 + thirdparty/boost/spirit/core/config.hpp | 63 + thirdparty/boost/spirit/core/impl/match.ipp | 109 + .../spirit/core/impl/match_attr_traits.ipp | 94 + thirdparty/boost/spirit/core/impl/parser.ipp | 51 + thirdparty/boost/spirit/core/match.hpp | 181 + thirdparty/boost/spirit/core/nil.hpp | 19 + .../spirit/core/non_terminal/grammar.hpp | 81 + .../spirit/core/non_terminal/impl/grammar.ipp | 403 + .../core/non_terminal/impl/object_with_id.ipp | 185 + .../spirit/core/non_terminal/impl/rule.ipp | 407 + .../spirit/core/non_terminal/impl/static.hpp | 112 + .../spirit/core/non_terminal/impl/subrule.ipp | 205 + .../core/non_terminal/parser_context.hpp | 147 + .../spirit/core/non_terminal/parser_id.hpp | 118 + .../boost/spirit/core/non_terminal/rule.hpp | 171 + .../spirit/core/non_terminal/subrule.hpp | 296 + .../spirit/core/non_terminal/subrule_fwd.hpp | 31 + thirdparty/boost/spirit/core/parser.hpp | 219 + .../spirit/core/primitives/impl/numerics.ipp | 474 + .../core/primitives/impl/primitives.ipp | 470 + .../boost/spirit/core/primitives/numerics.hpp | 285 + .../spirit/core/primitives/numerics_fwd.hpp | 83 + .../spirit/core/primitives/primitives.hpp | 650 + thirdparty/boost/spirit/core/safe_bool.hpp | 59 + .../spirit/core/scanner/impl/skipper.ipp | 177 + .../boost/spirit/core/scanner/scanner.hpp | 324 + .../boost/spirit/core/scanner/scanner_fwd.hpp | 48 + .../boost/spirit/core/scanner/skipper.hpp | 192 + .../boost/spirit/core/scanner/skipper_fwd.hpp | 28 + thirdparty/boost/spirit/core/typeof.hpp | 335 + thirdparty/boost/spirit/debug.hpp | 146 + thirdparty/boost/spirit/debug/debug_node.hpp | 315 + .../boost/spirit/debug/impl/parser_names.ipp | 551 + thirdparty/boost/spirit/debug/minimal.hpp | 82 + .../boost/spirit/debug/parser_names.hpp | 250 + thirdparty/boost/spirit/debug/typeof.hpp | 36 + thirdparty/boost/spirit/dynamic.hpp | 29 + thirdparty/boost/spirit/dynamic/for.hpp | 183 + thirdparty/boost/spirit/dynamic/if.hpp | 225 + .../boost/spirit/dynamic/impl/conditions.ipp | 100 + .../boost/spirit/dynamic/impl/select.ipp | 115 + .../boost/spirit/dynamic/impl/switch.ipp | 569 + thirdparty/boost/spirit/dynamic/lazy.hpp | 62 + .../boost/spirit/dynamic/rule_alias.hpp | 72 + thirdparty/boost/spirit/dynamic/select.hpp | 237 + .../boost/spirit/dynamic/stored_rule.hpp | 123 + .../boost/spirit/dynamic/stored_rule_fwd.hpp | 27 + thirdparty/boost/spirit/dynamic/switch.hpp | 255 + thirdparty/boost/spirit/dynamic/typeof.hpp | 85 + thirdparty/boost/spirit/dynamic/while.hpp | 185 + thirdparty/boost/spirit/error_handling.hpp | 22 + .../spirit/error_handling/exceptions.hpp | 361 + .../spirit/error_handling/exceptions_fwd.hpp | 37 + .../spirit/error_handling/impl/exceptions.ipp | 85 + .../boost/spirit/error_handling/typeof.hpp | 34 + thirdparty/boost/spirit/iterator.hpp | 26 + .../boost/spirit/iterator/file_iterator.hpp | 225 + .../spirit/iterator/file_iterator_fwd.hpp | 34 + .../spirit/iterator/fixed_size_queue.hpp | 398 + .../spirit/iterator/impl/file_iterator.ipp | 459 + .../iterator/impl/position_iterator.ipp | 131 + .../boost/spirit/iterator/multi_pass.hpp | 1299 ++ .../boost/spirit/iterator/multi_pass_fwd.hpp | 42 + .../spirit/iterator/position_iterator.hpp | 429 + .../spirit/iterator/position_iterator_fwd.hpp | 56 + thirdparty/boost/spirit/iterator/typeof.hpp | 93 + thirdparty/boost/spirit/meta.hpp | 27 + thirdparty/boost/spirit/meta/as_parser.hpp | 109 + thirdparty/boost/spirit/meta/fundamental.hpp | 52 + .../boost/spirit/meta/impl/fundamental.ipp | 305 + .../boost/spirit/meta/impl/parser_traits.ipp | 187 + .../boost/spirit/meta/impl/refactoring.ipp | 447 + .../boost/spirit/meta/impl/traverse.ipp | 389 + .../boost/spirit/meta/parser_traits.hpp | 316 + thirdparty/boost/spirit/meta/refactoring.hpp | 274 + thirdparty/boost/spirit/meta/traverse.hpp | 218 + thirdparty/boost/spirit/phoenix.hpp | 26 + thirdparty/boost/spirit/phoenix/actor.hpp | 596 + thirdparty/boost/spirit/phoenix/binders.hpp | 4067 ++++++ thirdparty/boost/spirit/phoenix/casts.hpp | 1471 ++ thirdparty/boost/spirit/phoenix/closures.hpp | 440 + thirdparty/boost/spirit/phoenix/composite.hpp | 1423 ++ thirdparty/boost/spirit/phoenix/functions.hpp | 761 + thirdparty/boost/spirit/phoenix/new.hpp | 1316 ++ thirdparty/boost/spirit/phoenix/operators.hpp | 2204 +++ .../boost/spirit/phoenix/primitives.hpp | 248 + .../boost/spirit/phoenix/special_ops.hpp | 342 + .../boost/spirit/phoenix/statements.hpp | 444 + .../boost/spirit/phoenix/tuple_helpers.hpp | 1076 ++ thirdparty/boost/spirit/phoenix/tuples.hpp | 1330 ++ thirdparty/boost/spirit/symbols.hpp | 22 + .../boost/spirit/symbols/impl/symbols.ipp | 114 + thirdparty/boost/spirit/symbols/impl/tst.ipp | 277 + thirdparty/boost/spirit/symbols/symbols.hpp | 225 + .../boost/spirit/symbols/symbols_fwd.hpp | 34 + thirdparty/boost/spirit/symbols/typeof.hpp | 26 + thirdparty/boost/spirit/tree/ast.hpp | 384 + thirdparty/boost/spirit/tree/ast_fwd.hpp | 38 + thirdparty/boost/spirit/tree/common.hpp | 1583 ++ thirdparty/boost/spirit/tree/common_fwd.hpp | 92 + .../spirit/tree/impl/parse_tree_utils.ipp | 131 + .../boost/spirit/tree/impl/tree_to_xml.ipp | 521 + thirdparty/boost/spirit/tree/parse_tree.hpp | 293 + .../boost/spirit/tree/parse_tree_fwd.hpp | 34 + .../boost/spirit/tree/parse_tree_utils.hpp | 63 + thirdparty/boost/spirit/tree/parsetree.dtd | 21 + thirdparty/boost/spirit/tree/tree_to_xml.hpp | 111 + thirdparty/boost/spirit/tree/typeof.hpp | 81 + thirdparty/boost/spirit/utility.hpp | 41 + thirdparty/boost/spirit/utility/chset.hpp | 183 + .../boost/spirit/utility/chset_operators.hpp | 398 + thirdparty/boost/spirit/utility/confix.hpp | 392 + .../boost/spirit/utility/confix_fwd.hpp | 35 + thirdparty/boost/spirit/utility/distinct.hpp | 227 + .../boost/spirit/utility/distinct_fwd.hpp | 32 + .../boost/spirit/utility/escape_char.hpp | 180 + .../boost/spirit/utility/escape_char_fwd.hpp | 25 + .../boost/spirit/utility/flush_multi_pass.hpp | 73 + .../boost/spirit/utility/functor_parser.hpp | 67 + .../boost/spirit/utility/grammar_def.hpp | 303 + .../boost/spirit/utility/grammar_def_fwd.hpp | 48 + .../boost/spirit/utility/impl/chset.ipp | 362 + .../spirit/utility/impl/chset/basic_chset.hpp | 102 + .../spirit/utility/impl/chset/basic_chset.ipp | 241 + .../spirit/utility/impl/chset/range_run.hpp | 118 + .../spirit/utility/impl/chset/range_run.ipp | 214 + .../spirit/utility/impl/chset_operators.ipp | 662 + .../boost/spirit/utility/impl/confix.ipp | 217 + .../boost/spirit/utility/impl/escape_char.ipp | 220 + .../boost/spirit/utility/impl/lists.ipp | 164 + .../boost/spirit/utility/impl/regex.ipp | 77 + thirdparty/boost/spirit/utility/lists.hpp | 336 + thirdparty/boost/spirit/utility/lists_fwd.hpp | 27 + thirdparty/boost/spirit/utility/loops.hpp | 313 + thirdparty/boost/spirit/utility/regex.hpp | 108 + .../boost/spirit/utility/rule_parser.hpp | 1118 ++ .../boost/spirit/utility/scoped_lock.hpp | 108 + thirdparty/boost/spirit/utility/typeof.hpp | 146 + thirdparty/boost/spirit/version.hpp | 31 + thirdparty/boost/state_saver.hpp | 94 + .../statechart/asynchronous_state_machine.hpp | 89 + .../boost/statechart/custom_reaction.hpp | 74 + thirdparty/boost/statechart/deep_history.hpp | 63 + thirdparty/boost/statechart/deferral.hpp | 71 + .../detail/avoid_unused_warning.hpp | 31 + .../boost/statechart/detail/constructor.hpp | 139 + .../boost/statechart/detail/counted_base.hpp | 92 + .../boost/statechart/detail/leaf_state.hpp | 84 + thirdparty/boost/statechart/detail/memory.hpp | 72 + .../boost/statechart/detail/node_state.hpp | 156 + .../boost/statechart/detail/rtti_policy.hpp | 217 + .../boost/statechart/detail/state_base.hpp | 200 + thirdparty/boost/statechart/event.hpp | 74 + thirdparty/boost/statechart/event_base.hpp | 127 + .../boost/statechart/event_processor.hpp | 84 + .../boost/statechart/exception_translator.hpp | 58 + .../boost/statechart/fifo_scheduler.hpp | 203 + thirdparty/boost/statechart/fifo_worker.hpp | 198 + thirdparty/boost/statechart/history.hpp | 16 + .../boost/statechart/in_state_reaction.hpp | 91 + .../statechart/null_exception_translator.hpp | 44 + .../boost/statechart/processor_container.hpp | 384 + thirdparty/boost/statechart/result.hpp | 122 + .../boost/statechart/shallow_history.hpp | 63 + thirdparty/boost/statechart/simple_state.hpp | 996 ++ thirdparty/boost/statechart/state.hpp | 102 + thirdparty/boost/statechart/state_machine.hpp | 1054 ++ thirdparty/boost/statechart/termination.hpp | 71 + thirdparty/boost/statechart/transition.hpp | 148 + thirdparty/boost/static_assert.hpp | 122 + thirdparty/boost/static_warning.hpp | 180 + thirdparty/boost/strong_typedef.hpp | 66 + thirdparty/boost/system/config.hpp | 75 + thirdparty/boost/system/cygwin_error.hpp | 56 + thirdparty/boost/system/error_code.hpp | 495 + thirdparty/boost/system/linux_error.hpp | 110 + thirdparty/boost/system/system_error.hpp | 71 + thirdparty/boost/system/windows_error.hpp | 118 + thirdparty/boost/test/auto_unit_test.hpp | 20 + thirdparty/boost/test/debug.hpp | 101 + thirdparty/boost/test/debug_config.hpp | 24 + thirdparty/boost/test/detail/config.hpp | 106 + .../boost/test/detail/enable_warnings.hpp | 27 + thirdparty/boost/test/detail/fwd_decl.hpp | 47 + .../boost/test/detail/global_typedef.hpp | 72 + thirdparty/boost/test/detail/log_level.hpp | 43 + .../boost/test/detail/suppress_warnings.hpp | 28 + .../test/detail/unit_test_parameters.hpp | 64 + thirdparty/boost/test/detail/workaround.hpp | 62 + thirdparty/boost/test/exception_safety.hpp | 187 + thirdparty/boost/test/execution_monitor.hpp | 254 + .../boost/test/floating_point_comparison.hpp | 259 + thirdparty/boost/test/framework.hpp | 106 + .../test/impl/compiler_log_formatter.ipp | 195 + thirdparty/boost/test/impl/cpp_main.ipp | 139 + thirdparty/boost/test/impl/debug.ipp | 966 ++ .../boost/test/impl/exception_safety.ipp | 540 + .../boost/test/impl/execution_monitor.ipp | 1151 ++ thirdparty/boost/test/impl/framework.ipp | 482 + .../boost/test/impl/interaction_based.ipp | 94 + .../boost/test/impl/logged_expectations.ipp | 249 + .../test/impl/plain_report_formatter.ipp | 198 + .../boost/test/impl/progress_monitor.ipp | 108 + .../boost/test/impl/results_collector.ipp | 294 + .../boost/test/impl/results_reporter.ipp | 198 + thirdparty/boost/test/impl/test_main.ipp | 68 + thirdparty/boost/test/impl/test_tools.ipp | 629 + thirdparty/boost/test/impl/unit_test_log.ipp | 410 + thirdparty/boost/test/impl/unit_test_main.ipp | 235 + .../boost/test/impl/unit_test_monitor.ipp | 101 + .../boost/test/impl/unit_test_parameters.ipp | 387 + .../boost/test/impl/unit_test_suite.ipp | 339 + .../boost/test/impl/xml_log_formatter.ipp | 173 + .../boost/test/impl/xml_report_formatter.ipp | 115 + .../boost/test/included/prg_exec_monitor.hpp | 25 + .../boost/test/included/test_exec_monitor.hpp | 39 + thirdparty/boost/test/included/unit_test.hpp | 41 + .../test/included/unit_test_framework.hpp | 2 + thirdparty/boost/test/interaction_based.hpp | 259 + thirdparty/boost/test/logged_expectations.hpp | 74 + thirdparty/boost/test/minimal.hpp | 143 + thirdparty/boost/test/mock_object.hpp | 328 + .../test/output/compiler_log_formatter.hpp | 67 + .../test/output/plain_report_formatter.hpp | 62 + .../boost/test/output/xml_log_formatter.hpp | 71 + .../test/output/xml_report_formatter.hpp | 58 + thirdparty/boost/test/output_test_stream.hpp | 78 + thirdparty/boost/test/parameterized_test.hpp | 181 + thirdparty/boost/test/predicate_result.hpp | 83 + thirdparty/boost/test/prg_exec_monitor.hpp | 68 + thirdparty/boost/test/progress_monitor.hpp | 70 + thirdparty/boost/test/results_collector.hpp | 112 + thirdparty/boost/test/results_reporter.hpp | 88 + thirdparty/boost/test/test_case_template.hpp | 154 + thirdparty/boost/test/test_exec_monitor.hpp | 36 + thirdparty/boost/test/test_observer.hpp | 65 + thirdparty/boost/test/test_tools.hpp | 692 + thirdparty/boost/test/unit_test.hpp | 66 + thirdparty/boost/test/unit_test_log.hpp | 172 + .../boost/test/unit_test_log_formatter.hpp | 115 + thirdparty/boost/test/unit_test_monitor.hpp | 69 + thirdparty/boost/test/unit_test_suite.hpp | 209 + .../boost/test/unit_test_suite_impl.hpp | 351 + thirdparty/boost/test/utils/algorithm.hpp | 228 + thirdparty/boost/test/utils/assign_op.hpp | 41 + .../utils/basic_cstring/basic_cstring.hpp | 731 + .../utils/basic_cstring/basic_cstring_fwd.hpp | 40 + .../utils/basic_cstring/bcs_char_traits.hpp | 150 + .../test/utils/basic_cstring/compare.hpp | 115 + .../boost/test/utils/basic_cstring/io.hpp | 73 + thirdparty/boost/test/utils/callback.hpp | 310 + .../boost/test/utils/class_properties.hpp | 225 + thirdparty/boost/test/utils/custom_manip.hpp | 63 + thirdparty/boost/test/utils/fixed_mapping.hpp | 124 + thirdparty/boost/test/utils/foreach.hpp | 305 + .../utils/iterator/ifstream_line_iterator.hpp | 104 + .../utils/iterator/input_iterator_facade.hpp | 109 + .../utils/iterator/istream_line_iterator.hpp | 97 + .../test/utils/iterator/token_iterator.hpp | 418 + thirdparty/boost/test/utils/named_params.hpp | 294 + thirdparty/boost/test/utils/nullstream.hpp | 100 + thirdparty/boost/test/utils/rtti.hpp | 64 + .../boost/test/utils/runtime/argument.hpp | 103 + .../utils/runtime/cla/argument_factory.hpp | 218 + .../test/utils/runtime/cla/argv_traverser.cpp | 16 + .../test/utils/runtime/cla/argv_traverser.hpp | 98 + .../test/utils/runtime/cla/argv_traverser.ipp | 209 + .../utils/runtime/cla/basic_parameter.hpp | 84 + .../test/utils/runtime/cla/char_parameter.cpp | 16 + .../test/utils/runtime/cla/char_parameter.hpp | 98 + .../test/utils/runtime/cla/char_parameter.ipp | 57 + .../cla/detail/argument_value_usage.hpp | 82 + .../utils/runtime/cla/dual_name_parameter.cpp | 16 + .../utils/runtime/cla/dual_name_parameter.hpp | 88 + .../utils/runtime/cla/dual_name_parameter.ipp | 90 + .../boost/test/utils/runtime/cla/fwd.hpp | 55 + .../test/utils/runtime/cla/id_policy.cpp | 16 + .../test/utils/runtime/cla/id_policy.hpp | 137 + .../test/utils/runtime/cla/id_policy.ipp | 112 + .../runtime/cla/iface/argument_factory.hpp | 49 + .../utils/runtime/cla/iface/id_policy.hpp | 63 + .../boost/test/utils/runtime/cla/modifier.hpp | 69 + .../utils/runtime/cla/named_parameter.cpp | 16 + .../utils/runtime/cla/named_parameter.hpp | 93 + .../utils/runtime/cla/named_parameter.ipp | 116 + .../test/utils/runtime/cla/parameter.hpp | 150 + .../boost/test/utils/runtime/cla/parser.cpp | 18 + .../boost/test/utils/runtime/cla/parser.hpp | 153 + .../boost/test/utils/runtime/cla/parser.ipp | 261 + .../runtime/cla/positional_parameter.hpp | 91 + .../utils/runtime/cla/typed_parameter.hpp | 68 + .../test/utils/runtime/cla/validation.cpp | 16 + .../test/utils/runtime/cla/validation.hpp | 55 + .../test/utils/runtime/cla/validation.ipp | 65 + .../utils/runtime/cla/value_generator.hpp | 81 + .../test/utils/runtime/cla/value_handler.hpp | 57 + .../boost/test/utils/runtime/config.hpp | 139 + .../test/utils/runtime/configuration.hpp | 61 + .../test/utils/runtime/env/environment.cpp | 23 + .../test/utils/runtime/env/environment.hpp | 168 + .../test/utils/runtime/env/environment.ipp | 117 + .../boost/test/utils/runtime/env/fwd.hpp | 48 + .../boost/test/utils/runtime/env/modifier.hpp | 47 + .../boost/test/utils/runtime/env/variable.hpp | 213 + .../test/utils/runtime/file/config_file.cpp | 249 + .../test/utils/runtime/file/config_file.hpp | 182 + .../runtime/file/config_file_iterator.cpp | 680 + .../runtime/file/config_file_iterator.hpp | 166 + thirdparty/boost/test/utils/runtime/fwd.hpp | 41 + .../runtime/interpret_argument_value.hpp | 163 + .../boost/test/utils/runtime/parameter.hpp | 38 + thirdparty/boost/test/utils/runtime/trace.hpp | 30 + .../boost/test/utils/runtime/validation.hpp | 82 + .../boost/test/utils/trivial_singleton.hpp | 74 + .../boost/test/utils/wrap_stringstream.hpp | 166 + thirdparty/boost/test/utils/xml_printer.hpp | 119 + thirdparty/boost/thread.hpp | 21 + thirdparty/boost/thread/barrier.hpp | 59 + thirdparty/boost/thread/condition.hpp | 16 + .../boost/thread/condition_variable.hpp | 21 + thirdparty/boost/thread/detail/config.hpp | 94 + thirdparty/boost/thread/detail/force_cast.hpp | 39 + thirdparty/boost/thread/detail/move.hpp | 33 + thirdparty/boost/thread/detail/platform.hpp | 71 + thirdparty/boost/thread/detail/singleton.hpp | 59 + thirdparty/boost/thread/detail/tss_hooks.hpp | 78 + thirdparty/boost/thread/exceptions.hpp | 106 + thirdparty/boost/thread/locks.hpp | 589 + thirdparty/boost/thread/mutex.hpp | 21 + thirdparty/boost/thread/once.hpp | 29 + .../thread/pthread/condition_variable.hpp | 178 + .../thread/pthread/condition_variable_fwd.hpp | 66 + thirdparty/boost/thread/pthread/mutex.hpp | 197 + thirdparty/boost/thread/pthread/once.hpp | 85 + .../pthread/pthread_mutex_scoped_lock.hpp | 50 + .../boost/thread/pthread/recursive_mutex.hpp | 249 + .../boost/thread/pthread/shared_mutex.hpp | 356 + thirdparty/boost/thread/pthread/thread.hpp | 329 + .../boost/thread/pthread/thread_data.hpp | 101 + thirdparty/boost/thread/pthread/timespec.hpp | 28 + thirdparty/boost/thread/pthread/tss.hpp | 103 + thirdparty/boost/thread/recursive_mutex.hpp | 21 + thirdparty/boost/thread/shared_mutex.hpp | 21 + thirdparty/boost/thread/thread.hpp | 22 + thirdparty/boost/thread/thread_time.hpp | 46 + thirdparty/boost/thread/tss.hpp | 18 + .../thread/win32/basic_recursive_mutex.hpp | 126 + .../boost/thread/win32/basic_timed_mutex.hpp | 185 + .../boost/thread/win32/condition_variable.hpp | 370 + .../boost/thread/win32/interlocked_read.hpp | 77 + thirdparty/boost/thread/win32/mutex.hpp | 61 + thirdparty/boost/thread/win32/once.hpp | 132 + .../boost/thread/win32/recursive_mutex.hpp | 61 + .../boost/thread/win32/shared_mutex.hpp | 621 + thirdparty/boost/thread/win32/thread.hpp | 524 + .../boost/thread/win32/thread_heap_alloc.hpp | 170 + .../boost/thread/win32/thread_primitives.hpp | 281 + thirdparty/boost/thread/win32/tss.hpp | 103 + thirdparty/boost/thread/xtime.hpp | 88 + thirdparty/boost/throw_exception.hpp | 46 + thirdparty/boost/timer.hpp | 72 + thirdparty/boost/token_functions.hpp | 621 + thirdparty/boost/token_iterator.hpp | 128 + thirdparty/boost/tokenizer.hpp | 98 + thirdparty/boost/tr1/array.hpp | 83 + thirdparty/boost/tr1/complex.hpp | 244 + thirdparty/boost/tr1/detail/config.hpp | 148 + thirdparty/boost/tr1/detail/config_all.hpp | 129 + .../boost/tr1/detail/functor2iterator.hpp | 34 + .../boost/tr1/detail/math_overloads.hpp | 58 + thirdparty/boost/tr1/functional.hpp | 137 + thirdparty/boost/tr1/memory.hpp | 72 + thirdparty/boost/tr1/random.hpp | 581 + thirdparty/boost/tr1/regex.hpp | 142 + thirdparty/boost/tr1/tr1/algorithm | 27 + thirdparty/boost/tr1/tr1/array | 22 + thirdparty/boost/tr1/tr1/bcc32/array.h | 13 + thirdparty/boost/tr1/tr1/bcc32/random.h | 13 + thirdparty/boost/tr1/tr1/bcc32/regex.h | 13 + thirdparty/boost/tr1/tr1/bcc32/tuple.h | 13 + thirdparty/boost/tr1/tr1/bcc32/type_tra.h | 13 + thirdparty/boost/tr1/tr1/bitset | 27 + thirdparty/boost/tr1/tr1/complex | 31 + thirdparty/boost/tr1/tr1/deque | 27 + thirdparty/boost/tr1/tr1/exception | 39 + thirdparty/boost/tr1/tr1/fstream | 27 + thirdparty/boost/tr1/tr1/functional | 30 + thirdparty/boost/tr1/tr1/iomanip | 27 + thirdparty/boost/tr1/tr1/ios | 27 + thirdparty/boost/tr1/tr1/iostream | 27 + thirdparty/boost/tr1/tr1/istream | 27 + thirdparty/boost/tr1/tr1/iterator | 27 + thirdparty/boost/tr1/tr1/limits | 27 + thirdparty/boost/tr1/tr1/list | 27 + thirdparty/boost/tr1/tr1/locale | 27 + thirdparty/boost/tr1/tr1/map | 27 + thirdparty/boost/tr1/tr1/memory | 31 + thirdparty/boost/tr1/tr1/new | 35 + thirdparty/boost/tr1/tr1/numeric | 27 + thirdparty/boost/tr1/tr1/ostream | 27 + thirdparty/boost/tr1/tr1/queue | 27 + thirdparty/boost/tr1/tr1/random | 22 + thirdparty/boost/tr1/tr1/regex | 22 + thirdparty/boost/tr1/tr1/set | 27 + thirdparty/boost/tr1/tr1/sstream | 27 + thirdparty/boost/tr1/tr1/stack | 27 + thirdparty/boost/tr1/tr1/stdexcept | 34 + thirdparty/boost/tr1/tr1/streambuf | 27 + thirdparty/boost/tr1/tr1/string | 27 + thirdparty/boost/tr1/tr1/strstream | 27 + .../boost/tr1/tr1/sun/algorithm.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/array.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/bcc32.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/bitset.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/complex.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/deque.SUNWCCh | 6 + .../boost/tr1/tr1/sun/exception.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/fstream.SUNWCCh | 6 + .../boost/tr1/tr1/sun/functional.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/iomanip.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/ios.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/iostream.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/istream.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/iterator.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/limits.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/list.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/locale.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/map.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/memory.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/new.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/numeric.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/ostream.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/queue.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/random.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/regex.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/set.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/sstream.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/stack.SUNWCCh | 6 + .../boost/tr1/tr1/sun/stdexcept.SUNWCCh | 6 + .../boost/tr1/tr1/sun/streambuf.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/string.SUNWCCh | 6 + .../boost/tr1/tr1/sun/strstream.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/sun.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/tuple.SUNWCCh | 6 + .../boost/tr1/tr1/sun/type_traits.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/typeinfo.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/utility.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/valarray.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/sun/vector.SUNWCCh | 6 + thirdparty/boost/tr1/tr1/tuple | 22 + thirdparty/boost/tr1/tr1/type_traits | 20 + thirdparty/boost/tr1/tr1/typeinfo | 27 + thirdparty/boost/tr1/tr1/utility | 41 + thirdparty/boost/tr1/tr1/valarray | 27 + thirdparty/boost/tr1/tr1/vector | 27 + thirdparty/boost/tr1/tuple.hpp | 77 + thirdparty/boost/tr1/type_traits.hpp | 79 + thirdparty/boost/tr1/utility.hpp | 123 + thirdparty/boost/tuple/detail/tuple_basic.hpp | 944 ++ .../detail/tuple_basic_no_partial_spec.hpp | 841 ++ thirdparty/boost/tuple/tuple.hpp | 90 + thirdparty/boost/tuple/tuple_comparison.hpp | 175 + thirdparty/boost/tuple/tuple_io.hpp | 525 + thirdparty/boost/type.hpp | 18 + thirdparty/boost/type_traits.hpp | 89 + thirdparty/boost/type_traits/add_const.hpp | 47 + thirdparty/boost/type_traits/add_cv.hpp | 48 + thirdparty/boost/type_traits/add_pointer.hpp | 72 + .../boost/type_traits/add_reference.hpp | 89 + thirdparty/boost/type_traits/add_volatile.hpp | 47 + .../boost/type_traits/aligned_storage.hpp | 13 + thirdparty/boost/type_traits/alignment_of.hpp | 100 + .../boost/type_traits/alignment_traits.hpp | 15 + .../boost/type_traits/arithmetic_traits.hpp | 20 + thirdparty/boost/type_traits/array_traits.hpp | 15 + .../type_traits/broken_compiler_spec.hpp | 117 + .../boost/type_traits/composite_traits.hpp | 29 + thirdparty/boost/type_traits/config.hpp | 76 + .../boost/type_traits/conversion_traits.hpp | 17 + thirdparty/boost/type_traits/cv_traits.hpp | 24 + thirdparty/boost/type_traits/decay.hpp | 44 + .../type_traits/detail/bool_trait_def.hpp | 173 + .../type_traits/detail/bool_trait_undef.hpp | 27 + .../type_traits/detail/cv_traits_impl.hpp | 97 + .../boost/type_traits/detail/false_result.hpp | 28 + .../boost/type_traits/detail/ice_and.hpp | 35 + .../boost/type_traits/detail/ice_eq.hpp | 36 + .../boost/type_traits/detail/ice_not.hpp | 31 + .../boost/type_traits/detail/ice_or.hpp | 34 + .../detail/is_function_ptr_helper.hpp | 220 + .../detail/is_function_ptr_tester.hpp | 654 + .../detail/is_mem_fun_pointer_impl.hpp | 817 ++ .../detail/is_mem_fun_pointer_tester.hpp | 2759 ++++ .../type_traits/detail/size_t_trait_def.hpp | 58 + .../type_traits/detail/size_t_trait_undef.hpp | 16 + .../detail/template_arity_spec.hpp | 31 + .../type_traits/detail/type_trait_def.hpp | 61 + .../type_traits/detail/type_trait_undef.hpp | 19 + thirdparty/boost/type_traits/detail/wrap.hpp | 18 + .../boost/type_traits/detail/yes_no_type.hpp | 26 + thirdparty/boost/type_traits/extent.hpp | 134 + .../type_traits/floating_point_promotion.hpp | 91 + .../boost/type_traits/function_traits.hpp | 236 + .../boost/type_traits/has_nothrow_assign.hpp | 38 + .../type_traits/has_nothrow_constructor.hpp | 39 + .../boost/type_traits/has_nothrow_copy.hpp | 39 + .../type_traits/has_nothrow_destructor.hpp | 25 + .../boost/type_traits/has_trivial_assign.hpp | 50 + .../type_traits/has_trivial_constructor.hpp | 43 + .../boost/type_traits/has_trivial_copy.hpp | 49 + .../type_traits/has_trivial_destructor.hpp | 42 + .../type_traits/has_virtual_destructor.hpp | 25 + thirdparty/boost/type_traits/ice.hpp | 20 + .../boost/type_traits/integral_constant.hpp | 53 + .../boost/type_traits/integral_promotion.hpp | 195 + thirdparty/boost/type_traits/intrinsics.hpp | 153 + thirdparty/boost/type_traits/is_abstract.hpp | 144 + .../boost/type_traits/is_arithmetic.hpp | 43 + thirdparty/boost/type_traits/is_array.hpp | 90 + .../boost/type_traits/is_base_and_derived.hpp | 237 + thirdparty/boost/type_traits/is_base_of.hpp | 40 + thirdparty/boost/type_traits/is_class.hpp | 128 + thirdparty/boost/type_traits/is_complex.hpp | 34 + thirdparty/boost/type_traits/is_compound.hpp | 40 + thirdparty/boost/type_traits/is_const.hpp | 142 + .../boost/type_traits/is_convertible.hpp | 418 + thirdparty/boost/type_traits/is_empty.hpp | 211 + thirdparty/boost/type_traits/is_enum.hpp | 180 + thirdparty/boost/type_traits/is_float.hpp | 27 + .../boost/type_traits/is_floating_point.hpp | 27 + thirdparty/boost/type_traits/is_function.hpp | 95 + .../boost/type_traits/is_fundamental.hpp | 41 + thirdparty/boost/type_traits/is_integral.hpp | 73 + .../is_member_function_pointer.hpp | 134 + .../type_traits/is_member_object_pointer.hpp | 46 + .../boost/type_traits/is_member_pointer.hpp | 114 + thirdparty/boost/type_traits/is_object.hpp | 53 + thirdparty/boost/type_traits/is_pod.hpp | 135 + thirdparty/boost/type_traits/is_pointer.hpp | 160 + .../boost/type_traits/is_polymorphic.hpp | 102 + thirdparty/boost/type_traits/is_reference.hpp | 116 + thirdparty/boost/type_traits/is_same.hpp | 103 + thirdparty/boost/type_traits/is_scalar.hpp | 55 + thirdparty/boost/type_traits/is_signed.hpp | 119 + thirdparty/boost/type_traits/is_stateless.hpp | 48 + thirdparty/boost/type_traits/is_union.hpp | 49 + thirdparty/boost/type_traits/is_unsigned.hpp | 116 + thirdparty/boost/type_traits/is_void.hpp | 33 + thirdparty/boost/type_traits/is_volatile.hpp | 131 + thirdparty/boost/type_traits/make_signed.hpp | 137 + .../boost/type_traits/make_unsigned.hpp | 137 + .../type_traits/msvc/remove_all_extents.hpp | 47 + .../boost/type_traits/msvc/remove_bounds.hpp | 43 + .../boost/type_traits/msvc/remove_const.hpp | 143 + .../boost/type_traits/msvc/remove_cv.hpp | 190 + .../boost/type_traits/msvc/remove_extent.hpp | 43 + .../boost/type_traits/msvc/remove_pointer.hpp | 42 + .../type_traits/msvc/remove_reference.hpp | 42 + .../type_traits/msvc/remove_volatile.hpp | 143 + thirdparty/boost/type_traits/msvc/typeof.hpp | 50 + .../boost/type_traits/object_traits.hpp | 33 + thirdparty/boost/type_traits/promote.hpp | 40 + thirdparty/boost/type_traits/rank.hpp | 81 + .../boost/type_traits/reference_traits.hpp | 15 + .../boost/type_traits/remove_all_extents.hpp | 48 + .../boost/type_traits/remove_bounds.hpp | 48 + thirdparty/boost/type_traits/remove_const.hpp | 78 + thirdparty/boost/type_traits/remove_cv.hpp | 61 + .../boost/type_traits/remove_extent.hpp | 48 + .../boost/type_traits/remove_pointer.hpp | 43 + .../boost/type_traits/remove_reference.hpp | 50 + .../boost/type_traits/remove_volatile.hpp | 77 + thirdparty/boost/type_traits/same_traits.hpp | 15 + .../boost/type_traits/transform_traits.hpp | 21 + .../type_traits/transform_traits_spec.hpp | 14 + .../boost/type_traits/type_with_alignment.hpp | 288 + thirdparty/boost/typeof/dmc/typeof_impl.hpp | 100 + thirdparty/boost/typeof/encode_decode.hpp | 61 + .../boost/typeof/encode_decode_params.hpp | 34 + .../boost/typeof/incr_registration_group.hpp | 14 + thirdparty/boost/typeof/int_encoding.hpp | 118 + .../boost/typeof/integral_template_param.hpp | 80 + thirdparty/boost/typeof/message.hpp | 8 + thirdparty/boost/typeof/modifiers.hpp | 121 + thirdparty/boost/typeof/msvc/typeof_impl.hpp | 281 + thirdparty/boost/typeof/native.hpp | 60 + .../boost/typeof/pointers_data_members.hpp | 38 + .../boost/typeof/register_functions.hpp | 43 + .../typeof/register_functions_iterate.hpp | 87 + .../boost/typeof/register_fundamental.hpp | 62 + .../boost/typeof/register_mem_functions.hpp | 32 + thirdparty/boost/typeof/std/bitset.hpp | 15 + thirdparty/boost/typeof/std/complex.hpp | 15 + thirdparty/boost/typeof/std/deque.hpp | 17 + thirdparty/boost/typeof/std/fstream.hpp | 27 + thirdparty/boost/typeof/std/functional.hpp | 55 + thirdparty/boost/typeof/std/iostream.hpp | 18 + thirdparty/boost/typeof/std/istream.hpp | 21 + thirdparty/boost/typeof/std/iterator.hpp | 58 + thirdparty/boost/typeof/std/list.hpp | 17 + thirdparty/boost/typeof/std/locale.hpp | 40 + thirdparty/boost/typeof/std/map.hpp | 23 + thirdparty/boost/typeof/std/memory.hpp | 17 + thirdparty/boost/typeof/std/ostream.hpp | 18 + thirdparty/boost/typeof/std/queue.hpp | 17 + thirdparty/boost/typeof/std/set.hpp | 22 + thirdparty/boost/typeof/std/sstream.hpp | 32 + thirdparty/boost/typeof/std/stack.hpp | 17 + thirdparty/boost/typeof/std/streambuf.hpp | 17 + thirdparty/boost/typeof/std/string.hpp | 24 + thirdparty/boost/typeof/std/utility.hpp | 15 + thirdparty/boost/typeof/std/valarray.hpp | 21 + thirdparty/boost/typeof/std/vector.hpp | 17 + thirdparty/boost/typeof/template_encoding.hpp | 160 + .../boost/typeof/template_template_param.hpp | 149 + thirdparty/boost/typeof/type_encoding.hpp | 27 + .../boost/typeof/type_template_param.hpp | 37 + thirdparty/boost/typeof/typeof.hpp | 189 + thirdparty/boost/typeof/typeof_impl.hpp | 186 + thirdparty/boost/typeof/vector.hpp | 166 + thirdparty/boost/typeof/vector100.hpp | 321 + thirdparty/boost/typeof/vector150.hpp | 471 + thirdparty/boost/typeof/vector200.hpp | 621 + thirdparty/boost/typeof/vector50.hpp | 171 + thirdparty/boost/utility.hpp | 19 + thirdparty/boost/utility/addressof.hpp | 58 + thirdparty/boost/utility/base_from_member.hpp | 87 + thirdparty/boost/utility/compare_pointees.hpp | 68 + .../detail/in_place_factory_prefix.hpp | 36 + .../detail/in_place_factory_suffix.hpp | 23 + .../utility/detail/result_of_iterate.hpp | 89 + thirdparty/boost/utility/enable_if.hpp | 119 + thirdparty/boost/utility/in_place_factory.hpp | 88 + thirdparty/boost/utility/result_of.hpp | 88 + .../boost/utility/typed_in_place_factory.hpp | 77 + thirdparty/boost/utility/value_init.hpp | 116 + thirdparty/boost/variant.hpp | 27 + thirdparty/boost/variant/apply_visitor.hpp | 20 + thirdparty/boost/variant/bad_visit.hpp | 41 + .../variant/detail/apply_visitor_binary.hpp | 172 + .../variant/detail/apply_visitor_delayed.hpp | 85 + .../variant/detail/apply_visitor_unary.hpp | 79 + .../boost/variant/detail/backup_holder.hpp | 94 + .../boost/variant/detail/bool_trait_def.hpp | 30 + .../boost/variant/detail/bool_trait_undef.hpp | 21 + .../boost/variant/detail/cast_storage.hpp | 48 + thirdparty/boost/variant/detail/config.hpp | 38 + .../boost/variant/detail/enable_recursive.hpp | 162 + .../variant/detail/enable_recursive_fwd.hpp | 116 + .../boost/variant/detail/forced_return.hpp | 104 + .../variant/detail/generic_result_type.hpp | 88 + .../boost/variant/detail/has_nothrow_move.hpp | 106 + .../boost/variant/detail/has_trivial_move.hpp | 100 + .../boost/variant/detail/initializer.hpp | 265 + .../variant/detail/make_variant_list.hpp | 60 + thirdparty/boost/variant/detail/move.hpp | 166 + .../boost/variant/detail/over_sequence.hpp | 95 + .../boost/variant/detail/substitute.hpp | 231 + .../boost/variant/detail/substitute_fwd.hpp | 59 + .../boost/variant/detail/variant_io.hpp | 92 + .../boost/variant/detail/visitation_impl.hpp | 286 + thirdparty/boost/variant/get.hpp | 202 + .../boost/variant/recursive_variant.hpp | 182 + .../boost/variant/recursive_wrapper.hpp | 123 + .../boost/variant/recursive_wrapper_fwd.hpp | 147 + thirdparty/boost/variant/static_visitor.hpp | 97 + thirdparty/boost/variant/variant.hpp | 1828 +++ thirdparty/boost/variant/variant_fwd.hpp | 253 + thirdparty/boost/variant/visitor_ptr.hpp | 116 + thirdparty/boost/vector_property_map.hpp | 92 + thirdparty/boost/version.hpp | 35 + thirdparty/boost/visit_each.hpp | 29 + thirdparty/boost/wave.hpp | 23 + thirdparty/boost/wave/cpp_context.hpp | 507 + thirdparty/boost/wave/cpp_exceptions.hpp | 421 + .../boost/wave/cpp_iteration_context.hpp | 210 + thirdparty/boost/wave/cpp_throw.hpp | 155 + .../boost/wave/cpplexer/convert_trigraphs.hpp | 139 + .../boost/wave/cpplexer/cpp_lex_interface.hpp | 72 + .../cpplexer/cpp_lex_interface_generator.hpp | 108 + .../boost/wave/cpplexer/cpp_lex_iterator.hpp | 200 + .../boost/wave/cpplexer/cpp_lex_token.hpp | 283 + .../wave/cpplexer/cpplexer_exceptions.hpp | 290 + .../wave/cpplexer/detect_include_guards.hpp | 263 + thirdparty/boost/wave/cpplexer/re2clex/aq.hpp | 64 + .../boost/wave/cpplexer/re2clex/cpp_re.hpp | 57 + .../wave/cpplexer/re2clex/cpp_re2c_lexer.hpp | 412 + .../boost/wave/cpplexer/re2clex/scanner.hpp | 73 + .../boost/wave/cpplexer/token_cache.hpp | 72 + .../wave/cpplexer/validate_universal_char.hpp | 322 + .../boost/wave/grammars/cpp_chlit_grammar.hpp | 361 + .../wave/grammars/cpp_defined_grammar.hpp | 191 + .../wave/grammars/cpp_defined_grammar_gen.hpp | 85 + .../wave/grammars/cpp_expression_grammar.hpp | 851 ++ .../grammars/cpp_expression_grammar_gen.hpp | 75 + .../wave/grammars/cpp_expression_value.hpp | 883 ++ .../boost/wave/grammars/cpp_grammar.hpp | 754 + .../boost/wave/grammars/cpp_grammar_gen.hpp | 110 + .../wave/grammars/cpp_intlit_grammar.hpp | 194 + .../wave/grammars/cpp_literal_grammar_gen.hpp | 77 + .../wave/grammars/cpp_predef_macros_gen.hpp | 80 + .../grammars/cpp_predef_macros_grammar.hpp | 173 + .../boost/wave/grammars/cpp_value_error.hpp | 51 + thirdparty/boost/wave/language_support.hpp | 185 + thirdparty/boost/wave/preprocessing_hooks.hpp | 627 + thirdparty/boost/wave/token_ids.hpp | 347 + thirdparty/boost/wave/util/cpp_ifblock.hpp | 161 + .../boost/wave/util/cpp_include_paths.hpp | 511 + thirdparty/boost/wave/util/cpp_iterator.hpp | 2258 +++ thirdparty/boost/wave/util/cpp_macromap.hpp | 1914 +++ .../boost/wave/util/cpp_macromap_predef.hpp | 272 + .../boost/wave/util/cpp_macromap_utils.hpp | 515 + thirdparty/boost/wave/util/file_position.hpp | 232 + thirdparty/boost/wave/util/flex_string.hpp | 2540 ++++ thirdparty/boost/wave/util/functor_input.hpp | 155 + .../wave/util/insert_whitespace_detection.hpp | 505 + .../boost/wave/util/interpret_pragma.hpp | 212 + .../boost/wave/util/iteration_context.hpp | 83 + .../boost/wave/util/macro_definition.hpp | 176 + thirdparty/boost/wave/util/macro_helpers.hpp | 260 + thirdparty/boost/wave/util/pattern_parser.hpp | 65 + thirdparty/boost/wave/util/symbol_table.hpp | 109 + .../wave/util/time_conversion_helper.hpp | 160 + .../boost/wave/util/transform_iterator.hpp | 169 + .../boost/wave/util/unput_queue_iterator.hpp | 461 + thirdparty/boost/wave/wave_config.hpp | 485 + .../boost/wave/wave_config_constant.hpp | 91 + thirdparty/boost/wave/wave_version.hpp | 26 + thirdparty/boost/wave/whitespace_handling.hpp | 229 + thirdparty/boost/weak_ptr.hpp | 188 + thirdparty/boost/xpressive/basic_regex.hpp | 270 + .../boost/xpressive/detail/core/access.hpp | 131 + .../boost/xpressive/detail/core/action.hpp | 39 + .../boost/xpressive/detail/core/adaptor.hpp | 75 + .../boost/xpressive/detail/core/finder.hpp | 199 + .../xpressive/detail/core/flow_control.hpp | 74 + .../boost/xpressive/detail/core/icase.hpp | 42 + .../boost/xpressive/detail/core/linker.hpp | 299 + .../detail/core/matcher/action_matcher.hpp | 471 + .../core/matcher/alternate_end_matcher.hpp | 51 + .../detail/core/matcher/alternate_matcher.hpp | 132 + .../detail/core/matcher/any_matcher.hpp | 51 + .../core/matcher/assert_bol_matcher.hpp | 57 + .../core/matcher/assert_bos_matcher.hpp | 39 + .../core/matcher/assert_eol_matcher.hpp | 57 + .../core/matcher/assert_eos_matcher.hpp | 39 + .../detail/core/matcher/assert_line_base.hpp | 67 + .../core/matcher/assert_word_matcher.hpp | 123 + .../core/matcher/attr_begin_matcher.hpp | 50 + .../detail/core/matcher/attr_end_matcher.hpp | 47 + .../detail/core/matcher/attr_matcher.hpp | 107 + .../detail/core/matcher/charset_matcher.hpp | 67 + .../detail/core/matcher/end_matcher.hpp | 79 + .../detail/core/matcher/epsilon_matcher.hpp | 39 + .../detail/core/matcher/keeper_matcher.hpp | 94 + .../detail/core/matcher/literal_matcher.hpp | 67 + .../core/matcher/logical_newline_matcher.hpp | 83 + .../detail/core/matcher/lookahead_matcher.hpp | 147 + .../core/matcher/lookbehind_matcher.hpp | 164 + .../core/matcher/mark_begin_matcher.hpp | 56 + .../detail/core/matcher/mark_end_matcher.hpp | 64 + .../detail/core/matcher/mark_matcher.hpp | 78 + .../detail/core/matcher/optional_matcher.hpp | 121 + .../core/matcher/posix_charset_matcher.hpp | 73 + .../detail/core/matcher/predicate_matcher.hpp | 147 + .../detail/core/matcher/range_matcher.hpp | 87 + .../core/matcher/regex_byref_matcher.hpp | 77 + .../detail/core/matcher/regex_matcher.hpp | 63 + .../core/matcher/repeat_begin_matcher.hpp | 69 + .../core/matcher/repeat_end_matcher.hpp | 121 + .../detail/core/matcher/set_matcher.hpp | 100 + .../core/matcher/simple_repeat_matcher.hpp | 209 + .../detail/core/matcher/string_matcher.hpp | 90 + .../detail/core/matcher/true_matcher.hpp | 38 + .../boost/xpressive/detail/core/matchers.hpp | 50 + .../boost/xpressive/detail/core/optimize.hpp | 109 + .../boost/xpressive/detail/core/peeker.hpp | 268 + .../xpressive/detail/core/quant_style.hpp | 129 + .../xpressive/detail/core/regex_impl.hpp | 212 + .../xpressive/detail/core/results_cache.hpp | 141 + .../boost/xpressive/detail/core/state.hpp | 388 + .../xpressive/detail/core/sub_match_impl.hpp | 47 + .../detail/core/sub_match_vector.hpp | 171 + .../boost/xpressive/detail/detail_fwd.hpp | 433 + .../xpressive/detail/dynamic/dynamic.hpp | 337 + .../xpressive/detail/dynamic/matchable.hpp | 177 + .../detail/dynamic/parse_charset.hpp | 365 + .../boost/xpressive/detail/dynamic/parser.hpp | 342 + .../xpressive/detail/dynamic/parser_enum.hpp | 77 + .../detail/dynamic/parser_traits.hpp | 459 + .../xpressive/detail/dynamic/sequence.hpp | 175 + .../boost/xpressive/detail/static/compile.hpp | 99 + .../boost/xpressive/detail/static/grammar.hpp | 321 + .../boost/xpressive/detail/static/is_pure.hpp | 204 + .../xpressive/detail/static/modifier.hpp | 66 + .../xpressive/detail/static/placeholders.hpp | 119 + .../boost/xpressive/detail/static/static.hpp | 259 + .../detail/static/transforms/as_action.hpp | 320 + .../detail/static/transforms/as_alternate.hpp | 139 + .../static/transforms/as_independent.hpp | 109 + .../detail/static/transforms/as_inverse.hpp | 93 + .../detail/static/transforms/as_marker.hpp | 87 + .../detail/static/transforms/as_matcher.hpp | 47 + .../detail/static/transforms/as_modifier.hpp | 73 + .../static/transforms/as_quantifier.hpp | 331 + .../detail/static/transforms/as_sequence.hpp | 52 + .../detail/static/transforms/as_set.hpp | 277 + .../xpressive/detail/static/transmogrify.hpp | 240 + .../xpressive/detail/static/type_traits.hpp | 60 + .../boost/xpressive/detail/static/visitor.hpp | 144 + .../xpressive/detail/static/width_of.hpp | 251 + .../xpressive/detail/utility/algorithm.hpp | 174 + .../boost/xpressive/detail/utility/any.hpp | 108 + .../xpressive/detail/utility/boyer_moore.hpp | 198 + .../detail/utility/chset/basic_chset.hpp | 172 + .../detail/utility/chset/basic_chset.ipp | 409 + .../xpressive/detail/utility/chset/chset.hpp | 165 + .../detail/utility/chset/range_run.hpp | 102 + .../detail/utility/chset/range_run.ipp | 235 + .../boost/xpressive/detail/utility/cons.hpp | 309 + .../xpressive/detail/utility/counted_base.hpp | 84 + .../xpressive/detail/utility/dont_care.hpp | 25 + .../detail/utility/hash_peek_bitset.hpp | 175 + .../detail/utility/ignore_unused.hpp | 27 + .../xpressive/detail/utility/literals.hpp | 85 + .../xpressive/detail/utility/never_true.hpp | 25 + .../xpressive/detail/utility/save_restore.hpp | 55 + .../detail/utility/sequence_stack.hpp | 241 + .../xpressive/detail/utility/symbols.hpp | 277 + .../xpressive/detail/utility/tracking_ptr.hpp | 493 + .../xpressive/detail/utility/traits_utils.hpp | 145 + .../boost/xpressive/detail/utility/width.hpp | 94 + thirdparty/boost/xpressive/match_results.hpp | 1104 ++ thirdparty/boost/xpressive/proto/args.hpp | 83 + thirdparty/boost/xpressive/proto/context.hpp | 18 + .../xpressive/proto/context/callable.hpp | 170 + .../boost/xpressive/proto/context/default.hpp | 389 + .../boost/xpressive/proto/context/null.hpp | 83 + thirdparty/boost/xpressive/proto/debug.hpp | 186 + .../boost/xpressive/proto/deep_copy.hpp | 118 + .../boost/xpressive/proto/detail/funop.hpp | 63 + .../boost/xpressive/proto/detail/prefix.hpp | 10 + .../boost/xpressive/proto/detail/suffix.hpp | 16 + thirdparty/boost/xpressive/proto/domain.hpp | 79 + thirdparty/boost/xpressive/proto/eval.hpp | 62 + thirdparty/boost/xpressive/proto/expr.hpp | 405 + thirdparty/boost/xpressive/proto/extends.hpp | 332 + thirdparty/boost/xpressive/proto/fusion.hpp | 554 + thirdparty/boost/xpressive/proto/generate.hpp | 186 + thirdparty/boost/xpressive/proto/literal.hpp | 77 + .../boost/xpressive/proto/make_expr.hpp | 792 + thirdparty/boost/xpressive/proto/matches.hpp | 598 + .../boost/xpressive/proto/operators.hpp | 407 + thirdparty/boost/xpressive/proto/proto.hpp | 30 + .../boost/xpressive/proto/proto_fwd.hpp | 570 + .../boost/xpressive/proto/proto_typeof.hpp | 135 + thirdparty/boost/xpressive/proto/ref.hpp | 180 + thirdparty/boost/xpressive/proto/tags.hpp | 156 + thirdparty/boost/xpressive/proto/traits.hpp | 745 + .../boost/xpressive/proto/transform.hpp | 25 + .../boost/xpressive/proto/transform/apply.hpp | 167 + .../boost/xpressive/proto/transform/arg.hpp | 192 + .../xpressive/proto/transform/branch.hpp | 52 + .../xpressive/proto/transform/compose.hpp | 58 + .../xpressive/proto/transform/construct.hpp | 270 + .../boost/xpressive/proto/transform/fold.hpp | 178 + .../xpressive/proto/transform/fold_tree.hpp | 78 + .../xpressive/proto/transform/function.hpp | 115 + .../boost/xpressive/proto/transform/list.hpp | 87 + .../proto/transform/pass_through.hpp | 156 + thirdparty/boost/xpressive/regex_actions.hpp | 822 ++ .../boost/xpressive/regex_algorithms.hpp | 590 + thirdparty/boost/xpressive/regex_compiler.hpp | 738 + .../boost/xpressive/regex_constants.hpp | 294 + thirdparty/boost/xpressive/regex_error.hpp | 87 + thirdparty/boost/xpressive/regex_iterator.hpp | 249 + .../boost/xpressive/regex_primitives.hpp | 676 + .../boost/xpressive/regex_token_iterator.hpp | 352 + thirdparty/boost/xpressive/regex_traits.hpp | 107 + thirdparty/boost/xpressive/sub_match.hpp | 392 + .../boost/xpressive/traits/c_regex_traits.hpp | 413 + .../xpressive/traits/cpp_regex_traits.hpp | 693 + .../boost/xpressive/traits/detail/c_ctype.hpp | 841 ++ .../xpressive/traits/null_regex_traits.hpp | 231 + thirdparty/boost/xpressive/xpressive.hpp | 21 + .../boost/xpressive/xpressive_dynamic.hpp | 25 + thirdparty/boost/xpressive/xpressive_fwd.hpp | 209 + .../boost/xpressive/xpressive_static.hpp | 32 + .../boost/xpressive/xpressive_typeof.hpp | 147 + thirdparty/libsvm/COPYRIGHT | 31 + thirdparty/libsvm/FAQ.html | 1396 ++ thirdparty/libsvm/Makefile | 15 + thirdparty/libsvm/Makefile.win | 39 + thirdparty/libsvm/README | 633 + thirdparty/libsvm/heart_scale | 270 + thirdparty/libsvm/svm-predict.c | 190 + thirdparty/libsvm/svm-scale.c | 314 + thirdparty/libsvm/svm-train.c | 322 + thirdparty/libsvm/svm.cpp | 3018 ++++ thirdparty/libsvm/svm.h | 91 + thirdparty/libsvm/tools/README | 147 + thirdparty/libsvm/tools/checkdata.py | 106 + thirdparty/libsvm/tools/easy.py | 79 + thirdparty/libsvm/tools/grid.py | 362 + thirdparty/libsvm/tools/subset.py | 144 + 5266 files changed, 970629 insertions(+) create mode 100644 CC create mode 100644 GPL create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 SVMUtil.cpp create mode 100644 SVMUtil.h create mode 100644 bin/SVMUtil.o create mode 100644 bin/parametersearch.o create mode 100755 bin/stupidfilter create mode 100644 bin/stupidfilter.o create mode 100644 bin/svm.o create mode 100755 classify.sh create mode 100644 data/c_rbf.mod create mode 100644 data/c_rbf.sf create mode 100644 parameterresult.h create mode 100644 parametersearch.cpp create mode 100644 parametersearch.h create mode 100644 stupidfilter.cpp create mode 100644 thirdparty/boost/LICENSE_1_0.txt create mode 100644 thirdparty/boost/algorithm/minmax.hpp create mode 100644 thirdparty/boost/algorithm/minmax_element.hpp create mode 100644 thirdparty/boost/algorithm/string.hpp create mode 100644 thirdparty/boost/algorithm/string/case_conv.hpp create mode 100644 thirdparty/boost/algorithm/string/classification.hpp create mode 100644 thirdparty/boost/algorithm/string/compare.hpp create mode 100644 thirdparty/boost/algorithm/string/concept.hpp create mode 100644 thirdparty/boost/algorithm/string/config.hpp create mode 100644 thirdparty/boost/algorithm/string/constants.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/case_conv.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/classification.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/find_format.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/find_format_all.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/find_format_store.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/find_iterator.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/finder.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/finder_regex.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/formatter.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/formatter_regex.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/predicate.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/replace_storage.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/sequence.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/trim.hpp create mode 100644 thirdparty/boost/algorithm/string/detail/util.hpp create mode 100644 thirdparty/boost/algorithm/string/erase.hpp create mode 100644 thirdparty/boost/algorithm/string/find.hpp create mode 100644 thirdparty/boost/algorithm/string/find_format.hpp create mode 100644 thirdparty/boost/algorithm/string/find_iterator.hpp create mode 100644 thirdparty/boost/algorithm/string/finder.hpp create mode 100644 thirdparty/boost/algorithm/string/formatter.hpp create mode 100644 thirdparty/boost/algorithm/string/iter_find.hpp create mode 100644 thirdparty/boost/algorithm/string/join.hpp create mode 100644 thirdparty/boost/algorithm/string/predicate.hpp create mode 100644 thirdparty/boost/algorithm/string/predicate_facade.hpp create mode 100644 thirdparty/boost/algorithm/string/regex.hpp create mode 100644 thirdparty/boost/algorithm/string/regex_find_format.hpp create mode 100644 thirdparty/boost/algorithm/string/replace.hpp create mode 100644 thirdparty/boost/algorithm/string/sequence_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/split.hpp create mode 100644 thirdparty/boost/algorithm/string/std/list_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/std/rope_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/std/slist_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/std/string_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/std_containers_traits.hpp create mode 100644 thirdparty/boost/algorithm/string/trim.hpp create mode 100644 thirdparty/boost/algorithm/string/yes_no_type.hpp create mode 100644 thirdparty/boost/algorithm/string_regex.hpp create mode 100644 thirdparty/boost/aligned_storage.hpp create mode 100644 thirdparty/boost/any.hpp create mode 100644 thirdparty/boost/archive/add_facet.hpp create mode 100644 thirdparty/boost/archive/archive_exception.hpp create mode 100644 thirdparty/boost/archive/array/iarchive.hpp create mode 100644 thirdparty/boost/archive/array/oarchive.hpp create mode 100644 thirdparty/boost/archive/basic_archive.hpp create mode 100644 thirdparty/boost/archive/basic_binary_iarchive.hpp create mode 100644 thirdparty/boost/archive/basic_binary_iprimitive.hpp create mode 100644 thirdparty/boost/archive/basic_binary_oarchive.hpp create mode 100644 thirdparty/boost/archive/basic_binary_oprimitive.hpp create mode 100644 thirdparty/boost/archive/basic_streambuf_locale_saver.hpp create mode 100644 thirdparty/boost/archive/basic_text_iarchive.hpp create mode 100644 thirdparty/boost/archive/basic_text_iprimitive.hpp create mode 100644 thirdparty/boost/archive/basic_text_oarchive.hpp create mode 100644 thirdparty/boost/archive/basic_text_oprimitive.hpp create mode 100644 thirdparty/boost/archive/basic_xml_archive.hpp create mode 100644 thirdparty/boost/archive/basic_xml_iarchive.hpp create mode 100644 thirdparty/boost/archive/basic_xml_oarchive.hpp create mode 100644 thirdparty/boost/archive/binary_iarchive.hpp create mode 100644 thirdparty/boost/archive/binary_iarchive_impl.hpp create mode 100644 thirdparty/boost/archive/binary_oarchive.hpp create mode 100644 thirdparty/boost/archive/binary_oarchive_impl.hpp create mode 100644 thirdparty/boost/archive/binary_wiarchive.hpp create mode 100644 thirdparty/boost/archive/binary_woarchive.hpp create mode 100644 thirdparty/boost/archive/codecvt_null.hpp create mode 100644 thirdparty/boost/archive/detail/abi_prefix.hpp create mode 100644 thirdparty/boost/archive/detail/abi_suffix.hpp create mode 100644 thirdparty/boost/archive/detail/archive_pointer_iserializer.hpp create mode 100644 thirdparty/boost/archive/detail/archive_pointer_oserializer.hpp create mode 100644 thirdparty/boost/archive/detail/auto_link_archive.hpp create mode 100644 thirdparty/boost/archive/detail/auto_link_warchive.hpp create mode 100644 thirdparty/boost/archive/detail/basic_archive_impl.hpp create mode 100644 thirdparty/boost/archive/detail/basic_config.hpp create mode 100644 thirdparty/boost/archive/detail/basic_iarchive.hpp create mode 100644 thirdparty/boost/archive/detail/basic_iserializer.hpp create mode 100644 thirdparty/boost/archive/detail/basic_oarchive.hpp create mode 100644 thirdparty/boost/archive/detail/basic_oserializer.hpp create mode 100644 thirdparty/boost/archive/detail/basic_pointer_iserializer.hpp create mode 100644 thirdparty/boost/archive/detail/basic_pointer_oserializer.hpp create mode 100644 thirdparty/boost/archive/detail/basic_serializer.hpp create mode 100644 thirdparty/boost/archive/detail/basic_serializer_map.hpp create mode 100644 thirdparty/boost/archive/detail/common_iarchive.hpp create mode 100644 thirdparty/boost/archive/detail/common_oarchive.hpp create mode 100644 thirdparty/boost/archive/detail/decl.hpp create mode 100644 thirdparty/boost/archive/detail/dynamically_initialized.hpp create mode 100644 thirdparty/boost/archive/detail/interface_iarchive.hpp create mode 100644 thirdparty/boost/archive/detail/interface_oarchive.hpp create mode 100644 thirdparty/boost/archive/detail/iserializer.hpp create mode 100644 thirdparty/boost/archive/detail/oserializer.hpp create mode 100644 thirdparty/boost/archive/detail/polymorphic_iarchive_dispatch.hpp create mode 100644 thirdparty/boost/archive/detail/polymorphic_oarchive_dispatch.hpp create mode 100644 thirdparty/boost/archive/detail/register_archive.hpp create mode 100644 thirdparty/boost/archive/detail/utf8_codecvt_facet.hpp create mode 100644 thirdparty/boost/archive/dinkumware.hpp create mode 100644 thirdparty/boost/archive/impl/archive_pointer_iserializer.ipp create mode 100644 thirdparty/boost/archive/impl/archive_pointer_oserializer.ipp create mode 100644 thirdparty/boost/archive/impl/basic_binary_iarchive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_binary_iprimitive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_binary_oarchive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_binary_oprimitive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_text_iarchive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_text_iprimitive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_text_oarchive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_text_oprimitive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_xml_grammar.hpp create mode 100644 thirdparty/boost/archive/impl/basic_xml_iarchive.ipp create mode 100644 thirdparty/boost/archive/impl/basic_xml_oarchive.ipp create mode 100644 thirdparty/boost/archive/impl/text_iarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/text_oarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/text_wiarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/text_woarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/xml_iarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/xml_oarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/xml_wiarchive_impl.ipp create mode 100644 thirdparty/boost/archive/impl/xml_woarchive_impl.ipp create mode 100644 thirdparty/boost/archive/iterators/base64_exception.hpp create mode 100644 thirdparty/boost/archive/iterators/base64_from_binary.hpp create mode 100644 thirdparty/boost/archive/iterators/binary_from_base64.hpp create mode 100644 thirdparty/boost/archive/iterators/dataflow.hpp create mode 100644 thirdparty/boost/archive/iterators/dataflow_exception.hpp create mode 100644 thirdparty/boost/archive/iterators/escape.hpp create mode 100644 thirdparty/boost/archive/iterators/head_iterator.hpp create mode 100644 thirdparty/boost/archive/iterators/insert_linebreaks.hpp create mode 100644 thirdparty/boost/archive/iterators/istream_iterator.hpp create mode 100644 thirdparty/boost/archive/iterators/mb_from_wchar.hpp create mode 100644 thirdparty/boost/archive/iterators/ostream_iterator.hpp create mode 100644 thirdparty/boost/archive/iterators/remove_whitespace.hpp create mode 100644 thirdparty/boost/archive/iterators/transform_width.hpp create mode 100644 thirdparty/boost/archive/iterators/unescape.hpp create mode 100644 thirdparty/boost/archive/iterators/wchar_from_mb.hpp create mode 100644 thirdparty/boost/archive/iterators/xml_escape.hpp create mode 100644 thirdparty/boost/archive/iterators/xml_unescape.hpp create mode 100644 thirdparty/boost/archive/iterators/xml_unescape_exception.hpp create mode 100644 thirdparty/boost/archive/polymorphic_binary_iarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_binary_oarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_iarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_oarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_text_iarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_text_oarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_text_wiarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_text_woarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_xml_iarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_xml_oarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_xml_wiarchive.hpp create mode 100644 thirdparty/boost/archive/polymorphic_xml_woarchive.hpp create mode 100644 thirdparty/boost/archive/shared_ptr_helper.hpp create mode 100644 thirdparty/boost/archive/text_iarchive.hpp create mode 100644 thirdparty/boost/archive/text_oarchive.hpp create mode 100644 thirdparty/boost/archive/text_wiarchive.hpp create mode 100644 thirdparty/boost/archive/text_woarchive.hpp create mode 100644 thirdparty/boost/archive/tmpdir.hpp create mode 100644 thirdparty/boost/archive/wcslen.hpp create mode 100644 thirdparty/boost/archive/xml_iarchive.hpp create mode 100644 thirdparty/boost/archive/xml_oarchive.hpp create mode 100644 thirdparty/boost/archive/xml_wiarchive.hpp create mode 100644 thirdparty/boost/archive/xml_woarchive.hpp create mode 100644 thirdparty/boost/array.hpp create mode 100644 thirdparty/boost/asio.hpp create mode 100644 thirdparty/boost/asio/basic_datagram_socket.hpp create mode 100644 thirdparty/boost/asio/basic_deadline_timer.hpp create mode 100644 thirdparty/boost/asio/basic_io_object.hpp create mode 100644 thirdparty/boost/asio/basic_socket.hpp create mode 100644 thirdparty/boost/asio/basic_socket_acceptor.hpp create mode 100644 thirdparty/boost/asio/basic_socket_iostream.hpp create mode 100644 thirdparty/boost/asio/basic_socket_streambuf.hpp create mode 100644 thirdparty/boost/asio/basic_stream_socket.hpp create mode 100644 thirdparty/boost/asio/basic_streambuf.hpp create mode 100644 thirdparty/boost/asio/buffer.hpp create mode 100644 thirdparty/boost/asio/buffered_read_stream.hpp create mode 100644 thirdparty/boost/asio/buffered_read_stream_fwd.hpp create mode 100644 thirdparty/boost/asio/buffered_stream.hpp create mode 100644 thirdparty/boost/asio/buffered_stream_fwd.hpp create mode 100644 thirdparty/boost/asio/buffered_write_stream.hpp create mode 100644 thirdparty/boost/asio/buffered_write_stream_fwd.hpp create mode 100644 thirdparty/boost/asio/completion_condition.hpp create mode 100644 thirdparty/boost/asio/datagram_socket_service.hpp create mode 100644 thirdparty/boost/asio/deadline_timer.hpp create mode 100644 thirdparty/boost/asio/deadline_timer_service.hpp create mode 100644 thirdparty/boost/asio/detail/bind_handler.hpp create mode 100644 thirdparty/boost/asio/detail/buffer_resize_guard.hpp create mode 100644 thirdparty/boost/asio/detail/buffered_stream_storage.hpp create mode 100644 thirdparty/boost/asio/detail/call_stack.hpp create mode 100644 thirdparty/boost/asio/detail/const_buffers_iterator.hpp create mode 100644 thirdparty/boost/asio/detail/consuming_buffers.hpp create mode 100644 thirdparty/boost/asio/detail/deadline_timer_service.hpp create mode 100644 thirdparty/boost/asio/detail/dev_poll_reactor.hpp create mode 100644 thirdparty/boost/asio/detail/dev_poll_reactor_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/epoll_reactor.hpp create mode 100644 thirdparty/boost/asio/detail/epoll_reactor_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/event.hpp create mode 100644 thirdparty/boost/asio/detail/fd_set_adapter.hpp create mode 100644 thirdparty/boost/asio/detail/handler_alloc_helpers.hpp create mode 100644 thirdparty/boost/asio/detail/handler_invoke_helpers.hpp create mode 100644 thirdparty/boost/asio/detail/handler_queue.hpp create mode 100644 thirdparty/boost/asio/detail/hash_map.hpp create mode 100644 thirdparty/boost/asio/detail/io_control.hpp create mode 100644 thirdparty/boost/asio/detail/kqueue_reactor.hpp create mode 100644 thirdparty/boost/asio/detail/kqueue_reactor_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/local_free_on_block_exit.hpp create mode 100644 thirdparty/boost/asio/detail/mutex.hpp create mode 100644 thirdparty/boost/asio/detail/noncopyable.hpp create mode 100644 thirdparty/boost/asio/detail/null_event.hpp create mode 100644 thirdparty/boost/asio/detail/null_mutex.hpp create mode 100644 thirdparty/boost/asio/detail/null_signal_blocker.hpp create mode 100644 thirdparty/boost/asio/detail/null_thread.hpp create mode 100644 thirdparty/boost/asio/detail/null_tss_ptr.hpp create mode 100644 thirdparty/boost/asio/detail/old_win_sdk_compat.hpp create mode 100644 thirdparty/boost/asio/detail/pipe_select_interrupter.hpp create mode 100644 thirdparty/boost/asio/detail/pop_options.hpp create mode 100644 thirdparty/boost/asio/detail/posix_event.hpp create mode 100644 thirdparty/boost/asio/detail/posix_fd_set_adapter.hpp create mode 100644 thirdparty/boost/asio/detail/posix_mutex.hpp create mode 100644 thirdparty/boost/asio/detail/posix_signal_blocker.hpp create mode 100644 thirdparty/boost/asio/detail/posix_thread.hpp create mode 100644 thirdparty/boost/asio/detail/posix_tss_ptr.hpp create mode 100644 thirdparty/boost/asio/detail/push_options.hpp create mode 100644 thirdparty/boost/asio/detail/reactive_socket_service.hpp create mode 100644 thirdparty/boost/asio/detail/reactor_op_queue.hpp create mode 100644 thirdparty/boost/asio/detail/resolver_service.hpp create mode 100644 thirdparty/boost/asio/detail/scoped_lock.hpp create mode 100644 thirdparty/boost/asio/detail/select_interrupter.hpp create mode 100644 thirdparty/boost/asio/detail/select_reactor.hpp create mode 100644 thirdparty/boost/asio/detail/select_reactor_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/service_base.hpp create mode 100644 thirdparty/boost/asio/detail/service_id.hpp create mode 100644 thirdparty/boost/asio/detail/service_registry.hpp create mode 100644 thirdparty/boost/asio/detail/service_registry_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/signal_blocker.hpp create mode 100644 thirdparty/boost/asio/detail/signal_init.hpp create mode 100644 thirdparty/boost/asio/detail/socket_holder.hpp create mode 100644 thirdparty/boost/asio/detail/socket_ops.hpp create mode 100644 thirdparty/boost/asio/detail/socket_option.hpp create mode 100644 thirdparty/boost/asio/detail/socket_select_interrupter.hpp create mode 100644 thirdparty/boost/asio/detail/socket_types.hpp create mode 100644 thirdparty/boost/asio/detail/strand_service.hpp create mode 100644 thirdparty/boost/asio/detail/task_io_service.hpp create mode 100644 thirdparty/boost/asio/detail/task_io_service_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/thread.hpp create mode 100644 thirdparty/boost/asio/detail/throw_error.hpp create mode 100644 thirdparty/boost/asio/detail/timer_queue.hpp create mode 100644 thirdparty/boost/asio/detail/timer_queue_base.hpp create mode 100644 thirdparty/boost/asio/detail/tss_ptr.hpp create mode 100644 thirdparty/boost/asio/detail/win_event.hpp create mode 100644 thirdparty/boost/asio/detail/win_fd_set_adapter.hpp create mode 100644 thirdparty/boost/asio/detail/win_iocp_io_service.hpp create mode 100644 thirdparty/boost/asio/detail/win_iocp_io_service_fwd.hpp create mode 100644 thirdparty/boost/asio/detail/win_iocp_socket_service.hpp create mode 100644 thirdparty/boost/asio/detail/win_mutex.hpp create mode 100644 thirdparty/boost/asio/detail/win_signal_blocker.hpp create mode 100644 thirdparty/boost/asio/detail/win_thread.hpp create mode 100644 thirdparty/boost/asio/detail/win_tss_ptr.hpp create mode 100644 thirdparty/boost/asio/detail/wince_thread.hpp create mode 100644 thirdparty/boost/asio/detail/winsock_init.hpp create mode 100644 thirdparty/boost/asio/detail/wrapped_handler.hpp create mode 100644 thirdparty/boost/asio/error.hpp create mode 100644 thirdparty/boost/asio/handler_alloc_hook.hpp create mode 100644 thirdparty/boost/asio/handler_invoke_hook.hpp create mode 100644 thirdparty/boost/asio/impl/io_service.ipp create mode 100644 thirdparty/boost/asio/impl/read.ipp create mode 100644 thirdparty/boost/asio/impl/read_until.ipp create mode 100644 thirdparty/boost/asio/impl/write.ipp create mode 100644 thirdparty/boost/asio/io_service.hpp create mode 100644 thirdparty/boost/asio/ip/address.hpp create mode 100644 thirdparty/boost/asio/ip/address_v4.hpp create mode 100644 thirdparty/boost/asio/ip/address_v6.hpp create mode 100644 thirdparty/boost/asio/ip/basic_endpoint.hpp create mode 100644 thirdparty/boost/asio/ip/basic_resolver.hpp create mode 100644 thirdparty/boost/asio/ip/basic_resolver_entry.hpp create mode 100644 thirdparty/boost/asio/ip/basic_resolver_iterator.hpp create mode 100644 thirdparty/boost/asio/ip/basic_resolver_query.hpp create mode 100644 thirdparty/boost/asio/ip/detail/socket_option.hpp create mode 100644 thirdparty/boost/asio/ip/host_name.hpp create mode 100644 thirdparty/boost/asio/ip/multicast.hpp create mode 100644 thirdparty/boost/asio/ip/resolver_query_base.hpp create mode 100644 thirdparty/boost/asio/ip/resolver_service.hpp create mode 100644 thirdparty/boost/asio/ip/tcp.hpp create mode 100644 thirdparty/boost/asio/ip/udp.hpp create mode 100644 thirdparty/boost/asio/ip/unicast.hpp create mode 100644 thirdparty/boost/asio/ip/v6_only.hpp create mode 100644 thirdparty/boost/asio/is_read_buffered.hpp create mode 100644 thirdparty/boost/asio/is_write_buffered.hpp create mode 100644 thirdparty/boost/asio/placeholders.hpp create mode 100644 thirdparty/boost/asio/read.hpp create mode 100644 thirdparty/boost/asio/read_until.hpp create mode 100644 thirdparty/boost/asio/socket_acceptor_service.hpp create mode 100644 thirdparty/boost/asio/socket_base.hpp create mode 100644 thirdparty/boost/asio/ssl.hpp create mode 100644 thirdparty/boost/asio/ssl/basic_context.hpp create mode 100644 thirdparty/boost/asio/ssl/context.hpp create mode 100644 thirdparty/boost/asio/ssl/context_base.hpp create mode 100644 thirdparty/boost/asio/ssl/context_service.hpp create mode 100644 thirdparty/boost/asio/ssl/detail/openssl_context_service.hpp create mode 100644 thirdparty/boost/asio/ssl/detail/openssl_init.hpp create mode 100644 thirdparty/boost/asio/ssl/detail/openssl_operation.hpp create mode 100644 thirdparty/boost/asio/ssl/detail/openssl_stream_service.hpp create mode 100644 thirdparty/boost/asio/ssl/detail/openssl_types.hpp create mode 100644 thirdparty/boost/asio/ssl/stream.hpp create mode 100644 thirdparty/boost/asio/ssl/stream_base.hpp create mode 100644 thirdparty/boost/asio/ssl/stream_service.hpp create mode 100644 thirdparty/boost/asio/strand.hpp create mode 100644 thirdparty/boost/asio/stream_socket_service.hpp create mode 100644 thirdparty/boost/asio/streambuf.hpp create mode 100644 thirdparty/boost/asio/time_traits.hpp create mode 100644 thirdparty/boost/asio/version.hpp create mode 100644 thirdparty/boost/asio/write.hpp create mode 100644 thirdparty/boost/assert.hpp create mode 100644 thirdparty/boost/assign.hpp create mode 100644 thirdparty/boost/assign/assignment_exception.hpp create mode 100644 thirdparty/boost/assign/list_inserter.hpp create mode 100644 thirdparty/boost/assign/list_of.hpp create mode 100644 thirdparty/boost/assign/ptr_list_inserter.hpp create mode 100644 thirdparty/boost/assign/ptr_list_of.hpp create mode 100644 thirdparty/boost/assign/ptr_map_inserter.hpp create mode 100644 thirdparty/boost/assign/std.hpp create mode 100644 thirdparty/boost/assign/std/deque.hpp create mode 100644 thirdparty/boost/assign/std/list.hpp create mode 100644 thirdparty/boost/assign/std/map.hpp create mode 100644 thirdparty/boost/assign/std/queue.hpp create mode 100644 thirdparty/boost/assign/std/set.hpp create mode 100644 thirdparty/boost/assign/std/slist.hpp create mode 100644 thirdparty/boost/assign/std/stack.hpp create mode 100644 thirdparty/boost/assign/std/vector.hpp create mode 100644 thirdparty/boost/bimap.hpp create mode 100644 thirdparty/boost/bimap/bimap.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/associative_container_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/container_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/detail/functor_bag.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/detail/identity_converters.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/detail/key_extractor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/list_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/list_map_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/map_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/multimap_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/multiset_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/sequence_container_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/set_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/unordered_map_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/unordered_set_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/vector_adaptor.hpp create mode 100644 thirdparty/boost/bimap/container_adaptor/vector_map_adaptor.hpp create mode 100644 thirdparty/boost/bimap/detail/bimap_core.hpp create mode 100644 thirdparty/boost/bimap/detail/concept_tags.hpp create mode 100644 thirdparty/boost/bimap/detail/debug/static_error.hpp create mode 100644 thirdparty/boost/bimap/detail/generate_index_binder.hpp create mode 100644 thirdparty/boost/bimap/detail/generate_relation_binder.hpp create mode 100644 thirdparty/boost/bimap/detail/generate_view_binder.hpp create mode 100644 thirdparty/boost/bimap/detail/is_set_type_of.hpp create mode 100644 thirdparty/boost/bimap/detail/manage_additional_parameters.hpp create mode 100644 thirdparty/boost/bimap/detail/manage_bimap_key.hpp create mode 100644 thirdparty/boost/bimap/detail/map_view_base.hpp create mode 100644 thirdparty/boost/bimap/detail/map_view_iterator.hpp create mode 100644 thirdparty/boost/bimap/detail/modifier_adaptor.hpp create mode 100644 thirdparty/boost/bimap/detail/non_unique_views_helper.hpp create mode 100644 thirdparty/boost/bimap/detail/set_view_base.hpp create mode 100644 thirdparty/boost/bimap/detail/set_view_iterator.hpp create mode 100644 thirdparty/boost/bimap/detail/test/check_metadata.hpp create mode 100644 thirdparty/boost/bimap/detail/user_interface_config.hpp create mode 100644 thirdparty/boost/bimap/list_of.hpp create mode 100644 thirdparty/boost/bimap/multiset_of.hpp create mode 100644 thirdparty/boost/bimap/property_map/set_support.hpp create mode 100644 thirdparty/boost/bimap/property_map/unordered_set_support.hpp create mode 100644 thirdparty/boost/bimap/relation/detail/access_builder.hpp create mode 100644 thirdparty/boost/bimap/relation/detail/metadata_access_builder.hpp create mode 100644 thirdparty/boost/bimap/relation/detail/mutant.hpp create mode 100644 thirdparty/boost/bimap/relation/detail/static_access_builder.hpp create mode 100644 thirdparty/boost/bimap/relation/detail/to_mutable_relation_functor.hpp create mode 100644 thirdparty/boost/bimap/relation/member_at.hpp create mode 100644 thirdparty/boost/bimap/relation/mutant_relation.hpp create mode 100644 thirdparty/boost/bimap/relation/pair_layout.hpp create mode 100644 thirdparty/boost/bimap/relation/structured_pair.hpp create mode 100644 thirdparty/boost/bimap/relation/support/data_extractor.hpp create mode 100644 thirdparty/boost/bimap/relation/support/get.hpp create mode 100644 thirdparty/boost/bimap/relation/support/get_pair_functor.hpp create mode 100644 thirdparty/boost/bimap/relation/support/is_tag_of_member_at.hpp create mode 100644 thirdparty/boost/bimap/relation/support/member_with_tag.hpp create mode 100644 thirdparty/boost/bimap/relation/support/opposite_tag.hpp create mode 100644 thirdparty/boost/bimap/relation/support/pair_by.hpp create mode 100644 thirdparty/boost/bimap/relation/support/pair_type_by.hpp create mode 100644 thirdparty/boost/bimap/relation/support/value_type_of.hpp create mode 100644 thirdparty/boost/bimap/relation/symmetrical_base.hpp create mode 100644 thirdparty/boost/bimap/set_of.hpp create mode 100644 thirdparty/boost/bimap/support/data_type_by.hpp create mode 100644 thirdparty/boost/bimap/support/iterator_type_by.hpp create mode 100644 thirdparty/boost/bimap/support/key_type_by.hpp create mode 100644 thirdparty/boost/bimap/support/lambda.hpp create mode 100644 thirdparty/boost/bimap/support/map_by.hpp create mode 100644 thirdparty/boost/bimap/support/map_type_by.hpp create mode 100644 thirdparty/boost/bimap/support/value_type_by.hpp create mode 100644 thirdparty/boost/bimap/tags/support/apply_to_value_type.hpp create mode 100644 thirdparty/boost/bimap/tags/support/default_tagged.hpp create mode 100644 thirdparty/boost/bimap/tags/support/is_tagged.hpp create mode 100644 thirdparty/boost/bimap/tags/support/overwrite_tagged.hpp create mode 100644 thirdparty/boost/bimap/tags/support/tag_of.hpp create mode 100644 thirdparty/boost/bimap/tags/support/value_type_of.hpp create mode 100644 thirdparty/boost/bimap/tags/tagged.hpp create mode 100644 thirdparty/boost/bimap/unconstrained_set_of.hpp create mode 100644 thirdparty/boost/bimap/unordered_multiset_of.hpp create mode 100644 thirdparty/boost/bimap/unordered_set_of.hpp create mode 100644 thirdparty/boost/bimap/vector_of.hpp create mode 100644 thirdparty/boost/bimap/views/list_map_view.hpp create mode 100644 thirdparty/boost/bimap/views/list_set_view.hpp create mode 100644 thirdparty/boost/bimap/views/map_view.hpp create mode 100644 thirdparty/boost/bimap/views/multimap_view.hpp create mode 100644 thirdparty/boost/bimap/views/multiset_view.hpp create mode 100644 thirdparty/boost/bimap/views/set_view.hpp create mode 100644 thirdparty/boost/bimap/views/unconstrained_map_view.hpp create mode 100644 thirdparty/boost/bimap/views/unconstrained_set_view.hpp create mode 100644 thirdparty/boost/bimap/views/unordered_map_view.hpp create mode 100644 thirdparty/boost/bimap/views/unordered_multimap_view.hpp create mode 100644 thirdparty/boost/bimap/views/unordered_multiset_view.hpp create mode 100644 thirdparty/boost/bimap/views/unordered_set_view.hpp create mode 100644 thirdparty/boost/bimap/views/vector_map_view.hpp create mode 100644 thirdparty/boost/bimap/views/vector_set_view.hpp create mode 100644 thirdparty/boost/bind.hpp create mode 100644 thirdparty/boost/bind/apply.hpp create mode 100644 thirdparty/boost/bind/arg.hpp create mode 100644 thirdparty/boost/bind/bind_cc.hpp create mode 100644 thirdparty/boost/bind/bind_mf_cc.hpp create mode 100644 thirdparty/boost/bind/bind_template.hpp create mode 100644 thirdparty/boost/bind/make_adaptable.hpp create mode 100644 thirdparty/boost/bind/mem_fn_cc.hpp create mode 100644 thirdparty/boost/bind/mem_fn_template.hpp create mode 100644 thirdparty/boost/bind/mem_fn_vw.hpp create mode 100644 thirdparty/boost/bind/placeholders.hpp create mode 100644 thirdparty/boost/bind/protect.hpp create mode 100644 thirdparty/boost/bind/storage.hpp create mode 100644 thirdparty/boost/blank.hpp create mode 100644 thirdparty/boost/blank_fwd.hpp create mode 100644 thirdparty/boost/call_traits.hpp create mode 100644 thirdparty/boost/cast.hpp create mode 100644 thirdparty/boost/cerrno.hpp create mode 100644 thirdparty/boost/checked_delete.hpp create mode 100644 thirdparty/boost/circular_buffer.hpp create mode 100644 thirdparty/boost/circular_buffer/base.hpp create mode 100644 thirdparty/boost/circular_buffer/debug.hpp create mode 100644 thirdparty/boost/circular_buffer/details.hpp create mode 100644 thirdparty/boost/circular_buffer/space_optimized.hpp create mode 100644 thirdparty/boost/circular_buffer_fwd.hpp create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cassert create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cctype create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cerrno create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cfloat create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/climits create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/clocale create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cmath create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/csetjmp create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/csignal create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cstdarg create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cstddef create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cstdio create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cstdlib create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cstring create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/ctime create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cwchar create mode 100644 thirdparty/boost/compatibility/cpp_c_headers/cwctype create mode 100644 thirdparty/boost/compressed_pair.hpp create mode 100644 thirdparty/boost/concept/assert.hpp create mode 100644 thirdparty/boost/concept/detail/borland.hpp create mode 100644 thirdparty/boost/concept/detail/concept_def.hpp create mode 100644 thirdparty/boost/concept/detail/concept_undef.hpp create mode 100644 thirdparty/boost/concept/detail/general.hpp create mode 100644 thirdparty/boost/concept/detail/has_constraints.hpp create mode 100644 thirdparty/boost/concept/detail/msvc.hpp create mode 100644 thirdparty/boost/concept/requires.hpp create mode 100644 thirdparty/boost/concept/usage.hpp create mode 100644 thirdparty/boost/concept_archetype.hpp create mode 100644 thirdparty/boost/concept_check.hpp create mode 100644 thirdparty/boost/concept_check/borland.hpp create mode 100644 thirdparty/boost/concept_check/general.hpp create mode 100644 thirdparty/boost/concept_check/has_constraints.hpp create mode 100644 thirdparty/boost/concept_check/msvc.hpp create mode 100644 thirdparty/boost/config.hpp create mode 100644 thirdparty/boost/config/abi/borland_prefix.hpp create mode 100644 thirdparty/boost/config/abi/borland_suffix.hpp create mode 100644 thirdparty/boost/config/abi/msvc_prefix.hpp create mode 100644 thirdparty/boost/config/abi/msvc_suffix.hpp create mode 100644 thirdparty/boost/config/abi_prefix.hpp create mode 100644 thirdparty/boost/config/abi_suffix.hpp create mode 100644 thirdparty/boost/config/auto_link.hpp create mode 100644 thirdparty/boost/config/compiler/borland.hpp create mode 100644 thirdparty/boost/config/compiler/comeau.hpp create mode 100644 thirdparty/boost/config/compiler/common_edg.hpp create mode 100644 thirdparty/boost/config/compiler/compaq_cxx.hpp create mode 100644 thirdparty/boost/config/compiler/digitalmars.hpp create mode 100644 thirdparty/boost/config/compiler/gcc.hpp create mode 100644 thirdparty/boost/config/compiler/gcc_xml.hpp create mode 100644 thirdparty/boost/config/compiler/greenhills.hpp create mode 100644 thirdparty/boost/config/compiler/hp_acc.hpp create mode 100644 thirdparty/boost/config/compiler/intel.hpp create mode 100644 thirdparty/boost/config/compiler/kai.hpp create mode 100644 thirdparty/boost/config/compiler/metrowerks.hpp create mode 100644 thirdparty/boost/config/compiler/mpw.hpp create mode 100644 thirdparty/boost/config/compiler/pgi.hpp create mode 100644 thirdparty/boost/config/compiler/sgi_mipspro.hpp create mode 100644 thirdparty/boost/config/compiler/sunpro_cc.hpp create mode 100644 thirdparty/boost/config/compiler/vacpp.hpp create mode 100644 thirdparty/boost/config/compiler/visualc.hpp create mode 100644 thirdparty/boost/config/no_tr1/complex.hpp create mode 100644 thirdparty/boost/config/no_tr1/functional.hpp create mode 100644 thirdparty/boost/config/no_tr1/memory.hpp create mode 100644 thirdparty/boost/config/no_tr1/utility.hpp create mode 100644 thirdparty/boost/config/platform/aix.hpp create mode 100644 thirdparty/boost/config/platform/amigaos.hpp create mode 100644 thirdparty/boost/config/platform/beos.hpp create mode 100644 thirdparty/boost/config/platform/bsd.hpp create mode 100644 thirdparty/boost/config/platform/cygwin.hpp create mode 100644 thirdparty/boost/config/platform/hpux.hpp create mode 100644 thirdparty/boost/config/platform/irix.hpp create mode 100644 thirdparty/boost/config/platform/linux.hpp create mode 100644 thirdparty/boost/config/platform/macos.hpp create mode 100644 thirdparty/boost/config/platform/qnxnto.hpp create mode 100644 thirdparty/boost/config/platform/solaris.hpp create mode 100644 thirdparty/boost/config/platform/win32.hpp create mode 100644 thirdparty/boost/config/posix_features.hpp create mode 100644 thirdparty/boost/config/requires_threads.hpp create mode 100644 thirdparty/boost/config/select_compiler_config.hpp create mode 100644 thirdparty/boost/config/select_platform_config.hpp create mode 100644 thirdparty/boost/config/select_stdlib_config.hpp create mode 100644 thirdparty/boost/config/stdlib/dinkumware.hpp create mode 100644 thirdparty/boost/config/stdlib/libcomo.hpp create mode 100644 thirdparty/boost/config/stdlib/libstdcpp3.hpp create mode 100644 thirdparty/boost/config/stdlib/modena.hpp create mode 100644 thirdparty/boost/config/stdlib/msl.hpp create mode 100644 thirdparty/boost/config/stdlib/roguewave.hpp create mode 100644 thirdparty/boost/config/stdlib/sgi.hpp create mode 100644 thirdparty/boost/config/stdlib/stlport.hpp create mode 100644 thirdparty/boost/config/stdlib/vacpp.hpp create mode 100644 thirdparty/boost/config/suffix.hpp create mode 100644 thirdparty/boost/config/user.hpp create mode 100644 thirdparty/boost/crc.hpp create mode 100644 thirdparty/boost/cregex.hpp create mode 100644 thirdparty/boost/cstdint.hpp create mode 100644 thirdparty/boost/cstdlib.hpp create mode 100644 thirdparty/boost/current_function.hpp create mode 100644 thirdparty/boost/date_time.hpp create mode 100644 thirdparty/boost/date_time/adjust_functors.hpp create mode 100644 thirdparty/boost/date_time/c_local_time_adjustor.hpp create mode 100644 thirdparty/boost/date_time/c_time.hpp create mode 100644 thirdparty/boost/date_time/compiler_config.hpp create mode 100644 thirdparty/boost/date_time/constrained_value.hpp create mode 100644 thirdparty/boost/date_time/date.hpp create mode 100644 thirdparty/boost/date_time/date_clock_device.hpp create mode 100644 thirdparty/boost/date_time/date_defs.hpp create mode 100644 thirdparty/boost/date_time/date_duration.hpp create mode 100644 thirdparty/boost/date_time/date_duration_types.hpp create mode 100644 thirdparty/boost/date_time/date_facet.hpp create mode 100644 thirdparty/boost/date_time/date_format_simple.hpp create mode 100644 thirdparty/boost/date_time/date_formatting.hpp create mode 100644 thirdparty/boost/date_time/date_formatting_limited.hpp create mode 100644 thirdparty/boost/date_time/date_formatting_locales.hpp create mode 100644 thirdparty/boost/date_time/date_generator_formatter.hpp create mode 100644 thirdparty/boost/date_time/date_generator_parser.hpp create mode 100644 thirdparty/boost/date_time/date_generators.hpp create mode 100644 thirdparty/boost/date_time/date_iterator.hpp create mode 100644 thirdparty/boost/date_time/date_names_put.hpp create mode 100644 thirdparty/boost/date_time/date_parsing.hpp create mode 100644 thirdparty/boost/date_time/dst_rules.hpp create mode 100644 thirdparty/boost/date_time/dst_transition_generators.hpp create mode 100644 thirdparty/boost/date_time/filetime_functions.hpp create mode 100644 thirdparty/boost/date_time/format_date_parser.hpp create mode 100644 thirdparty/boost/date_time/gregorian/conversion.hpp create mode 100644 thirdparty/boost/date_time/gregorian/formatters.hpp create mode 100644 thirdparty/boost/date_time/gregorian/formatters_limited.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_calendar.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_date.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_day.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_day_of_year.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_duration.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_duration_types.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_facet.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_month.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_serialize.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_weekday.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_year.hpp create mode 100644 thirdparty/boost/date_time/gregorian/greg_ymd.hpp create mode 100644 thirdparty/boost/date_time/gregorian/gregorian.hpp create mode 100644 thirdparty/boost/date_time/gregorian/gregorian_io.hpp create mode 100644 thirdparty/boost/date_time/gregorian/gregorian_types.hpp create mode 100644 thirdparty/boost/date_time/gregorian/parsers.hpp create mode 100644 thirdparty/boost/date_time/gregorian_calendar.hpp create mode 100644 thirdparty/boost/date_time/gregorian_calendar.ipp create mode 100644 thirdparty/boost/date_time/int_adapter.hpp create mode 100644 thirdparty/boost/date_time/iso_format.hpp create mode 100644 thirdparty/boost/date_time/local_time/conversion.hpp create mode 100644 thirdparty/boost/date_time/local_time/custom_time_zone.hpp create mode 100644 thirdparty/boost/date_time/local_time/date_duration_operators.hpp create mode 100644 thirdparty/boost/date_time/local_time/dst_transition_day_rules.hpp create mode 100644 thirdparty/boost/date_time/local_time/local_date_time.hpp create mode 100644 thirdparty/boost/date_time/local_time/local_time.hpp create mode 100644 thirdparty/boost/date_time/local_time/local_time_io.hpp create mode 100644 thirdparty/boost/date_time/local_time/local_time_types.hpp create mode 100644 thirdparty/boost/date_time/local_time/posix_time_zone.hpp create mode 100644 thirdparty/boost/date_time/local_time/tz_database.hpp create mode 100644 thirdparty/boost/date_time/local_time_adjustor.hpp create mode 100644 thirdparty/boost/date_time/local_timezone_defs.hpp create mode 100644 thirdparty/boost/date_time/locale_config.hpp create mode 100644 thirdparty/boost/date_time/microsec_time_clock.hpp create mode 100644 thirdparty/boost/date_time/parse_format_base.hpp create mode 100644 thirdparty/boost/date_time/period.hpp create mode 100644 thirdparty/boost/date_time/period_formatter.hpp create mode 100644 thirdparty/boost/date_time/period_parser.hpp create mode 100644 thirdparty/boost/date_time/posix_time/conversion.hpp create mode 100644 thirdparty/boost/date_time/posix_time/date_duration_operators.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_config.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_duration.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_io.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_legacy_io.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_system.hpp create mode 100644 thirdparty/boost/date_time/posix_time/posix_time_types.hpp create mode 100644 thirdparty/boost/date_time/posix_time/ptime.hpp create mode 100644 thirdparty/boost/date_time/posix_time/time_formatters.hpp create mode 100644 thirdparty/boost/date_time/posix_time/time_formatters_limited.hpp create mode 100644 thirdparty/boost/date_time/posix_time/time_parsers.hpp create mode 100644 thirdparty/boost/date_time/posix_time/time_period.hpp create mode 100644 thirdparty/boost/date_time/posix_time/time_serialize.hpp create mode 100644 thirdparty/boost/date_time/special_defs.hpp create mode 100644 thirdparty/boost/date_time/special_values_formatter.hpp create mode 100644 thirdparty/boost/date_time/special_values_parser.hpp create mode 100644 thirdparty/boost/date_time/string_convert.hpp create mode 100644 thirdparty/boost/date_time/string_parse_tree.hpp create mode 100644 thirdparty/boost/date_time/strings_from_facet.hpp create mode 100644 thirdparty/boost/date_time/testfrmwk.hpp create mode 100644 thirdparty/boost/date_time/time.hpp create mode 100644 thirdparty/boost/date_time/time_clock.hpp create mode 100644 thirdparty/boost/date_time/time_defs.hpp create mode 100644 thirdparty/boost/date_time/time_duration.hpp create mode 100644 thirdparty/boost/date_time/time_facet.hpp create mode 100644 thirdparty/boost/date_time/time_formatting_streams.hpp create mode 100644 thirdparty/boost/date_time/time_iterator.hpp create mode 100644 thirdparty/boost/date_time/time_parsing.hpp create mode 100644 thirdparty/boost/date_time/time_resolution_traits.hpp create mode 100644 thirdparty/boost/date_time/time_system_counted.hpp create mode 100644 thirdparty/boost/date_time/time_system_split.hpp create mode 100644 thirdparty/boost/date_time/time_zone_base.hpp create mode 100644 thirdparty/boost/date_time/time_zone_names.hpp create mode 100644 thirdparty/boost/date_time/tz_db_base.hpp create mode 100644 thirdparty/boost/date_time/wrapping_int.hpp create mode 100644 thirdparty/boost/date_time/year_month_day.hpp create mode 100644 thirdparty/boost/detail/algorithm.hpp create mode 100644 thirdparty/boost/detail/allocator_utilities.hpp create mode 100644 thirdparty/boost/detail/atomic_count.hpp create mode 100644 thirdparty/boost/detail/atomic_count_gcc.hpp create mode 100644 thirdparty/boost/detail/atomic_count_gcc_x86.hpp create mode 100644 thirdparty/boost/detail/atomic_count_pthreads.hpp create mode 100644 thirdparty/boost/detail/atomic_count_solaris.hpp create mode 100644 thirdparty/boost/detail/atomic_count_sync.hpp create mode 100644 thirdparty/boost/detail/atomic_count_win32.hpp create mode 100644 thirdparty/boost/detail/bad_weak_ptr.hpp create mode 100644 thirdparty/boost/detail/binary_search.hpp create mode 100644 thirdparty/boost/detail/call_traits.hpp create mode 100644 thirdparty/boost/detail/catch_exceptions.hpp create mode 100644 thirdparty/boost/detail/compressed_pair.hpp create mode 100644 thirdparty/boost/detail/dynamic_bitset.hpp create mode 100644 thirdparty/boost/detail/endian.hpp create mode 100644 thirdparty/boost/detail/has_default_constructor.hpp create mode 100644 thirdparty/boost/detail/identifier.hpp create mode 100644 thirdparty/boost/detail/indirect_traits.hpp create mode 100644 thirdparty/boost/detail/interlocked.hpp create mode 100644 thirdparty/boost/detail/is_function_ref_tester.hpp create mode 100644 thirdparty/boost/detail/is_incrementable.hpp create mode 100644 thirdparty/boost/detail/is_xxx.hpp create mode 100644 thirdparty/boost/detail/iterator.hpp create mode 100644 thirdparty/boost/detail/lcast_precision.hpp create mode 100644 thirdparty/boost/detail/lightweight_mutex.hpp create mode 100644 thirdparty/boost/detail/lightweight_test.hpp create mode 100644 thirdparty/boost/detail/limits.hpp create mode 100644 thirdparty/boost/detail/lwm_nop.hpp create mode 100644 thirdparty/boost/detail/lwm_pthreads.hpp create mode 100644 thirdparty/boost/detail/lwm_win32_cs.hpp create mode 100644 thirdparty/boost/detail/named_template_params.hpp create mode 100644 thirdparty/boost/detail/no_exceptions_support.hpp create mode 100644 thirdparty/boost/detail/none_t.hpp create mode 100644 thirdparty/boost/detail/numeric_traits.hpp create mode 100644 thirdparty/boost/detail/ob_call_traits.hpp create mode 100644 thirdparty/boost/detail/ob_compressed_pair.hpp create mode 100644 thirdparty/boost/detail/quick_allocator.hpp create mode 100644 thirdparty/boost/detail/reference_content.hpp create mode 100644 thirdparty/boost/detail/select_type.hpp create mode 100644 thirdparty/boost/detail/shared_array_nmt.hpp create mode 100644 thirdparty/boost/detail/shared_count.hpp create mode 100644 thirdparty/boost/detail/shared_ptr_nmt.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_acc_ia64.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_cw_ppc.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_cw_x86.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_gcc_ia64.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_gcc_ppc.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_gcc_sparc.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_gcc_x86.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_nt.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_pt.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_solaris.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_sync.hpp create mode 100644 thirdparty/boost/detail/sp_counted_base_w32.hpp create mode 100644 thirdparty/boost/detail/sp_counted_impl.hpp create mode 100644 thirdparty/boost/detail/sp_typeinfo.hpp create mode 100644 thirdparty/boost/detail/templated_streams.hpp create mode 100644 thirdparty/boost/detail/utf8_codecvt_facet.hpp create mode 100644 thirdparty/boost/detail/workaround.hpp create mode 100644 thirdparty/boost/dynamic_bitset.hpp create mode 100644 thirdparty/boost/dynamic_bitset/config.hpp create mode 100644 thirdparty/boost/dynamic_bitset/dynamic_bitset.hpp create mode 100644 thirdparty/boost/dynamic_bitset_fwd.hpp create mode 100644 thirdparty/boost/dynamic_property_map.hpp create mode 100644 thirdparty/boost/enable_shared_from_this.hpp create mode 100644 thirdparty/boost/filesystem.hpp create mode 100644 thirdparty/boost/filesystem/config.hpp create mode 100644 thirdparty/boost/filesystem/convenience.hpp create mode 100644 thirdparty/boost/filesystem/exception.hpp create mode 100644 thirdparty/boost/filesystem/fstream.hpp create mode 100644 thirdparty/boost/filesystem/operations.hpp create mode 100644 thirdparty/boost/filesystem/path.hpp create mode 100644 thirdparty/boost/foreach.hpp create mode 100644 thirdparty/boost/format.hpp create mode 100644 thirdparty/boost/format/alt_sstream.hpp create mode 100644 thirdparty/boost/format/alt_sstream_impl.hpp create mode 100644 thirdparty/boost/format/detail/compat_workarounds.hpp create mode 100644 thirdparty/boost/format/detail/config_macros.hpp create mode 100644 thirdparty/boost/format/detail/msvc_disambiguater.hpp create mode 100644 thirdparty/boost/format/detail/unset_macros.hpp create mode 100644 thirdparty/boost/format/detail/workarounds_gcc-2_95.hpp create mode 100644 thirdparty/boost/format/detail/workarounds_stlport.hpp create mode 100644 thirdparty/boost/format/exceptions.hpp create mode 100644 thirdparty/boost/format/feed_args.hpp create mode 100644 thirdparty/boost/format/format_class.hpp create mode 100644 thirdparty/boost/format/format_fwd.hpp create mode 100644 thirdparty/boost/format/format_implementation.hpp create mode 100644 thirdparty/boost/format/free_funcs.hpp create mode 100644 thirdparty/boost/format/group.hpp create mode 100644 thirdparty/boost/format/internals.hpp create mode 100644 thirdparty/boost/format/internals_fwd.hpp create mode 100644 thirdparty/boost/format/parsing.hpp create mode 100644 thirdparty/boost/function.hpp create mode 100644 thirdparty/boost/function/detail/function_iterate.hpp create mode 100644 thirdparty/boost/function/detail/gen_maybe_include.pl create mode 100644 thirdparty/boost/function/detail/maybe_include.hpp create mode 100644 thirdparty/boost/function/detail/prologue.hpp create mode 100644 thirdparty/boost/function/function0.hpp create mode 100644 thirdparty/boost/function/function1.hpp create mode 100644 thirdparty/boost/function/function10.hpp create mode 100644 thirdparty/boost/function/function2.hpp create mode 100644 thirdparty/boost/function/function3.hpp create mode 100644 thirdparty/boost/function/function4.hpp create mode 100644 thirdparty/boost/function/function5.hpp create mode 100644 thirdparty/boost/function/function6.hpp create mode 100644 thirdparty/boost/function/function7.hpp create mode 100644 thirdparty/boost/function/function8.hpp create mode 100644 thirdparty/boost/function/function9.hpp create mode 100644 thirdparty/boost/function/function_base.hpp create mode 100644 thirdparty/boost/function/function_template.hpp create mode 100644 thirdparty/boost/function/gen_function_N.pl create mode 100644 thirdparty/boost/function_equal.hpp create mode 100644 thirdparty/boost/function_output_iterator.hpp create mode 100644 thirdparty/boost/function_types/components.hpp create mode 100644 thirdparty/boost/function_types/config/cc_names.hpp create mode 100644 thirdparty/boost/function_types/config/compiler.hpp create mode 100644 thirdparty/boost/function_types/config/config.hpp create mode 100644 thirdparty/boost/function_types/detail/class_transform.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity10_0.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity10_1.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity20_0.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity20_1.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity30_0.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity30_1.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity40_0.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity40_1.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity50_0.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/arity50_1.hpp create mode 100644 thirdparty/boost/function_types/detail/classifier_impl/master.hpp create mode 100644 thirdparty/boost/function_types/detail/components_as_mpl_sequence.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity10_0.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity10_1.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity20_0.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity20_1.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity30_0.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity30_1.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity40_0.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity40_1.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity50_0.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/arity50_1.hpp create mode 100644 thirdparty/boost/function_types/detail/components_impl/master.hpp create mode 100644 thirdparty/boost/function_types/detail/cv_traits.hpp create mode 100644 thirdparty/boost/function_types/detail/encoding/aliases_def.hpp create mode 100644 thirdparty/boost/function_types/detail/encoding/aliases_undef.hpp create mode 100644 thirdparty/boost/function_types/detail/encoding/def.hpp create mode 100644 thirdparty/boost/function_types/detail/encoding/undef.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_arity_loop.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_cc_loop/master.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_cc_loop/preprocessed.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_loop.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_retag_default_cc/master.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_tags/cc_tag.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_tags/master.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_tags/preprocessed.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_variate_loop/master.hpp create mode 100644 thirdparty/boost/function_types/detail/pp_variate_loop/preprocessed.hpp create mode 100644 thirdparty/boost/function_types/detail/retag_default_cc.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity10_0.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity10_1.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity20_0.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity20_1.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity30_0.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity30_1.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity40_0.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity40_1.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity50_0.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/arity50_1.hpp create mode 100644 thirdparty/boost/function_types/detail/synthesize_impl/master.hpp create mode 100644 thirdparty/boost/function_types/detail/to_sequence.hpp create mode 100644 thirdparty/boost/function_types/function_arity.hpp create mode 100644 thirdparty/boost/function_types/function_pointer.hpp create mode 100644 thirdparty/boost/function_types/function_reference.hpp create mode 100644 thirdparty/boost/function_types/function_type.hpp create mode 100644 thirdparty/boost/function_types/is_callable_builtin.hpp create mode 100644 thirdparty/boost/function_types/is_function.hpp create mode 100644 thirdparty/boost/function_types/is_function_pointer.hpp create mode 100644 thirdparty/boost/function_types/is_function_reference.hpp create mode 100644 thirdparty/boost/function_types/is_member_function_pointer.hpp create mode 100644 thirdparty/boost/function_types/is_member_object_pointer.hpp create mode 100644 thirdparty/boost/function_types/is_member_pointer.hpp create mode 100644 thirdparty/boost/function_types/is_nonmember_callable_builtin.hpp create mode 100644 thirdparty/boost/function_types/member_function_pointer.hpp create mode 100644 thirdparty/boost/function_types/member_object_pointer.hpp create mode 100644 thirdparty/boost/function_types/parameter_types.hpp create mode 100644 thirdparty/boost/function_types/property_tags.hpp create mode 100644 thirdparty/boost/function_types/result_type.hpp create mode 100644 thirdparty/boost/functional.hpp create mode 100644 thirdparty/boost/functional/detail/container_fwd.hpp create mode 100644 thirdparty/boost/functional/detail/float_functions.hpp create mode 100644 thirdparty/boost/functional/detail/hash_float.hpp create mode 100644 thirdparty/boost/functional/hash.hpp create mode 100644 thirdparty/boost/functional/hash/deque.hpp create mode 100644 thirdparty/boost/functional/hash/hash.hpp create mode 100644 thirdparty/boost/functional/hash/list.hpp create mode 100644 thirdparty/boost/functional/hash/map.hpp create mode 100644 thirdparty/boost/functional/hash/pair.hpp create mode 100644 thirdparty/boost/functional/hash/set.hpp create mode 100644 thirdparty/boost/functional/hash/vector.hpp create mode 100644 thirdparty/boost/functional/hash_fwd.hpp create mode 100644 thirdparty/boost/fusion/adapted.hpp create mode 100644 thirdparty/boost/fusion/adapted/array.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/array_iterator.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/category_of_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/is_sequence_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/is_view_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/array/tag_of.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/category_of_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/is_sequence_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/is_view_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/boost_tuple/tag_of.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/category_of_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/empty_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/has_key_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/is_sequence_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/is_view_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/mpl/mpl_iterator.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/category_of_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/is_sequence_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/is_view_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/std_pair_iterator.hpp create mode 100644 thirdparty/boost/fusion/adapted/std_pair/tag_of.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/adapt_assoc_struct.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/adapt_struct.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/category_of_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/has_key_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/is_sequence_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/is_view_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/detail/value_at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/extension.hpp create mode 100644 thirdparty/boost/fusion/adapted/struct/struct_iterator.hpp create mode 100644 thirdparty/boost/fusion/algorithm.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/accumulate.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/detail/fold.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/detail/for_each.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/fold.hpp create mode 100644 thirdparty/boost/fusion/algorithm/iteration/for_each.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/all.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/any.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/count.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/count_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/all.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/any.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/assoc_find.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/count.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/count_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/detail/find_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/ext_/find_if_s.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/find.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/find_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/query/none.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/clear.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/detail/replace.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/detail/replace_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/erase.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/erase_key.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/filter.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/filter_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/insert.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/insert_range.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/join.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/pop_back.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/pop_front.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/push_back.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/push_front.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/remove.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/remove_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/replace.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/replace_if.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/reverse.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/transform.hpp create mode 100644 thirdparty/boost/fusion/algorithm/transformation/zip.hpp create mode 100644 thirdparty/boost/fusion/container.hpp create mode 100644 thirdparty/boost/fusion/container/deque.hpp create mode 100644 thirdparty/boost/fusion/container/deque/back_extended_deque.hpp create mode 100644 thirdparty/boost/fusion/container/deque/convert.hpp create mode 100644 thirdparty/boost/fusion/container/deque/deque.hpp create mode 100644 thirdparty/boost/fusion/container/deque/deque_fwd.hpp create mode 100644 thirdparty/boost/fusion/container/deque/deque_iterator.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/as_deque.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/convert_impl.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/deque_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/deque_initial_size.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/deque_keyed_values.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/keyed_element.hpp create mode 100644 thirdparty/boost/fusion/container/deque/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/deque/front_extended_deque.hpp create mode 100644 thirdparty/boost/fusion/container/deque/limits.hpp create mode 100644 thirdparty/boost/fusion/container/ext_/tree.hpp create mode 100644 thirdparty/boost/fusion/container/generation.hpp create mode 100644 thirdparty/boost/fusion/container/generation/cons_tie.hpp create mode 100644 thirdparty/boost/fusion/container/generation/deque_tie.hpp create mode 100644 thirdparty/boost/fusion/container/generation/ignore.hpp create mode 100644 thirdparty/boost/fusion/container/generation/list_tie.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_cons.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_deque.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_list.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_map.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_set.hpp create mode 100644 thirdparty/boost/fusion/container/generation/make_vector.hpp create mode 100644 thirdparty/boost/fusion/container/generation/map_tie.hpp create mode 100644 thirdparty/boost/fusion/container/generation/pair_tie.hpp create mode 100644 thirdparty/boost/fusion/container/generation/vector_tie.hpp create mode 100644 thirdparty/boost/fusion/container/list.hpp create mode 100644 thirdparty/boost/fusion/container/list/cons.hpp create mode 100644 thirdparty/boost/fusion/container/list/cons_iterator.hpp create mode 100644 thirdparty/boost/fusion/container/list/convert.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/build_cons.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/convert_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/empty_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/equal_to_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/list_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/list_to_cons.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/list_to_cons_call.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/container/list/limits.hpp create mode 100644 thirdparty/boost/fusion/container/list/list.hpp create mode 100644 thirdparty/boost/fusion/container/list/list_fwd.hpp create mode 100644 thirdparty/boost/fusion/container/map.hpp create mode 100644 thirdparty/boost/fusion/container/map/convert.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/as_map.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/convert_impl.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/lookup_key.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/map_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/map_lookup.hpp create mode 100644 thirdparty/boost/fusion/container/map/detail/value_at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/container/map/limits.hpp create mode 100644 thirdparty/boost/fusion/container/map/map.hpp create mode 100644 thirdparty/boost/fusion/container/map/map_fwd.hpp create mode 100644 thirdparty/boost/fusion/container/set.hpp create mode 100644 thirdparty/boost/fusion/container/set/convert.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/as_set.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/convert_impl.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/lookup_key.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/set_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/set_lookup.hpp create mode 100644 thirdparty/boost/fusion/container/set/detail/value_at_key_impl.hpp create mode 100644 thirdparty/boost/fusion/container/set/limits.hpp create mode 100644 thirdparty/boost/fusion/container/set/set.hpp create mode 100644 thirdparty/boost/fusion/container/set/set_fwd.hpp create mode 100644 thirdparty/boost/fusion/container/vector.hpp create mode 100644 thirdparty/boost/fusion/container/vector/convert.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/advance_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/as_vector.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/convert_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/distance_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/equal_to_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/prior_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/vector_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/vector_n.hpp create mode 100644 thirdparty/boost/fusion/container/vector/detail/vector_n_chooser.hpp create mode 100644 thirdparty/boost/fusion/container/vector/limits.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector10.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector20.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector30.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector40.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector50.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector_fwd.hpp create mode 100644 thirdparty/boost/fusion/container/vector/vector_iterator.hpp create mode 100644 thirdparty/boost/fusion/functional.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/detail/access.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/detail/pow2_explode.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/detail/pt_def.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/detail/pt_undef.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/fused.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/fused_function_object.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/fused_procedure.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/limits.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/unfused_generic.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/unfused_lvalue_args.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/unfused_rvalue_args.hpp create mode 100644 thirdparty/boost/fusion/functional/adapter/unfused_typed.hpp create mode 100644 thirdparty/boost/fusion/functional/generation.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/detail/gen_make_adapter.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_fused.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_fused_function_object.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_fused_procedure.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_unfused_generic.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_unfused_lvalue_args.hpp create mode 100644 thirdparty/boost/fusion/functional/generation/make_unfused_rvalue_args.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation/detail/that_ptr.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation/invoke.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation/invoke_function_object.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation/invoke_procedure.hpp create mode 100644 thirdparty/boost/fusion/functional/invocation/limits.hpp create mode 100644 thirdparty/boost/fusion/include/accumulate.hpp create mode 100644 thirdparty/boost/fusion/include/adapt_struct.hpp create mode 100644 thirdparty/boost/fusion/include/adapted.hpp create mode 100644 thirdparty/boost/fusion/include/adapter.hpp create mode 100644 thirdparty/boost/fusion/include/advance.hpp create mode 100644 thirdparty/boost/fusion/include/algorithm.hpp create mode 100644 thirdparty/boost/fusion/include/all.hpp create mode 100644 thirdparty/boost/fusion/include/any.hpp create mode 100644 thirdparty/boost/fusion/include/array.hpp create mode 100644 thirdparty/boost/fusion/include/as_deque.hpp create mode 100644 thirdparty/boost/fusion/include/as_list.hpp create mode 100644 thirdparty/boost/fusion/include/as_map.hpp create mode 100644 thirdparty/boost/fusion/include/as_set.hpp create mode 100644 thirdparty/boost/fusion/include/as_vector.hpp create mode 100644 thirdparty/boost/fusion/include/at.hpp create mode 100644 thirdparty/boost/fusion/include/at_key.hpp create mode 100644 thirdparty/boost/fusion/include/back.hpp create mode 100644 thirdparty/boost/fusion/include/begin.hpp create mode 100644 thirdparty/boost/fusion/include/boost_tuple.hpp create mode 100644 thirdparty/boost/fusion/include/category_of.hpp create mode 100644 thirdparty/boost/fusion/include/clear.hpp create mode 100644 thirdparty/boost/fusion/include/comparison.hpp create mode 100644 thirdparty/boost/fusion/include/cons.hpp create mode 100644 thirdparty/boost/fusion/include/cons_tie.hpp create mode 100644 thirdparty/boost/fusion/include/container.hpp create mode 100644 thirdparty/boost/fusion/include/convert.hpp create mode 100644 thirdparty/boost/fusion/include/count.hpp create mode 100644 thirdparty/boost/fusion/include/count_if.hpp create mode 100644 thirdparty/boost/fusion/include/deduce.hpp create mode 100644 thirdparty/boost/fusion/include/deduce_sequence.hpp create mode 100644 thirdparty/boost/fusion/include/deque.hpp create mode 100644 thirdparty/boost/fusion/include/deque_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/deque_tie.hpp create mode 100644 thirdparty/boost/fusion/include/deref.hpp create mode 100644 thirdparty/boost/fusion/include/distance.hpp create mode 100644 thirdparty/boost/fusion/include/empty.hpp create mode 100644 thirdparty/boost/fusion/include/end.hpp create mode 100644 thirdparty/boost/fusion/include/equal_to.hpp create mode 100644 thirdparty/boost/fusion/include/erase.hpp create mode 100644 thirdparty/boost/fusion/include/erase_key.hpp create mode 100644 thirdparty/boost/fusion/include/filter.hpp create mode 100644 thirdparty/boost/fusion/include/filter_if.hpp create mode 100644 thirdparty/boost/fusion/include/filter_view.hpp create mode 100644 thirdparty/boost/fusion/include/find.hpp create mode 100644 thirdparty/boost/fusion/include/find_if.hpp create mode 100644 thirdparty/boost/fusion/include/fold.hpp create mode 100644 thirdparty/boost/fusion/include/for_each.hpp create mode 100644 thirdparty/boost/fusion/include/front.hpp create mode 100644 thirdparty/boost/fusion/include/functional.hpp create mode 100644 thirdparty/boost/fusion/include/fused.hpp create mode 100644 thirdparty/boost/fusion/include/fused_function_object.hpp create mode 100644 thirdparty/boost/fusion/include/fused_procedure.hpp create mode 100644 thirdparty/boost/fusion/include/generation.hpp create mode 100644 thirdparty/boost/fusion/include/greater.hpp create mode 100644 thirdparty/boost/fusion/include/greater_equal.hpp create mode 100644 thirdparty/boost/fusion/include/has_key.hpp create mode 100644 thirdparty/boost/fusion/include/ignore.hpp create mode 100644 thirdparty/boost/fusion/include/in.hpp create mode 100644 thirdparty/boost/fusion/include/insert.hpp create mode 100644 thirdparty/boost/fusion/include/insert_range.hpp create mode 100644 thirdparty/boost/fusion/include/intrinsic.hpp create mode 100644 thirdparty/boost/fusion/include/invocation.hpp create mode 100644 thirdparty/boost/fusion/include/invoke.hpp create mode 100644 thirdparty/boost/fusion/include/invoke_function_object.hpp create mode 100644 thirdparty/boost/fusion/include/invoke_procedure.hpp create mode 100644 thirdparty/boost/fusion/include/io.hpp create mode 100644 thirdparty/boost/fusion/include/is_iterator.hpp create mode 100644 thirdparty/boost/fusion/include/is_sequence.hpp create mode 100644 thirdparty/boost/fusion/include/is_view.hpp create mode 100644 thirdparty/boost/fusion/include/iteration.hpp create mode 100644 thirdparty/boost/fusion/include/iterator.hpp create mode 100644 thirdparty/boost/fusion/include/iterator_base.hpp create mode 100644 thirdparty/boost/fusion/include/iterator_facade.hpp create mode 100644 thirdparty/boost/fusion/include/iterator_range.hpp create mode 100644 thirdparty/boost/fusion/include/join.hpp create mode 100644 thirdparty/boost/fusion/include/joint_view.hpp create mode 100644 thirdparty/boost/fusion/include/less.hpp create mode 100644 thirdparty/boost/fusion/include/less_equal.hpp create mode 100644 thirdparty/boost/fusion/include/list.hpp create mode 100644 thirdparty/boost/fusion/include/list_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/list_tie.hpp create mode 100644 thirdparty/boost/fusion/include/make_cons.hpp create mode 100644 thirdparty/boost/fusion/include/make_deque.hpp create mode 100644 thirdparty/boost/fusion/include/make_fused.hpp create mode 100644 thirdparty/boost/fusion/include/make_fused_function_object.hpp create mode 100644 thirdparty/boost/fusion/include/make_fused_procedure.hpp create mode 100644 thirdparty/boost/fusion/include/make_list.hpp create mode 100644 thirdparty/boost/fusion/include/make_map.hpp create mode 100644 thirdparty/boost/fusion/include/make_set.hpp create mode 100644 thirdparty/boost/fusion/include/make_tuple.hpp create mode 100644 thirdparty/boost/fusion/include/make_unfused_generic.hpp create mode 100644 thirdparty/boost/fusion/include/make_unfused_lvalue_args.hpp create mode 100644 thirdparty/boost/fusion/include/make_unfused_rvalue_args.hpp create mode 100644 thirdparty/boost/fusion/include/make_vector.hpp create mode 100644 thirdparty/boost/fusion/include/map.hpp create mode 100644 thirdparty/boost/fusion/include/map_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/map_tie.hpp create mode 100644 thirdparty/boost/fusion/include/mpl.hpp create mode 100644 thirdparty/boost/fusion/include/next.hpp create mode 100644 thirdparty/boost/fusion/include/none.hpp create mode 100644 thirdparty/boost/fusion/include/not_equal_to.hpp create mode 100644 thirdparty/boost/fusion/include/out.hpp create mode 100644 thirdparty/boost/fusion/include/pair.hpp create mode 100644 thirdparty/boost/fusion/include/pair_tie.hpp create mode 100644 thirdparty/boost/fusion/include/pop_back.hpp create mode 100644 thirdparty/boost/fusion/include/pop_front.hpp create mode 100644 thirdparty/boost/fusion/include/prior.hpp create mode 100644 thirdparty/boost/fusion/include/push_back.hpp create mode 100644 thirdparty/boost/fusion/include/push_front.hpp create mode 100644 thirdparty/boost/fusion/include/query.hpp create mode 100644 thirdparty/boost/fusion/include/remove.hpp create mode 100644 thirdparty/boost/fusion/include/remove_if.hpp create mode 100644 thirdparty/boost/fusion/include/repetetive_view.hpp create mode 100644 thirdparty/boost/fusion/include/replace.hpp create mode 100644 thirdparty/boost/fusion/include/replace_if.hpp create mode 100644 thirdparty/boost/fusion/include/reverse.hpp create mode 100644 thirdparty/boost/fusion/include/reverse_view.hpp create mode 100644 thirdparty/boost/fusion/include/sequence.hpp create mode 100644 thirdparty/boost/fusion/include/sequence_base.hpp create mode 100644 thirdparty/boost/fusion/include/sequence_facade.hpp create mode 100644 thirdparty/boost/fusion/include/set.hpp create mode 100644 thirdparty/boost/fusion/include/set_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/single_view.hpp create mode 100644 thirdparty/boost/fusion/include/size.hpp create mode 100644 thirdparty/boost/fusion/include/std_pair.hpp create mode 100644 thirdparty/boost/fusion/include/struct.hpp create mode 100644 thirdparty/boost/fusion/include/support.hpp create mode 100644 thirdparty/boost/fusion/include/swap.hpp create mode 100644 thirdparty/boost/fusion/include/tag_of.hpp create mode 100644 thirdparty/boost/fusion/include/tag_of_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/transform.hpp create mode 100644 thirdparty/boost/fusion/include/transform_view.hpp create mode 100644 thirdparty/boost/fusion/include/transformation.hpp create mode 100644 thirdparty/boost/fusion/include/tuple.hpp create mode 100644 thirdparty/boost/fusion/include/tuple_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/tuple_tie.hpp create mode 100644 thirdparty/boost/fusion/include/unfused_generic.hpp create mode 100644 thirdparty/boost/fusion/include/unfused_lvalue_args.hpp create mode 100644 thirdparty/boost/fusion/include/unfused_rvalue_args.hpp create mode 100644 thirdparty/boost/fusion/include/unfused_typed.hpp create mode 100644 thirdparty/boost/fusion/include/unused.hpp create mode 100644 thirdparty/boost/fusion/include/value_at.hpp create mode 100644 thirdparty/boost/fusion/include/value_at_key.hpp create mode 100644 thirdparty/boost/fusion/include/value_of.hpp create mode 100644 thirdparty/boost/fusion/include/vector.hpp create mode 100644 thirdparty/boost/fusion/include/vector10.hpp create mode 100644 thirdparty/boost/fusion/include/vector20.hpp create mode 100644 thirdparty/boost/fusion/include/vector30.hpp create mode 100644 thirdparty/boost/fusion/include/vector40.hpp create mode 100644 thirdparty/boost/fusion/include/vector50.hpp create mode 100644 thirdparty/boost/fusion/include/vector_fwd.hpp create mode 100644 thirdparty/boost/fusion/include/vector_tie.hpp create mode 100644 thirdparty/boost/fusion/include/view.hpp create mode 100644 thirdparty/boost/fusion/include/void.hpp create mode 100644 thirdparty/boost/fusion/include/zip.hpp create mode 100644 thirdparty/boost/fusion/include/zip_view.hpp create mode 100644 thirdparty/boost/fusion/iterator.hpp create mode 100644 thirdparty/boost/fusion/iterator/advance.hpp create mode 100644 thirdparty/boost/fusion/iterator/deref.hpp create mode 100644 thirdparty/boost/fusion/iterator/detail/adapt_deref_traits.hpp create mode 100644 thirdparty/boost/fusion/iterator/detail/adapt_value_traits.hpp create mode 100644 thirdparty/boost/fusion/iterator/detail/advance.hpp create mode 100644 thirdparty/boost/fusion/iterator/detail/distance.hpp create mode 100644 thirdparty/boost/fusion/iterator/distance.hpp create mode 100644 thirdparty/boost/fusion/iterator/equal_to.hpp create mode 100644 thirdparty/boost/fusion/iterator/iterator_facade.hpp create mode 100644 thirdparty/boost/fusion/iterator/mpl.hpp create mode 100644 thirdparty/boost/fusion/iterator/mpl/convert_iterator.hpp create mode 100644 thirdparty/boost/fusion/iterator/mpl/fusion_iterator.hpp create mode 100644 thirdparty/boost/fusion/iterator/next.hpp create mode 100644 thirdparty/boost/fusion/iterator/prior.hpp create mode 100644 thirdparty/boost/fusion/iterator/value_of.hpp create mode 100644 thirdparty/boost/fusion/mpl.hpp create mode 100644 thirdparty/boost/fusion/mpl/at.hpp create mode 100644 thirdparty/boost/fusion/mpl/back.hpp create mode 100644 thirdparty/boost/fusion/mpl/begin.hpp create mode 100644 thirdparty/boost/fusion/mpl/clear.hpp create mode 100644 thirdparty/boost/fusion/mpl/detail/clear.hpp create mode 100644 thirdparty/boost/fusion/mpl/empty.hpp create mode 100644 thirdparty/boost/fusion/mpl/end.hpp create mode 100644 thirdparty/boost/fusion/mpl/erase.hpp create mode 100644 thirdparty/boost/fusion/mpl/erase_key.hpp create mode 100644 thirdparty/boost/fusion/mpl/front.hpp create mode 100644 thirdparty/boost/fusion/mpl/has_key.hpp create mode 100644 thirdparty/boost/fusion/mpl/insert.hpp create mode 100644 thirdparty/boost/fusion/mpl/insert_range.hpp create mode 100644 thirdparty/boost/fusion/mpl/pop_back.hpp create mode 100644 thirdparty/boost/fusion/mpl/pop_front.hpp create mode 100644 thirdparty/boost/fusion/mpl/push_back.hpp create mode 100644 thirdparty/boost/fusion/mpl/push_front.hpp create mode 100644 thirdparty/boost/fusion/mpl/size.hpp create mode 100644 thirdparty/boost/fusion/sequence.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/enable_comparison.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/equal_to.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/greater.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/greater_equal.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/less.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/less_equal.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/equal_to.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/greater.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/greater_equal.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/less.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/less_equal.hpp create mode 100644 thirdparty/boost/fusion/sequence/comparison/not_equal_to.hpp create mode 100644 thirdparty/boost/fusion/sequence/convert.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/at.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/at_key.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/back.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/begin.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/empty.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/end.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/ext_/segments.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/ext_/size_s.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/front.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/has_key.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/size.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/swap.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/value_at.hpp create mode 100644 thirdparty/boost/fusion/sequence/intrinsic/value_at_key.hpp create mode 100644 thirdparty/boost/fusion/sequence/io.hpp create mode 100644 thirdparty/boost/fusion/sequence/io/detail/in.hpp create mode 100644 thirdparty/boost/fusion/sequence/io/detail/manip.hpp create mode 100644 thirdparty/boost/fusion/sequence/io/detail/out.hpp create mode 100644 thirdparty/boost/fusion/sequence/io/in.hpp create mode 100644 thirdparty/boost/fusion/sequence/io/out.hpp create mode 100644 thirdparty/boost/fusion/sequence/sequence_facade.hpp create mode 100644 thirdparty/boost/fusion/support.hpp create mode 100644 thirdparty/boost/fusion/support/category_of.hpp create mode 100644 thirdparty/boost/fusion/support/deduce.hpp create mode 100644 thirdparty/boost/fusion/support/deduce_sequence.hpp create mode 100644 thirdparty/boost/fusion/support/detail/access.hpp create mode 100644 thirdparty/boost/fusion/support/detail/as_fusion_element.hpp create mode 100644 thirdparty/boost/fusion/support/detail/category_of.hpp create mode 100644 thirdparty/boost/fusion/support/detail/is_mpl_sequence.hpp create mode 100644 thirdparty/boost/fusion/support/detail/is_view.hpp create mode 100644 thirdparty/boost/fusion/support/detail/mpl_iterator_category.hpp create mode 100644 thirdparty/boost/fusion/support/detail/unknown_key.hpp create mode 100644 thirdparty/boost/fusion/support/ext_/is_segmented.hpp create mode 100644 thirdparty/boost/fusion/support/is_iterator.hpp create mode 100644 thirdparty/boost/fusion/support/is_sequence.hpp create mode 100644 thirdparty/boost/fusion/support/is_view.hpp create mode 100644 thirdparty/boost/fusion/support/iterator_base.hpp create mode 100644 thirdparty/boost/fusion/support/pair.hpp create mode 100644 thirdparty/boost/fusion/support/sequence_base.hpp create mode 100644 thirdparty/boost/fusion/support/tag_of.hpp create mode 100644 thirdparty/boost/fusion/support/tag_of_fwd.hpp create mode 100644 thirdparty/boost/fusion/support/unused.hpp create mode 100644 thirdparty/boost/fusion/support/void.hpp create mode 100644 thirdparty/boost/fusion/tuple.hpp create mode 100644 thirdparty/boost/fusion/tuple/detail/tuple_forward_ctor.hpp create mode 100644 thirdparty/boost/fusion/tuple/make_tuple.hpp create mode 100644 thirdparty/boost/fusion/tuple/tuple.hpp create mode 100644 thirdparty/boost/fusion/tuple/tuple_fwd.hpp create mode 100644 thirdparty/boost/fusion/tuple/tuple_tie.hpp create mode 100644 thirdparty/boost/fusion/view.hpp create mode 100644 thirdparty/boost/fusion/view/detail/strictest_traversal.hpp create mode 100644 thirdparty/boost/fusion/view/ext_/multiple_view.hpp create mode 100644 thirdparty/boost/fusion/view/ext_/segmented_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/ext_/segmented_iterator_range.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/equal_to_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/filter_view.hpp create mode 100644 thirdparty/boost/fusion/view/filter_view/filter_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/iterator_range/iterator_range.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/joint_view.hpp create mode 100644 thirdparty/boost/fusion/view/joint_view/joint_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/repetitive_view.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/repetitive_view_fwd.hpp create mode 100644 thirdparty/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/advance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/distance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/prior_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/reverse_view.hpp create mode 100644 thirdparty/boost/fusion/view/reverse_view/reverse_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/single_view.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/single_view.hpp create mode 100644 thirdparty/boost/fusion/view/single_view/single_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/advance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/apply_transform_result.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/distance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/equal_to_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/prior_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/transform_view.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/transform_view_fwd.hpp create mode 100644 thirdparty/boost/fusion/view/transform_view/transform_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/advance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/begin_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/deref_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/distance_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/end_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/equal_to_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/next_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/prior_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/size_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/value_at_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/detail/value_of_impl.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/zip_view.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/zip_view_iterator.hpp create mode 100644 thirdparty/boost/fusion/view/zip_view/zip_view_iterator_fwd.hpp create mode 100644 thirdparty/boost/generator_iterator.hpp create mode 100644 thirdparty/boost/get_pointer.hpp create mode 100644 thirdparty/boost/gil/algorithm.hpp create mode 100644 thirdparty/boost/gil/bit_aligned_pixel_iterator.hpp create mode 100644 thirdparty/boost/gil/bit_aligned_pixel_reference.hpp create mode 100644 thirdparty/boost/gil/channel.hpp create mode 100644 thirdparty/boost/gil/channel_algorithm.hpp create mode 100644 thirdparty/boost/gil/cmyk.hpp create mode 100644 thirdparty/boost/gil/color_base.hpp create mode 100644 thirdparty/boost/gil/color_base_algorithm.hpp create mode 100644 thirdparty/boost/gil/color_convert.hpp create mode 100644 thirdparty/boost/gil/deprecated.hpp create mode 100644 thirdparty/boost/gil/device_n.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/algorithm.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/any_image.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/any_image_view.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/apply_operation.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/apply_operation_base.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/dynamic_at_c.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/dynamic_image_all.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/image_view_factory.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/reduce.hpp create mode 100644 thirdparty/boost/gil/extension/dynamic_image/variant.hpp create mode 100644 thirdparty/boost/gil/extension/io/dynamic_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/io_error.hpp create mode 100644 thirdparty/boost/gil/extension/io/jpeg_dynamic_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/jpeg_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/jpeg_io_private.hpp create mode 100644 thirdparty/boost/gil/extension/io/png_dynamic_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/png_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/png_io_private.hpp create mode 100644 thirdparty/boost/gil/extension/io/tiff_dynamic_io.hpp create mode 100644 thirdparty/boost/gil/extension/io/tiff_io.hpp create mode 100644 thirdparty/boost/gil/gil_all.hpp create mode 100644 thirdparty/boost/gil/gil_concept.hpp create mode 100644 thirdparty/boost/gil/gil_config.hpp create mode 100644 thirdparty/boost/gil/gray.hpp create mode 100644 thirdparty/boost/gil/image.hpp create mode 100644 thirdparty/boost/gil/image_view.hpp create mode 100644 thirdparty/boost/gil/image_view_factory.hpp create mode 100644 thirdparty/boost/gil/iterator_from_2d.hpp create mode 100644 thirdparty/boost/gil/locator.hpp create mode 100644 thirdparty/boost/gil/metafunctions.hpp create mode 100644 thirdparty/boost/gil/packed_pixel.hpp create mode 100644 thirdparty/boost/gil/pixel.hpp create mode 100644 thirdparty/boost/gil/pixel_iterator.hpp create mode 100644 thirdparty/boost/gil/pixel_iterator_adaptor.hpp create mode 100644 thirdparty/boost/gil/planar_pixel_iterator.hpp create mode 100644 thirdparty/boost/gil/planar_pixel_reference.hpp create mode 100644 thirdparty/boost/gil/position_iterator.hpp create mode 100644 thirdparty/boost/gil/rgb.hpp create mode 100644 thirdparty/boost/gil/rgba.hpp create mode 100644 thirdparty/boost/gil/step_iterator.hpp create mode 100644 thirdparty/boost/gil/typedefs.hpp create mode 100644 thirdparty/boost/gil/utilities.hpp create mode 100644 thirdparty/boost/gil/virtual_locator.hpp create mode 100644 thirdparty/boost/graph/adj_list_serialize.hpp create mode 100644 thirdparty/boost/graph/adjacency_iterator.hpp create mode 100644 thirdparty/boost/graph/adjacency_list.hpp create mode 100644 thirdparty/boost/graph/adjacency_list_io.hpp create mode 100644 thirdparty/boost/graph/adjacency_matrix.hpp create mode 100644 thirdparty/boost/graph/astar_search.hpp create mode 100644 thirdparty/boost/graph/bandwidth.hpp create mode 100644 thirdparty/boost/graph/bc_clustering.hpp create mode 100644 thirdparty/boost/graph/bellman_ford_shortest_paths.hpp create mode 100644 thirdparty/boost/graph/betweenness_centrality.hpp create mode 100644 thirdparty/boost/graph/biconnected_components.hpp create mode 100644 thirdparty/boost/graph/boyer_myrvold_planar_test.hpp create mode 100644 thirdparty/boost/graph/breadth_first_search.hpp create mode 100644 thirdparty/boost/graph/chrobak_payne_drawing.hpp create mode 100644 thirdparty/boost/graph/circle_layout.hpp create mode 100644 thirdparty/boost/graph/compressed_sparse_row_graph.hpp create mode 100644 thirdparty/boost/graph/connected_components.hpp create mode 100644 thirdparty/boost/graph/copy.hpp create mode 100644 thirdparty/boost/graph/create_condensation_graph.hpp create mode 100644 thirdparty/boost/graph/cuthill_mckee_ordering.hpp create mode 100644 thirdparty/boost/graph/dag_shortest_paths.hpp create mode 100644 thirdparty/boost/graph/depth_first_search.hpp create mode 100644 thirdparty/boost/graph/detail/adj_list_edge_iterator.hpp create mode 100644 thirdparty/boost/graph/detail/adjacency_list.hpp create mode 100644 thirdparty/boost/graph/detail/array_binary_tree.hpp create mode 100644 thirdparty/boost/graph/detail/connected_components.hpp create mode 100644 thirdparty/boost/graph/detail/edge.hpp create mode 100644 thirdparty/boost/graph/detail/incidence_iterator.hpp create mode 100644 thirdparty/boost/graph/detail/incremental_components.hpp create mode 100644 thirdparty/boost/graph/detail/indexed_properties.hpp create mode 100644 thirdparty/boost/graph/detail/is_same.hpp create mode 100644 thirdparty/boost/graph/detail/list_base.hpp create mode 100644 thirdparty/boost/graph/detail/permutation.hpp create mode 100644 thirdparty/boost/graph/detail/read_graphviz_spirit.hpp create mode 100644 thirdparty/boost/graph/detail/self_avoiding_walk.hpp create mode 100644 thirdparty/boost/graph/detail/set_adaptor.hpp create mode 100644 thirdparty/boost/graph/detail/shadow_iterator.hpp create mode 100644 thirdparty/boost/graph/detail/sparse_ordering.hpp create mode 100644 thirdparty/boost/graph/dijkstra_shortest_paths.hpp create mode 100644 thirdparty/boost/graph/dominator_tree.hpp create mode 100644 thirdparty/boost/graph/edge_connectivity.hpp create mode 100644 thirdparty/boost/graph/edge_list.hpp create mode 100644 thirdparty/boost/graph/edmunds_karp_max_flow.hpp create mode 100644 thirdparty/boost/graph/erdos_renyi_generator.hpp create mode 100644 thirdparty/boost/graph/exception.hpp create mode 100644 thirdparty/boost/graph/filtered_graph.hpp create mode 100644 thirdparty/boost/graph/floyd_warshall_shortest.hpp create mode 100644 thirdparty/boost/graph/fruchterman_reingold.hpp create mode 100644 thirdparty/boost/graph/graph_archetypes.hpp create mode 100644 thirdparty/boost/graph/graph_as_tree.hpp create mode 100644 thirdparty/boost/graph/graph_concepts.hpp create mode 100644 thirdparty/boost/graph/graph_selectors.hpp create mode 100644 thirdparty/boost/graph/graph_test.hpp create mode 100644 thirdparty/boost/graph/graph_traits.hpp create mode 100644 thirdparty/boost/graph/graph_utility.hpp create mode 100644 thirdparty/boost/graph/graphml.hpp create mode 100644 thirdparty/boost/graph/graphviz.hpp create mode 100644 thirdparty/boost/graph/gursoy_atun_layout.hpp create mode 100644 thirdparty/boost/graph/howard_cycle_ratio.hpp create mode 100644 thirdparty/boost/graph/incremental_components.hpp create mode 100644 thirdparty/boost/graph/is_kuratowski_subgraph.hpp create mode 100644 thirdparty/boost/graph/is_straight_line_drawing.hpp create mode 100644 thirdparty/boost/graph/isomorphism.hpp create mode 100644 thirdparty/boost/graph/iteration_macros.hpp create mode 100644 thirdparty/boost/graph/iteration_macros_undef.hpp create mode 100644 thirdparty/boost/graph/johnson_all_pairs_shortest.hpp create mode 100644 thirdparty/boost/graph/kamada_kawai_spring_layout.hpp create mode 100644 thirdparty/boost/graph/king_ordering.hpp create mode 100644 thirdparty/boost/graph/kolmogorov_max_flow.hpp create mode 100644 thirdparty/boost/graph/kruskal_min_spanning_tree.hpp create mode 100644 thirdparty/boost/graph/leda_graph.hpp create mode 100644 thirdparty/boost/graph/make_biconnected_planar.hpp create mode 100644 thirdparty/boost/graph/make_connected.hpp create mode 100644 thirdparty/boost/graph/make_maximal_planar.hpp create mode 100644 thirdparty/boost/graph/matrix_as_graph.hpp create mode 100644 thirdparty/boost/graph/max_cardinality_matching.hpp create mode 100644 thirdparty/boost/graph/minimum_degree_ordering.hpp create mode 100644 thirdparty/boost/graph/named_function_params.hpp create mode 100644 thirdparty/boost/graph/neighbor_bfs.hpp create mode 100644 thirdparty/boost/graph/page_rank.hpp create mode 100644 thirdparty/boost/graph/planar_canonical_ordering.hpp create mode 100644 thirdparty/boost/graph/planar_detail/add_edge_visitors.hpp create mode 100644 thirdparty/boost/graph/planar_detail/boyer_myrvold_impl.hpp create mode 100644 thirdparty/boost/graph/planar_detail/bucket_sort.hpp create mode 100644 thirdparty/boost/graph/planar_detail/face_handles.hpp create mode 100644 thirdparty/boost/graph/planar_detail/face_iterators.hpp create mode 100644 thirdparty/boost/graph/planar_face_traversal.hpp create mode 100644 thirdparty/boost/graph/plod_generator.hpp create mode 100644 thirdparty/boost/graph/prim_minimum_spanning_tree.hpp create mode 100644 thirdparty/boost/graph/profile.hpp create mode 100644 thirdparty/boost/graph/properties.hpp create mode 100644 thirdparty/boost/graph/property_iter_range.hpp create mode 100644 thirdparty/boost/graph/push_relabel_max_flow.hpp create mode 100644 thirdparty/boost/graph/random.hpp create mode 100644 thirdparty/boost/graph/random_layout.hpp create mode 100644 thirdparty/boost/graph/read_dimacs.hpp create mode 100644 thirdparty/boost/graph/relax.hpp create mode 100644 thirdparty/boost/graph/reverse_graph.hpp create mode 100644 thirdparty/boost/graph/sequential_vertex_coloring.hpp create mode 100644 thirdparty/boost/graph/simple_point.hpp create mode 100644 thirdparty/boost/graph/sloan_ordering.hpp create mode 100644 thirdparty/boost/graph/small_world_generator.hpp create mode 100644 thirdparty/boost/graph/smallest_last_ordering.hpp create mode 100644 thirdparty/boost/graph/stanford_graph.hpp create mode 100644 thirdparty/boost/graph/strong_components.hpp create mode 100644 thirdparty/boost/graph/subgraph.hpp create mode 100644 thirdparty/boost/graph/topological_sort.hpp create mode 100644 thirdparty/boost/graph/transitive_closure.hpp create mode 100644 thirdparty/boost/graph/transpose_graph.hpp create mode 100644 thirdparty/boost/graph/tree_traits.hpp create mode 100644 thirdparty/boost/graph/two_bit_color_map.hpp create mode 100644 thirdparty/boost/graph/undirected_dfs.hpp create mode 100644 thirdparty/boost/graph/vector_as_graph.hpp create mode 100644 thirdparty/boost/graph/visitors.hpp create mode 100644 thirdparty/boost/graph/wavefront.hpp create mode 100644 thirdparty/boost/graph/write_dimacs.hpp create mode 100644 thirdparty/boost/implicit_cast.hpp create mode 100644 thirdparty/boost/indirect_reference.hpp create mode 100644 thirdparty/boost/integer.hpp create mode 100644 thirdparty/boost/integer/integer_mask.hpp create mode 100644 thirdparty/boost/integer/static_log2.hpp create mode 100644 thirdparty/boost/integer/static_min_max.hpp create mode 100644 thirdparty/boost/integer_fwd.hpp create mode 100644 thirdparty/boost/integer_traits.hpp create mode 100644 thirdparty/boost/interprocess/allocators/adaptive_pool.hpp create mode 100644 thirdparty/boost/interprocess/allocators/allocation_type.hpp create mode 100644 thirdparty/boost/interprocess/allocators/allocator.hpp create mode 100644 thirdparty/boost/interprocess/allocators/cached_adaptive_pool.hpp create mode 100644 thirdparty/boost/interprocess/allocators/cached_node_allocator.hpp create mode 100644 thirdparty/boost/interprocess/allocators/detail/adaptive_node_pool.hpp create mode 100644 thirdparty/boost/interprocess/allocators/detail/allocator_common.hpp create mode 100644 thirdparty/boost/interprocess/allocators/detail/node_pool.hpp create mode 100644 thirdparty/boost/interprocess/allocators/detail/node_tools.hpp create mode 100644 thirdparty/boost/interprocess/allocators/node_allocator.hpp create mode 100644 thirdparty/boost/interprocess/allocators/private_adaptive_pool.hpp create mode 100644 thirdparty/boost/interprocess/allocators/private_node_allocator.hpp create mode 100644 thirdparty/boost/interprocess/containers/deque.hpp create mode 100644 thirdparty/boost/interprocess/containers/detail/flat_tree.hpp create mode 100644 thirdparty/boost/interprocess/containers/detail/node_alloc_holder.hpp create mode 100644 thirdparty/boost/interprocess/containers/detail/tree.hpp create mode 100644 thirdparty/boost/interprocess/containers/flat_map.hpp create mode 100644 thirdparty/boost/interprocess/containers/flat_set.hpp create mode 100644 thirdparty/boost/interprocess/containers/list.hpp create mode 100644 thirdparty/boost/interprocess/containers/map.hpp create mode 100644 thirdparty/boost/interprocess/containers/set.hpp create mode 100644 thirdparty/boost/interprocess/containers/slist.hpp create mode 100644 thirdparty/boost/interprocess/containers/string.hpp create mode 100644 thirdparty/boost/interprocess/containers/vector.hpp create mode 100644 thirdparty/boost/interprocess/creation_tags.hpp create mode 100644 thirdparty/boost/interprocess/detail/algorithms.hpp create mode 100644 thirdparty/boost/interprocess/detail/atomic.hpp create mode 100644 thirdparty/boost/interprocess/detail/cast_tags.hpp create mode 100644 thirdparty/boost/interprocess/detail/config_begin.hpp create mode 100644 thirdparty/boost/interprocess/detail/config_end.hpp create mode 100644 thirdparty/boost/interprocess/detail/file_wrapper.hpp create mode 100644 thirdparty/boost/interprocess/detail/in_place_interface.hpp create mode 100644 thirdparty/boost/interprocess/detail/interprocess_tester.hpp create mode 100644 thirdparty/boost/interprocess/detail/iterators.hpp create mode 100644 thirdparty/boost/interprocess/detail/managed_memory_impl.hpp create mode 100644 thirdparty/boost/interprocess/detail/managed_open_or_create_impl.hpp create mode 100644 thirdparty/boost/interprocess/detail/math_functions.hpp create mode 100644 thirdparty/boost/interprocess/detail/min_max.hpp create mode 100644 thirdparty/boost/interprocess/detail/move.hpp create mode 100644 thirdparty/boost/interprocess/detail/move_iterator.hpp create mode 100644 thirdparty/boost/interprocess/detail/mpl.hpp create mode 100644 thirdparty/boost/interprocess/detail/named_proxy.hpp create mode 100644 thirdparty/boost/interprocess/detail/os_file_functions.hpp create mode 100644 thirdparty/boost/interprocess/detail/os_thread_functions.hpp create mode 100644 thirdparty/boost/interprocess/detail/pointer_type.hpp create mode 100644 thirdparty/boost/interprocess/detail/posix_time_types_wrk.hpp create mode 100644 thirdparty/boost/interprocess/detail/ptime_wrk.hpp create mode 100644 thirdparty/boost/interprocess/detail/segment_manager_helper.hpp create mode 100644 thirdparty/boost/interprocess/detail/tmp_dir_helpers.hpp create mode 100644 thirdparty/boost/interprocess/detail/type_traits.hpp create mode 100644 thirdparty/boost/interprocess/detail/utilities.hpp create mode 100644 thirdparty/boost/interprocess/detail/version_type.hpp create mode 100644 thirdparty/boost/interprocess/detail/win32_api.hpp create mode 100644 thirdparty/boost/interprocess/detail/workaround.hpp create mode 100644 thirdparty/boost/interprocess/errors.hpp create mode 100644 thirdparty/boost/interprocess/exceptions.hpp create mode 100644 thirdparty/boost/interprocess/file_mapping.hpp create mode 100644 thirdparty/boost/interprocess/indexes/flat_map_index.hpp create mode 100644 thirdparty/boost/interprocess/indexes/iset_index.hpp create mode 100644 thirdparty/boost/interprocess/indexes/iunordered_set_index.hpp create mode 100644 thirdparty/boost/interprocess/indexes/map_index.hpp create mode 100644 thirdparty/boost/interprocess/indexes/null_index.hpp create mode 100644 thirdparty/boost/interprocess/indexes/unordered_map_index.hpp create mode 100644 thirdparty/boost/interprocess/interprocess_fwd.hpp create mode 100644 thirdparty/boost/interprocess/ipc/message_queue.hpp create mode 100644 thirdparty/boost/interprocess/managed_external_buffer.hpp create mode 100644 thirdparty/boost/interprocess/managed_heap_memory.hpp create mode 100644 thirdparty/boost/interprocess/managed_mapped_file.hpp create mode 100644 thirdparty/boost/interprocess/managed_shared_memory.hpp create mode 100644 thirdparty/boost/interprocess/managed_windows_shared_memory.hpp create mode 100644 thirdparty/boost/interprocess/mapped_region.hpp create mode 100644 thirdparty/boost/interprocess/mem_algo/detail/mem_algo_common.hpp create mode 100644 thirdparty/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp create mode 100644 thirdparty/boost/interprocess/mem_algo/rbtree_best_fit.hpp create mode 100644 thirdparty/boost/interprocess/mem_algo/simple_seq_fit.hpp create mode 100644 thirdparty/boost/interprocess/offset_ptr.hpp create mode 100644 thirdparty/boost/interprocess/segment_manager.hpp create mode 100644 thirdparty/boost/interprocess/shared_memory_object.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/deleter.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/detail/shared_count.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/enable_shared_from_this.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/intrusive_ptr.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/scoped_ptr.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/shared_ptr.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/unique_ptr.hpp create mode 100644 thirdparty/boost/interprocess/smart_ptr/weak_ptr.hpp create mode 100644 thirdparty/boost/interprocess/streams/bufferstream.hpp create mode 100644 thirdparty/boost/interprocess/streams/vectorstream.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/interprocess_barrier.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/interprocess_condition.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/interprocess_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/interprocess_semaphore.hpp create mode 100644 thirdparty/boost/interprocess/sync/emulation/named_creation_functor.hpp create mode 100644 thirdparty/boost/interprocess/sync/file_lock.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_barrier.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_condition.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_recursive_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_semaphore.hpp create mode 100644 thirdparty/boost/interprocess/sync/interprocess_upgradable_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/lock_options.hpp create mode 100644 thirdparty/boost/interprocess/sync/mutex_family.hpp create mode 100644 thirdparty/boost/interprocess/sync/named_condition.hpp create mode 100644 thirdparty/boost/interprocess/sync/named_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/named_recursive_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/named_semaphore.hpp create mode 100644 thirdparty/boost/interprocess/sync/named_upgradable_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/null_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/interprocess_barrier.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/interprocess_condition.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/interprocess_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/interprocess_semaphore.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/pthread_helpers.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/ptime_to_timespec.hpp create mode 100644 thirdparty/boost/interprocess/sync/posix/semaphore_wrapper.hpp create mode 100644 thirdparty/boost/interprocess/sync/scoped_lock.hpp create mode 100644 thirdparty/boost/interprocess/sync/sharable_lock.hpp create mode 100644 thirdparty/boost/interprocess/sync/upgradable_lock.hpp create mode 100644 thirdparty/boost/interprocess/windows_shared_memory.hpp create mode 100644 thirdparty/boost/intrusive/avl_set.hpp create mode 100644 thirdparty/boost/intrusive/avl_set_hook.hpp create mode 100644 thirdparty/boost/intrusive/avltree.hpp create mode 100644 thirdparty/boost/intrusive/avltree_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/bs_set_hook.hpp create mode 100644 thirdparty/boost/intrusive/circular_list_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/circular_slist_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/derivation_value_traits.hpp create mode 100644 thirdparty/boost/intrusive/detail/assert.hpp create mode 100644 thirdparty/boost/intrusive/detail/avltree_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/common_slist_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/detail/config_begin.hpp create mode 100644 thirdparty/boost/intrusive/detail/config_end.hpp create mode 100644 thirdparty/boost/intrusive/detail/ebo_functor_holder.hpp create mode 100644 thirdparty/boost/intrusive/detail/generic_hook.hpp create mode 100644 thirdparty/boost/intrusive/detail/hashtable_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/list_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/mpl.hpp create mode 100644 thirdparty/boost/intrusive/detail/no_exceptions_support.hpp create mode 100644 thirdparty/boost/intrusive/detail/parent_from_member.hpp create mode 100644 thirdparty/boost/intrusive/detail/pointer_to_other.hpp create mode 100644 thirdparty/boost/intrusive/detail/rbtree_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/slist_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/transform_iterator.hpp create mode 100644 thirdparty/boost/intrusive/detail/tree_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/detail/tree_node.hpp create mode 100644 thirdparty/boost/intrusive/detail/utilities.hpp create mode 100644 thirdparty/boost/intrusive/hashtable.hpp create mode 100644 thirdparty/boost/intrusive/intrusive_fwd.hpp create mode 100644 thirdparty/boost/intrusive/linear_slist_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/link_mode.hpp create mode 100644 thirdparty/boost/intrusive/list.hpp create mode 100644 thirdparty/boost/intrusive/list_hook.hpp create mode 100644 thirdparty/boost/intrusive/member_value_traits.hpp create mode 100644 thirdparty/boost/intrusive/options.hpp create mode 100644 thirdparty/boost/intrusive/pointer_plus_2_bits.hpp create mode 100644 thirdparty/boost/intrusive/pointer_plus_bit.hpp create mode 100644 thirdparty/boost/intrusive/rbtree.hpp create mode 100644 thirdparty/boost/intrusive/rbtree_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/set.hpp create mode 100644 thirdparty/boost/intrusive/set_hook.hpp create mode 100644 thirdparty/boost/intrusive/sg_set.hpp create mode 100644 thirdparty/boost/intrusive/sgtree.hpp create mode 100644 thirdparty/boost/intrusive/sgtree_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/slist.hpp create mode 100644 thirdparty/boost/intrusive/slist_hook.hpp create mode 100644 thirdparty/boost/intrusive/splay_set.hpp create mode 100644 thirdparty/boost/intrusive/splay_set_hook.hpp create mode 100644 thirdparty/boost/intrusive/splaytree.hpp create mode 100644 thirdparty/boost/intrusive/splaytree_algorithms.hpp create mode 100644 thirdparty/boost/intrusive/trivial_value_traits.hpp create mode 100644 thirdparty/boost/intrusive/unordered_set.hpp create mode 100644 thirdparty/boost/intrusive/unordered_set_hook.hpp create mode 100644 thirdparty/boost/intrusive_ptr.hpp create mode 100644 thirdparty/boost/io/ios_state.hpp create mode 100644 thirdparty/boost/io_fwd.hpp create mode 100644 thirdparty/boost/iostreams/categories.hpp create mode 100644 thirdparty/boost/iostreams/chain.hpp create mode 100644 thirdparty/boost/iostreams/char_traits.hpp create mode 100644 thirdparty/boost/iostreams/checked_operations.hpp create mode 100644 thirdparty/boost/iostreams/close.hpp create mode 100644 thirdparty/boost/iostreams/code_converter.hpp create mode 100644 thirdparty/boost/iostreams/combine.hpp create mode 100644 thirdparty/boost/iostreams/compose.hpp create mode 100644 thirdparty/boost/iostreams/concepts.hpp create mode 100644 thirdparty/boost/iostreams/constants.hpp create mode 100644 thirdparty/boost/iostreams/copy.hpp create mode 100644 thirdparty/boost/iostreams/detail/absolute_path.hpp create mode 100644 thirdparty/boost/iostreams/detail/access_control.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/concept_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/device_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/direct_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/filter_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/mode_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/non_blocking_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/output_iterator_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/adapter/range_adapter.hpp create mode 100644 thirdparty/boost/iostreams/detail/add_facet.hpp create mode 100644 thirdparty/boost/iostreams/detail/bool_trait_def.hpp create mode 100644 thirdparty/boost/iostreams/detail/broken_overload_resolution/forward.hpp create mode 100644 thirdparty/boost/iostreams/detail/broken_overload_resolution/stream.hpp create mode 100644 thirdparty/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp create mode 100644 thirdparty/boost/iostreams/detail/buffer.hpp create mode 100644 thirdparty/boost/iostreams/detail/call_traits.hpp create mode 100644 thirdparty/boost/iostreams/detail/char_traits.hpp create mode 100644 thirdparty/boost/iostreams/detail/codecvt_helper.hpp create mode 100644 thirdparty/boost/iostreams/detail/codecvt_holder.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/auto_link.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/bzip2.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/codecvt.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/disable_warnings.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/dyn_link.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/enable_warnings.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/fpos.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/gcc.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/limits.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/overload_resolution.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/rtl.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/wide_streams.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/windows_posix.hpp create mode 100644 thirdparty/boost/iostreams/detail/config/zlib.hpp create mode 100644 thirdparty/boost/iostreams/detail/counted_array.hpp create mode 100644 thirdparty/boost/iostreams/detail/current_directory.hpp create mode 100644 thirdparty/boost/iostreams/detail/default_arg.hpp create mode 100644 thirdparty/boost/iostreams/detail/dispatch.hpp create mode 100644 thirdparty/boost/iostreams/detail/double_object.hpp create mode 100644 thirdparty/boost/iostreams/detail/enable_if_stream.hpp create mode 100644 thirdparty/boost/iostreams/detail/error.hpp create mode 100644 thirdparty/boost/iostreams/detail/execute.hpp create mode 100644 thirdparty/boost/iostreams/detail/forward.hpp create mode 100644 thirdparty/boost/iostreams/detail/fstream.hpp create mode 100644 thirdparty/boost/iostreams/detail/functional.hpp create mode 100644 thirdparty/boost/iostreams/detail/ios.hpp create mode 100644 thirdparty/boost/iostreams/detail/iostream.hpp create mode 100644 thirdparty/boost/iostreams/detail/is_dereferenceable.hpp create mode 100644 thirdparty/boost/iostreams/detail/is_iterator_range.hpp create mode 100644 thirdparty/boost/iostreams/detail/newline.hpp create mode 100644 thirdparty/boost/iostreams/detail/optional.hpp create mode 100644 thirdparty/boost/iostreams/detail/param_type.hpp create mode 100644 thirdparty/boost/iostreams/detail/push.hpp create mode 100644 thirdparty/boost/iostreams/detail/push_params.hpp create mode 100644 thirdparty/boost/iostreams/detail/resolve.hpp create mode 100644 thirdparty/boost/iostreams/detail/restrict_impl.hpp create mode 100644 thirdparty/boost/iostreams/detail/select.hpp create mode 100644 thirdparty/boost/iostreams/detail/select_by_size.hpp create mode 100644 thirdparty/boost/iostreams/detail/streambuf.hpp create mode 100644 thirdparty/boost/iostreams/detail/streambuf/chainbuf.hpp create mode 100644 thirdparty/boost/iostreams/detail/streambuf/direct_streambuf.hpp create mode 100644 thirdparty/boost/iostreams/detail/streambuf/indirect_streambuf.hpp create mode 100644 thirdparty/boost/iostreams/detail/streambuf/linked_streambuf.hpp create mode 100644 thirdparty/boost/iostreams/detail/system_failure.hpp create mode 100644 thirdparty/boost/iostreams/detail/template_params.hpp create mode 100644 thirdparty/boost/iostreams/detail/translate_int_type.hpp create mode 100644 thirdparty/boost/iostreams/detail/vc6/close.hpp create mode 100644 thirdparty/boost/iostreams/detail/vc6/read.hpp create mode 100644 thirdparty/boost/iostreams/detail/vc6/write.hpp create mode 100644 thirdparty/boost/iostreams/detail/wrap_unwrap.hpp create mode 100644 thirdparty/boost/iostreams/device/array.hpp create mode 100644 thirdparty/boost/iostreams/device/back_inserter.hpp create mode 100644 thirdparty/boost/iostreams/device/file.hpp create mode 100644 thirdparty/boost/iostreams/device/file_descriptor.hpp create mode 100644 thirdparty/boost/iostreams/device/mapped_file.hpp create mode 100644 thirdparty/boost/iostreams/device/null.hpp create mode 100644 thirdparty/boost/iostreams/filter/aggregate.hpp create mode 100644 thirdparty/boost/iostreams/filter/bzip2.hpp create mode 100644 thirdparty/boost/iostreams/filter/counter.hpp create mode 100644 thirdparty/boost/iostreams/filter/gzip.hpp create mode 100644 thirdparty/boost/iostreams/filter/line.hpp create mode 100644 thirdparty/boost/iostreams/filter/newline.hpp create mode 100644 thirdparty/boost/iostreams/filter/regex.hpp create mode 100644 thirdparty/boost/iostreams/filter/stdio.hpp create mode 100644 thirdparty/boost/iostreams/filter/symmetric.hpp create mode 100644 thirdparty/boost/iostreams/filter/test.hpp create mode 100644 thirdparty/boost/iostreams/filter/zlib.hpp create mode 100644 thirdparty/boost/iostreams/filtering_stream.hpp create mode 100644 thirdparty/boost/iostreams/filtering_streambuf.hpp create mode 100644 thirdparty/boost/iostreams/flush.hpp create mode 100644 thirdparty/boost/iostreams/get.hpp create mode 100644 thirdparty/boost/iostreams/imbue.hpp create mode 100644 thirdparty/boost/iostreams/input_sequence.hpp create mode 100644 thirdparty/boost/iostreams/invert.hpp create mode 100644 thirdparty/boost/iostreams/operations.hpp create mode 100644 thirdparty/boost/iostreams/operations_fwd.hpp create mode 100644 thirdparty/boost/iostreams/optimal_buffer_size.hpp create mode 100644 thirdparty/boost/iostreams/output_sequence.hpp create mode 100644 thirdparty/boost/iostreams/pipeline.hpp create mode 100644 thirdparty/boost/iostreams/positioning.hpp create mode 100644 thirdparty/boost/iostreams/put.hpp create mode 100644 thirdparty/boost/iostreams/putback.hpp create mode 100644 thirdparty/boost/iostreams/read.hpp create mode 100644 thirdparty/boost/iostreams/restrict.hpp create mode 100644 thirdparty/boost/iostreams/seek.hpp create mode 100644 thirdparty/boost/iostreams/skip.hpp create mode 100644 thirdparty/boost/iostreams/slice.hpp create mode 100644 thirdparty/boost/iostreams/stream.hpp create mode 100644 thirdparty/boost/iostreams/stream_buffer.hpp create mode 100644 thirdparty/boost/iostreams/tee.hpp create mode 100644 thirdparty/boost/iostreams/traits.hpp create mode 100644 thirdparty/boost/iostreams/traits_fwd.hpp create mode 100644 thirdparty/boost/iostreams/write.hpp create mode 100644 thirdparty/boost/is_placeholder.hpp create mode 100644 thirdparty/boost/iterator.hpp create mode 100644 thirdparty/boost/iterator/counting_iterator.hpp create mode 100644 thirdparty/boost/iterator/detail/any_conversion_eater.hpp create mode 100644 thirdparty/boost/iterator/detail/config_def.hpp create mode 100644 thirdparty/boost/iterator/detail/config_undef.hpp create mode 100644 thirdparty/boost/iterator/detail/enable_if.hpp create mode 100644 thirdparty/boost/iterator/detail/facade_iterator_category.hpp create mode 100644 thirdparty/boost/iterator/detail/minimum_category.hpp create mode 100644 thirdparty/boost/iterator/filter_iterator.hpp create mode 100644 thirdparty/boost/iterator/indirect_iterator.hpp create mode 100644 thirdparty/boost/iterator/interoperable.hpp create mode 100644 thirdparty/boost/iterator/is_lvalue_iterator.hpp create mode 100644 thirdparty/boost/iterator/is_readable_iterator.hpp create mode 100644 thirdparty/boost/iterator/iterator_adaptor.hpp create mode 100644 thirdparty/boost/iterator/iterator_archetypes.hpp create mode 100644 thirdparty/boost/iterator/iterator_categories.hpp create mode 100644 thirdparty/boost/iterator/iterator_concepts.hpp create mode 100644 thirdparty/boost/iterator/iterator_facade.hpp create mode 100644 thirdparty/boost/iterator/iterator_traits.hpp create mode 100644 thirdparty/boost/iterator/new_iterator_tests.hpp create mode 100644 thirdparty/boost/iterator/permutation_iterator.hpp create mode 100644 thirdparty/boost/iterator/reverse_iterator.hpp create mode 100644 thirdparty/boost/iterator/transform_iterator.hpp create mode 100644 thirdparty/boost/iterator/zip_iterator.hpp create mode 100644 thirdparty/boost/iterator_adaptors.hpp create mode 100644 thirdparty/boost/lambda/algorithm.hpp create mode 100644 thirdparty/boost/lambda/bind.hpp create mode 100644 thirdparty/boost/lambda/casts.hpp create mode 100644 thirdparty/boost/lambda/closures.hpp create mode 100644 thirdparty/boost/lambda/construct.hpp create mode 100644 thirdparty/boost/lambda/control_structures.hpp create mode 100644 thirdparty/boost/lambda/core.hpp create mode 100644 thirdparty/boost/lambda/detail/actions.hpp create mode 100644 thirdparty/boost/lambda/detail/arity_code.hpp create mode 100644 thirdparty/boost/lambda/detail/bind_functions.hpp create mode 100644 thirdparty/boost/lambda/detail/control_constructs_common.hpp create mode 100644 thirdparty/boost/lambda/detail/control_structures_impl.hpp create mode 100644 thirdparty/boost/lambda/detail/function_adaptors.hpp create mode 100644 thirdparty/boost/lambda/detail/is_instance_of.hpp create mode 100644 thirdparty/boost/lambda/detail/lambda_config.hpp create mode 100644 thirdparty/boost/lambda/detail/lambda_functor_base.hpp create mode 100644 thirdparty/boost/lambda/detail/lambda_functors.hpp create mode 100644 thirdparty/boost/lambda/detail/lambda_fwd.hpp create mode 100644 thirdparty/boost/lambda/detail/lambda_traits.hpp create mode 100644 thirdparty/boost/lambda/detail/member_ptr.hpp create mode 100644 thirdparty/boost/lambda/detail/operator_actions.hpp create mode 100644 thirdparty/boost/lambda/detail/operator_lambda_func_base.hpp create mode 100644 thirdparty/boost/lambda/detail/operator_return_type_traits.hpp create mode 100644 thirdparty/boost/lambda/detail/operators.hpp create mode 100644 thirdparty/boost/lambda/detail/ret.hpp create mode 100644 thirdparty/boost/lambda/detail/return_type_traits.hpp create mode 100644 thirdparty/boost/lambda/detail/select_functions.hpp create mode 100644 thirdparty/boost/lambda/exceptions.hpp create mode 100644 thirdparty/boost/lambda/if.hpp create mode 100644 thirdparty/boost/lambda/lambda.hpp create mode 100644 thirdparty/boost/lambda/loops.hpp create mode 100644 thirdparty/boost/lambda/numeric.hpp create mode 100644 thirdparty/boost/lambda/switch.hpp create mode 100644 thirdparty/boost/last_value.hpp create mode 100644 thirdparty/boost/lexical_cast.hpp create mode 100644 thirdparty/boost/limits.hpp create mode 100644 thirdparty/boost/logic/tribool.hpp create mode 100644 thirdparty/boost/logic/tribool_fwd.hpp create mode 100644 thirdparty/boost/logic/tribool_io.hpp create mode 100644 thirdparty/boost/math/bindings/rr.hpp create mode 100644 thirdparty/boost/math/common_factor.hpp create mode 100644 thirdparty/boost/math/common_factor_ct.hpp create mode 100644 thirdparty/boost/math/common_factor_rt.hpp create mode 100644 thirdparty/boost/math/complex.hpp create mode 100644 thirdparty/boost/math/complex/acos.hpp create mode 100644 thirdparty/boost/math/complex/acosh.hpp create mode 100644 thirdparty/boost/math/complex/asin.hpp create mode 100644 thirdparty/boost/math/complex/asinh.hpp create mode 100644 thirdparty/boost/math/complex/atan.hpp create mode 100644 thirdparty/boost/math/complex/atanh.hpp create mode 100644 thirdparty/boost/math/complex/details.hpp create mode 100644 thirdparty/boost/math/complex/fabs.hpp create mode 100644 thirdparty/boost/math/concepts/distributions.hpp create mode 100644 thirdparty/boost/math/concepts/real_concept.hpp create mode 100644 thirdparty/boost/math/concepts/std_real_concept.hpp create mode 100644 thirdparty/boost/math/constants/constants.hpp create mode 100644 thirdparty/boost/math/distributions.hpp create mode 100644 thirdparty/boost/math/distributions/bernoulli.hpp create mode 100644 thirdparty/boost/math/distributions/beta.hpp create mode 100644 thirdparty/boost/math/distributions/binomial.hpp create mode 100644 thirdparty/boost/math/distributions/cauchy.hpp create mode 100644 thirdparty/boost/math/distributions/chi_squared.hpp create mode 100644 thirdparty/boost/math/distributions/complement.hpp create mode 100644 thirdparty/boost/math/distributions/detail/common_error_handling.hpp create mode 100644 thirdparty/boost/math/distributions/detail/derived_accessors.hpp create mode 100644 thirdparty/boost/math/distributions/detail/inv_discrete_quantile.hpp create mode 100644 thirdparty/boost/math/distributions/exponential.hpp create mode 100644 thirdparty/boost/math/distributions/extreme_value.hpp create mode 100644 thirdparty/boost/math/distributions/find_location.hpp create mode 100644 thirdparty/boost/math/distributions/find_scale.hpp create mode 100644 thirdparty/boost/math/distributions/fisher_f.hpp create mode 100644 thirdparty/boost/math/distributions/fwd.hpp create mode 100644 thirdparty/boost/math/distributions/gamma.hpp create mode 100644 thirdparty/boost/math/distributions/lognormal.hpp create mode 100644 thirdparty/boost/math/distributions/negative_binomial.hpp create mode 100644 thirdparty/boost/math/distributions/normal.hpp create mode 100644 thirdparty/boost/math/distributions/pareto.hpp create mode 100644 thirdparty/boost/math/distributions/poisson.hpp create mode 100644 thirdparty/boost/math/distributions/rayleigh.hpp create mode 100644 thirdparty/boost/math/distributions/students_t.hpp create mode 100644 thirdparty/boost/math/distributions/triangular.hpp create mode 100644 thirdparty/boost/math/distributions/uniform.hpp create mode 100644 thirdparty/boost/math/distributions/weibull.hpp create mode 100644 thirdparty/boost/math/octonion.hpp create mode 100644 thirdparty/boost/math/policies/error_handling.hpp create mode 100644 thirdparty/boost/math/policies/policy.hpp create mode 100644 thirdparty/boost/math/quaternion.hpp create mode 100644 thirdparty/boost/math/special_functions.hpp create mode 100644 thirdparty/boost/math/special_functions/acosh.hpp create mode 100644 thirdparty/boost/math/special_functions/asinh.hpp create mode 100644 thirdparty/boost/math/special_functions/atanh.hpp create mode 100644 thirdparty/boost/math/special_functions/bessel.hpp create mode 100644 thirdparty/boost/math/special_functions/beta.hpp create mode 100644 thirdparty/boost/math/special_functions/binomial.hpp create mode 100644 thirdparty/boost/math/special_functions/cbrt.hpp create mode 100644 thirdparty/boost/math/special_functions/cos_pi.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_i0.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_i1.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_ik.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_j0.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_j1.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_jn.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_jy.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_jy_asym.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_k0.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_k1.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_kn.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_y0.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_y1.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/bessel_yn.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/erf_inv.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/gamma_inva.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/ibeta_inv_ab.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/ibeta_inverse.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/igamma_inverse.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/igamma_large.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/lgamma_small.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/simple_complex.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/t_distribution_inv.hpp create mode 100644 thirdparty/boost/math/special_functions/detail/unchecked_factorial.hpp create mode 100644 thirdparty/boost/math/special_functions/digamma.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_1.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_2.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_3.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_rc.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_rd.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_rf.hpp create mode 100644 thirdparty/boost/math/special_functions/ellint_rj.hpp create mode 100644 thirdparty/boost/math/special_functions/erf.hpp create mode 100644 thirdparty/boost/math/special_functions/expm1.hpp create mode 100644 thirdparty/boost/math/special_functions/factorials.hpp create mode 100644 thirdparty/boost/math/special_functions/fpclassify.hpp create mode 100644 thirdparty/boost/math/special_functions/gamma.hpp create mode 100644 thirdparty/boost/math/special_functions/hermite.hpp create mode 100644 thirdparty/boost/math/special_functions/hypot.hpp create mode 100644 thirdparty/boost/math/special_functions/laguerre.hpp create mode 100644 thirdparty/boost/math/special_functions/lanczos.hpp create mode 100644 thirdparty/boost/math/special_functions/legendre.hpp create mode 100644 thirdparty/boost/math/special_functions/log1p.hpp create mode 100644 thirdparty/boost/math/special_functions/math_fwd.hpp create mode 100644 thirdparty/boost/math/special_functions/powm1.hpp create mode 100644 thirdparty/boost/math/special_functions/sign.hpp create mode 100644 thirdparty/boost/math/special_functions/sin_pi.hpp create mode 100644 thirdparty/boost/math/special_functions/sinc.hpp create mode 100644 thirdparty/boost/math/special_functions/sinhc.hpp create mode 100644 thirdparty/boost/math/special_functions/spherical_harmonic.hpp create mode 100644 thirdparty/boost/math/special_functions/sqrt1pm1.hpp create mode 100644 thirdparty/boost/math/tools/config.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner1_9.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner2_9.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/polynomial_horner3_9.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner1_9.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner2_9.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_10.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_11.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_12.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_13.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_14.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_15.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_16.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_17.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_18.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_19.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_2.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_20.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_3.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_4.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_5.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_6.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_7.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_8.hpp create mode 100644 thirdparty/boost/math/tools/detail/rational_horner3_9.hpp create mode 100644 thirdparty/boost/math/tools/fraction.hpp create mode 100644 thirdparty/boost/math/tools/minima.hpp create mode 100644 thirdparty/boost/math/tools/polynomial.hpp create mode 100644 thirdparty/boost/math/tools/precision.hpp create mode 100644 thirdparty/boost/math/tools/promotion.hpp create mode 100644 thirdparty/boost/math/tools/rational.hpp create mode 100644 thirdparty/boost/math/tools/real_cast.hpp create mode 100644 thirdparty/boost/math/tools/remez.hpp create mode 100644 thirdparty/boost/math/tools/roots.hpp create mode 100644 thirdparty/boost/math/tools/series.hpp create mode 100644 thirdparty/boost/math/tools/solve.hpp create mode 100644 thirdparty/boost/math/tools/stats.hpp create mode 100644 thirdparty/boost/math/tools/test.hpp create mode 100644 thirdparty/boost/math/tools/test_data.hpp create mode 100644 thirdparty/boost/math/tools/toms748_solve.hpp create mode 100644 thirdparty/boost/math/tools/traits.hpp create mode 100644 thirdparty/boost/math/tools/user.hpp create mode 100644 thirdparty/boost/math/tools/workaround.hpp create mode 100644 thirdparty/boost/math_fwd.hpp create mode 100644 thirdparty/boost/mem_fn.hpp create mode 100644 thirdparty/boost/mpi.hpp create mode 100644 thirdparty/boost/mpi/allocator.hpp create mode 100644 thirdparty/boost/mpi/collectives.hpp create mode 100644 thirdparty/boost/mpi/collectives/all_gather.hpp create mode 100644 thirdparty/boost/mpi/collectives/all_reduce.hpp create mode 100644 thirdparty/boost/mpi/collectives/all_to_all.hpp create mode 100644 thirdparty/boost/mpi/collectives/broadcast.hpp create mode 100644 thirdparty/boost/mpi/collectives/gather.hpp create mode 100644 thirdparty/boost/mpi/collectives/reduce.hpp create mode 100644 thirdparty/boost/mpi/collectives/scan.hpp create mode 100644 thirdparty/boost/mpi/collectives/scatter.hpp create mode 100644 thirdparty/boost/mpi/collectives_fwd.hpp create mode 100644 thirdparty/boost/mpi/communicator.hpp create mode 100644 thirdparty/boost/mpi/config.hpp create mode 100644 thirdparty/boost/mpi/datatype.hpp create mode 100644 thirdparty/boost/mpi/datatype_fwd.hpp create mode 100644 thirdparty/boost/mpi/detail/broadcast_sc.hpp create mode 100644 thirdparty/boost/mpi/detail/communicator_sc.hpp create mode 100644 thirdparty/boost/mpi/detail/computation_tree.hpp create mode 100644 thirdparty/boost/mpi/detail/content_oarchive.hpp create mode 100644 thirdparty/boost/mpi/detail/forward_iprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/forward_oprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/forward_skeleton_iarchive.hpp create mode 100644 thirdparty/boost/mpi/detail/forward_skeleton_oarchive.hpp create mode 100644 thirdparty/boost/mpi/detail/ignore_iprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/ignore_oprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/ignore_skeleton_oarchive.hpp create mode 100644 thirdparty/boost/mpi/detail/mpi_datatype_cache.hpp create mode 100644 thirdparty/boost/mpi/detail/mpi_datatype_oarchive.hpp create mode 100644 thirdparty/boost/mpi/detail/mpi_datatype_primitive.hpp create mode 100644 thirdparty/boost/mpi/detail/packed_iprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/packed_oprimitive.hpp create mode 100644 thirdparty/boost/mpi/detail/point_to_point.hpp create mode 100644 thirdparty/boost/mpi/detail/text_skeleton_oarchive.hpp create mode 100644 thirdparty/boost/mpi/environment.hpp create mode 100644 thirdparty/boost/mpi/exception.hpp create mode 100644 thirdparty/boost/mpi/graph_communicator.hpp create mode 100644 thirdparty/boost/mpi/group.hpp create mode 100644 thirdparty/boost/mpi/intercommunicator.hpp create mode 100644 thirdparty/boost/mpi/nonblocking.hpp create mode 100644 thirdparty/boost/mpi/operations.hpp create mode 100644 thirdparty/boost/mpi/packed_iarchive.hpp create mode 100644 thirdparty/boost/mpi/packed_oarchive.hpp create mode 100644 thirdparty/boost/mpi/python.hpp create mode 100644 thirdparty/boost/mpi/python/config.hpp create mode 100644 thirdparty/boost/mpi/python/serialize.hpp create mode 100644 thirdparty/boost/mpi/python/skeleton_and_content.hpp create mode 100644 thirdparty/boost/mpi/request.hpp create mode 100644 thirdparty/boost/mpi/skeleton_and_content.hpp create mode 100644 thirdparty/boost/mpi/skeleton_and_content_fwd.hpp create mode 100644 thirdparty/boost/mpi/status.hpp create mode 100644 thirdparty/boost/mpi/timer.hpp create mode 100644 thirdparty/boost/mpl/O1_size.hpp create mode 100644 thirdparty/boost/mpl/O1_size_fwd.hpp create mode 100644 thirdparty/boost/mpl/accumulate.hpp create mode 100644 thirdparty/boost/mpl/advance.hpp create mode 100644 thirdparty/boost/mpl/advance_fwd.hpp create mode 100644 thirdparty/boost/mpl/alias.hpp create mode 100644 thirdparty/boost/mpl/always.hpp create mode 100644 thirdparty/boost/mpl/and.hpp create mode 100644 thirdparty/boost/mpl/apply.hpp create mode 100644 thirdparty/boost/mpl/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/arg.hpp create mode 100644 thirdparty/boost/mpl/arg_fwd.hpp create mode 100644 thirdparty/boost/mpl/arithmetic.hpp create mode 100644 thirdparty/boost/mpl/as_sequence.hpp create mode 100644 thirdparty/boost/mpl/assert.hpp create mode 100644 thirdparty/boost/mpl/at.hpp create mode 100644 thirdparty/boost/mpl/at_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/O1_size_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/adl_barrier.hpp create mode 100644 thirdparty/boost/mpl/aux_/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/apply_1st.hpp create mode 100644 thirdparty/boost/mpl/aux_/arg_typedef.hpp create mode 100644 thirdparty/boost/mpl/aux_/arithmetic_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/arity_spec.hpp create mode 100644 thirdparty/boost/mpl/aux_/at_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/back_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/begin_end_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/clear_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/common_name_wknd.hpp create mode 100644 thirdparty/boost/mpl/aux_/comparison_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/adl.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/arrays.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/compiler.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/dependent_nttp.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/dtp.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/eti.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/forwarding.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/gcc.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/has_apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/has_xxx.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/integral.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/intel.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/msvc.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/msvc_typename.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/nttp.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/operators.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/overload_resolution.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/pp_counter.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/preprocessor.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/static_constant.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/ttp.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/typeof.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/use_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/aux_/config/workaround.hpp create mode 100644 thirdparty/boost/mpl/aux_/contains_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/count_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/count_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/empty_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/erase_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/erase_key_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/filter_iter.hpp create mode 100644 thirdparty/boost/mpl/aux_/find_if_pred.hpp create mode 100644 thirdparty/boost/mpl/aux_/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/fold_impl_body.hpp create mode 100644 thirdparty/boost/mpl/aux_/fold_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/fold_pred.hpp create mode 100644 thirdparty/boost/mpl/aux_/front_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_begin.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_key_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_rebind.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_size.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_tag.hpp create mode 100644 thirdparty/boost/mpl/aux_/has_type.hpp create mode 100644 thirdparty/boost/mpl/aux_/include_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/aux_/insert_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/insert_range_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/inserter_algorithm.hpp create mode 100644 thirdparty/boost/mpl/aux_/integral_wrapper.hpp create mode 100644 thirdparty/boost/mpl/aux_/is_msvc_eti_arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/iter_apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/iter_push_front.hpp create mode 100644 thirdparty/boost/mpl/aux_/joint_iter.hpp create mode 100644 thirdparty/boost/mpl/aux_/lambda_arity_param.hpp create mode 100644 thirdparty/boost/mpl/aux_/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/lambda_spec.hpp create mode 100644 thirdparty/boost/mpl/aux_/lambda_support.hpp create mode 100644 thirdparty/boost/mpl/aux_/largest_int.hpp create mode 100644 thirdparty/boost/mpl/aux_/logical_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/msvc_dtw.hpp create mode 100644 thirdparty/boost/mpl/aux_/msvc_eti_base.hpp create mode 100644 thirdparty/boost/mpl/aux_/msvc_is_class.hpp create mode 100644 thirdparty/boost/mpl/aux_/msvc_never_true.hpp create mode 100644 thirdparty/boost/mpl/aux_/msvc_type.hpp create mode 100644 thirdparty/boost/mpl/aux_/na.hpp create mode 100644 thirdparty/boost/mpl/aux_/na_assert.hpp create mode 100644 thirdparty/boost/mpl/aux_/na_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/na_spec.hpp create mode 100644 thirdparty/boost/mpl/aux_/nested_type_wknd.hpp create mode 100644 thirdparty/boost/mpl/aux_/nttp_decl.hpp create mode 100644 thirdparty/boost/mpl/aux_/numeric_cast_utils.hpp create mode 100644 thirdparty/boost/mpl/aux_/numeric_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/order_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/overload_names.hpp create mode 100644 thirdparty/boost/mpl/aux_/partition_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/pop_back_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/pop_front_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/dmc/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/gcc/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/advance_backward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/and.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/apply.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/arg.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/basic_bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/bind.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/bitand.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/bitor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/bitxor.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/deque.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/divides.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/full_lambda.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/greater.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/inherit.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/less.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/less_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/list.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/list_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/map.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/minus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/modulus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/or.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/placeholders.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/plus.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/quote.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/set.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/set_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/shift_left.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/shift_right.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/times.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/vector.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessed/plain/vector_c.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/add.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/def_params_tail.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/default_params.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/enum.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/ext_params.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/filter_params.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/is_seq.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/params.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/partial_spec_params.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/range.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/repeat.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/sub.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/token_equal.hpp create mode 100644 thirdparty/boost/mpl/aux_/preprocessor/tuple.hpp create mode 100644 thirdparty/boost/mpl/aux_/ptr_to_ref.hpp create mode 100644 thirdparty/boost/mpl/aux_/push_back_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/push_front_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/O1_size.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/back.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/empty.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/front.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/iterator.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/size.hpp create mode 100644 thirdparty/boost/mpl/aux_/range_c/tag.hpp create mode 100644 thirdparty/boost/mpl/aux_/reverse_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/reverse_fold_impl_body.hpp create mode 100644 thirdparty/boost/mpl/aux_/reverse_iter_fold_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/sequence_wrapper.hpp create mode 100644 thirdparty/boost/mpl/aux_/shift_op.hpp create mode 100644 thirdparty/boost/mpl/aux_/single_element_iter.hpp create mode 100644 thirdparty/boost/mpl/aux_/size_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/sort_impl.hpp create mode 100644 thirdparty/boost/mpl/aux_/static_cast.hpp create mode 100644 thirdparty/boost/mpl/aux_/template_arity.hpp create mode 100644 thirdparty/boost/mpl/aux_/template_arity_fwd.hpp create mode 100644 thirdparty/boost/mpl/aux_/test.hpp create mode 100644 thirdparty/boost/mpl/aux_/test/assert.hpp create mode 100644 thirdparty/boost/mpl/aux_/test/data.hpp create mode 100644 thirdparty/boost/mpl/aux_/test/test_case.hpp create mode 100644 thirdparty/boost/mpl/aux_/traits_lambda_spec.hpp create mode 100644 thirdparty/boost/mpl/aux_/transform_iter.hpp create mode 100644 thirdparty/boost/mpl/aux_/type_wrapper.hpp create mode 100644 thirdparty/boost/mpl/aux_/unwrap.hpp create mode 100644 thirdparty/boost/mpl/aux_/value_wknd.hpp create mode 100644 thirdparty/boost/mpl/aux_/yes_no.hpp create mode 100644 thirdparty/boost/mpl/back.hpp create mode 100644 thirdparty/boost/mpl/back_fwd.hpp create mode 100644 thirdparty/boost/mpl/back_inserter.hpp create mode 100644 thirdparty/boost/mpl/base.hpp create mode 100644 thirdparty/boost/mpl/begin.hpp create mode 100644 thirdparty/boost/mpl/begin_end.hpp create mode 100644 thirdparty/boost/mpl/begin_end_fwd.hpp create mode 100644 thirdparty/boost/mpl/bind.hpp create mode 100644 thirdparty/boost/mpl/bind_fwd.hpp create mode 100644 thirdparty/boost/mpl/bitand.hpp create mode 100644 thirdparty/boost/mpl/bitor.hpp create mode 100644 thirdparty/boost/mpl/bitwise.hpp create mode 100644 thirdparty/boost/mpl/bitxor.hpp create mode 100644 thirdparty/boost/mpl/bool.hpp create mode 100644 thirdparty/boost/mpl/bool_fwd.hpp create mode 100644 thirdparty/boost/mpl/clear.hpp create mode 100644 thirdparty/boost/mpl/clear_fwd.hpp create mode 100644 thirdparty/boost/mpl/comparison.hpp create mode 100644 thirdparty/boost/mpl/contains.hpp create mode 100644 thirdparty/boost/mpl/contains_fwd.hpp create mode 100644 thirdparty/boost/mpl/copy.hpp create mode 100644 thirdparty/boost/mpl/copy_if.hpp create mode 100644 thirdparty/boost/mpl/count.hpp create mode 100644 thirdparty/boost/mpl/count_fwd.hpp create mode 100644 thirdparty/boost/mpl/count_if.hpp create mode 100644 thirdparty/boost/mpl/deque.hpp create mode 100644 thirdparty/boost/mpl/deref.hpp create mode 100644 thirdparty/boost/mpl/distance.hpp create mode 100644 thirdparty/boost/mpl/distance_fwd.hpp create mode 100644 thirdparty/boost/mpl/divides.hpp create mode 100644 thirdparty/boost/mpl/empty.hpp create mode 100644 thirdparty/boost/mpl/empty_base.hpp create mode 100644 thirdparty/boost/mpl/empty_fwd.hpp create mode 100644 thirdparty/boost/mpl/empty_sequence.hpp create mode 100644 thirdparty/boost/mpl/end.hpp create mode 100644 thirdparty/boost/mpl/equal.hpp create mode 100644 thirdparty/boost/mpl/equal_to.hpp create mode 100644 thirdparty/boost/mpl/erase.hpp create mode 100644 thirdparty/boost/mpl/erase_fwd.hpp create mode 100644 thirdparty/boost/mpl/erase_key.hpp create mode 100644 thirdparty/boost/mpl/erase_key_fwd.hpp create mode 100644 thirdparty/boost/mpl/eval_if.hpp create mode 100644 thirdparty/boost/mpl/filter_view.hpp create mode 100644 thirdparty/boost/mpl/find.hpp create mode 100644 thirdparty/boost/mpl/find_if.hpp create mode 100644 thirdparty/boost/mpl/fold.hpp create mode 100644 thirdparty/boost/mpl/for_each.hpp create mode 100644 thirdparty/boost/mpl/front.hpp create mode 100644 thirdparty/boost/mpl/front_fwd.hpp create mode 100644 thirdparty/boost/mpl/front_inserter.hpp create mode 100644 thirdparty/boost/mpl/greater.hpp create mode 100644 thirdparty/boost/mpl/greater_equal.hpp create mode 100644 thirdparty/boost/mpl/has_key.hpp create mode 100644 thirdparty/boost/mpl/has_key_fwd.hpp create mode 100644 thirdparty/boost/mpl/has_xxx.hpp create mode 100644 thirdparty/boost/mpl/identity.hpp create mode 100644 thirdparty/boost/mpl/if.hpp create mode 100644 thirdparty/boost/mpl/index_if.hpp create mode 100644 thirdparty/boost/mpl/index_of.hpp create mode 100644 thirdparty/boost/mpl/inherit.hpp create mode 100644 thirdparty/boost/mpl/inherit_linearly.hpp create mode 100644 thirdparty/boost/mpl/insert.hpp create mode 100644 thirdparty/boost/mpl/insert_fwd.hpp create mode 100644 thirdparty/boost/mpl/insert_range.hpp create mode 100644 thirdparty/boost/mpl/insert_range_fwd.hpp create mode 100644 thirdparty/boost/mpl/inserter.hpp create mode 100644 thirdparty/boost/mpl/int.hpp create mode 100644 thirdparty/boost/mpl/int_fwd.hpp create mode 100644 thirdparty/boost/mpl/integral_c.hpp create mode 100644 thirdparty/boost/mpl/integral_c_fwd.hpp create mode 100644 thirdparty/boost/mpl/integral_c_tag.hpp create mode 100644 thirdparty/boost/mpl/is_placeholder.hpp create mode 100644 thirdparty/boost/mpl/is_sequence.hpp create mode 100644 thirdparty/boost/mpl/iter_fold.hpp create mode 100644 thirdparty/boost/mpl/iter_fold_if.hpp create mode 100644 thirdparty/boost/mpl/iterator_category.hpp create mode 100644 thirdparty/boost/mpl/iterator_range.hpp create mode 100644 thirdparty/boost/mpl/iterator_tags.hpp create mode 100644 thirdparty/boost/mpl/joint_view.hpp create mode 100644 thirdparty/boost/mpl/key_type.hpp create mode 100644 thirdparty/boost/mpl/key_type_fwd.hpp create mode 100644 thirdparty/boost/mpl/lambda.hpp create mode 100644 thirdparty/boost/mpl/lambda_fwd.hpp create mode 100644 thirdparty/boost/mpl/less.hpp create mode 100644 thirdparty/boost/mpl/less_equal.hpp create mode 100644 thirdparty/boost/mpl/limits/arity.hpp create mode 100644 thirdparty/boost/mpl/limits/list.hpp create mode 100644 thirdparty/boost/mpl/limits/map.hpp create mode 100644 thirdparty/boost/mpl/limits/set.hpp create mode 100644 thirdparty/boost/mpl/limits/unrolling.hpp create mode 100644 thirdparty/boost/mpl/limits/vector.hpp create mode 100644 thirdparty/boost/mpl/list.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/O1_size.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/begin_end.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/clear.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/empty.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/front.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/include_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/item.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/iterator.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/numbered.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/numbered_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/pop_front.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list10.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list20.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list30.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list40.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list50.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/push_back.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/push_front.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/size.hpp create mode 100644 thirdparty/boost/mpl/list/aux_/tag.hpp create mode 100644 thirdparty/boost/mpl/list/list0.hpp create mode 100644 thirdparty/boost/mpl/list/list0_c.hpp create mode 100644 thirdparty/boost/mpl/list/list10.hpp create mode 100644 thirdparty/boost/mpl/list/list10_c.hpp create mode 100644 thirdparty/boost/mpl/list/list20.hpp create mode 100644 thirdparty/boost/mpl/list/list20_c.hpp create mode 100644 thirdparty/boost/mpl/list/list30.hpp create mode 100644 thirdparty/boost/mpl/list/list30_c.hpp create mode 100644 thirdparty/boost/mpl/list/list40.hpp create mode 100644 thirdparty/boost/mpl/list/list40_c.hpp create mode 100644 thirdparty/boost/mpl/list/list50.hpp create mode 100644 thirdparty/boost/mpl/list/list50_c.hpp create mode 100644 thirdparty/boost/mpl/list_c.hpp create mode 100644 thirdparty/boost/mpl/logical.hpp create mode 100644 thirdparty/boost/mpl/long.hpp create mode 100644 thirdparty/boost/mpl/long_fwd.hpp create mode 100644 thirdparty/boost/mpl/lower_bound.hpp create mode 100644 thirdparty/boost/mpl/map.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/at_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/begin_end_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/clear_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/contains_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/empty_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/erase_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/erase_key_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/has_key_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/include_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/insert_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/item.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/iterator.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/key_type_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/map0.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/numbered.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/no_ctps/map10.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/no_ctps/map20.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/no_ctps/map30.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/no_ctps/map40.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/no_ctps/map50.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/plain/map10.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/plain/map20.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/plain/map30.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/plain/map40.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/plain/map50.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/typeof_based/map10.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/typeof_based/map20.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/typeof_based/map30.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/typeof_based/map40.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/preprocessed/typeof_based/map50.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/size_impl.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/tag.hpp create mode 100644 thirdparty/boost/mpl/map/aux_/value_type_impl.hpp create mode 100644 thirdparty/boost/mpl/map/map0.hpp create mode 100644 thirdparty/boost/mpl/map/map10.hpp create mode 100644 thirdparty/boost/mpl/map/map20.hpp create mode 100644 thirdparty/boost/mpl/map/map30.hpp create mode 100644 thirdparty/boost/mpl/map/map40.hpp create mode 100644 thirdparty/boost/mpl/map/map50.hpp create mode 100644 thirdparty/boost/mpl/math/fixed_c.hpp create mode 100644 thirdparty/boost/mpl/math/is_even.hpp create mode 100644 thirdparty/boost/mpl/math/rational_c.hpp create mode 100644 thirdparty/boost/mpl/max.hpp create mode 100644 thirdparty/boost/mpl/max_element.hpp create mode 100644 thirdparty/boost/mpl/min.hpp create mode 100644 thirdparty/boost/mpl/min_element.hpp create mode 100644 thirdparty/boost/mpl/min_max.hpp create mode 100644 thirdparty/boost/mpl/minus.hpp create mode 100644 thirdparty/boost/mpl/modulus.hpp create mode 100644 thirdparty/boost/mpl/multiplies.hpp create mode 100644 thirdparty/boost/mpl/multiset/aux_/count_impl.hpp create mode 100644 thirdparty/boost/mpl/multiset/aux_/insert_impl.hpp create mode 100644 thirdparty/boost/mpl/multiset/aux_/item.hpp create mode 100644 thirdparty/boost/mpl/multiset/aux_/multiset0.hpp create mode 100644 thirdparty/boost/mpl/multiset/aux_/tag.hpp create mode 100644 thirdparty/boost/mpl/multiset/multiset0.hpp create mode 100644 thirdparty/boost/mpl/negate.hpp create mode 100644 thirdparty/boost/mpl/next.hpp create mode 100644 thirdparty/boost/mpl/next_prior.hpp create mode 100644 thirdparty/boost/mpl/not.hpp create mode 100644 thirdparty/boost/mpl/not_equal_to.hpp create mode 100644 thirdparty/boost/mpl/numeric_cast.hpp create mode 100644 thirdparty/boost/mpl/or.hpp create mode 100644 thirdparty/boost/mpl/order.hpp create mode 100644 thirdparty/boost/mpl/order_fwd.hpp create mode 100644 thirdparty/boost/mpl/pair.hpp create mode 100644 thirdparty/boost/mpl/pair_view.hpp create mode 100644 thirdparty/boost/mpl/partition.hpp create mode 100644 thirdparty/boost/mpl/placeholders.hpp create mode 100644 thirdparty/boost/mpl/plus.hpp create mode 100644 thirdparty/boost/mpl/pop_back.hpp create mode 100644 thirdparty/boost/mpl/pop_back_fwd.hpp create mode 100644 thirdparty/boost/mpl/pop_front.hpp create mode 100644 thirdparty/boost/mpl/pop_front_fwd.hpp create mode 100644 thirdparty/boost/mpl/print.hpp create mode 100644 thirdparty/boost/mpl/prior.hpp create mode 100644 thirdparty/boost/mpl/protect.hpp create mode 100644 thirdparty/boost/mpl/push_back.hpp create mode 100644 thirdparty/boost/mpl/push_back_fwd.hpp create mode 100644 thirdparty/boost/mpl/push_front.hpp create mode 100644 thirdparty/boost/mpl/push_front_fwd.hpp create mode 100644 thirdparty/boost/mpl/quote.hpp create mode 100644 thirdparty/boost/mpl/range_c.hpp create mode 100644 thirdparty/boost/mpl/remove.hpp create mode 100644 thirdparty/boost/mpl/remove_if.hpp create mode 100644 thirdparty/boost/mpl/replace.hpp create mode 100644 thirdparty/boost/mpl/replace_if.hpp create mode 100644 thirdparty/boost/mpl/reverse.hpp create mode 100644 thirdparty/boost/mpl/reverse_fold.hpp create mode 100644 thirdparty/boost/mpl/reverse_iter_fold.hpp create mode 100644 thirdparty/boost/mpl/same_as.hpp create mode 100644 thirdparty/boost/mpl/sequence_tag.hpp create mode 100644 thirdparty/boost/mpl/sequence_tag_fwd.hpp create mode 100644 thirdparty/boost/mpl/set.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/at_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/begin_end_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/clear_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/empty_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/erase_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/erase_key_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/has_key_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/include_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/insert_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/item.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/iterator.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/key_type_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/numbered.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/numbered_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set10.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set10_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set20.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set20_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set30.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set30_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set40.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set40_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set50.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/preprocessed/plain/set50_c.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/set0.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/size_impl.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/tag.hpp create mode 100644 thirdparty/boost/mpl/set/aux_/value_type_impl.hpp create mode 100644 thirdparty/boost/mpl/set/set0.hpp create mode 100644 thirdparty/boost/mpl/set/set0_c.hpp create mode 100644 thirdparty/boost/mpl/set/set10.hpp create mode 100644 thirdparty/boost/mpl/set/set10_c.hpp create mode 100644 thirdparty/boost/mpl/set/set20.hpp create mode 100644 thirdparty/boost/mpl/set/set20_c.hpp create mode 100644 thirdparty/boost/mpl/set/set30.hpp create mode 100644 thirdparty/boost/mpl/set/set30_c.hpp create mode 100644 thirdparty/boost/mpl/set/set40.hpp create mode 100644 thirdparty/boost/mpl/set/set40_c.hpp create mode 100644 thirdparty/boost/mpl/set/set50.hpp create mode 100644 thirdparty/boost/mpl/set/set50_c.hpp create mode 100644 thirdparty/boost/mpl/set_c.hpp create mode 100644 thirdparty/boost/mpl/shift_left.hpp create mode 100644 thirdparty/boost/mpl/shift_right.hpp create mode 100644 thirdparty/boost/mpl/single_view.hpp create mode 100644 thirdparty/boost/mpl/size.hpp create mode 100644 thirdparty/boost/mpl/size_fwd.hpp create mode 100644 thirdparty/boost/mpl/size_t.hpp create mode 100644 thirdparty/boost/mpl/size_t_fwd.hpp create mode 100644 thirdparty/boost/mpl/sizeof.hpp create mode 100644 thirdparty/boost/mpl/sort.hpp create mode 100644 thirdparty/boost/mpl/stable_partition.hpp create mode 100644 thirdparty/boost/mpl/switch.hpp create mode 100644 thirdparty/boost/mpl/tag.hpp create mode 100644 thirdparty/boost/mpl/times.hpp create mode 100644 thirdparty/boost/mpl/transform.hpp create mode 100644 thirdparty/boost/mpl/transform_view.hpp create mode 100644 thirdparty/boost/mpl/unique.hpp create mode 100644 thirdparty/boost/mpl/unpack_args.hpp create mode 100644 thirdparty/boost/mpl/upper_bound.hpp create mode 100644 thirdparty/boost/mpl/value_type.hpp create mode 100644 thirdparty/boost/mpl/value_type_fwd.hpp create mode 100644 thirdparty/boost/mpl/vector.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/O1_size.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/at.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/back.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/begin_end.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/clear.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/empty.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/front.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/include_preprocessed.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/item.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/iterator.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/numbered.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/numbered_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/pop_back.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/pop_front.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector10_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector20_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector30.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector30_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector40.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector40_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector50.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/plain/vector50_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50_c.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/push_back.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/push_front.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/size.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/tag.hpp create mode 100644 thirdparty/boost/mpl/vector/aux_/vector0.hpp create mode 100644 thirdparty/boost/mpl/vector/vector0.hpp create mode 100644 thirdparty/boost/mpl/vector/vector0_c.hpp create mode 100644 thirdparty/boost/mpl/vector/vector10.hpp create mode 100644 thirdparty/boost/mpl/vector/vector10_c.hpp create mode 100644 thirdparty/boost/mpl/vector/vector20.hpp create mode 100644 thirdparty/boost/mpl/vector/vector20_c.hpp create mode 100644 thirdparty/boost/mpl/vector/vector30.hpp create mode 100644 thirdparty/boost/mpl/vector/vector30_c.hpp create mode 100644 thirdparty/boost/mpl/vector/vector40.hpp create mode 100644 thirdparty/boost/mpl/vector/vector40_c.hpp create mode 100644 thirdparty/boost/mpl/vector/vector50.hpp create mode 100644 thirdparty/boost/mpl/vector/vector50_c.hpp create mode 100644 thirdparty/boost/mpl/vector_c.hpp create mode 100644 thirdparty/boost/mpl/void.hpp create mode 100644 thirdparty/boost/mpl/void_fwd.hpp create mode 100644 thirdparty/boost/mpl/zip_view.hpp create mode 100644 thirdparty/boost/multi_array.hpp create mode 100644 thirdparty/boost/multi_array/algorithm.hpp create mode 100644 thirdparty/boost/multi_array/base.hpp create mode 100644 thirdparty/boost/multi_array/collection_concept.hpp create mode 100644 thirdparty/boost/multi_array/concept_checks.hpp create mode 100644 thirdparty/boost/multi_array/copy_array.hpp create mode 100644 thirdparty/boost/multi_array/extent_gen.hpp create mode 100644 thirdparty/boost/multi_array/extent_range.hpp create mode 100644 thirdparty/boost/multi_array/index_gen.hpp create mode 100644 thirdparty/boost/multi_array/index_range.hpp create mode 100644 thirdparty/boost/multi_array/iterator.hpp create mode 100644 thirdparty/boost/multi_array/multi_array_ref.hpp create mode 100644 thirdparty/boost/multi_array/range_list.hpp create mode 100644 thirdparty/boost/multi_array/storage_order.hpp create mode 100644 thirdparty/boost/multi_array/subarray.hpp create mode 100644 thirdparty/boost/multi_array/types.hpp create mode 100644 thirdparty/boost/multi_array/view.hpp create mode 100644 thirdparty/boost/multi_index/composite_key.hpp create mode 100644 thirdparty/boost/multi_index/detail/access_specifier.hpp create mode 100644 thirdparty/boost/multi_index/detail/adl_swap.hpp create mode 100644 thirdparty/boost/multi_index/detail/archive_constructed.hpp create mode 100644 thirdparty/boost/multi_index/detail/auto_space.hpp create mode 100644 thirdparty/boost/multi_index/detail/base_type.hpp create mode 100644 thirdparty/boost/multi_index/detail/bidir_node_iterator.hpp create mode 100644 thirdparty/boost/multi_index/detail/bucket_array.hpp create mode 100644 thirdparty/boost/multi_index/detail/converter.hpp create mode 100644 thirdparty/boost/multi_index/detail/copy_map.hpp create mode 100644 thirdparty/boost/multi_index/detail/duplicates_iterator.hpp create mode 100644 thirdparty/boost/multi_index/detail/has_tag.hpp create mode 100644 thirdparty/boost/multi_index/detail/hash_index_args.hpp create mode 100644 thirdparty/boost/multi_index/detail/hash_index_iterator.hpp create mode 100644 thirdparty/boost/multi_index/detail/hash_index_node.hpp create mode 100644 thirdparty/boost/multi_index/detail/header_holder.hpp create mode 100644 thirdparty/boost/multi_index/detail/index_base.hpp create mode 100644 thirdparty/boost/multi_index/detail/index_loader.hpp create mode 100644 thirdparty/boost/multi_index/detail/index_matcher.hpp create mode 100644 thirdparty/boost/multi_index/detail/index_node_base.hpp create mode 100644 thirdparty/boost/multi_index/detail/index_saver.hpp create mode 100644 thirdparty/boost/multi_index/detail/invariant_assert.hpp create mode 100644 thirdparty/boost/multi_index/detail/is_index_list.hpp create mode 100644 thirdparty/boost/multi_index/detail/iter_adaptor.hpp create mode 100644 thirdparty/boost/multi_index/detail/modify_key_adaptor.hpp create mode 100644 thirdparty/boost/multi_index/detail/msvc_index_specifier.hpp create mode 100644 thirdparty/boost/multi_index/detail/no_duplicate_tags.hpp create mode 100644 thirdparty/boost/multi_index/detail/node_type.hpp create mode 100644 thirdparty/boost/multi_index/detail/ord_index_args.hpp create mode 100644 thirdparty/boost/multi_index/detail/ord_index_node.hpp create mode 100644 thirdparty/boost/multi_index/detail/ord_index_ops.hpp create mode 100644 thirdparty/boost/multi_index/detail/prevent_eti.hpp create mode 100644 thirdparty/boost/multi_index/detail/rnd_index_loader.hpp create mode 100644 thirdparty/boost/multi_index/detail/rnd_index_node.hpp create mode 100644 thirdparty/boost/multi_index/detail/rnd_index_ops.hpp create mode 100644 thirdparty/boost/multi_index/detail/rnd_index_ptr_array.hpp create mode 100644 thirdparty/boost/multi_index/detail/rnd_node_iterator.hpp create mode 100644 thirdparty/boost/multi_index/detail/safe_ctr_proxy.hpp create mode 100644 thirdparty/boost/multi_index/detail/safe_mode.hpp create mode 100644 thirdparty/boost/multi_index/detail/scope_guard.hpp create mode 100644 thirdparty/boost/multi_index/detail/seq_index_node.hpp create mode 100644 thirdparty/boost/multi_index/detail/seq_index_ops.hpp create mode 100644 thirdparty/boost/multi_index/detail/uintptr_type.hpp create mode 100644 thirdparty/boost/multi_index/detail/unbounded.hpp create mode 100644 thirdparty/boost/multi_index/detail/value_compare.hpp create mode 100644 thirdparty/boost/multi_index/global_fun.hpp create mode 100644 thirdparty/boost/multi_index/hashed_index.hpp create mode 100644 thirdparty/boost/multi_index/hashed_index_fwd.hpp create mode 100644 thirdparty/boost/multi_index/identity.hpp create mode 100644 thirdparty/boost/multi_index/identity_fwd.hpp create mode 100644 thirdparty/boost/multi_index/indexed_by.hpp create mode 100644 thirdparty/boost/multi_index/key_extractors.hpp create mode 100644 thirdparty/boost/multi_index/mem_fun.hpp create mode 100644 thirdparty/boost/multi_index/member.hpp create mode 100644 thirdparty/boost/multi_index/ordered_index.hpp create mode 100644 thirdparty/boost/multi_index/ordered_index_fwd.hpp create mode 100644 thirdparty/boost/multi_index/random_access_index.hpp create mode 100644 thirdparty/boost/multi_index/random_access_index_fwd.hpp create mode 100644 thirdparty/boost/multi_index/safe_mode_errors.hpp create mode 100644 thirdparty/boost/multi_index/sequenced_index.hpp create mode 100644 thirdparty/boost/multi_index/sequenced_index_fwd.hpp create mode 100644 thirdparty/boost/multi_index/tag.hpp create mode 100644 thirdparty/boost/multi_index_container.hpp create mode 100644 thirdparty/boost/multi_index_container_fwd.hpp create mode 100644 thirdparty/boost/next_prior.hpp create mode 100644 thirdparty/boost/non_type.hpp create mode 100644 thirdparty/boost/noncopyable.hpp create mode 100644 thirdparty/boost/nondet_random.hpp create mode 100644 thirdparty/boost/none.hpp create mode 100644 thirdparty/boost/none_t.hpp create mode 100644 thirdparty/boost/numeric/conversion/bounds.hpp create mode 100644 thirdparty/boost/numeric/conversion/cast.hpp create mode 100644 thirdparty/boost/numeric/conversion/conversion_traits.hpp create mode 100644 thirdparty/boost/numeric/conversion/converter.hpp create mode 100644 thirdparty/boost/numeric/conversion/converter_policies.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/bounds.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/conversion_traits.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/converter.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/int_float_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/is_subranged.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/meta.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/old_numeric_cast.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/sign_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/detail/udt_builtin_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/int_float_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/int_float_mixture_enum.hpp create mode 100644 thirdparty/boost/numeric/conversion/is_subranged.hpp create mode 100644 thirdparty/boost/numeric/conversion/sign_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/sign_mixture_enum.hpp create mode 100644 thirdparty/boost/numeric/conversion/udt_builtin_mixture.hpp create mode 100644 thirdparty/boost/numeric/conversion/udt_builtin_mixture_enum.hpp create mode 100644 thirdparty/boost/numeric/interval.hpp create mode 100644 thirdparty/boost/numeric/interval/arith.hpp create mode 100644 thirdparty/boost/numeric/interval/arith2.hpp create mode 100644 thirdparty/boost/numeric/interval/arith3.hpp create mode 100644 thirdparty/boost/numeric/interval/checking.hpp create mode 100644 thirdparty/boost/numeric/interval/compare.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/certain.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/explicit.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/lexicographic.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/possible.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/set.hpp create mode 100644 thirdparty/boost/numeric/interval/compare/tribool.hpp create mode 100644 thirdparty/boost/numeric/interval/constants.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/alpha_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/bcc_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/bugs.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/c99_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/c99sub_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/division.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/ia64_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/interval_prototype.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/msvc_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/ppc_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/sparc_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/test_input.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/x86_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/detail/x86gcc_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/ext/integer.hpp create mode 100644 thirdparty/boost/numeric/interval/ext/x86_fast_rounding_control.hpp create mode 100644 thirdparty/boost/numeric/interval/hw_rounding.hpp create mode 100644 thirdparty/boost/numeric/interval/interval.hpp create mode 100644 thirdparty/boost/numeric/interval/io.hpp create mode 100644 thirdparty/boost/numeric/interval/limits.hpp create mode 100644 thirdparty/boost/numeric/interval/policies.hpp create mode 100644 thirdparty/boost/numeric/interval/rounded_arith.hpp create mode 100644 thirdparty/boost/numeric/interval/rounded_transc.hpp create mode 100644 thirdparty/boost/numeric/interval/rounding.hpp create mode 100644 thirdparty/boost/numeric/interval/transc.hpp create mode 100644 thirdparty/boost/numeric/interval/utility.hpp create mode 100644 thirdparty/boost/numeric/ublas/banded.hpp create mode 100644 thirdparty/boost/numeric/ublas/blas.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/concepts.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/config.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/definitions.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/documentation.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/duff.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/iterator.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/matrix_assign.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/raw.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/returntype_deduction.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/temporary.hpp create mode 100644 thirdparty/boost/numeric/ublas/detail/vector_assign.hpp create mode 100644 thirdparty/boost/numeric/ublas/exception.hpp create mode 100644 thirdparty/boost/numeric/ublas/expression_types.hpp create mode 100644 thirdparty/boost/numeric/ublas/functional.hpp create mode 100644 thirdparty/boost/numeric/ublas/fwd.hpp create mode 100644 thirdparty/boost/numeric/ublas/hermitian.hpp create mode 100644 thirdparty/boost/numeric/ublas/io.hpp create mode 100644 thirdparty/boost/numeric/ublas/lu.hpp create mode 100644 thirdparty/boost/numeric/ublas/matrix.hpp create mode 100644 thirdparty/boost/numeric/ublas/matrix_expression.hpp create mode 100644 thirdparty/boost/numeric/ublas/matrix_proxy.hpp create mode 100644 thirdparty/boost/numeric/ublas/matrix_sparse.hpp create mode 100644 thirdparty/boost/numeric/ublas/operation.hpp create mode 100644 thirdparty/boost/numeric/ublas/operation_blocked.hpp create mode 100644 thirdparty/boost/numeric/ublas/operation_sparse.hpp create mode 100644 thirdparty/boost/numeric/ublas/storage.hpp create mode 100644 thirdparty/boost/numeric/ublas/storage_sparse.hpp create mode 100644 thirdparty/boost/numeric/ublas/symmetric.hpp create mode 100644 thirdparty/boost/numeric/ublas/traits.hpp create mode 100644 thirdparty/boost/numeric/ublas/triangular.hpp create mode 100644 thirdparty/boost/numeric/ublas/vector.hpp create mode 100644 thirdparty/boost/numeric/ublas/vector_expression.hpp create mode 100644 thirdparty/boost/numeric/ublas/vector_of_vector.hpp create mode 100644 thirdparty/boost/numeric/ublas/vector_proxy.hpp create mode 100644 thirdparty/boost/numeric/ublas/vector_sparse.hpp create mode 100644 thirdparty/boost/operators.hpp create mode 100644 thirdparty/boost/optional.hpp create mode 100644 thirdparty/boost/optional/optional.hpp create mode 100644 thirdparty/boost/optional/optional_fwd.hpp create mode 100644 thirdparty/boost/optional/optional_io.hpp create mode 100644 thirdparty/boost/parameter.hpp create mode 100644 thirdparty/boost/parameter/aux_/arg_list.hpp create mode 100644 thirdparty/boost/parameter/aux_/cast.hpp create mode 100644 thirdparty/boost/parameter/aux_/default.hpp create mode 100644 thirdparty/boost/parameter/aux_/maybe.hpp create mode 100644 thirdparty/boost/parameter/aux_/overloads.hpp create mode 100644 thirdparty/boost/parameter/aux_/parameter_requirements.hpp create mode 100644 thirdparty/boost/parameter/aux_/parenthesized_type.hpp create mode 100644 thirdparty/boost/parameter/aux_/preprocessor/flatten.hpp create mode 100644 thirdparty/boost/parameter/aux_/preprocessor/for_each.hpp create mode 100644 thirdparty/boost/parameter/aux_/python/invoker.hpp create mode 100644 thirdparty/boost/parameter/aux_/python/invoker_iterate.hpp create mode 100644 thirdparty/boost/parameter/aux_/result_of0.hpp create mode 100644 thirdparty/boost/parameter/aux_/set.hpp create mode 100644 thirdparty/boost/parameter/aux_/tag.hpp create mode 100644 thirdparty/boost/parameter/aux_/tagged_argument.hpp create mode 100644 thirdparty/boost/parameter/aux_/template_keyword.hpp create mode 100644 thirdparty/boost/parameter/aux_/unwrap_cv_reference.hpp create mode 100644 thirdparty/boost/parameter/aux_/void.hpp create mode 100644 thirdparty/boost/parameter/aux_/yesno.hpp create mode 100644 thirdparty/boost/parameter/binding.hpp create mode 100644 thirdparty/boost/parameter/config.hpp create mode 100644 thirdparty/boost/parameter/keyword.hpp create mode 100644 thirdparty/boost/parameter/macros.hpp create mode 100644 thirdparty/boost/parameter/match.hpp create mode 100644 thirdparty/boost/parameter/name.hpp create mode 100644 thirdparty/boost/parameter/parameters.hpp create mode 100644 thirdparty/boost/parameter/preprocessor.hpp create mode 100644 thirdparty/boost/parameter/python.hpp create mode 100644 thirdparty/boost/parameter/value_type.hpp create mode 100644 thirdparty/boost/pending/bucket_sorter.hpp create mode 100644 thirdparty/boost/pending/container_traits.hpp create mode 100644 thirdparty/boost/pending/cstddef.hpp create mode 100644 thirdparty/boost/pending/ct_if.hpp create mode 100644 thirdparty/boost/pending/detail/disjoint_sets.hpp create mode 100644 thirdparty/boost/pending/detail/int_iterator.hpp create mode 100644 thirdparty/boost/pending/detail/property.hpp create mode 100644 thirdparty/boost/pending/disjoint_sets.hpp create mode 100644 thirdparty/boost/pending/fenced_priority_queue.hpp create mode 100644 thirdparty/boost/pending/fibonacci_heap.hpp create mode 100644 thirdparty/boost/pending/indirect_cmp.hpp create mode 100644 thirdparty/boost/pending/integer_log2.hpp create mode 100644 thirdparty/boost/pending/integer_range.hpp create mode 100644 thirdparty/boost/pending/is_heap.hpp create mode 100644 thirdparty/boost/pending/iterator_adaptors.hpp create mode 100644 thirdparty/boost/pending/iterator_tests.hpp create mode 100644 thirdparty/boost/pending/lowest_bit.hpp create mode 100644 thirdparty/boost/pending/mutable_heap.hpp create mode 100644 thirdparty/boost/pending/mutable_queue.hpp create mode 100644 thirdparty/boost/pending/property.hpp create mode 100644 thirdparty/boost/pending/property_serialize.hpp create mode 100644 thirdparty/boost/pending/queue.hpp create mode 100644 thirdparty/boost/pending/relaxed_heap.hpp create mode 100644 thirdparty/boost/pending/stringtok.hpp create mode 100644 thirdparty/boost/pfto.hpp create mode 100644 thirdparty/boost/pointee.hpp create mode 100644 thirdparty/boost/pointer_cast.hpp create mode 100644 thirdparty/boost/pointer_to_other.hpp create mode 100644 thirdparty/boost/pool/detail/ct_gcd_lcm.hpp create mode 100644 thirdparty/boost/pool/detail/for.m4 create mode 100644 thirdparty/boost/pool/detail/gcd_lcm.hpp create mode 100644 thirdparty/boost/pool/detail/guard.hpp create mode 100644 thirdparty/boost/pool/detail/mutex.hpp create mode 100644 thirdparty/boost/pool/detail/pool_construct.bat create mode 100644 thirdparty/boost/pool/detail/pool_construct.inc create mode 100644 thirdparty/boost/pool/detail/pool_construct.m4 create mode 100644 thirdparty/boost/pool/detail/pool_construct.sh create mode 100644 thirdparty/boost/pool/detail/pool_construct_simple.bat create mode 100644 thirdparty/boost/pool/detail/pool_construct_simple.inc create mode 100644 thirdparty/boost/pool/detail/pool_construct_simple.m4 create mode 100644 thirdparty/boost/pool/detail/pool_construct_simple.sh create mode 100644 thirdparty/boost/pool/detail/singleton.hpp create mode 100644 thirdparty/boost/pool/object_pool.hpp create mode 100644 thirdparty/boost/pool/pool.hpp create mode 100644 thirdparty/boost/pool/pool_alloc.hpp create mode 100644 thirdparty/boost/pool/poolfwd.hpp create mode 100644 thirdparty/boost/pool/simple_segregated_storage.hpp create mode 100644 thirdparty/boost/pool/singleton_pool.hpp create mode 100644 thirdparty/boost/preprocessor.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/add.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/dec.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/detail/div_base.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/div.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/inc.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/mod.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/mul.hpp create mode 100644 thirdparty/boost/preprocessor/arithmetic/sub.hpp create mode 100644 thirdparty/boost/preprocessor/array.hpp create mode 100644 thirdparty/boost/preprocessor/array/data.hpp create mode 100644 thirdparty/boost/preprocessor/array/elem.hpp create mode 100644 thirdparty/boost/preprocessor/array/insert.hpp create mode 100644 thirdparty/boost/preprocessor/array/pop_back.hpp create mode 100644 thirdparty/boost/preprocessor/array/pop_front.hpp create mode 100644 thirdparty/boost/preprocessor/array/push_back.hpp create mode 100644 thirdparty/boost/preprocessor/array/push_front.hpp create mode 100644 thirdparty/boost/preprocessor/array/remove.hpp create mode 100644 thirdparty/boost/preprocessor/array/replace.hpp create mode 100644 thirdparty/boost/preprocessor/array/reverse.hpp create mode 100644 thirdparty/boost/preprocessor/array/size.hpp create mode 100644 thirdparty/boost/preprocessor/assert_msg.hpp create mode 100644 thirdparty/boost/preprocessor/cat.hpp create mode 100644 thirdparty/boost/preprocessor/comma.hpp create mode 100644 thirdparty/boost/preprocessor/comma_if.hpp create mode 100644 thirdparty/boost/preprocessor/comparison.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/equal.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/greater.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/greater_equal.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/less.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/less_equal.hpp create mode 100644 thirdparty/boost/preprocessor/comparison/not_equal.hpp create mode 100644 thirdparty/boost/preprocessor/config/config.hpp create mode 100644 thirdparty/boost/preprocessor/config/limits.hpp create mode 100644 thirdparty/boost/preprocessor/control.hpp create mode 100644 thirdparty/boost/preprocessor/control/deduce_d.hpp create mode 100644 thirdparty/boost/preprocessor/control/detail/dmc/while.hpp create mode 100644 thirdparty/boost/preprocessor/control/detail/edg/while.hpp create mode 100644 thirdparty/boost/preprocessor/control/detail/msvc/while.hpp create mode 100644 thirdparty/boost/preprocessor/control/detail/while.hpp create mode 100644 thirdparty/boost/preprocessor/control/expr_if.hpp create mode 100644 thirdparty/boost/preprocessor/control/expr_iif.hpp create mode 100644 thirdparty/boost/preprocessor/control/if.hpp create mode 100644 thirdparty/boost/preprocessor/control/iif.hpp create mode 100644 thirdparty/boost/preprocessor/control/while.hpp create mode 100644 thirdparty/boost/preprocessor/debug.hpp create mode 100644 thirdparty/boost/preprocessor/debug/assert.hpp create mode 100644 thirdparty/boost/preprocessor/debug/error.hpp create mode 100644 thirdparty/boost/preprocessor/debug/line.hpp create mode 100644 thirdparty/boost/preprocessor/dec.hpp create mode 100644 thirdparty/boost/preprocessor/detail/auto_rec.hpp create mode 100644 thirdparty/boost/preprocessor/detail/check.hpp create mode 100644 thirdparty/boost/preprocessor/detail/dmc/auto_rec.hpp create mode 100644 thirdparty/boost/preprocessor/detail/is_binary.hpp create mode 100644 thirdparty/boost/preprocessor/detail/is_nullary.hpp create mode 100644 thirdparty/boost/preprocessor/detail/is_unary.hpp create mode 100644 thirdparty/boost/preprocessor/detail/null.hpp create mode 100644 thirdparty/boost/preprocessor/detail/split.hpp create mode 100644 thirdparty/boost/preprocessor/empty.hpp create mode 100644 thirdparty/boost/preprocessor/enum.hpp create mode 100644 thirdparty/boost/preprocessor/enum_params.hpp create mode 100644 thirdparty/boost/preprocessor/enum_params_with_a_default.hpp create mode 100644 thirdparty/boost/preprocessor/enum_params_with_defaults.hpp create mode 100644 thirdparty/boost/preprocessor/enum_shifted.hpp create mode 100644 thirdparty/boost/preprocessor/enum_shifted_params.hpp create mode 100644 thirdparty/boost/preprocessor/expand.hpp create mode 100644 thirdparty/boost/preprocessor/expr_if.hpp create mode 100644 thirdparty/boost/preprocessor/facilities.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/apply.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/empty.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/expand.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/identity.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/intercept.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/is_1.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/is_empty.hpp create mode 100644 thirdparty/boost/preprocessor/facilities/is_empty_or_1.hpp create mode 100644 thirdparty/boost/preprocessor/for.hpp create mode 100644 thirdparty/boost/preprocessor/identity.hpp create mode 100644 thirdparty/boost/preprocessor/if.hpp create mode 100644 thirdparty/boost/preprocessor/inc.hpp create mode 100644 thirdparty/boost/preprocessor/iterate.hpp create mode 100644 thirdparty/boost/preprocessor/iteration.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/lower1.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/lower2.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/lower3.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/lower4.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/lower5.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/upper1.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/upper2.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/upper3.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/upper4.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/bounds/upper5.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/finish.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/forward1.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/forward2.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/forward3.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/forward4.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/forward5.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/reverse1.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/reverse2.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/reverse3.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/reverse4.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/iter/reverse5.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/local.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/rlocal.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/self.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/detail/start.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/iterate.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/local.hpp create mode 100644 thirdparty/boost/preprocessor/iteration/self.hpp create mode 100644 thirdparty/boost/preprocessor/library.hpp create mode 100644 thirdparty/boost/preprocessor/limits.hpp create mode 100644 thirdparty/boost/preprocessor/list.hpp create mode 100644 thirdparty/boost/preprocessor/list/adt.hpp create mode 100644 thirdparty/boost/preprocessor/list/append.hpp create mode 100644 thirdparty/boost/preprocessor/list/at.hpp create mode 100644 thirdparty/boost/preprocessor/list/cat.hpp create mode 100644 thirdparty/boost/preprocessor/list/detail/dmc/fold_left.hpp create mode 100644 thirdparty/boost/preprocessor/list/detail/edg/fold_left.hpp create mode 100644 thirdparty/boost/preprocessor/list/detail/edg/fold_right.hpp create mode 100644 thirdparty/boost/preprocessor/list/detail/fold_left.hpp create mode 100644 thirdparty/boost/preprocessor/list/detail/fold_right.hpp create mode 100644 thirdparty/boost/preprocessor/list/enum.hpp create mode 100644 thirdparty/boost/preprocessor/list/filter.hpp create mode 100644 thirdparty/boost/preprocessor/list/first_n.hpp create mode 100644 thirdparty/boost/preprocessor/list/fold_left.hpp create mode 100644 thirdparty/boost/preprocessor/list/fold_right.hpp create mode 100644 thirdparty/boost/preprocessor/list/for_each.hpp create mode 100644 thirdparty/boost/preprocessor/list/for_each_i.hpp create mode 100644 thirdparty/boost/preprocessor/list/for_each_product.hpp create mode 100644 thirdparty/boost/preprocessor/list/rest_n.hpp create mode 100644 thirdparty/boost/preprocessor/list/reverse.hpp create mode 100644 thirdparty/boost/preprocessor/list/size.hpp create mode 100644 thirdparty/boost/preprocessor/list/to_tuple.hpp create mode 100644 thirdparty/boost/preprocessor/list/transform.hpp create mode 100644 thirdparty/boost/preprocessor/logical.hpp create mode 100644 thirdparty/boost/preprocessor/logical/and.hpp create mode 100644 thirdparty/boost/preprocessor/logical/bitand.hpp create mode 100644 thirdparty/boost/preprocessor/logical/bitnor.hpp create mode 100644 thirdparty/boost/preprocessor/logical/bitor.hpp create mode 100644 thirdparty/boost/preprocessor/logical/bitxor.hpp create mode 100644 thirdparty/boost/preprocessor/logical/bool.hpp create mode 100644 thirdparty/boost/preprocessor/logical/compl.hpp create mode 100644 thirdparty/boost/preprocessor/logical/nor.hpp create mode 100644 thirdparty/boost/preprocessor/logical/not.hpp create mode 100644 thirdparty/boost/preprocessor/logical/or.hpp create mode 100644 thirdparty/boost/preprocessor/logical/xor.hpp create mode 100644 thirdparty/boost/preprocessor/max.hpp create mode 100644 thirdparty/boost/preprocessor/min.hpp create mode 100644 thirdparty/boost/preprocessor/punctuation.hpp create mode 100644 thirdparty/boost/preprocessor/punctuation/comma.hpp create mode 100644 thirdparty/boost/preprocessor/punctuation/comma_if.hpp create mode 100644 thirdparty/boost/preprocessor/punctuation/paren.hpp create mode 100644 thirdparty/boost/preprocessor/punctuation/paren_if.hpp create mode 100644 thirdparty/boost/preprocessor/repeat.hpp create mode 100644 thirdparty/boost/preprocessor/repeat_2nd.hpp create mode 100644 thirdparty/boost/preprocessor/repeat_3rd.hpp create mode 100644 thirdparty/boost/preprocessor/repeat_from_to.hpp create mode 100644 thirdparty/boost/preprocessor/repeat_from_to_2nd.hpp create mode 100644 thirdparty/boost/preprocessor/repeat_from_to_3rd.hpp create mode 100644 thirdparty/boost/preprocessor/repetition.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/deduce_r.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/deduce_z.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/detail/dmc/for.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/detail/edg/for.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/detail/for.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/detail/msvc/for.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_binary_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_params_with_a_default.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_params_with_defaults.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_shifted.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_shifted_binary_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_shifted_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_trailing.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_trailing_binary_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/enum_trailing_params.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/for.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/repeat.hpp create mode 100644 thirdparty/boost/preprocessor/repetition/repeat_from_to.hpp create mode 100644 thirdparty/boost/preprocessor/selection.hpp create mode 100644 thirdparty/boost/preprocessor/selection/max.hpp create mode 100644 thirdparty/boost/preprocessor/selection/min.hpp create mode 100644 thirdparty/boost/preprocessor/seq.hpp create mode 100644 thirdparty/boost/preprocessor/seq/cat.hpp create mode 100644 thirdparty/boost/preprocessor/seq/detail/split.hpp create mode 100644 thirdparty/boost/preprocessor/seq/elem.hpp create mode 100644 thirdparty/boost/preprocessor/seq/enum.hpp create mode 100644 thirdparty/boost/preprocessor/seq/filter.hpp create mode 100644 thirdparty/boost/preprocessor/seq/first_n.hpp create mode 100644 thirdparty/boost/preprocessor/seq/fold_left.hpp create mode 100644 thirdparty/boost/preprocessor/seq/fold_right.hpp create mode 100644 thirdparty/boost/preprocessor/seq/for_each.hpp create mode 100644 thirdparty/boost/preprocessor/seq/for_each_i.hpp create mode 100644 thirdparty/boost/preprocessor/seq/for_each_product.hpp create mode 100644 thirdparty/boost/preprocessor/seq/insert.hpp create mode 100644 thirdparty/boost/preprocessor/seq/pop_back.hpp create mode 100644 thirdparty/boost/preprocessor/seq/pop_front.hpp create mode 100644 thirdparty/boost/preprocessor/seq/push_back.hpp create mode 100644 thirdparty/boost/preprocessor/seq/push_front.hpp create mode 100644 thirdparty/boost/preprocessor/seq/remove.hpp create mode 100644 thirdparty/boost/preprocessor/seq/replace.hpp create mode 100644 thirdparty/boost/preprocessor/seq/rest_n.hpp create mode 100644 thirdparty/boost/preprocessor/seq/reverse.hpp create mode 100644 thirdparty/boost/preprocessor/seq/seq.hpp create mode 100644 thirdparty/boost/preprocessor/seq/size.hpp create mode 100644 thirdparty/boost/preprocessor/seq/subseq.hpp create mode 100644 thirdparty/boost/preprocessor/seq/to_array.hpp create mode 100644 thirdparty/boost/preprocessor/seq/to_tuple.hpp create mode 100644 thirdparty/boost/preprocessor/seq/transform.hpp create mode 100644 thirdparty/boost/preprocessor/slot.hpp create mode 100644 thirdparty/boost/preprocessor/slot/counter.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/counter.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/def.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/shared.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/slot1.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/slot2.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/slot3.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/slot4.hpp create mode 100644 thirdparty/boost/preprocessor/slot/detail/slot5.hpp create mode 100644 thirdparty/boost/preprocessor/slot/slot.hpp create mode 100644 thirdparty/boost/preprocessor/stringize.hpp create mode 100644 thirdparty/boost/preprocessor/tuple.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/eat.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/elem.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/rem.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/reverse.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/to_list.hpp create mode 100644 thirdparty/boost/preprocessor/tuple/to_seq.hpp create mode 100644 thirdparty/boost/preprocessor/while.hpp create mode 100644 thirdparty/boost/preprocessor/wstringize.hpp create mode 100644 thirdparty/boost/program_options.hpp create mode 100644 thirdparty/boost/program_options/cmdline.hpp create mode 100644 thirdparty/boost/program_options/config.hpp create mode 100644 thirdparty/boost/program_options/detail/cmdline.hpp create mode 100644 thirdparty/boost/program_options/detail/config_file.hpp create mode 100644 thirdparty/boost/program_options/detail/convert.hpp create mode 100644 thirdparty/boost/program_options/detail/parsers.hpp create mode 100644 thirdparty/boost/program_options/detail/utf8_codecvt_facet.hpp create mode 100644 thirdparty/boost/program_options/detail/value_semantic.hpp create mode 100644 thirdparty/boost/program_options/environment_iterator.hpp create mode 100644 thirdparty/boost/program_options/eof_iterator.hpp create mode 100644 thirdparty/boost/program_options/errors.hpp create mode 100644 thirdparty/boost/program_options/option.hpp create mode 100644 thirdparty/boost/program_options/options_description.hpp create mode 100644 thirdparty/boost/program_options/parsers.hpp create mode 100644 thirdparty/boost/program_options/positional_options.hpp create mode 100644 thirdparty/boost/program_options/value_semantic.hpp create mode 100644 thirdparty/boost/program_options/variables_map.hpp create mode 100644 thirdparty/boost/program_options/version.hpp create mode 100644 thirdparty/boost/progress.hpp create mode 100644 thirdparty/boost/property_map.hpp create mode 100644 thirdparty/boost/property_map_iterator.hpp create mode 100644 thirdparty/boost/ptr_container/clone_allocator.hpp create mode 100644 thirdparty/boost/ptr_container/detail/associative_ptr_container.hpp create mode 100644 thirdparty/boost/ptr_container/detail/default_deleter.hpp create mode 100644 thirdparty/boost/ptr_container/detail/is_convertible.hpp create mode 100644 thirdparty/boost/ptr_container/detail/map_iterator.hpp create mode 100644 thirdparty/boost/ptr_container/detail/move.hpp create mode 100644 thirdparty/boost/ptr_container/detail/reversible_ptr_container.hpp create mode 100644 thirdparty/boost/ptr_container/detail/scoped_deleter.hpp create mode 100644 thirdparty/boost/ptr_container/detail/serialize_ptr_map_adapter.hpp create mode 100644 thirdparty/boost/ptr_container/detail/serialize_reversible_cont.hpp create mode 100644 thirdparty/boost/ptr_container/detail/serialize_xml_names.hpp create mode 100644 thirdparty/boost/ptr_container/detail/static_move_ptr.hpp create mode 100644 thirdparty/boost/ptr_container/detail/throw_exception.hpp create mode 100644 thirdparty/boost/ptr_container/detail/void_ptr_iterator.hpp create mode 100644 thirdparty/boost/ptr_container/exception.hpp create mode 100644 thirdparty/boost/ptr_container/indirect_fun.hpp create mode 100644 thirdparty/boost/ptr_container/nullable.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_array.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_container.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_deque.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_list.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_map.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_map_adapter.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_sequence_adapter.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_set.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_set_adapter.hpp create mode 100644 thirdparty/boost/ptr_container/ptr_vector.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_array.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_container.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_deque.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_list.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_map.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_set.hpp create mode 100644 thirdparty/boost/ptr_container/serialize_ptr_vector.hpp create mode 100644 thirdparty/boost/python.hpp create mode 100644 thirdparty/boost/python/arg_from_python.hpp create mode 100644 thirdparty/boost/python/args.hpp create mode 100644 thirdparty/boost/python/args_fwd.hpp create mode 100644 thirdparty/boost/python/back_reference.hpp create mode 100644 thirdparty/boost/python/base_type_traits.hpp create mode 100644 thirdparty/boost/python/bases.hpp create mode 100644 thirdparty/boost/python/borrowed.hpp create mode 100644 thirdparty/boost/python/call.hpp create mode 100644 thirdparty/boost/python/call_method.hpp create mode 100644 thirdparty/boost/python/cast.hpp create mode 100644 thirdparty/boost/python/class.hpp create mode 100644 thirdparty/boost/python/class_fwd.hpp create mode 100644 thirdparty/boost/python/converter/arg_from_python.hpp create mode 100644 thirdparty/boost/python/converter/arg_to_python.hpp create mode 100644 thirdparty/boost/python/converter/arg_to_python_base.hpp create mode 100644 thirdparty/boost/python/converter/as_to_python_function.hpp create mode 100644 thirdparty/boost/python/converter/builtin_converters.hpp create mode 100644 thirdparty/boost/python/converter/constructor_function.hpp create mode 100644 thirdparty/boost/python/converter/context_result_converter.hpp create mode 100644 thirdparty/boost/python/converter/convertible_function.hpp create mode 100644 thirdparty/boost/python/converter/from_python.hpp create mode 100644 thirdparty/boost/python/converter/implicit.hpp create mode 100644 thirdparty/boost/python/converter/obj_mgr_arg_from_python.hpp create mode 100644 thirdparty/boost/python/converter/object_manager.hpp create mode 100644 thirdparty/boost/python/converter/pointer_type_id.hpp create mode 100644 thirdparty/boost/python/converter/pyobject_traits.hpp create mode 100644 thirdparty/boost/python/converter/pyobject_type.hpp create mode 100644 thirdparty/boost/python/converter/pytype_function.hpp create mode 100644 thirdparty/boost/python/converter/pytype_object_mgr_traits.hpp create mode 100644 thirdparty/boost/python/converter/registered.hpp create mode 100644 thirdparty/boost/python/converter/registered_pointee.hpp create mode 100644 thirdparty/boost/python/converter/registrations.hpp create mode 100644 thirdparty/boost/python/converter/registry.hpp create mode 100644 thirdparty/boost/python/converter/return_from_python.hpp create mode 100644 thirdparty/boost/python/converter/rvalue_from_python_data.hpp create mode 100644 thirdparty/boost/python/converter/shared_ptr_deleter.hpp create mode 100644 thirdparty/boost/python/converter/shared_ptr_from_python.hpp create mode 100644 thirdparty/boost/python/converter/shared_ptr_to_python.hpp create mode 100644 thirdparty/boost/python/converter/to_python_function_type.hpp create mode 100644 thirdparty/boost/python/copy_const_reference.hpp create mode 100644 thirdparty/boost/python/copy_non_const_reference.hpp create mode 100644 thirdparty/boost/python/data_members.hpp create mode 100644 thirdparty/boost/python/def.hpp create mode 100644 thirdparty/boost/python/def_visitor.hpp create mode 100644 thirdparty/boost/python/default_call_policies.hpp create mode 100644 thirdparty/boost/python/detail/aix_init_module.hpp create mode 100644 thirdparty/boost/python/detail/api_placeholder.hpp create mode 100644 thirdparty/boost/python/detail/borrowed_ptr.hpp create mode 100644 thirdparty/boost/python/detail/caller.hpp create mode 100644 thirdparty/boost/python/detail/config.hpp create mode 100644 thirdparty/boost/python/detail/construct.hpp create mode 100644 thirdparty/boost/python/detail/convertible.hpp create mode 100644 thirdparty/boost/python/detail/copy_ctor_mutates_rhs.hpp create mode 100644 thirdparty/boost/python/detail/cv_category.hpp create mode 100644 thirdparty/boost/python/detail/dealloc.hpp create mode 100644 thirdparty/boost/python/detail/decorated_type_id.hpp create mode 100644 thirdparty/boost/python/detail/decref_guard.hpp create mode 100644 thirdparty/boost/python/detail/def_helper.hpp create mode 100644 thirdparty/boost/python/detail/def_helper_fwd.hpp create mode 100644 thirdparty/boost/python/detail/defaults_def.hpp create mode 100644 thirdparty/boost/python/detail/defaults_gen.hpp create mode 100644 thirdparty/boost/python/detail/dependent.hpp create mode 100644 thirdparty/boost/python/detail/destroy.hpp create mode 100644 thirdparty/boost/python/detail/enable_if.hpp create mode 100644 thirdparty/boost/python/detail/exception_handler.hpp create mode 100644 thirdparty/boost/python/detail/force_instantiate.hpp create mode 100644 thirdparty/boost/python/detail/if_else.hpp create mode 100644 thirdparty/boost/python/detail/indirect_traits.hpp create mode 100644 thirdparty/boost/python/detail/invoke.hpp create mode 100644 thirdparty/boost/python/detail/is_auto_ptr.hpp create mode 100644 thirdparty/boost/python/detail/is_shared_ptr.hpp create mode 100644 thirdparty/boost/python/detail/is_wrapper.hpp create mode 100644 thirdparty/boost/python/detail/is_xxx.hpp create mode 100644 thirdparty/boost/python/detail/make_keyword_range_fn.hpp create mode 100644 thirdparty/boost/python/detail/make_tuple.hpp create mode 100644 thirdparty/boost/python/detail/map_entry.hpp create mode 100644 thirdparty/boost/python/detail/mpl_lambda.hpp create mode 100644 thirdparty/boost/python/detail/msvc_typeinfo.hpp create mode 100644 thirdparty/boost/python/detail/none.hpp create mode 100644 thirdparty/boost/python/detail/not_specified.hpp create mode 100644 thirdparty/boost/python/detail/nullary_function_adaptor.hpp create mode 100644 thirdparty/boost/python/detail/operator_id.hpp create mode 100644 thirdparty/boost/python/detail/overloads_fwd.hpp create mode 100644 thirdparty/boost/python/detail/pointee.hpp create mode 100644 thirdparty/boost/python/detail/prefix.hpp create mode 100644 thirdparty/boost/python/detail/preprocessor.hpp create mode 100644 thirdparty/boost/python/detail/python22_fixed.h create mode 100644 thirdparty/boost/python/detail/python_type.hpp create mode 100644 thirdparty/boost/python/detail/raw_pyobject.hpp create mode 100644 thirdparty/boost/python/detail/referent_storage.hpp create mode 100644 thirdparty/boost/python/detail/result.hpp create mode 100644 thirdparty/boost/python/detail/scope.hpp create mode 100644 thirdparty/boost/python/detail/sfinae.hpp create mode 100644 thirdparty/boost/python/detail/signature.hpp create mode 100644 thirdparty/boost/python/detail/string_literal.hpp create mode 100644 thirdparty/boost/python/detail/target.hpp create mode 100644 thirdparty/boost/python/detail/translate_exception.hpp create mode 100644 thirdparty/boost/python/detail/type_list.hpp create mode 100644 thirdparty/boost/python/detail/type_list_impl.hpp create mode 100644 thirdparty/boost/python/detail/type_list_impl_no_pts.hpp create mode 100644 thirdparty/boost/python/detail/unwind_type.hpp create mode 100644 thirdparty/boost/python/detail/unwrap_type_id.hpp create mode 100644 thirdparty/boost/python/detail/unwrap_wrapper.hpp create mode 100644 thirdparty/boost/python/detail/value_arg.hpp create mode 100644 thirdparty/boost/python/detail/value_is_shared_ptr.hpp create mode 100644 thirdparty/boost/python/detail/value_is_xxx.hpp create mode 100644 thirdparty/boost/python/detail/void_ptr.hpp create mode 100644 thirdparty/boost/python/detail/void_return.hpp create mode 100644 thirdparty/boost/python/detail/wrap_python.hpp create mode 100644 thirdparty/boost/python/detail/wrapper_base.hpp create mode 100644 thirdparty/boost/python/dict.hpp create mode 100644 thirdparty/boost/python/docstring_options.hpp create mode 100644 thirdparty/boost/python/enum.hpp create mode 100644 thirdparty/boost/python/errors.hpp create mode 100644 thirdparty/boost/python/exception_translator.hpp create mode 100644 thirdparty/boost/python/exec.hpp create mode 100644 thirdparty/boost/python/extract.hpp create mode 100644 thirdparty/boost/python/handle.hpp create mode 100644 thirdparty/boost/python/handle_fwd.hpp create mode 100644 thirdparty/boost/python/has_back_reference.hpp create mode 100644 thirdparty/boost/python/implicit.hpp create mode 100644 thirdparty/boost/python/import.hpp create mode 100644 thirdparty/boost/python/init.hpp create mode 100644 thirdparty/boost/python/instance_holder.hpp create mode 100644 thirdparty/boost/python/iterator.hpp create mode 100644 thirdparty/boost/python/list.hpp create mode 100644 thirdparty/boost/python/long.hpp create mode 100644 thirdparty/boost/python/lvalue_from_pytype.hpp create mode 100644 thirdparty/boost/python/make_constructor.hpp create mode 100644 thirdparty/boost/python/make_function.hpp create mode 100644 thirdparty/boost/python/manage_new_object.hpp create mode 100644 thirdparty/boost/python/module.hpp create mode 100644 thirdparty/boost/python/module_init.hpp create mode 100644 thirdparty/boost/python/numeric.hpp create mode 100644 thirdparty/boost/python/object.hpp create mode 100644 thirdparty/boost/python/object/add_to_namespace.hpp create mode 100644 thirdparty/boost/python/object/class.hpp create mode 100644 thirdparty/boost/python/object/class_detail.hpp create mode 100644 thirdparty/boost/python/object/class_metadata.hpp create mode 100644 thirdparty/boost/python/object/class_wrapper.hpp create mode 100644 thirdparty/boost/python/object/enum_base.hpp create mode 100644 thirdparty/boost/python/object/find_instance.hpp create mode 100644 thirdparty/boost/python/object/forward.hpp create mode 100644 thirdparty/boost/python/object/function.hpp create mode 100644 thirdparty/boost/python/object/function_doc_signature.hpp create mode 100644 thirdparty/boost/python/object/function_handle.hpp create mode 100644 thirdparty/boost/python/object/function_object.hpp create mode 100644 thirdparty/boost/python/object/inheritance.hpp create mode 100644 thirdparty/boost/python/object/inheritance_query.hpp create mode 100644 thirdparty/boost/python/object/instance.hpp create mode 100644 thirdparty/boost/python/object/iterator.hpp create mode 100644 thirdparty/boost/python/object/iterator_core.hpp create mode 100644 thirdparty/boost/python/object/life_support.hpp create mode 100644 thirdparty/boost/python/object/make_holder.hpp create mode 100644 thirdparty/boost/python/object/make_instance.hpp create mode 100644 thirdparty/boost/python/object/make_ptr_instance.hpp create mode 100644 thirdparty/boost/python/object/pickle_support.hpp create mode 100644 thirdparty/boost/python/object/pointer_holder.hpp create mode 100644 thirdparty/boost/python/object/py_function.hpp create mode 100644 thirdparty/boost/python/object/stl_iterator_core.hpp create mode 100644 thirdparty/boost/python/object/value_holder.hpp create mode 100644 thirdparty/boost/python/object/value_holder_fwd.hpp create mode 100644 thirdparty/boost/python/object_attributes.hpp create mode 100644 thirdparty/boost/python/object_call.hpp create mode 100644 thirdparty/boost/python/object_core.hpp create mode 100644 thirdparty/boost/python/object_fwd.hpp create mode 100644 thirdparty/boost/python/object_items.hpp create mode 100644 thirdparty/boost/python/object_operators.hpp create mode 100644 thirdparty/boost/python/object_protocol.hpp create mode 100644 thirdparty/boost/python/object_protocol_core.hpp create mode 100644 thirdparty/boost/python/object_slices.hpp create mode 100644 thirdparty/boost/python/opaque_pointer_converter.hpp create mode 100644 thirdparty/boost/python/operators.hpp create mode 100644 thirdparty/boost/python/other.hpp create mode 100644 thirdparty/boost/python/overloads.hpp create mode 100644 thirdparty/boost/python/override.hpp create mode 100644 thirdparty/boost/python/pointee.hpp create mode 100644 thirdparty/boost/python/proxy.hpp create mode 100644 thirdparty/boost/python/ptr.hpp create mode 100644 thirdparty/boost/python/pure_virtual.hpp create mode 100644 thirdparty/boost/python/raw_function.hpp create mode 100644 thirdparty/boost/python/refcount.hpp create mode 100644 thirdparty/boost/python/reference_existing_object.hpp create mode 100644 thirdparty/boost/python/register_ptr_to_python.hpp create mode 100644 thirdparty/boost/python/return_arg.hpp create mode 100644 thirdparty/boost/python/return_by_value.hpp create mode 100644 thirdparty/boost/python/return_internal_reference.hpp create mode 100644 thirdparty/boost/python/return_opaque_pointer.hpp create mode 100644 thirdparty/boost/python/return_value_policy.hpp create mode 100644 thirdparty/boost/python/scope.hpp create mode 100644 thirdparty/boost/python/self.hpp create mode 100644 thirdparty/boost/python/signature.hpp create mode 100644 thirdparty/boost/python/slice.hpp create mode 100644 thirdparty/boost/python/slice_nil.hpp create mode 100644 thirdparty/boost/python/ssize_t.hpp create mode 100644 thirdparty/boost/python/stl_iterator.hpp create mode 100644 thirdparty/boost/python/str.hpp create mode 100644 thirdparty/boost/python/suite/indexing/container_utils.hpp create mode 100644 thirdparty/boost/python/suite/indexing/detail/indexing_suite_detail.hpp create mode 100644 thirdparty/boost/python/suite/indexing/indexing_suite.hpp create mode 100644 thirdparty/boost/python/suite/indexing/map_indexing_suite.hpp create mode 100644 thirdparty/boost/python/suite/indexing/vector_indexing_suite.hpp create mode 100644 thirdparty/boost/python/tag.hpp create mode 100644 thirdparty/boost/python/to_python_converter.hpp create mode 100644 thirdparty/boost/python/to_python_indirect.hpp create mode 100644 thirdparty/boost/python/to_python_value.hpp create mode 100644 thirdparty/boost/python/tuple.hpp create mode 100644 thirdparty/boost/python/type_id.hpp create mode 100644 thirdparty/boost/python/with_custodian_and_ward.hpp create mode 100644 thirdparty/boost/python/wrapper.hpp create mode 100644 thirdparty/boost/random.hpp create mode 100644 thirdparty/boost/random/additive_combine.hpp create mode 100644 thirdparty/boost/random/bernoulli_distribution.hpp create mode 100644 thirdparty/boost/random/binomial_distribution.hpp create mode 100644 thirdparty/boost/random/cauchy_distribution.hpp create mode 100644 thirdparty/boost/random/detail/const_mod.hpp create mode 100644 thirdparty/boost/random/detail/iterator_mixin.hpp create mode 100644 thirdparty/boost/random/detail/pass_through_engine.hpp create mode 100644 thirdparty/boost/random/detail/ptr_helper.hpp create mode 100644 thirdparty/boost/random/detail/signed_unsigned_tools.hpp create mode 100644 thirdparty/boost/random/detail/uniform_int_float.hpp create mode 100644 thirdparty/boost/random/discard_block.hpp create mode 100644 thirdparty/boost/random/exponential_distribution.hpp create mode 100644 thirdparty/boost/random/gamma_distribution.hpp create mode 100644 thirdparty/boost/random/geometric_distribution.hpp create mode 100644 thirdparty/boost/random/inversive_congruential.hpp create mode 100644 thirdparty/boost/random/lagged_fibonacci.hpp create mode 100644 thirdparty/boost/random/linear_congruential.hpp create mode 100644 thirdparty/boost/random/linear_feedback_shift.hpp create mode 100644 thirdparty/boost/random/lognormal_distribution.hpp create mode 100644 thirdparty/boost/random/mersenne_twister.hpp create mode 100644 thirdparty/boost/random/normal_distribution.hpp create mode 100644 thirdparty/boost/random/poisson_distribution.hpp create mode 100644 thirdparty/boost/random/random_number_generator.hpp create mode 100644 thirdparty/boost/random/ranlux.hpp create mode 100644 thirdparty/boost/random/shuffle_output.hpp create mode 100644 thirdparty/boost/random/subtract_with_carry.hpp create mode 100644 thirdparty/boost/random/triangle_distribution.hpp create mode 100644 thirdparty/boost/random/uniform_01.hpp create mode 100644 thirdparty/boost/random/uniform_int.hpp create mode 100644 thirdparty/boost/random/uniform_on_sphere.hpp create mode 100644 thirdparty/boost/random/uniform_real.hpp create mode 100644 thirdparty/boost/random/uniform_smallint.hpp create mode 100644 thirdparty/boost/random/variate_generator.hpp create mode 100644 thirdparty/boost/random/xor_combine.hpp create mode 100644 thirdparty/boost/range.hpp create mode 100644 thirdparty/boost/range/as_array.hpp create mode 100644 thirdparty/boost/range/as_literal.hpp create mode 100644 thirdparty/boost/range/atl.hpp create mode 100644 thirdparty/boost/range/begin.hpp create mode 100644 thirdparty/boost/range/category.hpp create mode 100644 thirdparty/boost/range/concepts.hpp create mode 100644 thirdparty/boost/range/config.hpp create mode 100644 thirdparty/boost/range/const_iterator.hpp create mode 100644 thirdparty/boost/range/const_reverse_iterator.hpp create mode 100644 thirdparty/boost/range/detail/as_literal.hpp create mode 100644 thirdparty/boost/range/detail/begin.hpp create mode 100644 thirdparty/boost/range/detail/collection_traits.hpp create mode 100644 thirdparty/boost/range/detail/collection_traits_detail.hpp create mode 100644 thirdparty/boost/range/detail/common.hpp create mode 100644 thirdparty/boost/range/detail/const_iterator.hpp create mode 100644 thirdparty/boost/range/detail/detail_str.hpp create mode 100644 thirdparty/boost/range/detail/difference_type.hpp create mode 100644 thirdparty/boost/range/detail/empty.hpp create mode 100644 thirdparty/boost/range/detail/end.hpp create mode 100644 thirdparty/boost/range/detail/implementation_help.hpp create mode 100644 thirdparty/boost/range/detail/iterator.hpp create mode 100644 thirdparty/boost/range/detail/microsoft.hpp create mode 100644 thirdparty/boost/range/detail/remove_extent.hpp create mode 100644 thirdparty/boost/range/detail/sfinae.hpp create mode 100644 thirdparty/boost/range/detail/size.hpp create mode 100644 thirdparty/boost/range/detail/size_type.hpp create mode 100644 thirdparty/boost/range/detail/sizer.hpp create mode 100644 thirdparty/boost/range/detail/str_types.hpp create mode 100644 thirdparty/boost/range/detail/value_type.hpp create mode 100644 thirdparty/boost/range/detail/vc6/end.hpp create mode 100644 thirdparty/boost/range/detail/vc6/size.hpp create mode 100644 thirdparty/boost/range/difference_type.hpp create mode 100644 thirdparty/boost/range/distance.hpp create mode 100644 thirdparty/boost/range/empty.hpp create mode 100644 thirdparty/boost/range/end.hpp create mode 100644 thirdparty/boost/range/functions.hpp create mode 100644 thirdparty/boost/range/iterator.hpp create mode 100644 thirdparty/boost/range/iterator_range.hpp create mode 100644 thirdparty/boost/range/metafunctions.hpp create mode 100644 thirdparty/boost/range/mfc.hpp create mode 100644 thirdparty/boost/range/mutable_iterator.hpp create mode 100644 thirdparty/boost/range/pointer.hpp create mode 100644 thirdparty/boost/range/rbegin.hpp create mode 100644 thirdparty/boost/range/reference.hpp create mode 100644 thirdparty/boost/range/rend.hpp create mode 100644 thirdparty/boost/range/result_iterator.hpp create mode 100644 thirdparty/boost/range/reverse_iterator.hpp create mode 100644 thirdparty/boost/range/reverse_result_iterator.hpp create mode 100644 thirdparty/boost/range/size.hpp create mode 100644 thirdparty/boost/range/size_type.hpp create mode 100644 thirdparty/boost/range/sub_range.hpp create mode 100644 thirdparty/boost/range/value_type.hpp create mode 100644 thirdparty/boost/rational.hpp create mode 100644 thirdparty/boost/ref.hpp create mode 100644 thirdparty/boost/regex.h create mode 100644 thirdparty/boost/regex.hpp create mode 100644 thirdparty/boost/regex/concepts.hpp create mode 100644 thirdparty/boost/regex/config.hpp create mode 100644 thirdparty/boost/regex/config/borland.hpp create mode 100644 thirdparty/boost/regex/config/cwchar.hpp create mode 100644 thirdparty/boost/regex/icu.hpp create mode 100644 thirdparty/boost/regex/mfc.hpp create mode 100644 thirdparty/boost/regex/pattern_except.hpp create mode 100644 thirdparty/boost/regex/pending/object_cache.hpp create mode 100644 thirdparty/boost/regex/pending/static_mutex.hpp create mode 100644 thirdparty/boost/regex/pending/unicode_iterator.hpp create mode 100644 thirdparty/boost/regex/regex_traits.hpp create mode 100644 thirdparty/boost/regex/user.hpp create mode 100644 thirdparty/boost/regex/v4/basic_regex.hpp create mode 100644 thirdparty/boost/regex/v4/basic_regex_creator.hpp create mode 100644 thirdparty/boost/regex/v4/basic_regex_parser.hpp create mode 100644 thirdparty/boost/regex/v4/c_regex_traits.hpp create mode 100644 thirdparty/boost/regex/v4/char_regex_traits.hpp create mode 100644 thirdparty/boost/regex/v4/cpp_regex_traits.hpp create mode 100644 thirdparty/boost/regex/v4/cregex.hpp create mode 100644 thirdparty/boost/regex/v4/error_type.hpp create mode 100644 thirdparty/boost/regex/v4/fileiter.hpp create mode 100644 thirdparty/boost/regex/v4/instances.hpp create mode 100644 thirdparty/boost/regex/v4/iterator_category.hpp create mode 100644 thirdparty/boost/regex/v4/iterator_traits.hpp create mode 100644 thirdparty/boost/regex/v4/match_flags.hpp create mode 100644 thirdparty/boost/regex/v4/match_results.hpp create mode 100644 thirdparty/boost/regex/v4/mem_block_cache.hpp create mode 100644 thirdparty/boost/regex/v4/perl_matcher.hpp create mode 100644 thirdparty/boost/regex/v4/perl_matcher_common.hpp create mode 100644 thirdparty/boost/regex/v4/perl_matcher_non_recursive.hpp create mode 100644 thirdparty/boost/regex/v4/perl_matcher_recursive.hpp create mode 100644 thirdparty/boost/regex/v4/primary_transform.hpp create mode 100644 thirdparty/boost/regex/v4/protected_call.hpp create mode 100644 thirdparty/boost/regex/v4/regbase.hpp create mode 100644 thirdparty/boost/regex/v4/regex.hpp create mode 100644 thirdparty/boost/regex/v4/regex_format.hpp create mode 100644 thirdparty/boost/regex/v4/regex_fwd.hpp create mode 100644 thirdparty/boost/regex/v4/regex_grep.hpp create mode 100644 thirdparty/boost/regex/v4/regex_iterator.hpp create mode 100644 thirdparty/boost/regex/v4/regex_match.hpp create mode 100644 thirdparty/boost/regex/v4/regex_merge.hpp create mode 100644 thirdparty/boost/regex/v4/regex_raw_buffer.hpp create mode 100644 thirdparty/boost/regex/v4/regex_replace.hpp create mode 100644 thirdparty/boost/regex/v4/regex_search.hpp create mode 100644 thirdparty/boost/regex/v4/regex_split.hpp create mode 100644 thirdparty/boost/regex/v4/regex_token_iterator.hpp create mode 100644 thirdparty/boost/regex/v4/regex_traits.hpp create mode 100644 thirdparty/boost/regex/v4/regex_traits_defaults.hpp create mode 100644 thirdparty/boost/regex/v4/regex_workaround.hpp create mode 100644 thirdparty/boost/regex/v4/states.hpp create mode 100644 thirdparty/boost/regex/v4/sub_match.hpp create mode 100644 thirdparty/boost/regex/v4/syntax_type.hpp create mode 100644 thirdparty/boost/regex/v4/u32regex_iterator.hpp create mode 100644 thirdparty/boost/regex/v4/u32regex_token_iterator.hpp create mode 100644 thirdparty/boost/regex/v4/w32_regex_traits.hpp create mode 100644 thirdparty/boost/regex_fwd.hpp create mode 100644 thirdparty/boost/scoped_array.hpp create mode 100644 thirdparty/boost/scoped_ptr.hpp create mode 100644 thirdparty/boost/serialization/access.hpp create mode 100644 thirdparty/boost/serialization/array.hpp create mode 100644 thirdparty/boost/serialization/base_object.hpp create mode 100644 thirdparty/boost/serialization/binary_object.hpp create mode 100644 thirdparty/boost/serialization/collection_size_type.hpp create mode 100644 thirdparty/boost/serialization/collection_traits.hpp create mode 100644 thirdparty/boost/serialization/collections_load_imp.hpp create mode 100644 thirdparty/boost/serialization/collections_save_imp.hpp create mode 100644 thirdparty/boost/serialization/complex.hpp create mode 100644 thirdparty/boost/serialization/config.hpp create mode 100644 thirdparty/boost/serialization/deque.hpp create mode 100644 thirdparty/boost/serialization/detail/get_data.hpp create mode 100644 thirdparty/boost/serialization/detail/shared_count_132.hpp create mode 100644 thirdparty/boost/serialization/detail/shared_ptr_132.hpp create mode 100644 thirdparty/boost/serialization/detail/shared_ptr_nmt_132.hpp create mode 100644 thirdparty/boost/serialization/detail/stack_constructor.hpp create mode 100644 thirdparty/boost/serialization/ephemeral.hpp create mode 100644 thirdparty/boost/serialization/export.hpp create mode 100644 thirdparty/boost/serialization/extended_type_info.hpp create mode 100644 thirdparty/boost/serialization/extended_type_info_no_rtti.hpp create mode 100644 thirdparty/boost/serialization/extended_type_info_typeid.hpp create mode 100644 thirdparty/boost/serialization/force_include.hpp create mode 100644 thirdparty/boost/serialization/hash_collections_load_imp.hpp create mode 100644 thirdparty/boost/serialization/hash_collections_save_imp.hpp create mode 100644 thirdparty/boost/serialization/hash_map.hpp create mode 100644 thirdparty/boost/serialization/hash_set.hpp create mode 100644 thirdparty/boost/serialization/is_abstract.hpp create mode 100644 thirdparty/boost/serialization/is_bitwise_serializable.hpp create mode 100644 thirdparty/boost/serialization/level.hpp create mode 100644 thirdparty/boost/serialization/level_enum.hpp create mode 100644 thirdparty/boost/serialization/list.hpp create mode 100644 thirdparty/boost/serialization/map.hpp create mode 100644 thirdparty/boost/serialization/nvp.hpp create mode 100644 thirdparty/boost/serialization/optional.hpp create mode 100644 thirdparty/boost/serialization/scoped_ptr.hpp create mode 100644 thirdparty/boost/serialization/serialization.hpp create mode 100644 thirdparty/boost/serialization/set.hpp create mode 100644 thirdparty/boost/serialization/shared_ptr.hpp create mode 100644 thirdparty/boost/serialization/shared_ptr_132.hpp create mode 100644 thirdparty/boost/serialization/slist.hpp create mode 100644 thirdparty/boost/serialization/split_free.hpp create mode 100644 thirdparty/boost/serialization/split_member.hpp create mode 100644 thirdparty/boost/serialization/string.hpp create mode 100644 thirdparty/boost/serialization/tracking.hpp create mode 100644 thirdparty/boost/serialization/tracking_enum.hpp create mode 100644 thirdparty/boost/serialization/traits.hpp create mode 100644 thirdparty/boost/serialization/type_info_implementation.hpp create mode 100644 thirdparty/boost/serialization/utility.hpp create mode 100644 thirdparty/boost/serialization/valarray.hpp create mode 100644 thirdparty/boost/serialization/variant.hpp create mode 100644 thirdparty/boost/serialization/vector.hpp create mode 100644 thirdparty/boost/serialization/version.hpp create mode 100644 thirdparty/boost/serialization/void_cast.hpp create mode 100644 thirdparty/boost/serialization/void_cast_fwd.hpp create mode 100644 thirdparty/boost/serialization/weak_ptr.hpp create mode 100644 thirdparty/boost/serialization/wrapper.hpp create mode 100644 thirdparty/boost/shared_array.hpp create mode 100644 thirdparty/boost/shared_container_iterator.hpp create mode 100644 thirdparty/boost/shared_ptr.hpp create mode 100644 thirdparty/boost/signal.hpp create mode 100644 thirdparty/boost/signals.hpp create mode 100644 thirdparty/boost/signals/connection.hpp create mode 100644 thirdparty/boost/signals/detail/config.hpp create mode 100644 thirdparty/boost/signals/detail/gen_signal_N.pl create mode 100644 thirdparty/boost/signals/detail/named_slot_map.hpp create mode 100644 thirdparty/boost/signals/detail/signal_base.hpp create mode 100644 thirdparty/boost/signals/detail/signals_common.hpp create mode 100644 thirdparty/boost/signals/detail/slot_call_iterator.hpp create mode 100644 thirdparty/boost/signals/signal0.hpp create mode 100644 thirdparty/boost/signals/signal1.hpp create mode 100644 thirdparty/boost/signals/signal10.hpp create mode 100644 thirdparty/boost/signals/signal2.hpp create mode 100644 thirdparty/boost/signals/signal3.hpp create mode 100644 thirdparty/boost/signals/signal4.hpp create mode 100644 thirdparty/boost/signals/signal5.hpp create mode 100644 thirdparty/boost/signals/signal6.hpp create mode 100644 thirdparty/boost/signals/signal7.hpp create mode 100644 thirdparty/boost/signals/signal8.hpp create mode 100644 thirdparty/boost/signals/signal9.hpp create mode 100644 thirdparty/boost/signals/signal_template.hpp create mode 100644 thirdparty/boost/signals/slot.hpp create mode 100644 thirdparty/boost/signals/trackable.hpp create mode 100644 thirdparty/boost/smart_cast.hpp create mode 100644 thirdparty/boost/smart_ptr.hpp create mode 100644 thirdparty/boost/spirit.hpp create mode 100644 thirdparty/boost/spirit/actor.hpp create mode 100644 thirdparty/boost/spirit/actor/assign_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/assign_key_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/clear_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/decrement_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/erase_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/increment_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/insert_at_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/insert_key_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/push_back_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/push_front_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/ref_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/ref_const_ref_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/ref_const_ref_const_ref_a.hpp create mode 100644 thirdparty/boost/spirit/actor/ref_const_ref_value_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/ref_value_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/swap_actor.hpp create mode 100644 thirdparty/boost/spirit/actor/typeof.hpp create mode 100644 thirdparty/boost/spirit/attribute.hpp create mode 100644 thirdparty/boost/spirit/attribute/closure.hpp create mode 100644 thirdparty/boost/spirit/attribute/closure_context.hpp create mode 100644 thirdparty/boost/spirit/attribute/closure_fwd.hpp create mode 100644 thirdparty/boost/spirit/attribute/parametric.hpp create mode 100644 thirdparty/boost/spirit/attribute/typeof.hpp create mode 100644 thirdparty/boost/spirit/core.hpp create mode 100644 thirdparty/boost/spirit/core/assert.hpp create mode 100644 thirdparty/boost/spirit/core/composite/actions.hpp create mode 100644 thirdparty/boost/spirit/core/composite/alternative.hpp create mode 100644 thirdparty/boost/spirit/core/composite/composite.hpp create mode 100644 thirdparty/boost/spirit/core/composite/difference.hpp create mode 100644 thirdparty/boost/spirit/core/composite/directives.hpp create mode 100644 thirdparty/boost/spirit/core/composite/epsilon.hpp create mode 100644 thirdparty/boost/spirit/core/composite/exclusive_or.hpp create mode 100644 thirdparty/boost/spirit/core/composite/impl/alternative.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/difference.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/directives.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/exclusive_or.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/intersection.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/kleene_star.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/list.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/optional.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/positive.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/sequence.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/sequential_and.ipp create mode 100644 thirdparty/boost/spirit/core/composite/impl/sequential_or.ipp create mode 100644 thirdparty/boost/spirit/core/composite/intersection.hpp create mode 100644 thirdparty/boost/spirit/core/composite/kleene_star.hpp create mode 100644 thirdparty/boost/spirit/core/composite/list.hpp create mode 100644 thirdparty/boost/spirit/core/composite/no_actions.hpp create mode 100644 thirdparty/boost/spirit/core/composite/operators.hpp create mode 100644 thirdparty/boost/spirit/core/composite/optional.hpp create mode 100644 thirdparty/boost/spirit/core/composite/positive.hpp create mode 100644 thirdparty/boost/spirit/core/composite/sequence.hpp create mode 100644 thirdparty/boost/spirit/core/composite/sequential_and.hpp create mode 100644 thirdparty/boost/spirit/core/composite/sequential_or.hpp create mode 100644 thirdparty/boost/spirit/core/config.hpp create mode 100644 thirdparty/boost/spirit/core/impl/match.ipp create mode 100644 thirdparty/boost/spirit/core/impl/match_attr_traits.ipp create mode 100644 thirdparty/boost/spirit/core/impl/parser.ipp create mode 100644 thirdparty/boost/spirit/core/match.hpp create mode 100644 thirdparty/boost/spirit/core/nil.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/grammar.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/impl/grammar.ipp create mode 100644 thirdparty/boost/spirit/core/non_terminal/impl/object_with_id.ipp create mode 100644 thirdparty/boost/spirit/core/non_terminal/impl/rule.ipp create mode 100644 thirdparty/boost/spirit/core/non_terminal/impl/static.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/impl/subrule.ipp create mode 100644 thirdparty/boost/spirit/core/non_terminal/parser_context.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/parser_id.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/rule.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/subrule.hpp create mode 100644 thirdparty/boost/spirit/core/non_terminal/subrule_fwd.hpp create mode 100644 thirdparty/boost/spirit/core/parser.hpp create mode 100644 thirdparty/boost/spirit/core/primitives/impl/numerics.ipp create mode 100644 thirdparty/boost/spirit/core/primitives/impl/primitives.ipp create mode 100644 thirdparty/boost/spirit/core/primitives/numerics.hpp create mode 100644 thirdparty/boost/spirit/core/primitives/numerics_fwd.hpp create mode 100644 thirdparty/boost/spirit/core/primitives/primitives.hpp create mode 100644 thirdparty/boost/spirit/core/safe_bool.hpp create mode 100644 thirdparty/boost/spirit/core/scanner/impl/skipper.ipp create mode 100644 thirdparty/boost/spirit/core/scanner/scanner.hpp create mode 100644 thirdparty/boost/spirit/core/scanner/scanner_fwd.hpp create mode 100644 thirdparty/boost/spirit/core/scanner/skipper.hpp create mode 100644 thirdparty/boost/spirit/core/scanner/skipper_fwd.hpp create mode 100644 thirdparty/boost/spirit/core/typeof.hpp create mode 100644 thirdparty/boost/spirit/debug.hpp create mode 100644 thirdparty/boost/spirit/debug/debug_node.hpp create mode 100644 thirdparty/boost/spirit/debug/impl/parser_names.ipp create mode 100644 thirdparty/boost/spirit/debug/minimal.hpp create mode 100644 thirdparty/boost/spirit/debug/parser_names.hpp create mode 100644 thirdparty/boost/spirit/debug/typeof.hpp create mode 100644 thirdparty/boost/spirit/dynamic.hpp create mode 100644 thirdparty/boost/spirit/dynamic/for.hpp create mode 100644 thirdparty/boost/spirit/dynamic/if.hpp create mode 100644 thirdparty/boost/spirit/dynamic/impl/conditions.ipp create mode 100644 thirdparty/boost/spirit/dynamic/impl/select.ipp create mode 100644 thirdparty/boost/spirit/dynamic/impl/switch.ipp create mode 100644 thirdparty/boost/spirit/dynamic/lazy.hpp create mode 100644 thirdparty/boost/spirit/dynamic/rule_alias.hpp create mode 100644 thirdparty/boost/spirit/dynamic/select.hpp create mode 100644 thirdparty/boost/spirit/dynamic/stored_rule.hpp create mode 100644 thirdparty/boost/spirit/dynamic/stored_rule_fwd.hpp create mode 100644 thirdparty/boost/spirit/dynamic/switch.hpp create mode 100644 thirdparty/boost/spirit/dynamic/typeof.hpp create mode 100644 thirdparty/boost/spirit/dynamic/while.hpp create mode 100644 thirdparty/boost/spirit/error_handling.hpp create mode 100644 thirdparty/boost/spirit/error_handling/exceptions.hpp create mode 100644 thirdparty/boost/spirit/error_handling/exceptions_fwd.hpp create mode 100644 thirdparty/boost/spirit/error_handling/impl/exceptions.ipp create mode 100644 thirdparty/boost/spirit/error_handling/typeof.hpp create mode 100644 thirdparty/boost/spirit/iterator.hpp create mode 100644 thirdparty/boost/spirit/iterator/file_iterator.hpp create mode 100644 thirdparty/boost/spirit/iterator/file_iterator_fwd.hpp create mode 100644 thirdparty/boost/spirit/iterator/fixed_size_queue.hpp create mode 100644 thirdparty/boost/spirit/iterator/impl/file_iterator.ipp create mode 100644 thirdparty/boost/spirit/iterator/impl/position_iterator.ipp create mode 100644 thirdparty/boost/spirit/iterator/multi_pass.hpp create mode 100644 thirdparty/boost/spirit/iterator/multi_pass_fwd.hpp create mode 100644 thirdparty/boost/spirit/iterator/position_iterator.hpp create mode 100644 thirdparty/boost/spirit/iterator/position_iterator_fwd.hpp create mode 100644 thirdparty/boost/spirit/iterator/typeof.hpp create mode 100644 thirdparty/boost/spirit/meta.hpp create mode 100644 thirdparty/boost/spirit/meta/as_parser.hpp create mode 100644 thirdparty/boost/spirit/meta/fundamental.hpp create mode 100644 thirdparty/boost/spirit/meta/impl/fundamental.ipp create mode 100644 thirdparty/boost/spirit/meta/impl/parser_traits.ipp create mode 100644 thirdparty/boost/spirit/meta/impl/refactoring.ipp create mode 100644 thirdparty/boost/spirit/meta/impl/traverse.ipp create mode 100644 thirdparty/boost/spirit/meta/parser_traits.hpp create mode 100644 thirdparty/boost/spirit/meta/refactoring.hpp create mode 100644 thirdparty/boost/spirit/meta/traverse.hpp create mode 100644 thirdparty/boost/spirit/phoenix.hpp create mode 100644 thirdparty/boost/spirit/phoenix/actor.hpp create mode 100644 thirdparty/boost/spirit/phoenix/binders.hpp create mode 100644 thirdparty/boost/spirit/phoenix/casts.hpp create mode 100644 thirdparty/boost/spirit/phoenix/closures.hpp create mode 100644 thirdparty/boost/spirit/phoenix/composite.hpp create mode 100644 thirdparty/boost/spirit/phoenix/functions.hpp create mode 100644 thirdparty/boost/spirit/phoenix/new.hpp create mode 100644 thirdparty/boost/spirit/phoenix/operators.hpp create mode 100644 thirdparty/boost/spirit/phoenix/primitives.hpp create mode 100644 thirdparty/boost/spirit/phoenix/special_ops.hpp create mode 100644 thirdparty/boost/spirit/phoenix/statements.hpp create mode 100644 thirdparty/boost/spirit/phoenix/tuple_helpers.hpp create mode 100644 thirdparty/boost/spirit/phoenix/tuples.hpp create mode 100644 thirdparty/boost/spirit/symbols.hpp create mode 100644 thirdparty/boost/spirit/symbols/impl/symbols.ipp create mode 100644 thirdparty/boost/spirit/symbols/impl/tst.ipp create mode 100644 thirdparty/boost/spirit/symbols/symbols.hpp create mode 100644 thirdparty/boost/spirit/symbols/symbols_fwd.hpp create mode 100644 thirdparty/boost/spirit/symbols/typeof.hpp create mode 100644 thirdparty/boost/spirit/tree/ast.hpp create mode 100644 thirdparty/boost/spirit/tree/ast_fwd.hpp create mode 100644 thirdparty/boost/spirit/tree/common.hpp create mode 100644 thirdparty/boost/spirit/tree/common_fwd.hpp create mode 100644 thirdparty/boost/spirit/tree/impl/parse_tree_utils.ipp create mode 100644 thirdparty/boost/spirit/tree/impl/tree_to_xml.ipp create mode 100644 thirdparty/boost/spirit/tree/parse_tree.hpp create mode 100644 thirdparty/boost/spirit/tree/parse_tree_fwd.hpp create mode 100644 thirdparty/boost/spirit/tree/parse_tree_utils.hpp create mode 100644 thirdparty/boost/spirit/tree/parsetree.dtd create mode 100644 thirdparty/boost/spirit/tree/tree_to_xml.hpp create mode 100644 thirdparty/boost/spirit/tree/typeof.hpp create mode 100644 thirdparty/boost/spirit/utility.hpp create mode 100644 thirdparty/boost/spirit/utility/chset.hpp create mode 100644 thirdparty/boost/spirit/utility/chset_operators.hpp create mode 100644 thirdparty/boost/spirit/utility/confix.hpp create mode 100644 thirdparty/boost/spirit/utility/confix_fwd.hpp create mode 100644 thirdparty/boost/spirit/utility/distinct.hpp create mode 100644 thirdparty/boost/spirit/utility/distinct_fwd.hpp create mode 100644 thirdparty/boost/spirit/utility/escape_char.hpp create mode 100644 thirdparty/boost/spirit/utility/escape_char_fwd.hpp create mode 100644 thirdparty/boost/spirit/utility/flush_multi_pass.hpp create mode 100644 thirdparty/boost/spirit/utility/functor_parser.hpp create mode 100644 thirdparty/boost/spirit/utility/grammar_def.hpp create mode 100644 thirdparty/boost/spirit/utility/grammar_def_fwd.hpp create mode 100644 thirdparty/boost/spirit/utility/impl/chset.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/chset/basic_chset.hpp create mode 100644 thirdparty/boost/spirit/utility/impl/chset/basic_chset.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/chset/range_run.hpp create mode 100644 thirdparty/boost/spirit/utility/impl/chset/range_run.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/chset_operators.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/confix.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/escape_char.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/lists.ipp create mode 100644 thirdparty/boost/spirit/utility/impl/regex.ipp create mode 100644 thirdparty/boost/spirit/utility/lists.hpp create mode 100644 thirdparty/boost/spirit/utility/lists_fwd.hpp create mode 100644 thirdparty/boost/spirit/utility/loops.hpp create mode 100644 thirdparty/boost/spirit/utility/regex.hpp create mode 100644 thirdparty/boost/spirit/utility/rule_parser.hpp create mode 100644 thirdparty/boost/spirit/utility/scoped_lock.hpp create mode 100644 thirdparty/boost/spirit/utility/typeof.hpp create mode 100644 thirdparty/boost/spirit/version.hpp create mode 100644 thirdparty/boost/state_saver.hpp create mode 100644 thirdparty/boost/statechart/asynchronous_state_machine.hpp create mode 100644 thirdparty/boost/statechart/custom_reaction.hpp create mode 100644 thirdparty/boost/statechart/deep_history.hpp create mode 100644 thirdparty/boost/statechart/deferral.hpp create mode 100644 thirdparty/boost/statechart/detail/avoid_unused_warning.hpp create mode 100644 thirdparty/boost/statechart/detail/constructor.hpp create mode 100644 thirdparty/boost/statechart/detail/counted_base.hpp create mode 100644 thirdparty/boost/statechart/detail/leaf_state.hpp create mode 100644 thirdparty/boost/statechart/detail/memory.hpp create mode 100644 thirdparty/boost/statechart/detail/node_state.hpp create mode 100644 thirdparty/boost/statechart/detail/rtti_policy.hpp create mode 100644 thirdparty/boost/statechart/detail/state_base.hpp create mode 100644 thirdparty/boost/statechart/event.hpp create mode 100644 thirdparty/boost/statechart/event_base.hpp create mode 100644 thirdparty/boost/statechart/event_processor.hpp create mode 100644 thirdparty/boost/statechart/exception_translator.hpp create mode 100644 thirdparty/boost/statechart/fifo_scheduler.hpp create mode 100644 thirdparty/boost/statechart/fifo_worker.hpp create mode 100644 thirdparty/boost/statechart/history.hpp create mode 100644 thirdparty/boost/statechart/in_state_reaction.hpp create mode 100644 thirdparty/boost/statechart/null_exception_translator.hpp create mode 100644 thirdparty/boost/statechart/processor_container.hpp create mode 100644 thirdparty/boost/statechart/result.hpp create mode 100644 thirdparty/boost/statechart/shallow_history.hpp create mode 100644 thirdparty/boost/statechart/simple_state.hpp create mode 100644 thirdparty/boost/statechart/state.hpp create mode 100644 thirdparty/boost/statechart/state_machine.hpp create mode 100644 thirdparty/boost/statechart/termination.hpp create mode 100644 thirdparty/boost/statechart/transition.hpp create mode 100644 thirdparty/boost/static_assert.hpp create mode 100644 thirdparty/boost/static_warning.hpp create mode 100644 thirdparty/boost/strong_typedef.hpp create mode 100644 thirdparty/boost/system/config.hpp create mode 100644 thirdparty/boost/system/cygwin_error.hpp create mode 100644 thirdparty/boost/system/error_code.hpp create mode 100644 thirdparty/boost/system/linux_error.hpp create mode 100644 thirdparty/boost/system/system_error.hpp create mode 100644 thirdparty/boost/system/windows_error.hpp create mode 100644 thirdparty/boost/test/auto_unit_test.hpp create mode 100644 thirdparty/boost/test/debug.hpp create mode 100644 thirdparty/boost/test/debug_config.hpp create mode 100644 thirdparty/boost/test/detail/config.hpp create mode 100644 thirdparty/boost/test/detail/enable_warnings.hpp create mode 100644 thirdparty/boost/test/detail/fwd_decl.hpp create mode 100644 thirdparty/boost/test/detail/global_typedef.hpp create mode 100644 thirdparty/boost/test/detail/log_level.hpp create mode 100644 thirdparty/boost/test/detail/suppress_warnings.hpp create mode 100644 thirdparty/boost/test/detail/unit_test_parameters.hpp create mode 100644 thirdparty/boost/test/detail/workaround.hpp create mode 100644 thirdparty/boost/test/exception_safety.hpp create mode 100644 thirdparty/boost/test/execution_monitor.hpp create mode 100644 thirdparty/boost/test/floating_point_comparison.hpp create mode 100644 thirdparty/boost/test/framework.hpp create mode 100644 thirdparty/boost/test/impl/compiler_log_formatter.ipp create mode 100644 thirdparty/boost/test/impl/cpp_main.ipp create mode 100644 thirdparty/boost/test/impl/debug.ipp create mode 100644 thirdparty/boost/test/impl/exception_safety.ipp create mode 100644 thirdparty/boost/test/impl/execution_monitor.ipp create mode 100644 thirdparty/boost/test/impl/framework.ipp create mode 100644 thirdparty/boost/test/impl/interaction_based.ipp create mode 100644 thirdparty/boost/test/impl/logged_expectations.ipp create mode 100644 thirdparty/boost/test/impl/plain_report_formatter.ipp create mode 100644 thirdparty/boost/test/impl/progress_monitor.ipp create mode 100644 thirdparty/boost/test/impl/results_collector.ipp create mode 100644 thirdparty/boost/test/impl/results_reporter.ipp create mode 100644 thirdparty/boost/test/impl/test_main.ipp create mode 100644 thirdparty/boost/test/impl/test_tools.ipp create mode 100644 thirdparty/boost/test/impl/unit_test_log.ipp create mode 100644 thirdparty/boost/test/impl/unit_test_main.ipp create mode 100644 thirdparty/boost/test/impl/unit_test_monitor.ipp create mode 100644 thirdparty/boost/test/impl/unit_test_parameters.ipp create mode 100644 thirdparty/boost/test/impl/unit_test_suite.ipp create mode 100644 thirdparty/boost/test/impl/xml_log_formatter.ipp create mode 100644 thirdparty/boost/test/impl/xml_report_formatter.ipp create mode 100644 thirdparty/boost/test/included/prg_exec_monitor.hpp create mode 100644 thirdparty/boost/test/included/test_exec_monitor.hpp create mode 100644 thirdparty/boost/test/included/unit_test.hpp create mode 100644 thirdparty/boost/test/included/unit_test_framework.hpp create mode 100644 thirdparty/boost/test/interaction_based.hpp create mode 100644 thirdparty/boost/test/logged_expectations.hpp create mode 100644 thirdparty/boost/test/minimal.hpp create mode 100644 thirdparty/boost/test/mock_object.hpp create mode 100644 thirdparty/boost/test/output/compiler_log_formatter.hpp create mode 100644 thirdparty/boost/test/output/plain_report_formatter.hpp create mode 100644 thirdparty/boost/test/output/xml_log_formatter.hpp create mode 100644 thirdparty/boost/test/output/xml_report_formatter.hpp create mode 100644 thirdparty/boost/test/output_test_stream.hpp create mode 100644 thirdparty/boost/test/parameterized_test.hpp create mode 100644 thirdparty/boost/test/predicate_result.hpp create mode 100644 thirdparty/boost/test/prg_exec_monitor.hpp create mode 100644 thirdparty/boost/test/progress_monitor.hpp create mode 100644 thirdparty/boost/test/results_collector.hpp create mode 100644 thirdparty/boost/test/results_reporter.hpp create mode 100644 thirdparty/boost/test/test_case_template.hpp create mode 100644 thirdparty/boost/test/test_exec_monitor.hpp create mode 100644 thirdparty/boost/test/test_observer.hpp create mode 100644 thirdparty/boost/test/test_tools.hpp create mode 100644 thirdparty/boost/test/unit_test.hpp create mode 100644 thirdparty/boost/test/unit_test_log.hpp create mode 100644 thirdparty/boost/test/unit_test_log_formatter.hpp create mode 100644 thirdparty/boost/test/unit_test_monitor.hpp create mode 100644 thirdparty/boost/test/unit_test_suite.hpp create mode 100644 thirdparty/boost/test/unit_test_suite_impl.hpp create mode 100644 thirdparty/boost/test/utils/algorithm.hpp create mode 100644 thirdparty/boost/test/utils/assign_op.hpp create mode 100644 thirdparty/boost/test/utils/basic_cstring/basic_cstring.hpp create mode 100644 thirdparty/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp create mode 100644 thirdparty/boost/test/utils/basic_cstring/bcs_char_traits.hpp create mode 100644 thirdparty/boost/test/utils/basic_cstring/compare.hpp create mode 100644 thirdparty/boost/test/utils/basic_cstring/io.hpp create mode 100644 thirdparty/boost/test/utils/callback.hpp create mode 100644 thirdparty/boost/test/utils/class_properties.hpp create mode 100644 thirdparty/boost/test/utils/custom_manip.hpp create mode 100644 thirdparty/boost/test/utils/fixed_mapping.hpp create mode 100644 thirdparty/boost/test/utils/foreach.hpp create mode 100644 thirdparty/boost/test/utils/iterator/ifstream_line_iterator.hpp create mode 100644 thirdparty/boost/test/utils/iterator/input_iterator_facade.hpp create mode 100644 thirdparty/boost/test/utils/iterator/istream_line_iterator.hpp create mode 100644 thirdparty/boost/test/utils/iterator/token_iterator.hpp create mode 100644 thirdparty/boost/test/utils/named_params.hpp create mode 100644 thirdparty/boost/test/utils/nullstream.hpp create mode 100644 thirdparty/boost/test/utils/rtti.hpp create mode 100644 thirdparty/boost/test/utils/runtime/argument.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/argument_factory.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/argv_traverser.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/argv_traverser.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/argv_traverser.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/basic_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/char_parameter.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/char_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/char_parameter.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/dual_name_parameter.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/dual_name_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/dual_name_parameter.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/fwd.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/id_policy.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/id_policy.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/id_policy.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/iface/argument_factory.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/iface/id_policy.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/modifier.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/named_parameter.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/named_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/named_parameter.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/parser.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/parser.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/parser.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/positional_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/typed_parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/validation.cpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/validation.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/validation.ipp create mode 100644 thirdparty/boost/test/utils/runtime/cla/value_generator.hpp create mode 100644 thirdparty/boost/test/utils/runtime/cla/value_handler.hpp create mode 100644 thirdparty/boost/test/utils/runtime/config.hpp create mode 100644 thirdparty/boost/test/utils/runtime/configuration.hpp create mode 100644 thirdparty/boost/test/utils/runtime/env/environment.cpp create mode 100644 thirdparty/boost/test/utils/runtime/env/environment.hpp create mode 100644 thirdparty/boost/test/utils/runtime/env/environment.ipp create mode 100644 thirdparty/boost/test/utils/runtime/env/fwd.hpp create mode 100644 thirdparty/boost/test/utils/runtime/env/modifier.hpp create mode 100644 thirdparty/boost/test/utils/runtime/env/variable.hpp create mode 100644 thirdparty/boost/test/utils/runtime/file/config_file.cpp create mode 100644 thirdparty/boost/test/utils/runtime/file/config_file.hpp create mode 100644 thirdparty/boost/test/utils/runtime/file/config_file_iterator.cpp create mode 100644 thirdparty/boost/test/utils/runtime/file/config_file_iterator.hpp create mode 100644 thirdparty/boost/test/utils/runtime/fwd.hpp create mode 100644 thirdparty/boost/test/utils/runtime/interpret_argument_value.hpp create mode 100644 thirdparty/boost/test/utils/runtime/parameter.hpp create mode 100644 thirdparty/boost/test/utils/runtime/trace.hpp create mode 100644 thirdparty/boost/test/utils/runtime/validation.hpp create mode 100644 thirdparty/boost/test/utils/trivial_singleton.hpp create mode 100644 thirdparty/boost/test/utils/wrap_stringstream.hpp create mode 100644 thirdparty/boost/test/utils/xml_printer.hpp create mode 100644 thirdparty/boost/thread.hpp create mode 100644 thirdparty/boost/thread/barrier.hpp create mode 100644 thirdparty/boost/thread/condition.hpp create mode 100644 thirdparty/boost/thread/condition_variable.hpp create mode 100644 thirdparty/boost/thread/detail/config.hpp create mode 100644 thirdparty/boost/thread/detail/force_cast.hpp create mode 100644 thirdparty/boost/thread/detail/move.hpp create mode 100644 thirdparty/boost/thread/detail/platform.hpp create mode 100644 thirdparty/boost/thread/detail/singleton.hpp create mode 100644 thirdparty/boost/thread/detail/tss_hooks.hpp create mode 100644 thirdparty/boost/thread/exceptions.hpp create mode 100644 thirdparty/boost/thread/locks.hpp create mode 100644 thirdparty/boost/thread/mutex.hpp create mode 100644 thirdparty/boost/thread/once.hpp create mode 100644 thirdparty/boost/thread/pthread/condition_variable.hpp create mode 100644 thirdparty/boost/thread/pthread/condition_variable_fwd.hpp create mode 100644 thirdparty/boost/thread/pthread/mutex.hpp create mode 100644 thirdparty/boost/thread/pthread/once.hpp create mode 100644 thirdparty/boost/thread/pthread/pthread_mutex_scoped_lock.hpp create mode 100644 thirdparty/boost/thread/pthread/recursive_mutex.hpp create mode 100644 thirdparty/boost/thread/pthread/shared_mutex.hpp create mode 100644 thirdparty/boost/thread/pthread/thread.hpp create mode 100644 thirdparty/boost/thread/pthread/thread_data.hpp create mode 100644 thirdparty/boost/thread/pthread/timespec.hpp create mode 100644 thirdparty/boost/thread/pthread/tss.hpp create mode 100644 thirdparty/boost/thread/recursive_mutex.hpp create mode 100644 thirdparty/boost/thread/shared_mutex.hpp create mode 100644 thirdparty/boost/thread/thread.hpp create mode 100644 thirdparty/boost/thread/thread_time.hpp create mode 100644 thirdparty/boost/thread/tss.hpp create mode 100644 thirdparty/boost/thread/win32/basic_recursive_mutex.hpp create mode 100644 thirdparty/boost/thread/win32/basic_timed_mutex.hpp create mode 100644 thirdparty/boost/thread/win32/condition_variable.hpp create mode 100644 thirdparty/boost/thread/win32/interlocked_read.hpp create mode 100644 thirdparty/boost/thread/win32/mutex.hpp create mode 100644 thirdparty/boost/thread/win32/once.hpp create mode 100644 thirdparty/boost/thread/win32/recursive_mutex.hpp create mode 100644 thirdparty/boost/thread/win32/shared_mutex.hpp create mode 100644 thirdparty/boost/thread/win32/thread.hpp create mode 100644 thirdparty/boost/thread/win32/thread_heap_alloc.hpp create mode 100644 thirdparty/boost/thread/win32/thread_primitives.hpp create mode 100644 thirdparty/boost/thread/win32/tss.hpp create mode 100644 thirdparty/boost/thread/xtime.hpp create mode 100644 thirdparty/boost/throw_exception.hpp create mode 100644 thirdparty/boost/timer.hpp create mode 100644 thirdparty/boost/token_functions.hpp create mode 100644 thirdparty/boost/token_iterator.hpp create mode 100644 thirdparty/boost/tokenizer.hpp create mode 100644 thirdparty/boost/tr1/array.hpp create mode 100644 thirdparty/boost/tr1/complex.hpp create mode 100644 thirdparty/boost/tr1/detail/config.hpp create mode 100644 thirdparty/boost/tr1/detail/config_all.hpp create mode 100644 thirdparty/boost/tr1/detail/functor2iterator.hpp create mode 100644 thirdparty/boost/tr1/detail/math_overloads.hpp create mode 100644 thirdparty/boost/tr1/functional.hpp create mode 100644 thirdparty/boost/tr1/memory.hpp create mode 100644 thirdparty/boost/tr1/random.hpp create mode 100644 thirdparty/boost/tr1/regex.hpp create mode 100644 thirdparty/boost/tr1/tr1/algorithm create mode 100644 thirdparty/boost/tr1/tr1/array create mode 100644 thirdparty/boost/tr1/tr1/bcc32/array.h create mode 100644 thirdparty/boost/tr1/tr1/bcc32/random.h create mode 100644 thirdparty/boost/tr1/tr1/bcc32/regex.h create mode 100644 thirdparty/boost/tr1/tr1/bcc32/tuple.h create mode 100644 thirdparty/boost/tr1/tr1/bcc32/type_tra.h create mode 100644 thirdparty/boost/tr1/tr1/bitset create mode 100644 thirdparty/boost/tr1/tr1/complex create mode 100644 thirdparty/boost/tr1/tr1/deque create mode 100644 thirdparty/boost/tr1/tr1/exception create mode 100644 thirdparty/boost/tr1/tr1/fstream create mode 100644 thirdparty/boost/tr1/tr1/functional create mode 100644 thirdparty/boost/tr1/tr1/iomanip create mode 100644 thirdparty/boost/tr1/tr1/ios create mode 100644 thirdparty/boost/tr1/tr1/iostream create mode 100644 thirdparty/boost/tr1/tr1/istream create mode 100644 thirdparty/boost/tr1/tr1/iterator create mode 100644 thirdparty/boost/tr1/tr1/limits create mode 100644 thirdparty/boost/tr1/tr1/list create mode 100644 thirdparty/boost/tr1/tr1/locale create mode 100644 thirdparty/boost/tr1/tr1/map create mode 100644 thirdparty/boost/tr1/tr1/memory create mode 100644 thirdparty/boost/tr1/tr1/new create mode 100644 thirdparty/boost/tr1/tr1/numeric create mode 100644 thirdparty/boost/tr1/tr1/ostream create mode 100644 thirdparty/boost/tr1/tr1/queue create mode 100644 thirdparty/boost/tr1/tr1/random create mode 100644 thirdparty/boost/tr1/tr1/regex create mode 100644 thirdparty/boost/tr1/tr1/set create mode 100644 thirdparty/boost/tr1/tr1/sstream create mode 100644 thirdparty/boost/tr1/tr1/stack create mode 100644 thirdparty/boost/tr1/tr1/stdexcept create mode 100644 thirdparty/boost/tr1/tr1/streambuf create mode 100644 thirdparty/boost/tr1/tr1/string create mode 100644 thirdparty/boost/tr1/tr1/strstream create mode 100644 thirdparty/boost/tr1/tr1/sun/algorithm.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/array.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/bcc32.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/bitset.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/complex.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/deque.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/exception.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/fstream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/functional.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/iomanip.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/ios.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/iostream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/istream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/iterator.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/limits.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/list.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/locale.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/map.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/memory.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/new.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/numeric.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/ostream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/queue.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/random.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/regex.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/set.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/sstream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/stack.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/stdexcept.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/streambuf.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/string.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/strstream.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/sun.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/tuple.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/type_traits.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/typeinfo.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/utility.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/valarray.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/sun/vector.SUNWCCh create mode 100644 thirdparty/boost/tr1/tr1/tuple create mode 100644 thirdparty/boost/tr1/tr1/type_traits create mode 100644 thirdparty/boost/tr1/tr1/typeinfo create mode 100644 thirdparty/boost/tr1/tr1/utility create mode 100644 thirdparty/boost/tr1/tr1/valarray create mode 100644 thirdparty/boost/tr1/tr1/vector create mode 100644 thirdparty/boost/tr1/tuple.hpp create mode 100644 thirdparty/boost/tr1/type_traits.hpp create mode 100644 thirdparty/boost/tr1/utility.hpp create mode 100644 thirdparty/boost/tuple/detail/tuple_basic.hpp create mode 100644 thirdparty/boost/tuple/detail/tuple_basic_no_partial_spec.hpp create mode 100644 thirdparty/boost/tuple/tuple.hpp create mode 100644 thirdparty/boost/tuple/tuple_comparison.hpp create mode 100644 thirdparty/boost/tuple/tuple_io.hpp create mode 100644 thirdparty/boost/type.hpp create mode 100644 thirdparty/boost/type_traits.hpp create mode 100644 thirdparty/boost/type_traits/add_const.hpp create mode 100644 thirdparty/boost/type_traits/add_cv.hpp create mode 100644 thirdparty/boost/type_traits/add_pointer.hpp create mode 100644 thirdparty/boost/type_traits/add_reference.hpp create mode 100644 thirdparty/boost/type_traits/add_volatile.hpp create mode 100644 thirdparty/boost/type_traits/aligned_storage.hpp create mode 100644 thirdparty/boost/type_traits/alignment_of.hpp create mode 100644 thirdparty/boost/type_traits/alignment_traits.hpp create mode 100644 thirdparty/boost/type_traits/arithmetic_traits.hpp create mode 100644 thirdparty/boost/type_traits/array_traits.hpp create mode 100644 thirdparty/boost/type_traits/broken_compiler_spec.hpp create mode 100644 thirdparty/boost/type_traits/composite_traits.hpp create mode 100644 thirdparty/boost/type_traits/config.hpp create mode 100644 thirdparty/boost/type_traits/conversion_traits.hpp create mode 100644 thirdparty/boost/type_traits/cv_traits.hpp create mode 100644 thirdparty/boost/type_traits/decay.hpp create mode 100644 thirdparty/boost/type_traits/detail/bool_trait_def.hpp create mode 100644 thirdparty/boost/type_traits/detail/bool_trait_undef.hpp create mode 100644 thirdparty/boost/type_traits/detail/cv_traits_impl.hpp create mode 100644 thirdparty/boost/type_traits/detail/false_result.hpp create mode 100644 thirdparty/boost/type_traits/detail/ice_and.hpp create mode 100644 thirdparty/boost/type_traits/detail/ice_eq.hpp create mode 100644 thirdparty/boost/type_traits/detail/ice_not.hpp create mode 100644 thirdparty/boost/type_traits/detail/ice_or.hpp create mode 100644 thirdparty/boost/type_traits/detail/is_function_ptr_helper.hpp create mode 100644 thirdparty/boost/type_traits/detail/is_function_ptr_tester.hpp create mode 100644 thirdparty/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp create mode 100644 thirdparty/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp create mode 100644 thirdparty/boost/type_traits/detail/size_t_trait_def.hpp create mode 100644 thirdparty/boost/type_traits/detail/size_t_trait_undef.hpp create mode 100644 thirdparty/boost/type_traits/detail/template_arity_spec.hpp create mode 100644 thirdparty/boost/type_traits/detail/type_trait_def.hpp create mode 100644 thirdparty/boost/type_traits/detail/type_trait_undef.hpp create mode 100644 thirdparty/boost/type_traits/detail/wrap.hpp create mode 100644 thirdparty/boost/type_traits/detail/yes_no_type.hpp create mode 100644 thirdparty/boost/type_traits/extent.hpp create mode 100644 thirdparty/boost/type_traits/floating_point_promotion.hpp create mode 100644 thirdparty/boost/type_traits/function_traits.hpp create mode 100644 thirdparty/boost/type_traits/has_nothrow_assign.hpp create mode 100644 thirdparty/boost/type_traits/has_nothrow_constructor.hpp create mode 100644 thirdparty/boost/type_traits/has_nothrow_copy.hpp create mode 100644 thirdparty/boost/type_traits/has_nothrow_destructor.hpp create mode 100644 thirdparty/boost/type_traits/has_trivial_assign.hpp create mode 100644 thirdparty/boost/type_traits/has_trivial_constructor.hpp create mode 100644 thirdparty/boost/type_traits/has_trivial_copy.hpp create mode 100644 thirdparty/boost/type_traits/has_trivial_destructor.hpp create mode 100644 thirdparty/boost/type_traits/has_virtual_destructor.hpp create mode 100644 thirdparty/boost/type_traits/ice.hpp create mode 100644 thirdparty/boost/type_traits/integral_constant.hpp create mode 100644 thirdparty/boost/type_traits/integral_promotion.hpp create mode 100644 thirdparty/boost/type_traits/intrinsics.hpp create mode 100644 thirdparty/boost/type_traits/is_abstract.hpp create mode 100644 thirdparty/boost/type_traits/is_arithmetic.hpp create mode 100644 thirdparty/boost/type_traits/is_array.hpp create mode 100644 thirdparty/boost/type_traits/is_base_and_derived.hpp create mode 100644 thirdparty/boost/type_traits/is_base_of.hpp create mode 100644 thirdparty/boost/type_traits/is_class.hpp create mode 100644 thirdparty/boost/type_traits/is_complex.hpp create mode 100644 thirdparty/boost/type_traits/is_compound.hpp create mode 100644 thirdparty/boost/type_traits/is_const.hpp create mode 100644 thirdparty/boost/type_traits/is_convertible.hpp create mode 100644 thirdparty/boost/type_traits/is_empty.hpp create mode 100644 thirdparty/boost/type_traits/is_enum.hpp create mode 100644 thirdparty/boost/type_traits/is_float.hpp create mode 100644 thirdparty/boost/type_traits/is_floating_point.hpp create mode 100644 thirdparty/boost/type_traits/is_function.hpp create mode 100644 thirdparty/boost/type_traits/is_fundamental.hpp create mode 100644 thirdparty/boost/type_traits/is_integral.hpp create mode 100644 thirdparty/boost/type_traits/is_member_function_pointer.hpp create mode 100644 thirdparty/boost/type_traits/is_member_object_pointer.hpp create mode 100644 thirdparty/boost/type_traits/is_member_pointer.hpp create mode 100644 thirdparty/boost/type_traits/is_object.hpp create mode 100644 thirdparty/boost/type_traits/is_pod.hpp create mode 100644 thirdparty/boost/type_traits/is_pointer.hpp create mode 100644 thirdparty/boost/type_traits/is_polymorphic.hpp create mode 100644 thirdparty/boost/type_traits/is_reference.hpp create mode 100644 thirdparty/boost/type_traits/is_same.hpp create mode 100644 thirdparty/boost/type_traits/is_scalar.hpp create mode 100644 thirdparty/boost/type_traits/is_signed.hpp create mode 100644 thirdparty/boost/type_traits/is_stateless.hpp create mode 100644 thirdparty/boost/type_traits/is_union.hpp create mode 100644 thirdparty/boost/type_traits/is_unsigned.hpp create mode 100644 thirdparty/boost/type_traits/is_void.hpp create mode 100644 thirdparty/boost/type_traits/is_volatile.hpp create mode 100644 thirdparty/boost/type_traits/make_signed.hpp create mode 100644 thirdparty/boost/type_traits/make_unsigned.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_all_extents.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_bounds.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_const.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_cv.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_extent.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_pointer.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_reference.hpp create mode 100644 thirdparty/boost/type_traits/msvc/remove_volatile.hpp create mode 100644 thirdparty/boost/type_traits/msvc/typeof.hpp create mode 100644 thirdparty/boost/type_traits/object_traits.hpp create mode 100644 thirdparty/boost/type_traits/promote.hpp create mode 100644 thirdparty/boost/type_traits/rank.hpp create mode 100644 thirdparty/boost/type_traits/reference_traits.hpp create mode 100644 thirdparty/boost/type_traits/remove_all_extents.hpp create mode 100644 thirdparty/boost/type_traits/remove_bounds.hpp create mode 100644 thirdparty/boost/type_traits/remove_const.hpp create mode 100644 thirdparty/boost/type_traits/remove_cv.hpp create mode 100644 thirdparty/boost/type_traits/remove_extent.hpp create mode 100644 thirdparty/boost/type_traits/remove_pointer.hpp create mode 100644 thirdparty/boost/type_traits/remove_reference.hpp create mode 100644 thirdparty/boost/type_traits/remove_volatile.hpp create mode 100644 thirdparty/boost/type_traits/same_traits.hpp create mode 100644 thirdparty/boost/type_traits/transform_traits.hpp create mode 100644 thirdparty/boost/type_traits/transform_traits_spec.hpp create mode 100644 thirdparty/boost/type_traits/type_with_alignment.hpp create mode 100644 thirdparty/boost/typeof/dmc/typeof_impl.hpp create mode 100644 thirdparty/boost/typeof/encode_decode.hpp create mode 100644 thirdparty/boost/typeof/encode_decode_params.hpp create mode 100644 thirdparty/boost/typeof/incr_registration_group.hpp create mode 100644 thirdparty/boost/typeof/int_encoding.hpp create mode 100644 thirdparty/boost/typeof/integral_template_param.hpp create mode 100644 thirdparty/boost/typeof/message.hpp create mode 100644 thirdparty/boost/typeof/modifiers.hpp create mode 100644 thirdparty/boost/typeof/msvc/typeof_impl.hpp create mode 100644 thirdparty/boost/typeof/native.hpp create mode 100644 thirdparty/boost/typeof/pointers_data_members.hpp create mode 100644 thirdparty/boost/typeof/register_functions.hpp create mode 100644 thirdparty/boost/typeof/register_functions_iterate.hpp create mode 100644 thirdparty/boost/typeof/register_fundamental.hpp create mode 100644 thirdparty/boost/typeof/register_mem_functions.hpp create mode 100644 thirdparty/boost/typeof/std/bitset.hpp create mode 100644 thirdparty/boost/typeof/std/complex.hpp create mode 100644 thirdparty/boost/typeof/std/deque.hpp create mode 100644 thirdparty/boost/typeof/std/fstream.hpp create mode 100644 thirdparty/boost/typeof/std/functional.hpp create mode 100644 thirdparty/boost/typeof/std/iostream.hpp create mode 100644 thirdparty/boost/typeof/std/istream.hpp create mode 100644 thirdparty/boost/typeof/std/iterator.hpp create mode 100644 thirdparty/boost/typeof/std/list.hpp create mode 100644 thirdparty/boost/typeof/std/locale.hpp create mode 100644 thirdparty/boost/typeof/std/map.hpp create mode 100644 thirdparty/boost/typeof/std/memory.hpp create mode 100644 thirdparty/boost/typeof/std/ostream.hpp create mode 100644 thirdparty/boost/typeof/std/queue.hpp create mode 100644 thirdparty/boost/typeof/std/set.hpp create mode 100644 thirdparty/boost/typeof/std/sstream.hpp create mode 100644 thirdparty/boost/typeof/std/stack.hpp create mode 100644 thirdparty/boost/typeof/std/streambuf.hpp create mode 100644 thirdparty/boost/typeof/std/string.hpp create mode 100644 thirdparty/boost/typeof/std/utility.hpp create mode 100644 thirdparty/boost/typeof/std/valarray.hpp create mode 100644 thirdparty/boost/typeof/std/vector.hpp create mode 100644 thirdparty/boost/typeof/template_encoding.hpp create mode 100644 thirdparty/boost/typeof/template_template_param.hpp create mode 100644 thirdparty/boost/typeof/type_encoding.hpp create mode 100644 thirdparty/boost/typeof/type_template_param.hpp create mode 100644 thirdparty/boost/typeof/typeof.hpp create mode 100644 thirdparty/boost/typeof/typeof_impl.hpp create mode 100644 thirdparty/boost/typeof/vector.hpp create mode 100644 thirdparty/boost/typeof/vector100.hpp create mode 100644 thirdparty/boost/typeof/vector150.hpp create mode 100644 thirdparty/boost/typeof/vector200.hpp create mode 100644 thirdparty/boost/typeof/vector50.hpp create mode 100644 thirdparty/boost/utility.hpp create mode 100644 thirdparty/boost/utility/addressof.hpp create mode 100644 thirdparty/boost/utility/base_from_member.hpp create mode 100644 thirdparty/boost/utility/compare_pointees.hpp create mode 100644 thirdparty/boost/utility/detail/in_place_factory_prefix.hpp create mode 100644 thirdparty/boost/utility/detail/in_place_factory_suffix.hpp create mode 100644 thirdparty/boost/utility/detail/result_of_iterate.hpp create mode 100644 thirdparty/boost/utility/enable_if.hpp create mode 100644 thirdparty/boost/utility/in_place_factory.hpp create mode 100644 thirdparty/boost/utility/result_of.hpp create mode 100644 thirdparty/boost/utility/typed_in_place_factory.hpp create mode 100644 thirdparty/boost/utility/value_init.hpp create mode 100644 thirdparty/boost/variant.hpp create mode 100644 thirdparty/boost/variant/apply_visitor.hpp create mode 100644 thirdparty/boost/variant/bad_visit.hpp create mode 100644 thirdparty/boost/variant/detail/apply_visitor_binary.hpp create mode 100644 thirdparty/boost/variant/detail/apply_visitor_delayed.hpp create mode 100644 thirdparty/boost/variant/detail/apply_visitor_unary.hpp create mode 100644 thirdparty/boost/variant/detail/backup_holder.hpp create mode 100644 thirdparty/boost/variant/detail/bool_trait_def.hpp create mode 100644 thirdparty/boost/variant/detail/bool_trait_undef.hpp create mode 100644 thirdparty/boost/variant/detail/cast_storage.hpp create mode 100644 thirdparty/boost/variant/detail/config.hpp create mode 100644 thirdparty/boost/variant/detail/enable_recursive.hpp create mode 100644 thirdparty/boost/variant/detail/enable_recursive_fwd.hpp create mode 100644 thirdparty/boost/variant/detail/forced_return.hpp create mode 100644 thirdparty/boost/variant/detail/generic_result_type.hpp create mode 100644 thirdparty/boost/variant/detail/has_nothrow_move.hpp create mode 100644 thirdparty/boost/variant/detail/has_trivial_move.hpp create mode 100644 thirdparty/boost/variant/detail/initializer.hpp create mode 100644 thirdparty/boost/variant/detail/make_variant_list.hpp create mode 100644 thirdparty/boost/variant/detail/move.hpp create mode 100644 thirdparty/boost/variant/detail/over_sequence.hpp create mode 100644 thirdparty/boost/variant/detail/substitute.hpp create mode 100644 thirdparty/boost/variant/detail/substitute_fwd.hpp create mode 100644 thirdparty/boost/variant/detail/variant_io.hpp create mode 100644 thirdparty/boost/variant/detail/visitation_impl.hpp create mode 100644 thirdparty/boost/variant/get.hpp create mode 100644 thirdparty/boost/variant/recursive_variant.hpp create mode 100644 thirdparty/boost/variant/recursive_wrapper.hpp create mode 100644 thirdparty/boost/variant/recursive_wrapper_fwd.hpp create mode 100644 thirdparty/boost/variant/static_visitor.hpp create mode 100644 thirdparty/boost/variant/variant.hpp create mode 100644 thirdparty/boost/variant/variant_fwd.hpp create mode 100644 thirdparty/boost/variant/visitor_ptr.hpp create mode 100644 thirdparty/boost/vector_property_map.hpp create mode 100644 thirdparty/boost/version.hpp create mode 100644 thirdparty/boost/visit_each.hpp create mode 100644 thirdparty/boost/wave.hpp create mode 100644 thirdparty/boost/wave/cpp_context.hpp create mode 100644 thirdparty/boost/wave/cpp_exceptions.hpp create mode 100644 thirdparty/boost/wave/cpp_iteration_context.hpp create mode 100644 thirdparty/boost/wave/cpp_throw.hpp create mode 100644 thirdparty/boost/wave/cpplexer/convert_trigraphs.hpp create mode 100644 thirdparty/boost/wave/cpplexer/cpp_lex_interface.hpp create mode 100644 thirdparty/boost/wave/cpplexer/cpp_lex_interface_generator.hpp create mode 100644 thirdparty/boost/wave/cpplexer/cpp_lex_iterator.hpp create mode 100644 thirdparty/boost/wave/cpplexer/cpp_lex_token.hpp create mode 100644 thirdparty/boost/wave/cpplexer/cpplexer_exceptions.hpp create mode 100644 thirdparty/boost/wave/cpplexer/detect_include_guards.hpp create mode 100644 thirdparty/boost/wave/cpplexer/re2clex/aq.hpp create mode 100644 thirdparty/boost/wave/cpplexer/re2clex/cpp_re.hpp create mode 100644 thirdparty/boost/wave/cpplexer/re2clex/cpp_re2c_lexer.hpp create mode 100644 thirdparty/boost/wave/cpplexer/re2clex/scanner.hpp create mode 100644 thirdparty/boost/wave/cpplexer/token_cache.hpp create mode 100644 thirdparty/boost/wave/cpplexer/validate_universal_char.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_chlit_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_defined_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_defined_grammar_gen.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_expression_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_expression_grammar_gen.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_expression_value.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_grammar_gen.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_intlit_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_literal_grammar_gen.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_predef_macros_gen.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_predef_macros_grammar.hpp create mode 100644 thirdparty/boost/wave/grammars/cpp_value_error.hpp create mode 100644 thirdparty/boost/wave/language_support.hpp create mode 100644 thirdparty/boost/wave/preprocessing_hooks.hpp create mode 100644 thirdparty/boost/wave/token_ids.hpp create mode 100644 thirdparty/boost/wave/util/cpp_ifblock.hpp create mode 100644 thirdparty/boost/wave/util/cpp_include_paths.hpp create mode 100644 thirdparty/boost/wave/util/cpp_iterator.hpp create mode 100644 thirdparty/boost/wave/util/cpp_macromap.hpp create mode 100644 thirdparty/boost/wave/util/cpp_macromap_predef.hpp create mode 100644 thirdparty/boost/wave/util/cpp_macromap_utils.hpp create mode 100644 thirdparty/boost/wave/util/file_position.hpp create mode 100644 thirdparty/boost/wave/util/flex_string.hpp create mode 100644 thirdparty/boost/wave/util/functor_input.hpp create mode 100644 thirdparty/boost/wave/util/insert_whitespace_detection.hpp create mode 100644 thirdparty/boost/wave/util/interpret_pragma.hpp create mode 100644 thirdparty/boost/wave/util/iteration_context.hpp create mode 100644 thirdparty/boost/wave/util/macro_definition.hpp create mode 100644 thirdparty/boost/wave/util/macro_helpers.hpp create mode 100644 thirdparty/boost/wave/util/pattern_parser.hpp create mode 100644 thirdparty/boost/wave/util/symbol_table.hpp create mode 100644 thirdparty/boost/wave/util/time_conversion_helper.hpp create mode 100644 thirdparty/boost/wave/util/transform_iterator.hpp create mode 100644 thirdparty/boost/wave/util/unput_queue_iterator.hpp create mode 100644 thirdparty/boost/wave/wave_config.hpp create mode 100644 thirdparty/boost/wave/wave_config_constant.hpp create mode 100644 thirdparty/boost/wave/wave_version.hpp create mode 100644 thirdparty/boost/wave/whitespace_handling.hpp create mode 100644 thirdparty/boost/weak_ptr.hpp create mode 100644 thirdparty/boost/xpressive/basic_regex.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/access.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/action.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/adaptor.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/finder.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/flow_control.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/icase.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/linker.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/action_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/alternate_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/any_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_line_base.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/attr_end_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/attr_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/charset_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/end_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/keeper_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/literal_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/mark_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/optional_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/predicate_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/range_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/regex_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/set_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/string_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matcher/true_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/matchers.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/optimize.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/peeker.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/quant_style.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/regex_impl.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/results_cache.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/state.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/sub_match_impl.hpp create mode 100644 thirdparty/boost/xpressive/detail/core/sub_match_vector.hpp create mode 100644 thirdparty/boost/xpressive/detail/detail_fwd.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/dynamic.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/matchable.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/parse_charset.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/parser.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/parser_enum.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/parser_traits.hpp create mode 100644 thirdparty/boost/xpressive/detail/dynamic/sequence.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/compile.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/grammar.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/is_pure.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/modifier.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/placeholders.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/static.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_action.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_alternate.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_independent.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_inverse.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_marker.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_matcher.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_modifier.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_quantifier.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_sequence.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transforms/as_set.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/transmogrify.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/type_traits.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/visitor.hpp create mode 100644 thirdparty/boost/xpressive/detail/static/width_of.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/algorithm.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/any.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/boyer_moore.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/chset/basic_chset.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/chset/basic_chset.ipp create mode 100644 thirdparty/boost/xpressive/detail/utility/chset/chset.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/chset/range_run.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/chset/range_run.ipp create mode 100644 thirdparty/boost/xpressive/detail/utility/cons.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/counted_base.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/dont_care.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/hash_peek_bitset.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/ignore_unused.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/literals.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/never_true.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/save_restore.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/sequence_stack.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/symbols.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/tracking_ptr.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/traits_utils.hpp create mode 100644 thirdparty/boost/xpressive/detail/utility/width.hpp create mode 100644 thirdparty/boost/xpressive/match_results.hpp create mode 100644 thirdparty/boost/xpressive/proto/args.hpp create mode 100644 thirdparty/boost/xpressive/proto/context.hpp create mode 100644 thirdparty/boost/xpressive/proto/context/callable.hpp create mode 100644 thirdparty/boost/xpressive/proto/context/default.hpp create mode 100644 thirdparty/boost/xpressive/proto/context/null.hpp create mode 100644 thirdparty/boost/xpressive/proto/debug.hpp create mode 100644 thirdparty/boost/xpressive/proto/deep_copy.hpp create mode 100644 thirdparty/boost/xpressive/proto/detail/funop.hpp create mode 100644 thirdparty/boost/xpressive/proto/detail/prefix.hpp create mode 100644 thirdparty/boost/xpressive/proto/detail/suffix.hpp create mode 100644 thirdparty/boost/xpressive/proto/domain.hpp create mode 100644 thirdparty/boost/xpressive/proto/eval.hpp create mode 100644 thirdparty/boost/xpressive/proto/expr.hpp create mode 100644 thirdparty/boost/xpressive/proto/extends.hpp create mode 100644 thirdparty/boost/xpressive/proto/fusion.hpp create mode 100644 thirdparty/boost/xpressive/proto/generate.hpp create mode 100644 thirdparty/boost/xpressive/proto/literal.hpp create mode 100644 thirdparty/boost/xpressive/proto/make_expr.hpp create mode 100644 thirdparty/boost/xpressive/proto/matches.hpp create mode 100644 thirdparty/boost/xpressive/proto/operators.hpp create mode 100644 thirdparty/boost/xpressive/proto/proto.hpp create mode 100644 thirdparty/boost/xpressive/proto/proto_fwd.hpp create mode 100644 thirdparty/boost/xpressive/proto/proto_typeof.hpp create mode 100644 thirdparty/boost/xpressive/proto/ref.hpp create mode 100644 thirdparty/boost/xpressive/proto/tags.hpp create mode 100644 thirdparty/boost/xpressive/proto/traits.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/apply.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/arg.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/branch.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/compose.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/construct.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/fold.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/fold_tree.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/function.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/list.hpp create mode 100644 thirdparty/boost/xpressive/proto/transform/pass_through.hpp create mode 100644 thirdparty/boost/xpressive/regex_actions.hpp create mode 100644 thirdparty/boost/xpressive/regex_algorithms.hpp create mode 100644 thirdparty/boost/xpressive/regex_compiler.hpp create mode 100644 thirdparty/boost/xpressive/regex_constants.hpp create mode 100644 thirdparty/boost/xpressive/regex_error.hpp create mode 100644 thirdparty/boost/xpressive/regex_iterator.hpp create mode 100644 thirdparty/boost/xpressive/regex_primitives.hpp create mode 100644 thirdparty/boost/xpressive/regex_token_iterator.hpp create mode 100644 thirdparty/boost/xpressive/regex_traits.hpp create mode 100644 thirdparty/boost/xpressive/sub_match.hpp create mode 100644 thirdparty/boost/xpressive/traits/c_regex_traits.hpp create mode 100644 thirdparty/boost/xpressive/traits/cpp_regex_traits.hpp create mode 100644 thirdparty/boost/xpressive/traits/detail/c_ctype.hpp create mode 100644 thirdparty/boost/xpressive/traits/null_regex_traits.hpp create mode 100644 thirdparty/boost/xpressive/xpressive.hpp create mode 100644 thirdparty/boost/xpressive/xpressive_dynamic.hpp create mode 100644 thirdparty/boost/xpressive/xpressive_fwd.hpp create mode 100644 thirdparty/boost/xpressive/xpressive_static.hpp create mode 100644 thirdparty/boost/xpressive/xpressive_typeof.hpp create mode 100644 thirdparty/libsvm/COPYRIGHT create mode 100644 thirdparty/libsvm/FAQ.html create mode 100644 thirdparty/libsvm/Makefile create mode 100644 thirdparty/libsvm/Makefile.win create mode 100644 thirdparty/libsvm/README create mode 100644 thirdparty/libsvm/heart_scale create mode 100644 thirdparty/libsvm/svm-predict.c create mode 100644 thirdparty/libsvm/svm-scale.c create mode 100644 thirdparty/libsvm/svm-train.c create mode 100644 thirdparty/libsvm/svm.cpp create mode 100644 thirdparty/libsvm/svm.h create mode 100644 thirdparty/libsvm/tools/README create mode 100755 thirdparty/libsvm/tools/checkdata.py create mode 100755 thirdparty/libsvm/tools/easy.py create mode 100755 thirdparty/libsvm/tools/grid.py create mode 100755 thirdparty/libsvm/tools/subset.py diff --git a/CC b/CC new file mode 100644 index 0000000..c3cc62e --- /dev/null +++ b/CC @@ -0,0 +1,64 @@ +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. + 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(g) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. + 3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. + 4. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, Noncommercial, ShareAlike. + 5. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. + 6. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. + 7. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. + 8. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + 9. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. + 10. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; + 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; + 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, + 4. to Distribute and Publicly Perform Adaptations. + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights described in Section 4(e). + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(d), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(d), as requested. + 2. You may Distribute or Publicly Perform an Adaptation only under: (i) the terms of this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-NonCommercial-ShareAlike 3.0 US) ("Applicable License"). You must include a copy of, or the URI, for Applicable License with every copy of each Adaptation You Distribute or Publicly Perform. You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License. You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. + 3. You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in con-nection with the exchange of copyrighted works. + 4. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(d) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. + 5. + + For the avoidance of doubt: + 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; + 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and, + 3. Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c). + 6. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING AND TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THIS EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. + diff --git a/GPL b/GPL new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/GPL @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..560b28b --- /dev/null +++ b/INSTALL @@ -0,0 +1,15 @@ +Library requirements for building Stupidfilter: +flex +libboost-serialization-dev + +On Ubuntu 8.04, you should be able to just run +sudo apt-get install build-essential flex libboost-serialization-dev +make +make install + +The Makefile may require a little bit of tweaking, specifically the path to your Boost serialization library, which in the test environment was /usr/lib/libboost_serialization-gcc42-mt-1_34_1.a + +To run the StupidFilter directly just type bin/stupidfilter data/c_rbf +It will take data from standard in followed by a EOF and return a 0.000000 classification for stupid text and a 1.000000 for nonstupid text. Once we have regression working more accurately, this number will be actually be a floating point that describes how sure we are of the classification, so it's worth keeping it as a float in your implementations. + +We have provided an example bash implementation in classify.sh. Note that we're normalizing whitespace with a call to sed. It's a good idea to strip HTML and normalize whitespace to avoid false positives. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..db70937 --- /dev/null +++ b/LICENSE @@ -0,0 +1,8 @@ +The StupidFilter is copyrighted by Rarefied Technologies, Inc. All rights not explicitly declared are reserved by the copyright holder. This software is distributed without warranty. Use it at your own risk. + +All source code files (.cpp and .h files in root directory) are open source and licenced under The GPL version 2.0, as defined in the included GPL text file. Data files (everything in the data/ directory) are licensed as Creative Commons Attribution-NonCommercial-ShareAlike 3.0 unported, as defined in the included CC text file. More lax license terms may be applied by Rarefied Technologies, Inc. at a later date, pending legal review. + +For more specific questions regarding licensing, please email project@stupidfilter.org. + +Thanks, +The StupidFilter Team diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9d184d7 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +# Thirdparty directory +TP = thirdparty +LIBSVM = $(TP)/libsvm/ +# Location of boost library headers +BOOST = -I$(TP) +# Path to binary boost serialization library must be defined here +BOOSTLIB = "/usr/lib64/" + +all : stupidfilter + +stupidfilter : stupidfilter.o svm.o SVMUtil.o parametersearch.o + cd bin && \ + g++ -L$(BOOSTLIB) -o"stupidfilter" stupidfilter.o svm.o SVMUtil.o parametersearch.o /usr/lib64/libboost_serialization.a -lfl + +stupidfilter.o : stupidfilter.cpp SVMUtil.cpp SVMUtil.h $(LIBSVM)svm.cpp $(LIBSVM)svm.h + g++ -c $(BOOST) -o"bin/stupidfilter.o" stupidfilter.cpp + +SVMUtil.o : SVMUtil.cpp SVMUtil.h parametersearch.cpp parametersearch.h parameterresult.h $(LIBSVM)svm.cpp $(LIBSVM)svm.h + g++ -c $(BOOST) -o"bin/SVMUtil.o" SVMUtil.cpp + +parametersearch.o : parametersearch.cpp parametersearch.h parameterresult.h $(LIBSVM)svm.cpp $(LIBSVM)svm.h + g++ -c $(BOOST) -o"bin/parametersearch.o" parametersearch.cpp + +svm.o : $(LIBSVM)svm.cpp $(LIBSVM)svm.h + g++ -c -o"bin/svm.o" $(LIBSVM)svm.cpp + + +clean: + rm -f bin/*.o + +install: + cp bin/stupidfilter /usr/bin/. diff --git a/SVMUtil.cpp b/SVMUtil.cpp new file mode 100644 index 0000000..17c0b18 --- /dev/null +++ b/SVMUtil.cpp @@ -0,0 +1,377 @@ +// Copyright 2008 Rarefied Technologies, Inc. +// Distributed under the GPL v2 please see +// LICENSE file for more information. + +#include "SVMUtil.h" +#include +#include +#include +#include +#include +#include +#include "parametersearch.h" +#include "parameterresult.h" +#include "../thirdparty/libsvm/svm.h" +#include "../thirdparty/boost/serialization/set.hpp" + +void myfunction(int); + +//#define SCALED_MAX 1 +//#define SCALED_MIN 0 //assume features > 0 +//#define SCALED_MIN -1 // if features can be < 0 + +//svm_problem ParseTrainingFile(string strFilename); + +#define MAX_LINE_LENGTH 1024 + +SVMUtil::SVMUtil() +{ + m_pProblem = NULL; + m_pScaleFactors = NULL; + m_nParams = 0; + m_pModel = NULL; +} + +SVMUtil::~SVMUtil() +{ + // problem destroyed when the model is + //delete m_pProblem; + //m_pProblem = NULL; + if(m_pModel) + svm_destroy_model(m_pModel); +} + +// borrowed from read_problem in svm-train.c +svm_problem* SVMUtil::ParseTrainingFile(std::string strFilename) +{ + m_pProblem = new svm_problem; + svm_node *x_space; + svm_parameter param; + + const char* filename = strFilename.c_str(); + + int elements, i, j; + FILE *fp = fopen(filename,"r"); + + if(fp == NULL) + { + fprintf(stderr,"can't open input file %s\n",filename); + exit(1); + } + + m_pProblem->l = 0; + elements = 0; + while(1) + { + int c = fgetc(fp); + switch(c) + { + case '\n': + ++m_pProblem->l; + // fall through, + // count the '-1' element + case ':': + ++elements; + break; + case EOF: + goto out; + default: + ; + } + } +out: + rewind(fp); + + m_pProblem->y = Malloc(double,m_pProblem->l); + m_pProblem->x = Malloc(struct svm_node *,m_pProblem->l); + + int nParamCountGuess = elements / m_pProblem->l; + + m_nParams = 0; + + for(i=0;il;i++) + { + double label; + x_space = Malloc(struct svm_node, nParamCountGuess+1); + m_pProblem->x[i] = x_space; + fscanf(fp,"%lf",&label); + m_pProblem->y[i] = label; + + j=0; + + while(1) + { + int c; + do { + c = getc(fp); + if(c=='\n') goto out2; + } while(isspace(c)); + ungetc(c,fp); + + int nIndex; + double dValue; + + if (fscanf(fp,"%d:%lf", &nIndex, &dValue) < 2) + { + fprintf(stderr,"Wrong input format at line %d\n", i+1); + exit(1); + } + if(dValue!=0) + { + x_space[j].index = nIndex; + x_space[j].value = dValue; + + ++j; + } + } +out2: + if(j>=1 && x_space[j-1].index > m_nParams) + m_nParams = x_space[j-1].index; + x_space[j++].index = -1; + } + + if(param.gamma == 0) + param.gamma = 1.0/m_nParams; + + if(param.kernel_type == PRECOMPUTED) + for(i=0;il;i++) + { + if (m_pProblem->x[i][0].index != 0) + { + fprintf(stderr,"Wrong input format: first column must be 0:sample_serial_number\n"); + exit(1); + } + if ((int)m_pProblem->x[i][0].value <= 0 || (int)m_pProblem->x[i][0].value > m_nParams) + { + fprintf(stderr,"Wrong input format: sample_serial_number out of range\n"); + exit(1); + } + } + + fclose(fp); + + ScaleTrainingData(); + SaveScaleFactors(strFilename + ".sf"); + + return m_pProblem; +} + +bool SVMUtil::ScaleTrainingData() +{ + if(!m_pProblem) + { + assert(0); + return false; + } + + if(!DetermineScaleFactors()) + return false; + + svm_node* pNode = NULL; + + for(int i=0; i < m_pProblem->l; i++) + { + pNode = m_pProblem->x[i]; + ScaleNode(pNode); + } + + return true; +} + +bool SVMUtil::DetermineScaleFactors() +{ + if(!m_pProblem) + return false; + + svm_node* pNode = NULL; + double* pMaxValue = Malloc(double, m_nParams); + m_pScaleFactors = Malloc(double, m_nParams); + + for(int j=0; j < m_nParams; j++) + { + pMaxValue[j] = 0; // assumes values should be scaled between 0 and 1 + } + + for(int i=0; i < m_pProblem->l; i++) + { + pNode = m_pProblem->x[i]; + int nindex = 0; + int j=0; + while(pNode) + { + nindex = pNode[j].index; + if(nindex==-1) + break; + + pMaxValue[nindex-1] = max(pMaxValue[nindex-1], pNode[j].value); // assume values are positive + j++; + } + } + + for(int j=0; j < m_nParams; j++) + { + if(pMaxValue[j] > 0) + m_pScaleFactors[j] = (double)1./pMaxValue[j]; + else + m_pScaleFactors[j] = 1; + } + + return true; +} + +bool SVMUtil::ScaleNode(svm_node* pNode) +{ + if(!pNode) + { + cerr << "error scaling" << endl; + assert(0); + return false; + } + if(!m_pScaleFactors) + { + if(m_pProblem) + DetermineScaleFactors(); + else + { + assert(0); + return false; + } + } + + int i = 0; + + while(pNode[i].index != -1) + { + pNode[i].value *= m_pScaleFactors[pNode[i].index-1]; + i++; + } + return true; +} + +bool SVMUtil::ParameterSearch(svm_parameter* pSvmParam, string strFilename) +{ + if(!m_pProblem || !pSvmParam) + return false; + + //struct sigaction sa; + //sa.sa_handler = &myfunction; + //sigaction(SIGINT, &sa, NULL); + + CParameterSearch* paramSearch = new CParameterSearch(m_pProblem, pSvmParam, strFilename); + + //SaveSearch(paramSearch); + + delete paramSearch; + + return true; +} + +bool SVMUtil::SaveSearch(const CParameterSearch* p_Search) +{ + std::ofstream ofs("searchResults.txt"); + boost::archive::text_oarchive oa(ofs); + oa << *p_Search; + return true; +} + +void myfunction(int number) +{ + int ten; + int five = number; + + ten = five + five; + +} + +bool SVMUtil::Load(string filename) +{ + if(m_pModel) + svm_destroy_model(m_pModel); + + string modelname = filename + ".mod"; + string scalename = filename + ".sf"; + m_pModel = svm_load_model(modelname.c_str()); + LoadScaleFactors(scalename); + + return true; +} + +bool SVMUtil::Save(string filename) +{ + string modelname = filename + ".mod"; + string scalename = filename + ".sf"; + svm_save_model(modelname.c_str(), m_pModel); + SaveScaleFactors(scalename); + + return true; +} + +void SVMUtil::SaveScaleFactors(string filename) +{ + ofstream fout; + fout.open(filename.c_str()); + fout << m_nParams << endl; + for(int i=0; i> m_nParams; + + if(m_pScaleFactors) + delete m_pScaleFactors; + m_pScaleFactors = new double[m_nParams]; + + for(int i=0; i> m_pScaleFactors[i]; + } + return true; +} + +bool SVMUtil::CrossValidate(int nFolds, svm_parameter* pParam) +{ + double* target = new double[m_pProblem->l]; + if(nFolds>0) + svm_cross_validation(m_pProblem, pParam, nFolds, target); + else + { + if(!m_pModel) + m_pModel = svm_train(m_pProblem, pParam); + for(int i=0; il; i++) + { + target[i] = svm_predict(m_pModel, m_pProblem->x[i]); + } + } + + float fError = 0; + float fWrong = 0; + for(int i=0; il; i++) + { + fError += abs(m_pProblem->y[i] - target[i]) ; + if( m_pProblem->y[i] >= 0.5 && target[i] < 0.5) + fWrong++; + else if( m_pProblem->y[i] < 0.5 && target[i] >= 0.5) + fWrong++; + + } + fError = (float)fError/m_pProblem->l; + fWrong = (float) fWrong/m_pProblem->l; + + float fStdDev = 0; + for(int i=0; il; i++) + { + fStdDev += pow(fError - abs(m_pProblem->y[i] - target[i]), 2) ; + } + fStdDev = pow(fStdDev, (float)0.5) / m_pProblem->l; + + std::cout << "Percent wrong: " << fWrong << " Avg Error: " << fError << " Std Dev: " << fStdDev << std::endl; + return true; +} diff --git a/SVMUtil.h b/SVMUtil.h new file mode 100644 index 0000000..a43c2f4 --- /dev/null +++ b/SVMUtil.h @@ -0,0 +1,46 @@ +#pragma once + +struct svm_problem; +struct svm_node; +struct svm_parameter; +struct svm_model; + +class CParameterSearch; + +#include + +#define Malloc(type,n) (type *)malloc((n)*sizeof(type)) + +class SVMUtil +{ +public: + SVMUtil(); + + ~SVMUtil(); + + svm_problem* ParseTrainingFile(std::string strFilename); + bool ParameterSearch( svm_parameter* pSvmParam, std::string strFilename); + bool ScaleNode(svm_node*); + bool CrossValidate(int nFolds, svm_parameter*); + bool Load(std::string); + bool Save(std::string); + + svm_model* m_pModel; + +private: + + bool ScaleTrainingData(); + bool DetermineScaleFactors(); + bool SaveSearch(const CParameterSearch* p_Search); + void SaveScaleFactors(std::string); + bool LoadScaleFactors(std::string); + + svm_problem* m_pProblem; + + double* m_pScaleFactors; + int m_nParams; +}; + + + + diff --git a/bin/SVMUtil.o b/bin/SVMUtil.o new file mode 100644 index 0000000000000000000000000000000000000000..8a29100c370000a66ad7f01cb636960444334836 GIT binary patch literal 278216 zcmeFa3w%|@wLiWCL8DD2Dr#y`j~X#j#3Td=h#E0R4+S;yu+*YSNP-E?tH}ul3QA41 zi2EpxeNfH=8_Mk{pGCO?<#Q;XN4XQ_3n+hq@;Ey~}a+=uc_l-(%*i1JS;dr4 z|BCWml<%SZ8_Gi{-$(g(lpmn%NBJSjk5C>#`7f0JMtKxv%qUsDqfo}8JPzgYC{IB7 z8I=M^HAQd=zCf%EwT)pnM$V7L-q*Y(@DL%B?7$LD`0K z8_Mk{cc5%Xxf5jv$`?`YM)@+zJt$v6*@^NslzUOWjD3ei6L^%oNWRxi=(@>_PoQ5(3u7NA^)vIymJlqD$3P*$L< zL>Wf80%Z-#RVY`ZydC9Qly{=6LwPsKdX)E|T!->rlp9dqk8&f*2T^W9`4Gy@C?7%D zgz{08%_tv3*@E(Mlv_|ffwC3lQz*BhdVzITPh9l$W8r0%a!3*(kG622oy(GK6vt z%DE`#p}ZF5^(b#ZIUnT$l#5V)3FTsxH=+Cr$|WdoL79s(59Lyn1t^!HycK0J%H=4( zin0`CIm!x@l_0#;9wr9%r7vXvCOyhZ@F6^Ea4&2K#OJ3oZQF zQAceP(RYYH(Xf|ZFwr{%msqMAy-yxJdenBA3zq|XenF`AU=b8aXG8U#P{X2js2QE1 z#>}`zBeW^Be%3DpA!az(Rl8=7ar;>^N=;m-@!GD&MSDVx)$L}Cx4#K-rP2u9)n5Ji zXhe(=YS?LpH6-i`9uz4bfXjnG^nCZ|P{RwM(KmNVOeQ3roenV&=hJIT^l?YW8oT&OM?gR_>t-BhF~|!o?XE{!T0t>;HCG+-W2Q>_!bKUWO0qb zKFkP^9U7Zp3m6^jf&gRL*yL9aja||Sawq0taj@mk*qhqlhs3%EN(``*&GH`mKznUp z4Ah1zqI@#>IG`}2K-A~Qeg~r^zCSi0*aLq)E3*Io*u~EauAT$A1F<=hx^2{fDQ>Pv zcB)1lIGtvw4fZ*F+Bf#Tj(;CLYSA`AUMB7q(C+ug-eP7d;((|QGA?yJSPs3rf`^46 z2Ud$h=oN*~3TM}f;<&cWN?aDlVRvy@0eo>JT-yc(v>OWO`R8D@AS>>nv5SMPRw?z? z1`j*zIz0BiuR$Ye4E9=1ZU}A`c5OC`cx>`+D_5pj?NA56s7|N?q9A%*4KmcQt1;N) zNCAS(NM>@TzFVR1<@I9!$_UkV6n#au>II>19LxYqLk-V%{R>K`;pt8x)<4?~LNYc! zD}s>yMO1Bzv%C{(eA-0TzL@BQ-DL(hW+p&W4kv^f@wz4flQpj!GZQ`C1T=9Ow;?;y z%#*D!XRA&hW#^R5*h*J4P^W@`PK zc2`Ja5E?YpOz5H^x|MZ^)P#uYc2IO%7tnpIX|vLjp$ElNDTGMVK91&$uNJKm>!rU0#0i0u3P^ zdIOkA$uY<|vPumXOZaawBqsfbzQF{+PclJ~U6&WVeziGMy2~6?A>D+~dVel$0+)(H zLEksr+{C!liWqTeliQ^&rc14O5tl;1nkIB<3%GQ#t<}}bR#z{YWW&>ILAY8PRN4&? z+OX5sZ?1n@1VNrRIO-e}otc73wd=0c5C0OGiOH3yNymq3*K``y z@lcncDjRQ$zfktOqvf(5<`fOV*5~R$gS?_ii6koGLXC@{s$AO&j>c9a>QqCpH;RWb z4FcMMr`@QYe&8CokOdWih?0+u1lub_r2OCnOW!)d#s@753pUa}guvEz$RPYTZ4}0B zH;ohbLqfZPo#H}7pvDbh7p)PK#`cgoob-qk4vdFE)|xf$42@pYWlk?b4Wnv0cV`xua`W&~)6}4?&+jm|D)FV%_NGR_naEVU+0v7yny&PJmlc(8WO!K2|D z!1G<9+IQk?v(xdT9Faro&GK=_nl(z6qUaQ1&ILU_W6(MCiCZ@IOYJaA+znH^>85K;i>yd7J3RnvYIz8zV=&Vi1=U`7)CCKfUNnrp zD@;$C^Cam>m?Yh1=1ANpGa7^2q2xnWEr*T`TG<+?Yt`LgQMXY&)jKPSHszm*65RGD z_~VWx>Z_b@RHs7z#D&>XJ_B{I*L2;1&q=gcJGjuhf=5Kc2NuJM(=1x3*UyJWU)vqM z9xZ152_a}YNVGn?-=T$qkxLP|0x%AZ{jzY^m2tJfBQdU+wf#q{H=5J2$S5Ga5Y2cs z=JxyE+(s-i7X#rFb_Hd{UJQ-IT&P&)L>*xkmNad2$XpLWHG(xuV>SFo|A>5Ao)Zh9 zBX_hz%CgLQqBF*R$PmmJlc7kV2M&OEE)jyTj}h}XsmcadJuB3x5mjbQd$cHlAL{s; zE~7dr)OZ=B0Bw7b)SFewgvoWORLXRrSmhqWuHYUKegI%=y3EMXe}VrR?ivTAwa<#b zGsBnQ$sNCyCr88Q%aaqsqYnJS%B)zyjjC;r5q-d(m;*nKBpHdY7_5n8z$|L#^7g8z zUKusPkrXU~8=i0IeE!38{_)QS=$Rx9?x|p}_jU^u19V%EMW|#AyF$o>I?+q!B?}P{q2o;`%+OS*6cNIzZz;;8}z`iKVU_N z_RwgR3H1FlcHRy>+(3~UvJ<1|(ZRM|2Bdye@YDu7!K6reh-TC|_P*J$_60-MXF@E? zmQ|ym0-lF)f%Ooqh+RGHT_S$tUFjn2{@Ag1{R3QXRfu21xsAwK@Unq78Zc3~Ak=6s z{mVKt&nQL4GyP5qbbb5gHMBp4a#BqleTv1tmYh_+(X>r-D zfx^nl@=Bw+thlT=T%1=@ysEGuP*{^+SP?ERFN5&P!dr{0!iAL(oL`bxRb>>Ht$=6+ zfvVzL%ksk2m4y(gs=A`0yfO@NRuooN31CHeaT%Zj`Q>HHN{aKt0Lw2gt;h=(FD)qy z0I+yPVPIK#Wocg6$g8Z(TM6l{Dh!0n%L7$Kkd#pst}M(e#q62PfGU+SO3KS_b!Kfv zIpiomuPO||Uo9)Ytt?PbSP2w%TMQ#yR9sn5kyjaBdCAi9@~ZG9d6oG^5X+J|5yK}J zRa6+u@=B@-h0j=AL18$rxa5-ZDj+j`S7`!sa>}YpN&@Fz7N{{@&f=HmRTbywgbQoJ zIpr0V#idXLD+N4KxB|}c=)S@**1~_|ipizr1;*s6Wkyw@@WlMWs_K$( z)#PwZ*orG;-xX#Z2~_2SiQxDJH(t9aTwF3aA6%4TR2untWfz76TqCL zF%ue741Fh@Eb++Dh~uo6<>cxDDDK%g9QTfQt%nOAmeVFcYLeB(G)6jz3; z^GZZz7I`VktDG1xE6~iDSc4)b(JC}^=50lJ;pB@X%8{P?!mPdS1j)KF>-q&|ySRKN zcwj|gGJr}h3Vh|Z;&4#_Re{R_RpEk}GbJ8sxoAhTM5ZT6g*eR#SLPLmtIXib1DD_I z&XMz)%%80LGiPE;&#^UvSy#$-H7T$VGn!Mrba`QZIHw|9De_zujyP=QOe-PGFnV;t zBy_hRpNL*WOEGz{)SZ@WN|*%DLzL`1=;{igFOt=pGF5mnfYo~D%mq--3$H6LC`_(e zQJPZ*ClfDn`on!i;1_~_p-;UvD=(ave35y_OKdIoM@Qp?Yx|dtT_|SrV#*BvVd@Op zV4u~)%llP*po+}r%{x^M)rVo^>NiIa`^W&(i+*z+7K+&^B}~#F4Ax#SVZk)uP8Xk= z6?+s6DAw2`h8?(DH1?VHXbK`sUWq-VWLRp6g);nyjo|jgP$O(KuIYw*KGra|9+qJ+ zQ#|@BSfnN6z6*f*MLM{?8vE^blOoF7AXX8JL>zFIHjk*oZfUb!N%g{ErJd z=@+~wX|DlJuX)g-s@hT$7B?(9XoX;UPCvj(09J6e$&ckBA1Jd@TJf-icV#AsDWVnX z;9MlDzNk38$>t_AY`|N5c2|qi@mB6&A1tzjR~xdSf=eGYnzyX1t7v_peCzVg@cQ}_ zotn#XTWxgLkQAtu=1xk(qJ53k`=Dv}$;qpAB9=L31D87@HqV>&s$r3+?@-PV&78rC z+8?=!mRs$?2or2fc0sHzXe-eEfqgyn1JH@!q#3ssWS&J2lo)FGD8kk72dFDRP>tDa zfDM6;L|d;DwKaNXX3gxr0=E3S^_j^SV%1@*rrI!(e0-v8{^aJ$(Hli-!2gxHX8OI+ z?B(R*&FaVPJ9AKd;V!7vtf1cbsAZxl!LF63h7KY`!N%2fK3v!)+HJqw8WmlQV~4H} zcIf(yaCBfCgAF?}D)MP3SZO;(8YaFqJL!gEkh^(ek_BxY{)?#!^hjc(ukUE5c+{gY za`$OhsNqd3OOV;Nc)+!;e$e9SRFd$M879g}aYmRXB;T|4p}p9+!Yjagz; zr<+Edv;?ki8}rQ=qbcSzGbBC*LgtS7iV;4`b$y2Gn%0jy7w{K1$G|&OeZpBk7zKa8 zeP;OVmYDt+<8LCo3B%*hf{Te`QjIUlco&`xGG)yF#28s;e?P`pK4z6sH3m*L$B3{U z0@@?~K#~_FL6$;e;4QNolHgUkHDlJt7e# z9*JO9adQ-kf)1ov%S$nJ9{Wu2AM$SAiP0$LOt(SIz;POlOGeC%IljuV4<;p6pJz2E z*Br)#%122*AvqWGEzCXKrxLReympPma$aUz{rlI;*^OK!MI0nBJ z=}BsompQWbB8F=XKD<4nW!ERK+&`_c1JvmMr)n%dy8%6oxl;u#tS>s%h8ENxs(mq2 zgvuh90b)KP1ETHNZgu0LgC^8ZEHR02&%;v&w+C|NLec(2M&zR?a$5tsUa|N{mWz+x zqn!;e%xf&{0$SYQXxP>8#=M68(!kn|z*nwZBG(w7wr2AN=qG*TjMhPOG!-=&`=|fw zW0JkiMVgV=-H0|kYYefCjYDmnc2=1d)rP&X#2&>bu-AYtBT{d~ltDPsK5eki)CTDF zJ!zPAFj_b5{;-wRv7N_!+M|8ad$j+*^j@MSiaVLs7%cj%$PEX1Vy%L@%}oV(6dLYq ziRBn9sl<6=WN9XM8O?hlvVSpm9$$&6S$$YhmO$&Us9Gu>clO=J7qgw1!*hW9NP0}fD@7b3Gu*zRw z-D!<(vZQ*WC1s9-&er6;mD~pJNQfsJqnq$lQyaFlMJc$p;f3!+dyE6;^+n(D5;rEq z9Zj4kA2DQiY|HRzMIZt%%9GM=+xt^$1qIT@g ztgr5XJ;4t7-iQ%C2OheP31gQbo{RE!8Bp3-k<2r;B6aSFR0h#RWr15KW<_d)iqsa> zHNb`S($Cmusym?cfdMO!qo&x(!m<%+iup*AIW-ow10_d0_5ti9Y*dD0_ITFy+%y7n{X$yfCL*IJj85j>PCPTz6}zKDhQpS1;@8 zVLhGlkow?AtF?~>|3~^$@UFdQhkD*E-l07Lg^l9iPjlc zJQ*i4<#5I`_gG-Vpd0ko3>+TKH$T_{A4`aaiJd51DqEokPKFG?4uuUIS-aT!Z1JQ& ztY{G(i4n;q&bEkUxO<=a(|MU~L(o}{{m>xAy!B&RCsL!dec?V#yS<-~I@7Thy1;ty z_*$seYq8>r*N0l=x%fKU`bDjd8)Wscti`)(jce-7c(whb;ftPd8)(9=;AU|_7SsEP#-vNM3*=>VKiJr77OOiM;9rcbecXl}!uC=zD&(rTyZ2 zRQ*TI2cfGsGp*M#EyJ?5k6b$MEIRkVb)F@HekRh%SUW|7%*Al;Ba1%YeD}Oz&Edv1 zhs8VQvNIKd(3ivi2Jzw31o8TnmG=a3EAa^Yxfb3Z?}rbKGz1UB4Y_L%H!Kn|c-Sm$ z5$UjazuZ&?4@SQ|)VO3bT zFXY&JcDF+;B{ONW+JQyTBf$&f5nG_e$a~1Bij=01G?qo4TG1D~%DDeuu zHBH$S>=Mt2Kqk8218#lb^=>$aCLl@yN4oS4Rh53Fk^*+O6r6uKswR zEBUzmV0+8WJR#Ed#L0kni)?XS>@uA}>D|4DY$lEyFe5+n zv-(Hq8>>4T;Ctok*Su$Sjj}0=S?l^m?}4IQDr_;Z7d1DlrPkJoM&da-Q7aioL`>Nc z(b3b|=F!&ldpPcNh}nkTaotq&J1^7myDq6y9G`g!l8K22daPrV=yq*~T_=Lw>1R07 z&nbpa4b8c3K}wFBI7n05nEai(_|sC!Z~x3$P|gs#@ToKGcyyYs0d^nR&xJ+qYZw1C z`9+`9sqn?G((} zPn?l9NHhJxmfwPKMk#!8t+=W%JSRJKYNQ~I*n=PuBtK2Hq!Y^v&P#Tzxm{{ z#iT!_U?qIgu^2wLR258VipM-Hv z2MIq#XBbzWlyLW`t3G=ioCbdj_P|w*{hx!aA{bq%}1NCCdf-Ha3&tmkkW|cP# zF8@iWAIspg6#4?x!xwfysiWcod*pUUWCO{W>gg^WH4_3*_bGW{&n z=P>#L)Qb<`o2Rb!S%-SA{xzeX^M8jz-=omSj)9E9!Ie)E>N)-_g}y+cuT$_hEASl( zeUCyPD?0Ll>_X<{z%b_!Aokf8gN!lZ1NCKUt{f z{8OMvzfO^Uvm*Tt)N}Qt2lZV2h=nhW4QM~=S^H7X+K>9r0g0pjz_mI4qkaOTZ$>>= zejTW1%U_|76%`i_4xgmZXQ7@OKgI79h=a?2okHKN(08Cd3pgnM_9*bNpE0w?<}XR1 z&q95+o8OxMq26q3g38rD)uEo7A2y?&8^1dg`X1DC^P|{!X+M{Kl0u(_dM^C}1-?$9 zZ&sw=p}_Yj^s(kI^B4w~|0L9N{>f743l!~6zMmkem>;U(Y~>Lb)f!Uw;rxVo9jXS7Z`o4nApI<;ge8*A;fX;!?j313-#wP z`T~W%4)qfme6xbT1NB__^(gSM<|kPUgY$0^>N)>pp`P<^fdXHLdd|PisOS9Kq0slB zp7U?4m^i?}@h734^KX^{Ux4}`a8UK94)qr>`euc`1NGGWCJEB)L4CG6{cCDt*Wubw z)Z=(D0f2+62a{0G)q{Dc=juU;0>2LRr$QbmKW#xhS5A9S&()KI3VpmFhJ&jolTgp` z&qF;|Pf8T&uR}do54I@udldSE3VpoT0E2_$pQO;wLp@awMg1y4y{MB^`L07fSAJU* z`aP)U%I_fRx$=uYO<2#5gOgA{AL2OjkK@oh)N}2l1od3|Sf{{mK|PoMJ*emWcTk~^ z7aP2AaQ>TwdX9e{>Zd{)4*$TlS^lW6ck9uA>lFAc3jH3`bMusg3jTPpK!JlRze%XS z0^(5i%|ku6&M85?czT<{uS0z;qu+vhPyK`V!oPbI`h%#?aHo&{j~9-EqZR%;@`w6K zsGsK6!?oa_hx%kjUxIqBey&sKw`P|wxhgQ(}~Z@gHb!@2gY^^k_ce{d~K+lzXxog7x^$DIv{z`?bXbkwWb z$r6k=1=6DOxf=DHA2y?&^W%0!`uh~=A5o+~UQ_@$xOP4Z^;|t&f_ko=u138Olz%oW z^xGBseW>T^=@Ha({v96>*7NmrR=`xV%T_Q|ON<^yAMp%!6tN zqMgk`eG;5g<+lX&!p)R^wL-rc^<4RFM?F`5`%urduOq1E`r+~CndTc@{hoz-u6{2; zJ!`*0zgeN*j(W~N`%usM=LqUK|BOFh+Rvpw3-w(6UZT*iR_He?^xGBseG2^%)N}QF zyr|f4aP@l@>bde=qR_8KJ?G!esOQRWJL)`=^sHox1Jj>Zb-tx+ONxAUIOtKc!DX{S}Np3-vojyYSc#7NCBn zyPQJu`N%rdU&82{QGb)0AJgwZ{ril*2lb-4Q})G*4OuuieG=-AbLS8Fvry0ZuK@L2 zJ+4#en^C_R^61FFWxoR7qtM5S2_77Oh5wH9v3!zH&+%s|^aZGA?N{iV75WZ^z6bT9 zxjXEGYcUSRUJQTW;QF~Fg+5E6FF?Jhh7^At>bZWf8TFk1I#A#2P9N(>j{+Y%Sy<1H z^GT>b0C61ox9UIY|H-tE0@Qoj52PpjUx)e@clxMrM*Y|^E`F$=#x+-6H8YTW&2@_| z3Zzd?otzd(OG(K{nVym!NS#VY{ByX~K zi`kf5kQdG~CNHh3GA5g$`Qh?P>s-W`oO9E43&JxZuc};?7F=PNSkNqh$P2=$Q*!2% zSLIw^QCL=5UQoCo2a+n6=|+gm$W!u`Ru$O5scGd~gEXPVObxM9oUR6~Nyl*OA zK!qf8Qr&>GISbNqia}$&dy!IDS`l8E120k+3YB>IGAKP`x7hXKhKmWZ4<=jI&UKkP zC0v=8|JCBMTg_bMuUKkx`*rTfQ>6*;x?CYfpPxN9Umym^j%7=_d>!0+4LfyuRo;ri zoU-bY66?*r0jRA+reh-3E53!5X{nL(f}Ff6DlMnUd{P-uO>&l2lvf3_MS-VHm1M+w zhd#^R^{QHG+KR$TQ3Vw>VEJHcz<_*E50-oC!GMVT74zpVw-<_Zq^H`N_1u+GT1tL- zNl9V8cm+GBs(6*GFnp~q9VVM;Ua-AXWjl=&J}C9na92+?f3E0^u!$`QPbtl-nNtv) zKX+jcG+Ou<(YacxRTX`ILLhx%QE`Q?`aIwAQT|I%7 z@xiI8Jfx~M1##Mkv-JFL#0(XzH4tu)trI(g2DL< zrsT|DC`NW`>L4ZtPJ1n0e;@Xkx*BJia9&xynNPYpp?lLt@V$6q3Nw^GOyk20=EoiE9h{?{4J8wv zuY(M0KdND(`HhYd>11^?F|0kXF8OeF&$`^H1N7a49!Wi4*%^^C_EzIzEk$qg!&y$= z)JLWyBCos4Pvitgs3hDp!(0;Xw#vMUio(hq zm@gKGtISW|OetGYF~{>gkYI3LaT@$j3C>%dB4-p+h_6bSA8K2WE>`P~T?}iR!1;Zu z)EVZKEWaEE=E~~)aE{o~aBduk{71em79_H@0;Wvaa~G!Mzyi(8-vS zS0KJFXWOpOVzpenAe>&2S6n#ZEr?t z-dACxfi6*VLTb`1gaR{DP4}$VT)E<_jGW%mOJA+pW6o3j)E>6>!peP!)phQIa2m|U zmqNoREQBpDsGvE;;lj#1*o`AT6c&W_M0CrJsqB1qiRz-0e{k zGCpTcL19_AIJ|NWTn8N=I};!AN*7xfo;kfp+3zRQ9H~&vWG?M0dOO1GQmi&K&3_vj zuwq)x$zPj{Hm3m-4H7MDs;y<&dkUzlgXMr#i#CW&CYZ#l@gYeaIrcWTQwunqKZy5hp1IrU6)yj%sUKLcUJ~G{AQQn%Ik1+ zDpQvh-dbEXweq{#H)KuA}ugEK@cJ$l>q%vTOA5?yKz(VE6b~@(nVr0Yf2-& z$-7`GyOEVTtXcWEGBHTrv=m!8=oNu^7tZz7L=(3WS1 zkPDZ$%=NC?KRWyS>YGcREwQW=&!|cpKA5yqhbwK3)q}aL89uADnTO40@2f}NmVQjw2h$g*f1*Ic2l7S%H%_=)kFqD# zWgd+EIz5qgeg^C*XAFB!shdAnKdQ(O-;ZkW${&C^CcUgit}@K0zelzY*2vCupV=8y z53P|8>6Ve|zlSL!-d_rs5qW5Rj_c`0_YP3d9PfSI*q@e{pASFQWKVm58~Wbavz%G@ zeT?83(L_h3Lgh0G8YT_;F)S}f>NGibTDlw_cQ+s32*M2o`0XI~Erjg3^qUe<6SaP^ z%>BsA@DA+W<>6q4F7?puz($Qx*y!nDB@yzL*-=WQNX_}3@a-gT<#M=eTZT4U=+6>_K;M@h% z{XL}zFD+J-6o+$U76whOXEUEW@zNbrQywq z)w}xMNR#i4`L3qJzs2TVzlp~VhjTJdtSUUOYYofhyqAcz#MP8U#7ok;NY_Kd!&q|gtfP4|QErG;gex`o!>p_j#w#l~ zh2bh|>eO&iW%+G*FCX4}cdW9kTtwC8GE((`Us|f%>=EwGDX*w3E`?tdhnu?#%Hd@a za7%ERtHhn1OlpP%=2hkw0nB_-nXWx@Cc8}3B2}K8HPZw_)wFUZ79Q?hXERxi+sry+ z_Of8AD+|u?a$pBxm#;^tLm>S+98MYRy?1o}$PKo>2nIE_LdrTrsqZBK+)MYFw6gud zm#PLBfOXs7(vfL@X0jvH{+24*-@pzUMEhH6+X55&1p^cC?N8S!gKdAvGji?E7r~&~ zAEZ1|?T<~`^N@>um(4Z0dEVX-`?4c&bJP3Wjn)RR-GTvbp$?HHy6>jk9Q62DP9DXZ zFK+L-=7ClXWSrj{Q?~z9w6`y)};N`aF)Qy=(Sj<=*j@KF2gd zeL6`u@HA@#9)l!v;hcM^Soz+cO#Ikvhw#)RH%1JW(`xU&r&iWixnK$4Y8N^qiT201 z+;juZ%9I^Qv9D>E=Gw|%qS{@9nd}Jl1I3ED-N5yA5Ocd?*W7Mk0={+YI%TkPJLDNS zn?rey*%!f}8Y!f#(;|I$0I;@VllI(8x6h0|uDKogkOVaqk{OInv&`F@b_)iY+YOB+ zO6p^7=bLKqb2~T1u+8lT-&U-zPewnC9C;mlWIsR266!TD?IACXB_43_8?uL8AA}a4 zgC1Z9WKeyRoUKGYBWix(dW5~{wrW75loJT=EpF}uJbw0DH76RwORha3(V`!riHrX{ zC{{JhM{2C4=pd#z{L{|pPlo(69;@|_`{9cL8plY!B&O+@5$WiByMmsq;Se63 zA4H$I8u05nR&8M)fRsBz?%g1A3WP5T4C2|!0ke4Q9ad7_ZKwZYB6QxucCxIY}QT7nRP<$<*df{E}!Kj{a1Lzhhc5?(wsq#+&eoa+hFF2%VB6QtSrtefe#c9ZvpvB zH##BGFPxEQ7}U(phap4g?6~n(uzvh+*0^fDpVxZ${&*l$Ki(Nvq=-kZ4_6vLFtycj z`M!NKz}qphbD{fv=NxJ96G_~~cm1~Ah}Z~|e&;Xfabud(Hp`>h`}Hoi0XLY3?7+0t za{0XUF}exD(2cN5IV(rjx2fsqTkFR+N2+?dc}Ccq9=lv_)cgU5iVB~%hKBIj*s0>< zwYCpwo8PZBM-n+d6<=ple@512C*9r$pG!HiK~BV^)BI+f_8AlJh11-0RRIGyhn0Nh&oE^gj z8Oa`P4(1AN#>nmQlk~FD=xyy23He(Ijr@*2ku}`{_Ge0T**FZ8gIeVchIa&(ePlM+ zb)e$Aci3s^ycESPQ^ROH6$wES<K zPEN?8%~Rgvt_qjntD(`~1|MkaO5^K$(a#a`U&eK1$Ev05(CV#}j-LlJKND%bRpR(L zFc=aRrsgb6%Mm|2O+04h%0+6*GV$wb;?2+jzc8fX3-b%7o)+sfH}a!HB2U9qGG=b{ zMoWJqiSOdEyH2-sBEOudyg_VdQDkjkmkjn9Pu&a*{t3_p;VBj6w-vbN(K2+I>+RhI z;fj(u`S8A+N4=%`?lOGH&SUP86jw}=L%aGGxmBsxsq%{P)-c*LK1k7Jh zPFHRVVs(T5Hh{9yA}`llugE*sml{31IxXLK71c>O@64#*ly}AF-jcVx=>J_SHMM`M zmART>f88G6nuo5-JNF2xv!#)iDqos)j{9K*%lVqgsdAU9ecyRO72bgJ`_(I*xhNz) z@SW!cRpeOe@{T5@Yls|}!kR63>y@@=27C9}B69V+?(YZtuf#AFF~8FRQ;*7G__@Qm z{ur#fsI@~Pk{)QTXceVK=jzJ7bt7V`debnG7#rG^j8HLRZu z(VfdketIiXD}p%mN4|8mQ1!`t0F)Qxh4Y|aT)4oMbJz00N8-Ncsv<3(S1Xyqk~~{l zZhHrKpwWjt{^th+8l=bs?+88qfjwaja{k8B0qxOG%3s!?9>Y(HF3Za=%qbsmdEzT~ zI;qLgY4Gy`t)9!=>55kW8(q!L@~(O|;$c-+=^-Z0R@I@U>vaF1dUE2EECY;JOc4wd zGhYnDNZ=`oVNBcATs^*Z^xlNlS)SVSE{##y+#eihRAx$g#Ph`0fn!4LsU63H)miL= zs*f5)ubhxEMSo24#TWlEqxV#SW5(?2J~YZS6&@pUbS~OhSqJGM^<$cYa|8TP7Te$? zmzQaihqR)1l*GuS@5_iZtMiKdzG->nd46#x(7VxS)*^ptkKl%gvntaL9HecY#%;L> zCt@R6)xj)hPw(O$?u`{!P3M}EkNL8D_lWPMhruL2r9T)~dE7s!e%S3?qT3#SCNGuAau@TSrGqX`KmJ?zJi*@u6<7%NDx&7hfRvb_oOW_-^2w z4cI%3WY6ST2-tU^72Sw(x64y1L)fPBq&1YC9(Q8aTHNoQXR-BJB9gQH74I$SzcXX48xJwVi+eA z>11M99LgWX8piU`h5^DnEXm457zk$Htrh(r?;A=GSO$2_W2EK*BuhPJ`68Nuc;M)lN zY7KllfnTG6-%a3e*T8oY_&YT4T?D>X1K&;H>ooAa1pY1!d>?`TrUt&Bz}IWwjTo6g z9Ht}s{{{_w9D%<_1D`KfCfIBz<*liYJC-4tz z;5QKXM>O!82>gF&;F}11lLo$p!2hQPzLmf~s)27K@ZZQKR5cvPrz$X*>1pX%)_zVKSRRf<%;GfpOhY0*L8u)Ai|5FY8Vglc$fzKuI zKhwY$5%_Hy_zD95a}9hAf#0ryUrXSh)xg&i_#GPf4Fvu<4g4ko->!jgBJj^^;9Cg% zP7Qo3fqy{*-$vj&H1O>N{udhf-30zc4SXko-=%@?BJg`O@ZALdmm2t90{@BzzK_8F zuLi!Kz`v@2Hz2M!?Cby6H1Kf*{#P3K1OopX4SXVj|E&f-K;VC;flnszzt_O05cof6 z;4=vPA2slq1pZGN_z;2rvj#q!!1rq47Zdn*H1N3u{-6fFh`_(Afv+I&eH!>00)I#Y zzm~us*1*>j_j0V1yz#p%HZzJ$= z8u)ese}V>nH-SG<1K&yDKcj)~BJlAV_-+FKSq*$Ifj>zDFWS0${7uln_Y?S&HSktL zv5)_!YT!j(bLW4Y242|e#-FBvPbBcCYv2O}{tOL#GJzL)!r+MH`kxd6|2YkO27y0Q z1D{FYKd*rg5%}>M_-q1ymIi(?fj?UVpG)A+(ZClG_<#n!g211rfv+L(=WF2C68H-= z@bv_Kf(CvAfxl1#zlp$$Hi^Lz$+f>G0)LSPzJgrv`pI zfv?rTcM$kG4g4Mgf0qV+FM+>X1HX^Je^UeBL*VN*@CONeg9iREfp65nA0hDTH1M&< zd&mFv8u)kuf3F699D%=213#X?Z_vOe5%_Ou;3pCI`!(?C1pWaH{44^$Q3Ibv;J>Yb zpGV*y)W9z!@N+cqO9=dTH1Gukev<~igus7S10N>v4{6|66Zr3G;OhwdW)1v00{^fE zej|Z@L<7H>z&B~&n+g1XYT&mJ_(wJHTM7L4HSpUBe6t3=gTVhl1HXsBKc<1-OW=Q~ zf!{~qTQu-J1YYdnz(4b_BzOPlAc22e1Amyn|Ca{-2!Y?Cfse%-|MvU;Ki0s<6Zj`I z@Z$*llN$K(1in=RpG4sQTLV9dz(1vdPbcs{(ZJ6l@LM(TSp@!R4g5R;|BMEHA%Snx zz%L>2KhwY$5cq8x_!0vDa}9i$z;D;UuO{%%YT)Y#{0c1HX^JzodchA@DD2 z;13e`|Ixr7Ch&VS@J9&zFE#M7CwSNYuV~=o3H<+R;Kvd8P7VBc0{^N8K8e7;rh%VC z;D4ooPbctuHSn_t{I50eSp@!d4g5R;{~HbbLIVF=4g3-U|2qwQ0fFDAfiEHOzt_Nr z3H+NH_|*jd4;uJ70^hBHUq|5osDa-|;NQ}~Zzk}6(!e(p_#O@X76Sig4g6LDzh48t zoxuM^1K&a5do}QT2>ja`_`L-F9S!_G0)IdQ-$URJYTyqN_`ho44-@!zHSk9W{CgVs z*b}|u|KBw5@dW;m27VlYe_sPXp1>d0z$X#-ziZ$p5%>=@@aY8pLk;{a0{@W)K8wJg z3eS{466Rq^ZvSf@fj?UVzmUM6tASra;FC1)1q6PA2EK&AU!;K#6ZnZ5_|*jdVhwy9 zfuF2_Uq|3C(ZFvc@ZyC-6xc_#^@!tAU?H;7`%OrxW;(;GIrL z!q@mai@=Z7;LjrPH)!DJ5qR-Vu;2VIB=F*ye!uu71pdn!_yPj|6%Bj|fnTD54-@#C zHSntme2xabj=+m|BK-P)9f8l&z;7h*OEvJD34Fc=zL~%mXyCUHc=1lUU;k|-@Ow4z z+X;N3M*cep{4x#v9s>WiM*jB_`28CAeFR>-ljGO_Jp_Ka2L2#{e^4X;hY5U%2LBNP zzfXfd7GGS!+X&|SD{pAv;|YAJM*hbU_%aRrcmn@djr=DO_yZdFNd&%JBme0HUc3|L zxBku|@EbMqpGDxmrolgtz<*1Fe<6Vnf$@IrUqaw3HS%9T;Hxz7B?LaKfe#b-Y7P8q z0>457Uq|4@JB5DzzmC9*Z>spkZzS+~&@Zzk}oH1Jyp{NFV4zm>qhr-9#2 z;J>bs{|*AbS_8j_z&C5;e=mVwqrtxq@hHsk>uVbPy##-bM*q`C;P24Le?Ni0R)gR8 ztatq$(BO|F@E2;}6A1hT8u&y4f1U2Un>Fkbt)*_X^OZ3@v&hzEIY-s*N+qS&xSaH|2X{KslbS1 z6Y`%fFC%|l(TvMLL-A)2{96eAC4i^+pFsX`5oUSf=3k9?cX&7AMVq%D0s94hJT|^{vb@;sQfo0{w#Z@2>)dQo~nPDME-wC$j;lDQlPx)^#`Y(idQU6~f{Pz_Y5Gea6 zenA2+RPf&jc#6LX`BQBCdkOwuF#Pk8-!=XBw7)Y>pz~jZ_#8$4PXRoY|4zbxzajE} zJ;T2n`EeN&$%VW8zsT?>iXZEM!`^@Wmf+vU@V}1yCq|g%iJSj&h(MKpH{w}n_{3)>(DuLM z6Mre-Df?Rp``;t%f0W_>5c#2davbjd_dJ*&P~{hUv4pAS4;vZ$>4=}>W5pFg}$*gpm~D5(5rBmX4|{wo;#TEu54@G}8VlpqvFVB6Zzl3@XtnmmH!$U{%*p5ClLIvG5i(CuNpss&_F2v--&qD_>l>C%76Ws zfBX0mPvrln4F7iIN5R&=_Zj>_1ggsaT_*pT;>QZ%u#X>OiTuxmj-2ve5&~7_KNawl z|0<9l)aD`9?lyy}$p1OSTLO}B9Qzr33F1}zhks=9Ur*$J9FhMkA%m3v?nizo z9>?L%|17{${%a!mPbc_m8UDwSUp4-`#NfC4#GeTpoRs~q_{879;Jba|zsukcA^s$X z_r2q165Jr5@^7R{psM`N0X$WHZAAHx<82&_`{LKu1C&7OX!GG>}+Wr)u{Nn*n z+22d>pG)wsXZSHkB{)-6yZ!r9Okv|*D&k~S?<5u>WF${}F~i6ZxTeI}SJhcNzXT@ngYo z*z4aV1plQ0+WsZTKh;bn`p3;b4e*rx0pz#)Kb7GB4#R)HPyYKE{vv{Z3c>$A!@t`n z|GNx-E5SdN;4eLw_W!?q@)rS~@_#?UKb_$J3&Wp2#V`+5`M<^RXNn)2hQnU|GYI~x z&ZF&L?vwv=z*F|u6a1GF{Qtr5H~Hj$h~e)f_%9>)k1+hN`{e%z!=EUAtlQ=PD+vBC zpHKTgKHY>Hs`6h5c*_5|1pk!;|IZly**^KVGW;zB|5XJ4=aOjqYkcyL13YDaAHg3a z_`k#OKjD-Aeuh6o{Mfpy{I4PSPrHD&zsDzk0^lk8*Ao152>xn@|4giSs`^*K@b4!0 z=MwzCX85yx@^>=)3F61W{|>{y9r@>* zRz&|m5{~13hQA5(7k@|Emmt3i7M$-^1{? zBEQ}K#RUJ1WZM5bkROtF9B%v50Z;kg_#bIMF5}Jh+f4-j&l&#x$Pd$F$KmFGhT%^^ ze*64+3Bf=4BHI4rW=dKW|3!eO><|3ruN-ul0q;m;-fpG)xno#D?$ zepUJRG5i|{`&UO_zcT<&*&o;=+n>Gv7JYFX`on4$KWF%pFO?Bh{m(ND|0d+O_dm-C z{vh0^rtE(P`5}470ZBNHOu$q2_x{q`|CSK^&oTUO`LurjM(_vWJ||^= z#Vl#2s{LgGp0a=K|9bo13WER74F4wNSM`7041X)~TlGw|ze<9C#bnz4HlO@o13YE_ zZh}8d@c)J3??QfP-i`y3a2#(j{N05AR}lOw;XV;n{-Z9FG^+9s1D>)!p;MN>-TyTN ze;f?Z6#qozSM|T60Z;KKBfq`>T}AMV`z#cHu21{dGyE0E4{Gxe^=~!7|9RM_r1cxikKvDd%{%_xL+~50PeIvV zcZDQYjsG7p{EL4j`R(Puj^JOy@V6qr%Kk3_p7MVa^4rJ%dkOvyhX3+RY5%DT|3Am@ z_lb`U!C~+JHxT@nK?hIye}1M3H&o+K2H+|C<9;pq?e+hDg8w;&e--kp<{#S_{tV=| z+rN?EPlJ65%KnFZ@?Q*i%KmJE|3QNPE{1;_@~h?_YZ?9`!vC8H{(mz3J;<*r|HBOb zCc=L4uAY1Sv3xr1|M)8n^MK-Y9FTwJp;6`%YMF#IV5|5F5iEUYsq{&$gI z)&Cx4_(RBVpMPv6_`k*QCtf8BUN!!$13cyb8p8f(2>#E*Je#sV6Zuu+-|2v-_%|TG zz5cfm{7nr13glOe>d{0=HEvc{%rBFPB`rI@9hMC z8N+{Lmdv9(H(~$F1pl(xwEtg5epUaM z2YAZ=-NWb#@~iAm z13bl__?ZI@9PBr`wahySa4@x{jmfj;W*x9_i$#@HX4Bh#;S@wu{T{Dk3edQ0-RBVO45Cc&Qt^_=qm9^_x5;J*U!l>c-8 zB>8h~{M`h94a1-OMF~{#S26tU1piwE{}zV74*4?__WzLK4~UON!cl{G;r||j|DO#1 zcI0nGyd@wB$07PD%Kw{?zYAjv{`~}h2J|yj`IpR!=H%!_WE~-;Ln48 zj`IIPD{HpoavkZSO@`HQKL$tpS2>!F7pP}r3%BTIG z13YDa3*rBMf`28${|54JSNK27@OL4{QoBSix~bs#hn&nW*tiu|hn?=rws{_jM7d;fPL!T$)u-{sT(?=t*} z;>T*>u#Z3S1phx7e&c#s@IRL#^4Hz}9A@}K$lr%Z(f^-B@P85Pr2M}f`7ekt%M&+$ z5b%`$Gv1N*TkTx%ClLHUW%%Fn$^R6?pH1+eLhzpjJe2)$+0tIs{hvg@Q}!1jzrFsA zBlznX{@KWnB2o%&|JO47t;nB(Na6p}3I5Ll0cHRFNW3Y+EKl70!cUa_-N@f=<4+{` zmofYkZ;-%Ah_{5BKab&WIsjyFq##h(e}Ie}Lf6fEzrN{X2Z}PXRn-e+t2W9>ISv z!~Z7otH$33hChV-_WGAZ@Q+zQ+aCw%ibFO28i1$luOaN8K=7|*_*0NyHU5Sf{td`) z@Bfks{$7TEnNR!w#PD|!{+~$jU$>C>$ z_%|~A0kBIPs{ZdjhQAg0?e%Xm!T&bHKM(m;{a+8m-%aqR5d2w-X#b0PB@R{pcLm@n z|0ldF{crF8(g^;i8UBqv`CA$OWP(4P;6MFF+WxIR`A-HsWq&5YKaJr3GQ+@U&&p8)k*98;x;{B^hg&jFtDe-rZC z`@dNP|0;%m3G%D#uV(mr3IAVC@c)|OuS5R&h~@IcZGR`jpZFe-!C~+JG70_(i)sJI zL%R}(YW;C8;3@yNBfq`<&nEaEVEEH~^54twcM<$q1phx7{>8|zT7Mj7`1_FGUjMEp z_zS*F`~QCAhv}{3aF>4$;3@xS^Z^+h_Vynl_}^yu-$MQ=4tDSUR}aHqMDTx+;9q(Z zZNKQ3#W7Wi$X~bpHv^use-rZC{XdW3{~g0W5BXK?|8<7Ho3Q^nf`9H;X#2y+uk!!Z zfT!$F_#2SHVK4t|f`1#s-{RB%Pc!_P$Zz-me1iWXxWP!RKi>4||0KXu_SX~kFC_Ty zWB8AQepMWsq=@`=*S~uh{x;-qN2Hj4-bnEOi{XC+`Bn4Jeuls15Rk!PFaN~^|Eim5 z|G$j<$(Vmjxb3e7Jmvoug8wFh|6dIMA>>!hKl>T}F62+dj0^uSA^11lLfd}|^y}hK z@jn1~%Kkor{}zJ({2ZD;%_slafT#H5#E<>KVYfe*;J=sQpO5^i`DX*eA3%P4{aZ@# zpP5VBzZ&^f{qJdjr|i!r>@Ohrzt8YDBfo0=d4%CFLVkPyw~XMwFpswX4WIr$5Ac-z zt%U!J2>u5d{#Y2-#i5%2eT(7mCj7sg;6H0AZU01{{E2|4?C&S|O9=ig41cyy{vR^@ z35S6UjzsgXeEzA7;GdLF+rPpm|Am03>`x~6D+vDoVE8xtLhd{xHG+2*clt{4=opEHTPDLHS*VzXJK~?SBQqe@-E7|9LR46i1R2k-u*K zGXYQ8-$vM9L-4mV{8uCYIT2=g;^zN3!{15puOj%rw2ZcYnNR-tfT!&5CHPkp{I4+l zcO$=Q{CkPvH~tP}aM;Jc+X?<^T10aLL zUjBCz{1b|4`}ZJ!GUneB?)G;s;3@ly2>yD4{~HYdVdPh}|J4ltCgiu*zk3M&Lk#~o zSl5U{#s61^zm?!$NANFLPWwOIC;xSTr~JR0;J=sPe~{r{i2SPl=UWVaH&Ol@2>uTl z{@amX)&KmR;ZOJnkilUu|N9C4uY8sE|6|Cn>VIwoJmvpn1_qu$1UcFe_1*0{}A%4#=ktkQ~uvT@V5~Be`5HHeDc4^@V5~Bj}!cv6}0{J$gdjz zE(JVge>?Kq``;}D{|<)#Ddbm;e?MdR`w07=Aoyo|jkf;{42x~kNYQ(!C|le ztpxv*41Yq7tn#Y+505ka*~oAA|5F72S(UW?S;()lKN0Yh{c8#Pw-Wq~4F4+RSC#+W z4F7Jz{$~jOK8F8M$getZ4fPVmnQ)AnZ}zsmpD0G_hH6ZtV2bN#u4;NQ;h z*CS9>|9{Hxr+nn~e>=fHshYNb2lA`x|Am03?5{z7yZ?6*{0}hv`;mW|;XK^+|6Yc_ z1^MmspALfm*9`x7*w+?^%KlDLOO3fli!KKWMwp7MVe!M~f}Pq>ZdFF}4> z21#eYU$_5119*zR5BX~lDf*w63I5v|{@uubUW8emxcOHy{6$BA3=Vtw?;-eKWBA`e ze%1Wrmkj?}5tNed1;3@kP{sm-k*!{nk;9tk^Z$^IA`um#;DJmvpRCM$bXK4zZme8 z{V4?heuDo9!~bue{QqG1Lj->>!N2@=+WxZ(q~WUmw-E4@{kh0*?|k6%mkKZg9H#N@zsxavnt!wuO49Re+~U;D|KM7hzX`o!Z-0jf{&T-U^S_Mzs{Us@;3@yN zVW{2z;+Ak6+GFMGNrpcb?(2#}HU2!#@Eb8QR~C=(zqlpi=AU{eZU01{{3(E^>`x^4 z#g>$t|2c*~8~IiK-^TE#Aiv%JVoB`g57pB4--Gi;PC@8i|#j zcOk#3|Nkc7C6hA?MaUn*U}67p@ZZhW{u2rQN`}ANr~Rc2fBk5gtB{R9p5T9!;XfUoD-egu{|__# zodo|$1pjLc|2*VZ`Tv&;f1;@DaM=ByK=7Y+H(ma{KKT;?FPTib$e$L1{}h71h~ckW zE|XIEKcC^x7$b9KFaL1_|5k>7n@|2H8UD2d|LFw3@lD$QeLnd=V)%Cx{D}nr^$h<6 zc&^n|Bom5KV$?$jhEcM|2FMDVX<_)mi8O2l!Y6p_E~`WI&SjpJpm?Bzd!;Qt-NKMna+ z?eBGlKN0yum~%1yCKLP__t5??LH_25{fh~ZCw=UT*} zvcH+(FA|d-IPCUMBKXg2r0u^N`BmkA8sI7WTan-1|4b(M?*M!p?8Ik|^ zZ_)lU;JGkyTq;H6Zy<6ePZl%yOvER+;=8XG0AA+Q8L=MopMt?6|CvPozs>MxBfqNr zH!%Ed$Zzj|XA}ItXZY75|0JhbM!` zUBKsxMBotqznZZB#|(ca^1Jtc0%mH_KmTIzYZ33RFYfDpCjYr&u?~m5{>&lrKlcIJ z|4qn0JDOGVEa1BSF5s#0uMhF6`uCZQG`~?HiLCl((YpDM1H81k0mLhJP*c&vTmPX+MeIrv2ZI_<#a`FW{;1!@{R1 z@C|^MmO3MDLi=klSlGXSu>U=VKjCWyEP})C|3w7<+y`m#X|ku!O6fWdD-yt}=) zulEC9=G2*RHs;^*zwqC!ME)=Q9-aRtH+HnWj^4k`qPPcp|cw^q`w@?1R z0G_gcE!uCdKVK#6zX3MLsqrTembuQbXCBT2uIqV#r}+DkKNsT*|CbW{|IP5{BL6}c zU%+*J`onbo+Yzs-|0e^U%KzfAGSpuGD~SA8GW^}h@2;=z>r#fl3Hh!1C;V4Q@E>CM zjcVzrxh{XX{Ws?k+JCu-M>8U+xbZImo~r-dh*$al(*L0OExhG_D+6x+X@Hj{WyO%P z6aCkY!NPyH5&ql6@TaVhKvn)9VE8wPn?-O~`4{{v3I0BYKNtB`^UqKd?f-Vf2Sg@p zN5FP2PIolX{J>jdS`nrQ!bq5U-&PuRbPu>YL@r1|@N`u|M8L$aPD`(znv z_x~LP|JND*z-=#m!PU?Ed>E!T(K$ z-}>RBWX!)M0@ex2I~o4P$ZxNI4FvyB8U9RcI7u!(H~(J%9|v*V``>F3?~d=jzVrKZ z`CIs0NZWn{>=$sp2Jq6;PDK;iZ@+)Bp0NKX41YJ~Ki8S85pZ2U!SJ`7DsyG$zmMQQ z%J65dltj5MzJTlcLx#Uq+$@K~&i^ffe_k`~|0bXO*8pBJIWyLFnhdq`KLA0Zu81R1 z3gbI~r|OTfN=C5aVRX;>^~4|0`M2;^{kQM|>jdQ(z*G5e7dQLiXgB}L{l5o^{1-9& z**^21&+xB3L-Jes7yZ{Jg8zAje=YJ~i}|-iz&b&B=3}(~yAkh>@4o&P;A0>y_x%S8 zZ}opj=V?Fd052`IVo13g?Z;+l?!Rs(?0=u(Px!h_M^%5`W%x72!xnJZ{r?ETpZ!DH z{!HY*L1rWJHxN0KCr>f>Cd9kPOZWAU0Z;j_9`kScU(}!fB=Y|%!{3Vhr@Hd%=Ks5e zcg5R{`1Z+8g=p*cqmRjd8|FV@f{ZQl-%RBHDDvCW6zBDi%Mcg6Sy%0G<630-*~7&7 zGl+MGi@I(SM@;zRp775?N~0kCH&K&h%fM)3 zizmKNk2aoQ!k=Wqt*7d3iJR#>#l-&!6aF+4{tOe|#)SWj3E#$qZ)d`vWx{tb;mLA6aFp}{vH$l zHzxcL6aGFE{&yz)117wm3IC7@|A+}c!i4{e3I8_}ev}E1k%O7DxKbPk1JTi*!0g z1UQ`OTqqe3{MyCVU|iej^jUm^ z@B$`$853T_gfC~pOPKI7CcJ_PuVli*O!x{WyoL#1#e}bB!f$87*D~REGU0Vh_}xr+ zJrjNp6TXfKzn2N$z=Yq=gl}ZRA7sKeG2ss};hUN8N0{&?Cj3z*yqO7qj0taH!XIbC zw=m&PFyXCC_)|>yRwn!zCcKRa-^PS*XTo;ioX+k|FyS+q@L5dw>&tk%_X2L^E_!pV*c})0qOn5dE zKA#C+$b{d>gfC{oZ(_oiFyXf_;kiusQYO5B317y97ct@D4vY5~ZIm$KWlVSl6JE)L zhnesdOn40wzKRK7&4l0n|CM(h@NpF9-(L_#fB|DnGfff(glRezTLuEcwm`zh7M3w! z9L^`{WSvn%l4YA}x~MU|22587A*O~<9Uw#yLJT34gyIk&P9R`f0)&uvp4oY3f495O z=}vbd`TXDgfKT_`=bm}ynVDy1XJ=;xzEt362>dL8pCj--fuAq%3k80$z?TX9Qh{GC z@GAv=wZN|x`1Jz6LEy^;ezU-D75MD}?-%%;0>4Y(cME)l!0#3K{Q`eb;13D>VSzs? z@W%zdQs7St{AqzdBk%!%KPT|#1^$A-R|)(jfxj&9R|Ni=!2cldHw6Bcz*h_W9f7|q z@b?A2M&N%F_=f`jNZ@M){;9w}7x+H}{-wab7Wg*-{wsC8K=Y`}&2{4UOt<$>eI4Q5 zuQ#Wi_0^RE$**g!7?S5pzYXXobqboRzT`etT}KGqY&w%HuJmjm$eV|h1M=qKzW_H6 z6$Q9?SRla7BH{oyiwgtXEV>JDvzRQv%_5for=3=UN1j7FpahRRhju0j9(hiIz>5S< zJ8T4xJZCq77Ylrx!1ogPJ^{X|s%LaPTd=-s&o0I+x>G=Wp5aAcZk|&T&_k#5oQS|n z1zslba)DO}e7wLX2)t6@69rCB}78sKF!8IZEJ13w(~ij}540Ji1IyTa6Esf%%q4Bg&9NtrrTR)bE=?g72&vPx^@aHP6{l;Q0cl z)wjVT&)GN#70Gip5%>s!(`wk@k>_j{go@-jn+trTz-jez@W^xgPi?s}d5(WIIP=j# zC5q%ZTM2w?fo~&lyxQeqTy#;yys(zN=SCB6ectqf(0xuJIxxgy~K3?Dx1YRldi2~nG z;QI^w0D<$YK=SE4=fGrOzNza7fmaFqV1Z8(_+)`k5qP!04-xpG04N?l0;g4T!6VP{Kb_>t1(Ch!J@G7Jaiu5i+#lX zn&+5@bbV*@_~F+8HxK0n_{l!ve$8`E5%{SBKTY6E1%A4~&k*>T0zXUOXAArsfuAez zK7pSn@bd+Jfxs^m_(cN0Sl~Yp_%eZCBJfKEewn~87x)zdzf#~=3H)k-UnB5q1%92t zuNU|a1%89TZxr})f!`$Xn+1N0z;6}!Z34et;CBeTU*JCy_?-g(vB2*V_)i3Wx4?fY z@D&2TN8tAg{62x-FYpHh{-D5rCh&&@{&RspEbvDJ{;0qo6Zqo-e?s6Z1^x?xKPm91 z1pc(Ze<|>11pX_54+#8Ofj=kkUkm(sf&WI}F9`g%0$(NY7X|*3z<($3mj(WNfxjZ~ zR|Wo>z+V^m9|ZnKfxjW}HwFHdz~2`5YJvYr;O_|h&jNo};O`0ieS!Z);A;f_SAqXc z;2#M5LxKNY;2#P6V}Y*~_$LDYRN$Wp{BwbSA@F|){GS5#OW@xK{NDoq zR^a~;xVmK@a^yMd2;BeHMEA#P{$G$^PvGkdd;@`RDDZrNZzS-I1-^;EM+kgVfo~@8 z%>_PE;9CfMl)$$X_-KJ|CGf2UzKy{7Db3_cq~`wx`7r|DUf??jd`E%rB=DUDULf#7 zffosU7lDrz_^txqP2jr=yjb9S2z;Et_Z0YE0^eKU`v`nrf%DV3{`wOUzMsJN7x)1J|DM1P6!<{`uM+sd0-q%C$pW7u@M?h{BJe{6&QIm} z>rbs9f0)3h3VfQt4;T1!fzJ?loxqO}_)LM<3w)Nqj}-W9fgdICqXmA9z~>13Sb@(K z`1b{VoWP?3pC|B`z#9bKDDWnM#|7Rj@c9C75qLu23j}_=z*`00Ch&HFcL=;w;3o*Y zOW@rC?-BSyf%gi0k-!%Ve2KtM6!=L3r>94QhnoKv_^ARvP2fufe!9TV5crt_KTF_e z3;Y~`pDXY_fuASv^96o^z%LZ|MFPKA;6D)fGJ#(r@Jj`LnZPd>_!R=bQs7q!{Az(; zBk*elex1Ot7x)haeuKbo6!>z1-z4yx1%8XbZx#4$0Z!XW7QsG>TbpKoiQ*%JA;6)X zF2eZFw4S@I{?X>QFKWKR@_h{dqvrQoKFaWqHNVgDDTeQr=QxFW$8Hx?89qz#BIf}s zzp>%ZYW|?*yBJPS=oC2*S@S{Ym9JZky&hW}FY$1ERX z_zvrn{Nt9homXl8gyn4KlbZj+a<=Ca&7ZWK_4I5&`k%6VHUrTZJpcQkrdX#QKvS^q{Gk^HIvU!eJmmTzJ7ysG(2mRA@) zMHNJm^Rnf;8{V(^E0%9%_{W;RYI)S~9X267uUo#U;ioHJ=y>bfRd(EC1j+x=%5!~K zqWK$^bACTlyimV+#{D__b9a?ck@HqS{!GOS^_!-W<*(85s{`^|ssb%?{$x4(|9s8= zY&qLQOH_-TcLV%X&EE^~KWP5G<*dI#=;K=Z!__y?N*Ex->|1zqHPU^(kw zuKC|BXZ>Gl{!xG*tpZw+^KpRRuXv$;b3(E|pVRW6Sa~kTDO-}BPc7$q_+!mKvwWhf z&e>W8v?AvV%l9?BTJwKc&h7U!&A+sKA0z*q=3iUR_RLTfxXAfefIqDHHw5-5UwBROB^X}+G7=X|}b`39D= zp8sg>?HkE@#;Jf-Mq7D~|CegMwdE?C`glR}Z7pa2Z>Bo3BFEb|lKC;3j|s@1 zuerBxB+Eaq`3_coGn4ML9Z0{oZzS9EjOO0Hk<80f11xe1tsdr=YwqnEImPH7y%V)B z?>RVC9QvqKoMW9q`lCtU-2y*D@gm3Dmy+%IMssgpO6G~3N#5I+lKFF*d;3z>8KY(w zgxmRm;zf?PU!`)FK1vFS?`!>|+^&x&HIGl-?$?`91dGEO%w!cUX0E%G$ zOqTCaybzubV*PJw`GeOr#bMu*URq4@-t&VcM&KO9!^-PdiWk9to1E?rdypRQ`NRUF zr%&-B$J=j{<^QGSz32Ei-L`Qg@9o3M@~agubYg1s>mCK>bHSb@@9o3M@=qvUsNcZk z3bOt!_ab?3e@>QfQM}Oco?m1AFKc;ke@>Pkw>Qaq&qJ~P(-bdqW(55FdoAxhSH=1# zslXfN=OYv^a*nWiW}5uoF3A5y;Jd1hpvakJ^;~T9oTGT5<2@IgZ}{hmhuM>_G8o2p z5cnPfA20A4#fzNT)=pJ?`nX1r|3u3lZRI&%(<79x3R_P&Uk@o>f-~=j|=d!GLoNXxvH-ExL)%H%Q@Y3%Spb;a;{g6nm1d{@=s~rVma4` z@#=>~&H~HX4-Y6_=y=a}vmXu~Px7r+p8dQ+^LEQw&z=)V&-j2p?^C?U>9q1}XH6yX zF3Z_(FKFHq;N=rZzSna0+asDUww(1Jv>(ZzXgT}sam`P*oaGPLpX5)qyxNq@nVK)P zT!m|Wys!Bg0X|7xU=}%NS+2~}$1R$lV|kt7JAIGj`z+`3>el>x%h}H_D_-b$`v7ox zO*)YDTxjLFye`xHV#`_2TEz<;Z{GmcGv^@Ev&_n?;k`ZvG{4kx_S->KB!9W(T#k2W zer14vtohZJb2%P;FzLD0a@PO2=GR-!<+$@ClE1-n*0Wgi<(6}K{Z(_CHF6K;4U(B`eSM za6t2wmb0GS4kJC@{ur$162*(0C#^i&ztL3UPg~CZ>C*g}0DnaD0n6DxyG|oL&som; zFVy^b%h^94Y5s!ceWtt)Jv_W$ctY_)$9vvibwm2tW;&&NNS^uXaD7;$_(+EE`715I z%BIWq6wDw!F9rA##S0zpdGi9JYhx8~)Vz?DXZss9f5mbxmodm8L#=fR$g^y`dF-ZnEp!?FNFOBijDlw z1^HiU{qI}-D~$YCg8XhrhNs&h@Fj|?`75hmb@%#sN|4`VHp&0Z%Cr5)YW|_++)jU? z`9}f1%~7OhZGg|v{8P)h{q}4Ax#iq`zt#L7mRA`2XBL<=k&JYCbB!AJ=@e^|gY|T1KHGAx=PxN9R_7QeHu}S9{&F5Oq z$sZTsuV_9mz{ej?@(q@Ax&KV_Cd)Zr6|E%SY&rYkZp~XPXFa3ZNPdCkT)r1;-WuSe z+DX1Wz|YmZGr&LAyeq)xcaWZ*0Dn#MUduUNP46W6#g_B<{9VmYw4D9ic>>9w9N=$g zeyZi{heQ|2FSVTg`I+WtSkC@j+)eUlS$yVnt1ajH z^H0sM4e;0^(sO-)KdSi+0lx8Kl3yO+Et=mP;7@3NtL0pOwqHVeZnvE4&sCcDTh4yo z=tPpgGr*74{4UGc4=-qbx8>~515YA7D=cS!{z&tCE$28k;$)J)-*T4k(ELHmS^u+| zKVBOJ2Tn&5lu}JghEiW>BrRFbK&gD4n4AQg8 za<=CZ&0n&d{qULQFI&!frk_cAUa_3p#V<5}Ex->ri{$?h;QgAv5#Sr1P4aIAc(3NG z1N<$`-?5zA#nf|1&%2h7HU4=`^Y<<1c5&>vB)=xWAJ_bEma`uw^^yFCma{*f()=UK z*`EiUNAhbeUw0kXpr;fMt3T_VPx7Byc`o16H2>Uk&hNSxko-R^=W;nk^DhJZ8_mDA zob{Y|A?f+X@;c+UQ5S{VIZoh{1U^l1b^T)XM~wcXH1{?#JIL?`LC<`}Y2D74bzMPj z;g<{Y*9!a$~~d&(xFG1^N6Rgxk4|z~>5lzQDT# zev{&4=co-`JNGqqJ}Jn5BJlCc!tJjTc(=fBR$Q%%SkF`&M_sP!<8?v)eS!Z|;OkuC z=66!QtM@abe=EgDn!oX5f{`D;kxO?oCl3|mTa5f%pZsFO&oF!g7edp4~2^biI8h zSx>X#YCgf*f4#Bib}jGiSIP44DIS*Y)|Zo>5mpbUyT9h%e%H+BDNgmdZ(}#XzngR~ zQanumZ?zt8e{8mM^D8LbQ8r!XGc+G3{o}Qod;4ayA3oIF z+c*1GjJYn{p0SEkeQwy?mG3w9R~x>u$;9TSpP4V{ zX%l#lz)u$V=>k7j;1>)03V~lM@S6qxBZ03F_|F8sTJb{IZ@j?xc|Fze3mtF2@k+xd zD;`#V+O)j45BdH^{w~d{Y`x{*zM=Uf%eOW1JNz(Q|0Kl=oheqHuhY9U_x2}0!05SG zb8mlgw*L#wz5U5~oK|@Q>G$?0XFE^Te5y@%lF|RP=H7neZ2#yRNzV~hewvYQQk-=f zq(3gx@<&>E*7FxZe(G}4@9j5UXO!Kjc$ogTwY<0A_$VX)h33Zv(rvtn^v|<=fsubv z^CrvL&dE2Eytf~CyODoDb8p}862t$hd7IV4<#O;Xq{rLGdzO*EMssf;Z%%iO=H5Qu zocDRRk{)j#@2N)5PZehwgY?JyT7IFmr^lQ;?l#in?bpre-mST}UpJTUx0-wVZ?pW& z+ey#qR)3w*f4k;qScFnzgst-4M zp3wXTYY)qhR)Mz=_MJY$$R{-S_Ltt$aHoFu;Yao)TK8$}>~x}sPMb05;AzolZ8SP( z`UG=oa%pw16OHyXHb=*s&k5$U!hDvP&r0(-(R`Mh&xrXfbE0#~BhhGgPpl`=7)`V% zdJ?hL#EI%#M|(8Z-V|+$clUHHY}DT)iG-4$Gkt1BLq|t<&xBZ4V@skp9^pTt@x_ht zP7*C&)Dr8d?yZhYj7IBbR?nJsO!SZ=r%#?$J7an@8m41>Q@kgZXpKzl>`1it#Ji#$ z-SIAMO1!IfdVNVWQq~h++!O6EX;w!n>SA57wz!g=8Sh@$+M`H!tT!I*Xjl+$?1^^v zbXCusULT1@${S+cDsT3ebyHK>m7KNGi2GwV?ar=5n{rTZytclhx|~w0ZV^*v>=hVCZ)SERH%-qYC?Z%lNnYC_d%da}nuD%0dhwOf$ZuxKOY zUHy30?7@Fdaz-jLzNe!n*4nxx+R@b%?}|4?RNabl^^KG@w#K@cJF;d3%=jOMl(LPzGp8=V@(R>7T{(R^N=q6$T3c0sqkMHIPIL=juBvU>WG*~0mB}_ali|Oi z%(l6i#aN;m%FL-cM)*26=0gTU^_uem^U!+MW83YznV+ zmAXr5jy0;@!So-YeM)uttd>M~QY-Me-!z8O392uOw>QPzNTK@8<_=xUROpD*PK}J8 zY&)m=IHg!UVZN&7@t%ZMKC3n;0UqUe#4Rr}XkQpiFH&M+nX)V?L%C31$ssDKw&z0g z1k+@5ZgQkNK>@0DNn1x(XGg7sA{3d8p_SB!z$Se>JS3M$S`Q3Uno+S#`0^3{Lt20Ve8g`7Ft zZ*;Dl?bn;q*+UGN{xp06JP`7|p3IkEqS+r~)J2XOVwHuAyc2Dmt+n;#6gs&pa|advlqc#@TVsdnZD~#`+N35!RPrzb zFxVthb*~y=)lHpM64e)ap~;lGgTv%xqOqpdtdgqlDesIWx@y%`ez1R~eCsii`lk#A zN2aynJxi5=R#h$=A(y{9z74;^&8RBq5k~5& zAXY+kQ9k5aH?_W}R1Lu!RLzdZ)g+awXVHY3p^T}yv5-+wwYqZ9lRKf+D21OwDnKSS z>p=#)N7-D-CWqLl#OWqtdAf?GtYq90QnVqjC8X3;9nvT&v}sA%T#!l2RaKJ>#OV&PsZv!A zF(Xym%rruV)x_Znk%Om|~tugf=|4nuPt_#K{y6gxV3JAgnap`kGI;<|wCRe5`20ls&>D5pZ)G0``};`54Vt~N)`c8Ui&b8ai~={sqFZJFE)Hr_3DZ+0&`atja?nx z-Q}cAjVMY3x5lcg)g^Y)JdnCImc#VF)08twth5BOnVE<69FFf6V|Dc`<;D{1Ptx?G z|7KFvp2dl|^da22rrq(*RPVsws2u4hC@9J@+$$`d*Zyw*9Qs+g5OGfmIe)`nDunWi~xB^(l`ePgvDbnp#;Prfyj31>-b@V>C2$bg3oeY<>=|t&)q}uP`_vpr_f@w5HE< zVP#vLQ$zi&BB>nxb`N@iG_>)8FB!E+npO(ZWX7P=AR!65w~}dbSd*$9;}h+@9mlKX zhP2Rcs+yOOz2}?QiMVFC4@an5v}!%Bp7IP9o?If?WhD*U^&=H}Ie>q{E$A72BVH~3 z#pzj}>m%tccT}|$*K&r96Ln%Ci#Rh_^O!{{JlT`>ydf-E?2MEh!$i4b7*3;nAwJ9sImBn+0e#6lj2%D*rc~0Rv*G9-GO%GnDjSB>d1R2d z>wuhgE!m_Vyr`RKZ($8~57jM4d0pT5SYxAF#*PZTTlawxOYoY_t+6SW4i2YouVac2 zx)^aVK8Z@BAaMnCJ9-q0dAX_14$Lr`hTjw(ln`_o9H zJBke2BL}mR?4OJ~*`Pwd-PvBDWp-;rsJ2-=yHi?1j}HazmBS2)&uN+Tzaj2R+3lye z9?ULTU&kJnj@+>ab1{rvw~$!QuigChP8tFXsrwDd1az?BPiYBDySZ5G5;K24m1d_G ziL}Mr8q`7*3f8ICvFkN?f-z>KL~E*2^s;6rh*C(9wtx_GKnqI51ihN8mKaT~pO7M9 zwKYMf+Rh;AraR;m)9B>|Yt!re(=4#`l%@1t8aerHQt|rCK}RkbXDEyC9Gu}43bwl1 zT~^)E-nzuAka`MlLT;|qGB70#12|{|cU{RKonZ{}nOc$K=%0h+htw@(k}mWYq4!zR z954rm>&YWRuVrR33=e8eIV>EmL~=7`4rV6VMZN%&#wa|fF{OKkBY`wrlhKGWBun4P zNH&y?P?=1R{?MvvFa{uIanXXsUUi@6wKBhac+SPL5l_ zFjj$7d%r~7yY}w9bEH)5I2BcU=f&C@TIm`*I6Qaz2XB_tSCjo)Atq~dpET$#iME%O zM$_Npky7)`tA*_0V>X0TOIXwndvWzBT(jEkG32K?Xw4by1E~y{MHwzFkNToYNEX7w zPYOZY>C6Ph3{nfdxf+&Ql3=8wr=_c7k+&0P(mV#&2k*3=lF?5H>GeixZ=;SzwWi1u zAQuI0oP_8x3zl^1RIct-2MZ3mk7l#33(8~eRBEE5yS7n1-x_IbiP?Q38r6g5RBd!c zt?yB*9Ku9q(qpmwAd7kqKh{<|E2?Iks_Vx`^%Jx8umL5dTHn#yU9HnkwmDLnv>Akc zZZo{qx!23h)cQgnw#s0cNTu2ut4A&IF%RDQEJ_LoI#m@9cu&%>fS_$seSFGwGMS9z zo2w(fbdv|vA%5f-n!!S-=ITMU%5xNH<$0)UgN*VV&nU=RIUc6HG>6vyD0PDlu+vtk z*7~HCRv!dc=Y?GBc^8j*_6}{8 zZ?^=p=ngu4mytfz-q$oPQv(YNlT7!GHMtU`adX?RcW5gQ(jC(9Pyu&y_C{O&0aB)e z4b$1DsXXJ@D5=k7xC~7rbp%bd;yII1OlZ={Lypj-1U(oh*zuQY=T+YeA*xz%@Wz*XhnH3_2k)gq5i&?HcAq zs)MBMHJx%=uUeU6LTCuAjZBQv!=js)XDb=JmD9Mkws2eu-dzudWlpjzg(JSx zUWyGGKbS$o-ea*P6+^HjN4*!DkkT2@lO>N72OS8j&9&|QUOm8tu8NymrqjBpGufO- z#sgQaE0+UOwMDXS9NsRQ51JOJr$G3f zwmEQmddj>pLz)gBCbdHv=13-UbR9x;k@|2->c8}mj<2GMj|It5FIA@g3&RgvY&njU zgJv@%J&qq~&wsmjq{7FRI%5!BeLZxxuaES-ur_zOQA63}ci|@W5y`n=hh;nu>q{ay zvpDn_5uUw{n0I>*=iIfB#&CG7R7h(WTo)-fuH$!G=d^P9l@Eur0y!WrW%$;V&QATx zZM6#2zVS%C$g{C4-lkq|RHybc1y1i%(Qow*mIgPGEH<~VaQB0=ucOub+v@=Dj^1c* zx50Oumre8U{#L5*K=Nz8)%I`MC?9&h-7ZY!jfQ@D4?B99+F)-mkh3{-OYq7?y)7k} zgxuSPysTgtJ6S2UkOn;T09!jXgJih+XVj&J>4%;))pbh9Pq}dZ8*|4Y<_!0hOlXo` z4c3=76LUOM9GYg@*E%7;PVd5EnC68;>`AN8(lgq-$Qo)oL%KXlJF#K7UJ6ZHynqVZ z3C@I(T+I1~8soJOeMJ>!0*8_Gr+PzE8ph}^UGm6wPpf$_tg)lDHQv~h=x9$h3zNYnbl(1Z_Bk72#gKnkHjy@uYE3kB#k!V6d*fZ* z%BU3ETXTICyS-qwNP1PL-ZxP%rcT= z+w>lyfmWKz1b2TPG9*VOr%gzsQ%kQKNZb49q_muG-=Q(+JwjAHh&>^h7pm=`YwI&j zHPdBqO22v{P+yLf*S05m_%UWbcOT?dkE$<9G&Ps1L4AEsnflU1LDBuQx!F-bKczOI ze)i!<_9R*(Ws~WBinC*_3AOuRygE^*>V9uqv@_NfYm2Lwuc;rm$7uDEdQ+U@`t6HR z^@d6kR}HpqY9ylNyE@c!xozre^3M}>P3pH3NklDjP7Erqgjr#{Dbc7dO!aTu)CFm4 z-PB6bLl>t?Oug>3v11|a^{$_WRM)Tm=OsfPhHO;tXjWG|>MhN#2K7*JYsL>!s-L>g zP1YSUv%aG~sy8UG4jn(OBi2;k7;B9mqTb!s(bZjD->rYq!%rY5n!DXcGsB+X)ce*$O0GUu ztDe!VZ*U*DRecJ*lYG3YYUZ8f_1&sy6>=*>_jq~>e0vj>l`e#Czkkcgy>8u6cOF%} z*RvR=Av9vUpx<+;7%h`mYkGCKuuLy45=@D-wzO+ud1|9#TN2;4d{s3w8|>EGtzc$Vye4BMysRw>_p z3K{AM_e91kO6t4KE&K581k!Iq`a;I`1flN9WL`kom3n20+vDUS9pCke?#Yt%@C3;lMX0)~R<*%QRE^i;@L-D` znDDStk3v+iQUehhujn90f23}$8D)|t1cRoe$T+()y*}GK)JU)J2}=jZHt_UTy$STb z%M;x;+861kGlE?J#dW?KaW8Meem*_;L-rj%bS>4EXipw6_d0EQ(-|~+q8?ID zS3~ydI{)=fyo;{K>{u-_LCemf3#&x?{3*13yxx49(~V3}&tP@OS>TXFs~%A{(^Z1g z-P1(+n$;#M?LEzoew9|Unv-dCy5jT>HK)0|G1lJfXq4#g?u<3YorUfCYxAP6L{Hpl z)}v@;k{YQ+O6aX!i(?Im-bktXyE_qet0O(nqwX{|cTjDcRqqStAw#<0mOE*8dpZf9 zEsoV6_;@T7_VhW0^m4^acc?T`v zOy?ex{PNwT#(B%!V?%h$Zc_ff!xS?p2Q@L2RFnLrki}M>Nx9FpUM@$U-XZKMn=1Rm zx&37-_vAVo749Z{{MJj@XE&u4!?@LEDzB%pFL#CiY5r9C7_vUDWJ7AYFx;ot|F-tH z4UGpEIn^0Ri^BLU|Jat>inpU=sMkU^wscDiH_^RR9O}pcf6lPa|Av=sy zwzDfiNog<(&J~V(Y^*+B%QIip$F=6qb=BvqihuJT_xOq7B>x7;-wX181o>Zr{A!SY z4&>hk`8PrSU66kV}^4~&!Ujj}(U6=k*$E%>{KalR`<~)@PraRhj`uGykoecb2;Bnyp0e&uU zXMN9~F9BZ%_-vCGI^7O-o(Fs*veo?lE`k5b$440XfBHD<+16y9#8CepKF)gH1CDln z1N>|CH`kxNR37PI{UeP%6M_E=(13v=zE2_?Lx(k3~{l5+PCZOk8;3I&4An z@HUV?5;*!{0r1U1&r;y$Lp|v;T*n6`&&Nd|kLB__@R6YZWkJvDAdh;!1il66Sufx7 z!zkbd0xtuO{+w$#*Z*xzdyIknmY~1gC%>bS?-u0G1&;o|4EVO7e>w2cz<&aKQ{WE* z-x~O{0)JcJp9*{(3OeebY@+@#0^c1t`gu0+F<|G(0>4Ax_Z#jnub+cFme(^rc`mPC z3-T`m$MSju_>N%zXTY(%95PTHz)u8@<@FQb7*8HC zoIWV)g{JPflmhhIdClBtw(6{wf(O^eBK*4%I^mp?VJpJ3Zy#?IO@L{_#q(wsK77W z)U)$Uuye!BJWl0aZpyvKa4I(9RfaDCUZc|G<5bXto33$h5U{i>Dohju>Ma0j&bq`!`c41#?P}sek$m10X_}* z2|hi?89gU~{NW&fHt^}d`+?5@{x9Hlz>Bu<@{8@|aDiVZ@D~hcKP)!(zXtM0K)NGF zdFjpsUI@G%cm((?;FApJbWb+vP6K&Nw-Gq{zs0Ag&*;8(1jUQ>H^+&XPd`UJU7%-IBTqJV14sEKz)g0w zJtqTa`~CUC{GOxa`9S@PKo9Ca3;1s4hh*mk!1o1?@{*oHkiQW0>RUps#CHsF19OKN3z%d@atT@N{9YO!^K_256USAA{ zo%;C4m%ajdjL%r#4h4A}_ihCG|E2Ws!Eut(MLxy|P+a{6(%s8& zlE?d=5s;^QOkDptp8NIh5Ay#8`6|On9`EZN2AphKW4_NYpTzLKUYp_mbh|*FZuqgC zX97pR^?@GDFUNmM_iM19$N$9F1^qjL9_)9pT-H$4PpaD0gIXOvJb$kQnoT%UvGG7{{>azXvsmdkQevC=6Q zOgEcy!Te(U*#h#5?NN$9TY@~6<7nXN#GkD|9@E_#IJdi0@n;*5&nEuR+7j+(@j45y z*Y+{xM)r&V`GbIO2YhGXV+6iE@a;kVMCh-_0+;4hb^twGZ^_OVK+j~*vm?l-6K`>R zI~?)0P}#!=mpjE<-gX@~<#gIL<|~_ajrqlRTLAgR zb}GeNy#B>_J60$cRF5fgUX1-GQeQhl@cT)1@_a91poYri#PkKwgT&XwMT6m&Tg%A^m%T9*m!R34CvX z?<4Si1zsZX2=Hv;b1CTI>nzG|8E`Dea)DO>M}OjYdo1{KJji4DP5_=x`Bs9wRKDr- zBRDTH9R0`v%1%BwUliw&rxUMmeKN+Y{lE_xuTX!s@v0<)egxCaCSGBFF<$Kt`NjGv z^&>cMiT%hyLb)JMr(E6@`uFdFomeiYKihIyWhz!W{RpO;O}SuxvA;MF@{8?S>MyE5 z9?S7y;OWGZNg$8uP6p2HE>(Xq1>~i8VwU0P`+7K@!FqBi=-I`T52br4^e@GRQyi#K z@_avq>jNzdt5uv2o}VO6>GCnn{6YG$zy3b(#gJ|%@Wa5)Q-I?<9=AKcop?QhdeCpu zeILwkrh5K=^FPL`Iw*Ip&r~kRu^vkE&-mO5_9N4wK482;{ain(z71vmxh8{t1k=qX zUSWPQUe!Z>*>BXo$miT1E7ad~5dVe#%l(J1uUWpxoU1jT%=a_j>wWxi^PSr%%SR2L z@00H~-%s%Iv&{FCeEdf9{cIn<-+cdpk8|Fx@$uiA@3;8)hvxg8=9B6n`K?OD8ag-~ z=J}@Ff9{^v>wHLlg5i%FPW1}c9~!Ku4Ogl!T>tXT3Hmv4&M%i6^J*i<{RngJFAL0h z=Es=t9G{st8eZa)Z!_O3eSDGmUghJbo9{I~eu4R3=i^tH@4PO8{YiZ%9X#)CIT@^u zJ>3uM=T5`fe!rjD9^yDZbDYsb{0^ZXxf3|{BNL&0;eEOjlsx;F`wOxk`4mWZ4(OQ; z9Q&8y)^C;#>VE$?u%`&@`2qNWuOld5bCo*xgNLEZ}-#{)}&cR;!q18)TVw*hYg&ixnJ*$f=(XAC&XW86mn$3Y&) zlk)}MBJc!ojvHjBbUnKOu0{y#0Rd2%|-MdnEfi1bL~xodEJ!-?{|eE$|-T>D0G{AYTai?FEkcmFn9fkmvd^l=`+9^l(2# zdfI{S4R#_wP~bCwF9ALCfTJEB7x~jYLy*4=IO@L@IO=~u;5!395$r^M67cO&9^&U% z;L`n+lR*!U&ndsyUrz=-r+|C}IJQ%i$99U>mDo;?1U=YJTLiukIJVPMf%kwPE&`rT z`^ETq8sr!2ztn!0f;_h0(*=Hpz|RDpPWwFzjOUkuofvN~7x)#xvx&o3f}V8ZFwNufcpJ+X%MtyF{!gde zuLk|ul>0THXE^M<4)kYZ=k=iHe=S~Nzjmt7uiXgtWBE#P>;^$ziet+`9^=?e0>4?{ zw*XHkj@=6KSbuH0{$qjPCGejB z&nEud4SIHh{QeX;mir2U-vb=|iRCgD^xq5eSibiGPp5qE2YIP{|JT|zjzfM1_G5mf z_WPh9FSXx?KpxBS=K_CN;Ew=Lr+gm;c`V<@fMb5Ko?!cZ9OR|)MSFfBwBIK{54PWx z0{?};pA`600)JZIzXYC5`+WxVVEg?Qa4h!$fjFya@J4{*?5f zoiBl&|All9f4*_2Z{8dQzH^5QP>xOf_ct6dzK>iWX{{iriKtINfkAY`X&p!b@ z*nU41_-DYgN%wQmlg|9f7a))A?knJXfZx6Wj_nus>Eiq2R1ddW-8@!3Y8$>NCc-GJ#hJd_3@U#v2nr9{c@D;AlUNTW~x{dlB>eHnvBU$9x?C@Xr=$nV z@gUG+%+c%Uj#8ZaqkMCMhFeD~&Ig|-ehhFvPkfG`=U9;EdPwqff%Ez=;@=03`e`p~ zwgc^q3i49Ecuz#q&H5R|CjnzHnb4%vU4Gr<1QHkjMPSfusGes`kPM+VeZ$ z1xA4Kd#V~2@qu<;2l6FGfaI?SUJ3k%z^j1Y0Nmh|^{rXR*L>jUhZf-IhXio+1HDIp zj{@@tRybAn=`MnY3u^sVROR^o?(M=#l<>Em)h59U_aKwrNB`??oWvIc@@}+dR_sJ{`nnnEXN-LNB>*|<%|Bg z7UZi;hN+%Zf&DeW`#`=9IPKHU$I-y|0FHjZaq0ghKkNhfML+Bf9Q}af=l@H7D1rQ< zANB=~e!%hk|0O?^LVnQ?5#Z>D(}ANO=sjF~Yzyt{PrwU+?*#3%82Gs$Ujn=jcqQ=j zfL8%OAGpCO`-?M#d`bP?nS#93-+d1D6o8$d0!Kfb4LlwD&l2p(w7)wW^zd^@G=JL) z_OPAAH)P|~XN~!rcs}qJ;B=0UKJy2$O&F@re&8d34*=&mJwj`M^Bg82elC#oZ*FAh zqnJ7nbr9z|OyBwWQQ}(=Fh>i>k7B4k`+&2r=yX5u(I7tnoab2R^cvt>gM2g#5Kz0KCfko|k9egHVH*`U*Ffb$$O@q7~;$!`Y`Fh?=)?=e)L zHNg2^A)Rgkeh|p_0j~ny5By-@1HdN%UjuwH@cexD3)w#fcroy5;5EPx0p0@qP~d&Q zYk>Cy=X?5edI0!gAioAU-%F*_`5U=HWdAhxPyKH(@WX-E0G|%L1^5i$eZcF0_X9ry z_yF*kz}En;2cA!ctAjpf>A&26ih&;qyaqV05u(#Az>fm?KHx_K?+1Pi@B!d+fUg05 zEbx5OsnhAXz>9%@A9xM$k^tG4M8!uL0f; zyahPvS!2%i0q3y*o$3dEf{~?<0pO%Z56IQW8sOc;&5>^gb7X%HL-knQMgf+l> zLB0j}BH(?%Ne}Ns)en3L$ln9}MBoF!PXhiTaFQQs&aDA{GRWtfK`Q0<6yRF`Cp|o7 zDh7Tk$kzbpH4=2X1^7~s?*o21@P6QD03QH;Ch#@D&jOxrGEVtA8~7H$DPQBvxnkhw zfP4fv$?s>*)c`*ik2DuQWd9Yww*yZ8~|( z5je?nY^?)+707o2zZ&=w;H2jSb8Z>%Ye0Sl@N0pu0)8FvwZN|jK5|R<3;E%Pz)OJN z0K5+PjlesBF9*I1_)Wl90KXadD&V&OUkm(J;3G%7U&#L3fR_Nj9e5q^JAiir?+3mN z_>X|E0DdR%Rlt7?d@b<1fR8j6&t(5kfR_Nj8~8-vR8Kfo)&c)1$R7ioWoYG~RMsDK@QGOo-`R#y{{D3)E0-VyF zXVR?${sidh1in&nN{5bRz@KuF{&xlNUn;`#tAIZPd@b-_fu51ux?kw`Y&((dfK$GH zPf#5tz@K%I{R{?(k_*&q<1wL{+_Y37~74Q<^F9NRv z{u1zGfRi8IGv_*izYOxrfV0o&^a|jwfcz@puL55S{59Ys$GBf8U#|l%0saTzb-@1! zyc75vz?T7k6Zi_?ZvkHg{B7WCfv*NWa(nj++5actmB8NtelYM875}F>cQo)ngZyIP z?*hLXIF})vehB#cApaWhzX1Od_!{8b?%;l*eEk)8CGfuiKN|Q4z!wAm5cui9$qyTv zcycxHzk~ckz&`^18t{*Se+hgo@NLb2pYrty@JisH0zVq~XTTQ&{~Y+$z`p?g5b%Eh ze+@X-1v>pD@Gn7r+nwAmWdB#dD}jFvd>-(B0bdII8{o@<{~P#9;NJpY4g5dAot@n; zWG7#n(w_yu*D+;Id=KDMAGR^)s(`Nx^7DY_0bdGyJ>biMuMd1B@C|^k2F`Vp>~sqB zzq)_Q2l)cv8v(BZzA^B5z&8QD6!-|>%YknSd?oPBfUgF=IdG@Y(Fc{wNZW1%YknNd?oO$fv*P6bwL|m`@Oi*@0lpOYSm4Wn?+Sb+ z@ZEr~2F^a#mXG!9F9!Jn;CleC0zMA-Jm7l*UkZFL;LCyU4SXf=eSoh9zAtcRSI>T) zyCPBmJOc7nz)OM816~GvDe!XO%Yjz_UkQ9X@YTS1PgZUDZl3*>AYTA{BJe8U`vIQ^ ze1G6efgb>TIq>fRUkUs`;H!Zj1l-x(v%d;>0q}!?R{@^{d>-)0z?TA_0(?2}YTzq@ z9|C+e@I!&~MyV86`I?M!R8Z{Ys}|&|fFA~Y9`LEamja&#d^zyLfv*HU9r$YCGk`mL zcy`tSF93c7@G9UlfzJb84}2-`S-|^&ud7U0Zq5z(IKRhyjgPNOKT=2jIQNtMe>CVX z27V0i8sMa2jM3BLOBEC^)KA^`hb&)Q5(AQmjEYu_H{q-IbhE{z)5~S`vExV zpOo+Fe-SvzFEa9LfRp_Aja>QsJ>AcZ)d%sph8O$z8HPuIlm45H{ufod4{%ENx8~dc@F>Wy0X`3S{$A?G>frqH{kbiGlm55OZ;FA(Ku-iX$^XZk zs{!5s@<#wC`OV4M>SzJp2=aZvn}GKNj{_e7-VA&VaIQO)ZvNi%uj_{vkS_+F0A2%p z0q_>!#{=&J-U_@QcpLBm;O)R)1Wtb2+4yY@@D7mA-$!Rlmv1NVV&J5rcN14G0-W@h o8~ruF2{nvx z69Y=E`lgmDZBt)rsihWq^IFu1DNtX2Hm{|=sim5>sg06XQ>B_JmEV~==ia?Ldrs!g zCPCkRy&uTgz2`pjoO5R8%-p$u_O?Lo<)cT9^4Z%c-^ISjH+!$o7p#ix&9-)D`=*V_ z7$f%n5&j7IXOulC|AO+bDBnPN5M>|Aw@|)~vLEF;DBneS2<6{VzK?PM#=^HKW9ffi<%41L_pd5qpSd_=1OhkDC$`et32IWa8lTe<5ay-gYQJ#kKbd;Y% z`FWIIKzSBQKgutnJR4;S%5zapM45{6e3X+=PDVKeWg5y1l$j`}qnv?qCdvy@&PI7L z%50Q#P+o>Ifbw#bSD*}{yb|R+l({IcLU|3!Jd|HSIUnUhl-HuX4&_%--hgrm%9~K; zqbx+Z6lD?0Vw542%Tbn~T!FF-?h$K>2Sdzm4)cD8GyH5tQFU`2&@=K7+CyS?DEFg$ z8D$sBS5O{6`6|k8lz&3mgYtEhy(r&A*@yBil>I2*L3s$}dngA`et_~Y%8yX`j*>C@C{IF}gz^-W<58Z5G8yF=C?}vi6Qv*J*(g&`PDGiCauUkPD5s!I zLz#gx6XkT2Stw_roQ?8gl-Vffpv*yeIm#f&EAewK%BxZ4p`4F$Ajxr17ER?fRUW_su7>*kniE=0hAx0{1D|~lpmq=jluIKl*gbPgYsCE z$DvF_c>>C@C_jVpB$P=gPeJ)vl&7LR4dv-5lTn_5astXPpga?$ALZF7&p~-E%84jb zQBFcR8RVj1(_e!1eM!Nlbpy|e^W9$Y=U31FU)sL_97qNS`h(5zzy9qy%ZFfd0KT+? zXMtW&^jbR)PJ*x9!R8y`KcNmb3B|f@SwMY9@(nT)BhN5c9W<>w+*C7AzwYp;n)7d8 zH*n;L&sXDb6ZJH1hp(Z%X1w)zw{Mg*y9ugQRN+Rf!!!s@S8z{YK;Ss_Ve$Li&RnYT!Q>0~T!sx=u+K z=!{sB_hZ3!s};YVZ+z^(<4WYxW2yp(UBwC_9|o0RMQ!3 zhX3`uvqc;*274?<;!E>7IMf{~cLXq0H4rXWNhb&cg#%7BKpj;|Osswk0q#OC7X)wb zONO(ZVAIpR{{%1nP|~wW@CVC$x*zs7?Q$91{G>QAxWUr6kFq`={Bp4A&Ter)^LH)b zKCVgbYJOU1B=q(U!48eyYCD%M6z$#*%?CP==tSAI!8_Z-6Pz#5Uh3O}!R92nr?&RU zOQ@@KA6OZ*4or+3SSb#KQtiGvx2Z$%wdwh1ePD_-t0~ac^h$2i>yc1f<}B(8Hsw`5 zyV!}3)wL}{D}znDt=0q(*_#iZDH<{KeE9EFnDwPolE@;vp~%{(VkE+`tG=-?4USmTl2d8^>2?7`QQc8EV#YIt|tS7GmBi^j^0A|qr&AC@`Ns?PSNBp%ZzLI{`~!1P&!h{;QcvT!@v z28PC%w;j!cL)yW_Y-k;pt4qX=#yru;ELRr```g^E7RQv;=5qD0FkAeIa&@05r60}C z6X`0-Y|B>~bO=EU0dyz|G(O72o#I<_b}{AaPQ};cHj&6&eZCRCLj7+GHq~r_YTpcH zZ4;dadYfQ@&k!H@a$K-}-4|cuGEVE_v z4{UDs!NG6L0wf%{84~?i$nrT7wK(zJan}d-2CcFHn7wRV>Rw18wUBb(8JA>9tFU** zoosyxHcQcT+2Vtz*p^ylz!BMt1w(UoQd3~x8;`)`3JE8ug!|$lOp7MmCkWH_1iBz= z2qK7CrD#(ivx3c6bv7@O`5wb`0A=@{K)(pl8xx^Qgy9FEoIs-lLOFSfVxG_ve6IVL z;D&_J5CqqbV*;J9!v{h7?{~&6=>)k8qq8{B_|CZNMZ*pp7^EzKPO;kQxNo&v!)?ta z5jt6VA~0Boz@g8L`!_r+85($?8~%Jo7!RG<>gL@C^9Lb|DrxoTgHu&1$C~QV2T!93 z>I3~E;fTiB?7J|~KknYWF#I}u-W@k-uK*r^25(tpJKqd8N);F_Roz$vJ$nL&gcAq9 zF2dg8ci}n!Qjp&pj(zhEqQq?fU7d4;*s)bZFeY z)zI9V13h+lo9+z54)|tCs|3+4>@a|5?a%_iuTE$HqRM-eISgd`$dDbYYYyxqD55~{ zr8%%ycNA6h0UgLHx<_{uRdlxw^y~yX;=!ipgH5klp@WgMJ=nacy*Y58X|(*%(=-PL z4za7dX%2K+@o8_<92oAzr+rOxlEfzn_?G7E>eVD{m8%Gsw#AvRD{4AjS2{ zYJr)GHR{R{4fi>tE_~k%)fu#U5eyBo_lV3Xc4vaG_S}of;67phF0GhTu zQq;Y5WC9$ycU=9?Kd_G6vO9Y`w4`<0EQ26Ni!9$9Xb9fk(FmWMbBWvgMAL^ko=B^~ zrY9>c@j!_sHWUcaEOpN8)BbLs+tfcTK)!Je;@V8G{%L{r)r@&VTmrIl@}BHkpmBYz zlwYyvx9ftD_-82UV6I)vc zUxR4S?(AHMj;-;5rXcb)4~of)eBIpMG-qMtt0)Er6Kky5oxMaUrkHDI&=}BgFtJHw zEik4j&;~LOWIM>kAfYeA)qh2fg25FAupQ(0M26^3J0g{rCru(G1G z98mtEit=S;rA1+Y6;-UPEDV<}EerVpSh_0YUsh4IvM}r`tg0%!1YtBOkCC|l+`j!!A6tn@7_EUONQn6bFxP`I$P?1GAFAhTjuWdZZ^ z%WKNY{9nAtZw-PxeraKKX;FSSR2$B(sH`eo301HvWEGL-zvv==sekQSf4cR_S5#3` z4p9t;R_5C=7GHb|Lc)ppq3W8laP^dMZ5ZtR+C`5&3;!=UVUn`>F7sdH&$!7q*&nK` zE`>14ua~Y`?hlA|Fw5`r`xk_Z{W+mk@HsD3RTL@@`&U;%z~Q^xx-aqh>fpam{I|AM zrB&gY!ZK0W)nR{8NnzC_zZKwFvoONWhe(KL&01Yj7*0K3qU@qbY1OV;AQ`*a*DSEw z&Be23RTr)br2?qzeE$urOT#68RDsLY;o@1dBpzCUXlJv9(UYY@e9RA56_$ppt=$*< zFTRm9%h^fVC)>uXS=bZuU5#Y+rLx^k_Af+3^DCCF2o;6%E5lX7=IXE$uvxS0g3w@$ z=)}nwZb3c?qllhj@!+XimTYQR1kl4Fd4-S)LeN)b8@kb2l@}*M1NO-u$g2jHja&Gf z*lVRA81(yLubqqR_2Z@*v0xz=o7_1JCeQ<7==KFi?UK@(d=E4S4#AW=lHu?ZUJ-DY zCQ1-TkN(y3@~VNzht^UtEJL?PN)Y?xH?ew{YArs)(uiCGOb#}~9B5rPtl!#GiVZd0 zVu|I*Z-Vt5sW`I$kX1IUdnCcS2h3|MiU_ZjhZl)s`h#$K5MejBpTo*rkD(OKOEPfZ z9wQ>2TK0lX?ubVp2d4%;rw&Bu0|R@qlSPF%$MphZH?012fwEhio+QGDE^$JVC{O(x z14qW~2po~?@|o08d)JH(k3RT0RM~i66x`vnM>B9t%u=CM`GPZd#l{*;m6hjr*Ss7F z2f#c*(+^V6z_Nn4U;vd8=shSDKw_Pf^~Pca#yZ3ZYgv=+s&PRQ;}bX|e2N~u@hEKD zPB(E`Hsm9?vbp_{cAo6=A=XFP-oYz$$-ZvqhnCk1d*MHvTr};5z9m;SVIR&??9343 zuX|~~zCFZQ!eaaPg(brt12rui~p}FA|EcDV|U$@+pCnQQ4 z(8JUi2|FXD+x1}CA?9+5Eixt+0(v4uRpcRDEVhEbCp*!~qItY#%OnONdA%^}DQ=4;LGft<)0v9`QQOs#_-~)O11R+9&Ix(ie5Z;s@@qHFiAg zy4|quBYEN`uC{Dg^pP7OH4#LToyF9sh&&F><3lSWHoYdA7Bm)FZWCMw=tzXL9m&n+ zwHFihn*L`+n2`c5*w(M>_JvQ94PE3>$dggyP}?%O9UEyy)+pz)OZ#1}$=f~4iiUgq ziyndgFPA3jv1w7C9h;~=VUKs#>X{tR>;@z!6&_F)z&;N11oRgozE+EpeHQv6EM)bj z3b7#*21vBTJ*0}RVg){G5(DR2c~);~%7auS>#x~bGPl1)@(_HAsX4-~`0G8={$ir+ z^yj8U2byaRL{hb#v&E2QO@`#ErOSHR^F%%p!!#Ub4Fj?};J1kH^?eQ#&L+BG5QaQv zrGNoQ0o`_$+C(DHie3&w2=;Q|5h>KGB3DFwr9N3kHfN`z&TeIPy?)}o z`((!aU%yphyK&DdM00P>j$@Ce?Qw0A-!En&q9+afrx@X_+!VR8BTmU+r0VxsH_gBp z33K2v*wq5P!)uFuZUqBjjl8gFv0M2;+?4@Y0mjL7{YN^*r5F1q2ys!Q=~de#Fg9|= zjYf&knxjM-H%I+H$R*pbs7pD+ zl_v~#KDOI|Ro7ye5jU^&KP95;uED7G2Y1!LH1K&p3~BF+Axt(f@x^Xz@EKbjOk;}UjR=fDSNL=J(uzJ2eWYp2Kuu8~rXhd52F*(F;oj%V_&KuK;D7CAo>9n>lP z;6(TeD-n2Spj$=V6?o*xsKhUfndZ9|CK~X0?8zV}j`_0ha{2xEv@wf(cZ?#we9T9l zIwsvG?*FvyR==l%E_cilUrnav*GWs@`|2^@80FhM>Qw1z8tj=j<_2H*3(EJ?<@e8= zEc8XbwQ!t>jPgAyGGjG`B?PPc;K;b zRJx@5!kD?fIgz8sYQCSGZk2wUui_-1uLUdY+mC-CZuj??hJ&aaid5am`R$fFL79`g z&W@eti6fvz?aYVNBdsygsbJC~Z0+`d>KyD4c|f5NRxN$nVn1!M*3H?_bFK9pry+e( zTdc^4*7=iTZ-3-e19}iFi&{74+cPw4M!v zRmOd9yt70rrjz32D^;F+^&aVLdOo)~V?tFEjw`DiBfNKv5MAbUROw05<)$ia>VbL*!W?USC-{-2vs z+h?56LUWr>pL@)j?t`N?y0TVpzq&3&Zko6Q@-oYlUsFw%z8dL5rRvEou`dsrWz#B!qSx9If>_abD`mcCc93DK0R%r+{!)x1pxf z&UUhndLwmYWg+(oD|JDzO+4lS&q_rWovCH$VJln2Us-k*u@l)Z5rWt6dVJG*20~<5 z%R$Qz%X$0B2pbm!9NhPFa$rB4(Zl4?7ZkG#`AN(#dy~b!4YNmEgNeh(gEOA73iyX!lG_MKX; zIlVIiKoR|5p*Tse-;>-F=o3)+prCUGO^hhwcsn}OadDl~yLd>vIs!@u<*K*!*|9`D zau~-v1*v*7QjFm_FGt7L4lfZE1}WPM^A zQfE{{lATfXRm%>mA+NxCJ*JkO*?WpO1+6M+~Kv6BlRTs98&{ANPY1|HL zDkNG(@A8QKwyYO3~pExN6`PLH9{iqmX(+{#|QlsgjD9q`0T^btwwj`8Y_ zWOWBT#2a0PU)_=7?1-F^yKNup`9m6XmR=aYxIOEbgZTbJo zI{C*?_wY1fnrvy#Ncd^3c6{Q>(-Ab)tPZ{Nu(J5w7 z9MTv_&Kv)A#xwWG3hlgGyjJ2cq&&P13iY_5=CD#DBU|5}FpI<)U@D9`cq(SCl;UUm z1{nKPwi{N8L=551alA#``kWl;1>(*!dB=-9d9>!?T`&)a{| zdlhwR9MwB%lrT&=>2=20Pl(T-plk15u>}?U02dX^@wV6R}rp5x<-!wyEE30DGz))6Ls!4_%s73na`cWKBl>8^xEgY zb_M`nKY_EWV7%`#}z1~_C#d8Y#oXvWCrQ28YMZh@wAZOZDYVSRGGF*7GPe|l} z&e^W3C5UsDGzaY*;m$dZ_G7qbjj`j?`P--SH*W2zqYnCcBc#eYXt;GUKf;Oq27Kik zd}xQKthc!r^5O8vE9%xYTA2EQW8h7WZ~{GXPhgWskm6z*05`<|U0Og!o(-*EIWP*Y_YWMA?-bj_^xmk+ zIL_76L@tCF8D4Y2EDFibx|`MHZZF6)F*z$pRkag%> zJJ%e;Tpo%pC|fLH>e%2NE82s^3&GWEHqlg-$xbbRqxO{-xBqw+jx}p}>t0@pjAPaq z;#N5&TaP7BD^I`^2g+Wf>$l3a1~u_+7JCW=Z<7^kaNtf?@EGVj^8M1#ZN$iqBjmwZ z@U;_G;yU4;9sS`^?~!(UgR`!Wciryeii7KUsF*l>T1U=PIfJxtR|M7B-XJJ3_6*jW zL@svvp7uKpPC{pu&>kVd2>kc)qJ0#vzCflXh3E30= zLlzag;lX(4ii5=ff3AWzjSawy6=k7U9co%63%3F}2&3Ir@X2P$7!>cRzE8YCOukAC z8od2fKAglfb;7&7M+Zj#U<$5sMZb;(f%X%E&xsp->?zBO<+rXVI!KSM=!-Q;`ujWGN25qvm z3j|%T?f!#=u`KfK#3| zuw4Z=dOioUl$zdgJJ!Jgi|o<^ZSWR`)Zm6Zc>gYZZpup)2LYWuONDW;zM};1ZLs@H zCwQKV){7ZMea+9pS^l9@8%a@0oH(*vX?PH{ULi^LF+V7Et*W*@{V>8H@ z0k4M*l^2JK^TW4PhVo0xmsMDwN{jQ;=g#xuL(DNF?T}&l@z&phaMntA?QLmwC_FbW zeVS8`@=c~$WufZoa7khLg2K5ArsoG>Gqh{C4j)SW8u&Pk^UjcmPpbsX)F zbNtf#5R=-y8g`V9i@W}&U*`zR2>6 zQ9n!72kMUz@oPZ+=T$v?7y4GzpTX!mP|x|-gL=-t1e~;R_NSnpD?bPI6B+x8HRU&; zp7XC2^{Gtx9jF(-Lq*kZ59-fl^a)mz_xa#ObR<3n^%pYw9F4vh^<4XIKs^`#R@95O zK>62!daizYP!BKCBk>7Vp*|mnPeDD0&(YwEHTVXNzEz{|Ks^`V9*sU>3?)^Xz;D5=ltu?=zCDl)o+4G zih3@79jNE*??F8`ekCM=VX%#Z|D^vKeU3(7tkE~19$x%O^0#X69U6U)MxP*VIDn1g zPeDBwpB#<8Sfg*y@V9F49U6TP>fr^dWPB4uVt{QL{3q)l_2)7A9Mp5;XEEyY8GHlk z#c$41{H>@Lg3@=Oo~xf8jXvQ-C>S=j{!!1BpQF(iqn@+B0rgz{w4#0{*hu=1`U@C+ z59+fReZp8!z%~W`N0pEHDFyYM{W%(au}0s3dN%)|o*Q2~P|y00de(pI$BqZ_AN5@M zIjHB#FV>XbfO@w6QP0*t>N)#*P|w+yAO?2W*!o93S3fx#eX&O0pwYLYUWlmn3E#z> zxC8ZE`{>c=6UIRyuyObl)aSr46n~BeU#!tLX!Nb9&r|uae|DgrJ3r__JvTo|upSN_ zB>!vlIjB!o?St>areY1gL8EWgl;5Gj_h|G9qT|8F*`I=XZhXwq=!-SwH=v%IzqX>D z8-F`ce+~E$)jqL(^q_ves)z4Zn-Luwwx#f&!l$5~>mNC&=i*bW(Kn!;i+`&I-=Wd> zXv$CctmQsG|Iz4kP|w+4tid;E^sSomJ5WELslOi7-=pf`yH)?b_Q zR@8I$b)cS$Z;wWwAQpCELgxv1y(%TUj?ll7YNx1yeF2m3VoK8=2?Sb&0!D}S;^pR3WA zp?)TCQ1!PS^;Vk{hA8WhTT#!|&pwU55A|IAjTH;M=i)b3OpsyY^pjD~#V;529Df<=x%jO|JvR^As?qO5z3Apt`|3lz zcs7gDj}=J-wtDza=_jK;rheggp~}_h%TS-CmXGt)^{C&*=(nPNx~hloLbVU|sf@l4 z^<4dq6$?PHar(&`eJ<*`_ECm8S*U!&iy(eFn+7r#TO=i)d1Y%l^gE`FJ)=kN-y1QJZ>su=LB)V4K^+gvr*5*VF~KF^4Dt0-=ryjC+cJ3jP3M*ru@Si{e%?hznC^t z^*9^#9RCv3bMw8msK10Me-rAtJhl_{Tt7U3dafTHMm^ULCx`|L8>gSG(Jw(g*ALgC zo@+mwP|vl$otp9wpk9as;fQiRaag0DFj0W`^P$-q{Su9Stwz5I^;AC>d2%P}MKx0X z9Y8%-e}^^t38G?Pbd$`f_kq0)}o#pXEvdpYu`Ij&$aIZsAv7x=qHGRVdL<# zQP0I^3F-w6RX=M{&&6kxru?0#=i2uHjsCDkKjD1KeRe%ywno21qhE`9u6=JpJ=eZ> zqMoat0~-Bd)N}PWK`3D3>Tfpcx%yjzdUpKN;5TXbccMNAY>aAO_V}kM|FEX~31T4v zHm>~HsAv60Jr}>VsOQdSH=$lM(IUfjl<8@=$B~pYc={!sOR#-PSmG> zjZ}OOpq|SQhc)^MQ!MxS@elP}{VhQ~SAT0!KYA2x|0dLP?Q19Mx%eDFJy(B+HTnq` zNdKwwMa*ZTUU!~RjK^KX)KdfMxq56xJvR^UK>ZP>{2tW*h|wpcfdaM-@IR^@1?Bze zDX33Z_3&NToP+v_YCS5~Ps;GP%ZPGBK3k7^uDxv4==Y(1lUhEG2Ynj+Sm7XS9RFn0 zbLHo1^ktgz*K71!HTr!TeIM$%@no!67=(?>7n3#mT#ddA_1t){9`#&4*@}9ue)gfh z6?}+l$9DZ|@MFb91vZXrsCRqu+}9`HX%a z>QfkfAL_4D^%$SAnV^7e7yOU15A~B#zlG7~qF#t7JbV}NDMNk#7)6hHWrnHOnawP-?B1X zxD;f#O3D)ZQ&p&}aEf@#g>Oo6VYtvYWodP_Z;G|IC|prxe-=kf$-n;U1>u>Y+M-aU zc&z`jjKC_Ng#}Id>XmtsZwmmrAe=rme{Mx}{xy}M@|6|Ep#}NQ(V)wKXWc8SLPe$3 zP*f>UR!DxwASiS}cxvI&>SDCVwn2FZi1YAn#IW>$^A|rxukJR#)f4+X=+$3ZTgRbQO>>cR@yeDQN5`ozp@qE5on1*e`?#Rb`|* zpNsPgtEsZ0UFM6*f;N=Dw6dZ)kS8iUW11u*p5pdc_sWC6=^3j+Rib@rTEL2UTfm@v z&<<9_w1YtrMXTn|Tj8!08OWGsYqfKwq>Qwpin6j$k?7g^)un4>gW+5K%3<=E<^|tZ z>U^h>A_gmCTDX$8=Ff8_qpM?{$_DmGF1vc3^Zt#ZvOpfZr^I>GS-zeF`nk*01>uaT z`SX|NhpR#%NIT`#;r!BYsHzY$BJpaEKzS$t#tfwdNNf>fA!DvAtev|I3SF2F#kxxt zy3%r52Z=q)wwf>#Iu}GRe{ON8JX{*SWiEUVI8hOAB@u7i$jZMee`#oWX}QZDCDYkm z+4Bo~G8dMVR=dkH3@_9qgg2Z%!*(uG8N%jBz0J(eUtV65UsPM0KD9iwIv<9GiXyJk zh>Q+Fh<$NOAi5zLapYK|YgC%1IdY;JE6-t#$9BUkhw+dyI6%|Jj~#lmf?0%Zwe|k3 z1)2G|OVa`Y>9-mnkCsNoY*^a#RX~V!aBY#1DS!kIj zGNWt+?KMwymq^I1h9bL4RH)%7$4jCi0YaZJra9Rnrf9EkLlSvskYenX6R(9+;dNCa z`wYoGyAXRuHw=-R4yhJRvrB~vaV2OX7s22KsW9C&Rt+^*&}lHX`4GlHW|V^lm{d4- zVceN`MsWzvWGZffZs#6DhatpS(8pF4meqv3_K0ENoDQ5fhrk)O58Aa2K_-SYBG95o z$JU6~u`d=$P>2&8sK#l~vZDHlm>0yP5*|M_20!!+<4R;vV~3m;Q1*$)2yZe+z#7S# znNJ4G`y1edg;125mgw1m=w~sN0B^8_^U_Gyi>kKa$n5D;m&2KvGlz5TsUX0gFaPs8OUcnc;M zFncL#C_GvAdJ(ahFdXI2z$FrQA0N&zWtNI1qOx07R#a7%lv-<7L#~aOCN(mZ5koV) zbrDniuvSG(>FFa<6Kby;p_))>hPfux;)k~;)Y1p5iRh(MgBL)HDXv3qbd1t zrcG0BeNt7X$?2J^s|qVCLshWUUsxKhwq9sFwR~0O+?Xo_fk19)2K-M80xFDQaSy&2}Naht0=P+`GAzhpr#Viw$!C~qF5-JePx6ZHh z{=$jV&2Yh!u2E~avS?uSN|q|t3~YZ$tN11(2S54}oKfqsvY1Sw@tU&2h%i$uB@B&_ zsBn`GVGYgHDadM` zgElR@LwM^|kq$9vp#h?Ah}A(d1S@d)(6n>Ig>Kt;v07r%n*mChsPDd}8JB9)(?w=LNKcoS=;ca(2 zCyjB3imSjCfw*8qaM*G%(9^0{7FLDxiwebU3Gi!1Gpj<&;LazQ_0OH}8pQ4MH{}+f z0NCkTib54Q>t< ztJ~qZ(B=Y)>DGD?IWHJSE0kynGvHJ}7axYRc3$H@p#IPz3v!i z*#`4yYl1&~UKukFo6oUl;KSz?QTFiJ9eep|7!4;1kF|WL7eUk0ibHrk8t&+TjtaMz zMx8T2s~GCtLh0#nTTW$7*t!nQ-*z$Vv>A94%u(hQ_j|&Pt<@r)v9}n&$?xz-Sl;uu zyr>A*$n)W8hO$sBkI5N2aUUUhR)S-x?y|V|bgZ0P#9e-DXBmS12FcM{YGU(1T;3V8 z53BD)3gw2ySX*3Q3Uy@B8hw76baTv$~+y|jE)#m#WdSX`nd?wuo}I5Z2)C^Ln* z0 z3(Mj3RPE1$-X;)N&M+O5hBsrGvd5DP^uNz(V1>LI!)0x?_h?T+O_}5I-y{rCevXk z1}+WfEx^;Q$!5jU74USjb(c#3u2sPgXRBAI^5zZese;_%hve7w2C3zx|oqBZe5hm{X2cWiaBRg95fkM30DUl*_kWd!)k#tc55j4 zu{+kcqje6XcCis2e;G#yAMoQEVF@OB3^lr2!LCB~W;^r2EIoZ?XysD4+=pk#Y|)W> zdI;Ynueb#5Z6GZUg$ql|(lcD#RfF9`C~nba?%)UnBHaM4JkMJ&!DjB$c=dkH-t6X>Y7QPyt7G?LXE8B_+i_@r^C| z=%k+51q(U2k6en0k1?)PLQxHtGVFekE-y*RMV9moc)v+Lydbb}C0yYrFWtzHDHs2h zGt6|m@W?}TnX5|*!_En!eC?okg3%PI+;40X*&!RkIW628D|#3%cvOa~4A(nsQwZnT z%k_g{xW)YRY2lKpiq(FiKV)#XccR48POys zFAJnACPe4M!2@Iumm$^={#C&vc0vXrg2ugaK*H$t3BbQ7)5!i{q^Yu(|?G#G( zk}8eMhHIrBi`Mo(c#Z5Jw@8@wzojG7|Eyw1sQ)e1^uNIa6i5GCs`S6X3HbhJ8kBhZ zAM%V`|MNs(+($(JgOW$8|FK2K+{EBsMNvk#mON^+-F%G(wr5q#JxP26vhdT4`|%2c#9zQ$QUnKSq#+ADxq8 zo_gd)l6X1otY9>`qsdIh8*dY0*L!W?ydu^7z&JyXR$15_#Ep8=|Ot<7|=is9lGIVFPUVCCwe@*=m$ zubDW{n~&_9+*m@h4rV;$Ww6A94u0`xBYah!@+&UlH(Ul;Cy6UJ$q9t>Mn3CjX+}7j zs#l(z8p7JQe2A;qURfN;_w^ZFfYeSfW3NKfKk_m{ zr>*Lp8bcvBp0FDEK0*^)?>1=8dYShHDUILcs)u*elv81iDg0#FJLAzhKQ?HeBl#$q zVPHmNAoLsxdNPkwyvY19a%Yxxqa)Yz?bgEHCMhpUo2r;g*kOpP6~cY0mAw(iawv_x;GHs%e%Te)HmsJGFy5qzB7kxr;x z#vdlpYRs~;VC;Plu|tE+K6Q}rd|czF zZQFF6ZG#VC@t-=1m!5OgHEn1{*=gPL0+oCPJ7>+HA)?3F=!Glo+#g=b>ETWs!^LH9 zg&NP*tzt)L4h}DawE9=%4x{MKNzW~YkkVEti_3!(@O|GjDDf^XBhSe7NlyfE^)D!y z?kj`MM_0%j-(a=xW1e+_^>S8oH0G9qEYk3;8RW=4*(2TvZ0MRCJ66C$8=Fw*M1Jp9AwO4VW=GWcdXB<2=mm%&2QVWY z@47!q7s(j95e_Nm<;cc1JriSFT0Ejx9%Fb$IGQnhN*E1)vb?e~=F*{g3G|CFlyNhC z2=8B>Cf>j7dKbL)3TA68k~3WK7C8Nzkd;W$86$ox<=6<8h`F8hZaVREH@ep|kFZhh z;XU?8bE8AR5AMV}v5(G}&Jhnj*2JHf=gy0d(H?J%);}mJdf*=HgpDZ0uE>x1434nO z^t{K8YaEvgNcKo~u+H&jj@(rOl3sQivx@^nLEg@#-@;&D|O0Ec${S*`$(X0T_Hn)mBr=Nd7)BAv}TwbWQ+CoS*G{A4hW z&bY*#eDNlY+=w;Yw%9q>Xe=``f*$4MY$Vb>{sKvo&N#xGn_SiYceE=o#?ZZIS)OwV7KkuQEXo46lM zu_8TfSyc$$hzw6C5Beq}gIHK^QjO`c9<7ltHxf1tQ_Wb`n2na+MiS4};|`r^?M!u6 zX>~6-bhBto8$2ZO-bHL`K>YU@J5QM@w=I+H-5xrXC*9#5M0iwr-A|Om8xWgu(~E=DeVK(42tLF{D(6w!tavQ9gDq zY8;t(uRGgBBR6mK#$dNaquHP+dayZO9DNXGK-Oz&q8~JY=#~{$SLc@(t_+RrGH(o# zHxKRbc^i%JS<3m=9f7gFMR$t@;i;7stCuMaMD8sn_byZ4r83mtxyo{WyTk; zF)Y7vC0@B(UQry18K{SYAQOI8stDfu6o#MP794QvXu5ir+%WLW1e(%vm==bupRaNP zW08s%3Wwm1)e+)O&ydXdp|8~xmT?}M{D>9gQp*)IcxiPtywd85Yp+)xBeUCnJTEiI z5Va08@S871Q1byuKk~D0$}rF=Q_z6=T*>g##lH8=giks3vq!%f@M;2hX<0~K-GWdp ztFRIvT<%Jzeih{?P!1)k@p(D4$l9Zj9nz`Ax4<}3S_Db$76>T33Cz0FrWnp?;r;JJ zcsvV!$yjaAGwt>a$!5q6+V~_+wPujs6<5U=7-TJo#Ds@1h)yme`Lvm1g#Fus&g=UY z>VD?|M(T>X60= zJ`iU7gGa(1>nUp3o+fkYqSj(o7=6|iy z?d<5rF&oi0=^+-*Hr1h(8y)_*GCA>{sX+!0rV56MnXiUnB#5bsVJutet}(HV%HD)F zx;~ZZi~fzy2BWgI*gV*%%+&OV+r+nlqe30iI*tZwbhXFT9u2BqJ0WAL{;1f+SN~C? zk7)u&jaf+_26YNQk1Zk>G2I*+O|A~E#LJ&!t7@S#B6|X{801IM{wn zrxa>P?V*1t=bcdJ(eNF(z)&w2WxC5&~3AKmrNS7YdxQ40V=!Owri;cB7rq-SH(3ok3oot7Tny-rCWQeJb;VfM3 z>@o3;?(LL1x(GYQcAL>IBgX)Su>KoU)=-vE)xzuvf%hd;5t&d){<12#?C+aWRIzep zs66bOQeF`bO}XOgMPG(Xg+({}rYx_jsHyY~dAqyK=R27wB^&o8qMSO$=X>cGpDzKw z+mgcv3H)yj@OcFOWdras@V_&_+g0n1|L+a(wFLhG1AHBU|APU( zk-)!dfZs^qUo*hB5cqBb{AL3GM+5v80{0|dU$0PhY9d=`NpZ-CDx@TVEzg9JX=0G~(T&oIC*Ch(s(z!wns2?qEQ0{;aA zd?kTD(*R#f;LkF^*AaNX0ltyIf6)NHk-(pAfNvr2=NRBO6ZjMZ{1yU#t^s}h1}@ZALd%Le#f0zbt7-%sGv4DbU4KHUKC zgSocY+~@xp2KYn*Kh*%AMBpqFe~|&cfWTjDfG;8Nml)tH34FEzzLvmWYJjgJ@N*3CjRgKO z1N=q;pJRY;A@BhM{AL1wxdDC)fxp54zm32L4e)IQey#z&oxopdfZt2t=NaHT34E>r zzKg(LWq|J{@K+n)dkOqC2KasgpJ#v{An;!?z}pLD?(u)V0bZ=NsPl*G4DjMyUBxdp zz>9ND75`NOyg1iU@z)#R#avm%FEPN2xt@x@(Eu;z3M&341H2e(RQyr{yvS85zSsaS z+PaEgW`GxMMa7pG;0p-+3In|0Qu)ga@RbC<+yGxo;6<6Z+mYP*cO8NMngPC%z*iaI zHxl@21AGgCuQ9-HCh)5a@LLG{Y6JW>0>8!p-$vlq8sOUr{H+G~y#!vgDctQyuKjfq z_&W^nT?D?t0N+jE?=rym5_r)kaJM5l|N9AivjKj9z~5(p_rd*MYW}+40G~+UA2h%x z5qQz3;h(kHl8aw5f&aDv-cR5kGQg)2`0p6t(+K<~1AG>N|E>W(o4`M8fDaP*M-1?J z1pa#l_{9YN`v&*|0^e$YFCp+hG{9F9_(u)!wFLg(4e)gYUW{q*&r|g!?@S6$zRs;MN0{;^O{5AsrxBFV3mppQrv`OW=QHfUhI)FBsq(3H*N<;5QQZeFpdz0{@}` zelvmpwE=z$f&Xs<{5Asrk^#Pr!2iYo-%jB78{qd6_}?1fI|=;D2KX)l|B3;=8}VbY zzlrCc{$PObBlur4z#k&;e>A`!Ch$E5_=Mx6eQF9!Ir1pW;J{CEQYzXtdT1paLU zd1>m68Luv@Usd0y9W3i0)NN=pG)BXZh&7%;NLUAFCp;n z8{mrx{67rvWd!~M1ALgke`tVTOW+S1;2Q}1KMnBf3H(O}`1=X`5d-`t0`G$y4n=tC zzpVs*lmUJ#fgf#v-%j9M0KbpGA8UZ$PvDO;z#ky+Cm7&+2>gi# z_&x$Z)&PHqz<hb;XA=0+4DhoF{OJbx90H$gfX^lHpEJNOB=Bb#;Fl2i&l}*23H$^Dd>MiNf&o5E z;LkL`uO;wj8Q>cTyx#!7p1^<60DnJ$KidGmiNK#@fNv%6DF*nh1pZtD{B{CA(Ez`b zz@KM;?;!B02Kaph{(J-cegZ$q0DpkMPcgvv5cmrW@O=b6-2i`xz-JiX4-@!l2Ka>I zV1U}0EKc2wPG{8?F@Usl?DFpsP1N>wHKidGGN#HLsz|SV|7aQPn z2>c}m_*?>?ZGc}$;4d}6FCp-A4DiJS{xSo68G+9+z=sKZzyQCNz+Y~FZy@kj7~t0v z_@Dv)egZ$&0KbXAUul4ECGhhM@LLIdt^s~KfxpTCzmvdUV}S1<@OcLKeFXk12KfC1 ze!c-(!H^MBwi=z_$|k`wZ|~34DtIemjBRY=GZM;D2C%?;!9$G{Em8 z@LLS<`w9Gy4DbgC{9^|A9s>Vk1AHHW-)ewAMBsm7fIm#&A2+}!;Ej*&_5Yt5;Kvg9 zZ3g)91pWyF`~(93a|3(|f!}U`pG@GNG{9#P_#FoL*#!PS4DdMwzRduiOW=1J;1?43 zrw#B+2>i1K_+kRT%K%?S;GZ|ZhY9>I4e)CT{2l{*1A*UbfL~AGe`SEbpTPf@0e%yK z-)DetCGZaz+<&;0z&~k#-%jAgGx1*UU))LH*BjtF2>cTU_@M8)5?+x(d3H$*A`~(93 z2LpTxfq%^aKbgRH8{jhu{2vYQvkCm44DdMw{?7*ZTms)?fL}=9iwxTT5(1xZfG;NS ze=)GXjKIHcfDaS+uN&CEmcZ8<;2Q{huYvvR3H+M|`1=X`=M3!MMBw`j_*)75as&RY z1U_Vd-%jBF*TDXr1pX}pd@Okk|1`i? z68L%p`)djO?FRTd0{@YL{fz|vhyi{hfj`~A{uTo7gJ+td2v7NMGl5Stuzw4IuQ0HG z8-ZVGfNvx4qYV6SC-9>U@OugTHw^6WB=C0{;JXO?F$VT`6ZixJd@q4N)xiFK0zbxp ze}KS0WYB(n<6_7EM-A|a1isY(pG4rlN8tTnrueBM2u;+MjQG)?joR(>e|zue;R94l z%+{YE_in^;#M;sCfylm|k&K9mAO%0ZF4-w(!r9Kps1GXFWYCH-IXwOhlT(I@pAH&| z-;eyZy>>67pThsw2><86v4a0t{JjW)6~#UBL06R;=db?rs979`Ewj*`9bA>4t7)gdyzkgc+vjeAo!1m zeH6d{JPE|xn6MO|Pvvi7@RJaKj)RmRRD1*ADf^Q|vWLyxfBN89yZ_nyw=?`#BfqZw zi9P}UV*1}w#N#kv*&_a^_9w#*3SWu%Sq@TuQ1PFI9hCp6g#Y3<=~VxhF#L}pzsS$- zP30HAlSJ9S8}Vnj!SGqdkAcKX;kyy9Yd_5l{!PT|+Rt5pr{b4Q#P9D!{B|<@C#6cq zb@eZPla}&-0^)W4i!~hzKN0bm2Ao<@dtf|NlYwFWzZL@#lK{9)ur!NzYogWrU}N(U)FsPQji@MF)H$Dgagi+g$~`!f)K zss=Bv2~hYT;xE+T#W^K~Z}5o!{IN8?9r3#PLp6hc3GurA_dJ8|M*IYg|DQjOw*N5V zb^Z4S27l}%NqoA7|60IP{kM^5|B2A}60tmc{JV|eKNI8y8eGBgKzbSe}}>EK>X)4{cqk0wEdlk*NwlI1DzSHDhyPt~r z_vu9Z9%cC7Lw;TU_#VTbOz?k>;QwES|D-R;!0G(&W%$zw{?8Nqm&1LMRR7IHex3i9 z0-lP0kl_CU!G9OSpNssu_ABmlrR=}SBYqrQV50Dqh==e-ZQw%Gwv@rILA-AMeG|J@q?A2Iyx z1pj1$e>SWyQt{i0{9=8~y+ILC+YG={{&yjN5RVr1KZW4`4#WQ@@{9FB_onhc$ng8c z#TwY${AmRL9~k}#UzV)8{@=y$mmt4;{K_Es&rPD^pN0H5jh4p1U)6s<;Hmi65&W41 ze*?q66!~@edw{`*5wFW1?=tqcp#5p+xoAH#2>Vx@OvkSU`E~6#1b8Zbdx`kXB>10X z_+LhT-TGM)1eof7Zz3L=SJbA~|A~O7?C&P*pH0|b%kY2Tk-wVZA0YTICiq`t_)nN3 z-PZa43d5h2ETiJ?f7t~8rEqz$3p|7 z><@ahzl6ar_K5#AgD>%jpAHK&l>N0HD`R5J>KN>4;9P-;jjsMR8PsJ}t*e|Yi!E%+g*?vuj2`**- zDIWQM!QjtEyl(v40eH&(0>b`$!u~8+pr-84_Gtfh2A}5`17{^JtD{xjeNpQ^tz()P+{8GHxgb?x_M#(qEA?{2@m(Hc*zuhB#ErZ|f5&v@r-{leiA%lMt z@h55gzY8v~QT=BC@w)NjcEHP;iYCe?>aU5YzZ2mEjp9$rl;!F8j|Du%znI`}Civ?a z{#1|rw=(>d1pfwt|80gp8~Jmh!y2=GE$&mJ{BK150>q2)`(A>7O)4G#29N&N0G{IS zCH(&;!GDC|-{g`11BTx>L0aX`AKxPQSHlGYs{L*E$X^9`%Kv17{{e#k&kX-QR8 z|Emmt8uABS_5W`Kzqn6>@_zy@-01FKssTLZe=Xtvw+Vh9TxX>CvyfkR{pdr6eu@s{Bz+t4dwsj>9U%2^`8TH%KyCt{|^cN zA2R$)J@Rj6_><0zjsL$B{G(ukM)}|3k^eBmznI|v5y5{G!~dd3{;vX_ivMPU|HlOX zFBtxW8M6Lic_3eKMf4+wQSin>M*Ao0cC-`q= z_}@bQr5gTQ82&EguXXwVB*Fh{VlEorK~qLw;TUJO}Vp{goiUd;EBc;BRF3zweR1p5fm{@b4t}dl~*N zkNkgT_y-97X9)gfuueh6|D+3L#p~i<2zV;~*oy|8c*{tW0~ zRQwMkKTOY~HYg%$`!e9E_*bUH*8htH|2+(U>P3=9=YJE!--i5d|2qkOF;A!b-+}zP z`ODuJ{=|vWe;A&uO~n5tg1;8#i4^~<$gi8fRRf-ie-`q)=TG|y{(}tvM;`fKXZZ67 z{+9{N-x>bY z^JG+NF?yo^brbxxaDjx1zyA^m)a9RQz*F(xjQsBW^CyCTG|aOo{>PDDmw*4s@b{-m ztK9Y9L-4O<_+Rnp|7yTf{%4&p_qzRmo!}o0<2>bmNw$o?uK)d$;cuKI`Q7=qm*D?C z!@m*vb@}(ZfT#R#L;hsxhBf}aN$^jFahCFbn@9dBfT#F73I0BUzm?(dM1EcVeT3of zCF1`U!9N|w8Or|;kY88->42yFPyUkJ>yCdv!T(E!|LjX;#p&{IJHwxb{O^zGDkYDyMF%x!|z9a zcl$d`@ZX$G$3GYO^Q0NhUnnAKTb517zXbW+?e8Ok|8Ib&>VFgR>&E{+hQ9^*YtdRU z{)?9!CE|CxUcLhLO!2>k{JQZ!7w}a3OZu|h>mL6`6Z}sz{A(|hhU&)uHio|dU)b|h-|hdg1pn;}|MVQ`|7WqjY%$vYfO0LvKOkOq3Y%Te zqW%*J{tp=bE0JH9fB(+#C#6Y#cl$qq;1~5w#lH&q&q6(;kQD`?e;e|<`~P@?|62_IEacb4{~m_lmoBYx$Nw~f z|9ytP82QhYVQ~Jc?f)HyKMnca?LV2|ufCj)|J@$>%K=ZtKS=POLGZuN@Ne_T{|>`n zK=4l>_{*-K{eRgb|8l@n{?`)xXA=DT8UDi_`G3vuZzTBr1b;4c5UT&34RICQxl%ZP z)%JG<;3@yN5d3Eo{7*CdLFCuX|JoS-cH{@OwTbaBh2Wn$m-hb-H z?qvA$kl&quClmZv&!hcMf_^2o^Q3V8s`Wn?@Ra{`g#S|r{w{_;3;A{9-)|WH7UXxg z|1^UC#$4L}a^%;Ye=G((<$pKw*J9*E|H~lwpJDjhkzY6e{!fN~@lkyz3%u=C-@r~{xt~H`CrfQ_andC|15(4Zw!AT$TZbo|qhUzh(X08hog68YWvcQ(P_%kbxUf`22!KY;wF%WmNORr`N4!=E-oTIFtkmlOPdX84m}Toc<~DV)D5|Emmt5cyj~ zhnKoFs_NM zUJB>0Vx}*T;qRR(`P&gG{Ldx$|H$xfNB$)av;3g)A7J>m%#!>CF8-?t{!?LqrTTvo zjB8@k@h1VEihtsTvHW=i|6GQ@4EeL98O~qT{~U(D1o>+bDdIn$;D3=QwmFxU} ziQ#V}_^Sy1GZxeF&q97({yP=$RQx-M`VSNQw=(=okzbepZejR++0v?H>^WlmUq$f0 z#_->b{JQ-23d5g_{O2R!Bf0P?%r zUjxDa7{k8?`ESGXSK9!U|A!2J>Ktj6xaV4IqW|AT@OLu&AHcj;Y%Nkae^vhfV)zGg zB!4?11%D&Ke?FXGQs^6SR`^$dS6 z!M~p1Kf>_8j{Lgu?*oQE`Eu#MJOAH9@ZWhO9sgrtUMV&me;wed_@@#48wvgo8UBeL z`QKysg9QJ51pilVqW!-d`E}!eF5oHu3y|O4{_ZFE_cHvI$gdm!pJ(_t68=9(@XyYt z{cl13X|fqOf7Sjs1MrmpTae$Ke_IItA2a+fdi4KMhQFVP|3d`-$py6k?;-zvj_2}& z>i<~4Q~vv}kbAcvUgW<`1pjq_r}AGToL7iVm;dG$(ENLm-`)NmCiu4kp5ot*{JQ-2 z?+pI{!M~Z{KdzAGKY;vaK@8lR8voINr{bR)lzZLz@B0LQEyI7Op2l;jR?*PN!hWzgQx0T?(sECe#he!Xj08ho=H&^a;$NzDHzlGuNL;gnD z44uEDolo+^w;293LJ82-d7rB&|sw}aq6FGTzQ0rKa`YHz`M|CMlFE4HapIDb|Ce`omX2>z!C{&Sbn{@;rHy8iD6Jmvp3BK|uG{)ZXK2MGV4A^1;PPWykrWBiW?Jmr7tJh|6h|Lp|-I)*<9&g;ddi+?S{zZm)5?SB`+ z-^cJ@j{N6IGn~I_`}-@yznSpAgW#WELdU-x`5PT(`9bBs3h-3?JCVO1@nZhDo8aHU z@W1CV{y$^*+jFH=K^OmCg8z(C+W*P0t{^sD{htbW%KyZxV)X{_`4bYBsi}Zo9_JQ_Y8ktp5%AupO*;!8*irlpN;&f(hTRX z>i=TEQ~uWx{QC+1Zic@Y`E~RE-!uH%kUtqM7x90Y;Qx9V?SF$u{#Agd{NGFPcM<%@ zuB7=}J@StNJjLHl@V`Rve~sbqK>kTi&C3sJ{g*NP14R8FAo%~u@V|xpy76a#;ZOaF zjEcMdUnThODyQRr8mudcO_zUf2Rs%3Y~*+6|89c+gbJEptgDGl7ymJUr}!I@-`)TJ zMDX9j@UKGtbEO&1U$y?j41XID{~m(hS4sQ7$s_-V41XuV|2n~cFT=mfBmdoir{dpB z@b?n@?8zZCG4|0T%31(9O@_YuLro#8(P)|JJkn}7e5;ZIs9t#a4DFf>sX z>pT~J{A$|&i;+JSkGF;De*)ks|Fa4H(FA`n!@msqb^Sk|;jct~cl%2q_U#{r`OW)f7By?I^e1JZzlK?3I1Cc{@uv0%Rga;zm2H>6A1o4F#P?}ne-wc0;NB(^b z{}zJ(G=hJ|*J=OX^vIt9c*_5Ff?xckpql?TGWwrM}94!&*B2OOStNbhC=N|Lj`8Q}Iu{R_=B8fALCjm46q*{~+?GX!xII z`16q8-T(Xq|J-%7|4$*mZv4#wy!15M&=P`Qyb@ORe>cPbibwwE82&nfU%V1kTe_tK#{|@BW`TrrqzZm)5{)<;a zsr=;(e;@Me>c155P;AV$neac2;QtNaM*&)W{&IXs7MY`zJX-nwVja!jiTnk4ycqv8 z2>vT?r}-Bnzb^g(z*GLGEtY%T@y{gqpJVv%L4IBQcQX97$nS1{(+U0y?x6kO;W7S` z08jb91^M0a&m#CAVfa7r82^VD{=~0JtK9JykHo6&e_TE7e;Qm@7n?5rCjg%EKM(oc z@fVLos{E@M{>8{YU7F$i9qoLQAHK%$*CD@q{1uO6sr+pW|2@c`s_?1&KWF$`2>xt> z{{x19hsXH;o#Ed`@QYjGRsT0P(DnbSNB-{s9*T|G_7eQ!mUxwa+MP82vCCzVOO%q; z_@@D$;_pU&I6bvCk^jUku`2%$82+Wmf3}AIVTOP4_0lSL`xCdssr>IV{0+#joBzDS z@K++gyZ?z>VpRUJyXg2oj{N6o{9g`u>1p(Vn+gBLEfFgJs|^3k$gdlJe#h{)A%76f z67?@`2~hdxeS`LYY>5Qw;(s~dDgS*p$i43Pi%X&^|IZly>BxU>bXa4~f3`CGX~^$x ze_}~m<-eej_J4^-{z-tR{0|cRVo6Blf0E(9!z2GThQEN|7gJ)De{vJ;{}zw@=K-Gb zzn0(^Qv#L$L5BZDkNn?c_%{;#qD!d!Nq5u!AM(h5BH$_iw-EeG2>yD8U)&cZHr@IE ztqgxV@&{!x*7ILC5&R!A{0osk1@X2}$Dj8Y{zTy{Z0`P7K=6O7nT~%g@}FfBqg46t z0lZ|2KG09_FD3ZDxSr;3@yI^`@DzU*!Cy@9-^=i~A^)Ukw_@_&-3)&o^1JizGJ^li z4YdE_zBI9&Cx!D@jsNEWPx)U*_+LWsKgRH%utHMm#=jpj{4L1uZvQI?{&cv(ZWK_d z=bzcgKUyeVo9h2$z*GKrBmXwUi}AON;BRO6=fHhkVmn(3=da5D3xnadzXbWy5GmS! zEy14z7r3eZ7e@Xg4zv8A@}CHJioXT-TZeG{DJ%F_BX#$`md}1Y`{wD{F5J`1p(VwaA~0yG8!nLh!F<_{)$#J-XPK z_E*L5ZzT91BltHk{NlcDv0WmC^Hu^4{HLvwz)YJMrON*(!{3Yi?)=k6@c#|)iBR@2O2K)^FLdrr{ayekC_};jdWiT- zzB@GjCx(bW_u--Oe|w1d^hbuq|I85a*K8gd|0{qOOGN7X=k4}q=P$brCfOfQ{&q9n z|B}UGGi*WYuYCVr2hskI{T|Iv?0=f!uS5Ph=)Wyg`%i48 z^H(S0lWibM)&6yW9|bx!e|00?&OdfBe)|K;TEK%_G234Bza2HA{{9CJw8vlDu2&fT zv|A+5KF%gk?f)&q-zYAY!Dibp_ae7odnZNLbYL!*szNg%WABPy{;SUvaZXrw#AOFx>YJ(nLg>%aa#%D$UYmT>>BGU+$jsGr}z7n1%8!T#C=Y0?HbMW( z)%9WVUqla^)xrLg{q7L^?+ErYPjMYLkKx@D^?#=QLr?7uJAcTROv zY#u{#@&oZd;hu2+Tg>(T`rk$8!3icNn`+Pkoz@L9_3)gp< z>kIip^Vfg<8-o9j8~@AAb>#oIA^vZ5Z+QG1^I@{>p6a`Ba=Uvzd7o9H`4K6EHUZF`u|f%`Y#vkuQB!u;?)M~-^GIcjFVlj z%FXqZ|La5SeRPS}sQRe=!|7Y4y?uVoA50Bp>bA4~^*K~D#Sp4dY|5$zos5Ef? zvEGLS`^$`de|_C2s|?jQSqrv2o8xIkS`WzygNEL!A#pXvUw|NGB> z7VPu&x%Nu;ga7&;)%9*l;|04-`sW)=>EALW{pAmar+@h(_rl)F&vEMdF#F|gF2(o{ z3bFsRV1JFVUt;{{Kbic&{N3fDaQ}19bOi?ak{lQH|g)q|EC1|*V1B3b+G?rf5#B}J3JDe{x!z_;l_XdlgS^<-&S>fSpF5B?DO?p{){=tfBnbm`mp$~G3m$pziUYPr#u>-{ubkZZ}Fd~t`D<+%$#8SGehim z3ig*7`$uxZ&0l}|2R;_=zjL;Gfxo`{&o@%nhxxzE_|NgD^0Rx0|9cAd2O0a@`26?V zKU}!J&|F{cyFSx*UM%>(%J`4#ABKncf4X3QS%UT#2=-UgVquKoFYxzbdAM}*iv+1N*&^ts~+myGazF~E1eP`Lh4bG=Vok2R5P ztxh5c%xAv-GNm66zkNF200qqFj^DX-$r2ajtF(vh|GTOBI?Vpi5|_TJ`WHO>_VGLX zOmZ7KU;m7ZKS!K*Le)f^_XPgFz&{A^?Ua!Xl>XaIP=>Kl^*7>t7?7v0BhKFh{;|M6 z5%{M9|GU8dA@I)y{)NE56!=#HUn}r$1pY69e=G3s1paSMA209|1s)T4g}^HXUM28qf!7FpmcZ)-K3m`o0&f&}lfat= z-Xic;fwu{Kj=<*$e7?XJ3j9=opC<4#1inb%X9@fqfuAez^8|jrz&iwffxs^m_{9Rh zRN$8h{0f0zCGcwmzEt4X3;afb-yGmG)ewvBBixaew~m|6BhD=Wd6(Z7;1%i%(le9< z)WLu0bHw>|K;Gqd26(;tg7olwOuU}E0`jh&djkAqqlf1Ow#>xh?nUc_|?8>RA!sml-{sB%qFXe_jsAlT5^UMc^w1zDnS)3jB3}zbWw50)JcJ z?+W~Vfv*wxM*{y?;GYV-Ti~Aw{0o79De$!d|3={73jBM4uM_x>0{=jkcgT*#sB zmj%9|z&93nhQJ33d~<6nMG7D+OLH z@LGY_1^65_!lZoZGWl{g#4h5@4#>OlY!G;pz*_{~D)4rJ&lUK5fiD#JsRBP;;EM!) zmcY*u_;~{F5cpz&UnKBL1inPzmkaz#fnP1~YXyFtz;6)vO#)vg@LL6byTI=dc&EVc z7WlmazhB_X1^%GG9~Std0)JfKPYV2Lfj=YgE`dKM@D~LBlE7C8{N(`eQtcJpznr7~ z(h+~(@k&6RWFpSW0AFGB++g$^OoHZ!=wC|ZGw*LiKf(0Q`BTJsJ)obyi|AkcWGU}& z#91xKzb){01^&Lk*9iP0fqyLUPX*pB@XrMPg}}cQ_*#K~Bk*qp{=LB03H(Qa|0MAB z0uNo1pvuDr?xFy%DCkcSXG4K+Ebt704;1+30^d^Lg9JWU;M)p(h`@&md`E%rEbv_g zo+Fz^esbEATpjo0qNw?OTH&-z0GJ z@dVxD?6>{)U>na6KZyW}Xh_jKvHx~FN0;f0ff=5KZ zDHp~!7v#4PIK6QeJR%Og2^Kse&R~IWBk=76K1AT#3!L6e3LX*t#!wjFS&-jF;PmEA z@Q66{MojRCIN1WHH&B8{#MwjO^u|ZQN9X5^**Y_~ruN zLf~5pd@F(b-#&81A`ZQU5j<3V3_?XBj{mJDS1jUeE6CGZ3Be=c3<*L-BF^>#$GaR) zB;xGgoxmqmf8osg7;$#;PT*6-*%{8fj}d1V?*u+YoL%9}`xtR{^G@KCs_$^-eT+C+ z-U)nC?Esv4A0y80-U)n)IK$w~`>5In?*u+YoZ)cheT)Qt^~L>8wHuxge2O@G!kPC` zwI|*Qe2O@G!gI8bb*%&yiDLn34DgYj~4hb0-q`HV+DSkz>gRB2?9S+;4y)h3%o+$l>)C4c(uT5 z1YRrfSpu&Uc)h@93;ZO3Hwe5@;7tN=7I=%mPZoHqz}p1gF7P=5pDXZr0-rDN1p+sl zxcR<~IA(LP05_Xn1^8(`;+{qvv&oI`+lX_9kFfkAfuAYxvjl#&z|Rr*xdJ~=;O7gx zL*N$(e6heU6!=8~zgXax2>eokFA?}<0>50~R|xz{fnO!?s|9|Iz^@hfQh{G5@aqMB zgTQYT_)P-8S>VeAev80w75Hrezg^(J7Wf?kzf<6y0>4Y(cMJR;f!{0e`viW!z<(p~ z3n-wXWT0$(Ta9|ZoR!2cugp9KD2fv*?% z&jMFVSwar={7c~eUte}FR`dUY{DuPGNZ=a_d=r85ZdUP$Q1kzS{6K+kCh*M#zJU?}d{=?*Ch$ywX9+x8 z;JXWan85cC_;7*$O5iyH-&5dw34CvX?<4Si1wKOH`w2W(;8B6+34El$^94Ri;G+dT zM&SHw*8cWqtRTO?zz-1kfdW5B;Nt{-u)qrieu%&i75I38PY`&Kz$XfPlE8}vK3U+0 z34DscrwaUVflm|o5dtp}_>lsiF7Q%;mkInRfzJ^5(E>k4;4=k&tiX>G`0)ZiLEt9} zJSOmRfmaB;Qs7kruNHWXz-t9QOW<_^uNU}ifuAJs27xyUyh-5A0&fxc$pUW`c$>i6 z1x|0d29Jm{SK#vmK40Jq1inz4DymkNA|z%LW{`&b;P(jpUV+~y@cRY+ z8-Xtu_yYoeP~Z;<{9%DVBJf8A{+PfY7x)tbe^TI23H)h+|5o772>f>f?-Ka40)I~6 z&kOtofxjs5mjwQMfv*tw9|Zog!2c-lR|Nhifv*(!p9Q{3;C~VLs{(&b;I9k(4S~NY z@V^RtwZPvJ_}c+KZUaZHs{GLMA!b-cJ97>S4$&OisWOby&WhQvZ}wnw?IO)Tw)(d< z{5s7)v7F`a*Zl96k1+DI^INv_56dSQ{+;4k`j^C9P-yrr5t9Gh$`3T0cG$>vzOa0E z!ynW9OUv0$dZRzv`O5Mwjr_n3iLbSMf5VG4|Hks245v5pvYmffzN6vvW=gj6t>x@z z`9{RQvz-0BQ1gFV&i*{9`8vy4&p{iLo*yh9ZtS*b{vXR(&z+k8WI6l!jOObt&oO%b zs`<~Bw-~-&b8o@=9)|C~3HdWX<(hkJXa2TozJcWj7~Y|IB*1Udd_&8*{H)b{Bg;8m z`)82djV<5V=)XwwO)TfQJ*#TWWIm>UmDe3q2&1U&L&9?~1FVuWX%US*& z%?Abemda4JGdREx)_hybISzMfzFmNCxf$shV)+gxUB_#_z2(CVzgKf_-)#1?Tl1X) z@}oB={ocOWEZ?HJw{JH4*`;}=)x-RsnrB(gaUQh=>Cd*D>sPDh!z|}~U#|Hcmb3mH zlt8vK+;Xm8i!`UVjNOCd^Lx#`eY08rHd~RNy{!Ch=DK3d_pyAj;eXV8gyjbrzME=P zvz=VaqlVAWJkN4Y?-iQoTfV1}|3Y(m8`?cMy+>_L`o~z#>3v#rZ{KY8XMnme+d06> zb9;EC<_B7?lB19N70=SY2;-hBH}vtMmZx6EJy%{q6Piy9@EuhHmF-Ll@VS~7Th99btodPd<{NAd;&vv~1x;dV=YF-hLAF2eh zoyq{eT5}o&xd;0>XjhW2ww&WUPxBhf$C~Rt(tMWX`x(BqYCy7`I?D?TpQ8C}%SRY~ zwdM_$vp+j!lAgu@KTq?f0N)^sc(&v1*FC}LU#WPO|p0JWK!Ls_O{r|4z%l5RgBtfaJaR=vn`x zif2171>`qZ4SSa3y;siqD-_RmRs`f9)AHW?>8yX){v`jhmFIk4pm+c1 z=Mp#B&ddYIPj4TU48wn~c$ofo1pbx4e-ikn2Zrn4N%3rFrS(%aYx-yqY$ zIoo|h^LH)hdN;a|^t^95%U`Ye8q2vnY%CM=Qy9O z`KOk%p7n}nIo^IatmnM(q^H};v!6Sujyv1=%yN#~Et-E3;F}bY{Fjz<+%D04t>vtL z@I;dT#&V9^Wtx9$Im>S~iR8bxT&dN^49(YBu7)@IctZ0Z1AMz;(({w$Jbs(2`FhJs zjGnJGSFbRegY#?RWYV*Nv7L z-)KI>a@I3t8tEBoIp^2Yn(r9kqf`f)?d%-jH*3CYfd8a~wD*Sx@T*7JknS&p}V7wf5>L3;ML^6dY+ znjdI6$EWCMk{=h~muOySImc(6=7(C&`eVnCo(Yz7e4bT&u-dP$%j8p~`TLIIVg2AI zMm~FhE6DOcYyA_g{_TyPNi)OsEK)q%DYo*P8u>>IA85{>F@HZ2^sLqLQ>~t}jr_^S zlKyFyv;JERXZ>6r{-}6ZdOy(eB>_EyjwAgg5x<_Xnoqa#1;(FK6c5vXrQ%tRx9?Mq zk$+l{U!nDvS^dk6{7-`Xp2vsVZ58;bimUl0t6vQ-_3@G*zvT%ee~gu9|4-EXSj)LQ zzo7Z?0lwpjr02u{pRRei$@1Nd{2I+$0(^7@>1hq{Ce7O|=Q#Xc^SPFDx^__& zGuxSOIme+%^M#hP{4<)LYWY*f&kd_c&*_$Pzf-IEq5ywZ^Rp};YxHDQlb&-dFERXj z&Cj!(S7<$|cv$?u7Wf7=q`$-Jxz^|}(R{Jx>ULfq_i28S<(yxGYDv!}mUDhxsQHor z|6cRU1N@L#q~}V@Ilu1H{A$ZN{zK|W{#wg9zZPnKo#ib5hUPa|ez{54p!)E*?WlOR zbCZ?lI8!E)9!wuSV(WI4y-a>c{y(ZG|b z-|_Yd%r*X3Djp{PpyKNO-Rft5HftsRa)4JWp5=J^-DMj6-)Z?*tUUWUt&Q}ow4BFL zuPL78c>9!Q7(KP^#Jzn-ng3n!Z1|l5ZU+vV6P~Uz#npYWwafM5CCy*AJjd7_H<#q! zw4Ce3O3haX__TQ>|8{`iulc){bG_JaKFPmtIp^$$w-y>shS%$Ch*X z-*_R(e;VM6HSZ4apEdt1z-OI8dcFwo4>bQWz)Mag`L&jF{d!6BZ!8~X;(YvRB>%1D z9OrJ$zYp-T(@B1vNmZ3Fx*&4&bd{yC&)Xn>!k`Hlg;M)REme9XC|XIIO){9K`V zrscy-JhnQIB+Nvf=SnXn&(^2dUjY$@}n(hJ*R43U^(mgQ1ksQXFU@yBs~XO z&U$Xue4OQcU+|XVVg1Fxi%3tQmFMz*h~jj=`R)KWK`J@=sMGR?T6wk`xj0;Zx#H@6 zHX#3*<`XSfw=McOTy-ewe$#SQXZ3Nl=7(9%`R-gw@>4Bme`aYu&2o<0A2ctqob?P_ zLVBiK&h_XT&C3FO@MR=FBfwAB{FnfLPxE5~e5z`=)bsiPe^~PqE$4cabp^?nTRzOh z=YGvAE$4a^y^`ds1N=(OYc1zE484lv>n!JZF4cUt0PaPtL2<8rE0*C?X(B@tD4WXob{9}CHeW5mzcP9D<0;jb6q$e zs(7}u(CYcw=ou-<*DFr-h-bv_GVJ-m{ zeS_K0djvhJwVp)*Jv-b;dc1v!SPpm;IC#v^+ndSmB>{ev=1T&6spgjl_XC?etAtu-3$Ho#J8o*9&}u zJHzG23A|X~ixek+nznHL;V0rx2=dPhe3j8tU=qQ4HdO%$OIM!aS|Wl4fo3opSqm<@qXum{l8vw?{_ZP);152y!Sg7Q;eQU#aYH6{b#9` z_kRDP-F&(AgQRDmX#We+`#lRTCl6@u{XPZzxzR(U$NPPX5~F{n=HBm6aQ-%H zzGJ{{m*(E@M;y+6K1}*E1M;<+d%p*9q>+D0bMJQ_wlUmksc5ZetZA=lZL6tht*RSQ z)zad`CQUu!&_kxiVv}RBW2Z$&k1t`NQY|z-uc#y%ZJXN|YiVt+Y^Z50iH_7~R;>AM^Eco89p%K1J$BlZQI*ZjZS7;ovHH0+QT`CCnO{}Y z(q7-(ls~VoqP=KtQFLr9Rx-V)tZZg%;!)GamrXumS}Yc(V{~;*dqsUibZkp=eUnOc zthueGwZ5XEeql}Ps;BP3o+^9xMXkQw zWYTD*Wm;+bSeqNFT+CIhYz9IlJZt{^Sc@uQ%}vUw_64!Is#qM`G_SFQq)XeITT9!c zBV&`B+hRww)HF3VSJ#wM<|&%jR@2_nT2ocurV>J4m$r|rsBEiNpQgn}Fr;vdj~2NZ zV;ziDDcwct;<6dNUrusHDmuEoxxJ#HVL`09wYsLYraG$1N{owRbYxXSMO#~}zB<;v zpru9`jRh{qn_QX~t5@G}0nDvwY*C?5*{*UqFIGf{iJ#xKc=ak(6o^3O7}?%hQFT&% z(=6>o)!a&*7Xh(RuCGn1(i_3)B~z+g+4zXEr@nF>9ixkX)0~Een5jgemiY29rdoLQ zEH7$5SH~*a;x zH)ki6n>`v)c{&^Nv`5*hxznf2#{3GDHC;G;I`VR>nj0EagGK3TQ>|SuiEB(HapA^P zA{*sIhF?R8ZFCchZHlTW)2HY*Vp^bmR%WPKnKq@Mp{A{^y{@9Es-dW4NB^QBw_>?%TDh?QvVYk&PAeC)X-PWih47 z)uvju#`-2dRqbm5dl%x4D)}ldvB}jnP3@{>ovhA_Y`RM;^m$Q1?C@A+&8+$+EH&JC zaWyT_-C=D-mFn3{-xt~+7Uh@K)wgk$Bo#W9Gb(iL(J`DLFVN&S<%a6UXEn`|cFjOT*;S{MgjW+@c~*8xW16vq#=Ful!xbUXI&}e1oq#EUWk7mMp zgpgRO7MeS=L~C^DX*w>=cmgB*HnJY zi$!uR4tKlZJt)W}uljMoq7%w!6l?Sypou zwaxloMBP0{Cr=4ZHWiJbe5`4&*UHN#2PO0{J{6mRDIUK`zd-61r&l!1sl9XC0pHXWMBm^<^dyBy80r+J8m1&z(E zEp_!~KEyZw$hS(p2i#v?(i!i7?sSDapg2v@4(LsHuzgh}t-2jcVqr=c$cRbM;(%k13*tINnAQ(Ho=YG#cvF6q25y z@~Pnl(tEn$j>X&?mv~_gVk(a@@~B^}SMyzJhAh-0?y*N!FHqCP^;LQT+&){VsaEqt z>aj-(E)*51LSXC%rPb#uiCjPDA}v#sNu~8cm+2Z;+6z zUQ7WLBy&n+AEZKcnH?pbJL=^s);U{QkEOj z&pJZQsE6^t}6FdK2(*Q|85T%{*b3AnWCWEsGf_0SP0c~sboy$QzO$? zQz03djBVY(vF&tBH{{bpHFIB*L<>M|I$Vk+bqYUxj(Z`h1<-pL4{O>CW#tI(#cdgDv}{?^i;=^ZRx^FVt+Mtz1xZ_ zK_TK0Yd0@K8ydHmgk5fe-$MYQbc84f%MG`@h7ZDob~hSzAJw|E*zN=09#W$FKcRI@ zQq}CDBrgaFLWln~I9me0SV^lUm!9M*F|0YgFR$s`V;4_4C-^9C7ZT>$l!F^o*>kx~^`U$;x4Ooxeo)JNRM(^z->SNm>Kd?URIR>h znbWQpJoL08Cmpu(%<89K!WgZSRSSRHC|tosDtd+LQBCve)!P(QJsNAMzeqzG?aIsK z7TWM-p?AHe$L(#gg@2Vnpd$KakNT<>>SFR5b9uRJdQ%$TNhR+VEmjG{ujeYALIRTL z6ZH(PzeVj+`jR!8QZ}o2CTq{vCjTO7?6({a>Cb&*`aY#Es5aGH3TjM8J_NP)U!;Rw zaayWN$iOD$SckZpj)p6!w*R6XXe8AHKCFL8zEtP(bDPliG+GdR%t7OuZ9T z-M|7B>bb3crIY6NjE2hQR`rr6yPt-e?)WVCD-6yQ>8BKGzS|eMu)KvT=GWWnoo(+O zcw9dAgMQ3IA>QhBNm_D6vs}GSQiUYQeWFgQY^qi17+v2qxA`QsZi`k-@v?EZ9{E$} zoAFaGe0#4wt647fW}co44`!a6BdH}N0pIn@(t1^df95b48ND7sy@H4H_Wl?owr)(7 zQd|@lHZau2LRP~iv3M*6D?9<0@Psn0xeJL{uQQhk8>nbflhpo6%-}jcU;R(){v+98 zWPIcFi?=HZI8wvO;U)s&}81-M=dIAworoBuy_NF-z zI)<_GqoDqD%Gbn)c_BCPNkl;3Bllwmkc2A*vaWr8Xr%h2ENuz=$PyljfG#9#>HIr*5xfs_Au2W^c~- z`Q4hJ;^=4?nd*h9@{T;-U5%F*z3WF}LyO=nMH&VVL8U!*RB3YDZzF;3sP_RtFe&lz zNxG8_D)jpuH+1R;{qb=TifsxnLFDDqdl-R56fi^LOH?xbZ%Fw1dOw(&SzpJF%Lh4m za>pJ_ML%}kg0ZyUyZN8BN<)A?b-y8rfDSgPm6n_>cI~0RpGvUPi$)u38Y|TbC2FjD zTF$Sg6>?+3vQINoqQ!PS^s;7;w>&UNo4biA=+U58a@E?iDWzk2Fs!yKYf&4V#az36 zwwORKFN7zt&OgBnOH5ghu}dH&zl;^H&+K*Nl5~Q&{o)Zs64Q0T8BQT%i;CP;>CH_I z3%mlUr|`z4=T0pNR}yf58;#%!z9j7QVUp}z=y&cek#>HQqy zM}%I@OlBA!aueWNsuVXY>@OqnW5e)i^j>GNf;XJ>iit*6^&|_`s~Jc zKp}DDp;;1lBDF=mYL&UsIhrN(&G`^G?q+Mx=Y>t zc;kynZ|y5LZTNEw-k{Du4okMZHDihdl_%W$WxuI6CCsEGCXG9;G>QK}1 zeL|=yx&02+*pIjDvb{97@<|!uI-k^_DBMD?eL-U5MA)lO4Z-88ORyyMTBYk@l%wxX z!h)UT-3jW9FWAZ7RcKx5tfTe4jGRK!--qg0?;AOVXq9VTLTT>n$jK-VaVUvfN7cv1 zultp?_Nf9Xb-mV>glnX_tBBVZct(t)5nqAr-;q=3qww^Mocf?TsgYC9`ujd|^6O1< z5yYK2> ztm=k8JaP!Gx-s>AiXADf@&mi=jgWhJtH+)L+&Y>^1eHQyLG2nmM zvWN7h^G+o3#P%|UfZJL6%Y710LK64KH?I(8U%tCZ+)TetHYAnlA%m8_4~%G2|5UAW z50&su5Y0y?VHWPbdRQ~77pzLPg-d|A_%y*;=sql;?a{A(UP;@FZLjL&)1umf^e(FH z#kgCcdR#)Rmtpp(25*+-srv*oH!)>2*6-c1gfjLQH<-jtbt=hBYrD^}&W}lzyN6}D z1@bU6nWz83#wro7yy~Tw2#5K??NV?BgKTnS4}thadnt~==-wRa_a2Kq8Px|*($ssg z3q1w{db0SDVy^>XwSl@_WTOYT@Ztqmw`3o3q0V@BlAjvay3#oyRU3Tk%Hb{aiLXu} z>F1l7B!-!@eN*EhTIDL5P@4NXHExurx$4MT`&12-Iw;aT4bEn(-&g46jiUs6>AnoX zl%KBlo~N@p2Fbs&L_cr;svumo_)pm8}r$5pks64?&e?&~O)eoVI=9|!|9~0J(!a}Mh=X{b?MKwo$<^2(? zfDwvPX?vb(E-TfKzSY#k+~2*aSHJa8(cY|n(=6~9zo@09h|;Z=-rK#N)$cr3wbnG& zG_~trV)uAcb9D`EKA?63?28@!mRj)Ln&`+$HSN>XK8$7`@g81gOW}tfM!8$!*&prI zzx|-Q4|i-x+uQa2YYf3+$R#B3?v7sVVfNso9q>|7-uHC79i&Pd4J`FGe)O|?z5VEf zoXoy^g7-!0mxO{Q=}(>>h^ai7E5$fkOOADARr^JAJzO zN;pyda5oleTf99B+YHY%Bk7n?4t2(>ANqbR%mr>n62D&ywbYNTzjQ+-`;q2;AuSH{ zsmDmpGV~?x-I7R^uFQ^x}T6Ks`<@i^j_G zVnr~M>oXnAt)&q>4I_Kpk0^<->1|X4wX`P}+%1a8ku>F;b|HaIEwOGO;pk(K5(>Wk z8QorAh(gu9_!E+Nq1g8Nx>T}OlU)+5^sAS=_03-XR6`vk_5xlBQy#_uiR;8|Dg@GL~=)NK39&%KvswZXkCbG?~)5-)l0JUxI%jRM4 zq^rcK-{mHMVv|*(k7%iBYE-wnWGX=oymLhSypej>M0pfzu4t{QtDjq=%&6DMpt|uW zA@L_-wAH<qxNuM^&(@WDr6pZ9+ zYbK~)bvJQt9#z{gr>)LCiw^>KMTt$G@kR{73cv)XW#xsmwmg_T3120f#C@IQa1ts) zyiL4Bi1rg+Mi^qghv&RPz~W1K_!41X2^H#0!hQ=z62CrfXAWBz6Q8jb97sYzs0T?_ z825L7eD821sUy^nXwu6-m zD#U*tQU-5 z)Y3e!zO6P-rLDAmq&lh9r6Snd=jE!o`RO&a^-VR^c4*gDR9{;=J+KjgQCkgat4Xb~ zQ0tH#ie{=mR$0K?AQd&Ld39|eIwlr#cUGbw9M|9L#|Ub;%FjYV9)76bxK>*l#U@v) zM;-O;3nr`cqPW{Pb*_G7UH#G{-8ItF4>R0JgVubdRXt@r!? zz0RQa@zOs|X+xkb=`p=pM9T)%^P;gFBXdfy&AKIWMCk(RP(EoZLbd&>1edHh6aE7_hgEKcWhw= z`&iXpQ1Mk|P5rL>+(wmi&8iidtJbYl>mhW>6xCZQ-qPBvHh)vaQZ+wxTG6T+8uj$8 zzNA{0)BLLDIrL*$$=?*I8x(b2$gK}GR`JGtw%yK6w`y*kXsal-eQPj2>J}pbed_ij znj2G_lFhHEte+drQ=i-FV{YS04^vf1s%@sWv#iwDfBQy(S|+fAS;B)jeYww6j zF+pdNGvxQPhjDUvx)L87h9ry{xkMt|n^%DxNzyBS6q4(lbi({D^g)H>MZ%+v9vw+e zi{wkM(>Q@nw5Ug~`l?UzFZ}1&?1qA>A;Eb9lSxVcPB0~j_n=H(W$sv-P*uHqMH3I= zLVmO{E^Nsg3H=F0t&>BSyv|(Lr$81{qsUr$V9Vvd*9=ypgGBp7ceXLC3GQEOoVMg6 z)`ws9O+DX}h^YHRP&%SXTt$OOx~9zE5pw2xyLrZ?hQAKkR8-4N#tlq+DpV=Hksj#5 zx%i~2mkSCf)V42XZZ7e6_uY8-;>+s#@ulI={9?PDtTZKKl)Gsv|EeeKXV9Y;{hfLt z6BF1Le3ZSRGz-6aN=Kjdv44GPje^VN;(Sc2&Va3+s&udYL~vZ6>c}GSB*s;kT6_hi zJUr}MfF-5Dm^kjSh50*B{jJ*2oTxv8&BqPY-%7=Q`q@49Fr4IPf&5+|UkmaFf&57z ze<;Y$2Kl2vz8U0?1^FhBZv^>MK)w~^7lQn`Ab$qPF9!M3LHjP2j76e-3;u@PPx|FDPG-Zx6g3uKFGf$@Rgt^5A?hNd>=^f55U()Ji8ebFm=$MFMvmZw}Ad}z#Y(k z1n|#6&pC!u9F({{E&%x@p#Kt(zZ5RG7C3!eVa{(ff9cN>@aGM~{dV65`OCoWe}QiT zd?S?>I!I53;(QD=oG#lGQUkUte;MV~EUf`RWvO)33dPi*z9mH<{ zJy!xp|Ca&35#%2Pj{dIzj`E)XzZUeY174v%bKEvkGIaR;9|j!dqrfq}M*zQGeP;b9 z0e=(ho&x-4kbf2U?|`obPWk(V$=|Iu*6wTn|Ecnb?G6J@@@tL!c;H`x{K>%4?r#PD z4si76N8sqspiMkK(VzW*qdzAAM}IyAz7payGQ-pVXW+LB{GY&Af&7u1dU{qve9i_= z{!gF+qmDZS{;ZErHS%kHob_x?6;~Z3hWfL8ob|j79R2(n_;Zl1Oj4>2)?Z@$843J( zkU!dRQb!-xneuZy@V_W|J}N*Dm0>Q2^&pS!b`!{ByWIxz^l_l^b3Smidm89LyH^AM z0_xpOpoczgZS>y;@~G!&;Hc*X(1Ypv1IS~#R)Rcz%rtgi1CHrh4SLX@uYsdKKY$+k zxR24l9^_Ha_M0mqb&we9+0AgucTCqXkjHfG3G!sBz}OuD9Md%t^q@aefulcVpa=b# z3G(Pq6>#hqnt=ZU>h+7jUx9M_A@HZ6{Co`@+wB?VMun1p6X>}W_!gk&LEx{0{Dxa9 z1?nI@ZvY|{e2^`Zqd@HS9>%Rf~84DcKRR;V|;LlRvUBK@Hj`Cf=PX_t5 zz;XP){UFaz9RKeH9Q)q};27sqfn%Ik0>?PN4IJZq)z+Rr80TfcG0tm&W1J)A#+C9H zOESh7^qXI`g?|_~?j6AvbE^w6p2>5m&{|RvR zpZvjene5f+`Ud2Ye=BerOLH7h{@(&e`JKVfp9J~;0#8K#XOPD@M4){@KQ{)x3;44E zaLz}HKiwm6dQpC$z&8Xw0`zYNd<^g(z<>1fU%<0Lesj>XH}LO39^-)dyA#N733|}( zAmEr@jL)v1=MAun^=Lb#hY#f23w#IQSkBjg{$x4EVJ+wx4*m~^^zH{7^>iQ5kMZ0ufw*D5{|)>Z2L68xd?fHuV0Ta8V}R!Y&j+3f zyZ|_sw}XJA{)2&|{{4ZY{zBlW=TP9N=K$cSXFTv!;#LHD(4R@b(Vqi>qd&#KF>ccY zeuThFfDbYGLglbjaXvV`#LIwZ8Ubn#j{-gW1D^pL{hTiFqXm8p@WG&eZ{VYWV?8|t z_;Dc5=_UV<1&;Olc;MJ?#uVrA0JewaAdl?^&bRc3o|-iIlP*2=Y4RssdK%N@PbzwF z{D9>F`->JRKiI!-1sul@8v)1h1NQq9p!}Z<^4kOd5!(6PfwzJDKEVG2@&^HL1$nHe zUx7T16Hq_amvtb280bfSG;kcxV>>ek{K0xRU-7W|y8z_TAIz`*&~sXv{7ILdGt=Zx zy7ZizCVx`VgXQ@GC?{NxsDH$A^(!c!i$NayM=WoXKpxBUriPRLi zYZrrEuD>LY&uyb1-vRR6pZfJ50P>fBe4*hakI&Z*15Q4boAV>gUt;)ttGwOF*RKcf zAFl^_>_^b9qzCQdJX<2|54QjP(f;r=O$r(NPxS(MBIO*{fnYhm3F3z39QCJK&gYx_ zPNbZp-BijsrWf0vn<2eeo~8B&$LHAo+@|#Kf%$?wk$l1RMVK$QfS;Hzs6W+w;rf|K zzM$Py@&(h2?a!@{UaXH&`*SGIH%9wZVWRSNBjNTb-m3oco#rF0ANH5k? zslCPd2W)R2fp}uRAWtM;P69ocFAssAm@lY5)qLT3=S1=a?WU41m|o16hatV#4kO3* zP-=%C13j3(j{{Gn9ex7j(e9JLIp2F~ho1s@sU1dt4g>jNrrwbLr-5Vp`CEZMBk zdIi#pS{iD|fk^C6LpD~;+e;@M2 zV7@-1>d(aFC>NP*xUVM?@ly& zh>wPRX#qYK_-Vjj29ERmxQ>hKDfy3l0_gb&^vnQW0ldHUZv%Ee1-se6_X5u25K7m_ zit~Zb5&jN5-w05gyFpJL@Xvrx0REOL3q0=Pc7^nO0`eF)@`vT?K@ak|z}rE75%9l) z-AjOf4)VVS{snMs&%XqYAD9{Z!O1in__UjyfMgW@TThra>&EJ*La zfTRDYhwCrt{}$xAUij@wdeH87pl1)`54R6pq);8KpZOxwK5#i?{*d8g-OKd4DQus) z|01!m|m&8{S5M49{N(=oQ=Hpg!?Jd^F8R_7yLv%PT)rX9{~Ex zfukNC7y0d;CCFa^9QEH09Q8jU@ZErK0DdBm0N)AZlbw&<5cKf<2&EVM>+ztU-eu!< zes|#54&yih->1NK7~iMBaRTZoG5V?9Ks`r+UDU(lCh{Nk%n|e~6!c)fgZ2GtLC^Jq zo`-;=KTipIxiI8l)U%OkkNtY^J!{mntC6QTV|<1SdiDl+ z)H5D9`ZGn)Qv&j+rw%yk;qj?IU2{Ml^+X{)*zaKZ$9`uj$YZ~Q=s<&)xx z{m$ti{~nBsE(VVA-wrtTM>rlB2=y1`rT%C$kjMULbAfLm@GXHS(jRRF@>!6sLBP>} zsXy8p*76UPs`2|N>cD&vYQ(38lx zA{*o}e=#31o*4f`@}1tb=W$Ca`Mw9}=?_1D1^QF*GY9l+3FQHwxAOcX^*eimJdW%3 zh4FTd(L?>|K1zO&IX}SsrMWlCM?NN*55&nXAJ}g`4EpiD??dSCTFiyy=f2=4&I@6` zxrLGU`?-st2jh(MKk3r*|F`(#^OTWL9=M)Tz97ePcrla*zKHS|Dm;N2<>BSJA z(U32k?-Vy_95PCfm&PGuKpw{-1p*%{@cn@&G7dQa~B= zJm&9Vz!S;eDIhQ9FScX<3-ucBBc_4>m|m&=9xljB^_TWC;_(>fV~N0z6!>)DiR5o7 z$YcJN0mt-WIl=mS6v#{Yi~dX%>hBEDgZ1}lfgdCAnF2pn;KvF4c;Knj-xEL&*54C> zW4^}(UJe}NiTQ%{w*urbe=C6}lD}0TFXb=lM}PK(_6qYi5xX@B*p>94KeeC-}8Y zfjsh7;25_PAm6dv9toV+o6z{}0~qg(2Y=oM`5D05!7e_>nFBnLdOa89FqMmV(zi9VUDCgWB()}IHWxO!JEeIo_JRAag3V}}r ze|Q}i)uRi5&oc6?|7D}U0rX4&{R@CsgPya1}HcTY%%fqYna~2zI-GH-X(h z0Y^P=8P4hYt4Y`UAU_%Oe-8Y7(2wm#2k=zN`C`z6_4h)7Uj#fAyBC8Vp0A+tAU$ur z1muT7eDFCJ-bY*k^3rqFqd*VJHv&if_?#5wFBjx*29ENN0Z08W07v=N!0|cPC%{qu zJK*>n1oL+(#E0Was=^kDmZ z8|cA)`A*fL*@dhmG=wpTbVTD_rnUv?4bLB13?>PaM? zkAt65JS9Dtk57XhjQ=wNe-`+j;QtH2QO`CI2h6XRKpvmR-3T1}mluH#0lU8kj&axu z>>dpAgMs7t1oubU1LOyQJg+0Aa2_U}#@KWHPLAjj+dw}A8a#NQV5yaV#wPLlk)!1;MJ@%MnE{`Up_9|-bNy4HX^ zrt3rCXje+tM<9>sDpTcw4@}qJK%T#+^h)Xa800ZuJ^_yYSAt#i=S1L{#xU9481$f@ z*&v?_^1A~s06q+OA@Dtb8{A`g`xN}abp0JT#-STH%Krm6#$h4&lL>y#1CDVR3Oo`2 zKLfky&*#8VkCg9UfIO!6pTJRnE%=G)tp<+iy%h9ddUHWO7vd8Ij`^Mkyb$C^0yntF zeE$;s!E{Oa{*@pv<@@R2PbTrVN={Q3|$ z=GS|``8sL`@VzQ5Z^+~1m7knXDE}|;AIsslz)}7?;H;1Q*$+7C838=gI7IS~Lb@R$&O^-KNE45|%q^@6N#c zZg7wJzJZV~Dc>W4yp-?ffj^nx=Q+SJ4%-4x#QzNif0E7jjX)3Pdnx#X`92HE8|Hf> za7^!P;F#V$fn&bsfL+Y@;UHfK@%%0DV&K~VF9CiR@MC~?0>?Pu{mB1IakvN4i*dLc zIK~0*oBm&l!+nrmjKjUaF%Ebi_y1BHego;nINT3>8&hBC`NHe!exHvV^MUv#4AtLa z;2c9jb-;NIFrg0Mq>GPE^MTmr4AtKizK#-oTj12wBp@E4yh;yFO zc`@*<37CW5BP0324AtKbkmp#@*PXz5Z3gibz5&jI2&G|{CF z;zRW(_rGG`JcmQy)B)!;)xvw?R2-yL`-@L|AL0N(?6H}K)WX-OyO1n>+~m&s3_gQc%?faijIF>ro%OkdXl=ec6y z9l%EtFh?hFo|~nwRsbKx!s>4~aDMhpUuT%H3i&^VfH`u27cf+Ri-C^?UI(1#TIuT! z;QVZYcqi}!37BIA@Pintzumyc0nadvBl*vB-Sl-1@InISC z348+Z6~K#tcLSdYJR`$BA^#@<&jDTxycjsIX`!#{fFB0(9l)mm?*z`zAn5BAzz+xc zZs5~^XPC~0{67MC4)7A-#lVjQUI%j07{&oUC9{392CjjpTej@M;S`?)Y`Z}gRx&P$= zF9%)>yaIR~@Jiqvz^j0F0wwP&-U0k1 z;GMu5fUf}F2)rA36YvZ(NFx86f#(2k0bUIJWZ-qcTY+}~Zv);5ydC%o;QUOAzU~G- z7vwX{V2=Es2RsM(eBi~v7XYsVz7Ti^@Kb&FX9Mp9eh%;zz|RHV4g5Ud8D?-y{+|y#2Y3hYV&EG9uLHgqcn9zc zfp-EYJv_!;0sLZ+?*@Je@C-AEC;v%LuK6wp_!5vW27VdvI^d+I*nHOk{0flo1b!v( z6~M0o-VOX};2Gv-gZ#e+_}0L$1)c+ZDez+8*8#5sem(FG;FR8S^Ia$K8$o^r@SA{l z11CLPS2MP8g(zLi+>iSI9N@PAF9uF}IM3>U-v;s>z;6fM37qtFn(tNszXRm|0-WM( znpvkC_?;mCHE@#Wd#8+TT_H*@+a!_${4Q5S{~rZTdiFHm6$8H;CCBR<*z7#m= z;XZgd@E1XT74VmUuLb^l;Dd&`ClrSjz;l8B0eA`Umw~qc|0D1vz+VBr9QdDruL8aj z_*&q920my9_k{dk1w0q{Ux1eYe-(HO@YjGZ0scDh<-p$nz6$u8z}Eu*EAT-(x+moS zYT&uR-vV9&{B7VffnTfmV)I=K@OMCd0dSJP&V087_`4v#9Qb>{p8!sJxNlem{C$vL z3;YA%gLZOHC=P3Y=K}u_cnR>2fVTku8}KE-sUPez-z^1B{&O3;95~5m4{$Gd0yxQY zU0ntIV^>uFzZUo>ictFK7-Tw1I`7uR{Vx~zX9}@=3GmN>w*dbF^eh4XPvA>|lmA?% zmjnM2D zX6dUzySW17{|3Nwfk%Ls0N)UJ3vk{mk2Eg3^4R2J**bYOL$k=D_Cz-vaoxz_$ecIPk52uLeE{_&VTQ10R~@ z=!5cQFz_tk6bFuJ0q|`={utof0-q0jJK)y>9|HVw;M)UV4SXo@b-;H3J~Z1)*N(so zfbRtS7~netpAUQ&;MW4@Js8R2QZ&pyw{&q=)y%>;k?Y$gcsO3*6a5U91kOUs2$h z!1I6?0v`#y9C$wPMZiY^Uk03GKz?)q=e_xfuK`{FdYs|(t?U0-;F-Yp2VMyL0N~}o z4+Opl_(8yz0Urmv3;4mn*8ndB&JPhO{)Yh1{FP3Y&X+@h7Xs%zC&_Z)6F`0u@FL(B z0H^X(YQ9?rd?Ltq0iOhX4e(;%{1BAVH5qtj4teY5*I~d5f%BfOBv%f6D#$MaemL-D zz^4K40)7PWHNbh#ShC9#Ead-@AfIU_UWiWzUI?6HNovZ0mx25u;70*p27CtaF5pK4 zUjzIY;LcuT-Hr21;F-XW1zrgJIN;^Lj|aX8_zA$50Y4FV7w{PHHNeY(^AAW2RB5OH zp1HS9maZ3-zzcy_0WSw$4SW&s8sN)-*8=YXPVMu%=DRh(XMw!4kLPC{@J!(Kzzc!T z23`*QB;bpHHvnG-yb*X8@Fw7EfHwno_VxVdy^)Dz0zVn#3xT%+F9+TRd=c<=;LCvX z-pgdS3;0}+Ujuv|aAyQv<(B{Xz%zj_0A2`uA@FkGrvP6B{8Zq}fS(4u3;5~4*8o2Q zI4{ni^1ldp=6*U^y8NFByb$ZSavBv1h z$kk@FpM(}i-1Du0Q@_J?H3#_lpuZS6>EU-~js#A6IPY74ll-`i)PL$&0=xtCF9&`B z@KwMU1AhxR*}ckqw-)$?AU`Oo&FeT^1Uwh`#lXh`C;h)R-<1Hr1mtG|C;3OrcP+p# z1^FewmjGW5{4(IHfL{)LE$}OV56bh>dnNE(;2blOECGHs$hQE$2KW--*8*P-d@1l% zz^?=T7I2E&i{`tvz^@1SK_k6%-2gln_>I6zfKxf7y>IAf0e%z6F9Cit@a4dl0bd3D z7T{}v-wJ$CzH6V_liPsj0>2%232-ih+JE4buG2Sh^)B)8rY&5)6gb8CZDV6OaMDvS O$d!KrILUuy^b$Q!5&+KtMFnho_C!UmL5osipN^m$s?$w6Ue-|NWksxp(#^L2duf z@AKPyviF`dXU?2CbLPyMxpQZ4c4nTRo0AhUpWMhf5kdv0#Ra9lBayO9uE6|?MyZkIn5&VHSC$ui;`&xy zqrXrL%{3A!lyv5!tdU+_VDDVPNA$H>5+jkKPbsv?M`|X;b-uW!H&;_Hb2as2-S~f` zF7C+OI3U7tUbIxfRdfM-$?uc%c)#Nkm2t-<(?||jU3Y(0z=*k;e3v4hu7V=?h;Jk3 z7Z)#@d&cQsTs-fT#fz5K)Sgm1>5Nm(IQ`TW%TApj@)v*)b$7wVrNWU?v7CbhibO`? zx)T4yABg|PlfQQ2_?(dkBrZMd+*{^JvZUXDv|9Y%g#T6eufzXp{NId!er~~k1OC_I zzY+iI@Sno}?f9?jT-Z{4?Vp`%r+@a2oQ2Vck6$uk`oU|O%U@nI{IwfrT>tds_tQs~ zJ$ho!@VnkRplNpeFW=l-x!~A;?m1{dX+^=IEhDDiTeah92epYbV8fY zJdHma{A~PJHUH~E^iOH}%R_P=uJMH-IS&(b8`8r{E&sBRJP&F)*ERm0kem}W{;CjvQ|^wC9zN7^HV%P*Dgnq6H@t>gSFALG1r19^D_@A%knTm9~-A%u12+?yK<)oZ*IV~jrg<3xchxkB^^7(m4&Pf_y5t8#wE&sPdd=Ak9ogUJs zvGds>y`ebyw1xN|p!v)U;iqf*AB6aDyy54oAwOyS@aRyzPSo`CLvk|C;%9pZZ|wQC zkUY(bJaSJ6zh2|tz}0R?W};}#K+XPG}P~mA1({=U#9tg5UTGmU9bN^x~-q{HT_RR^hTc(LhX*? z4ufli4O^d*{4p{7rv zT;f|bpRpSMnC8NuN@_dMfrkry$-ss_Iv?KX9Ydx6y{z2Ebxk&Mc zTI6#G>LvBn^oIWn+HUK0dyUcbPvA=aeIfqe)pFK`^cKPVa7A)n&Pt9SU%9Yid3kbq#iAq-j&u6_ibabRF;Y+0#Pe4qmseFR89c|b>Z+wq z$wlOLTKSA+E6OhcV#%_3RVeZDD=r>iR9;?LTU#-A(aP}?#+R3`T(YRVlERfIZ>+8= zU$k`oG6xl@tgR?tP*bsdUU|jbWy_PuJ1cp5W!3WKQiJ3fiZDmz;a?!G-Sru4bwYaKc1*;F$D@MYhVlgX`tSYy&EvT(6udZ6Y zV%gG)#fy?Rmai;gJ~Y&sl~7^j%H)j7%JER!5;Q#XCY|v`^Olv@EM2j1(fp)y8RRdi zoON3HW%$pk$C;w!MU}cS7cF1mTsBWA>US1p~lcu=n~NKd`I{PH67Rh{*dc5t+&C})LO^n{}FS>;trs?njAS5?D7 zE?Zu)pi0?-@g=JJQ_!V1pfRM2&aIeNURkjM?O;2k%CFQcTCV!@&`mRa0-Lma-i=Eu zmcYR(F0`&m@U`V|N>!)NSh^^wjdxaZ!sPPH=ECz<(Fd-mf&;HuIuFv$tyo;Kw6bb$ z33|gMpJXYVfiOXTzibwS7WtM}B^NGVc7s&h?>qaoV$*^5*RW@xVV9x1h;JFRW#OMz zOss@jmun;B2%{ZEme`AyRxYnvQnfT$f&vGtj%u?rDylJN%wv}X0=fw*?kl8x{<7ue zRm-8rAv7aup~636h?}@*$=sSMifb%E>2JtRcisf4WmW}(ie;hwW>PG(oBreU!O775 z;;N+!k_#>M(^YUZM58FaW? zIsdX*%Vw2lcN8^Rjz0r~1S~a)VXS<9MP*eI&2{mta{5@gnW&JE5Ix`%$O+RKB6`^W zFnAhNwWOlfsLPDg2on}#c&w_euBuE{!8J=yG5sVIkc>YQ$%6+Yut#*_WaUCpKHSkD z;gXD$Xs7{EhxTP>mcz>C&VXM;2y*#&(JP2isK|p3jc|uiff~rzi=YbR(Iaq{Z6O-a zeJKlVn_Q@N@Pg$l28*_&m-tbLvTsq-TttscKeF2Usqq=*R7Ux%s$})@s>($x7#ksI zU83UEWW~~jk;TgvM5>qFFh8>5D~R)O7eQN*Xh9`h3JJ%f(STpHV*Z3kdFj#{7NIFF zt6EXB1U^_2<{<$YDizoHG8{(cGZ2l;PgX5n96_{7wMGyuFJf@USQs9b!7b9rFtTXH zifULft`*7Tjgk2as*;rv8joaKj!qb}~5R)!NCuJzd+Ra~4Rds!& z5+UDmMyn{1-E=4ZJ<)@um zB-hhVE#lqG8PlehPdIhLsS_j9%gWB3Hluv}si!G)Ss92==cFVT&jN?xJ6FEdy@GS` zq>p!sN~I6O)2Cs;EBawpPGSrf;#C@H4L6oV3StzG0|YXh4F_IHY06P}a$&iOui~Si zsOG5nnC}BM7sV|*7dhE-sXVGyO1>QAeiL)S0#v>T|0O5hh#A^}k&{L!+?*>vk15~* zkqLnL$-&{Y5|20P}Li(`C*;e|~nqQEfXQk(YgUXLfl^*opObr#;NGZ6n(3vcG##NTS+&3u{o+bz6VA0U2>g*WRD#Pd0) z`Iz}N@o9s^wNUGm>pyG<^BHU5RZmbUMHU`Q0RCr^h1W|Wk`}k{EZck%7T&CVFs;PG zn>8uo%PhQEYao7(g*R&x#4oh)FhBoOZQ)_I{-@T$8&hLqy@em?Q=?5Syjc@ua?>-BElttff;g7cPk>9EQPFpZ*c}&i?@P$O^Pl1I$ z)*x{mZQ;jQ_(BVRoP{52;g7fQMHZfW3(RMdg-;nIu5k;0f`w05_!BLBiG}~Xg)g)4 zV=ep~3qQ`nFSPI{S@>!T{{;(QYvE6}@bwn{6brx3!k=p4n=SkoEqsfG=eS}%trou4 zAaUJj;m2F}HVZ$&!na%a(=2?4g_mJpr*&EQi57jgg+If>_gMHdEqt$qpJd@(3qRSy z_gVO}EPTI(pJL%7y8`<^+rsBtc=Ifc$psev9E*Omh3CE*^C`6OUouEs$6ENfg)g%3 z=UVtl7XC&HAGh$+EPTSkPq*+T7XCa7UuNMQ3qQxgpKsw8TKEere6@wIxA3(VK4IbO zE&L1%zs|y6XyKbJ{6!YN#lp|D@U0fU*urnL@aCB@liMu(B^G_Vg)g!29TxsJ3*Tko z&9glwcU$<&EczY`Kg+`RTKLN?yldf0EqtGazrw=zTlg=eb1Zzq!dF=M5)0p8;ma(% z(uhi&W8o_;`h^yLo`tWr@KqMR*22%X@bwmcfrVdZ;TKx?W(&W_!nas>^K6*Otrq?| zi+-bpzuv;PS@^{kzTLtvvG5%heyN4;vhd3+e7A+Kw(va`{wo%~*TOHi@UDelVd48M zeA2@ATlg9apJ>>f?;ebZ*S(!z-}`k=B+;-V|Al=MUwL{=WZwxp@f|xRjyuBA5?=2< zd`{R-m?6E_E%0-Ma|w3{{3PK#!fgUSN|>R$*DCOXgc-7X%>v&;n4!8?FYsN24lW5k;y@GXQ7B3vTyO@tYWdvSr66J`kR6$yMDVTRsbp}=zqGvxLP1iq3mLv1f2 z@MVM-E$~@{Ic4-Z1fD?n(}dduK8Y|xZLd|}F@zan zd(8qLL71VnS1<4(gc(wM)dCME%uw2!BXBNZhR|M#z<=Kan4z;57x;a`44J(mf!`y{ zP}wUK_#MJW5iSt;SA-cFdl7+OBg~N4>-#6`{|ezk!o31-C(IDo>lXMq!ea<`2>c}B z;|RA2{3v0Dx?Zcm4-#g`>NN{|4`GI?UcJC~5&k^kYJqPjJeKerfo~x^j&O;cs_KPM9I6S0wOtgc*8zg#ynd%#hP75co>M3^l!oz?Ttbi0Sq1mG&ph(9-J_cp71b zj$XIGXAx$|=yeD@fiOcwuT9{S2s1?VS_K|Mn4zK9EbtM884`N+0v|${p`ceS@NmKm z0lhf_=MrY<=amTj_oo0ewIBdxRO{d4&SMLwG9T0)c-;m?51P5%@L2 z4B5QCe@OcijuY+`cspT+XkNF#&k>$RxI^G42~Q{7Ch((#8FG280zXKYp_bPy@I8bX zVtMrf-$nQW!qo!bPB=k$j=;ANo5Leydr_GBh1jqD-?JxVTMFr zfxuT1W+>!E1ip+gLm;p3@6!H+8Txp=0#75%(8lW)_$R4}yd>LU5-Cke6v_D}E z*OZ33S}m_xGHD)1P>9E!bWfsY`(l5oAihY-Gj zaJ9h03D**yBXBO^8wr;P{P!mT-$Xbr@cV?nO1KE{_&?4_y?SjT^-iK;S6|8HGders z2ThA4I=7X`rL*ADc*K1d72ng`%$OjNjz0UtF_A=LM>2O`w}b@E_NO$F`u!{t)=wS% z47`5LdF@4bg(PvxSblHo&r39w?E{lN7^M=EUs!o`qM;)vk&5mDyzkH#g(@BWg-X5Q zotL7o;WmfmT=nt`v11~oiH51m9s^^Pll)9Osv)wB*g6UPXQW0yn9Bd0~yIho9`mz+#a>}e;n&e@kaDUEVkV$ZCN6poq}X+f!L>UMX6&*}n@ z?30WghcM$lpR)eb(;~60-Ar#9maB6ghTKz}-8D}PL6+)ZA-$tjA&~l9NNrbUJZsV5 z^yMJ!Fy2pg`eL`70$T;gmtUY}QgwS@a{iG+q4#D9y?0IBUSH^cSVI59rwoMtM_A~+ z6k0RPCd(4q6cW3;gDQ3QG}P^h)O;4=uEf}tF5T<5%Y49+m=C@wr!RA0r_;waPdk08 zCdhO+h!Wd+^Af4;fbs}YuyiCHFHA+J5Qe?MD+WZrCZvcG>39JwU^g-8=Hm zR$hG0j}S7MNR?1jKf)#UbYxxhb=+vF8g_$eU4NpXu0Il6+brhf^moP!DSRUB^rP7P zmx5dN0v{|vF9SuYq=47X_{lkbevZ?W^C%XLJ~#&Vhx6W-GLMj!k{ZiTXqACiUt)^W zUlVm-Kp=-sqWZ|6(4Bo<*1&n_6mVV^K z&j#3Zl>SWdHJl?l7|EI=j$ z(y!=SaWFxfLc&x{e?#5goSM(Cse}83gFAX_FZK|+4SV+OdoD42T4W1L+j{#X_|4w{ zr?t6-v|HJb?i1*VM#tJt6pKC~XRE-0D*H*-^}93vX8^snt2JPUW-5TN#u!HM-ZzH7 z{^+BOp%D3dNag3*Zt~C%C<{%;kB6;|lr~M*=DV{|g9Jt63@gwMST!yISo1|$IVM^;Qck~EbH5S`#e1-06goO9ORmXctnR&>Z(u~+A8?zWK zvltDm#c`?@mt|!++hkF-a9b472}DDd6HvynSs4yC8AP|S#_OexrtW!SOvHTz6Bl%) zUAR}eoBBth?^5WuHQK!$@x3;9@eRHerfT}w+=+BepZkNq4zxy^!gv2N2!856;S?}> z_HUVko*}&5SHNIvF63|vkj1z5baV#fpjjk4oqp<`3boPss*-f)Psp#<}g8$RB z!?!L3WA|1hYVt#c93+2d(W%b8iPWo7@CT17id3|pDV@=`apA}NKE9CQw?sFU(4t=A z?d0vT+twqg)7i`A1)#SAo!Sm>2ctkc>Jm@aB~D$3Wbv(#a}_zHqcyysPFl`iqZMU@ zOf-!!a$ZLg-{#IEM4N-;A+gUzl4Wz&`0@{k=RT<{Bu|x?tV8Mh9=BP0gaUKEI*~r? zuRz6~j(!e#)?vhq{xmB?yPp9AQS=o;scF3Zeiqr+0)ScscQ)%0St=*?MqD*B>-C3VI3GN&Klv3wLP@itrX9|71vzJ9=j#hmY zLgkgZ>ORluVXT+i;Oxx-W{UIrs$YRIxo%736}w8C+mS{bw2Y{Z8K7QqqON-_`)LZg zMys&Y4_WGqm|8>X-p=^(Y(w5!{}|hP|xC`#(&ix)OiGRLspuy(FXZ zFcA5B~Hv@PuHd*WuDek~2>x}zZuEGoKgqte>3 zxL?bAUu#PVX{}*2nBYc*d-U2Ys)SG-iME*f$M26pAQ?xeJ4jkQ4=l$qSv#~7vNFab zqs)1r2v-`#RhraB_h_u5}R_m zaQjFW`PW0_O(i)PKZ$G+7ZtsW_mj7;7``=eFdF8~zfrHzd09*@4w$6llc1qVAel|1 z%<2C2Fz;SXjN3+AZ|Kjd8PVzR4ap-^DtK+t%y4W|I z?oQ`*Dkbwd*nJnK_K9?H2RdehgB6Gdrz@wyc^&<>doud;+u*Z}rTR_y142qI>G;_V z{kb)#gXX?0n%jJug3jm`0Q{t*?YM&*_hvy#@>)z!G{_X86{6>g~I5 z@(p#nBCGq>;JXm(3g|9!1D2o3Vi^forsHE7jsFvJbUH3q!8@JZ_>N?#;op4EuHnms zOv9s3R65;gL0N^6t4pu9I|oY*=vZh_nE6x(dE9mv-Pv*BMfW8~;Cp!TfR~)jIb0vv z4Cm);#xV0W;-y)y%PREpk5?#p*TAz(ef=R6cmoPVM?fiCq?9czWeZknhHvenu5N&D zgWRd;IpFSbEO&Rn<*1=1Gr@fZKswUUKP(wj8O}!r?@rR)>(imI1uX2k3=MYVRk#<2 z!k+#xfWS1G3568bbT&e`_qWhS-Lc@AiatpO(Z}!&`({-R!maz*yQV5zr7Bxlm91+# zVvSd@yR?PtktH3Sh;-B>6+M}RSm$}rR>IE+1r3;v9zZHHe1rVyEb>;H9EFL?`#F(T zmWHe>OF~&v(c^$gJH08VJ?*r^D<^EPJSiQmL^`@|V+Km?j9v;zHEMJMS)sK@ZOsSD zT|uXwiXKTU*86ng@U5dqpz=$Rn3gnT7~UEERKOQxRkRKgkyy;dae*f&%z~Ly3=1fJP9!Q6@w90 zY3-%kce(JnGi%{<=bE~m^bfLH`>wU{`L0hHtZ2R~7Aitam_PO5oLJ+R-~vP?*9wu#rRrI{O-E;v4fWt>Ydw-H!qMqS$e`~| z!4*DoHPSh+l9g$aV7)mVJsOFVx38{9M-RoFN{k;ZE6Tk}(<48iO(2e@U8vh`4ysO% z8k|zmX@V_d<`z34>zyO9!-v%agcA{ZPH$va&eN1nV3fv{6(KIfDR^S#S zcxR*L2pB&VyNw5=pr0ht!(Oa~N$>0ZAXYH)uiqIH!8Q6|M-HxK+dhbmioOFJOy&|{ zuS{m-sRUBRsPW0TgC5ZD$o_2vapd!)=5wXR=R1nefi|B%0H^ru!kzGW6F1%l&1We9 z%5#Xt=Stup&sJQF36CUi#phn!37@ay#w*r*P69wauVAIn)ax_AfzJ)N_UAM-kmr6}d_JoQ2%lBB6Fw_&9`X3eH4xzcah`*?_Ny2I-^G;2S4sn&*pHH-Oz#H@e3%R=^n}u z{WUJ>=q`L?Juub1%{?Zk`_=x2j!$9U?#)B9B6db1$LEV=CO7qLfNlm0n%-GJSXG~b z1W|e_x{frJunaYP-N+P-b67h1jNF#?c*Sa7cs}8v{R!#8Rn)zJ2#GZy>jVJqNN|M; zPhY4(8k5w=vwNogIicCIu14n%ynXMyhT-mW%2e>elDn zj5(51pGX&N?L$s6Vz=T~$ezZ|Ew>bNICi5ID1+T`0j{yJuYM4_wmUX}yeS{2AA5IexEFM*bg7v3UT+_kl??)opbT z>7@!$>4px(mqm%D(yhR^x%a#UJPFSIwcIqjkNp%;@=1wQW3`0n_sNA6$B-hW;Phsq z-4W#4RQGfD$G?%AHuqO=kmx1w|2Yym+_Qv#O$UHx_uIe3D;|wElP}XweG>sd;ee7l z+{2KdOUfKA{J;D5zJ2wZnKM!|)?15yJ0RQ7-PIt{*}N4X!Hk$o+gtg7(!Ep!b9&4S z@kllG+t!P)gDYS?fawBd7T8d?`@q$|hQ4|*tk-wS);OBNoNuxzuIymS`>|1oj)kP7 zfQc9AL_4972@?iMC}P66K@#Fj$R8x3gb5#fLkVD)F^36T21%%9!UNd}H9gW2nO||X zRM(7oM~^!i`-i}=aUmNftu9=`V_=dJ@cmeUT(^!KiT)yE!1!NED>l0~{U6xNz*cN_ zE0ADX@eq{S=1xT$3}RYs?(xz%S*GkC%KWc3WN=A|xSb~Z0rcUHpjffts?9akjjO(XEE zDIyG&C1@VKxQXY#ADi8U8>jz$#BNd z8iA2gkP9v3uw1ZLCY~-S3n##2q$*fg+JzvP?5n3ZyKa7f3pe<9SR0O{Yj(lRdfcWT z;{`t~)%*}RRZ<*U!mY4RmsBfcZ4ol;dlfZv6{2KpRGjl5=Fmc*?fJe{^hTPGo-U%iHG1PIX#VM7`8UW%wJW zIm|#aZ2`-avoZ5!Q}R8gr6-;xA(-pfj4{Av} z8&l5nctXB;$+#(I%VPzfHw2I*i1*Kvy)l8IEHauHdKg-C-osJj5V%9 zXGqszt_n5&cbl)qgMuum5VHhoq@_D8R7ZDEqYw$}+=@E0FKew>6spdx(CW+VvE88F zc0<&=8&Pu_Rb^qc$PQR!zGg7VNRdn7X{s{zml+XIF=kX1i*4!1LFSXXf=r4V?0fdM z*w|M-h+W+k8;hCbl^v`{uaN{dkR&&Aq84i`ywvRCZrV-X4r2z_(us|7dNQ9MNcAhB z8vE+|h>qqXJQ6~X6^md<6szc+8UglL9g5yyR!`w zLXx*A0m_P7sZC(waV_77&c-CVE*dYAIR+EGdUj%rDdG{+&SR-uMZoTv7EQB||VI5GjQN_LK8qApRG%D|LHEOIwE|l1>T;d+z?BNn8X*@bD@j<7hu|#KX4}6~+ z`(}r1$a_m~%n^Qr=R4HO*Bj(pL+Q0_Uwe$QC9fMou5m-j6`@52JTpc6B@Bf2pC6{3 zw*uY82j~t8EJfcNbqyRvT|cCCH~-*2)Z%Bh4Wh-JAFah-W4(w232WSKw7Aow7L9Bd ziERI=7I%Jx7JK}{sYMwhVDLtZ`uTHO@6)43*(T}u!hk{|K49T=>KTplNu^^Rq!$HI zg*+zjRfNqX43glfu_B0QN#Y9^?58+;Z{87 znr!S~T!HjEKe*lza4j2*97vnIJRqNA$T8^pG6Si|fdu#DBfc;T4LJfXpBzY=dk(k< z`c@IT9U=DlQ6S^Remy<)9#Z3Ak5cb$%jLxy87HP|cB2pVxV_lkB|~SjETJNJsF>s- zPdImT&=>m1ha`7c*Ug*WIx@ zXJUQYZ$DM}evE}ifoNU^R(#S^${VNK{X3ScFo>+wTx5G5o0?S;8?LG9dbn*u* zzo{y%P_w)AM{426$O1KnRWKS$nU)Hqt<-iH-DIm;wL0*OlXpmLSd!JIcg%!N{Q319 zj13z*9n2cIxbze+e(&WRu00Ft@FDi>t}LiqTmaBL=B8JVCf>`cZ*5dPpOe~P@`6aqP%^p}~1-|8?p$b?Vh4{YG&Qdt-Ng9`2!` zt}U|qsP|(hIc;p09`vlNsgtW>_;wR$cY!LpzQZ4SIcQ@^=Mi9*iw`BKLdgF1dA5DigRRvqI*F_yus7e#ZO za$wPFFzd~5FdUc)9Z7x{`8gO4q)_=?ZS7sg+OLwqPYT3I zJCp3-HBrVj@G7OeDaB1OZ;EkK!yBhP^{<(!PIow-d~w0+TUrGuNDXUU94|S9cF9H> z>Mbbdla=u>_H_iqX_u@qsW#Y&w^uU9N+EW+8i7bYcIQnPD#BVgKnuAV9}*V-7fci?8Z_; zsZn>Y_lN&Kl;4EGToe;qdl&d+R!AA#xAdQ=`%G}v8qIcRAaw`ojjXl5I$YGIvl z@2WNWK1gg>BGW2kes>HH#_ct`IbbJJo8|dNYSSFHNoqqGFIFVpIAHO%zSCI`qAV(> z+0Ns%bULjh>2w~-qGU9HNI|XWj*v#uk5|Hry0J#JAS=>gmDT;!y}n0NgQCd@Uo^<_ z?#n;&otM-Afp?3v`2MrqrL)1&NH*|JIqNfX5@}zMC%$dsI zOTlfj6x@#C@e^cvDtrC-^gP&$Vaf*MQf?51-7M{?^|aHy?H<3u{wCWXEHzkb!06S8 zk;+8dbnocuLlbhzq#jDeTH4@5N~!f`oe*oUvZB0FR+QUh{>K&NcD15xcuZ1N;c7Fg zV=XENc%27n(bZ3IKg(>a8V4(ry{1Im1S^v$-dZ_61Npe_gEis(tQ?OOs_dwy2TD>a z#~aBWw#;9!f^aG4A$0j3_A2kLZ1w*d=B`~+ZB|D^f5}$A#GK96`ms^Vpp?;N_;o3> ze8tBZrwr8=5L)7hb94r_E|yBwT0gwKv<&zDr(xWowSFVQ$7&gQKERgQ_4vS+={F_f zCTJNw*vu|=A!YPlsFpEn#%z{8Hj7#_mg-2y#9CaS0t+SWUSUK-#K;yo*a1_rVCFttHTGGUt*GIdF&F3HrTGkwTR zYyC|5jU6}gwY1iPLf{u`Jfu$)qQ`cKJIu`pMG+}3v?#`gDdMCU3kt{>;adxk_W;UU zGX~XWl@mqbJTsVQ55^DBr&6j^4n z8@joqTO(s8^)?6V+rk*PSo>DGT}Ya1e42Ry%{-r`nKY9F8ZMl(d2(w+oOUK3p~S(y z<9tQfF8gyko$dnk0PO&{xffmU>_(s>?hiLHP{aaS7PduUv0men%6kJ}&<6cLJ|7U+ zORwk>CwJhm41GvJX1rN2=Gfemj_@Rm!vmabMCwiF%08sb2%d6*M81XBsjfBGhGJtoOdb7|8RjH$uWv1wv*tN?(sxn^++Y`N zXZFURZ=%X>wzsn~pEWi+=^YO<+?@B0b5iL^kud=vb9dQX5*ao8(RfmGyiG%cgup z)UD`itKFlNB;ZlXMxdp!zwBLNKW8gcu6%z9FU_H~4N1DFqw-0lEwCEOt}-kp2~ zH-RpyeSerL-H5q)>rCuwnVBkX25;#?J21^rT}VGz<0Qp&q3fT75LmXRuMM!J3X6`l z!@_<^VbQU6L!OAo=k6>-b*$`X8oFcQafz%juw$v!Pa0%5J61nCmceOb4?329y>%x$ zmg1~?1bPTw#>5xQp1o}+wxzJQb?F-TeX85N`RS~>`6)eal}bVVQ~;`ZLks=nZIEyQ zrnl`xZ^O%H&h9DBj@Wvx8YnWO$K!q^W%WTHeVx<}Jl1XrjV`b%@KPd=Z$#p0LBo5) z0z5(qKFmV|F#sKD8kUnfz%P5}svl|XXD$!&OBeThbRQOARqqz9HiM3pGFr5Wg`iLS zGry1>t0ZXr->n9!+XfXf2!z?vRmyEE6{v1oaEq7<1n?s-wAnT<{TgrJrb>I$rMs}} zj=Sj2Qo{!N6K8~K=UkLwS~@-&J^yI13#aj!AUf3f+$!m(_KNlf&*`V>oFj(HnP{pm z2v}Oe;QikM_n+&f=V)0um2#M@EaqX7 zepN{wFcrJwClDetTk%s$)79&7Uqn76sOt4RE&xjnR}bAm;Sz&ZPqL`l$>i;;HfZl{ z{2oPy_7;h!+D;k4jYeu^8%Mk@1tVue=V-L}4)@sGsYzYQnMzo2liXd26dDxUB=jCv zf6Rrh#WXSu8CBK(iEWh%7}yLoZy-g9_zRGIEPjuFJbt(O{AMNA>>kT`VQO=}#2a$i zGWuA&pHTe+2&cAFCmLk&C{k09=xprAtcLdE-8LM1)!T6APE@371HRgapOSeqron>j ztgmMld;$yyd42*6hk1Si3yp z`yei)c5yidB)ILx?Li%^NH;O%gNI|^+#b8DBlYT7ysD0kihQj^_P7pJ zUMKpWe#n~nBImU&iS*eo7XD!_MBGFv+!~lL_P%iH&qZ6%VCw%FK5o?H!xTAawuUjW z#!pKvN5&W6b*4igx4g!@bu8QHUg`S!%?A}$J@P24Vo(xUeIpCiN*y%_O1%_u1MjVN zeIg$UZ`w@Bw@hIvPs3iQ1qpD5(!w^>Q9onO6sd(HXkm_}g=NB~CgyA5snoP#RKrtH z0~ea`QlZd84O_yPSmOw3qmh&6Lk)-fYPf&`ZV(q?>RitXKKRH0HQbqnY9-YwK`Av< z^WIX!#sdR2RIrpMVC8BDliD}kupRzLI>wfTNLR-994hHm-~~CO!RwhdIUp+>jmr8J zKkLoRdZLxJhFK>M$U1sp*7KM(gXJqz>Q|ZdUuak@a5ZhHVf#XpH4yk9X61%SlXWe# zzAzx`;(=Lz3emh8D{B+8u9K{>#;-%c+7QzvC|H^&9bbr9LhOld|1~cC$~A-S7m*|4 zx(`DZL}J>8Q_c0jb~?{9F>|^>rv+`cx#r1m7gp%0kgvgc9@h2z6sLXF4)0}burSs9 z8fAS8Z4M1#Da%NQ^EJ{qVk3zCXNSdMm+EwOgvB9RjWC?8a`X+G#{E!CgR=wT?3m(o zK%BEIalT1$ibb4Hpt>$IPf@CS{CgqQ(Z}iygtqF4HevnXs`~(vaD^09m{360JNR;+ zb_(}V)(7xr0G-0eZsu;YETLr03Cl|FZ_WgP7W~ekhJx>~PT502It#_hxV3^(K5#MbEg$%h%psHv9Z19LIC$YDwdpPR;)c!q zJ}Y^YzPb4q>SkYZl)4$7%*||XaMtEzo=32>PS=I+e_;G!h5Sw@`>pQw;l-G-r=7c{ zb(FEZF7*$5LP>3>b1xZX5JYRg&-ICWrCqSQ@kq?@S}X=%7Y2C^&b?@td#5;eb0TdM zEDx7ZZI)UZ>RKYJ4@*01!7kOA*!J!)*AZf;74OAR2rY}3CoAkmoa#Uvp4;-6h&Bw< z{Z>rk^x9Mgi_V4~;#-Sxi8P`}Q=Pz@1f#{J@Js%B(cP<_K|rL99G1;zu)N@H=N;+i z?UMfQv|?z+;D?fMhaR{iT?zowewLIpbC>=^rgOj^?_<|V{^GXhuzas$Q;7p2!0S`% zGE>MlVa9CwUA^6xkA<`38t=G_*GELnTPFH7d>FZWkKVDWGbs1u zpj?ir*kvDEt9D~$l`VsNAG&}(%g5J;8i>{GUtWUSk3I@Tir%60(QE7D?(g{e;P^R| zTr!ZCiCnut7V+g$gRWYD_$ay7AwOR_9HO0e*>df@&zGxJ$(0PZlML899-yvVk;$|Z zGZ+^s+W`i&)4!0*cZpf;v{uT^veC(CUiWI`P-YOXMZfCO_wX7#pKLeF_uj#mS+MU5w zJp{gxg}DzP0UjHRIRKKdbFA!OL)ZPXq3eEb=(-_}*#mS8PDE{{d= zRou%*B|UUocwRc2yDZAMlMK7u@r+I0F_c{Z*tKveh@$5;b0b+nF;lm>XMBsVb72Px zlg4EweGW~A>sU*1ip9--!bw+^-W#3j`ZS<aNK~B z9)Z4fozw}3sk+`&&0APb?1r^M%UI2RU_~TiRN9O6GpasaG7Ohq96PC?dClA#SWOR}yiiCc0s_+lB#yTp%>Y{a7Q`7WE9n%!tqb zCbY|NOlnxDH*{pK6hykD(Au)W)4V_>tIph&;SaOa(_r{XZqHWLyV^j3-~uu79=NGJ zQ=GR}eJ4Y8Q$vLi3Ma6lKeQ*(*!;>?JM%^eo)VzleUcUsIyWtWt}>vlH{r)P{x7t3 z$N!UUz2laTYU?XE{BO4P?#=&ZTVHg8)z&ZFGqA18*wzTNd!%DysxRA0p2D_9^ua4J zjpTwJ`e5WZ)dxXH8@fshv=MfOINfRYPLnAo@|Us4)8)qt==?j-SyZ0SOP+#aIP}?Y z1&U@g{P?!iZ`|soYF|&l@Eyzu#QA}}>urS{)22CIaz_J>zrbcKIrTyYQjSsae6{)J zYHkyhH^lomcJ!%XW478>hH*^23xdZ2I1~e4Jq0{?-e$e}3oHbAE!KJ;f$STSeO1hl ztb75t*O2liID{iy6w8nkHW&e*4j9s7ji1NB{qHcT*(td`o|JxhJdi*XpFrajM2}CI zeR{JU*S+;?%F6sU$W&-*)s$#7-IQ1Vgp>uv7=c4g={}&Dv}ZW`QO&~LDdN;PjqZIr zp8xhW?V0Esf5HVc?P%bQ;08l#*inW_AfLeS2?qlcm}h+=wW*fjO=^Qo9n(%db(fpu zgx9M0tl8KRw^4&>Br}(D2<2w;WLk!J!W>LfjGPYsORy4P zh%mk2X-4VIN|0CF=l6;Rnm92xrqNi>ElPH{Ycg*4LwGR5YKJ1+h9` zpatvdx?U|DxnE*Fj^4`D2MXo~aLs_(Od2g|Cts$6L|^JJaxkVY~W8ws!r zfg1!sf|o30Cx9wl1^@Y47p=&XXez<4p4h2opMWlY-vIS^|*JSyK zu7DHv7IUu<&MMy_I*}d9#Pq1bn^|~3&bcEJF|4!Mb)w0s6MI!6EUKxb-|+Qk5AaYb zor_tjK2{oDC{ok3bMQPrPmVO__?|~!Qjj0QwE+hsQOEe8e<^3xrDkfoIJ!TV&Cblq z^JLng*af(cV%NLsIVHJXmskB%gg2H7A(W+dsTFq0j;JQjSS_M$9A?#lH6*=8zA?6b z0Ty?BBLX}_7JD!w*?uSOtghXCmN&tXOZutn9Q1ea!#Q3IC8d}19do%=Z=TETu$nI? znh=PlNm$qAzQPrGlcVNjNM4LFKz1{7v*3Ymxb!#&y&b)NZB7KYZ#(U8U(@Dc;=%q% zhlstco<0+#OM2d0SO+%i7jOCN7t#~d+Gc+f%9P`)N?{yYkaHo3T4pvoYF<@ju31v~ zES#cml&_>R6I`_sF;e*T5cCmDpnIfqpB(Uo*>e8eA5?;)@#+IWfgK4J z4-7Tflp^(K$k0VappE>c8^b|*nA(CD>@eQQcG;Nq^qgmRAWA_`D@707!yPr*KahaA zcxC^VLWu27X=dXv^zO&xqCl?PGqKH;JyHrySJaPDB41M?KZk^!{I_egi2cPc=YO+C|Gn_vsZn}rd16e&eGQ7& zbzHN%7fpe|yG#w|-k9!ZQ- z1WgW%NQm~m6B}3im)N-K-^Ru*d^I+1&bHXNvLD69l{^p|m-t$2Tzn07M~o%Yrp6*% zIwSdHse$;gq5y&~!SVoBc~xSfX+sI~(QukJF)s#wa&iw{@7JzjcOiTg%x92eF~$&U z9j0-J1-}jd)0a7PYXSkageC6J;2RkW^?|C7!7feTwdURnQ*{r)Cn7p1ZPxEBrE4DA zIu8|aFTV~aPCC!4QO5)a*Q6*tpNMiSGS~|g7Vi9{;)hU1^iO!f2+JlC&GzV>5MEMZ ze)VP#$EaqXyfYxj;Ato%+6a~O_BxiI7ZBl)s05vc$&|BQM`U=Q@)W9pUwOn=kRGPT zxpDhRG)Jy+FM=9aTe3=ngF$ss{Qe0z>SER)11|iak=4jzGK(w*Fo}j3MM=ns!BBQb zOmW&`>yL-&fS5UV9#T)6 z^p2V-4&eHKatT??!<&gm6WUO?uG=P-vLnk<;1TmmyF%8KsSHGslX9{|LkFNS7>%1I z%$7CZwifgOiOC>*8RwN&1-Lye;6y^?3=k}f)#jC9hKlC8?F!Ssm`e7V{YcILCTbFU zwK_BH>Q&VE~=?ij56Ez30KjA84#5(FDdp4JMp+C&uZ5~>)WgSYX zI9XB2TPA0or~?BI`>L!HLrvGBChEPiXhb7fEv`1>Dtd&0DOdEg7??2!V?PGQ^8>KT zYGkDlLlD@yhy<;a1%)@WM-~Tg^?TIIzzvum5-gFLnNDtUp zqvJT02|cijZYDF1p{g2BWQgm{Cja{ymVt?K7qr@iP5i5VrXM_+x3OnS$LbQVzsH-R zAb*7Fl@V%>hOzGf4IJH2E6*}uU{~|))KPN&9hB2dMFh{CWRPJ;XVSWXNpNoF>6Up! zRgC3^f>K5hyeY;F7a*_-;U4q{SpdMMiZs$0=Bp&q2r+0jRj9=|rc3_TApcc%nhg4; zQkbMjC5;+o;52|qG{macey6`a1YE!;*LSF0+S&~n3 zKdfhWFp@}j=yrDj32WPyc9)=Hsm&wM%Mo2iby z_eLAC83PLOCzcpcjs`3&a2=UkX&mY(!DWtQY9ZJ$^$IJMxCUXKqso}lNO@P?(b;%1 zu8dt1?LXQ4%Qt?r>dmQ${w2z8ANAfTYrgf(uMjZ_REhS#Ed1TNP5ryjUmN2wuT?`68`_}>;G;(;*@6X4b3i8#lK+S!Pe3e9^%tDD&gON?;IK)ha>>JB z>)2~Ket7V5#mPJhHedjRI-WbC=b7QS%`+eDa7-M9p!vA5*Mdc(l z)Firod8kFMx{=i!)!3z*?D{alSs*Y?c8(;{L<%;j4E`Cu@*Y1+I4R8F!`gtsKffYv zuG(MjRadQsfq37eD={nA*)7G#21bZyEgp|sJQjk-5ZPBEJ1f~ev@OiCO8BxWfz@nc z7Av@vy@J5&>dw~iD90V5#Rf;S-_fr@5$d1?bI1V$SbbmM)WiO`h%gFI4zk_5wg*3; z22lae*HyEUbs_39-A&O&wA?t*IYblY*h`Mhh9hp|K}Q*vD{)rEpxq#W2_NX9ld8qW zikmU9K?MuM;d8!%LFhOVd{z^*gb8A|orH-Zv!FF}gU>F88l-Zwopn%|-_a>ZE0gMt zB1KAQVYWPzVbRfhm(e?@lSM#`k($_BfyK2L{CL=`Y6j-ksuu=oSISjk25lg7P&Ji_ z>{!}t1|&-R!I^$v!l>Wj9V{WQ@woZS(7_DIsxnv(I7s!`1qc6GBZxC_1ThUr)?HvN zYvKQfBS+rAdG=_pP`XqU7C7?bYfSs#ym(23BfoQ%7(kQCrCeu^sb$YcIr85w*}o&_ zyFo+r?{6dnY3>0Vmg(kbX_yZP)XP3Ua8L_=L{*m$whN+bgb~*{X7j``oH4Gv>%aLSr+#~;2#DEV(eY*(G68a|bF$aFN3JyMoYtFWg-A(l zIuhS_5?dgbrhHrwZqkadnAmC5c9$KA`Y3ABjLjX{gk+k^m!BN==Jvxo|ET244}TvfnLUK?au0g`M(pCPpew zB{rQW6&FF>UtWS!5F{0WG83i(9bV7|%7zyiAUe+}-&601GsvdK#370y00Lissl7*d(Gf{>JRuu?_oJ5;BFMkWf z$Xu44WL8lFf`wTG!TNE7utcTESy!qlDBi;X!;$nRDOOpA8>hn6Z(4i{i6}x05LTCt zD68=4nLz84IYA)H*eqFOHXhNFgU-fz$RZVA9ArSni5{%tp(MSO9gycH@}zX0p`}jk zpDnWx?H_X*gcS8>0lNOT`W0Y5aZk9I8wg`-ab$KRkk8|OwLrv$*&=d3nrWL*k~v*y zR3jaBc2V1Bs*{#1W`k4!zOhU)!#Cs&Qi0fdR%VcvjjbP#B0C$;MlyAr-pn4i#l`6F zK3;-m#lavFHe@0VkH?Xe)3BMBNbK$oJRH5yrmq9NB5tS~9pPRQU0-^iLN4Mfd)e2$ zb))YikN-XNITBx4)CHt&+Hg8b!t z7`{GX0kOubN3eCJ($GwU=m>jI0^{cVjrPFfV~mhu;P@FFiSLFamWpX#OyX*CF)YZ^ zedR(~ATp7%1k7q0lis9r3*Cc*(Q(s-v9+;!4y2Z6OxNNsomdpYF+|ZEP!#w)kU#dc zsW&&DrWlR^70yE0n}ZgigZQY5XNk_4^td z5h-%ib~a)f{HcVszQOe!QziHSF&e*080;C+MQf@g4DHGy&8|Jj5UJYX?X?UM!a62mHnxua-}v;s6lsK^kDfztRapikL#-mc>voDVt# zPvuFq{`n&~+q3*#wgka=lEu$z6*-onoy#XU?Aa>PB7se@;rt?VGnWlTIz)K`Djr=? zsiqvLul!IFlxfd$u2!=grH!c95U%0?>0m3T%4`J+sTyVv08ofU&FTuB1gchj2Z*TW zK36l?9To8k!b}Hbpa@Pq%KtrjUY3F^Qc-t(xNu8ArEI63mZ3`i#wYH`=r-uA-In>= zy&wHKIt+*Jg-@nLe^!0EV?dwo2&yw^pUz6QYO5+UpdTaXAI1GLmih;1!18Wmt%{fp zTTz5ykG#nqe|{-^y{SipScSE-B*)_)?4?br|X$G2Ecaj({9J1UY{ znx&Zmtz!4*=|hnY(Vs0{ia{fkq>B&@pbO+?ZWxN8ZxO1i@a5Z~NIz~@VXfI;22|OS za-a*#uChfsM3pW5`Bl!6++v|CNx9b1M)7#bvQdkZMc7QjR{buZcT1LDMw=JBVg0sM z+j#NOctB>}8}vteiLTB1Op8qrjQbqaXLI$4eah?vc*~4y*hq#Qe6c&P#~7C#9({Kj zevj07Cp#9pLy*7ArhNHaPFJMrdb;wAU_@&gQ;LjdIqyhd8C!eofH{mrW@dit&!8o$ zsjqt{l3Z=}k1h=Kz0jOA6;hpzSHqhjv|Ob>F{wq(vx5~T60@lQMT>b_<;%xn^yh) zwb$&O0AY;+@nZv~yV#}t2c-|Ly%z6@_d^qs(f0fZJyHk$8`MgS6%+v*8Cw}i-AS3rphSx>U59sUBBUU}mrb=4zy zOwC&A#Uw$dVza*R{Gdb z`dIfv%&~p>`B^X8hbl7n05OnHg8oisWcmB(mq}G(8*or__0GW$-{3I zMRGDDEC?G1lvCu9r&wy`2`#h>ckvV%=UM4=d`_zIDcqou2)`X4`}Te90vGpS1wj;( z-XwxFsZ&7qVD$wl9YWO9C6`U2Ih$lfGu>%%<vu0Xd(IUAt{-GJHnhg|$d4g~UB6F>K= zPU2>4z)%}Iv3%*C#9g8aqQ&gUTaUG@ddGwP?pJ!=}a4@e)38;*m_~ zBzIlStWKBSf|)rVWWr92y*d3>h-G^Z8X6Mf< z_t|O%i;1YRT)2bT)Hu&P>dvPHF_u=-s?36bhWo@!LD)t$prAj@LP1~nLGAMbP-qCGe)kI?3j705vQ;M)3s8X_C>#vl_5dh8a09;CKMw6uTvRj;`vH-U z7!{}M)rn$TWFWuYgGbgTLeT`H;LZx7_g_j?WivqpgXhzOB#ef~=~5o2%Z*+GE5Sik z3hs6Phn-y;LFTMMJy0(V%_xn{aPU~DhfYpxy14@ za3xS_7d5o1WT3M#!;^OiME70&jMR>qc~vYs&-eba4-^K@ZGCtR39II)5ZE^HiqTSo zf_A5)Q!z4@H2k=VkmM!Oc{5=7elc{I;9weF^>sH$mfgqQT4`7~%@2~a4`#I5(|s5;1Cj^bUXVBR`02>?L*6cR{Ze%s>kf!d%wQC_I zhpwX0na19Xmu+9SI`4&-GYdCazs@c?MS;D@(1#4veTko0ZHHy>q<_S~g<2yS^b!{w z{nt%hN+IJ|B+~aK#NiF*hXZ!6dfjJ+pE_8LwPE9g*gY11QOuJn zl8*H{tE>c91+&+pj8I%8Q`1%Wu@&>txdFXIOC0S zX;MC@k!iHj9e8y+YcP56Qc`n}$;RKV@EBx>hXvoL5N7r$zd9UrZ<<-~8j^)KPM1>A z>dVlaBIqE#JnRWVzI=x@5`~JhlRi<2X2l29RNO<3A3qZCS@Fo5J5T|4=gBlQ*<@)u zepb$M{F455yy)%wnvtOC1#S^o?{(fJdT5d-^zISoa$wk@1_q3=oa5GE!nz@j;$g%r zK5IabhP4I+C|3duT=o1^1(6sCUSkCL#Wx{}E^Iue*}DHa{_x)lp96!g6%mccXX$P( zXXVOadi|iXniuULmKLCVM{l)>!iAgHT4czRpa`Nf5QzTk0uD&B36kNYdVquVEIqA6 zn_vgB(JL|}is-*~=pbjn^mf?}5L;2;zRLvm=cRvEus@FchH#T=@C%9t9Y@3%zJRpQ zI5LlJ9xwH)4yxZ)=n%!$t;3r@^^AzPN{nk07YY(-XB`&Hf}rogi-AN$j|3d;k!nPQ ziW5uujq_;a%`8FjNSZbb*E|+VAH=B+cW&YjhR6x;^@u7^rtEftlA5^d34VbWfPzk> z-cP6>{jB>V2K*}%lACXs*VM!O*0~S$0X=;H`t5$8Pac3?jF^|MDO(oO23SJ7}L08}(BKan~&AJ+n03veBc>u6jHaV^AkEUsg5 z#cbu=B3vioItkY}u5nxwxF&Ed!L7nk2b4T=+OTCp11+ebu z0mAj>AA%z_t~Y2-TkLP#G*jTaXJqTOq}o?%S?vJo`9hu7DH{f}rT5suKB59&o;IKY ztNr3|7?RorsW&OfQzq6%ZL5+Emj3=FHJSAD#$iv`dR2m|>Udrr&km|hm9;^LvAL0a z(KWO57Q6E_a!RWi#p($csDHQ#XfNUBL>DKCwXQKvSpVlcoqFc4r>>Ducr$VV462 zYU5*|Anf=yobx33d5QZowN81_jfNfH)G&T*T;15ewg9R08Rl!G2&X>L>4;y)RlK<` z8eR6)`)6g`%S6R%-N&OoP*LLuk`~%;P(kk<*?PsQ=rb;U;v=;2%ILyQC_iL{iCDXN z<6YZ=o%X!1FK)b)tn9QVYey)noyPec4s=jIAEO_(2EnCso-|Jc%m$>5Q)&HhY38M0 zjNu!E7LkYYZ9EXZ3#W@|Fi*W7h(0N=b1*N`ecI4sg??AKW7S4ez!gCOJcS~wjOX`T zhE47lvz49Iypp_Q)q`0kaTDVyRe~%kHd`=flk1FD5mQRZ4fHmzM;RcpPA)&qJ@{DK@5strghM;r)Jw$$spen>i%JQI>ps z8$d7WVlT?zxBp;KZ0%6N@L&T94w~I6`~I_rC_7+km%U?E6UI*3wL5Vdbe@)z_}y{1 zZ*W==r$2?UgpO#k^Hgm88GE@CpN(U%0>svjKtg&0>7dOxE~%1*Dj%w14nKPx33g;D zhqecf15+yDwd#qF=gQ6w%T=G{(0HD@9T{43 z@TW{HkOx}ADDV&`G)@lc#nqs3b5_TUtsRXC%f}PD@k=3fas>EzSuYG{<)C4;#FC)K ziYc31_s6UnbIQ3+A`iqLMoDC5X(gm2W@%Pgvf6AvI*Q%N@_B@)Dxy=)2SF+D2?k>( zG5Tjb1{mL$&!M)Q)&U9UNWyl*DJ3U92D(qI@HaIYoNgVNi7p3>X87Ton;$ZQ=%XiXqvwEwAD0Z5o>%(+vG*?UQB~Lecp^kb zi%xviSgS;h8hi%pBZ#y~V9G?38Xr+qQ0jxC)f#n1sS*fH(<XjSniVSZLLj_UbLI zk4BUvJY+yoqhO6sQVX)jK}{7QDv;mzyY@b>nMr`wdvE{ufBAgK?6V(huf6tKYp=cb zI{VC*d>=WrX%?JS3d+TzbKCbn#@<)o@MloM>@`AjEo?O86D778aMEZ$TUFJhE%C|o z926Wig>m9jIEDpyS*pFhr1Fbrl@twQ%Ppta*gn5bo1|ZyC9}5x`~3xR&Vk`p2uoJ- z0tXwh5P01vDpunHS$vPwOFya#*m%|RGnSa!Ms0jf06xaPou~1^H8Y~kv<KSjVA@AnHKF9(g{yrUv*Mmp4|-_~iJPPBuQp{UTkmT+D71h+b!C6b^#+`nz<&&!ygYJ& zLm2D>XX6FFNLtfxE^k!Rk0mb&KI2RWEYv){p~kMre&?rAX>-Bf&VcP8+8D+Qlw z2OnJ4>YFI`uv2t+ag7Ikn0~;l5TGYLgkQiRoq|@94s%bjS8CNwrJ&Eb7b(-dr8n4q+nXW+E!>hwQ<2EZ;u_{Cz zABqF0=NWClvrc_FQV^c6HtECy^>;~VL72Imt~k$q&RvibL?>xS>=Rgm`>fdzDF{Pz z5q@Iw&Kg)8^tBC$dx}}i1xH*mWVd_mPfY1u`%SvW95btO#T5N#1aEGc`UBoc(ZKNm zsbKT{c!W!UgrVdjNqU*&6gx>yY@W@>aI@S}iS56br8won-k*a=-TR-?Xb-|Of|t*b z5kOzx>&bmu=Poqg3rilYzf)!8bx`#}_jwRLs+C2bD|IO+h{$9)w$dTMwk)nF#w@xR{IzH3aXhL{I$q6kPoyLyzF)PCVPgp})#YgZX9+ z&|mJ-mjd|F1BGpL2Vv1Kj#W0)FXp8u@1|=4g2?rpXe8Z?gQ%%=>ZunBGvw83k ze$v{-pMn4OGzl*UXF(hw(xE0Bdt5(^wF2MLwo$c6S+I9?lfEk3&i5}|PIWPT&9}5Q zKS)Q@|I=m(2C>*Q{6uKzn*nEX1N}}-+GyDw;{!7TD%wptHxJ%Zj$u1+=$Zs+>;c27 zG`=n2!$H+^?2Q&&U!jE*0k<;t0^G6c@2q>aybDvvzk_PmGeZ)@^4~EXQ0XMKT5~Gr zUx(+$b(%t;o|ZHu<Vln&+r##lpbV4bU>f zJJV%+wGNDSj3vVIO6(l9=YF=tii&yEhJBo;CQp`|hy}mtb+1<*umpO!@p+pAN6`=D zbR|*v7rGwoPVQa>aRCi)Ix0Vcl*}|2R9Ev!C9pABSu}(XMN>%L2w6aOMY&^(p zUK28RX(t*$U6{dKDed=r;71itHr2U!T*Z7LokZ;ljXb_qv?knsT0^F2{Pf$J-y*BG z@7V4P&f;>y;fA{Yy->SXqlUv6E~4;vSK&v^T~C_xPCvc2@@y#B&@MDJt1Uc_DNFBs zDaM6(dtZgtT-UWJ{dAE4Q#j1S@RNwv%|tl~s6|aojXtmCE8H1tigj27HL75kbgSDR z)xMxY-Bx~hS);k%eC@P5QBA4Su;L`628U}hL*9KH(Emxl-bw%W2%3jY%?e9qu zbN$K#Nc$uzIP1x6EXI-aOsQ8pM@?m7=5iWU#>T?S6CI?tCEsqu;U_sAGLR#aATNN4 zinS-<^pgPrGs?9Vt$64z!V!)^1siW44@JdP3d^}DogF+ErA5YbQSR%@a4rgCNzO$> z^YM#w(a-|?mf&|GesL}em#LhK!pkY=qVS=~xhSvoT`S$kD!ch*C1YfnPhu|plmp-p zvy#*7`N8WN)I?-N>Qa5Kt=Y#p*LLf|UWacI&N=Tp@(h!-Tj&aMgty^X?MXueU*JU- zkD%BW53jp|ciyboO6MTQIfF^-y|;P~=F z70U7Q!a>YqU3CVIx#-Yj0s5C8Tu*7fY3EFuO&@+K!00Q_koK1$72*=#3lX$#uE5;~ znLOD*x1BiohY_MzmjbXoF$ z7$cj?&=@LsXN_=UkEYmWFX2wsqj!8DzDpz+mjmhS!N(gJ#zRK~2!asTX{+jMd$OWq z>T5S=MMvYqQXFw%W@3r;Xx|6t2Fpi90-te-1Mz5g}`96 ze%kYiaRypcpiSRBXzi)cKBKVPmxOUaf=od>$bwX?lex$h6Ghe}VoGe1CV?n%SJi2fu+ zbM1T;U{E8zx}xVzuEOkR>bPQd8lKdKZoeW4GYa3eu%1(qdug9$s;5~ha~ZthSZIK- zd;((*2CCn}Ge_wjmI=-}S4NF5XdZA224Vv2*I{`D3JcZGNjQA}Sv4a;RR|q9DunRI zL5K%($3ohOo-Ia#ghY5(Kz^c~)2Y6#;jL7okyy2?h4G14K=9p~TEvfI z^@I?4rx%}HrFFgy`}OK=P~W}7tR+hl!MmfQaNfDxdDtVpR&S4x00O1M+D&fmO^XRs`Yx6#H?ZIKYzJc)bm`E8=qN zLOY%t*T&}or8H{zMhy-nbEQ$KSS_p29Vpa*#o-V^=9+L9wYXn^_0T3`F26UVJHoDm zuXkgYfpg)8j_E_0|8`0E?TIS6w@z0fZ91jF8R|CB&39s4ScSf+MODlpFM?%fkc1iF zT+&Z5crtho?=9mOusGa&2Me6%CeJmwY4GfzPF}s7scBa7zzhKQaH-+q>h>saRpJ^o ze5=Puj+v!2P(qV5P&Ts)xb9CZ4EDp<%hO- zox;|^m~n@K;GQOa;wjV}d{PM5B=o~)tNWTjKFtA{@U7B)HaoZ?Lu3|x-RIz0HQq)I z>!?!|nXF33O*5*0j>}ceNTz10j!bX$;owsnv)vqtRlCiK_JWy4g?eiPWUA2SBtAoc z#bPr$@vKq3P!jS{lS-uIo2GIxa^P*~At<3e-wySpDVf0Xo&xJ!LoQ?wMZKqb{WD$1wALWL`eZoh=*l z)K;}@EgvRux z9jLwX6Wmebe60~%-IKIZ>v3kGD2+ZP9{Oy+Or+B1S1x^i(l34f8%8Mu>`WaX5T+W& z0Bx;bg%Pf_qRTD5I!xaU)%kK;bL+3T!o2|>L%2j&m>LFubdf(cT(4a+C@d)%xzupT zgBZ4XzeZk`;reAxGRY!cnnf0BVBU#F=S09e(R>W}C%RQ8S{H~9RJhHw<3!^H7)*4l znd60;1idif1x>69!8@Ls`UbwBYcqCQ+> z(|(5b*oxTmNKW-w_*l^R3R`Z@(fiUbxgX#C1L=c{df{S_El4k>I^Wg}j*}O)Oo3x< zi1)-ed->U|{X`;JE6>(9<~XOwv_`&GIVQhY&45cmdv0@c9^6NJO0j?8UgDBax0>|T zOnVqd3bnppSm^AvbU!5}ya8z+{V=se-F~QTW0Zt3$R4;%da`(WQrn|$$3e0rj>fx} zrg@dOd6gO^&0!>eT${SU^#H%!#b(pjoQ~44*>s)3<~{(tZ`gUa+ zHm$j`55;Fv>EPfDf;K4>m}>WVl-p<6OM$Q&Y4_QKLlplK|KUNY6xfwM2itxA5zP%^ zDSbYBh>)UJO=F+Fao(QZXG_{R(`efQ;g*>m<@T8})8|Q_LMFKc%x0nS>I}C;uGg|l zrl`Z*k{U17YSbXNWU9Ahs!G6(E+*6bJ5uTSs{_;MxeH@^e2N*{6=eXxHNr)TvPetxug?P`u0@1Zbq0F`a zNa>O7hW5=KW&9t;f5h!hNiqFL>f8Hi&D#y2-CP+^Wcyk8y+MdqE%KvXubN`yLA-T$4kPo=t`B`j?4IpA>ryK>R=oKYSDg(rXwmeT6jjBP?+b%(J!TD8?7ZwYttgmbet zI+BNj#tXx-iTIB*?WWr}0C`xb?x0?-UmkX%`%FFV?4s$I3ubm z(FA{h8aajF*XH;M-W{tcAyeP+Bh+=7x;s`MMh4-G_qE|ZmcjLI z`PBbO-Z0~`$*0F9du@g%2^~E6iS4Z~7&U_up?w~XDD&)_qPC&lDVmb0%Kg47HLMaZ znM4amv;f%Cu;`C&AuPk9QLYxQ7T^tF^_wO^3v-(eB@9Je*;#?3jtYxkD#BL;Xx%TQ zS-!w*dSNb?VbpK{GJHQ)30)Iy#mx;JxDN{VLQU*M&s}3<*Q}3)^7QpJyj^y10ie%^ zK1N`_RmlWCm1;$q2+gmwmQ-5k_Vuv!##rk;bsF4%z;cq@Y}BInAmU@jDjqKhaF7@; z(>$(|bi5?bPKI^prdi+r$#zyP?Fsmiu^$>lFJG@?FJLsaz3nZ@E3?#J56{X<$?sQ27 z5Jz6w(cv>|dl_LJ&2Mc2B630yJy6n+X*H<`RJU^CtByc(dykmwX@9KU{_yr<4rJoq zP;ueC%d*-yOYLn(mS(A^kY`%Av9ETz+0-AgdG9q z$2!0nV8N1r>~-zHsT=m95QMtwYgcDYKTKDd8UXip#j00>fjiV*FC&_hJ{4V<1zS6M zs9O;=Di;$5^=2m)Li-g8Jlf}J3_P3IrQ2YImoN&u3<^M>!2!2o)d8!P(lsBIAqI$Z z+eAfa@J6)2jNi*<1s0R}U2pDWP7DW?@Uas8eLl#aZiLPPzU?yP%9DY2JdoiFsZ#GF zew3T!1zhp4+EHco4-9Qj%2_ugI|~O~@|tDzTW)_Ed;neKJcBBzx+Hj?sg?%^Luftz z?DKmR=})cf7h0d3G*E8>>LvpUuJ3Q8_9f_4p#o3LoF2w`dteZT-3M)?p5UF!wYoKA zrk8|GyFbC@vOWUDfTu14;<{|TnFqW&Bf%iaX`BSbNrVsRQXZb}R|%!-rJ%=4p{K*n z$TS_7L6xCaB^2%iyp&qFq@4i@YRfr#mY{<5Ea6rmF-ja>f$et_gaqyy5;+Vj%nHrr zxaO)P8sjEi8!H)BhkQfh^3Gu4QjS@*Z9Bd!t9_D!kTwk=gU2Nr$3S=jVuq}?p(m7O zsVR0jVpmN0Y*T(H%foiLa>}EoeBp=^z{i8^`=Q(U*>NqsGdC4uq`U(c7CeH)I{DMQ zxEnv}Jwl8vW|sP84vSZqqD5Q<)G-w6*b~ySenp<$tX;AjC7X63{5ZLYG|VTyeL%!@U8~9w^Flk%FV%3i8&vNY%!mhyv9twTit(zasnqN`7h^cq z1FJC_xjDFlBaJ;EKL*NaLPDJtTg(!*6jX~fvJqlONh%NJ!u?Y2dXS(kAAReHmc%~% zc9sA!Kejak92=Tt71LNN3>>g0PdaBDOf;SVRkGGH`hXd zq6-%llW_-?bB<~|Bxf{p{t-q_j4`m_%+P#RSBGdapwfIbgu&6x(GC=Jt8NxFN1;D! zTh(`|W0-p#2%J0^ty^FawMf>*Li33&$*N@ zDzWWsfSqbjQx842s9%7Zd`(mfm$NE!&BRdfpKDq~0wK5tosUo+|H_)F)(K86uCwDE z`Wf07fS^;c%0^Y9>(cc<#--Br7dod?tR=FBNID-R<)n10!7?cm=leY!F>eu7!RxrLvG$x?}L z3vDo$0zqANG|n{|r=gBvj23k|m@t{o$TYT$Js>{-pbjHgLPzvbKV7+fzcypAzk9Wz{C%M2fQ;Y zI@ErV=@ASIbH7sNWi`UO!p+>yh8DIralmhgZly@k#Zv?O2reJlK0s;?xP)!V12|;k zyq-Y*;E5aEA@#K#Sqyn zfL2EM_8Cy(_cS&3GlvS^b^`TRv5Ca#_}*zXML&4_NDV%J_ussHIPcX>UYFm=wqCBk+M{E16Z@hhC2fmiKCfsNJmOvPyBS+CtmsP#KQcMib_w4gFkV`H@ zD#h&v+YpPXPXal^-F(ruFM6+-W6mm|si1)i`ycXD9mmQuR}Z!|+c;K?=vhP{=sQ>T zvKf0kghbfS9*#>0nPZKDhiiMFGVmYJZos^bn7YO-ZD`?L{ zmbz6|720owm~99gNTom8JK+n?A~~(Lqiq^z>~oz19_QV-xVK_-_^Bhn+tnRy(@`$= zzB&j1^}h5nRyS~=9OCGX2hpqflSDJzn;XC^LVtmNRwMj%xCN7c&y1XG5;I=ciN45D zI_UG0BpEOtrneJzT~z#x3u^>L;I*5My$E zps)#cUw3fcH!waGqxBLCFbz;!`gLz}x7EV}jY{1?Ov`eoVMI7>MXke5rnjiJt8I=$ z++IqSuVH}uC(XgqZ~;yn&Fe;n#-~EPYelwqu;GuOeXMqqIv0Q-bMJtay7;_~ST$F| zXIYJ_I?(4_r_TmdMHq1KR|q$W9D^lD-ntlF`IjTI+7>vq4u{s((|+}5J0!Ssj(ty1 zbja;F3BBQ3E2u(D`EF}#Ec6gxc=cyu@N?iVgZ!<{PT-uRufBF|)^vQLqq-Fu7&_0c zP6weqC(u|UmrjR<8>o`S6B@fUF1XSG>FkF$n0UxaG3pH7SqABX>XmCW?Xk$0SB^Aw z(W`k4DCgkM98Ig=6O_-5*7pt$Hf|NJmt`>VD$<^g{1Yz@4+N4!{T&^S?X&5LBeE8i zpg|jjxqT%_t-@e#P30Y1Q#k>ou{l9Q0`59&y0K&W={xDwuG{Gj4Fn|`*AR`<9W-)J z1R6`A&NLdg0gcSmgJ+*AuS=~JH6SlEsTH3iv$=L5Ot^fMFOr?ZUwEB%GjU((!Ei^>1M&lS>SR{6^mA-6v(+=AbMwv10)x+8AfE(>dtynPqm*VAx(!oAA@OO1`xR^XRiL3m6!{HZ!z$gb2E}6E|x1 zF7Q7}7_&s^nLG`JyOKh&P{pjw!n+xH;TX2AwcTw1*r)CySiO_z>RW?lpMmRMI573N zV&mI#{zz$910V~69)vVyhOX%9pTOVk(LZ+G2T1w08NBYyjXGxUc7GfauG-}d#@V;l@@1r&Un`Mqy7m$sKU|UML?9Ju?e(lOnHJN|g zu3~F&suvpZ#96&v!$cxFbhwsuz}fPZY%XnYvCW50t8cii)We>7qzmYW zV*)CjjC~>?fYgbBaa19HB*qy1Ss2>RnH%q4(8fUcZxt9^(VM9Fr%mfH%*WlM^*}TCIZU@N585NU53OgUZ{#kG(m13D94EH9RsB{hiWiO% zaCHYdl*G@G;KC{17p4A^GW(QaOCriJ$EYS65w+5+Jh-CzjM<@%NZXe=6a18crV7`Bys)(!GqFp&7Szjpk2($s zvdw=tuYCx~|5ru`cI*-Up>bgAaqnIaM1x-)Vzq+&iW$nlWzVK?8AS>EAXC$5+J7!5 zLvLIUU0h|&f!Ot`HM^A0u~BY&pW^DXD60tPjzwc(>V36`hLs(==`M^ps)8l%s_2!k z-|bSL8F93&lWs6tmwM+jY6Gq|X2t0MGr@SO?dj{3;10O2rr_9>3!wFmD!-KGHIa2~ z77t!>lB#|#$ca5;mxL4pVsP5wjybr zRwrg?RfV+;_`~49Fwxf~X?<-?ruUWF>Zr87mSkvEQ|#~SgPPQF#de|9U)ahwuIdb} zTF&zKH8ZWRVY|@koV30Y@269v<{SRLHngOU>#<#E^+&eyjjJ|8tE$udef==4uW`H3 zYD`*R`(?vQOpiiw^>u#h6c6T1t4B7bVlDwR z^N6`rcp6xGFds|I@56BW$6T7NhvLzUWH7%6Lun;!KjvKN)kMJ_9x1L4cs`@LpIrfW ze$ZG?qrN*Tt>Hzxn(}47a=q%H9Qzw-K9^g6y_r$1Qq}0`)S5&_Z+HIWgXrlI*i^dU zbmjj}R^6riN9NRVvQ)%Si;n-_urg7|K)N?p?I7y$vv2~t#XIeeJ zA$8s*fJr!3Dl7wIc;@{X&ilOg2AX$iwh4^xoA>*nb6W}9Kkq({{oQpOrn@Y;G|O+T z@nFuh`h0yV=H1Mm2cox2g}wZkPax(SFx>t*R+^oXiuvD=(Ms5U%rkOqx5BNRYgI&zB$dB@BA~>A`vHBC}RH z(tLkynl$q(KaMnC23?yf&Eq{X!L)ksZ>cgdiD85y%~Ijhzx$+lEoI_m+~L^2Oh~iC zAxb`JegPS+gzc9JpESQd8N>7#el9=dw@&h4&a^rq4RZ;|oCiv_ONCK>%p=77-~ln0 zW>-U1`7l3#m=kse%v}r}j#uTJO9nugHR-|c{Fh32V3Y6>SDY_nO?oQnfJ>3^c_?wm z>y;)BRXzR>Hl!iZqkaPtIMnji^h)PrQpvk}g|(vJ`wZf{>~e(neU^-@QmL+IUL6GB4fw**cSDwsc9N*MZHI(S&-;djTZLk1*X-3Z>MUs4o9O& zg`?K_G}apGC|=17a@C?uMrHVO~ni3EPi(M*Cy~BI#VL(>d*5w5ZSC_@#2< z7w=2szY{xRpbR(Uv|X*KEfRL-v>=Z_)hONATX^l|=RzHM+0M%Ta0O0zi-7$4`4 z12(OMox=IDHyk6JUJ*OEe9-OP$!zb+q!0wtTXdZ8go2Y4S2)(!uHXB%I~eta@1QO~ zPz}C=ib`dul&odyQl@TU>ISB+WoiafS1@%CQ`Jm8#MC)VwKG-9)LN#_VCrv7oygRu zOdZA4Py~1*?r749h~&8jGu~Fni0_N>NBy=-kJuSs6&QUbB)bD9DIyeVTeG5Qc@kPK zVarKu*}|6B>z1wb7??OOuttaa@O|Tv=9 zo}>4``EdP|fR^2D0idF;?iR{+tJ}c+%vN7VLe$Dis1+TIxfjbUJj8HI>CIR-^u32) zMO%tC6;QEy<5l4WrsWd7XZQ}mGwLyp#C>DTy9?v|sX_1(07MUQ#dOxk^AMiHrkey4 zhqF9u0b13Th$`t7>g>dN*}XNx)6cGXX||ApU!HaII~QEan$nDtjB6w4ag*E1yXU1I zCU>kXX^Jj~*AAD#GKMoNG7NvSBZoZIL7|=qMrfN)(Og5(d>J2($BbaM4I@d)&qxn| zaSbDNYDPNr9pRr&brMdSD647>w$Z{!tze{9$?D+F+J2XCI5;EtWOTXit5^;HYbvLB z<^p4UeY)lp3FZ*Pl-!~iBi9d?T>MQBmn`U~o|)zUVlL?X@ndyQ{;gav6q(3e> z$8F{160b~(@6k9k?&eHtKgeJRXOEicW&|Wdhlh*n1n&i)Mk6(a*LCt8w+ZebM2*pI zMxJDx;AVVXGD=+-`I51>TcbcSJ_8%MW6TGG`}cBC3+U+xnQ-sA>aVq{JF9cw!kDQ~Yl;>lLp%)AVKd zuC|lX8E5_PDCuw3<8CYOtY^}}^((ZN-MbeZ*SuIX6S= z;B^#z4MXeT^S$%epFXXYO8>e(?fWZwr#}7KYhRu|eNr!N{peFrw+QM~L7jHPX9hmU z3k-6}E6yrU0~(yi=IAzcz>fZBZXZ+6Ic%ff5d`j4pI}7&&G%~@ty%cJv4sO+^q^@& zjJW3Z2m1~ew$?iiM&BI(qmbLm%YnP4cOHO-@avsJ*UGHoODLb1#2TC&rs$mxIZQNq zXLzSsbE;k?9Ubkn-|B(2&&!b%?K8ldQ+?{cjrMtw1Tu`!+Mm3UowzFL=^W@ZcZLft zWzD$;B`(K!rCFGDmMlB}=Q(#`L2rCT7`8|K6p76C9rTB1?bbGmrut6yp6x!JnFd4c z#B=^jqW0zS%sDQ&6rLG@62mjQr3YrOO4S1gbP6@Q)iFGVrTy{zhiQ7C6p)(nwJ8UNy-fyZp27!a&OqBG8;Wch6 zFNS7^p?Fc3yubjDg2WOldT&=Rg~}DTF^ptv8$2=Gjs*dqKI+myF|Q{ae3JLHE~TEX zBPK`s*}GWcFm$?6u2e0;vIQA=c^WS+BJUDetK{{GUUmL+Bp`C1fZIR0pAJYjji-BU zDbEaZY_KW8R1Mx54wiP5-RaNEB+=?pPYzUb*X**5L{$rHiiEv@5_ith@W^|a4gXIo zJ6id*l^_WBi60~J@1>RZSmjLem*Gixj3dp+GrvHI!!yh4paPqq0_(umb?O@;=X~*E zq1qT1T6N$>qlInj>BXPTQhYuV+ghBeG5U+&lB_-!pa1F|gxj^Sdpjl`n#OK8oi0Ei2-^fR>_5J}&27bT7t%s$t&wKcJ#yJO*nI(-;TXLukCH|Q>mbMhF6KiT zB4DDF&vTaO@@cj zGL?F%t@cTy!;NmM{^>BEg1xhWoi=v2=&&cMJ9Ky*eC-`gk9zGdK05S|+u&Wn?H7pH z*o`^54%HppMiV#cTBuzH8uX}9e%x#i!=hBK`vz=m@2GlJHd?06QEIF0I3e@)hqt+& zOmCGc7vl<3BY|e`LaY7Q$}_fJbwzqBsDmEixn=nj1MTHfE3TpeX*72(#0S#LdZzBv z;Ix#H`pW&@ll1of@_ZY~Z;Cc?K`iWHc{^AN0V+K%w89EFriD$1$ zF7fv;AyW@~4cx=~2YY&Wnw*io8*Z=T*!GtLE1TAydw6$pkMA5g%*yGz$-S>YpKEkM z)Av#*kZBR7k*ksrM$!T?bY#h~ls#=if--octmHuRMj0Qu5GKDN6&I6CHju9#z!A}o zgoYrPOZKBmjXr|zI(2uUP7gnNM&h|qxSK=%%Ab8Pez|ub#_xN`Gp*bDy;1nDSSwQa zNdR6ajSUTpz#byv&}E(G#gZ;{(^rYUxd?O76POVD;ZZ(dF&9#GEH$Lk6gY&^XOl`o zGrH7EGPUtGTo#D?0sn-?q{dy$wW08SULUPa%oSSw2MFBdXrq~%@(}-qyRa128P7F@ zy-%Uj=EXh8g_(X;d^PWgmhzxR6Gd z=&MoT*d$UNL3zVGz4wjjkAQ zE7q_gj{hjDcmHumU%9p1GuELPtF^2>3#h1w%nCjb%NJ$Prc0G+$wPm<-Mp%%eLQJi zq3c0<1-BaP+(qf5Nw=!Rc1!ear&x1@Qh{C_Yv5#|BpX(D1LRa+-ENidtviTyz3=MS zejE-+JxjxdC`ibppfXkKTzpNFUKIzuxH`n;ZorsC4z;3dX~*+JT$T3a*ImIUt18g0 zqp1q#$sq(5=9Yw6YhkQ*ZT&~QUac!uGRX=(!p*=VYAl$V+XGx8sDs|a2Wj*kH|Vi1pve2RLmcV^W;9iicVwvJiGQnis8>6%E-|oLJwwGtDYue; za)x`*UQH-mAE^AQsIJu7q0UgNWUSJtx5FK)G}>$$U5G}T)tjD1IJ@_t_za(7C0BdL z`qY7Xtk0y3HBSskkIdu6Eyz4>p0c6~ut}Q_SPLmM2!mxWNXzw=az*C?xuO%{>bOO6 zUXC&KaKnEqbF9#6(-y7gAjb4r=BjT#LT=|~CN!T1?JE;!q9vc8=!e1v9;;i85AYW3 zmG-@hSta}m7gWep=oM^MN%WT06Mc?!S9{N@a_h5GbnV})Cxw+y+u?R(gd z!M=-we~Vl3CfyKlaETxI#(N2)CqsW|8}~95zKmPGJMp_zUG+FgH9pj2U-13b0I=lR z^Vi{%$$Setzjq^7r$31*>9??VgUk1M5JmPa?A-`1H=L6RaX`zt-atydgq>XpHs_#% zeF?jCQ0DExT*3~bW|=$KaWqJ+rgQ9T*53ldi{h~d@7}-;nC5nNGXuB@AJ><`G`oZ3 zUr+M4@CJ5H1g`w^j%Rb~MA#XbCgP1h3(r>0@n66m{ZP+Oi#%+#QTE&giHS#li ziu^QB;!jMM(NLeV7YApaVK4pYVGN*tF&kwC8?J-8!xP(PMRO9D@ex-)6GpsbD!TDJ z;*{P8Dja))ovAv`o9;mk-ooBz3xHUo#tgG$XJ{NbN0Nha)GV>eO5Dei5~~c0iCtQU z$FM1u#|a_YdEV6d3TxK@-*NC9)T=CktupwI}Poyo;U zZsIVA14a3g7LbvzfTAzCJQh%~8ir#)1K?SWtKM0M7aA=orUd(P1ab6@X=)p zNHh(;ekmxx_hV$1)G@sGJZ<(!p+rnrkd4U0pf$Nyy zTA?=Zh(Kz)fL{Px>5p~XYWJ1*F{+X6>uXh(_Rjw}i9t1vCkwt5?_TZ6bk5o3#<5T@R62Op+=I&Xiq}u(QIQ&-ga670T1;}E zx9nX4`olR*A%yUU%+1=T0z_J^m2z|MA*Kl0RW=q`zUEGUHm1FLKi$KP0zRjl`My)x z`Vn9cFeAW$E)dlxZys8p4cqqaR$KauVkJ2A5#Ngkn#LFCd&>Nt8!Vo^>Tl3Cw$BKy z|K%EXtRP`y3+}-7=6fSM&CFvAd7d%&N2TvBfyO7lb_5tFz@yZQ7E-z#9`g3^tfyzY z2ekC`Af9%oZTiSkPA_!YuCANHS;p*Y zjBcs$Bpfxc0)5Z<4zCo+sCoat-2927&*s`b1w#~=kR0&yG)Md7)=w$n*G6rgv*)(C zc89t`d}nCUT)jhD%;jKM@;zURTvvmD%Z9mS^c;gd%pI2N$Q+mhMQ+d+i3V(Mn?TsL z*<0npH{K_$6C@re+N0kFEui^IXE%d*BKx9ejGGh$O?>w;w@%jo_H?L6p7B5gV;?rx z@x-D>&uGan`g&g)yWShN?9)AT2lDfc`1)n}ARWGQj z9q%(sH^EeqXpo)9P?$VM$Z4M)*hO=sojEtyfK$~BUVXs84a5NI=P^xVumtA?w=ml; z+6L!wX)_zUBl*BOCDYPg0Hh75FYvxLNyUeNNpQ|%b*xT& zZ(0~_i-tY;H($R}#&BT+lo za;J`iS#;Y))$^2jR&%hmq5yd{4)wznz-@&FTZn~Z0l#z#b-FMsItmlhihKQKWD6oE z;BkQpiyHuhj4~|iC3Pf=CFT(j-cT>V=Eb=8ToIa=og9q6xC1{luPL-q8VEd%HdIb! zYq)+1crB`ePu8MB^#b*Vo~l;ZC58A<4E_E9TUE$P=&n;^!_O>uzs9HEUF^gNRszRP zbrJXXT6J}*8#!o@2^&VP4ni;}yQM-4j$D9W8vV7*vh0xgNpPTn`K6xpyirgDLSst!dM$o&N~cEIlV~3L7(#<_A+3P#bZh72F0^V}qAg=Mr~i^Tuieu0zC%teFT`IjwFDk7ry|DU%ir8&7Jt`Zw1RIXTvR~Q!Tj?b> ztpHzM=)?CxtS^#~<77B?OJ0SwQC$%vfxn+i7vP$EK)=QhqTQ9vlc$uMCTI}N;iu7@ zCKGU|WH*`bX;R#OlS{thHo3uWQXZR5oG_Wu{gYFO%=sv)Z2TZ{S*5k9JQgVchFjHP zn3?j}go47#*!3L5n~}AP!G3*~>Ip6x6R20&QG9?NV_Mf&m8&y{GV?#}Od03ay9IRg z;manLPAHuSz@?Wb-bJQtNdGmB=6o9%dSN#xYNq8=nhq*X8E|1-sOJrJxU?3pX z94J~;PJTj_7&8xVFlS{8_!13g1j1IN04#(*E5;U_0B(;@foK$B!V6U^CYD0BtYvab z*y`2QUk+Oz!)8ichNJtI$tT(J6Sl4|=&HaUsDW22tZ4k)QkJ7dUsXP`8+e?>u8K=z z--ZZA3aW@}RXBDrhddr&C#Y;WXuq%kVvj%iQ`KV&@?$k8G`!MuVL@T^%JSxh0^!)^ zXA0&6B93{0)o0R3NK6v4kXfizVv#|ACuyGXgv1{XgyYWms zlmkVOriQ50RA6A(`1W-sM@atT1$6+<+-99bX`rvu=$jBqKCiGol)>eOV{;2y1(in% zI@l`qkWjZG_DBI`zasW{L6`hKQ_ziH_%ApY%S!8}56ucTz6^cJKH1ZJrk3iKI&e%=gouB-=!Cq zTYdJTN+Tn6Va*4S)P)tnYhNS-T7S4pWj59>o7B-+E~y7tU3Yj$UFK;r!0dc6$n7O) zH}TBQ0m*B*x^9li?6mloR~#XyOwXFsXj zPU#hiD001P>_Hf)Ge^Z3f;~qk03*)Psdsti=veb$=BUNGcWmDJ)Q)@-1>a{Ph|yjkedMLE6x9>76cpaC;P?*!}(&^{CdOB z7=c$PPRq>ZJ46uEgo5AW%pgLvJfJwsV>3i3zV8u`atH`F2U3u-1^GywB^;_3m#Uu_ zB}su1k@}|Oycx+Ux86!F0`ntxt15JJ-$~9Xk6nS>KDEEeg$=we!AKE%reQ+H)#e`) z_M4HtX+GyCzG=!K?c=3~;C$-tyc8uHjjBxSn6j>drC_${@*j7b&aX>`2)#GozL-Zu4g{WOm61+EHI`0&F5fmd4~C1 z-{9eg4D-3%Tb@3j51ZouU(M&j`qcUSmE@$(XOo-jna`U|Zsz&C(3JK!pQn1uGtB3K z-tr9dx%o$)`A(nDS55IQ&1XgPZ2{`sPh~S>)NX7XR?LpbcVegGea$2s#AWjQRXlO) zdiRosRnhm63pLmgeZOH9w)0_YP4tKn9V2hazva4$k)M{z$5A6Eheq^`isqLF?~W&r zs<1vSA9Z~}Ui50W!oH|bitXR1kW^|fgzi=Aq5Vo@)zHl=Dy)BuwP@hd)n&b}MnV+I z>*09Fmhjdl+Bo=DUJP6P6eWa>oBBQ|Q5uT^(6R)hkZi?deyN}A@ng*?w>JC7e?vI- zO?f~5wm>o{`%g`WLnX5;KRl`?poy`;CdLMb7~crT#=tB)H!$Lr@W^l=SWjnwJMa>0 zdh;>(@ThP=$aAug=Z3ss<4=7R4=xwgTP>AiXTvR^8?+aZR8LVCRh=l^9N&_XqxhqNxf+CgH=E_mmItso{3W}?6}bATx*^PCnS7n+Ql|=(|EC-vcuL(kn^y0 zU_rU{B8*PF5CI+)w@V$VYOSlV9x7mRMMJ?X{2+^5)KJibw0cp_JjcQhh1?Q)*TNMr zg=)xQ;qv-;K7?^{v$%iOHE#N~$L8z}Ib0pnog+j_l3X1Sc_gS(0 zK2lI3zmFG$<@cF_D*VEIM#?Y4`9`tEN&C0xNDN!E#KUFXThIXnWKj1O@XdVCh?+vp z6LMczP)rYFaV&fSaW3MYN#bIh0tjpxy}>3@7W=k7LOxU4OPCl37IMg2ME554EXbkN zjIV+<9IvZVlLs3P=K~N}2)Ojd@t4r)ud6CbR7*=ZBWD%l>b_V>lFf@X_2_%_(f?u6 z*H8GoT_QXncL*Abg&bA9lmLUzC*y&9V+*Rtcu1K!m5#uI;}aJGP1!XOb;@hEC{r#KZG3KpOuST;+Y zMKN{#in=7+JhxyzO8wr&UrW_zA#>sQAaO39EIA*kA<(s9>scE7dF9qHEMpZ`zWPU< zlPl~f*|>jOvg7I%{NlXIl5>+Pe6=zhAD4?xvzFeo`o}~OwWmXZ`c0K zOz^x*s44FW3Ct37I>e;)d09WtiBtXXr48ZMe=lzb&Jb|&rvHiVb)H&UE?|rc`uH|{ zv7JJ$b(bYJ{*XhLf2J()ILeqo{n$?0_B1fn&tJW`t@?O>w!JBsL z)O)CmC-oxwO@7FIAY4i7=#N%!-lpNMnTn$2L~i&U4s|p=I%U0}G2ko^*2knxw?3HR zX>@GgaPznT)|9YyMn!XN9vt9>GAs*fx;a`H9&{ckdU1dTpjZXfdGMHHwGL3#l`}o) zCM-iCQC9#IEeg+EK?R}8F`R}sqchs``1A#afT4_lmn*J*MdagyWOiRcy4-qJ2N}Ie z0%NV>>v=fIh^qq8Lx)#d$8hwyB+B0e(mM4zfzaY>#;&_O28(rF7;1h{jZ)t+Ri5N8 z7t`2~@Sv$m{a73t6L>m=LnTfa*0t+#=o5<+jOPkB2~#&^8TEtptePqv$n;_ft7wKh zg(daNF#Zudx!yQ!hpgG>n(oHow>);ZgXtM2|6~DlRzW#F27#p!1_>Y>EUAz1?t$t9 z95N&ZHyBNlPn(CWx9;dm+%A0bYy$5Z+01YF{eO6Vuf?d``8`y|VCJ_i>dx=SNIUcU zDR|U3zhklVfn?tK%@#=O)Mo^ed47KYFr?OB`RkeA-!e1=0=aARJ4ZSgV19=HJZ4Q^{+C!P?;Y?2t6dPYBYA9=A0AiRDeN=cu z{hS&Q=~PZgaCl_c+>zS{yuu#YYJxF!h+qV$85}lDxwOu z=`kj?hf_=s$9Z~4r^hxkp?-S&n7KgzL;1yez@CI2+S~Rjyr;4g!(uselbB_VuLK*G z!9)R>EsN0dEGZmYP|B8amRrRflpw-EVD86~{h5=`95699ii3g; zm9X;av0-fGd-I?J{?^^GAI`HMMJhC+qjXUKiPEP~jR>vA4-Vb%U7Z#mQb`z2@Ee z_p^^!S{iKYSkt}N(#F10t1~hzTt6rq{Q$B3vm#Ant@eUV;GnJv29RvWab$B;u&qZO08THD9S9FCULGh>v5GzN8&^dF3kKtFgG7T4_Bh*9=9HEY96I)hWs_hqGm^ANO_#I!c7%f+CBtXMv4U+Pr*7U zTb=lreAY7O3%y+0(SvDw+kMH7{tS4|tGa{Ym~Oy7lEHxQma4SoobZ4fBx{`tL4#90 zwb1_Tp}mE8avWy(g)e%bs`vqAYyw;_(5Ko!H0Z(Et^*bVg4f?~_Tk07o3+8ep{Pp7 z=WS^PeGjF(3;5)f1lzW#-d)A%+@0g}j8yT_sNCRm1aTUeKEUV6Eov&qwJS7gziFp5 zIw2jOr=-<7br-tXIX<9I*A2Uf&&fN-XRcK7(Py~9C!6>{jc=zz4g3M6EpoF3(vTA! z9()q6i%$^fiK5yps(@TH2tGLmH|QWWfPZW=BImVc1o+PbljSy)jD+z z$hgb=G?g^pmHF$tai=(4F9`VP^_jFy(g&<}|D z9EZI+w(TphU0*Q{OW3&mef#qP%SUvCV;8|8d~qO>b4W-1%Ir@Nh37dh2J2wlh+!K! zE)e;O35~8_9>BTrkiJ|5tS0~AtFJ>vusyE6pl(JkxAW{CC}l^^3&(O^J?;p(Eg}SO zN?t{CO&~c4!ITvvKZ#(^yiQHO9%j|ZtMai=iEgZjo%mZ;hdtOF4X8b+RbVQf2@;pr z-%yyHe73Z1TETucs!?j_z_%8FzCL>vEF#o_DLVWAutgOk{uKC zU3ATe(|5o&0mvP@8!ga1^Wnf>1Hgda)Gz#e!hgXN-jtmI{@WOdfBq0X8yd0RRvX~s zoZ;+=uD$0t4ul|9G*3ZnE!dp{gTVy08;f}m(}Z$@9Q z9J#5&`g`P9?IDlhjewD#Mh*exBKslOB@(1}WW)ER(Vz+|iP4mgd^?H{UT(CJQy0mi zzPzx)>ef~OzSDPAe)27Xlw+#C}(BzBt7% zuUn2mbtA9mQx$@Re>&NbD383ZWlaDcNM37FpwIU}-%Mr(^b=g@l-Cc2QC^W^Tr+~2 z_dzkMg}@K08yF@3#>e;YsI}bA#&6KE-qOU42X0;Kh*!n7o43EANe<<%>s~=qq@R+@61%)_Bi;X^xy&+t{LkfYjkm~ib3O4EdzjqJ z@fPd9OW6I#LoN4~XNb3W$XlKv-lD-$w{5hu$$|d z&r?ip=J`C(l=c@tv-t|od}o-?wchd!^ZB^9JbgZAo8q0$r+aJyo7p{3DYyRWIhp4> zG>r&fc&VcK#z17k;%w*?9p=;28Av~1ig2Z2tNrUZFz+9q+!8m~j z>H^qcuS5{;QG&8H+AP#&UJfvbzC>&50swd=+TG9*w%(3j$~y9rl;AybYvgj`yD#y* zP<27LU_qXvgI7ju!HKMDfD;Os$nl`)em4Rr-*F6uLGJQVH{?a&V*f~e_i_Zl3jWC! z1X!#Ryy~asWkn7q$^r^F1sn9`Lu-=n5KGj2-_V9X*iRK>nOb`o76xq{ABH7r1s=IX z<*8?gmuEieMnA=>vKq}rN>-y6^lH>O!M_?k&YGlWJZF_j#&hPmnQU*$e}SY~jec&D z>Q5M-Z#8O}$ko<^Jn@G;jQ6i_)(6Le9QR3t2+lx-U-kP}9)A5E__b7GaWunLPzxJ| z{Tt3jB~}Kp6yVrjQ)U=WBn+EwO{XxdwgSpWt|hh1sVLxp`J-#Fk{U>`}o| zA18ijbEwUlX>mr)BphB@+s`|fkt2owZUJ;2_8IUO-~6V_f$ubQ!1RtHNE#=GV$7Rb z7u_;3OqqOFGu*QN8P0@b>n%0VeJC*%=vFj;FTi-9$Wt`z)?X%cOU^N4iat1^gYuDl zEM2Dy>udK!$t_0qvXbwIIFpsM3uP|1jQZWz*wS zlo3$-d@w{}auHs_lz-4ihky$%hpG(B=H(@3k(zm_d7!Y<}!vV zHivs5gm5tgLrXjZ)UI-Inv;KE4WCW&Zdd$f0XJMjaXkuL-*L4+#zeLL%eP5iyhCVf z9I{bj?ZqN*tnfpruulC6c!~a#S5A9`KVA5Lr(k*E{~4I3!#zQOVeURsM;N%55U%~N zU;OJ+;h&!o{_3|l8iBt=k~r^%+}Ys0_#-w0BvQAtT0E3RLaD<FWZi`ae*^z(Uigc*6Fm+8ZzuK#e~5wqt#tV0Up0i6fX4^%;|1|Cxl~Dz zNc~UBH}dA|%;l7{ZXyZy-51m|`urQp7TZ60RT+xrQwAe@oxLUc!t9Sk39nOU5We+3 zLP@BaSG|i%6tO*~W&{&KY2hS>ItkVl4mxEu&+J1#7mQD8I4_ZcF;mWDo{=h~x^qTU zE?Mi;5x@rX={X-Nrm1CpQQw;#IkvuckH|QLR_}`_E}pL$`;HjGb7kWNM-tvp@eXx_ z9_nBK$Dr6U`FvWXa=8Utt%D>dAI&_rTc84VGPZ71F^%bV^LocmOKqLWJ3e13`Dk;Z zWUW&;bO?93Xq5pc{CP+5I1@fzvev00nRtvxk3;h> zl+jiW3FA?JBr=FrLX6S9i}kSHqQIpNtBAvTS65bxOby&yu6A6oJELj2h}{i1n(b1> zH$^{{taa*2OqD+09B_V~e?|}FfPM#Zh#AN~w&|gAAhS7VyF4v%nc)Eka%%cOmKeVH z1*XSnAAF}m7Ff)O+5<-ia-_qXpAf@+7C+q)BGJ~V&%st|!;z5CCo!?> z)EiQ?P9156WQ_A7*dqScC2Y3NT(|kuR z!~ytxis3eP%=iP1#$m+j>hmG$_f!9a&vV1|AE4*$((^tno~_A)DbmyO@Ve+Iu+uzD(f>#^hzzY2q2K|lBjwffT!SA0jfkNP3< zloqRJ7!#eUABw3TmR4z2{iR*Qs62|-d*`BTm&I!eCVnS+;#H~Q(-T)p);e`2_`{t9 zSab`;qC=Rnb#X2@DdlC8{p4Gz^7GLgs11bP>gT^q~M|7y`_C@RZ(XZ?Sq6Hg%0gHl)FE)B9 zGSmzE;}O)EQjT>5?$?7-XcKIBkPYfb-=mw4=2PsTALA+9Tox!F84otTPxR<_xl{@- z%}bt(Qdx#K z7G#H0RWZDWu*VZ$3ATotCQtp8ZNLLnX*^K$oirX8uX$iH0_;G<7r%nR2OBCJ9%w^` zS|uOnp#_LQiac^o30Y!1&t`by3-=rX&klghq%ue24$hf**WDvL!Nv`qg1p3Qcrx~H z-RSc)5*KF6%oOtplu!H?O1EzGsk(5vo}okS!n39DU_M69TEzO8sqK54rcEf#h{ae> zL0;l?JZVljxLi2pNqGXKHwj61*<+INoE2{7GB??Qq~VmsCaHSQPT`c-06$R;g6ZxS zgxOuN;W#@7T~2X9)|zBI=K?pg%1u@xX}UbyBvoT-mshjPRiLx(@-)-sFYO$3`RQKH zDEBtd5g*}ZzU?O8K+<&inn|ktQ@i{J`bdmK2X&)s*)#(F&6&a!=ktDt+P@zs)PC2d z_6@9}sr@69jOUDZGppU?`A8Z(&NWH(Q;gInm)8Q1WCOMFI!LI^2zlyd^vm2;$W_bn z01p-vjU%pV619s~e#@!+-d&6d@-7U{brBxkjy~h`ko*%Ms=cWeekT$`7a1ZXT9b1e z|CC-2c6gVuoNxfDkqj}NRH&a?m=(E=VKd2`$t^n8;274>$}=*7if{wQh+uoVyesg= zYGhCR&5gcN5j*;eA*jkDf7~&mF2@`J5;h~E&C_n=7{-eUe)w&kOk9um;F5Q_%US8= zav8-S!17;avDzK)5|Z;cjMrVy6NiFip7k$-{ln0990uo;@P(Xst^1ZjT~m+cr|Get zbUjw6_1Lc%PE$X6PmDP$64mS2=X*kjm5?3oWZT|Rr}eAqMhu!?QZBw0o5ncD)<;XGk0AGti(@H(<-&%iVF z9*N%$<(O*H9Eu6lCQS)Zh(1&|`dduscn7AyP|2TZZu&u)aMK1`b)Ld<_8rd|XOi)p z!`#fTxygf(G~9HcNvdh2!UWs*06l^Y=Qsw< z2gp#pcuPQ{O9nJ(z6zO5QTV~eY-HL(;gOVJqvBNB(vo-sPx}0;ZuCrzgRy6(@QErx z+cQ_|LSxUIV;5?BW*i?~d*(#Dbhqu9aV5egjy>}gLegxKZ<6txE!j@yCvLI_Ny8=| zn4~HM*ZJ6FNU6`B>G~GC^V>6XT#%2NWIU(d&8%~iwMd#SZ#PNx1bXmwc`t_Kv1hI^ zU3%@Aqg{|^nq)jD*Uj9=P411P>2ioks0B z+SxNMF2#{PwxEYz4j~_j(COgVxC6Z<4IlU?s<5R>G>q0>4D;-?NPDKIp?>s3JMzH* z`$O;Fj})yWbE;W4`YtIt7`!o!DewkrMeSNzZ$EjKu*jRX-oBkR@ehseG|70*HE!mW zZt@Bw4U0@LNp&A4+s7ieVl?uCVfuJ&`g}1VBYkj`fZ&ck+&d+6n1?y^O_@!v3o!yt zY#MzGJx|?9`GIb^Y>fx|pS|>#^7W&f{>1-dGgTOGF`F<4_hn~&;VivuCKQ4uCIfU{ z!>t%J10y%;7#$ojW~oac=sdBcA7N>JL|P{)cmSM6TUj?j&B~6X*>@Il>iLem|@-?~Y zySkTOCdydU_$KxzlUvfUFYgC?OzTJLZRj)y4L^E_GPG|LNv;L#!LJPUL5H+E)T z@;>qm?_b=igNh|oAM=JYx%xOfV$=A_)ih9^YuB&A83ejNnJc$4c0(?Fhrx!QBD)gz z7FWj3All9ZPAn{s-H`9hAZ~{QrEBrN$%~|Puwet*=`b7CN%x{1lnuB5cyQV*1{+qP zZHRYd-vl}WlRRS5cq<-wewkZ=`<4QcTPkDMz=atlbGc|;0lqpp9jo{Y8mqSenJ~cT znUFeo0Hiw66lxF7Pp@r{c>GuteNGRktE7*}WCZ#o0>IUdU$ZC8H<`gkZWG-JO$?P5 zW6?+Yb}QKUiqF_ujwfEn34-UUO{;~qt;ElyjzQ+Hk{fJ1Pal7F;SrTnJyf3fhtg?pcH7QKHWjwy%Y(=x!2E8MJ!jpT}o*pz`e zi<$-ee#7&cvpz@DQqi%QS?g1j_s8#9z#-HC7U!jiKn6ZW-1@@@XL}??8^rrQ68mAp~K50%o9mq)lkB@nav?tjCj?SFLZ2PN!1FHP~(`0<98jmJU(oR=!qSl` zCp3w#38OQTD|QxEK2%Z7-g2IdYI(;{Z_#}RIMn%Gr2Zd!Zv!7ib@zRrNp=A-hG>JP zcGVRFB8HeC??&9ff`9=LBBdBj0=t1=NMf=e&{R{2_!f~;q}JxLl%`zPrj}AJYc;jh zrc`NasioAmxh%E0C`h!_QfqBWp6`F=OtRVRS@miA-1l?e&VF{kJOAH#f15KiyJwa< z!XJ(|*w*-6tT|fCIR3C5a-5PXi4ro7bGJjfiJ>RuOHXQI!mhjED=}wtYkm}`GS=*I zjTtBY)6l#6>=`G%(64tn$Cv2!m?tyun0=qDZ+evG<5YuQ-_&oPmCEmXIo|W3%|8)$ z9EWIJb_>&HS#(&;elhc*&0o@ia2%7X@vixRHq$QbxrBCor8ZNecB9bd|E4)dt$;3)jn;nWRU+zT@sKS^h9h~I^{eBh-el1s0p%)6i z!ETxZL+`s{#oAuSzTtRr778ZM2^PZTSH2wokA2GVF|6SXYC-NL4>|s`s3sRZvv|qP zUB-zY$Z6NONnH2ba^lp9xB3PIJsQ~6n;>$oAJGhsDV;-m1>cLuO7uzLmH=@2|44lA76Ovq{ z9h<7tGFOT(?f56{#Mn(Xk^etw|Ndj|Ug6}$_U}J_miABEPUQb??LXt#Gur?C5`V_= zPWxvXc27#=Ult&f^p8Ha!SO$=AxOnb7^9EZ*kMR<^`HL^yZel&c9?Pe@9~?;u)CM_ zb5_WnUY~hD6%4!k?WjO9jz?ctifVns?!LZXkooM{|3W=}8|4-Cf7IipG5a^LA2nt@ z{q^g)o8EW5{%M98)qD2Ec;>Fw%)dkJ2{S{_QkgFfYv{q{cZrviC;4e62j(<6d*Q}8 zpYG#MhBe5wP*!P6lRpW|Geh_d=16}5_Zml=7yEt8Qy&7SfW z=L_d@#*{OAiZsAs(+^`CcK0y)rVKs3i(ky)f}#Cq*Z7l-Eq2{X8snWkoke$z`b$Ba zUcvtaq@K8>!EX@z+;VCxS1O%|CHKdNN7YHc%IfY{r*HP|#q`f%cgsydw_|45t6j)F z2rjzX7iCA}$*&SvyI90{C@dmK=SpQA1*JHCcuWWFD#1cu%HiGH&TuG>*Es zak2AP;~Df~X$$?XZp@@Irc=`Te@e1~?2}{VDhGq7^Pi9R{F74ImN`>?F|6T}lmPbx zoSvJXCTrgwUyY6YI7<-ge|L}y`@cuB^Z+Mi(d!VOCyBnQCdXNO_c%e>gTirHd-vzF z?>o3=1Z(a-FfUEUjGEkg<%bDOZ+rVEznbCP_bMtOl1|q>HgnABo<0w?Kb4=s+;?35 z`SFKipQk%ML)+qCq?9+Ubjl!S9R>S&M_gZGp+%>Y|L9u#{$$^7n$te6ZcFpM94Xcr4Jq$R$oDdmjlTmk_73$Z*bD{zATxEWW(vO&$`&-?<*hC%^+J zHD}2WrQVHr#O0rVF#EoDPrTVTUd#2be=2>_c4*-IewUA9-?iI2{mbrE_fqrxVMFFK zZmyhPT3t)myFG2cvW_)Lr`#y(O)v$zBAbhJ`b1yDU2^&X@p7klk*kZB@ngXggPs46 zk#XngUN=Zk`cW@`xm2d@{FPKrtn9FVPE(Zs`^&!uNN<`wEF617CbV3J=sjY|{YZDc z=XmQ~hu!s_C!I*MqcgrEZ@A}SqaZ{OMc0>wVas z<}e?7Q5@&{XHUtg#qk`5rWa*s`i1+{%AQ~L?2%Zmr^un25g@7`*eT+NG6na&!P5Z$n?In+Az&E^lON{E|8IYA ztWX9RhO9=SaenMFXUcEa9NKc?$$9tvbsmN1MrdCnKYo>S^xCq;zB1A~+Q|K+{^Om@ ze~viE=?6!C@vxsR?cSH*kGE172kk>T}@8|?qI^!vxKJoFUE?@3n9bR2kv)*4`>0iG-Tv@xOCS1I1O<7sE zrnojzy8PDBm)V{Y`zx+pURtTW^?FDUk9NO460XJhveJ;>iPA|$e>G8higd@e3;dPPdvP@8p$W9B(}jpj3&N%I~1jye4~SKB|OS*^LIwsb{!s()my|EASdp)gfO3DG9Q zH~WXGk!4O}RsA=a8zy=)2T^j`?1_3Oa{oaze#~SqRml(A)cbkML{;3Kp($}mrrbDr zwrTHov8Cw!cwwJ~Cic{rH@~GDU~}EbAnksa#n;^L{Eoc$JHIFH{qE|*=rl;$-2HUE z59fU@@AG)eS=mQ<^UHnpG2TAj7x2E2_eH$@yf5ZGg7+o7Ma$$plJ_Xym-3dwhYT{J zjp2PcZ#O=dl7}> ztX+IwstPcE!Mc>usZxDf-J=$%hgB1{UDh4e7V8Rix0R}9sCCvk>htOz>q^|;tUhmT zu!3q1BjI-SsCrVZSD&@MroO8lu?M`d8RbhQwZLmVt zN^6DnJ+;DmTzylmvVKSmpR#VVmRX;+>Tz=udu3Lsb*puYbu+GSw3^g@RcI~cyHdYX zw^`NJn|A8E)!WKz4Yh_@=~jmImhxFQSXI_+T>eKb9N&K>rZOvx@8#AED-Sm- z)n8Sy9r_GnTWWp6nq~#DPqgx_Mb<*TEwCn7^DVzM6;83Pu(GWz>ssqdYo>J(Zbw@q ztpK0Xh;@>6l{Ex+Q*fDqi;JvWYmk*=jj_gB=UA7+%dAT+ua#+~S|hBBt-q*F^|bo2 z`ilCFT0t&?l&w6Sxo@**Q~&zc5RSYTsIxeRrLf-gS$v+)=cT+ZV1M9CMjFRDGD^*` zzn`J}91~>>`IyZNIFda-JVTuw^*V#&;s~sxsKL9?Qu#K5&x?7RU&A;$-o?mtIdAhT zP4&G-t1H!bj>q!36#F^-ULR3?uM5>!TKX7Vja8F)$>(VFYw-O;)yAi&*(#{6wK)rB ztI51(*`GhKKd({GV;5`RYl@nJFZsNNo*|s0ZsPO%e3rmk`*XQk&bQ@iHLoeWSMb`$ zdp&z)yjDbgu2w5~mGR!A%6YA{KUb+$Y9sGe>Q-JGc~|gS&%2V>6TG+cx|R3$)N}O7 zR`o3YpF#N!E$`dvDfM5t-K)Mu@7t}uLGS%Keq@|(QD0MERgbIxRJ&-O&Faf)r}~oG zp}wddQ~$x3@CEw%=hY+XbBqw%=;2${XVez;klL&sRE_EZb-%h#-OC8FN!_g)7)$Ea zo$3ztDOIOFsWzx}>UOnOtx*wGqi$2xs!AISty zU9aY=d5kvKskv&lnn^#IuJTntO;cB^Jav_tswS!lYMjbdIqC|P#f<9`W@A2PYUeR? zJChl5{4xEXxAyhbc;7tA%M5xjJ>?8$!b3?(3Nv*Nz0GOy!)&HS^^&t`tal*U9#?Gv=J^XP>ir9Xd+++RQozKEVUS*6>3?-FLRne@(4^z_k` zo3!rBDcP$jv9XltG+OsHwA&jg!|N&K9J^OY&yZIx^{|kZznD;lQ`YI!(jq=@;NAb_ z`Vgk8V%m;;_IHzRhdIUmjCMbXuqV(KhLfXZd|uhlMgP6I^rD+^vjra^UK4pQ#m8{k z$#6!Q0$S6}xEW5%y9GCOw84og%}mhcogFC#3K5DgApmJzVx>TygYg=;y=f>BDtj-^;ge@!k{F z--pxJ9oNI@^H1nr?^t$e#p(O5tKp0R!x;sJGY-fYFq~1Kn3ppW^dAF;+oOQ^bVh>V zj0K-$gmOlJ+TQ*z{`+2qxSz+U8nFBJmGs_!R}YTYYx``@u{Vi6Jd~b$HmN$F9+gS& z8A}hCL?6nhM_flsoA&`;*V{d*kbbt9J|zA2CfaE+Ewz+3|F3(6Xn8B`V?zb)vyyT4 zHjX!I7?nsL6J#q7vykE)g)U8SDH=8Uzj)nd$b-NpMhP)qK0 z-}f!4*Ous;m$BZ(&NtbMw)9!$Tl9M{t<81Wr}X)cEdvHGy`BB~*iV1{bGONT zwCJrqdWY}tv7Z^x?p?;X@71-le&OvCV@x^%YbtN8th&9@U%Pg-KeE0$tX#vbT%+VN zm~F#fD7>O39G2^p)m0ViE2~zQmsa?-n>>GxT3)(*Ww^Mud_&lucQyOr>RRW^3$7Fy(%SN66=6GO`8auv{u-!JBPZw7DvGPPUvatRmpxQDrP5#4B~`Yj(!Sz}E2lu! zNDgGBt5=t*kricXc~zJd+bU~{?Hs5`71xf7YuBopl~t;ubXmBuJEgzsUt&vJKpTc?8e*b`x|@9*)_-LYF}hqz}7ZvKCbz^ zW`}0UcE{ZY&25@bYQCUp2iEsd?|yyfa{>G7d5<_;sd@bK&i<%J9oml6$?rML$&ckc z`(kpaDqJfU?w40pMoOt2npjoM>Qa62yN0&9uwPr1CRh`$TpsSd?mTnd@^Cm*>t9{E zuDG202X-B=sfd)@O{G{Gy6yIp=}%t!yA2WDUd`pneJk1Sbkgg7p1h`@ypkIU;nJGr zEB$hpK)QoJa(k8TRM8zOTpKAT4`KUG&cZMQfOKOLh_%8miL^8LenXHn^rknUQ&g|1 zoaFYUckB$`iPt8ce@!;?WZ8yRRg;?X4Z2LrE6ZzFhC^BYOYFkB+HRt5SW&Ex`o1sf zdw`(;Ph~^Z49zH!uK{QGe9L#tf0 zSiX^q%IW%RZ+nO>j|X0LqWq=io0{I=I(DDt?WHx9RMS+yGf3K_3Q_p`20`lk_Hg-% zl?)@b_GoF}of)bMWi;};Y3fY~xsok5Jqu`%+3qOBpieW2_(R+bo9d6qy{m|SZE3}t zF!`&l35Uv;%V6wSF86Q98oFVszo4|bqI7xKA1ben)RZq@8azPFYk{!QIB<`8V3$dp~v@ zUuJ)Q=Tav>Zn`Eq?p4|`M<1=@n|Pf)e;D9Dp!I4^*MaN5UfU<#Ft3zqU+3y39?|YA z)13UQ8|tubn8TgJ9j0r#;q>N5`*+J}!lK19if?dT(a|q+^1JzLC!G6r_(ODj&F4Dy z98K4!8~zgQ-wi)E_xkxWi)R$%FIp5Gjq7ay_i6vt=Q!~+>G(IKIQys0bC{v&2H?j3 zN=*FZZ((%AZaui|B9;quIc93Q;m7tb4h$=5n8?T>z`n1|M3O-`!ZeXNVaOlm_{9ia zRf)YOyn;T>0WRc>LaMxyu3yd|RKB9JG{Q}P9QDo7XpXhwvAW8>b1nzbvI<5Fyh#^i z#AmAJ$7A{0Ft?KBxT;EPYD(7=9@EiCRTWc8rhAHUBwV^$C(jxG3!du;@>Ge-`EYltE`FZ|bcWqD1gy0j*;{)%N)Rke{TY1z^;KwD6t|Pnd{iPAVjNQ&5 zf1o~EvWZPUlW=-_4bvekNUnqpVRiIPSriVII0umiwb3XBRo+|6eu# zL-Rj1zp44G<_|T0s`)F;-)p|1=^j7)InMDfpy?)Z{sg<6Ch2m?y|Q01%~XoTO=YW( z@|VQ^KE0nLKh|J7=2*`Gm@K((mRcp!e%F z9oGXtW8xo|8@KPwSybgl7!yQ{|J*6j{&k@x%z!SxeNpL@^2-T2`H}DTHZEpgn`7di z==6x(2^=w3S5+2Qy;l<4^7HHPb+ElKgg@CnM3*sdfA1)I!%Fn!ppHK$;I#91uW@+( zO%A)JIPBIuf2y-TM$--3t$%f;Q(i}OIl6i*4f)HB8j|8xU+#p3GV=G15VeN(;l{T` zrzhuSC*4Q#9X_GCS?9}5|32-0#~ddgZaA^j>Ce5=ok!Rw#=04do5b{hpB;un_EoB4 zxg24CD-RXt&bcmL9(voucqiTgZekOl_qS;GO}hTdG?(4x<)YF#izXJ&WOEZ}VD$v2yxjUN znC|5JT+KUlKHdE7(C+`8_4@(xIKju`qN=+xtrx*spo^GjJpUN)Blf_3LV z+MVbY@A~7*Y^TXA)h?U86XzqQ|K#>|oZjL{eoZ%gcYgiPhQD=<6Mm7V8@@Y_{%6BK zt;2mGCj5ge^)FjQj}Ox{@1NtOXPhqg>6#^))tYWP-TtMncEbC&jSmxN^d1-%*_S{P z4-i{)dff3LbB2?zH}&{1Lg&Lx|32;h-#R|Lk36{JMb0#*JaY&5aZ5fvo!;AbKj*{i zhyUkXKXlrC|4VkRf%JTQ!N@Le_!7=vQq|>_ku0Oi1?ZfM9 zT)mFHl;vI)i!*ur-~0NS`3n61$>WCGmJ`vv9u#}u=7a86KjIvB_I=S|%>2o{el))S z71h2ulzTi-G1pbx)Y-SXX`!`J?E$5mEw7p!`HDfhsNb91Bi zOd0Q=D)+oJXOB}q3p8Wvr@t@L`SZ95PWs~vFtN$e<>!w&FOFCK`O{|vXU@8I_MExb z70jD|{el}7E-Jin@yC~ZVrl8J<)Ludik0Q7Zmn2dSyg=-H+9ymy?x#K4LP~vt{gvM z;-tw_F25o+-Ld-B>!wD{ce5j*zeTijvqRVa@y~!+kX0A zAIzOR@WNnh#pz&l{Tk<0@=@!!OHr?)i;`C23mY`F>ZYX`%>kb~$ z^{?r+XP13G`hW9Z*T4O{?sxFyCE2!U_V?90e#KlL&z&f@28-pcf3dz}lG|(PcPw$o z<0HDfV#9a$t9ANzyy>K8x66~x{tlP=y2cLe-p!XAPAub>|G@N*%ZWD;-3%|KZmGrUjgU@ zyZ#l6zRUK0%Qq%9IpQhVR-STz!`+PdzcI))i>w4JYQrA;`O#3;a-T$lF zPwtfH_M?9R6IFU8Jab1jzs^^+PEVSqo4D4@<^W&!fpdtMM?f*T}AGiHq_rbFezXSB^L%lzPP}awiuR6xU z2;E7nbI|#Zo)qr6Ph<7aEI8!oKY9w_W3U3w{=+|d8et)9fy-b!tcG2%4yLfU!u>D{ zHo*e82UfrrU?V&PTi{XH4r`9#AMS=JEX=SUX2Dls0el-)z%9q|5AS~+|1fj{|F8je z!6umUF{RpJ7ChaBe|XND_=o;K;vbGaiGO$uw!=|>!asZ$rubN$`7Qjz;GgjifBg>r zVS#nJrxE(Rr+eDr0@wwcV8I1SjUR;0LK3?MpYCaauczP+j!He77#v*WURXZ9nNK~9mY}o~O z!W4evvUDlwfO~Hyd^lny;ls^!_=oLxp6=;@1*`(y4Sn~X?#Ud(`Y-pN?g_$Wn@{(I z;K41Ydm7*>R)lVbFMa)VPaAC6eY&R;CViW9P+#}L6zc03%z~$31>E{H@xeD?3-o-4 z^uqID7hDEYsLykr!5_?n1+WZOz%8%~?iHQ-+%GzOMRfQ&Oz~3>&!WR1EP!ia1>6Z6 z;UU-p2elGE+yuMeQ!s`0u;9D+hxM=#?t(3_6Sl((pCdflM-Vo`YS;psU^{#PcEQsy zg?2KYwdS*62`qq(umV0UcG^pDA9nZzY=j5CPk6B9dBTH{Hte*I1wSObQS@7w1uORB z4<3OPu<%E?gE=qYAEvyBf4Bg4!JROL_Hznm!C42e!vipj_A4XCt3h9rq8NLhK;5jU$p2=^a4<05wIP?|#!>PZ*9nAhU?qDJ8gd3n|G3oma z`>?Wu{ZG&j{+n=M;cp2?_Ky$_O!^)1!gG$|j>Tq1!%Ub5gK!lL!8+Ig_rYd(0Jgz5 zVJA%b1OBtfC(ML%VGx$V5Uhs{@P60~pM-6&6?Ve?&_lU)!A$rr48rtdxPuE|C%grE zvdI_Bgm=IoY=R-!0vli}Y=$qvHt0Eyf0zY5oRv?9nQ$iz!rd?gpMeeV0BnZ8hHdb5 z*a?Tcj{h9`8O(&EVGvG+A-EVez%tkj*TOcq33kF}=;4oIdtoMQgF$!*hTyBP0iJ}- zaLft(!=eg*!!pU)du;X)XK_reDF9BhN9U?&{&XWUI;e1k!_9X7yYuo-hg~q8C+*2!AM#)ptbqmaU04BgSk}4`mce%TChUTB$+%~ne+1CWXWkUR4p;#_tQ6k}Ghqu1!gd&fU2ro@nMwRG3wFT*m_8K$@E~l2Z^IVoI}`tK zG3ghQJgE0MC`Y9X_cfvwAJ{AA4 z1a5=(!oBcucnH1#Pr+j_eKyCpVfcqrVIi!B5%>t)2K{OHhqK@zSOHJLT`+wP`Ga|I z%-KCXMX&_c!Fyp7Y=y1xE!Y9iKc}as8}5O=xzroXgM)ZJMG+hY>)`xCGY0CfEdDhOO{j*a35V_=iiN?*{rI%!3`U2%d&@aP$TEhYMgU z+ypz|ZrBYEL*GK`1LnaI7vdkzhIOzKHo4f+acFE9^228-aEuoL=6^z?Xcq&>q1_zcWkOnZPqIO39? zo)BCD8{jF}498^l^t8be==nJLgPHJ=k@$lz!4UL}!XKOpn_)Fii02^+h9$_=wD>`f!9d^ooG3k?in0^`Ym2fVKZ!oZSX1B2|J*ti28<^aL_dT!weXLBVYrZ z2Ag34Y=gJJPIwpe+)R1EO!x#0!UHe_3$MXH+zOjv8*GC|U?&_Jz(4ipgPAY@gYXU* zf?GwWKKFPOBkY1ruqDKK$!z?E@i&)!SOGK3a0l~X z(LB-(E9Mg}?7p7xV9O2UQ~Vd=4%RK^xCINA5D)Y%#ZGv>o3O*8BFYhV+)V$6U8Nkq zRxl4+Mn0hr24NN~f_X3ki(n(HfX%QDw!%hu2sXhk*a9T(VM-?f7!lv8s z2U}q??0~JX8y{s9}LONFCZw=uI*U}z@x07zzw2p9K-Fosx zIE~PU{}z}BTVbJu`$^oxqEAuIgqw8-IxM&oe=wzhLm<6}NJa`Hgz?53@2Qy&>%!9rilrPMJ6|ev{ zhz^@z9o!2WVLNPsov;OV!&aCcAzd&FcEBL)f<>?!Mqt*L2~W6-@`8 zTL2qj5lp`weK+}n9p9uJvA67@e8t_jNGJ9p*Z`Yg6YPe2VcuTKX&vc@g|G=$z%JMh zQ~nF$&i54MDE4ntPO#!TYzQ!jAKNCHWz<&^ZKKeO^_(SL==)( zx-tLgkD#04??itBz0nZACyDco$pO|3j93Q9=<}xr)UOPBC;I5C0`^+o9^AyXUr#dgdUR9zGSN%Wa}41J(YK)I zQqJ+h51~Jw7vLI1e7ynv@YMm8YS5d}JEsNIV1wR<-gQkt?K7mW6TKx6U@ge_@q0-0 z>*zl>=$Yux=G`{~JdcpL7dNx*{xiMMBhYC;T?_{e$vZjWEVP`x1XA`jNr_t4PMzJ)|rB#sF*n#n&^@ z3kK(_5`!K@Z$UrTpoh>)2>%g--hlo*{y!V5>+)$vUpyqA6$Rs`uMK?1BWN0)VNW{^*+ zdO-i~M1Qh~btet}J%brvi2o8p`ZLjAzd4|08vF;*W&Ie__!~l(^Jt8{1S(nO3KZ~ccAtPj}FAc!58m zgdaqg_0mjw2wm1W%l{4=o_dVaoYFy$Y8)sBFA*`No}H{<^f$zR>T z^oP(>eEDj*=noCl8_=sS$X7cheLDy0&FFbwGRNPBp1L!^`7gR3{Z&KyJ!f-Y2z`Y? z&qOc#azK4M_V}jDKZt(e69Kg}w*0joLSOgwfU1lgABfLx|L8}*9ZnY+=`h)p(e*N(e${P{fLAtsz_``k%&ppu~47N{@<9!pXzkkzWSXSESxPa$vxDSrPiCUkB6<2`6iyUWY#FRm#QC zE}PJ|9pSpbNAOR4(d8oXx1wjC3UJRmzTSbp^&ix`A^dLiYL%~UjICF~mhgSVdw7ER zyebd93!Q4~pFZus2whDy&ztMev(ZULT>nkz0ra3jZ$)oFr&-1I-+{gv{St%TjlKun zlztz=esqS`RH|4JteLlJ=e;w#G z=%(~{qt_=0-#47|HuO=3^yQ)NP7r<(`g7=}{MDhi(qAVV!f!%9l|XMr&$>9@c-^f7 z{T1TRGlbubp3XV}rt0e`rJM_ zeRBf64*d~yQ~zp0e=>ppR`jRQO~=m;^aJQL^SJ%58~rtOQ~CHfaGjH9E}uN~x#*_y zDMDX|ZVJB+{qY3hH=!R%5PmCq>ec4<(ShzqH?@y$^rh&g^!bn>(GZzGap}@&~wmD_1B6%8{Js{=t~pm-RKnwbRPr59SQV2^eyP7<7W~2 zW9X*z*P%a^KyN~SDS_UKeiYp_KkPss!@8HI_`A`kC(wNtQho{aJoFm$1+n$(&i~M# zN2i$M*FXBJ=rqH)dK0>=+i5y}x1!7Xo+iBmJ(ysA)Qv9dN}BxpF5sp!ocZmN4dN+Dwg7AHQ?i(lYpNB5%j+){xLT^qG zejU23XKC`^gf8n|n)Fum)&${qpv!uBCjZ^&vaX&<_g&2SO@i?A&}F?Xlm8-gS(nSC z*P(YM2)_w^DgGBK`p0!q=g+!-wW7D6Zx;QgD4l)ja~AD>R(Vsy#wSy4) zQP+R#K>rQsvTiMxW8&6xGy1*grg~~a-;Hi+C!OdA6X+f;aGXRp^}|f`^9#)J2hpda zo7zbTeI2?f{08)$=p-|K{?T7ZptqsFnLzJEPoHNF-$TJpO`vC@mn6`G=$p{vwL=+) zL+Ja^rA>Nx_g=^3tLP2ro#>|eYex6XH|uTandqkS?L?oC4&uh|8O`s{&`tH1iQa;4 z_m3B&+OO^(LG;t;_Bi>gC|&0-gx+|)xqmdEKaFntKRVEVGy1Fr=JdCrSE8HBuM>T9 z0^M^N#}RZ>`DLQNk|6#dx?=rlQ~8C^C!*gg<^SiX{OR&*K$rEaP5ztFWu0r2-iGcO zVZIL7i9Tkbjz9Uweb?!A{2nsC2i-3Jk3{LZ{xZ>hgnx~spLcBg4Wb7Yna?vq=(2wA za|Ztn=(1k-MuXmrF6#i>?JrLJZRoOIuu1PkFG3%19_!|xfqNVJZi(L?m4B^gq6Zh} z^PFKr{?Rv})6C+QPY8V{x~Y9Opg*5LZ$^JDf!>Cm^l@|h?L^N)H}?N5e*c7SYG0Y? z_b2clMBjtnD*4YDSbib&$|VVY|AW2*-BfqAx@@m0u8j1G=gFLg>2__-{ae1^rn={LSdwmYR=WZRpP=&^ytOpvOBt*~g@8 zj_)_U_dF>JcdKysh@^A+z)U8{JgTjp&QfP4(P@zBYm0j=nvC-i7`Y zx~ZO1xDa*(-Biz6=tFKc*K+~7tlMq!Ux8kRzE#R^;lT21M1KdJ<{GyhwxDO;VlKaS z^a6BK`E{XJB+yfGI8G$^ZeQ1eUPs!za61u6MWTDIR1s25CPt5s5A?}{R-IcNK*q8ZU1pQ5PQ#ouy zm-XOH<+vBU0NoV+A@q85Q~0OQW&L?m`03-gE{AUS^JN3u>3HyC z51^ac={EG&6X<)7O+N+jlx1*Oi&u_jvSXbW{5-L~lnoweJXe zR|0(-dddp3|Gns0=%(^HguWQvR6eKB??4A}k2C2^boV9*e?0oD=%)5vi0)Zw)+6X+ z66o8|7bMX4qOVP$A3|?Rpr1m29^KTw($EZZ$p0`-PAtzqIV^T{}6imYIFIVLZ6Fn3O{`+#}9N<{~nM2Xac zev#y#cW?Rf)hF)&=RpbdJoKgndJ%dnx@jD&LqCdcI!-sCr`~SPUn_bLy;+g|RRhbv z1N~S6|J~^Fyfst&zI=`|S^4UOgn#G2@bl0w9GkEHCjA39z2)cjfAowibpMIg`7Y&K zC;oHd{9a${P3Zg4hj|JA(Wv-!`)oy@`#^%Y20iD~Uam&{i zWS*KJ{yg-j6NF!cejtHfhu(p1s=p@mqv#(qq^}h{X|wtFcOB?y=%(`NMjwHGi6MO7 zOzu0Pf7GDop_e3xzX-h&-88<|p>IaN-w=Kidd5Qu=0E6*(M`wS4)lA`P36~(-i*%e z!T$BH$1mS3<|pW;^2`xueMQl*!=18twVnkePOKb<{v%qnS8ZO^lwFt z|Jr{m`c8Dy_|k#?c!KQ&0+qxAz$5R@SlhNBs$aR zxZxL}ccEt*^g8skPny%;guaaQ^%(rOqL0S^R}Fdx`pf7Kihk}(edVwJ=huy1!X#vr zl<$}*J?4H!=3IW?@~M2q;UaE6gXqh)nSVzfLO+22zZ>eY0evg}P5q!5y%XJ3j&0~e z9?n-Ek4>NMC!Ode=+7H;&vhIJw#S)=Y5$q%2hh1}96$f)`|r$GC%rMco~MP-pSn9= z9Y{idFshuj-hf_zuhw_=*JW&MMpvK9S3}(Rq1a{J*fi_}>!eHD4`KIXKijnjQ`5wK z7xn=5GhDlN?cd|BrF``lN%yx&*Ywo1hmvNdW=v1@Pfs14pPG}OIysnH zvT^XHL5t zrkw2j)|cshI`36>3PsY{u{l)=+e{q7k^K1-6Sd>@8vI@;M?%09?e%{ zfgN8kH6ZDb^?dy;`D(p6JnB&DE~x8~yy7o?KJ&h>Gp`~rkN>CB)!a>kHV$5vdL-$g zq|M0>dKzix5^o;va)@`h8!r_9h1eHhZPc&Ja-(oOT}Buj`^_50m^eKrGL7c*b8|diDR$8F3+<}aUDZ(-yr*Y28Q2+*^fQe z{a)Be3XV~;A2xa$H+dZj$7bvz!v%O>_b-u2iALDw$f z74nwnBu3AtH_{el6MqrjyLCETe-cL{?|s+@OMSj#w@1%L@4N?-8k4V0<(|H5;%+bR zgWt+mhsE952X(u>Ikj4vtTbKit^@A=FYRuc*`0@QwtSoNlJF|T-A3;w&kd;yBxb^p zP2$Z$-|@6|w=KTA@wh9*-R|$?s|WDxX~mt>j%DDOnd+x4%P_*YuyN4b)OuYmQf`g- z3w#%UeD@s0-+X#)(ndQ8qPL(QM1M&1-wo8;(Mz7w`db6_F7%VGp8T_Z;Ykp{QGn~qxy#cQSo-Z?MvkwAIQq^TX}q093qrJuR++x3sV9{UG5E=u`JV>|hLzFH*V)j8##FQxC_ zn7oO!%O>IPm3001gNNTG{(hjtzc+sPl8$sT#4{dDcG@{donYz$=dejwvf1^IbF!pU!j*Law;asx zTi1kiJ}BwTmrxs%qr;W-r4vK-&-$k?6MGi+eQo*bmEQQAaUv&boRIhmaVO7LeOKIV zOWe-Hy{ro;&t-9 z?=$G?^HcqedYrNI&wwt^{luB$A4<4cV#lAUKNO(L^G#Et{7HDSF5vDMyM$MVeINGd z^IG>fA$k+~kpy}xx;&@Ul%5WW7d<*X67DJN3VSW^v{T;mQx~}7lj!NRn}g_8q8~w@ zothS%uJP!BL;bI(xw_=H5Pcv1hl+pRvPrlV*sJkZ%y&X7QIp8MYqpyx(Dhl z=sCa8ddka^?tcE;(YK)AAmRJa=gPQotvxlC@Vn4Yx_Z_?J%tIzg2VC4Q~YP4R~z(9 z^aAuP=s%VCD$N2S*Nf9IA9ZZK2D%=I`Y+L`0lw8cQYH4=4?uyv(YoxE>qWC5O)V%celoOC+Vud zUG;x6ACd5$m2~x`TiQ({x;#&^_c|Olu{Vo9>~aWj+mqN^#r>=Ked|SP_lK~T#Ibit zIM~mP3CBZ2mFI_2Ed9dwVc!zRJ|4R~ua?6}KlcULcgL}Zu*>s3W8K$bKZrdxJ=?IK z#2%a97VPr8-st`;<kJyO7hht;bV`@?_TWkJl@#!v}0co$Gxlz zD9EG>I*$8vBCL;N&%(YXPB=mAJL0%6!oEAkz4WUH_I=p1C?L;}L(|m~Iaic3 zPUhTl2*=HM$v^H+zQuiSahHWVj@xn0?-oR#--*9N;_okvgETnLN~6E(Sbr&JQGS2R zS6`u%dA|Do{ACee5P$n4hpY=&a&+MFyj#+N{UPL(qimU;l({amG&g> z9oBU96G+u@vs4<CTW`Mg`J0@&$#pF~v&F4!lFk<13)FNqPs;OEDNoj8ODae$;kYIJxt(`f^7OuS zg4h>(CvQLYE1{h(ZSRI9*cZpx(+PiHjC*PKS=bMHrmHlGpM8CPlkj?!#2>;vfAr|P zKSWVTcy-v1c&C4$^B4(lFaB}}?_vq|4a$LWF_Z7@*h{d_6Z_wsa<$8!p0d$HA+brk zr*OA>@O1S_I4~cybGZoVURSewzf+Dfp6n+4-und9s-#CYYlD5c$NHGQ(j#`Mvz39K z9vN@kP3)3}66|(|)q*=wkjTxrYmy*2CB&lyDc^@9E zew)N>`cFy2f0L{>Cwp1x{Xdeue81oGi=@{FsoxJ0H=76J<{9}Qgfl;%bm{(N_1omQ zyTh))yzr>?t0eW7gp7w_m&5!H>$xQL%V^X5&w2jgQQN(atB)-rhd)U2-aSY?pX~jg zWc7ECeE<3&NA}HWr5dokIE1SAJ~l{wZjgNc(-7^wFq?Z#9`EM{^W5VOxI(fiQTFUJ4aX6ql8Iw^(q6)t;LRr?_zbm_fA#C z5$O@_>Ab56;d<{Ama6c6R#HT}w$MrJ@Qdzcs=Mb5FEin1&p`N_d>{##*k(=-Ld=sd^3w_#fe+>d$id!(P!B8)m#7PPvj8xdCU8AyS2!Hz}sV~ zE-Tlrl-SySul=~K;p`dShrH@x>-)*aJnC6J*u^zwe^DCH0W0HSk9s^QQ&48PLjGWDTB|Klf=&O zj{QWE_a8}2S2=;hTW%itRWBx;|Hr|qBbgHD@+5B>!qYK0t~~F}{?%Z$XHcF!;D2wh zIy9IcE8{7x=$8z@Ene?8z3N9g8~-okzjChkH%au1$CA}<%lr9c^@io;65}IDTv1a; zlf?e#B(e7-c|Vh^?n##O&Yt86)@7q8i7DQ#mYV1Nie>GP^7@YDeZflpf#vZeZlf}TI#owh`(53pp=~?ykB<|^L6!jKQYLAa**1j4?<^Mgy~jqwTx?a zU7U3Ztnx^M>~&MitPh-?~{KxKRc=Oc7XxF*^z2lY4X=cRV zAC||Dn>f-iwLBo1BHP11K1Qi$EpL4iKRA%j?fNJ;EPb?68!hj>mU>LP9hQD6E!L7_ zuYKUbdpy&}_yy3XE$=4#2xvz#%pYVc5?XkSyveb*ND?g_Hw7e~r zdS06@KI8l^C8<&Q94()=ykAaI`z`O^E%mm@_a(_!l66idd)eMbOD*@VQuk=D@vR^A zc|T*R%(OM?X7A@MZXao@JZ691lT2YhmF#=MD|1}Te@Q-{&o6s0 zAM}X%D|-05`W7!&tSKfw-$;_rP07BWc^R;A+L0`V`#dD!70-pDd9m*Hii1Du00PIP z7(bhoahHcFc*fhw_{un)to|m6+v3eQKv-Te9~ta>e2BVdi0|$*)VGHC{ys$gdWi4g zGbEG40^ToJ>edWqM^2+k&bKDs?0x7=i+bOErut6O-z=`z{LbV3+fZwd*ZaK(== zO!u5QWcbXb-g}bN z*Q~pUk=-G~ydPCQ9LV=E-kHn=?Q!M9j}J@W!xH$g1U@W*4@=;~68NwLJ}iO%J4&EO zZ;{CXJHzt-T-oGz@X?#=F4`vF-Fa**pOSmCQTlIU_T?U}Y$*=Z=*t84H%@)*Eo10( zn}0doQzc&lNdZ2Ua%ZdlG-to}nt!shucJ}LI$#}*eJ?@$%e~p?&AwTIVaRLCY_of> zV2Ad|b#Qy*Cl~f6zj2Z6-irb@UHjw2*n)@{mYaZ2nTXRs3j$d<>=0wd|nu|5dG}mfw z(%i1OOYn~dFARtLvr8k6eeC#&m#Gh3zjvABN(oNN$<3M2zXWr~P8c_^1V42Be^{AJ%+1No zjjj1Ba|Y(}U)s~MYuB%ilrB@*wUHW!E8TD9m632wwaTuniiETCr_UK1DP5tmS5&Ua zURheZQe}tMSK`@Wq{dO!hHGlet1A2L6r-a2V2dyep z8YxxT;g!W@HKnV=#VbSjb@vE#`SRlMy5-^ONHJ-x2&?Snk*bFV<3 zxUM2#KCeb=ONbgAYPkrI~yFD(u^HG%)z`~{t@|&0FEp`mQ1X1Ru zu76)rfIWUIqYZw0ukXX1f4UZK>8iJxi@N>;NdYV}54T~j9W38mf9|~3QI);MgiN7b z|4Pr#m7Z|>&vIPKd|uM-`giBa+}E(3y8hkyzCX?J=g#k)y@AKD>kwpa?fQ4;)AhRG zGIW8t>37|^T!Md@tGoN|eEkuA;UU`&`_nlekuco!Yjf|jNnQW$`N8B19T)ETfg8W; z-_8GRI1|nF@1Aem%Uu!K-18H0Bjp_H|C87xi|+Z6dww2gm5wZGW-zZ~O# z_X@}V?iG&zic;-S!>vEp`t=z9J|62To9{)(|M3)ixA!A9{_mkk`gM2X-q13~?GeZS z=w6@Bm)Q9CV~+MeTKgZZ{m0fZ0<NE1q_0LZd`)#pq&qj@L zV!L1bx|9BY^z%J1E(y z(f}lj>!d&&JO4Y0YftXI{uJ#gSw`sOc;R@Jd%WuJevopHL;dZ8m3w^YZy%!E<3@k` z8NJt^`rC*0UPtS1KU2BmcYk||a>wQV_Op~b-uAbrDt8?1Zy%=I@v*->O}XPEVw+~nDc+uZ}E(=I4i#FNcllkYG+rOj5 zWI0N@{WeNS=AUYAe~dDdp7W!3?e9)MNKtwE_~$y1{>85tdfa`NGCi^4lmow!!9K7Y zCfoLb_%1w?J;@-WE?Ox~Y)b?XK{pafpOTkO| zq@Qrg$31=yK^OZwG36%zjTL)_cJG$w2-}{j{AcNO>VQVO_Ol)PcJ^hvLfiM9p#-p{WWel!yP-nIJdW1+I}RXzg_;bAn6xs_qv0FUBbcb)c z?UG*~+S?o29=Oo4zwMY6zif@$U*zB_<*=|lV7r{A+f{+KZ~3WXuh;GQbK0JE$gv;P z?qAdPBfoU)Um-r(a_}eNZ~Aq>-ru3!OL+16ul#3R+`IRmGHqY{^iJF5xuCMS<^K(B zm*;s#+rO>t@*K`+yIYU){LE(paV+i!C1*^d1sZU3{j@6+x#YP;LcWj$Wm zV%zy--EJ-Iej1Z)DSugiS2nktXJME01g>!6y+pgeL)+`MeT23@g*{&V9?;>t_Z2g> zd$(R>-8k9Yc-?xD_2Q!KZaK?3anW`+{jxq>wB0R#SywIE?$)oYrxtB@>sQuMi?+M% zO4d({w!8JUFA%@J_T|T~FTb|C_2sr_SsyJre7Bv*x@fYw?ZmBLS)6R=xJ1LtGc8Qd2e>@^0vtRN&A!S(ir>wj#*8{F5$@Y)MdLu+m~R!nDOMue5YSb*7g^*ds**Gwihf% zn9g+$NvEv)EZZB7SykC~y#w6wWTSSUQyj2GH($-zFXnjd&f7<8ug_zbbjowxWpmT> zMojp_w0qB4{mWsdPUmRs5{^9IUN*O^Zr67CAG2)oUuN0lKe>`GS>HxBcU)bFUCQTR zj#EBvKi!Jmu9xYK`w6x$)=Sp*`pJ&nZC5vvU~w3ah zJ@=e*&pnr)cPdWzP|;)cd>A zb*0DV;}?|9$SrBckJ^WSB>qkDwDOPj=RSu^eRiKG?=^Y51~|Q!&YROiXU^$)OmVu0 zke*)t7x{q^P(tPDo@aVqs`zz^SG3^#`k!|>D~Z(Ob*7Furh84d@ak__)9_zQGkR*revyf)ote`%GJ@8?fJA2`pW6Xm^F zR`}TjoZh=r*YRg4ew*TtsyxB4^7F9Lf9lpW|GkC(O(YIS1F1fgSDl_GI^=_X;6y)h zkl-&7IB}8UbpJ9v#{VBseA8KiqZ|1-00M;Q+7?gtIxri6b9;NF zy~aPg72kcD;I>{or1bCZ6*@NWj({VE=)3;0=K`nt(EYdcSbY{0r@RF8P;LTx4tT!M z`TpC|{P%bHU!198T>rq2oc@{uPV^~15Iq+wezoG1cZi;>;`b>|_vO-KeE3}KGjTtx zm--k#q=6It^OsBcQ|>y_&IhJwd?4_y{eC4n(%W0aH3E7 z|L9q+@7<|5-ETtA0RM}_>$FjpepVRV`FOQyswfrMme#$9-2?QzClk$7fWA*Ad+140Ps-aykICB+;6(r9Dz{JJPmx;$_$vL~|Dzg%zX3Rn z%T68N^YlyK2kx)ueu_Wl;KwL_02TsE9l)udcWV8uA3hJ9-n)C9@PpBL zKAARP+(ZnMf0>!0I*(|hSY8+vY*;)x01%x}Fy-^$+z+~2N8wEX|k z^68|MKSS|{72l(D#uQ)kSJJMLY?_h0;uFBBKF`s90Q>RtHO24JbrZ`FKN$=hm8W~Q z=^5dFaVA)Cx-X9&OlN+61)SQor%&oxQ+yl?guh+(`#j^2w`xBw*YbBL{_$6&89811 z`CE!lEeQVaTK>1dsh+j7r9L+A&PKeL`E`n)=HSO@{VxJe^`!fO=&^dfOYzOBFCC(EeyjNHjy``vO2(J+A<|>> zZVPZ~*RFG=o|yjpyc;;ZH=*NrpyKx^zHFt?DJcF+#p#|LdW=ubgCHe3<--L3YKMH` z6^gG?xrb$!pKk%D`L#>yY2$lHw~Wi@oN+k{IMJtjaOtu4z6vpO6kd(OJK6$3~0{P~$ueyx`O zmE!vi3T|>{eXsW0ZGzv^Az%2R;%^)h+}e9#pR{+U>f1J6mjkEvQhsTAmI;}}wT$Z@ z_;J4e`XS&{Pr4V5o?{h%QNQ4HAE6(gR{Z0t2SS|kb3gFI^mqC}elB|csO2d?A3gi< zzllTz3KG5dGul7TR{W>HSw5@{^5=@vq&(d#LJ!mxe&!T^f!h0c9Y24k_#MlnJj^$K z?gUQbwOiM_Rf?Z}XHUp^=UC;9NG%I%dMg1H|Aii_ z_^*2eKSJ>j0;h5BboA##&XV`;)b(gc%U=$h=+iw!^jLd8pyhYJSn6r~c88WvJMwM6 zw9rqhpUujz0Z#NOuP8nJ9sDElhP2>6uLy4Aa*yJacat8Q*GJ$_|Gc}9KZXAfIMJUx zTFQ?oPRlXz!@4Wej8LvbdTs_ze7;NNt7@Tz=^j_a6{E%bz0cisE#y9X+Bjt~)N%@ zwbs+t>#lR8-_Ce%noHiNABzT<(E=_($TOwLINtOV3FHC%OiO4&ARrkI{J(a2pH4FQ9KX>A>hRS-F<1st)Cy)@^rr$ zJ@($?Ay|mcu&(=9=J zJt==TJ*J1ebbY;UjO)0}0;hUjevXtk`TQH;B%fER9kG(B0ox$uSDYv1Pg49tiqkz1 z^ej{SZs1g(o&O;CQHnnSoapaXIcfA?a)HpNdz0yTg_eJd;?t@>SU>;0;&cx)J=UM+ zV!~3p=-y0vtl!?O_(v}n-0J_J;&i_OJ@4UvA%`Gfsh*qFpJVl}0Vn!*s6J`y&U+Mp z#M!6o7?J)j|5chP@2~XFQhcZ4$0~j`a9Y21IClD@!0Ekop9?(;9rA@MMx~!AuRA^8 z6F6}@a4O&VsNl;LKW0pDx)+fi)5p#NPUA)Q#nN*E|BFO=TE6^z!EaUmxr)ncA^f;X ze|@i(|J>119@XaOZpE)re}2E>`&=aTc|`ryHeO}LDQ`GE-`4VX0;m2NcKYYSjndCr z%-bKV0H=Oqfy%zOB4e`uYBsrMdiy4*roi4LI|gqZhr2%S##h_Zsd0Zz-L1tJ4JYT?h2@ zKY&wv)5@PF2aeq&_?5cuSU*=4@6Jj+t$+RzIPt@0vS}jAIq~V|Z-Mjt?OIKLdix7& zUM}?MzG8Y%jGrqN-$&Qk6^egOak@u?o}(3iQgON$ke(wHKOX{t`$z3rn=fVH)ZWc1 zm#kgC)$%*nOFcW4PU=t|_e+vI7m)Ae=<5vCkbHJ%SuTVSP=F5{xf74siT$0jT z((}Bm&`+y=dz8S5ZNQ1n_tkH3hT^XU?r)dz$&Ff`?scXospWSoex4(T6Px9|tJEK2 z@4W)JpZ*_}&g+0veSYQWWBcW#-{?LmdXD6Ov5x_q%J0&Bv=bHo1aRgD-G8zE{DGFI ze8=>x?2s=M#)ZyXE;yTkmkONttm2!TcI}gw@=xh{VSF_ToW_^#+oI>Ml+GPmp6-XB zr=Zh`PzMvpP z%ipLt-3vy~H}>HliC+V!e%PV<&mjUQ)@>1dTKoTnir=a@-S0xr7ZpE$Dp=1)72nJ_ z+N=Bk^@g7tobta^{DZ)WuO8QaI6(0`fKxpmBZCW%@xwEVQod8m8y`L!IF+Ar+EoHh z`rGY}{WY)Ucd8z>zrOe5z!BvfiWmAKaR0cd7)bmAIMsjG8sWFiO6TycQlDGPQvU(P z-=#R^@26*(;y+ZJ?gyvG`hWE{p+oo1(qr;rLGkfX!SCcx6NwK1r~2&am-;|W<>wE; z{q?^=@q?y?KHXPE&vlBQsrYfq4<{;qEpX!JwDz0T|8C&?UX}l6Y54Of_rB3%@BOCI*{thhr_woQR_L$N_5Do6^T3Hu zj+hZT##jGj<%gu-jIT(rQ2Cpur2O$p=VIWb7wyu08Iv<#)bckzQ_82b{5KUp>e+(- zSn(e*ofU~;oRHgG>#dqsC z9?&5l9DIe)@6~ztMlC<7_z~(SU!nNzz-e5@d((`3Sn>O{{KwT!f4<`DD?o1~uB&wo{we%|TmpPvU#@1;Ec^c<}853UJL_d3u+cRSFtQSo$Nn*X-)lfY?w z>E3aAtlwUz_{kRw{$l<#k@%tFw`jW#QG9Gp=$xW@pv|=@#pxbCdQ9)SPVuYqg7+w$ zW%EMkrU}8V9~Knf?fOF$e_lq)o7^~NyU;mb<)QWemB6WP!>6SAjfd)c?`9lwTkE-8 z@e_9FJUU1Exl8fOfK&h9+Mi~``mG3@`jhTCr{@IzH<9?P;;+zpnm)g3LCSAbJ>U9y zUU9nTkDlcnLg<6QY2GCs8fV}VffGN_@^sH2J@;$*gRhkO?{VhWQNXGGbYBfUCQrtI zQ~l{4ZF*kD{~~L);x{|;`98(z-g$bgANGBv^s|25Tfbfeoai5?ehKS`_bX2KG12qf z4*BM96u)bu;5NQ%u99{oR6kiS#S`xUPV3zz+CSE=4+5w6eof`lYqb1bia+Jp@B6<> z%KuE|w(;Rnz^UKpeqwsoD4nyk{7$tm%r1KXILZ04#`7Gd<%eG_`1LCP4ZjmO(Lds% zG?yIG^8d!=;fGOqYwbE04WaUMUkN?7j!y%p_Fn76EB>qEw+{vT^Q@gx{xnB_c#q

=hD^B;S(=)>VCK8vuPUzqMh~WDw{!zt$uJh%&ivLpaJ&rwi=3fh)RjRjJ|9=EH z)pO?!X{G=*jGxbI`5SfIk5v3WffFBYcJ}=TUoZ6E=#2aO6%T6V)NoBz*#OiddRt0pjnS{_Dwbd z=Xo(B^?9C7j8`*WfA2tt{Qd<8e})!$95}tVGcE1yQGD=C+7G!P{xQWBi6IYlRNo-$~CM{BI)hVc;YO(vH4# z#C1}B%Ax;C;LM*Ir)~W9Z7u((%1P_D{_Ck-_2=?^{&({o*ie4!sWz4smJ&$(UT z#I)jPIQr736sLQ{>G@ABf6Uv3&hD9D{oe|l*4fRv&aTw=-Ugid;dZrytUrGN{4k|S zKX&WyFSwq7M!x^2c_Tm zc^h!5&vVr7J6+3vQ0dTp_Vm23Lq7N(h{{cAhVfmNijF{Xw;k`m< z*T;nZiv8pZw*V)8OP`u%;81}RzXVS6G2!U>XWc60wOC?<{xas^rblf9PVN1^%DpdY z`A-0+`tMSEWLEJPy-)Cj%57^`7Px<2q_q5%Tpse@ktZFWRy+`IQ83R^()$YzpUlgT`uK~{_!8A_hMhh@h4oS_*?qYOxfN$ z3!M1pA>~`+pPPYG|CDvUAENd7v*P<)Ebp~-ZR3Ze{07x0U!>(X#^5Fn2|23ua4b}gRPdYy; z^gnul(0`VePb)sG>xK2hFmQVBE$5}V03!Ak3nFXO^^zYX4%N7J5SNeN^Q#~Jb z`t5li3y%9a9rA@!fz!C(qkL%nbA#faQv1=y_bG?YLHgeQkJEdPPONhH{IkG$zC0lH zv~gVdcY=R3on{JWDxDL6Q+-Yvl=8|J%6VrTFJo3w@*W>`zHOcYG|(Z=BVE?@@egK=3EDKI;|#LcicptN5t_r~XOn zJhE|lJ#cF8_!aWrVJ-iHPYeE_;%6!T62-6FD&^NI{!ZY;Z!h>rnvqTW$_HQ5^2e8qV|?`or8E3) zp`+cFsC-`D`>V_3y&0u{18}0VTh|ejGxq?e_iom6xF>OKkrPzQr#~R{?@>B$`a*Dg z->Kzq15WgRt$N5Iiql3g;rBiwbe^U7HNZ*ET(5HG62-r)M3o1F4V6-+yBQDCMu~kT2W}oa*@vr=A~B`jd`7?Z`W$+q;EvjPF;3 z{`a*$f9sULRNMOt2Y-d)PXMR!>Q}wa`0Z6+7X0nXKh~~qD_(Qt;kmnIeD|o{dz9Aa zo4{F~bV@xxr1&F>fAsBXMv996nQ{FCKUV8JI`J}+?A@$Uks{@DfqPlC;mMd;K0 z;q;h(SOiXV);a6cj}^adQs|$kbWZ*!>F3?b=UWxO3AphFLHj8FDd0r^9<@hI4*a9y zdP{Hl4ujsGwFrj~!U;6K(1WP#K8K7LV}kt;gn zgR8aty?-y|uha6M0Z!w!OZSQT6<_f!!S7W)!N&b^;LJa-N^?n*x7&eJKhLW@W%c}- z;=8rI14{prZ%g@SIrH@Eitl=>)YJIt8TV>E2ZMZ=0Z#9IO!Z#tw>^r#%fZk1j+8I! zI&SlNr{W)R^#6ZR{LybpeU8-r9KTQK+&d(=wf7^6FP|0scx~^|-_`dzev&!GYcs*} z4=Fx86~ueLCv>h+J7`$xe?svi)(6Y4_!lYvGnGH5YWYpTY20^ikp8rJ^l9KUzIUCG z=8{Kr$QORfxPBQwo}s_~PU-JZJILn30rwMq=ta)DSprVub*Jj*Jxb?Cil3tVV{+rn zf0g>|x?9@ydo5p5{MTot8QHD)UjrxlyPSUhn&Lm(D0FPR_W8b)pI85Y$&H%ge^Nd0 z`AYwrz^#o0^(+1`Tw_t)n~`oSj|U!FMc^fcG-*;>ypJLM1432?vC|AX?a$-PZKlKwwY=~%yQ1y22Z zyW{VA8*pmZC940Uh5Wov@r25gm5TpT@jd4YANDDJ90VHC|GCONo7b;Y{Kt-d{seI1 zxATedO2sfm8Y04-h)9>=69Y ze-rvgoho$pSNuxgRQ_u!e~b@5t@u&bN%@!Qn-2V$lpniTaFY+4fKz|ouKw7gwERc3 z{OjH<<;#kHN6RO4e`=lL$Nam{e^A$b8<*{hzsp&_?gGy9RP82{OOI&z>;FaGd!f>w zd{D}-(s8%)?_eDJR_X^^rR6*RL+W$#`9kMf#m5zY^#2NO=PUmV+&|yfX!*l_E_9yM zeNyYUJaDeR?oV02y#YA!|JGe;rf{Fqd6&}Jt@88aedL4TUkLqcic%k&kGmCrh4#O- z_Xmo9e>hk^{ZO#}r4FHg9dN4W$`e;JVD-GkDR2G!BgWzHJx1tT`G*znRJpWF+x4Pf z2H$&vzBdb;-n(1%icT&6Uf{&Hld6x|xIE?1d6kxb&aZ^d_2&ia|8n5e&l~#ET++sF zhH?Eeex&r*8-UY$AJg^G`uPuv|J>n|(TAn{Z90!$qI5p0_(R*Je~cdv`?ZvR)ZyD} z6kqmEDSxrj`Gw+p&Jg?*#b5LrX>VHPs`c9z#&Ld1_4ZX-{$0SST^pVGb?76(ak*a0 z9}k?yWwXZn8T~7P6P?Z1N_|#n`MZIWJiN!T7rw3KZ*ugj^M6a_k4mgk|C`aj6gbfz zar*z0T7Ew*zn{MMOIrTkA4`4SrubhJU-?_XjSr81RO(sQdKx|eoZh=!?dTDu^HIe= zqwBJ*zo-7Elt0$7``!Ya`0ZIYq?tld>AXkF|61)|qw}ANKcM#Y@mhZL{|f#4o%eo5 z@r}!*T`$-2-&1^8<;HTw&-tCuS*HGEFoDbssBNWKdE?4_4&gUpZdM@=Ywaa89AUsK6tg_ zx9fi55nBF!#<5?Xl=3zoU+{-ueNNT#X8@;mJ*fUS>;GF6zwKF4&zhG1q~fb}+@G)b z!T%+6j(wMu|B&KSir;*Y;MONs0k_|&=uRzvla{|-<5FxKf1>y;&c6J`kIQ@ad_?FE zbO@mb6hBAj>CsC6_$Q=4SKXRs1ZodIN#N8En{|D$@x2W=>2;4g`$tb|`Lyzz&7*Bk z3jgd>y}DoNe;hc?i{*W3Myy@C6<@Wl$n7pI{}|)?2Y%$WUCaI`^?X$Qx<_k~jlhZi zUGGjaaO9Z!hy8ch{-cE-f#)13CaZUx( zb}hfFL)ry1pP%RaS?JuQ_Q-(Z^NL^X+T)5}f3MW%J}rOwQ_|jD|0FoNi=XQl*FW&% zi4OVw1Hfr~f1H={#^=ZWMRDcNll80J!2RtqIe!jtS{Kr)kDaIG=af$RZ9;!s@!g6a zqrff|Klphte)?8%ImNvz6_k|xysQi{-ShVr~0tT zpVxKBd(){jzws6w$M-Xid7=EdQS0-JeWX6ak4Ss1&Pl~To)Nr9%fDUm^PP44A>j61 zDtf(^|Ff1~cYx5@toW*Z<-M<8FSzl~n-%}UX2ES9J)!u{KEbWMSM4YL^Z1K}KcA`e z-wd4Q(M?lnM&`92KFqil!jBvD*DooZgp+S!kJ8zEQJPEMsO6v1^1D>eH2HAgGo)Sj zep2dre}{bGWs0A6gWxABof>d|zm*ifP0M#Wa&nL2vnz$pDy9FJLkHF4XE_Wg<{#B3 z?Y(CJr~Y|tmC&*JuLDl}dGAqzuhsfYX!-kIDfn9zf2)>1aYAsLkNaSOqxbI8_}F1B zzY#dmzeDY^FDZTvaH`KL#}Du;Eq~{QLf`ms&9Y#>ouhPe4*nL!tH9~KA6+AKu2uYd zim!F}>VgBM{yTM_-TG}iaH4a*>VdYt+y~r0jt40H{SOM_ukDZzUI?7%?4x?D$$_i5 zJkDjjTk2_Y;L}?EIT|lff;XYys}C&oi|AYqfl*>XUz`_&+OttI|JI z@y_K!ztho6tBN0SwA6D%%fA^ojr(SmS7#{xbuE9r>I1gktvFcdKU5StHs7yMe9tpv zUf-krcHjyrzxH4$Z~XRL;Pl={mETO?OKSN?v|XkzZC3n;gTeZLTJhOo!C$ELf59R0 z-jk++?_E&*t^))&dGb!+RG*z{FQ2Y-z6YH6e8sJ4Mr@28RQ&GO2%SfDz)oH%?|pE6 zus$DCe6!kFcPafB92y+=*DHQ1aN@Te>x7Q+$s2)FJ$I{~bC#C>x|Tm_M9RNW@#7BD zcB#BIxzP!n=wG>9%Kwd)Ki|r$zwSK6ZvsyJuysMok1PHu;G~D|aO|3Ul>R-AK6A?9 z^4?!h3mvm_-wB-PAEkQQ!Ak#DEx+p#DZj7czg7H=*9rby#ZNv$=&Zaj&B(X(3rWRK zRC)MeEx(@e@O@;Xz+Tp>z9gDgQCW&j)TiOwgl> zzXCXoV4?usbm~GqYgt$!u85 zuQ_Mr?Dd(f{Y9^_-|K|<;$0?$%9e{0lf`M=7JN#+Tux-qU3bCiv)5&_gV}|J>B8)m zM0Qguxv-GkQmAFimBM_nG*_j@)(Z0pz|w5_rB=v}&rK?dKgzgR7@rjK^zTH0Kba}i za`fkTu3Dg<`KfL6V;1)a(_cg&i&|_-_TtZ4Wg)xaqILM0o2?e9CY?a1OSuUuH(99o zDpCjX+p@J%nP1`+%FA2ux*VYf-|`t^ew*i7(XZH zFzhqAT7HVqX{vB{GRw6o=DAccH(k6kSHpG6+1%^|T91pF=kok_XOWsRTI1?4=DOHAtz+^l)h1u#{g*#vSB)@Im zzQFC0whVJa>+Px)hWoRF7i7;FT$iEZ{h&|7Jd0bMwS&1Qa(TM7nQDjMri;~DqB=h# z+_EW|td^$d3mCcTe13Qcf6mWOtqo^#QLHDiMpY#>RtDMX`p z0>Yy>og64*+JK$1rD~zV6Rl7g+%VdiO?J_R8X|EjDskeMW?eboGbmRWo0hO^fXu1V0f@w!4`N(4vEm?_zei6E$Fz&gch zp*9E!>h+6oRR46LTCGjxW=C^_qrKToCX-B&3@y&0F0=Up&Aymdr;^NzvycMD(6xnf zA(E5Ztwe8ecD}T&kQo{6%8m?;4$ypZr=<0O!~4krs{eFxypqH63sGIgT$N_@UAR71 zs}y&v?esSbjG)ty*Slozdhusy+Dc&ymXOLqPkFAg1zbMFGq)cT z7eii{$WkAm`>-gW&ZD)ia%uYnEtoOm*8_!#^e>ybk=>U;9eLiPIhEo>VGu8cvT#rK<7usvc3v9U+bmSv05E4S~PxH6Lw*NG?JU$Qt)`FD%3~D zIf;?Os1K_%s5NX*m~0tbO709MeNu7d)XVZq!T6Z~DtPDbn86Mi2 zfqVgW+_zBC89Kanj$Mb4Hd@ZIn*HtDU*2GCEYW=VmYD3GFE zK?|fp{n?Rm=$Zu#VNg~iyLG_;UlV&~MpN0*+CX-2qA*)4))ofwcLoh2Ss=ed7y!!j zXV*hlgQ}Yu9<3!Y6@@+vbuK|K_C$E+D0o!FEv7|S1}C7W7iLRtS0;ODouEleKdFAh zLj&~d43>^*?n_j*u!EF1@OE%$ym{sD29Gw4OA=MdkDxW&M^*eiAEGc?>zyvqy48~% z#L%pbDl!jN6w%|SrlXbYtU|j7dth0o2~PTe&B_?b z6qrch14!^-Eg;dEVFr8?4s1AsB@|qsB0t#$XJ2K@Sk>Ne40ju|;}uIn^P^@ZguvkW*pIT*onnV_uq1Y7HMLhJpaSA|t7 z#kw@?-fW545>^dQEuW;dms#E0STDnq$CdzEmM3zR31@}u&L*I_&DJK}*=5WXWF@Oo z+ucd?hgc&hU_2qmdhKK`4;8iHKu=dOSgtOTk>!5OC-JQdo9U>7TS<%$$yXiK-743o zI?T-DSVe+ymS@7`X?mCH~AVAB_CRc2$6HDQ^M$*e1;@PB7!-PTUb z!_I7~D}sG#HBjA4tR1&^lZ$57!J(ooZ^V_}lH|0hMP3MxRxBT+I;E?<-mSpdP^N`` z9N+1JGh%Q8nlm~C{}C0EM4|O1szYU&t*9TCzW2b+UF6EuPsN9Gvt`wP-QW)Fw&x zxO$|?m6#aK3jm7#xmoWe@rD5NO3 zaR53X-UruRaPe^FO=~K1n2Q5yK@XW+q@j=aO(f{kW6A6oR4`Jjr>i5QrIE0_tPiDA zv*Z9TS@{x-IP%(M$&hTM*M}=9l^PxjYW60MO{BJFy!6adbyxrocE=AM6Q^*=`($quRTq)YfYt8t!{)56D==fio@t2D3s88#F0lmH(IPzGb4_s zA6nTQ3&>-L(T!`e7m`E^y5{g_@J+)*x%x0!bK0G8iO2I$|Df7^tK=nJe$%yUA>}qiKmMgINsG2?gwMg{#F%| z-0UEFh}{jWL?ru&Vc6|mS`fyGVj|->UAV_adxr{@S+-hYv}apwVbHh^15;$NuJn;P zRHzmGs))xut*ZllvxV)`#n}RrNik=NomF8UcW%50`+32?cv4qdqf*JWWM9sJ06XW- z$??XE)XDtd-Nh<)G`2%rj>Ed0$i(Zv$whF1Eeo>Fq&llJ*rgKROr?O$f&yGrgK&X1 zu>6x*V+O}j1i=fjtJ9%}Cp1}p)B|Dl8x?8pKdet5Mv zc-&#X)E(7PGc(yEf_N4J(H2!0%G7*yLb_V0^$LGSr$P|dLM3I889x4oc zAV9DS2UjyZpn=Uf<0fZfguPwS&erZ~VR{l90+8q8m&S{dti0)XW#@C#a|P^e)pdKH zb~jAhbKcfnCnAr|lRvAB3? z>D~3}wCIN;ZVQ@54SK?6sQa1*4t;TSoV(H9;#5$_zL~QuWYN1@KY{6H?=rz+47L>O zLEuGB&)IvT7K5(oQfb>PmL(%z?%@3k#EMT23Qm~H1aLA_d1b7pBzk9Kr9Nz8A448yf zD}}kUCfRe>4LPUKyIjPen&35WeyHm@W~Z(#Y!Qa#YoO4Y z9b&sr?qqGvU}uHVnG3BO9q7*phq-I{vz-v*?FsF`CIkBy=s(0KO!QBbw$IWwEk=X1 z_OZdRMpGXE>xtG4TAuJU(uraVLf=>Kq$`kC! zxf$&6HC}2X2jqr^L9>%?@ zeb{B$O8u;p+K_0N!n~L6ZA$jBY$(Dui(4-o38o{`Q`-j5HTH>UZx0>73syu2VVl=v zeto(`lWe3>bV4lBG-UVww9mcoi!Y_PsPpHuBOF3esH~xIv;wh}r-)gHwaiuFIWJ53 z&}g*>L4Amj3UwRSQnx3g*-2v~l1Yg$$dX(OitV6}jk}m9aKzr08ds`$#=KAiP8#?L zI@JZ~8UEH&QP$apWb%Ryne3W%XOE7ySPM_ShFVEeM;vkolyK~>4GnM5&?p41$B6h z&D)spHpYwIM+y60`vM`5(HeKOtAX}eXT%{M>7}s=)M&MG4HAblBCT`cr1{S5Y^po! z_M~-b-MMX&1s11ose^IfnvbtFgGhHUHBQlWowK<#gdK#D?1eqF4qVvCt+-UuE=tBl z%avBfiMw&8Sgn?^9~&375l(Kb%wC>NBdx7Q?wjcGeUc;NvS*G7B{9;q1?Y7$$A zWY{M!nld|+DuvoqrL;Z9jTH0%c&=k>r4z1zJxjL@;cY~YKB4ed@0b8=6kqs>Gm!Sq zmUPHq%t6qlWE|0&Oab5ey-Ja>p8PhR{%B3HROM58-GexALAI%`(i+q4dFHGdkxE2Z z-E5+yMaF0MO%$tT1giwr(iY`_RWCHN>yzIdbi@Jo=%fz?;~Kdz3-X-tPv9``v=row zt*Y#{!U7x)*s}7(0f&sssY$Qr9Z?ixIGeXsBDhugRkdO-<+mGz*3hGq;xP5`;w&92 z!C}E*1VuA{_sE2tWPmiw;|xcb7uV$SQw39I%<-1&Ls(3;Fs7%X&O!XVxZ!Ls)4sr` z7OG*Ye1^^G=TvfT)-&V0xbSLbIMzWFmShggX*FWGZ87!*^P|~1DIETVty7%chQne0 zX=H-W_?kQO)-&#KH)kw&{R_pS1iYWIP6B&z z>){>Dzc?DY1;>H&J9Z?y5Q~*%*5MA~b_UMVL~)&GKKbIxf~#o!avWZ}e0vMB=wqQL zo(P@TXgMO78yT!n8`f?&orR2=&27*yW{fs$BiK4>E2(#`?Au5RtXqhCs1#@yg-$?4 zEN8CFg>i@t(7}lbC?mt@-(fj?C-H<^Dkbbzvp=6=Rf3B~aTtm`HWleVEOrYEr8(Xk zjc%C=g~s9O19YM*OUFBHV>HVDPjfqLFQqzRFO3vnP!%S;;7kNtPfm`6_Ckn)!v)@i z@eXd8Z(|8`jDF}C9PrbEmSHP{>mRr3IQ4Gbrwn=KJM?Jnjc|U7;N##Zx0l+EFc`HX zmlk3WtbVgFlT1W3vMn!dSVm#d674}kd;!a+df0^HwUE=DOV1JYb&1ZO59<2j^uBRM z%Q}PO{*F3LO51G7Y@%~L8GGSnCu|}*;mEA3VreQy zc#7H(-64}sW7LZYj@r)WIFSnPu5iv2@n>_^kcNs&y-(%+P3`9Fo?7vyrz~wxG&{>=g>W_IZV(mQo|%nw4#<=_nnPMU~@B3afnE z+DFJAL7KH+8Nt~V?4}{DNIUjbc>QUw*&$90PYS6eI~Vp=sY`ZF6jTwUgVo*H8I2=C zOl8D&2YJ<6ovpNc3a;ZFe>;#nyM1QZXI$9OHC-yUlWOP&616eCeY&BI#?$CyNhZnj zZb#zD&={aCO3uW9h9r@Bi3-qO6?X;|s2_lj81MWvO#uI@?Z}GypG|{Q!`fA3G=L3F z8=V~D-0;#I<5$sn=i8vJH%P)uev8|P6F5E=ybHsjwN2Rql|xqaOjR4LO5HbgEy^>D9Mr|%)S)+))2&1=wJoHI2o1!Ms79UEa$w%GSAV6&{dmjwDkdSd#6REBl6&iwWc*1Avx$f`0faq1_Rwy zo});)0Do9LmhfnRqXEL1iU=F>Z0bp@@hC+uUe#)2Qt@%)fWEZ>3t?=Kda?_CR~*;p zWwSOFv4_&=+XMKr#D>6k3Qx#To^&18VN#DMb*8U&d=s%4@% zL{&0{Z4^y6g)Be9mil#L%BNAGGCLD{t`XW1FRUG`9a+E6{495$A4Br4!ti|$kroY9p>Z;pT)<3(4?P5}wyrraK048OOdFOd%Q zt%I>ha2-p$0ykfHd5IQpQe)M@){a;=hA3JZckX$)DM4AJnGfcZjyfVoo2{rdv?tf1_$7B<4BqymIK$_U9WUj51G>a@m2vC3GS*Zimw2y zEysf%QKd{jX@*`(JFjca2uP;%)Nq!v6;fZIv-WoIX|-)b-xVXW&MV%eb;iHNeL}PV z`KGJ22^@2rs}}fFd2j>9xVgDEHylf612bCc*V`p!K$a9-){)-Ub|7 z_&c13&^Ne}e5^aWZoD&-3A)B@9IZ)_2XMvLxKsylafGkOadIc-kZ`nSlFkdBuyv`2 zgXQYszyV*qwV?hnul}+DBgZyasj`g)S6I0F;@T67$n_v{LNlLHo;up=0w{fQ2N!&Cx=CX#>+sEbf-hiAiJ(wXqv;kJsp{!kq!E>je&C%bq018 zOsxIe3Rz02JQSrG@EEZD4No|&VoS=p=fO<6J1sNu(_qgaI@&Hm zy;;0*YwI@Nb#o$dE;y4-ZWs=iD&z7sXyy(O}CbB0PvpV)2NMYBVOU zZz&+n0cXgrFUXEl)8>)G_MDu3ayqxAsyS6edoO$<}T9atuOIC_e7*1cbIlj205P(PxjU2x@(pXApN%;ACHcH z8(m9*4dh3IUfe)WbH*{|EDt5bs@5tINw>yEB|%$V9yt{ECJTzHy<>yM-&j4Dj#Yf; z?-my5yg0SNAs;f8lD+Vq=cc#k7OIGx$G*=zO&8ANSA@FM=T@P$ydVv&n096(V(prQ zuW=TcHd;*K8IA^H0}|ns(FLE z)4ew6VZG2Km__S2-C+ILM5S>}Z+6(kb*<5CoX6BBPmIy66>TZlQ97p2s}rNjMR;}m zH;?!#=X6+Wsh#P(jBU>Awt`(F;?4|f^ipW)8MqPn#x^?Qj6~{nj@=-;Z|X>}maYj82BAn`t&N;U>qeI@uV3^)shAOnNEO4BL8^IMgsT4EB z4cs&cXcUiCGScf)=YK~SY7!DXBGc%urY>x5%+nPQ7HvuDE{6$32N6VTYKu3T2ZuBP zBil`mj&0ny&iD6Xu|dpUz*=grd0n)*7( z86RS@CORvmE0|jjgotJu?WuOu`|xCUY!L|$Su7icJyMRaY!o_0<{yrK`QoN1T4gv7 zAxNGy*SvE&(>fzwZ|2yHaQH-|8vz_0r#>_~=Yp@{4qP%CCHkDU?e=!#stZ@_soyAY zJEzT)MaBw-If0d`sCnD^@i0iyV8Q~vq9||`pXpZ(Y%MczHg15KPv=OnyFH)88Cp3- z$N@$i;|`NQD(`3uuYit%%_I`rV}q`j#a#-*7Pw!bwy7Dvu^get4|vy<@ZL7GG5-d) z)jwVZ4V{R?TGQJ8we+nogKGsB>gB328Cu5wJ0`zp=P^m?yQOMsyB_6YU-SAC1%Ro-F0eY3q)gwK)d=XS&rTt-RZLAYM0ol zynT@DoUY7yo@&gn-l+oaSg%o$y3X#_Xen)RX8}(3oISGUyupo`>_*5|TnO!7w4AX> z#vZf5C0Fg-AlKkrjg5C3Tk2tf^fYTnAvIe2)a@=WH%9YQSD|eiUe?7&Ga0#CVfjV| z=E`()6kPB)Y(gIQ+8mC)gPq)g-V1#oW+jN+Ppuz>iLv{d3)?nkGdm@H`xf;L3uiE5 zBdjB~**Qf`DEi+z)FG@4D>0*BJU-A!)+=04QPMPM8b>a3?Iq?Wt-@y=sSyxe%eGG_ z1dmfI&o$Y~MMn4(x^RxJz#Sw@lew{tL8ZM1Q_z+`6>q%!;AJ#fqPs2ZmJMF|VtLEm z1n+HJ6Pe^A|K!@sA^cL7il|&jCKwwpgkk%@I#M{zVGCTeMVh~-*UGkClY2}eG-H-l z^(**P1F|F9u&3HezcW$bMJRSxV=ug%4aU0F4)!vPXm-Zn6p?OLT1chhUZqV@f6gF; znJkb@HnW~fFARJ(KDZrLN8oJecFI?{op(_Xm`x!LFzHEa92>M~4Vok@ z7{^_c-czKSwkvw_H0AkZ`#BCsA@LaizN7|Y8|#;5Qk&|3;g%*?Rk(u^se<{48$4r~ zks<^+x4mXzcE!o6+;|ibNzHqvZU+Sd5{k2yr3cfZl{7uhI&Q4hR7-6p3XFq{V4I#h z+F|jI5pjy`z%mpmZd!9~*PV1xk|yZqb~>lc*$}vkIeIA$?>d1?YT0olNu)G%jT5L4 z-$avj_J`o)3ZG~R>9s9IOjE+4N^#2+PKQSG7b?|-ixQoCjial%NG}yDKV7!rVn@qp z_m5NoPMd)baqpUwSIWJT6otJ-z!5IWwT%;~_#}(N?d^CH!V)`HnQRcrH{jd0bK26{ zvK^CVhT-4k01C2cRqxdtr5r{SdK?`RmrTkWxh)Z_@W__qtsco;$7NdB}3Y2Ip6&J=@3o20mF3A#GmN~f7erL)9>(><408N zzTXe;j372R%eXo?D`~O!=>BUWy2o*mnxg*aDtlBz| z4HZqY>)h8XTZxlV5)6@&5_B>;!(emxX}ntmiwyiyxc}HU?-w0-(^jlaH{FLZ(O}9f zQrvjy-!N6o5!cXqkU3}*b!p5(vFv$Mi0)g=&dnBflwrRVa8rD6gDt#!k?e={TBzAJ z0cTNy(OoHQ#}#C*zzi()(d?6qI&!yn7a%uw+rWifms8G^HjqBx4Uyf7zBuU_~w?bRMvcdHhhia zn=MYSeV*fsIGi)1OLo#2{tk~{;LU8)<2G9$e#a_0k6UABYm*@f5Mx|KIJo_%G&q66 zOqpmSJKgLY?p>v;MPn!K(yLj4*oy|L52sVYI+4};YqOMO*%hNfAs(5~27do`-Fq7l z4~PrQaPZvA3FvvhgCfU&V^3%++c|g3(vfcZS(Cjmv=g0OJ9fbc4oj}3TMlDpbvqU^ z=4-2IA9=$DbBEM-QVJ$;AFZ=p=eLw?PMWA`+ewv5c}}WQnRX;{)8>!x=8L4i&sS+< zwn&FwJT=Z<9}0q_?nNLk(h3Ytg1!Bxq=V|VRovChHIZ0d*(){jDn=`Ni`*vY3>pTl zYGN@hfj-{ox*wM<5eRKJemI&$ypa)}Q?X%!;2=0}Rb1D++ zAZty+i?QrGUS;!8JAV;r4diZJ3JDI$=ZHnjr(3$Oej4p04Z$DV7}#@(&v})aCrv=CZ>+WC0Z=(&lk@c;Mzn~;{@6-^mxE41Gzt-|`_CM%(#9-ms~wpD zU}Z+sex#xnAqN^qj7DCU#d2Z^td+Pl zHyr#N86`?K4C&Pp`5k0QYxv%{&QoOGdVU-Bk6ZKyeX=Gp#Hi)Sc=0r%`Z$)#4vg|# zrI4L3R%&xOxXgy)UVs{JtXK$hI!XjMcu3ri{kkZrfdhaYMs_a+1<*exVi4yq472bLBFw$sRAw z;m88F#8RdDr1xlnas?vgWEWj}P|j6yGw{|_XadJ5qxDsgb^(Y2u(uZp6~Hwf#LyuZPV7kP&Y$gwg;yu7kH?<%i6fUA zg!K|fc>{;%!cO}j(|A1J(*CO6B2C;9>p-awq*LKV1r_>4jmFhEF@@xgm-JJ}rXQ8W zGSf{LoJWYd$c}hA(+)@OcX`3!af9kVo|pJ5`clVIFvJ9QR&h_*-Wg>IQ(jo4W6X~y*z^9<># z)}}RpCtsSTxJ(KshXnShInK5=4CX%APL5bMm8W|Yp6QHVt?}O1rgbwsMAs5QQEMyq zxm*?%tUg*nzHxhr^V+eTjycTS+SHfci1)a)sA>Dw4fsU@&db>4LT5q~cSv}B(0)OO zh!&pZkV1HRC$MUbOwf)Kj`#O3ER;*-Kt^oh{Ui?j>UK+`>=elIn#7T)?3#6FkB*A& zvRF%}4fd2hlJ@pyHLFNO@Xq4Jw5~y^q-3qb1rNx_R6rbu?4Xda##&G2K&3EIMBubf z@AD_99UkhZQgpxJurCp@!^$o4LD*mvM#v&n)GTiCDCJpvgmy4Rjyvy+R@xvR>B<6Z z2B6mYN(mQ};tJ0qj#)tjHH%p-aufM{GHbipaeN&+T@~6`f-o4cljV8}FpE7f^z3+U znj&PzV}f>xrAI@D=_M+2Si>?U2+A{3JJm?7j8Ce88oiV`J5xBbKznn%A88q6X~uZo zOp}M+3dUC;PUgTCjf3`lvVPGt8suFGO9;q#Z;vk!=pSX<*#eO4U02FYjKcaWoRiDr zn&+yl24fo~Wf8g}5D&A+_=IEk2#u}M6Y!#vI+PIho!;u7kMP%=4={o1L@+$^2YE>g};>WH?E&)fEfIjLPH2>PXkMLC(^qE&tLZV2}y0OBoKn3U=w@ z^|`k0qo~_ROXb`q**ad>f{oyK>vM7O_UtN&*5%013xwXsG4_&kXyc7ePu=KaRbz~f zLqU|)({UR$@lLsf7iM*C$&Jf0noh6^j8Kjr& zvs4?SgXeBId+eeSaHj5m+9k{Nn-N;u1zmEkRo@U!0n;%@9C4_3QGHQxg=1si6udad zN>R-FF9@VqQF2x~snl;C290oL8Lh8{=l*&f+cZk|CSmJjPU zJ%se4OorD8-mV#go)4AJE>&z4xP<%9OE_0iohssd9EUIEDSIdWk87#&GRKyuy0eb7 zjqrdP^Do+R2s=dLOb3s>mNXSi?7C~`eYFpq`IPLM$JTjvqO^UMLXH~lcX-)4o$fRV z?I@+NB;q}p(Q=`OS5Z09-B2oceHhsMP2m(PdBJis>lxOF}D>JqH*6i!`4z;&LpKt~VWB4RmJXnI1<<*c>>I$J-b zL%ye|Ei&JNAFrvffjKe`CpE4nAWvw-jc9N`m>!Us2^>mxc%?;eJo+VgN;ZCk8)hta zCbCt=$^QTuFP1_PF0+wh6aH)vTcE37@c!6nAz}hx5eY&X?U{s9hxGgJda(A}#BF1W zg$!*RW^Hs7qCs?DI~qGuL^dA)8?wC!P9%94Cq`S@nT6hv;s>e zb!n_#r7FzkpsT>A&rbizN(qPaD0RQaouu>woN~wPzp_rF{f>`3_h@P_ILJ1{ z{@d ziO)sqOwRBDo#;$|CiH_VUA&ytIQJj^u#&%9eQ3Kax=vxi3Rm7z4X6p3QEHYy%^L)qH2GIhoDQ z&otj_mNrnt>m$ zM9`#$jE3uq8ZbQ1RSniDbokx#zqrA1o_21dYt3nS3x&trmZPRpCXmW5LcQOstx}{_ z_8cFJRU+E3k0j_X>g-ef_@&b!+Ph6`vvhgiaKv=RmjV-&!KZuh5WYqS)pc; zbGj8)o2pRGHvbtwh)Hh-4WEN6Kt|o*2{;5iu1Ucn%a_UvY~Li4zQ347{wFMscCM$5 z%SGMXu(yRYHblCv7RT~bvr(3-z$**geDrTVN@Z%3Z;WEE?>J%f8Z=R;;e^zGS;n2urD z#7ROZ$O5N(@>49$E{mBD??-Am-%7WN^8B=jc90%MP*$J z+O5QqN7_F1&^Ef+q`sdLjAe_P!{IeL+CMAyaTWQw3T2$?7|j-D%C!Z=ZIEEm=62-75Z&6S-_2xJm4!Mlj&ZuN00wZS*yZUZ#m&LZ}nL%R{q z`rXL3ZDTaV=VSR^yz{tSdLEZ1MXnMEE;6QmI?wb)@4b0%ZuJnaw=#DHkM}p&&RqOE zf&#_=3eQYO=H!On-k@z^RcTGOf%AgfD;i~AglNl7B6$!p2q0ZrB9FV6D^Y@HZ`TdW zW)-vjuooe8DNcVc#}w-x6xQA9d1dsBOg>^y$T~8dg^$;|ut6B-Z$TIX)cWbjgg)^{ zDMRw{$jh8Ahsk@^^No%1OA>~+{>6YwdLtrn=?6H`EYp%VA?O1pJ*ypMVuL-TG zpefxyE?j}Ei{xV!1(bp=5EtqTy5QdBqkEC|mx@uhchz0r*l@I-Qmwbgmw&m4QuCzBH(G@pnG* z5@4_6+n-AQlMBwblid{7KvX@m5pdd+WZN9B z%nJAtoZ8g?Z2k05Xqtloe1R+>r|;so4teZ}`@BnfJbk~OW6nfsFJB%ty^t+c;N~k# zBq>m*-agLG79%OCp!@X{-6lDMPmD1-#oJ9AbaK(8$M*;>3vBlJFAY!Ogg6po6=&(n zaOS(&?K7@`@g~1XUDqHX*47d3nkZ4K7{3OFPdWVA z4J9jI4N@>g9zt$6Qm8J^DeR52LHKUDx@eZJBgAe*b#8|A;5BQqU8i(XZHpUBl&_ULKnRu<$W6fv z61|TQyBlFn^cI3p{pkbyvy}P+6?GM-oZYkDil$-zXF}LQA1|{bAa8@ogVj7qza` z%c@BvY?%Nr29}Av5X231d6O$m9HxPTnO^G_ozg{BFh{xwC;06(v(oL2#&Y4f$h`?o zZk&G;rU*ub@Bb*`YCTL@{Kx7*h#82_{6{211<0gfmpA_Dl4MkiyibwOH@nd`s%S(n zW$k1S2x}ycI}0umYOJm#!KG?3m!F4SK;9N+(rgbLcNe3>n+e7itxq!=%48?`tFf1c zBciNthFhCV%GEO*@r?Ut+(6cmkcn3B4Xc#RtTvp6w7drUl2^RY>tQ3*V=Q?0y^n`u z349$b_yFNg;a!{Q(w30!(qP>Vx1xLLPuY`i9Q&4WZzE4A-z8B zaujEI_C~W@GYuhE*#h%!w$?jW=1gFk`3Ro0@N9=`4cCK&HouTw7tsMj_zD8z5;Mr9 z2?m(1!uZAJMQATIf%-<@^J{|QX}sh!lbB?2*BV>2o}CKGCn0lM4OZ%>4hy@o9D&(N zG97o}GgB*)%Uf@b7iZ#TGihGyr}Ju`1~y!9wFonPVE0iYJL3Ep#)pkn!3a^>)PA2x zV7{91)S98I_pR2C=XooD$<3#6N0!@2C&5CKK0-Lyz3DddU1?3Lf_Z|Hz2w(%^Zfrm DU8cf< literal 0 HcmV?d00001 diff --git a/bin/stupidfilter.o b/bin/stupidfilter.o new file mode 100644 index 0000000000000000000000000000000000000000..0b62ff550cc6245a6027b3b4939938d06d2664f2 GIT binary patch literal 34456 zcmeI53w+eoweR;o2@)+5q(t$_pr}y+!$Sl?43E)40V5Er_!x$n35g_=n3;iu8UX{s z7*X_y7ZrQ7^?~+OTlM%nNxoWN0lj;{}X)DOafs}u5=N6<3v{vjbdOmMOTVkL&EqcB!)z(_D zlC-Y&cXbuK>F;uip7(dH_V;w1-HLqH7rn58V%2)&y1aQ$J5F!z2az6;uqR8hXwwdg zUsI4LQjhoVNj~i%mTHrkcon9_zt`bnkMr*>x@A~T4`uw;>*SeK^Zqye-#BFSevxg; zzkhl2{DK}pw-{qUgjg?=@i)(zL_~iJ9N^Q<%L=zRo>4{G?W^? zdpf~Q?;5zWEpaNBIA_twV}$|ZGAP&^81L^+_Ud^3uRT3)y}mZnN3wirVvOcP%AqY$ z<;c=g$*GJCbxztJ2T-?Xrdy@0sa>npg+A12CO&f(IMnH(;$Nh!Gj)oxrjp$)&HJ6? znai8IdwP^gp0bH#I%xMY?Ovl@h8h38MzWizB0HW&Ph=mPb|S^8Rs!69TARDIW=r0* ztL0F~4d6f77<`=mzy?I)fZOg`%Z5Px(Yj7s8w<5XfsAQsi_I{*vaM*v$HKG&Rky0Z z%C=;$&X=N{%JiaJ`q>FIG>3{|A4 zldcFS{yUYzxIA5y(>Xs6V~bWUL@NulUP!)j6N{#v8+Y8czo*AEc(=!LD@-N#QgsJf zlY4Wv#!OSlPUq%>yJxrV6k4}duqlttIjP^hypbtG_Hd3Sbd=k3 zZq+w8Ej~btvwKqQ`va+WbjF`Q=_)ijGVbVn92szeHRbS{>*jG=idNl@sCNJU!i+>} z3&tqiUsC>VW8i3$qwuwtogZP~MRF=upDa5MtVUR#!)(#!#Qo(PnAh$+&L29M&!n&CZ|txiMdj#$>~uAhK%C0ITFw?kjQk) zHoIG9Cvk9pr@KmCM;?Y=*%8yN2zQ>2C;lVL5&wx>WYLNjG8IlH{?~A(mp8unGN(66 z(Ly=`spKx)Ep|DJhNB;L1X?~tJ^ObB(1I~%S$?wkz3*VqfC^-yHKTgUX}(Mo0AxPdoyxS@Q<@>rhdu{gnY#?8L<4CG=kHFH zqXE%$sf5Ma%fuvTY=)ZoQ2Jg#&BMPFiFamt3i)AYD*0Zk|Gkzr%(5Xt!Or)Fy{Ky?o$DKaAusxOwU-T{p^r{8vku+UwXZf~oa-U`_0X`NO0n;$ zKx$jys~rK{)KYIAcvnuh0-bRy9)~EIF@vg}sy#)GqNBZRted&p*U|0|)pvI28}bfQ zA3HF;>_{Bzswy?*fY#AE9*s~XPDb9lv?Zx_eOTFc^O5cT-;gj(?tf!cb+lIeCRJWy zoJB)!Dlb!`K5E&i%7#sFV&}DQ*$D(ftWyV#oGh`Tz~sZW+gIi5tKE`YZBl&XSvlwz2TgSQg1V)1}@CoVA(SdP}#H?9=Xlk=jh> zrUJS_zew|m&S!CM(xsE7-Z^V?Y8&+p|BiP5d(^zTPDCf&hDZBA>x?#Z%oacHJ1zcg zPK*CN^xGZd(5FA-{BxDFwQNF5cV2SzL1g-6rWbBmaZl`=4J!|l25~e1!UAFR?k?lE zA7PMhY2K}F-n$%oAJ!GnUG&MpRJN9t&}{raQ0#Vp$JzR@2Yc0(_HeEe257(z`*)xQ z^(urucF?G|$HBS@IuOD02f1myCX&gC`A^vtH|PXJMUmFV{A@x02{S?dPz(34wWo!_wS-?rTtx_0I820tgW<{O&}2(hIiqpT)p{d z1>r+=`+=_5E8w=A9AA!^qTpUa| zYaCzrIog7jMoF^g>|_F)9b-s65s+0bO@x z7o3`z>at=qp<^}`VntLpu0VFV5NSF>3?n|PN*|y3!34!?k%Z!C<|E9!_TL2&880bXBJO+gW***{v1Zv(^qt-wY_iDy>|) z{XH#wZqHiy+`hbdJB<%|wf6U7;q&)dlJ1J;?{$k#FT;-aZ>NP%p)ezsweZPC+h*eK zvjcY?p`h}@$DE>-7hwps@bjnZAoL@@B+iZ81|;nCAL$+?Ja| zrh??M^)A=bdc4E@XJ@)?q4(f+?%(O&oY?IZ@NS;F^hpWdbl`D}7{-nXftK1GnEJZC z_1hPqa{@|^31i=)Rg;jGrl_q2Z=iZq&#upl`f1~E)M`I3x@z<1MaSrKtI4>9NX;-M zh96wJIzPlD?r`W?cbN3dI81ta9VR`mV!C)Z{F6LPdWIb)J)huV^>CEyLH*F{&IxqG z3xsiV)02~z)3^N2QanoP2ep)cYv*b``ExswP9i3Gd#!fss+JH!Py>8*tmlpy4K`LDTJj9oO&f>7lW!d3#6g zCv^ISnPJfoPha>XN;nk_UOd>idT?uKt@t8UvAuJUeritl^3Gr3y5m&b@bRG1(!9+{ z6l0%PwBkt&95_>n1)Ur4;FX!1>$@lJvg_I~c|3=+bhC4<#(H3C$L5Yf&W?AwTiW`j z{JT0Ms8%;sa*r3S5~2vfmZi` zp#WvW+L^xGSJY1*-Tsok2c%Wys71H71Ev=HL)2{?Ihq!?ngg1a?wNt*TdDh^JFA@U zNFeTjaC-bG&FYc~UtOgy(i98TR)>AH(b~F(CSP^T*VGh^#gh%u;QVA|Wwap}PlUn? zOU`0N2T2!KcX(i^d}40+VTNbvz!8sOnffJY!hhqG&^9P2J+5KBzb| z;fuy>{q;|I^20JhUKsf$#LV@0!}WNEB5D51~y) zuk#(HPOo$ut7R1RvV(23nt|Ju!m?m`JDB|65=R5w5!iZv%Z-Lvl0DKKDK9D%=lLCR zPOOi)&ZVCwJjDB2Tak4w??p}4cLor8_@<0IMd|F{3Q zeSoMV6uI!(^q>L1iyNc|jI?5|Y}Y^hW0)HpAwB~HYtauzt7)B_5#J2yJ> zo#oCl$XtV~N+;wjbgp-|PQCL-ZT)`rrRwDzE}4rNc|OZs&t}A9d@QT6ChKizEVN0eF}1$>s;+jbf$ujaV9yl zomn_5cg}NWIzHzD9LG85I>Viz&Lz$$$L|b+Y>9KaQ-=LS~c$Raf)5{s+^mR^k20MRNyVZ;8ZS|;nNi9Grroy-5sqv(PgEn>e zKZUsSo~(|>J*P8PE*%lzZv^^IL7rptim`8t6F@}ypOK9$&> zQPucV>HQ7r2GxS?2DK2M7Hl>6G+~S3^CY%=@mYv%6W-Z;RsD;41?gW#%u8r_FR16$ zKSTC8^(=bdPu0`ty+1)38mIqB{a8JrHmb+fV`!g`s2`~xs)yA>>L1k))Pook9zb8e zPpwz~4I{)o=;3#(yVP2Br@BL}QMapBb(>15)fho;RV&pBj3vv|QgyRxRyV2dt0k&Y zEmn(EQYBP_x>41uIyGN~)b$umu2om7tJL?@m8wF`!T2*vU7^a=efbO31T|h=pvI{4)JQc#m8x^qP|Uba!))v%%+!v<%TJ2;6dn#W7PoN_fEr1b_jas8R+RH@Ef)6bKuzv z;jv-x=|r^di_mT>;KR$|s|7giE;ZrOBG`bD8?vIjB$X*fMSdSL44eiAbSib)}sKWbVq_>j0NAv2<46d z@pS*E^qJ2b$j`v2TBiH

XHR}aqFZPU=b_vWDwABCQK46Hf54HYM`L!>OOL9K8C|KKh`D1eQwL)%%jG&dFfKnWpE=7*vxA-W z!dTx6BYrQlchBfbk_@FYx%EbCW64ZRCVfwjGx2OJgFKwq>*YN4Y+kQ*z17EgSgZLg zulU#b>W=(gkL0Td^Lyd^wu1kW_vsPpcSn%S9las*GVN&1f`YT8eEKZqH1_MAPnY@m zeR>zJ#r%`vY0ZMd3AiqxlSzI1-I_P$Xj%`V_^HGYevU0yd_>18j7GWRSD5%GJmMcQ z@w7&iOaE3APwPav;&&e+z5wN-;H7_viTBb!)x^`cJWMEoNr-pjtN zhsb}oiND<={{nhoMW8SBa@jY;#CzF4)x^_!Sg!OD6HjYqx#Cxt`1?KLA2IP?d&F-w z@&D!#zuUyqnq02@3v`or*YtA54>9qj9_go=_!01PuJjQTKfoh?g^BO$5&wvZ@9h!4 z)x@`X*tgrnPxOc{&_*luu1EY36TikIeyWLo#g6y4NG4bm#-sn>vKTP}z6MrKX zjdR66V&Z>+a%9B^TJqH;Q>I+tE4gH5#aX`5!$%As=^I&EI=1xu($T(>S<#3u5K6dw z*yu4>XB{4Is!fFEEhZtQ|^ zI2dgVN9z+oD5{AX(P&k$vH{EZYIwM=wl*4rwpd*vIvfTL(_bmUABQ9Opaji9ugOb& zW#-~bpQOfb0?~T4ajT&C5_Oh)S#qv>q&0TRht~5cP#>p2>(|6h(;}q9*un16)@@%8 zg&66y)0dg_kGg8od(NN17@XwFpVQm&_Voy)w{0Tb^~-6WDJPX5&GvxuPX?p>&Cr4~ zH_S8kzfWHlh~N|FbebM(Exy|1Uq#9hD1Z7MfbD1hUka8h|1snk1hP*Cqb`j?ILnp3 z(WGy)oWuFEf@^VNiRh@kx404;O~sP^^t}(KXZsg|*)~zivEylvj_MxLds{Yv7@LuB zrAePoXijWd`cBAhdnC%~SD18su+!7EUH2qgT1I=NuA(ov5a@d-ZtHZ-<)`n(a^=7J zGLlm2RhnFhVCOHQvQ9~^Kz-Je1eFkH`)*_sN6)+f5RhD^M7M zjW`FILsFnGUTG%Ie&(D4hF6gg0=JtAoRj=&O*4GH=Dk%LSB6nU=^gZ(Hsi;8O}=%8 z&ohdDYV<8O+(#9I!17CRuJuqOM&Nt#tvDyXjJ`NTU{3c)va?asjGgOoO@83=(_ERt zQ`m^}9F6A46t-a_J@e=S!I-OlgLC3nX`11C41dUQ_UBiIKVmr7L;+4H-z}!Lg2 zcyQ8R?_Q?!9cK74!&(1%hOf2crx;GtC26N5&=`vrBm?pv;er)tK(qM{E>K@c)!#5gEb2tk03oWuUk0$*HG&iE~9kesz zJ{s5%Xih`nG;nGUWz-Q6?lyXc8NQ3YY)1IfJ?MQto(^+`d_7_w7?Y2+!dxL=Ke=Sb zj77f3!0SGPx&2%O-Y;8JU(GS{EXT*I!TY0ROK_y{gnLj+4Ig6KPanhY(t0xE3D?X0 zM!wWUaY-IGe4@qwS?eiC+sgL5V&tb=`Mz!BjT!0o_A4WQm8JjR4X-rZRGa$3@J7RV z96JivBe>7c{p3x}WW%zz`U!Z3*3XdCJ zU>ZW3rnsLQzSVGg7NhVkcrHKe_TXI}e4o+(zUf$NT=l9y>WRt~G50BYMx$^Rc&>a$ zdhl@`e6j}*fK$HDn|Uxj+fkV1A%B$z4}w!aDs_{m`*pS9qb;5=e5}Qr4WD4~Rfd;Y z{BFaiTKorw2Q2=$;nOYtg5f0=Zv)Te|8@`l3lIJwIQhARULZoCXJiWh?jhd^PW~L~ zilzPeXAk*2^ygf57JKkhJ@`luKFNbuc<`VHk9zQ1J@`*NxQZu|_0OUyAakkpropuk!$^W7Ub^ zf||Pdp_;fZS(d`u5WY5Wh3HtBtf>jsh7#c_x~d_AM~?_UUeqFAIZG<>YvmcM&Jh<#NkXt_zweS0Y+IHaP9_;KkFX`$>E(^jmMGYEOj1wD3dL z;jE@QPN#b5C>UJO*chyjHpJ`j#%*~gS;W&>kn5qDKy@su z_{f4NbZ6la@Gs>OiOx^zY*46ZqkBn4AexftXi`2C6nA7)YOH`7u70rik!}GYSI+%XXqowi3r-9s;qCo`_+}oSUv(i ztIyQ1J1pe336jCM+n^J52W=75%Ede8<>6W?I&2s3ilgb1uXT^mvM5n?Y=Q0()Hz~x z7$w5G`zigZahTDe;flHmT0vOhWqG_-uEI6ZP=ode zoEAYUw08J*5jhIYAA4$}v1BcVB6L`NhF8qdQ}k&#RPUbDCu8A+T3pwF!3eKuC-6pj zbpm5Y5E3}Ys7xmf(R#f59*ox3SB2u$aYb*j*GFq=RORA^>I99WiyI&otcWeH#$Yom z8c$+Pwl)MyOoizjXgE()!PuFzL({^3w_)NUjx)G!)@2%}<4rT1dH(DxXH+DrYgqoW z+41wjsOtu5*K^a+qo-qB_Ro&%^l_6I?|4g@akImrn&?ct0`4y#8(&l#jNudlBSz2# zZZDDQaH9OOadf3$6feI_ily_?+Hp_EZA}L}#^`(dGWRll4`&`RoafifR~Sz3FjKHO zuglr|JXc)H)7%0-7}SB*2`SKW*kEjJln~+j?jggC;p;5U>okvAoY!eyvUr=Bk8ig) z%kQ!{uitbTZkOvD56<&_mZ$Yd3i{8$;FvD2Dc7au`G7f>Yp%uF&X~oyT+1!a^6M(GeE-FRza=>Nxf~mX z_bh&ui`B;#uQL2oi`N_eg~b~Ur*#Pmwc)fb zL4ozGbuZOu!O5Tab*c^*2~PfGUSl{7Yjn!~xlzc|S_0SaA|X#}>>QQ}PB!s+>Pn%f z44m~mE#&Ex^L zm#fl)FBV+dN$Ud?*dET8*L|6DzCW?#nZIOl)E@kCp%fsUo6gg z`k4C<+sX0+J@{!J{A`P}{xKG3{ZlQ@^4D1W9$k8+;udH5r50!XYb?(4KNej2?HR$P z-}w6>_7CgXA>{qS|NkmD>0$ZbS)A?s%;GFxXx2CFe2*4H9Y4aUadejz^{ko7+z_zc0H6Fj6r!*?yt@@H5)Vf;VL z;tv@<#^S7hs>NCVEQ_=L>nzTC7FwM3G+KOvvF8?xv-}+vXZ;&2&hk%NoaJBk;F~@8 zFD=gccU$}(V}Bks5CpC-mhWqEw&x^^v;4&#e3r#o&peB>9`kelv^@#eJhjA(c-NCNsF_d7cI_u-mv%vW6v)w&U!wyIP2MG@q3J(IrKn@K=m>W8;`3I z!zme!!)4egd?w^C$2H3j>7%0$&@H3_sr!XI-HTYyla~B_Mt;ALze31=*L+_^ z_Rki4u;AwkK2dNvzFlf@_UBa=XMa8@I5D>W5y9!56XxxLOFO#+m;V38aQ54a&_!WT zU-xL&*960D`Gk;{<>lvl(nFlfdxwYoV-{!m=Pb_t*(CUI=x0B?CHR$szbm-3^J9y1 zzJIVd=R4HAS7Ddy0*kYJx!^;EJ=X{>{Znmm)^oGPH$WGK+bo`NvAV}_uCETmAF|}R zyiZx2^L^dotpC3YF3a_e;8ZS_FX-nQKz@_*Qv{cOxWeLW&jO3H{Yi_n{4Ew=Z~Sn( z#o3<^Se*4gVR6>K-Ej7^&#XiJ(UNC9`z_9TPNx_C5bSm}%Hk})K=9#6$L+sHaGL8e zzh7|a=ZzL;{W}Gh`acx>YN5Z|aP|YgA9{p&frQJ&e(oo@9IsCH;Aa_b>mTbO?-yL! zf2rVeh5c6uF6FNmT>7oX;_SEE1;0k(*JJ>F75nRi?f}( zEzb7*!GrfQ?}t%6N_&nH{ClFjCkQU>DX}=)cQ7r zob^9uan}Ew#aVuf#aaG+!R2$%Zv~hB`IE(2Pr(4U+}!?Gn{lSdaJzpE^x%Um&h`(p z_#8JoHPPbi&zTlyJ=a>C_1tK2*0bE=tmjUPvz~_qm-ms)f|EaQGWP${;*ExXVDX6I zor25x(q6$yKg)mR!5#Br9@m%t>*z?=$8fH%WhUQaEzb527F_nbVS--=9X!sD7F^1Y z7kspkzeMos1)nLnl&=t+{4fU_g^YdhfFM3M0SIgXbOV3UIx%{BefUV-GzCwUGeASvEK8bW<$O z-_y;uIDhZ9z~cNp-4ctl{2dnOdHj8b+x9=N0o$p4!M-{rygS^CS&ed}vW z{vOwz$}wLgv;EAA4QKzeo>M&JOFZ~UOAo(KJ;{>4-Pki-a5;|67kmt4xnI`_PVM<2 zqi4Crxt-r>ac*z-d+>)n__K!F{(0GwXMetD$qzK``6D486y^G#f>ZnF?`8K1F6F-# zT>9aNfv!Wie%a6cEY5Zw@4?Rye4em#xZu*x3j~+)lLVJ`&a^n&d6mW4&X5O>2_6!5 zE)rbYd5hpuJ|(!c^InUyoex=@?R>(6KQH)vVdratOFMrqxRifKaB1g97H2y@T>KKVEQY=NT4fJ4-Fjc8>Gl7YiPNO*}r#6kOUlS8ypG z5?tCDvpCz?XmPf4xd*>P@Tjo!UcsfEKNMWbKOwlZ^LdN2ooyCpJKyr)?+acj?EFY@ zY3HYcOZm?Pmv;Wu;%sLj{ZU2)9qlKLd1()}=q~Jq^{8GWI1pk5HQvPRx%W}PDah_*xxA+|7LE*O+XZb%_ zoaK8gzQI+ajyTah;reAg11!#ZP8D3vZ-)v_9$;L^^Cf=fH6 zT6~$&AF}v*!|Mf?^_vv@d%~WS;L@IZ1ef;w$b&y6xYYBS;H2kTW9N2@b36Ia;v0rLWJ2uPYtfQ9a5>Lh zD!7ziC3r~axl?ed=V8I6{1bxD7kYjsxYYBy;8Ol=!6QP?yMoL4$tQwK`9BCQ@4tT* zTOZnpjm*qN3@LFO2NWo)*Un+Q=;Ijp<7yMemZxlQ!xRhTl_zgn- zF2SWe_Y2-2J%8-MKNDQqf9xP6Mxc6;e3alx#IgQH!RHCS zPH@?7pAuZQ!*;>tyl9u;vb}vRxNJZDeJ}!n?3eA~93N4a%lXVCA5oVt!ja20(?`_h zi*aP$E8g!@~$@AEW<0h9}ROw^uENL z6E{gU30R!}jsneHDX={M9fj2{PILbK`bLZM@7K3koPVd@VR8PQdLdOH0_V%WM=!BB z|L#0sasJ(TmBsmY=c_HwzdPS(asJ);HjDG`%R4O2fA68tIG63`zsFEwaqbrZi}U-# zRTk&pm#?-s|Big4#rb#S+bqt%Bk!;{|Bk#cKimKOd+`#B^WS?2Se*afLzTt(_us26 z&cFZOXmS4i_cn|3@4q`N&cFXIEXcN>|IS2-#rgN#0gLnRxvMPBf0tsl#rb#G8!gVi O8~&N#C9Y|D|GxkplbzTA literal 0 HcmV?d00001 diff --git a/bin/svm.o b/bin/svm.o new file mode 100644 index 0000000000000000000000000000000000000000..456cb695d4d63dfb42f7cb87bf9b9f415d0001fb GIT binary patch literal 115016 zcmeFa4}6_Pl|TG6H-(7kP4UkbMG2*73RqG=EEMqqee_lu43uDCi)~0!5=oPo^(=FFLyGk>0$yY2NK%v-d`(!WL46_)#^p_bMCiu;`4$Aopn z`Z?p?h~-Ynrp2|p&`W(jYVuu8%j3Aadin}i>iuwKHg5;jQKC}ER?pOCOw z!WIczB}_?pr-W@1-X-CmN!Tu7hlJZCyj#NU5~d~WlJFi0GZJPc?2+(32|pv@=Oo-E z;pZj%f`or5;e!%>QNk}t_+<&dBH>ph{F;Pcm+)Z;2PFKKgpW%2n1q88J}%)C5bXopE1AiA_UT?fP5DeRePAggW*BiMnJtrdNlOL6uLyh8Xr_ zA^uDh=FafbZ#!9m7b_G>+e*)zXnj4U#*e9c@dzc@R&4Ct}H-Q}YB^>jCEHA$iIJVOInrEXm5E zw0&d|A%WW(`^ep28nKU%YNp6AvZ*7@s?2DtykyLtd?j9Jy%N892!&%$ySX{; z=H~d_{ci3Gkh}PO=bkumLR;1LqrH@$Oh-2iqBEJ<)rQC<8-`^~pMa=+zPJ7ndk-*9 zjMxuR;Kbbx%z+Vml(aPUFG@w-(0O6j9z~{l^7G=4S(h(L-IYy^LY>{L&h+#m(kNA1 z=z!3XT|(yqRoO-PEv7`b#6P-!OMIo>*Rptu+NpUFkeT)&$&9@x_t6mN*0rWYz>PTN z<(5Tas4|p<)AlH7yBnps#vYB|7lT@|_MVLWL~_I)BGJ9dmrBWFGu_I>k!`Y> zC)j3&Mr>+qtf@rI$s$yE(4)e5S2rp{Hgzzl#@D$dP$QAJY9vdy`$!#QZjJ&dl;?ir znd-8Xg$G0BxgW*wEY;XCVDGQV6~PakIJ7+HD3JOEAa{~ z0y0K~$~NLp4lM%lxuY(TN)7gX)Bbqz_g;x_9E}(6SJuA7p3suu0g~k9-X&rcqm{a; zbj)ivFULPdjo1=Y!$xjFCnGg2Xg;f_ayfTi*d)DEN|RDbzkx~pCzKM(_JA&*8C^bj zaLWe*sq&dbE}a}w`OJ{u)2e);u>9qNwyv<0{@AK~@^Wu<3TK)MCv6{eYvsZCeFMi& zoFMc*B|t@KKWP(?L_*{{b)>5mRTqV4<<3lI%R8wOqfg-$F>61R$x{eaJ+q9e+fdbO z&16!?C=bZllG2H6>KN+hjMHm$g9;pHRFinjF?%$Ls|AiqOK`W+lCd~Cf|T}T{PRQc z$A&WY;i>Pq>CH_y;nHm<>3y=be%v6}3X@zG$>OG&E14D16*_nFh?K4u3N3Zk%D`J< z|6($ms9j?pzkAr_AyOb^^7J52dS+3oh#tX|s{o=3<((amuAvn5jEov{sq#~A4N#r* zjQzVsxqSS!;*Z(C(>&8h3&nmi<&OhC zLI=>FdaXu>2koE(7);&OxAM@v9^$m)1(LrwGh!blo0{6K`oVFf-lLu-FWxmuc9lAc zI;0$H_5@oilFCtsiV1y|mT+47LrQ#hY-*BG_5oJ$9eJ*Fp#->rn?a}lBE*c8NqIvv zQ#8^HCBA@s%q%D$XbS`RXuTp*JainK2T~Kcb73{fFeGgsm7xNh*Q4?K*8c~&_ELT- z^E2oRwE|JRG$sN6_+yDy3@y6yQOYFeG`f8VT!FDOVgX4e@P|8Bc#AZ! z7>nQYV=3)t60J~*Sf=9El%8Cav5!vep0`d^mRi*4E;}zR>=vI zMIAk5Ix@Z0SEl!_hfbXF^=7n|dq!-UQL#pBnnVO#r~- z`e8zPlc{G_-P)sSJ`HO1_%Gf?b0JXfo^0y4wjCQ;AY9Z#X8@d!mKk{EqhQdFqJqDc zDW?a!pUJ3NQ`P~tN2hLJhVxEza2|;cPMv_HX?uXw8kP={kb6e9q-I0Lr+ygD*;SFW zDrcxebLMO;*AdXwY$*=SBgLWId1?F6+4D4^^E4qn{T{Zpr(%$D@+cqmgV|`{s+PnA;nkOeg zz)1C%qtstg7do14D?s35vv3}6cRI>*Ol}$E&I<7r06h8leRrX&2x{RZ)uoQAE;V%p z<;PdYxDB)?ICrS3W0W9}!aXeX4=;X%z4#IG;zy{9K3#Pdqtfe+aym*V)$1Og`qdvx z`BKe3i}Z3W%;S%tZt1r}x+d2}mGL5aQvJ4ASNrx*WO^$PtF-yudy3m{Z$C;Mb~3ZC zmI@=YcQXgODk$)H;$5N1+s+YtCy;ztcCVMl?i;cD31!6I?ZYH*0G`4q7+X`Pav^mw z`_QCryh}~UvUHebi9qAi+zdY5wm$GeZRo1GsS8X6`e727*=o0HkFAgv#s zB{gmxdf_UcV?t65L@#r|bUID=vTWQ^V9xjFXeqMxPRu*OBgxp0V&+#lMa~THz=_ri zoYdV(V3kT4>b&HYrh*4}DtHjx;{u2t_0Jz)%#*=dfoN!HD%bVG?&k6oJstEG*zYi* z>qtYrjb{!Rwc3Jjz}lwf9aUX(2qV%YQ74p&xwL2`rPNM6Pl&l!o>9JoXOstc{6{m& zgK9=ur?FZ~grTf&QrU$I4d}T0r}<;=%;bdThzECO672uTGsk-Y(klC$y`K4Ft(Hhk@qYBeNnY+frm{fE`uqqgT}+j#xqh_vTrxCw zmxXZ$=K8e=^C}r$A25~7jOK_3w`8QVxv6v#QaV|BHFL(QWb~Xd70Wagi<&d$>~O`# zwDEUj+PGKypnZ@*?7zb9-lGh<%8noTi4iYE%uN#oXtkco@}5NUrj{Ywl;vbeB+W7OAHZA0Gy4$mXSo7ExQ4wx<^%a*chceME(+ z+q3qeHTGEQeb3d5iC7o2u|=nC*w_x!LCufu<~Z`WV=Wl7#%!$gojZhP zaMZOORX5R;mDAi-wnMF2DZIi`>T*U^uYfVAGq>0w`H~u#yDV+bK;juFEWYzjNbKYQ z?;pmynHB=}yKO)rt%?AI|7{6n2I?irFHYZ41iVS$O=dgyKq)ZIxAR+~zH4Y(Aw4Fs zDJGd+&18DH=qwdc))tttQ&^t$AxxXn6498#Z)?($Al0@u&&yyZn0w!80N{P^4!rjU z-uvD6j!7nTbl+SN zH&iS&g-+}4#6(pr|C)wWEG(Ds3p1M>I4qkgmP%P_ z1Zv1}su2`Pwe29brBH1fl^i&AN=@FQPU*ZkG2=@0To0B1FKGjFhSJtRGy%G{9Yk$A z3Ym_sv4`V3Y1TlY1)8F1=wq5T+EI&jlwG3_c{1=!GDiF2uv(D*=X@6qSArJv;6a4I zR!{z-%t;RKgYDlG?dNWA>A8wKHF_FT%c^#>R(pX*nbKPHA~V9Yv}X>J;dXW!U)yXT zy8|?CfD;I_rKXY}`$>W7u@8^%semBuh->p)uQRD588pV_N3iRTcF|p?x(!r5TJTgm z=N6NjmQ5^0&3`A73&zo!pj0R~c7nARP3gqVMVahrDs+?d2$Sq-EA&)-64gl*%K|-3 zOHE`;17w~=U*jBV9dCO>vL`i>?CCh-5ha1buxF;I(}CnOJcoM(<#F#$F9apDO&n!6 z%g8S2QLj;}3;`&MxVciyL!yayO9(H1?V;9yWnw9cY|#N$oSKK4Nsc6_&0~>95=-?X zn)?D0mr>J0OOt4a;$3S|ot-`-f%bGflR5+^el$}$49sz5QL1BRyFd~!C3{lo{S6Qk zuhQ*h%ZY}fGS98ppBY8ho9;Mf#qa%l2$8!Y!lJ*<%tl zI=S>f`z~p{b-PC*>*P`KsWxQF$Vfe8D+n%J&~v6omZHRmrL;YnWNOqigz(W}!`LPv zdt9A97rJKC$dSu9G6&uT6RzlG~3K)3`9RuYmmx4rnK}^v4-B-cR%7 zk(DY;j&#jnR6__;_ncx`PYrlbn>dLs4l+D$#xR)QMmjr*1V0zjtpFYfb@TLdamX>C zp9|^dcUX>qmNeY$-dtYei zPm{L5fxG-xT5c5de1#62r-G1p*PA$(Z=eJpKMjALq<-`%dKE)dI?j6CDh={@RvOgr z67HkIQHglU^^pRSd>={fS^{Z-9h}*$@e2Gw=5tUS)~%1U7E*3YK8gOHU56p;1ae~nb#0%RT2(-H<*sr8p>4X>;O z)&u_8WIY5~X{rITzV!P@SyR4Z#$axIwqovQaSr3Jub2sp9j&08y_gR}oWpDEafq|Q zAP#JqO@vJha~ZAU+7;v(>bIr-@`#C~2!-0m!sT_Z-u3$Hh zAzT^oISxK}$?QFhwm7|y{$AGl4tcoydG&Cjb%}a7r8O^iAZ_nhlzRf6UAN?gzW?xb zT&hXP*!Me?upT4!EZ)s+LRs60{QxDDgA*+s8_iEVz~zG7jb~tl*B444mbM>2xjeAO zzMlrtVFb6;!52Owc0aL5cl24?-jcO`~4Wi$=p;9lg=6+;(I3Jl393>Iy>gpL}tA1Z~rzNB9F0P4lmtt^pw_$ zY{yX+7p}$6;O~&Dq(Od}dXfcx05!qUP1r+=a-Z|zj#x+*vsVvcRzMWo7vK3??yz0s zfe5cU2N-irJm$i{tIW*_;Z&>{!h zhsm4$Q+H%cvq6{zO7$nP3(fUrP?rXhw6`gB>WJM(!cSejm=dMJp&1;SDnfx}-^`5_ zhzCMdjpq6D=YvDDyKmzpX|Q5Si6)29vvaEHnY>o449RmWwVa+Yet`Nq1|VQBCL--# zB@rn@8KlO?WOxKE(w>#JAN3HOA1LvJ8aSLS$4f|B9?pfJ*d#OXIHvD|PT7b(4xp7= zL&+v}pH1zqZ1<&Q;aTKL+vBLOL$n|BK>U&NA;)V#%X;_M(W(qQg+Yjuf3R?NyTjvv zOeoZ_OsY|*;Wx>oI&R&f)BFglIZ)ndTUzv?_K`@w-Qa{>_VFERHU7lv#QfwsVv_5KL9Tu!SL-b0#AZz`JeLy@ z=q8f40~pFln#725indXee4-8YYE+)lYS?3XTK6UJ)zh{KJw+QsI}U8L(P|!Xeo8tn zN}^fvy)G$cfYtVhY4E33B|Vd$x(?6NsOR)8?)iuh)w$edgpthhSG&_n8JO>mZX2*P zQ%LCQbKGbA7VOS+#&@2Ewvd>y?$KgnGRJvo#fGjg@`kQ2(uS@tqLqG~G@taH3RNVO zP@miSCTOh}3#9l&ik3>osoBEoP4s! zG0h}q%MYU(%Cd|S8vTB}>(h`$jW9wZV$NZaZ0N|{%)GN@MV>7iXXFWRsRu~i3h4=1 zr#)WByxs3=Hbbgi1HgcD0U!AonyF)J?8EJUl_PaeV0N{LHS|u@hrwhPn_qRQB{Tdo zsH{3YoYcP8|6kUmvH$Osbp_RHINIY}u`$%=Z6%LlTO;b=%@{_~gr27k0#Vx#8Q&h* z8T@p6aOxtpY&Djxpc+q2exi^thEQ3&G=-&T&~HLhpm3H_%b)p~W6f@YFQJJYG4N-+FjwtQdfR!#1hk%{Wgh|W8Hv%(ZFsY18UU+x?4JqD1`~yZ`Rb zssuYb!5SGYpv(eUoiEUbd1=X4A7&V)eyu7}Cy(o>I^YT8x`))r-QTy+X&$>dL)T?_ zyCMzGGEXOCx1d+>=3}?F?+E8(Nf&Qc&#Hj>lHKS_cCWD?YX2%#@X%f*E;qfhPT!DP zxofoq*o8nF1b~8%EO;k?;;x+k0?|c3Xp%i;$6YEK!s&ei!hTQt-^%7}$)}v~u$#94 z4NvuW+K5p%CG0Jxy+ViFd0l~wE9Sk#+(l=`_+H-^Im{YUG9#@C6$y*#DVx#hI->`) zP%54#vwXUS0b?hHI;kdi1=jOpvNMWCB4{8A3j(kKz+fcm7$4Lx)mV+v@i4%o-u-cZ za(YxA<6(zN&V|jD+(i51N^+T(SM`)LrY#jhC`%nxGwf_**g>YP7T$JV+8)9j(lA8C z9QmI3&f93BQ5zB7*YRYJj7ZRfh~u$+nCiIpJ>X_;Mtw(msUZk8s%klXW6qE2%X5Cr zPkl7m14lGVh#jNKi_sLR^C5XD`T*X|NSg&ueqoYYoY%d`V+}mMXb--4%fM7G%m=vC zAi|HDk~2X@x#k^)FQ?}(4mY5Y9nW`cU-Z6^T(I}$u;psR7V zJm@WSC?jX;MyJ5lPi?_-yjkfGe5>bl{sg=f)UuBOOdt} z1ULc5Ir)n?FI9LFX3C2GUz;PfzQO8{JZ?Wafuca?T|sjb8Qwjg%y5snKEt!;>oYyn zpW?KXWTvZ#u(G>2=*g#3>nuzq(#0 zi549{rR2?B`e+f_Dwt2iu^7t;>N!l~G|&5s){D1H=iW?CigIr`QSybRfi;cpf_epe zQsxtAJXV|O*o`(3-a&bP6D>L*9vK!?cefxWh#|sAbi%XkwN{zvxJf3|8!NqBG>( z5o_#$_|D}p9i+$2_@lhq6i(eq;J* zYS!3z@5Dw5G4iSPSeg(+p?Tc_sxwo=K1<=wY&2j^xhhu_J}Jj18Y%!8gVwk%Lcgp9 zUTZ-eV4n=aSJ1f9lL6YE=B7l5pmYJmi?U52xf#lv8}nwE+83S43B4c54ke-nu^YW- zrrp3bcaoBx#Ljh_zP+YS3LPR=rPVGa=(PRsfI&04I0%70?}*=Hp^j^HQvV)gR>0DN zBP8DV9K!E;G5l3oiWW$|?_;K23NE5v_uUzARglNJWX_sxsjOrC?oC59TQQ`Rijx(U zycK-riF;sxivAdKqRt|dR<8obi4=d2W}6YR9${drDWU^Q-O|_gqs;^B2T00S$Vwp^ z!L@Z330kR`lR26jO|G@2-<7rs=MokI0~*-ZUwojsz2c_ZXyaD1LaX@b(D7a|4JCSt zanq|?dWotO(+!2?S5bt+$bK9qqjO#&=#fSSoxaW# z1}U6Ltw!!R^^16I_4)u++ zd<2DZ;GxUKZb8QQle7YIv$Ur$0FG#2_?t2eVMZ}p_mnApbHdhu>fn=HR|hQ#R|mZ& z;0|`Efcm(A6i1m((1V>lIZR=pdgz)YGwaRmFsvF{)a;H+lQfGGr{X?^M)s zc-IyOyLcZ(riV7h!n>x8vC^q@Ep_Mu0*$d~18RcHBGYlAmqKq1b+5*^Ar@yvbx34}p$rxzgyOKgL(&~PI zT61}3Pq>R*|11j&wfI|yt_s9qj6zD*E(eL^O%iP9C6caqT?1^wyHvmhm&_DuhhWAn ztSQohW|sMKnKO8zG130ZoExKw05l*@=RMTNu#XOxEMV0{5;B5Fc> zX9-aCN8UG|g!+(GM(=FF=PHn~JGC)%>xW+b(C0Cazd;`v$ndKyxy5{v8uA@oB2ZJ; zC}-Dz5L6OU+NB7bGkkf<-N+%3K&YxV!9b?ILQRRDxt_D6LTS_@jakSklVix_EGPjf z;Y=3x5Q)dRo^^V##WI`RZpbt492Uea7?M~PqO(HD8%7MRm z7kh9VY9JNT`MPRU(jCCo)f8g@ksAj(2XKNZPEd-yIz>G2LPrHnSHi`JtOiL8_<*Nv zth9Ga{03yOkQ;m&ub>k;+l$Z_M2O#WE(VH3(#9=@(htvpxMZpBBJDo+fC$< zDDAsv`h5Vs|IpOy+2z$OZUGSt5dlaQ!6-~p8elipNzOg^&(lQM;T}X6ASFGDqo%U_3uzUkBP{GuRI2G5*SQ>jwGBCa8?=DR>qtX%5CZw~o*x)#!CzC^rG;&6 z#x&1y6P-AQGbU(gJ`N+M4^XCA8u*eld%cT_4{jbd)ZmRh@0r{RDQWF&sp&aN+8#nm z>?p<4FR4nyEEyyfWl3N-N9SEA@0s1M_|DH`Q#sblP+w^>CR)m<$ z-ZQAZ%&1SeGCc)&gS$yqgvs0)R>Tr9+9f^8JeTZJWx!Lr*)B>Tb5#?vPYI%E3Mt53 zRiYm;#hxC5w}DojKV~`s{Tx6fqi4!i1I&-#T@ksUGFO$k5YAHOs)WdebJ5WGvM^OMDmkyrMI-!iCi~o{XZO;Fnj$FU zra2alGDWQ6WZGYlVV{mu#SQ|cplsP@arJ13LtnJ0SFF)7Hn@-{EL@(I z9O+^y@NoSuB^=Jn(z#J;N4nO72Mbo?3I<97>oG6g1)^oH@JH!cR2QMvhv3d1r#VSv zic*$L^|naj0%V-PQ5g?J$yBzBj&lZ>J6+5mcZe_}X&)D*85Q{_29p0zIT@gO!WpI; zJiZRGT=}MGznUvztzSgikEY8e5T#ESTGB-gc9<3Qah}8?GJv+Rf{D?y#v(Eh-$|K? zDB1YVRbV;NbvdF*$Ju>UCl z5bxS}DwQs08k$M7j<5&CHEtTeQHJRF7%e0lIIh8woi7Gt&X}~tgxo}_=p-mfRtXAI zd&=xEt6@xbuTY!u>`q7bWyLZEQqwcKYSB$6+8TkuDF!flU5r8}4baCQ)A^>&rw%R0 zSgZHPcRUN@aR~T&6jlbEXXjumFlAd+!-~;B6b&LI3TLNPIQO6Ifu~5lw!H_#;5Q~c z^BXk3qqBrIfQ`n<5;}Ww>9iL)>O=MC9%$swd)(WPk&DO+={o)5sPx@55j|I$OKAJ3 zAvtd|9>vKbCkTG&60%0J0u)4mWgv;LG)@xGC+|8R6n_WjgBsFQEve|AF2OnAYw!FL zxc!MQJx{6du?&MWeS*WDJuE#auqi4yhh<*wdK0RFUnt{j0Z6nI`K8gw5-8I<%Gp@j z34pD%v3M#S%wkA7*vd*Ctw13)`Q8oy3h`i5b{UUdQ%`7h`a9&)o2S*Lx`p4_U;gz7Pz{w1_u#-sj_20X1>u_q&X0~b|3vK#tR#gI&(@`X4c ziH$Tge6{tLlOSuw&Me0UI~QcJL$hGd-(qQqyHU(`iIr>cX(m)E-uisC3Dr=aJ-TFr zrh%T;0IEPqgV;-m{c=Uo)c@tv%Tl%Tjz3ZKTD2F>Z8R3h^ml_!eP{1l&(HLE z5!`-XUE$ZS>XhCIa9HolsVMQ0#rd5hg8SXH+%gwk=St$KM@nj<%^A{fX08k|j`@ixAnr&>N1}&qGcFOEk^K83l zssVdP$-c(4gbl;M+!16U>{9%8iElXOHE zHlnbNgd=d->Ql-m%*)lt|1Tf5uvrJJs`s%{j80A6pvkK)EM- z_K{s^rBSA{iOrd=NAUn7p!XLO#V@5e^_k4vIW|>1~?Q(J>Nx8{P{&Lh5UW&ymZy!K-?V%9rm)9-| z*JXaYE;F+}^W6H(PclDUpZT>C-Xn^q0XV`9z`k0_7!F6rM5*HED+rT5z_DwAzU> zT5zHxncPY;DqApf9|RgF$HqP=l_JvEDH6Nm#MqrT7`xti*8VLNhy8?)dOc@R zm>l%^prIzSjZKkx(RXCbUtM8br{4AVP!EohN_eS-tydd0LLTI?MyX{X(?*s#pv_D= z$1%OsT|gE@zO))v)>QL|!E$tb-{= z><35=U`c|SUWsJeq6GNv9?a>fD&ZjT^pDI5`4fQ$jZb(EcA+;9%;GE)5f4F5$}*y7i?_cpK|v!bs9u> zn)-E_;q|c^;vI9kc-{vJ1E+nL_zVfN=BiA4C`2~pmBFlAYEU>1m#Z*JESZh1gXKGH zsKJE1y5Ln^pLC;n_wkr04HKsYZj`jay5MDk5W7)br^7EjT^VakO1Z2K0Xr?On}R*V zFHr`1_6;D=HINFA8;l(kroUJro=MVeI~@Lylu`q3vdF8wsCJ`` zWY0dxfhP;-jtMmN*XVe(=YULjeMa`3T#%HrqhR%&3YC3e+Rx)ZJkkD8MD3l+pKwZu zYqLKCPMl-_wV4o9fo>nB%IotdlBzb(kQOrP(AA9EwUFUMSD{LZlaFl=g)8qk9RcW8 z(FqVtgMf5j<`Apxu;e_+B?c@{4z*+wDRLK1{`n+Hq5bd=zz79mWUBQJu-C z0gg_F@Ldbmqes4V*sb1VX62*WCOmN6=#o@q^%W>i7Br$Q54Hq>wtU#r69w3LqZY(b z&-fslD)m6ak4pmngj?i&L&$&_8gH`nHvE)1Ps7jgFD6P}e6SZ0$gqmXdmq2cUgy26 zhaO&`=aeCY>KM?+(ipb`1J+#$u!j*7dtZmZ1?%Y$pj>t^5VGT~ok(;9Kk|5xlpHgY zvcf0W(*5_NEr&t3v530GchGfnPiBuQv}h;5fCqh zH$jp+sTOcBpC!XelnGq{DS8D#vV_{NVR3RIhqr$~KjIX4L_gxhMfW3AA>FSPhFGy3 z-S`rylRP4tB}UlO#F?38kCt zp$kL!g!fK#$l%GlouH&1+VzBXfdafTIGK4lsV@EO_!peQaHeGC$~p0| z`+@QE319A;L22_Prk9}@=sW(@F_me`nlvx`{UZEA{tO090o-jI>xU3SLTr+xK|J45 z<||5f4rI0J4JN4`tNBCUVfR#{li3~>$SfMp1b~XJDoAFoEI^3q>njTpE=9N$A%>V& z79lJ~Sd0*(l`BgSu12^TVFF~yVHv_QgcS%Y5N<}e8P%0|s*_MDw*X8~%fUz4 zAbIC4)_R)fEkEA1Of8f%d7_rgLlR4l@UfYa8fR&wv!7n^b8)&AzyqQ0$>{e~0sbhp zqX$zGV(z|8^H0zGZOFBmkx&DZA*(sbrWZH3p*$ zQ$Ys9BQFvR`B^gN0J2PI$$X`n8rHLy>N_HtvQi%r86@mvnYc{wk(RuzCgY$>{HT=x z0(Mk68yT-e6GLN&;O0Nn3}375R6m?MB3mwHD;pF-c}ET4RPX)&SH1Ahm1g-_RKkl&gdw?A+tmn}5%RDzr2;S9S@H_ER&$zD!46QuUBh{A z|4NqkcXQ@^A~XTVBf@!p5onY}7!X0#RhpQ=zF|rk49-VzDZjLjxQR^t8hO;84dZfe zAuUUI(w3v2^f$%o3>LLEg=q|&AG5zT&fgX*9`-={w}qWOkb3WIX`-FxgVh7a{?chw z`ukGNJwy95MW+-L+|05M+fU6ulYFS5cwY*2skF1Fx}d&1EdZM=h{?|T} zxQqNLnN6V~Vz1|&Mw8uItCTIOE$guz-diISl-g(Mq}7@wzW$&-9KE1gadci8tlC52 zoUe|i>kM+@-hr&g$ujW|af0(c7bn-Fn9WImo1xaUGFKPqqNsHWR@G5V>htC3tym6F zdZV)oJ4sadq0)<~9Wjxsa9ZNA_`2)r7hS+}~ zDRmm2lGy6zSS9MIkG>q!kh7b;v^7 z7qmVaq6aZ@jfcVb?0!Rpr}X=guB(fwhw0Vk+jnqnFJ5r)zbAL09*Yjy@Kj%X?omLu zl+&FWX?sjOGj20Ny%{dPxqG+HQdXTy={0)l3~;$*kbA7WpW!}rD%UK&^Gawgn|dHL zu2y3W`+*Dw8hk~GzhigxQPvdd;&azIA~?+y@`T_PZB)xcjhXnj zUsUqom>F)(ygsx?Pi?Nz&~f!z6&RU$Y7gIO^FSyWeE392(yD@yG!BCy-A{dw8wkQ? z_v+BpmmPrDs=O`~ue(q$6*5+wbLtTtrIyz81$!lm4^?A3HEtu}KwiE4HSKOdHI6D*a z91h4+?#P3~T73mY9Oe{<4zBTt57*Bx(UJCy>P8Rg4wG()z7}1qufTO>U5*HJ!PKuw zcZ_LAYH~3D*eegbhgUz-AW%P3iRw{&2nq~~;2Xa`+^^$&7?)zs4vT2h$$44zs2nf>~XC#k?H4>Zg^&)$*wUgl|>nf0${ z{_fv0V==tb*^v*iMGHFVMY&jr))CagLM9_3xtc8eNHQj;{3?Nc6s{y|>>cs@O2LUP zpTboCrS?PkxD)R>J2YSA)j_}X0qW*1btr&eJZM;p8$+kRI$OFUy&q{CB*=VEjjy4J zeN<$#sEzM1+M%?jaKE?WKxV8b|75z-+LfO+{_A35TaNF%6d?3q-CFt`s1a5UcWG-; zGo)FVcX_uuDqF+-9hZa7uCLsst?YprZTp5c3EIS>b@&SF(3gLwa0|?ep&OgLxg~bA zKQKC>k_GCyC;uc~h8@DSJvpdGXBb|k%x$q9#>)HjKnqh}_5f7@7a3y#8nLQ-);&Ys zfq?q|gPL7W3GpVD|BT{5lkPOUc=k5PR0(v0IiMd@6FN1F64OlrjvUjv;p{>mJABQ+ z&ot&Wy55)XKr6FiEL_JAs*TZ(vqWimYiu89oSwzhVDGGf5med963o@;fY{p?%40KvR`S6 ztALv2Ga)%kduj)?iy0T{DfRa~`g0d*&Uwa_-51gmH@mDOo(xpJ2dF7s12yUtIX^~f zx{EBW&)6P|?O?W$U4}qeD%?Zex6;~Bd!beN^?QQik1Vq z)j-ZSKh%C7&?Xrzml7FjqElYD4D;dtIY&&i4rGu@y`JM&d^IY*^D#`ffX49+RgFz< zA10?NxYo{hH)8RV5=I?ZtjdTQ9&Ta-g`oEa!w*-LBbh}LEUW6YD9Wx3D;C`)QxTbYlZw|8nHO+8Ftf-boC0)By}Pzb&y zJP`OcUX0Tclu{oqFpS^V%xndMy%(cGpw8;SmJLNdq&J}gvZRL^j+f)taRY*PK4Ki0 z+`!St3slMQ@xogOM!1dPz?VtzJ^*r%;7!x$i%h`E(M5Y`++9V*9>f1I&;ciKu!3(;Q;W zq9<09^WvF|;+=Y8j8rr=E{47v+y4}PDd&jiD;3}KfWKe$m%k^k8@|tB-G?Aeaseq# zZ;w36X@q!uMR-j8mIg7JyK~7VoY{_H8p4+kr4P8$Ii4;>9?@h4+42eOTOxmf+*#CJ zb>B^(d4SvB56J>htYI7_<>)PsSShAK%TcjF^${uMUiGSKh)=!hD685T{-Zo0XZaoj zX@Q;{Fp#SAVPyyAg!-5Yc|x_w{TEB5wT$g9lkxkS*czvm#$;CymvHU^m3wCn#CM1U z?aM*!oW|viw2gPs#`j$-VytLDn4)aIl&Q5i+1IBcbagjPZa{Hnm3&`!$+tgqw347(?j_q)LKCZ zwTCUsO&YWdj5dPz&;`Wm3uOT1N{Svm?}A%bRJrj{n1-UG9&=1=a*iqqHwyP!WYis3 zhU94c1y?<)T4OdG9SsELD=_+yQS}v`ETwx)Ccg6{oNKvLGwI!6uWv7fENWJXnnJXZ zYiw+PjA5gln-|gzx3jD9K#Iint^y8HW9u?QO8?kQsvlI-`YcVJ{CD}$xz6ayaDz?< zcCw=%M|JiZ8ZLmPal&!T9F!kNM>2C}X8-=FGkfw+Nlz?VF-kX8$DwpOPaoe7QA&7X zCq!N+72V{Si^iUtK|<+{0q1o!M@%BNKUhAy6zf+e`;Gi?ly zz>q#}a&CIVv;kkagRHPDZu@`v%96EU6nG+Tol>9J5^vXWHU( zw$n$KLZpy3e7QzlAu|tYNpr^uufTxs<0wI;9k`2jHrhT9t&?`$Y)xnpZl z>nEFPEDgB5rn#Y}Uco?DU2|J=O-)hbmZGM{`cF1AZmp}VFA|)~i%P7j%BtF$O)YhI z)f8R+e!SN-wWx=yRnU;)u&A-Q2#;43t+JYmh_0o!xvt^%x`x||&H`CcWkYq5544Je z#;>Wl@z%;)>+0)TKj~ryfP~xFQ1hOu`pTA;q765e7I_gGQ>{&@)}n^S)}oeFQ&VGe zYfW|0Cu>@*mZqAjx-E5hgJg9rMRg5ZYARdmZmq9j&h%&c1M-+?w$52y(qchfn|$ih z`dfL5rL^LY7ENtQHB`0MH8ucCDbzZr+PbZB>()x^ocb+RRb$PT604zk6X(EcZEUTq z-_&x4)m+wUILCfHolP*rn^7Qk++s;Q}NDcV}uwyCbQrkTq) zRo`02rm~3)opJx{&ENRY&+lp#do}A5-VOck*6FKo`UC6h8fuDKYATznYKyj1*40yW zC~Cd4Q7V*T-qqr`RP zeb3cr+}cE&eheU6cw_AB=N5N8ed}s^V4|i$2pDji%{7mwT2Bh(i3vg zaFskd_7J4k>CP42S=roxV!EtIHIm$_fJKqp2%^02tf{-L7R^Wtx0YKPQw^x?H&AO- zq-Amh5r#o|%3zQybt?o5hnch%RadrFURKmv*?e0~YtbE*^{E={ z=&timx$Cl`^_5Nal~pxG)paec&2_h?xU$rItoS|cceP*8Qg_?d$`uzBU#K3==K#7w zW2JsUc@*@`i7K?2RaQfa19TSB)Jib|+N>g*t$Ngi%4W;$?yTlpw^+oev920Ta7|U? zR&*#e)!Ns?Sdwn@6TiprqB=gCaxoHRu7@I!WC+scfn-w3n_gp2Z(}Eo{6W5|i`;K^ z)*Nj3ia0<4J|nGlAIF2b@_I5;h=~Hs*BsBd{*i;rs}tmzk(&%e@;DhEkMOc1C|=vt z=P6J6C~G}9-f%qZi{ZzI-0REpWFSW|2|l<8b0~}kCoxPbo+HmV39ailIvRwp*iBbU z+7t1|Sb^QFzxZSJiEgORXC*#)%M{NZM^*ri@qC$A&aw(E8piJqDu9Ga3r0P@Y|%Bs zDkola0E6gSvP{QESqCFiRZm_m|)an%cX-sF$gVHPAHluX77?Z8XTU7^XUIpV6I__eI z%|z-|6fQL?uK}*ZI!YLy9eE{psUpNOQt=|deDm-})Qz_Ww4q&^#+Xr0ugv&fxn3rM zbp(KjIwDnxtAkTVq&j))h`&sIvLt-WJ0fI36%W@e08KS3eH3$q9g~^VkxV(a%gHQq zjMb+e%JmV>HP67!tU=rH07l929WSB`xiTG}dWIj5OD(500kFr(n3?iXJfi8xcQSl# zgc{MupY(ubdS~uYOfijsW z^OBco6xFvzb#O9s`d=Xps?==#xmqx%>)B~xg)@hieQpgTy&6a^Oare8&xPmn4=-s} z6CXaRO{l_aLVT>Jj;Zy=GJcL&sUi4(1^)6nrstqQ3 zbpW11AB1ypGj!r3^+{!g6lT%AAvRk&#_8x04)9ep{vtX(l1OG#Y902e)ySV}1+di) zd-1@|J(msQ?SDBLKYvUT*T=cBXcb9@k~iT0UVv;JEX&ID^_tzv)*)D#XFS1f_#orL zgL0i|m2;nu1yIn(8e$(yMPPq4YNdyce5_*_6rCuC$Ifo%pz^W!ES7OP1m&1=v2yQ( zjt7$2Tkv0Rfy(g9fYM5OIO%*t5!C+tH2-Q;oR~w!$p{sLM31Ie#n25|)529e>QgZc zEn3A`zh)KV>Kz)YM5`F(d<*`&DyEk~uZp>rg)Mx3I%YM&y0H_dEHQtDPh^`C&KZTS zQBPzO2|1>$3#O~nbjkh?{UXLhM5oeCcfjoRrGMmN6AONbU^Nb&m5u?@+WR-eij&n(b!CaedKd_2-n z$GA(TxYB-~zu40HH|e-mNMLyO#yk!iW z$Jb_Sj%4kn>X1Mp$zP7t`_Ufb^T|vpJIHHkaQN^Rkr?mYf)R_$?yd&D;7KT z@~>jO5R!d1UUJiBB5R-y!h>hWOnQ zzrqkdJV*SIIpXtat0#V+0A6JNCH`tS?osh;C4P;8zFOkX29GHE9THEMIY-6smiW^Q z^uu$+ADJUQpH1GfXm4v2|K$?D#1Ow$;;Rht)e_%gh~FXc7%oNf-!1Xy8{&s0{z60i zkvZt|In$P9qF+8o{91{p%^OkrtCsi+4DmZ8{tJfq-E+_nOMIijevU}|lh6Y{2I_Y{ z4M_1j2mhnumrFby%M}&BR^l%;#8*rFRR;b$B>oO09+m!Xi9Z7kZdClR#K&RhQSnD4 z{v3mR`P7i(XR@#5bHuNmBfeVV-wPg5^6i)-e)k;d56=;QWRCd!lR5iV48ldpw_M_j z4f3y*_+J>}t0n#wL;38G_>G46-4egkkp8g5*BIiDNPNOjKk^Geh+mN*e!0Z|95_+> zSu61)2Ks7=FEh~Zm?M6-#J`BmG(P@G)qf95dBXh*(%O)jb{^y8aEAeX${IOY!f7cu0 zcgzvLdye>FiO&V?PyD+hbHwMrUdi`Bu>J}Ca*2N>*nW%st(EwtL3$)h_E#L;i*(zRD1PMB@KCD4+I!PX%NAO#GKi{As|6svm15{-=icYKgzi5Whp> zzm0aR;lACB6aW?4t)iuKyB$J0_}q@hHFLBop5iU|ClL)BkWfe3qn=BYrmsUMG-zc*3t$;>Tv;N9jBucwY&Yo7mkG65k(8N8%4ld_#~P zX;b>gCH^no6qb|X&v+yL;8%_IBbX10zg*&fYDj;h#Fq!ll@k5X)mL9uRQ#c9%U2X# zymHmb3yUr+DOp|ezLJZJim%7s%VcG%g1_hDOIBFc%9c-VZLPc&VQaGrYxPreO?~A` z+GcL8o*dumgNuy?w)`4JGu?$@j%A zcUCs7tF!O89#N};@Ukr`;=*8rz{3RBtfr4J8nC}!QC=LRtae%Xl;K!M2}!i6uA#c7 zjZH%eNC{eLqE`7{H7jwIODu_Aw6(4QnGb1&;nh)aXwd}srsK<+nBdxyP|eXXT>OzV z;o9a}O+O_TQbfUruilK(I?#qeaX6L|Fmd{oBx^TnbPs)g;Y{3|< zo4pcghOmJ=%t{Fop<#&#E5lbcBMANRVR|KX1ffKPDBfFzPaJC2T~kSwqU?r}O=UN1 z3bcM2rJ8EptSED1TvO&$?Xqjog!odtt*UBM4L*ixYTbm63Eyb>I}fLFUo1M84f`g& zqdmMHg-uNfecMuBvlXuw@oQys<<=T}#Zq<+`Zu4U`4l{l6awT*%?qbYdQ~`M+v|=E?n~VqOPv=He*+Q9J=fK@W z98e$$pH+lY3P!sL24e#0Dsu@Z=)m2S98e&MK)!2g;WNOvt(EwOWou0XTseFeS+f$} z;d|h(RNZc^ysf!0)kJ>dtNbm(7=h+-gTI6TWU9b=3Ga{KKl{C&&_th%p#M7$oleI@ zPje&m^YVWb@0w1BCi)7d_S4h7I+{+0Ci=}0^n(kauZ^Jp&I0Il*?RN;_Y0uc3yWU* zCl)~830(Sl>FMKWtv4N-^w-VQetNpWLDT8bMBf`hPakn=IvtwmY3+-CUipXcuIY4W zqVEST{k-(Uc-M3~G|}&2YCrwR0_X=K=tmboPqs=wul&#AUCXUQll((OjGveO2YApbYE zBj^u#=;q4*Oa%QuE`XlTuK~Wd{GML`eF5g)=;x*XG2XS@IyC98FoOOk3!q;bLH|z+ zpr^Ti`g!F)jCU=!4o&hGN6`O#0rVvi^wbAyzB)AVUmZbzWC8Sv2>M?xfSzvfq@P!R zzrwqgTZbn3%OdE1y#V@(2>Qtd&~J{QpIQKYZ3O*4FMz%&g8r2S(6>dmE8y%YLr!RuO5HL-rLlb>}1pQkVK))w~e(3_}2O{WCUjY4J z1pV6=KtB{gf5rmnMLS@KtCQqf7Sx%CnD&VEr5P9g8u9U&`(FuziR>X zGZFMF7eH@e4TFB(_Pb;O^aT<0s}?|C7(su<0_bV&F)06c0nqhcho<^p6hTklI%ql_ zn&^uo=;`EkO{YT>eMtoUhZjJ0$acnHEMZek;)YFWi=IpF!j>+q=S!%_vd&O=C;vaLX%mNi6^efTx0!1-I`JgJ9w zA&BB%@Fm4xkE34#-Uj>+@?RyeApa6lR>UvJ>k{Cw{zPAzMALst10)QfSsygeKPLP) z&q3d6pnvOQitw#-&^IDJm?t8c5&h|MBK=k1e^7t-0Tz}2^M(KC5bym3^Z#i?M)5EF zYgK+FLQMQ`#{VFHViU!GNchtpcJD99pUgXoe?s_s^S=?eLH<7jEQAIU zX($Tyw<3c7#}F0d|9ilq_+L0r{@yX6mw!_P|IHEn-w5VW{FA~z=}i>RLH(a^pzjs> zfjQ{k4f?3^>yD7WDnfqh6Qbl#3@XOhYvcO`<-gNF|M7X!|Am46{&~_rF7!dUhJ^m8 z>~+ z$irLzKaNy_{C{TPKQ^RT(jGnUFUX(HAdiy&r6EN%7ya9iU=;nadD35Opg(E9;=fV_ z&flQ?>kaf53;p>HrFsa`R~zUz3;l(2(03TNZ3F%EJn0V^ z=$9Q(84n!58EU_N2>Ph{GZ10FDI^)R-~Vmk|JTC*f;sem8XT7>{ryPj=^GO75A1xu zH-J7${t1ykDcCO|Y{UPc{1+Pd*FUWY=aT=!2Kont{v6@2gP{Dk8t4xQJ$<9%{RQdo zGSFMYii*Br@&1DJpEb~5CiHX3|A>Kpv(V2~fBzQrQRP?s6|xGPcq_tF`H?LL%kNnO z|DE&XPv2Ta@vn&BzdeHgFAV$#=gI%42L9a<{L>Nq|J}g_ZaxE{%Y9%J`=(J1q1(QgnyArMzas~zlRL` zJB9yJp``rNSTvab83X@c(Pj<&ey#%NZ!rI_82I-^@ZW`0g8bjPIJ*9ijw+TTbL9VY z&_jgKZyzWfAU3w{HqN7>%XrE?-hC- z1o?l=z`s});Pwb1@&8Nw5Ats}@c-9&^1su-e=LIkgAx398TfY}RD#p|j`tVLf3Jam z+t-xg^a?TM|BLt^%>P~k|Ks!IKVaZr@V8<9Uy9)Wj|Tot|4Ruzm;H?y`1c9_X_X9* zU%wo||2GEy>uIwSesl4kGVt&Iy2`(o|5uP+Q2!^N6kY#|f5_~evn148c>W|0^ilP{ z?IFeA+x~qug8#V&{`JEDdd*nEp#7a=;NKg;|7#KaOAY*=oG1UJf&ZQe{$G#a-)P`p zIHoc@SN=b4;6D_>|KSM!e{$~vQ6Z7Q%ih+OafXcs@{}U1Xmp~xG4CcRcp8QV*eU$ypMDVBm)4}|oW8gn1 z{9g|m?@#5*g$lv`<#VINHRDS#MAL#tk=~fu{PYQpHFJ!E1 z{Y>E}4D{1NACx!vUJv>x{f~+KCBls4AI5(zkCwm7z~6d75o&x%CM5q~8R!dzUh~oP zLHWM``Y8FWZ-w zn}vRLfW9d3{&R!;Z6bfK;8XdNOAK`W>2moG1ONVcmf!CU{0sgrTz=$|2Kg_6f(SF% z{tOC#G;h9NP=6~7^h5L1-*V7L*pprghBiJt$}`<&+mne9&Z%I z3o*3Zd)r5aBSX|UEhLoayvB(h{@m(B+4mc)hBYrXKum=3+YRtD4Dfdt;O{iR&osb`4DhoI@MQ-0*#`J>1N2Kg#rEn13Y1XUul3}Wq@C8fUh;cZ3Fy+2Ka{z@T390 z&H(?g0e+1EzTN;YHNdYmz&~PumxbUNbiK>08y)zkP}rNl5#|m+==g3h+6B z(|3x?tc~)f?tGw^Pci&s4qWr4{n}@F{8i2OON_rcgiqhGE%VGjXv=t-;Z+X)fIR(@ z;WZ9ix0rb`N@q(5ekQ|j3&Af2ob<31dZphdB>bqrKMg+gqdOev*DmlMh)Y9vH_)$- z(|6}9&Q@TH_T8SvE0PMJ_3#}@=M-^uY)R)QoKC$^lWgku8-{NU!C#k8`E3Zn-vKz~ zt4v%bZF^S;e6zr{r?N@l%>u8I6lr`z={zs+7J)wm_%f@};j4R&CmG)4z;zEa#_&%# zaNQI9g5k{$T;u<5hHGx>js-$mf^t}9x$`GFowFI9a?+7um~{oiWpIaB-IJ9uyv@P? zf;@ek;deQ3jZgc(NDm(tSCj5cpx>Vh{P9!OJKdE)zi)Cnf2LmW_Z)e8n&IsZT=xXD zziFA(;lOnd^lQM0Z<`b#-GxBElTK3b$KRyh=?(T%4B*<993njQGX8c4q|5P(3{QvP-(Yx`1J^zJ5X0{Y z!GFZ?j04x{zr^rt2>vp|dqVI$)LYW$#v&C(cNfs_GQgwqb)^Bm&H%qw(%-yXrK>%> zR)Kd5{1+Ij{&pU9v-}IA`{_*ovRGDDhBk=W7P#V5V z;139#?k1q$*8z{x|2GZrLBN-I=HW|JGS-Lz{|5&6KN{eNCH;h?tJD9D0snUf_`e(A zi_z{!<@falIIZ7C;h%1R7a8F1Ho#W`PW9q0ah2>O*7@NX3S8F6v{L7`h)4fvk` ze3@sS^RVFWlynYCLs%#9zXbd&&%BoIH@^yalpekz>0BZ%v`%NA!21L6gMcsNoxY0U zy~6h=fS<)H_zIx;{*v(@6fDcq_^&Yhiw<1(Otc<$mi3$i*Xg_s@MYGQ9Jt26fZ<b{OjduC&RxUf`6Ie4~O8R zhV*|7IN8-HGK8VKCg>MKKe~)}3aa-VDzKITPWb;Pp#U2HT7kcGm4efq6ZGo>JStzG z7W{3t!lOGV==Zq5o7buLrIOCi1^(%46#Pdju%-czO8<9&FZ0Yl>-~%GJ~bNuJ%BIs z%uDP2hLsF|Ot@K=-UoOu;M`BG_sjF3z*ou;<}{&v81N`LA2q=LUeZZOIzN?kMhy5r z6#REys}OG!{ND-uQv#>EDCoEJ4NCqi%GEpFK|#M#f%jFYcd|?R-41w^{EdQtQkCGn zS%qH*e3@r{evblM|F__OFrxr;hXei2exs7-(X4u>yBp|NCh%`b0(2(>{kjF-`*rnB zcQMfK2LiuVsyyBCK)+Ms(elR)@HYc~mS-M*sY=E=o8iOq=B9Z8!$%yr#$RJd|60Z$ za`0iU{JX_~|0%|Q+QCP+#lO!Q@COqUZ-#2$ncd_O-r z-2u9(YE#P{Rb~Fe#qkb*)T916dw zs=l(N<<+J3K9yQcQ%fDrnMX!nopk#8kxiR!Yirwt`!!k`8!GGTT0gnzjuHre?R&4T ztg5Y9RZ`!a+EiUrk0ajgvTHYNx}>(IvU*di9Ym>XXsKy#4WT#(%^U7C30`DE$E`cZ zaMN8P>O}L4svD8EdzZxqT!4XCC-vY(C*HX5?Ix7&2EKrnuQVZ^`ZRS<6rJzyzB;#= zxFFLNCLWCNFyf}OYSpbZn_6m{Qw_J*G}v`qg|2napXbX@0_Wa?*hL7@ zs}w@lq=3kOLxg(`3Pq`7*uAh-m(Z00bj=Edt)FbFDZA!UdfbZpOX`sW7onk9*C{{3 z#X5!h%3EvdQRUp|vO1)2;rj>ymR)r_Uu95vYaJUsbMRsVH+V-2?(7NN&Y~fnds#Hd zy^%#jJoc+DKEYiqI?la?g*4;bh~d9_MI*bHuDEIp-s7Qh-8)u*D^?!Hbz&~8ZY0a7 zYaruc%L-n}LTbS!EuKqPL{UD7*IF*Bs;sX{)zf7^&9#lnTs_7VX6YrKmpw;t;Ii}F z0ORJKZ}ix7b9H^0w|=knS9iXW1vIXlLgs}CiEghnjq^@-w;&DYUE!}{ixdlVZ_k*$ zqp`MD*4H;ySKZf&ji21qM5&bpy3P=mvUImvI0$^1fvQzCp}wlF z3~la)i};^ve02vAv{A0uxZOI!%KWWC1cFL)HMIbAKa*WoROJn^dUP60}Y0K0=Kd(rT@#ueY`|p5!OHIw~R$WU=Q)N|+ zm1E!Q-T65qO_DlImK=n6a_^T)D)ypkx6VV zEc@(t_vU^%9TBmr*$z?J`nxK-j^49-^ig8! z20cKk^wS=76)HPb0Twap$UQqnA2o!VVq9f5uTIsecXBT+%p2phwzcY!2KVniwwod<(8eajSv@SZbq!6Ri z+?ij_T0&DpWj|)~k$Hq%$4!uqt2!k1V`q)z2FCu1Q+K)UHqa&ON|IIJrU1$vHM*oY zFWZ^WRfMlGojI5U2?k4+mt)5D6gQ{ZUzF6{f5 z3TaU8Ub7&%edCMYK6bbJ3V$XgSJ6~`QrYFY??LQ?j0g2KF_iSnh9owBd6`T4HI9a6oPmAacO8e3c}M^J&gXt^VBU;7uh-D?j^#3g9AG$|{7u$iDFM0Cif z+E?Y&p4w?IB73^yHnmY#)6$mc^Gtbc^tyZP{xw?C^?8@@SHb1y&9VrWpS_xXWPslU z{u=ZHYPkT@h<=TG8E>ft5l;P(0Jk}RMZW?*F9h^QxaXm=h@N%m0xosvCL*^a0{nV#)?qC; z{SVLwa1xjPSpj}FIQ>_Gzv;ZJZuQ-BKv~3}yfwHy^)vn5;F3>2_mX8E_#5uC=_|nL zf3$mUD2pH0{{NA1#;q&C+#;Oy=>;x7yRo==;H<-RaQW?F({BW)e-r(|fW)PLXK?zD z1*iWma0xZoy=2MO=jY;2J~qG~4)7!NdA?tti@?Qym;`mplmLGrz`qReUEr+4?xUhO zl8-#ywmJ{jUu^REByjfoT5#6?dvIyj=qOxT^P{5`@#i?42+n*~1o%d9=2Ouq_UAY` zQh(J~;z~Z(MY6Q>0(=ZO>-LcTYOwf_7akWGn*Uwu|9g*H-1j~Hpz0emj(wQ_7;xtQ zcz~xjiG4(G`DA_(DAHZiQIP)I~&i4Ka zPJO4=u|IilaQZwA&VE?~&ipIDS%;==;<)th6X0V5{NVt9N%_GpOnvwIM9(Knq2KMe z_2VY+Z^5rV#eHy#`K(o+66JFK`Nh4==N{#UI3{uB@2t!6S-|Jd0iVCZ=Wmfk>feJ- zjXp@+U){^%o~&HrQr|7W`@u)9Mdovva%*p;=06w4272~ajniDxZjrhjpx*NNQ00D|+XnQ#0(=mBSm!I1Te}XDKyJAT zde(Uo_!g(L{<=HBX9f7Y054Z=`83mfmO;-tS9AR}`Wa#NX!_!-Ro`#b=Klrs^#9(|pRfKqp{IZQwo!kHjOW8~%59uj-6liNxHCQdK#e;Kdd7VdoN;Tm zt2%zHy@x6nTgE-v(_gG{PlKLu$AUBNe9y<)y99d1UG3>F*SMcS&$!2(UVWV}Q|{M! zB=n4Xlcyh{ai>7fxX*&Ky_-EBtMg9i8Ml7>s{K-+aT_X^kBr+Aye6(AIpDRxhk*0^ znWx<9WAnaU4gG=enGDYJ=Y0V_JHQtN`1|0s5%-u5asM6!o&(PM-yY!42Kbr)AK0;K zzu36FOu6(6`>_O^{c;<4I`W?ZF5g-0di0KR>zDg=JgkJCaqD!7>vJ%CjsZUee5!Ku zpP~K_LeKlUHLlK?*yF3F#9Pgid3wd+o2=ovTP(_5Vjp=aDA zIOERre16jYngu=M{_5#}QGK0mal06|zjA9=t(uW;Xh1*7(;uw*TLSv0z}c=>z9*PR=rr)J!Fwt9o!Tb)$K;DTN0dgdkUO&TMEv)tp;b^wt};6^?Ih#Pvy_LwF76}?geMv-UDadR)e!{ zNA!x~S{+{3Iy6&$fZI&}Apu?lKHu$Q{aD#MZkL>A=BfWKaGsYk&W`nr+ZDW3jo80= zpI9$HGqJc&f%Cq7GdT6fo)h~}f9bg~=l78j0lonIWaRTHxYVIS>u|z(u|MOU0ZyO3 z;MDi+8~ZTN!2$jT_$kPVz55G9tF8#R9y^Oa8{|x+k zaQZI+m%o{4J}rjE{;XT)0Phjt#o(>s-{_LqU-D^lVD!0TfX@!_r5-W(N4X;PhDqPM`GwUi*r;KJ;l7 z;2pr}KQ1@+5#CS7$wL92HoU6d>eDd5dj$A7dDZ(21!ueR!I}RUaE_n3;M8vfr~h_v z>i-H(|E^b7&3~BI?N*Q5`Qa7ib{%utelz{gu%EZKV7Fx0(Ib1pIW=?NabJ5O=KSFMp>>mWj~Qe=<1zvkId9 zBpne+Qh$*T(@~S{mo` zid(hgbTRm;7`GiJ#`-hCdw@3r9~0me%B}vdYyG!C&v8CvQXH3c8yVo&f>)qjcL(?^ zaDLza8JzXJ`nPdDGOj+-{O=F&?>xRv_1nQeL!K91SJmJ2mw{8i5S)2#0e=hrZLW{~ z*}p~L(k_cTDZuXoKMVc-7&ynnB5?Y@s@%rIds?4z=s6xL!0G?k$f!+viJPXC9%*^hGq{KWu&1DyT%d4O*P zXaDxRInJN`J21dYZ;AD)#st^Spg5_;K*>65##7 zS?6H^o&c{vyKV{aY2d8qW^mT?fZO7Bkslf0ji$tU*0~6r<9ro3>$V=8`y)! zT>8uYUgw+2ZT#DHa2fO*|DS`i{@(@oF9BZX_Bc=W%ZUNr8Jztx37pR><|vovlhWR6 zbbOZH5yiFkW+}f(`2lV-+xsH8_zYA1!FNVJq9^YX;A50q+}`Rl0eZ&$2%PQOa#tLe zJnQc2`IX>3aC}V#?+*SUIQ`q-6Z=bhzt#Mc;M6Y;@E^eGGk0q2zs0TE`R504`ggfE z)^CG;066s@2Ke*$#Xf1M!wbr-zou(@{|G&QuHE_m*oSdv2Kc4`Kk9+%ebxl{jsQRJ zq1dM<+O-Ir{oeNBSYO|*TK_&5;G4kNUpoRkXIkvf`fLdBY16CMe;D9z&!}GiMS#Ek zNTj#^mB0Hd%L?WGd0-1T^S^m!w4dn78$Mb+zdXRlKOXB@&l>_f8Q>2F_^be*7vL`k z_*((KGQf8R_(@Mx-`=bMKO?|z2WS1~26)F=aolZg)y^}0!ReD1;4g#s#_^T?q%(Dk zjE5EOW&Y>R78-H(?~nk`3-I3rcyWL)0B4@t!I|f*IdPt>!_ok6@Jy`FMjb8$|4%2e zI^==V|8?*#@Yw{;x@DKearyI7|=i}mzBF2K7js9t}5fR}-D+}2(g`|#(O*Mf6gT@U`f+ttSTZQ!ii)Bs-w z-WC168k|1s13bz;n!~of`!HR{L%MEo)~Wl|$CcOf_#EYpJU(A}hR0t~p6&5JDbMk^ z{JnWuE{NXbmMfLdN6LqK{1fHFJ-$JC9py5fUvw{P&n3#`JiOSwtY5~1&j;@XPCfnq z-D%7}#5=%eDg5pCyrjL7(}Ue3;qaQ#yYc6hCp=!R{2GscrM%SRyOrDTNtyqRJ)(F? zPydMWdp*8L`E-vjS3b+*mCEh+l4`hc(%weBqPXRrzLWBm9#1O&#N&0&j(j$FypMAG zo@a6A-X7^o_5RNIkIHZK_+fWM`lQECR4(&R$YMU-l*_Rui?nr#d)atvD9|l3KHqjP z8$V|Xbc^UebT89S6zCS=tK7>t$JNK+`EFen(ewPNUkg(F1Gmk54i&LmBp;6FmMI$f zeC^i%C-kgO6Xf$}t2Q=fl@z8TuP9d*b8{|NkIaE_DPz&RfNQUBb4 z&xznaxOE#pA>J#XZwfBQR5v}&=YaG4ybxUU{Z#)JIDekb@qe^Ci0ybh6?#6`IuHCO zw{Gnk1kQ0d2An>;?i}UfnokmX`utza^H|iAXiELUoZYYwD(xlAp^&CvwspF2p^vJMuYSB zt9jg=gnT-vUatE*@A0_f@7r7s|I^@eEx4R-zt!_C&tq+%=Xsm;8Rayx$av$pDhB6s z{x&Ifq-VR@DwlTgc<%{4^S=mO^53cX^EhJucRV zx-Dpv0A2XKb)!M|o}ufaU$5)(mZ|H)Ki746v*Sqk7vRk29NDM~^QkcC-kHx=;2F9u z7JmX~J{!Q9&!^zbCnu24x!}x)JVQN2D)*DNFrNnSVLtW2Z9hSBj96Wm=XucEc0sHs zea;W~^n(xep}75_XWRkc^a;hazv(4fwre1K=)cQM-8<|5E_jBni^UFb)?a?l#Fi{w z5!4XewhIc?;X>${C&v%lH7KC}(So^mwyPXGL)XP(Cpg+%9{^AUa^c#f_M*Goi-Bs|_;KPSO!>$<#^f$Jl}6e$N6 z{~PslC3w27%UinET=J;{o(V47Y_VfU*dYepdjk5p;7M@%t|yzzzz>7I9Q<(bN^t9I z*_^ILw0hdP!~X7wal20EczT<6I01eH;wHgm)#ev21Gh0CyOo1CfKMg(QQ-D>tu0TR zUpQ0mcZ?606}RMg+~yZfc--a}PJ%a#EK>iLfgcTC4sOSeY_0@9273GdZIYgSN07~# zwIY%5!H9@QXQm8kK6phWgfTrh08r|^9xskw?N!RJQKVOycKvk_{rdv;H|;a_2eb_OWlTLL>n_bZu9@ z{J&)$xA}j|J#O>QR(jm#nN8P|zQncfn37K>xWu*jWOF=j^TQ@QZu7$?!P|+kE@j}S z8+7mG;C2m^&6VKx9bdT23oDDfbxf^A|73!90?z^O44weDXLqtW3ElLDxajR#n64LH*)006dPe$8k54{3;yE6-d0G?TXGYT0ze#ZM zzoT!ou?+ky=of-Zo_3Bd2k#F32jHT&F;@wm4gEH7(f8JE>3Wl4br{w!+K}mSo7XkR z<2Fxg!s9j{YtrL3A8VP%Z9dj=kK25#l^(ZwSJU-o$nr0m5anMVT-tlFwl@o0yF9gJ zD7f_3f=SU1dEnwRKEi3G;G)mEA=>aeaM3@k`dQ$jPrEtV@CR_wzZl`P*TF^q`&*+8 p?}3Ycx#~B7i{9p$P1Bn~tB=hyo8fVrH#XbjHvjB!kK6pS{|)Yg*nR*2 literal 0 HcmV?d00001 diff --git a/classify.sh b/classify.sh new file mode 100755 index 0000000..9f86ca0 --- /dev/null +++ b/classify.sh @@ -0,0 +1,13 @@ +echo "Enter text to be classified, hit return to run classification." +read text + +if [ `echo "$text" | sed -r 's/ +/ /g' | bin/stupidfilter data/c_rbf` = "1.000000" ] + then + echo "Text is not likely to be stupid." +fi + +if [ `echo "$text" | sed -r 's/ +/ /g' | bin/stupidfilter data/c_rbf` = "0.000000" ] + then + echo "Text is likely to be stupid." +fi + diff --git a/data/c_rbf.mod b/data/c_rbf.mod new file mode 100644 index 0000000..dccda55 --- /dev/null +++ b/data/c_rbf.mod @@ -0,0 +1,12023 @@ +svm_type c_svc +kernel_type rbf +gamma 0.111 +nr_class 2 +total_sv 12014 +rho 8.52292 +label 1 0 +nr_sv 6007 6007 +SV +1 1:0.739726 2:0.054795 3:0.027397 5:0.024361517 6:0.01960802 7:0.017039762 +1 1:0.775194 2:0.023256 3:0.031008 5:0.019068776 6:0.0076740077 7:0.018481756 +1 1:0.769585 2:0.011521 3:0.029954 7:0.016620768 +1 1:0.786624 2:0.015924 3:0.022293 5:0.01651186 6:0.0066450066 7:0.017535341 +1 1:0.769231 2:0.014514 3:0.059507 5:0.029042983 7:0.020443201 +1 1:0.681081 2:0.081081 3:0.048649 5:0.014171127 6:0.045627046 7:0.017336848 +1 1:0.779685 2:0.007153 3:0.032904 5:0.019434049 7:0.01673122 +1 1:0.765625 2:0.015625 3:0.054688 7:0.017625762 +1 1:0.755102 2:0.013605 3:0.027211 5:0.037369731 7:0.016550524 +1 1:0.691824 2:0.012579 3:0.113208 5:0.035498636 7:0.016106768 +1 1:0.768627 2:0.017647 3:0.021569 5:0.01669077 7:0.016021043 +1 1:0.777108 2:0.016064 3:0.01004 5:0.011882576 7:0.015366341 +1 1:0.762295 2:0.02459 3:0.045082 5:0.02900571 7:0.019267293 +1 1:0.76259 2:0.014388 3:0.035971 5:0.037653005 7:0.01737147 +1 1:0.727273 2:0.024793 3:0.090909 5:0.019359504 7:0.019401329 +1 1:0.781609 2:0.022989 3:0.057471 5:0.034454997 7:0.022743201 +1 1:0.759804 2:0.019608 3:0.029412 5:0.027708616 7:0.016080823 +1 1:0.734417 2:0.02168 3:0.04065 5:0.036184456 7:0.013616232 +1 1:0.77 2:0.02 3:0.035 5:0.025181519 7:0.01804878 +1 1:0.765957 2:0.007092 3:0.035461 5:0.022386057 7:0.014400622 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.7833 2:0.007952 3:0.021869 5:0.017085862 7:0.015868207 +1 1:0.724311 2:0.027569 3:0.055138 5:0.012732396 7:0.017895348 +1 1:0.767932 2:0.008439 3:0.054852 5:0.019284958 7:0.019887823 +1 1:0.75 2:0.047297 3:0.027027 5:0.01840532 6:0.02963103 7:0.01668589 +1 1:0.750742 2:0.014837 3:0.040059 5:0.029684076 7:0.015904323 +1 1:0.793388 2:0.008264 3:0.049587 5:0.01822641 7:0.020610762 +1 1:0.726667 2:0.033333 3:0.053333 5:0.072547821 7:0.016707317 +1 1:0.769802 2:0.012376 3:0.049505 5:0.01241185 6:0.004995005 7:0.018126659 +1 1:0.789116 2:0.006803 3:0.040816 7:0.021528122 +1 1:0.618367 2:0.028571 3:0.116327 5:0.060426699 7:0.016886512 +1 1:0.721519 2:0.046414 3:0.033755 5:0.025636247 6:0.023217023 7:0.014960896 +1 1:0.72093 2:0.034884 3:0.075581 5:0.053918865 7:0.019604366 +1 1:0.766055 2:0.022936 3:0.022936 5:0.013052942 7:0.015971134 +1 1:0.77439 2:0.021341 3:0.039634 5:0.014849492 7:0.018664488 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.742515 2:0.023952 3:0.047904 5:0.037459186 7:0.014531915 +1 1:0.785965 2:0.003509 3:0.021053 5:0.0099667526 7:0.016003421 +1 1:0.725888 2:0.071066 3:0.055838 5:0.044906296 6:0.036144036 7:0.020552183 +1 1:0.730061 2:0.04908 3:0.03681 5:0.057899602 6:0.011649012 7:0.019265299 +1 1:0.727811 2:0.017751 3:0.059172 5:0.033277176 7:0.016163945 +1 1:0.777778 2:0.015152 3:0.040404 5:0.021327509 7:0.021526238 +1 1:0.767857 2:0.010714 3:0.089286 5:0.0077080196 7:0.0421385 +1 1:0.738693 2:0.027638 3:0.070352 5:0.062223249 7:0.018353963 +1 1:0.733871 2:0.043011 3:0.053763 5:0.069670359 7:0.017538683 +1 1:0.702602 2:0.048327 3:0.081784 5:0.085794582 7:0.017725994 +1 1:0.756098 2:0.014634 3:0.043902 5:0.02464479 7:0.017995244 +1 1:0.707665 2:0.040998 3:0.044563 5:0.050370492 6:0.0022530023 7:0.014477628 +1 1:0.788066 2:0.006173 3:0.024691 5:0.016370223 7:0.017138415 +1 1:0.788419 2:0.008909 3:0.033408 5:0.010540754 7:0.019202561 +1 1:0.794118 2:0.003268 3:0.022876 5:0.0090051138 7:0.01649928 +1 1:0.761092 2:0.020478 3:0.030717 5:0.030056804 7:0.015483226 +1 1:0.744939 2:0.040486 3:0.044534 5:0.042356835 7:0.01737928 +1 1:0.740586 2:0.029289 3:0.033473 5:0.013030579 7:0.014593329 +1 1:0.767442 2:0.027907 3:0.051163 5:0.035416636 6:0.0071250071 7:0.02387975 +1 1:0.797297 2:0.004505 3:0.027027 5:0.011450211 7:0.017880683 +1 1:0.771982 2:0.019374 3:0.023845 5:0.023630969 6:0.0015840016 7:0.017202207 +1 1:0.774725 2:0.016484 3:0.032967 5:0.030183531 7:0.016550524 +1 1:0.744597 2:0.086444 3:0.043222 5:0.010667482 6:0.037215037 7:0.025109012 +1 1:0.621262 2:0.10299 3:0.083056 5:0.16218896 7:0.025139774 +1 1:0.73913 2:0.019324 3:0.033816 7:0.013697421 +1 1:0.774674 2:0.022346 3:0.042831 5:0.021409509 6:0.0068940069 7:0.019768817 +1 1:0.781705 2:0.014553 3:0.04158 5:0.018040046 7:0.020954817 +1 1:0.709184 2:0.040816 3:0.05102 5:0.078966201 6:0.012711013 7:0.014683921 +1 1:0.75 2:0.02381 3:0.035714 5:0.047030847 7:0.015340689 +1 1:0.784615 2:0.015385 3:0.107692 5:0.011062574 7:0.031613512 +1 1:0.761062 2:0.013274 3:0.066372 5:0.020939871 7:0.019210012 +1 1:0.754448 2:0.02847 3:0.046263 5:0.051824132 7:0.018726671 +1 1:0.805405 2:0.005405 3:0.040541 5:0.01130112 7:0.021736982 +1 1:0.794595 2:0.013514 3:0.043243 5:0.026582977 7:0.023104811 +1 1:0.808333 2:0.008333 3:0.058333 5:0.01309767 7:0.028912604 +1 1:0.706294 2:0.034965 3:0.055944 4:0.0036900369 5:0.070102724 7:0.01360225 +1 1:0.774799 2:0.016086 3:0.040214 5:0.027060069 6:0.0027210027 7:0.01801478 +1 1:0.762712 2:0.025424 3:0.072034 5:0.021238054 7:0.036275317 +1 1:0.694779 2:0.076305 3:0.048193 5:0.0098772979 6:0.055629056 7:0.018488591 +1 1:0.71345 2:0.040936 3:0.046784 5:0.079137656 7:0.016795037 +1 1:0.760234 2:0.01462 3:0.046784 5:0.01634786 7:0.016260165 +1 1:0.772834 2:0.018735 3:0.044496 5:0.036259001 7:0.020548921 +1 1:0.775591 2:0.027559 3:0.023622 5:0.019135867 6:0.011553012 7:0.018700787 +1 1:0.755 2:0.035 3:0.03 5:0.032785174 6:0.010554011 7:0.017332317 +1 1:0.782895 2:0.006579 3:0.026316 5:0.019210413 7:0.015564829 +1 1:0.756757 2:0.040541 3:0.031532 5:0.032889538 6:0.013236013 7:0.018677213 +1 1:0.771429 2:0.012987 3:0.041558 5:0.032129173 7:0.018371872 +1 1:0.781609 2:0.005747 3:0.037356 5:0.014968765 7:0.01745164 +1 1:0.75 2:0.033654 3:0.043269 5:0.03483518 7:0.01882036 +1 1:0.729107 2:0.033141 3:0.033141 5:0.036273911 7:0.014444366 +1 1:0.776398 2:0.006211 3:0.037267 5:0.017257317 7:0.016361159 +1 1:0.741259 2:0.013986 3:0.027972 5:0.022520239 7:0.014113933 +1 1:0.7934 2:0.004304 3:0.022956 5:0.0075440192 7:0.017295378 +1 1:0.704434 2:0.049261 3:0.054187 5:0.077885289 7:0.020124957 +1 1:0.737705 2:0.02459 3:0.07377 5:0.018360592 7:0.020291884 +1 1:0.774566 2:0.009634 3:0.042389 5:0.025032427 7:0.017493774 +1 1:0.732558 2:0.02907 3:0.034884 5:0.052867771 7:0.014995744 +1 1:0.77665 2:0.025381 3:0.035533 5:0.011241483 6:0.0090510091 7:0.020521232 +1 1:0.75 2:0.02459 3:0.057377 5:0.028595709 6:0.0038370038 7:0.019542183 +1 1:0.761905 2:0.015873 3:0.047619 5:0.043087382 7:0.016744098 +1 1:0.726636 2:0.025701 3:0.07243 5:0.03508118 7:0.018164463 +1 1:0.684615 2:0.046154 3:0.092308 5:0.1090901 7:0.019230768 +1 1:0.706161 2:0.056872 3:0.085308 5:0.020231688 6:0.0027150027 7:0.063894348 +1 1:0.77619 2:0.004762 3:0.028571 5:0.013410761 7:0.016144018 +1 1:0.772074 2:0.014374 3:0.051335 5:0.021320054 7:0.02188611 +1 1:0.743083 2:0.035573 3:0.031621 5:0.040187557 6:0.0080850081 7:0.017882963 +1 1:0.755294 2:0.014118 3:0.035294 5:0.045182115 7:0.014203732 +1 1:0.681909 2:0.033797 3:0.049702 4:0.0036900369 5:0.042252471 6:0.0072870073 7:0.014971146 +1 1:0.718954 2:0.058824 3:0.039216 5:0.019068776 6:0.030690031 7:0.015582659 +1 1:0.691489 2:0.053191 3:0.12766 5:0.01616895 6:0.0032550033 7:0.089711988 +1 1:0.725962 2:0.009615 3:0.072115 5:0.012404395 7:0.017618433 +1 1:0.773756 2:0.0181 3:0.040724 5:0.022728967 7:0.018099549 +1 1:0.756654 2:0.011407 3:0.041825 5:0.02823789 7:0.018362238 +1 1:0.770833 2:0.013021 3:0.036458 5:0.034671179 7:0.017069994 +1 1:0.742857 2:0.028571 3:0.042857 5:0.015527858 6:0.012501013 7:0.020905921 +1 1:0.714286 2:0.014778 3:0.073892 5:0.047992486 7:0.01399736 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.707101 2:0.053254 3:0.042899 5:0.069223085 6:0.006966007 7:0.015541567 +1 1:0.766129 2:0.024194 3:0.104839 5:0.0038018279 7:0.096479146 +1 1:0.776923 2:0.015385 3:0.030769 5:0.021424418 7:0.016322701 +1 1:0.770492 2:0.021858 3:0.027322 5:0.015304221 6:0.012321012 7:0.016226841 +1 1:0.782765 2:0.014363 3:0.025135 5:0.0177195 6:0.0017820018 7:0.018424049 +1 1:0.784574 2:0.010638 3:0.026596 5:0.020276415 7:0.017887262 +1 1:0.754412 2:0.019118 3:0.055882 5:0.027969526 7:0.019117646 +1 1:0.771186 2:0.021186 3:0.055085 5:0.038033188 7:0.020256305 +1 1:0.790055 2:0.01105 3:0.049724 5:0.012344759 7:0.020347665 +1 1:0.707094 2:0.036613 3:0.075515 5:0.069372177 7:0.016492713 +1 1:0.72449 2:0.017007 3:0.054422 5:0.037802096 7:0.02044964 +1 1:0.769115 2:0.014993 3:0.043478 5:0.037593368 7:0.018128128 +1 1:0.722222 2:0.013889 3:0.069444 5:0.037272822 7:0.016937671 +1 1:0.751468 2:0.041096 3:0.021526 5:0.031301716 6:0.023094023 7:0.017051695 +1 1:0.737968 2:0.053476 3:0.032086 5:0.057899602 6:0.017475017 7:0.01679275 +1 1:0.747423 2:0.036082 3:0.036082 5:0.043512293 6:0.0058380058 7:0.016155396 +1 1:0.763415 2:0.019512 3:0.036585 6:0.0026940027 7:0.016567518 +1 1:0.736501 2:0.049676 3:0.043197 5:0.056617417 6:0.011391011 7:0.020808091 +1 1:0.756436 2:0.021782 3:0.047525 5:0.044637932 7:0.018147793 +1 1:0.761194 2:0.034826 3:0.052239 5:0.031301716 7:0.021675159 +1 1:0.774744 2:0.013652 3:0.03413 5:0.0090796595 7:0.017085659 +1 1:0.713873 2:0.037572 3:0.092486 5:0.061380884 6:0.0027450027 7:0.019261951 +1 1:0.745645 2:0.02439 3:0.038328 5:0.030846988 7:0.015403244 +1 1:0.790295 2:0.006932 3:0.029463 5:0.016862225 7:0.018683689 +1 1:0.768638 2:0.010283 3:0.03599 5:0.021141145 7:0.01658411 +1 1:0.740458 2:0.045802 3:0.022901 5:0.044108658 6:0.017751018 7:0.01573264 +1 1:0.773196 2:0.015464 3:0.041237 5:0.024518062 7:0.019109884 +1 1:0.78673 2:0.014218 3:0.033175 5:0.018002773 7:0.017945902 +1 1:0.748428 2:0.018868 3:0.044025 7:0.016183463 +1 1:0.738602 2:0.012158 3:0.030395 5:0.021320054 7:0.019441768 +1 1:0.746479 2:0.035211 3:0.035211 6:0.024063024 7:0.016059774 +1 1:0.723164 2:0.022599 3:0.073446 5:0.043512293 7:0.017707043 +1 1:0.784672 2:0.016423 3:0.029197 5:0.017428772 6:0.0035070035 7:0.019038189 +1 1:0.768595 2:0.011019 3:0.027548 5:0.028558436 7:0.017536787 +1 1:0.765203 2:0.037162 3:0.030405 5:0.028222981 6:0.014601015 7:0.019044579 +1 1:0.790146 2:0.020073 3:0.020073 5:0.01909114 6:0.011523012 7:0.017380274 +1 1:0.765957 2:0.007092 3:0.035461 5:0.022386057 7:0.014400622 +1 1:0.780899 2:0.005618 3:0.033708 7:0.01805289 +1 1:0.71134 2:0.044674 3:0.072165 5:0.090580412 7:0.017244994 +1 1:0.648649 2:0.03861 3:0.096525 5:0.056334143 7:0.018692909 +1 1:0.69112 2:0.050193 3:0.081081 4:0.0036900369 5:0.027171887 6:0.014580015 7:0.019375646 +1 1:0.748752 2:0.034942 3:0.043261 5:0.047097938 7:0.017663652 +1 1:0.73913 2:0.03913 3:0.052174 5:0.065779077 7:0.018027573 +1 1:0.776836 2:0.00565 3:0.042373 5:0.013656762 7:0.018809427 +1 1:0.743191 2:0.031128 3:0.054475 5:0.06194743 7:0.017130116 +1 1:0.646809 2:0.025532 3:0.07234 5:0.042677381 7:0.013596262 +1 1:0.77037 2:0.007407 3:0.02963 5:0.021238054 7:0.015853659 +1 1:0.761658 2:0.010363 3:0.036269 5:0.0075514738 7:0.015591433 +1 1:0.741228 2:0.02193 3:0.030702 5:0.026478613 7:0.015056695 +1 1:0.804598 2:0.003831 3:0.032567 5:0.0086472947 7:0.020138305 +1 1:0.768212 2:0.006623 3:0.02649 5:0.021923874 7:0.01372961 +1 1:0.659864 2:0.081633 3:0.034014 5:0.11222101 6:0.019356019 7:0.019288201 +1 1:0.705036 2:0.035971 3:0.086331 5:0.056617417 7:0.017327604 +1 1:0.792291 2:0.010707 3:0.029979 5:0.0051361949 7:0.018958585 +1 1:0.754777 2:0.025478 3:0.02707 5:0.02464479 7:0.017622726 +1 1:0.773973 2:0.006849 3:0.054795 5:0.016601315 7:0.018752085 +1 1:0.751073 2:0.038627 3:0.023605 5:0.022102784 6:0.02001602 7:0.017651524 +1 1:0.740458 2:0.015267 3:0.061069 5:0.041298287 7:0.016803201 +1 1:0.75 2:0.02381 3:0.043651 5:0.010943301 6:0.013215013 7:0.016477933 +1 1:0.768212 2:0.013245 3:0.043046 5:0.03439536 7:0.01750525 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.778226 2:0.008065 3:0.028226 5:0.023593696 7:0.015538945 +1 1:0.77044 2:0.012579 3:0.044025 5:0.033239903 7:0.017199726 +1 1:0.769795 2:0.01173 3:0.032258 5:0.018599138 7:0.017917171 +1 1:0.742857 2:0.042857 3:0.042857 5:0.036363365 6:0.014634015 7:0.01785714 +1 1:0.678571 2:0.059524 3:0.065476 5:0.036013001 6:0.014493014 7:0.015026134 +1 1:0.719828 2:0.034483 3:0.081897 5:0.076178194 7:0.018003573 +1 1:0.71 2:0.055 3:0.07 5:0.072026002 6:0.019323019 7:0.018932927 +1 1:0.684615 2:0.046154 3:0.092308 5:0.1090901 7:0.019230768 +1 1:0.786585 2:0.003049 3:0.033537 5:0.007052018 7:0.019649762 +1 1:0.738019 2:0.028754 3:0.044728 5:0.0089156591 6:0.010767011 7:0.01628614 +1 1:0.731898 2:0.035225 3:0.031311 5:0.035983183 7:0.014832226 +1 1:0.769882 2:0.010152 3:0.027073 5:0.021894056 7:0.01405225 +1 1:0.747312 2:0.016129 3:0.053763 5:0.015274403 7:0.015997902 +1 1:0.712598 2:0.035433 3:0.051181 5:0.034514633 6:0.018519019 7:0.015555982 +1 1:0.715909 2:0.0625 3:0.039773 5:0.057675965 6:0.011604012 7:0.017911585 +1 1:0.759674 2:0.02444 3:0.032587 5:0.032226082 7:0.017237098 +1 1:0.783951 2:0.012346 3:0.055556 5:0.014364946 7:0.01953478 +1 1:0.721088 2:0.034014 3:0.102041 5:0.014253127 7:0.021694043 +1 1:0.763245 2:0.02649 3:0.034768 5:0.054701594 7:0.019261829 8:0.023809524 +1 1:0.785924 2:0.008798 3:0.035191 5:0.014983675 7:0.017792006 +1 1:0.64 2:0.113333 3:0.06 5:0.037653005 6:0.083334083 7:0.016097561 +1 1:0.768182 2:0.020455 3:0.036364 5:0.037116276 6:0.0024900025 7:0.016699 +1 1:0.689655 2:0.08046 3:0.022989 5:0.01951605 6:0.062826063 7:0.013386598 +1 1:0.822951 2:0.003279 3:0.036066 5:0.0062916524 7:0.023690524 +1 1:0.782946 2:0.007752 3:0.03876 5:0.019068776 7:0.018481756 +1 1:0.755981 2:0.023923 3:0.043062 5:0.012568396 7:0.017300738 +1 1:0.766404 2:0.015748 3:0.020997 5:0.021715146 7:0.01648422 +1 1:0.785714 2:0.047619 3:0.015873 6:0.027843028 7:0.02085753 +1 1:0.716 2:0.084 3:0.052 5:0.047888122 6:0.028908029 7:0.022780488 +1 1:0.755906 2:0.031496 3:0.070866 5:0.067307262 7:0.021269445 +1 1:0.790244 2:0.014634 3:0.034146 5:0.0089454773 7:0.024776921 +1 1:0.792 2:0.02 3:0.04 5:0.018845139 7:0.048243902 +1 1:0.763578 2:0.009585 3:0.038339 5:0.025971702 7:0.016773165 8:0.023809524 +1 1:0.730769 2:0.030769 3:0.038462 5:0.059010332 7:0.017776738 +1 1:0.723404 2:0.042553 3:0.035461 5:0.067359444 6:0.009036009 7:0.014357378 +1 1:0.781046 2:0.019608 3:0.022876 5:0.0080658387 6:0.0032460032 7:0.018412244 +1 1:0.730496 2:0.035461 3:0.049645 5:0.020037869 7:0.016087183 +1 1:0.742331 2:0.067485 3:0.01227 5:0.03269572 6:0.052632053 7:0.017058207 +1 1:0.748466 2:0.01227 3:0.06135 5:0.015758949 7:0.017694146 +1 1:0.736625 2:0.024691 3:0.037037 5:0.02448079 6:0.0049260049 7:0.015281543 +1 1:0.771357 2:0.017588 3:0.027638 5:0.0065227439 7:0.017511335 +1 1:0.748837 2:0.009302 3:0.060465 5:0.025054791 7:0.016874646 +1 1:0.787402 2:0.007874 3:0.055118 5:0.018450047 7:0.019396963 +1 1:0.765152 2:0.007576 3:0.030303 5:0.021059145 7:0.016352549 +1 1:0.731034 2:0.048276 3:0.034483 5:0.057049782 6:0.015306015 7:0.016484439 +1 1:0.770186 2:0.018634 3:0.062112 5:0.042841382 7:0.019769732 +1 1:0.707692 2:0.030769 3:0.084615 5:0.036721184 7:0.019043152 +1 1:0.770701 2:0.006369 3:0.063694 5:0.014558764 7:0.019885043 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.770992 2:0.038168 3:0.045802 5:0.036721184 6:0.014778015 7:0.018897787 +1 1:0.738182 2:0.036364 3:0.047273 5:0.047910486 6:0.0038550039 7:0.017250555 +1 1:0.79021 2:0.013986 3:0.034965 5:0.01840532 7:0.017269317 +1 1:0.637097 2:0.145161 3:0.024194 4:0.0036900369 5:0.059166878 6:0.095238095 7:0.018587726 +1 1:0.753799 2:0.015198 3:0.039514 5:0.035580636 7:0.015531171 +1 1:0.747076 2:0.032164 3:0.04386 5:0.043676293 6:0.0058590059 7:0.018257024 +1 1:0.792929 2:0.017677 3:0.035354 5:0.021715146 7:0.021141293 +1 1:0.727273 2:0.034759 3:0.072193 5:0.057839965 7:0.01891222 +1 1:0.758721 2:0.014535 3:0.037791 5:0.039606101 7:0.016679665 +1 1:0.637681 2:0.149758 3:0.038647 5:0.044973387 6:0.085974086 7:0.019529872 +1 1:0.764471 2:0.015968 3:0.041916 5:0.021163508 7:0.017148628 +1 1:0.741697 2:0.02583 3:0.055351 5:0.018293501 7:0.018337683 +1 1:0.736842 2:0.033493 3:0.023923 5:0.032129173 6:0.012930013 7:0.013537171 +1 1:0.746479 2:0.035211 3:0.035211 6:0.024063024 7:0.016059774 +1 1:0.731392 2:0.029126 3:0.055016 4:0.0036900369 5:0.016489497 6:0.00995701 7:0.017838817 +1 1:0.712121 2:0.034091 3:0.075758 5:0.075626556 7:0.015936805 +1 1:0.731183 2:0.017921 3:0.046595 5:0.02096969 6:0.0084390084 7:0.015538945 +1 1:0.761589 2:0.013245 3:0.039735 5:0.038525189 7:0.015627524 +1 1:0.72619 2:0.035714 3:0.059524 5:0.015863313 7:0.017058652 +1 1:0.737201 2:0.027304 3:0.064846 5:0.056595053 7:0.019187549 +1 1:0.72766 2:0.046809 3:0.059574 4:0.0073800738 5:0.047545212 6:0.0076530077 7:0.0203425 +1 1:0.752809 2:0.031835 3:0.02809 5:0.039233373 6:0.0022560023 7:0.015186811 +1 1:0.731959 2:0.030928 3:0.041237 5:0.043847748 7:0.016029671 +1 1:0.674603 2:0.031746 3:0.095238 5:0.070773635 7:0.015292293 +1 1:0.748344 2:0.006623 3:0.059603 5:0.016824952 7:0.017888872 +1 1:0.759336 2:0.016598 3:0.053942 5:0.028819346 7:0.01963364 +1 1:0.75 2:0.022727 3:0.037879 7:0.014828159 +1 1:0.734375 2:0.015625 3:0.057292 5:0.01634786 7:0.014481707 +1 1:0.640244 2:0.042683 3:0.134146 5:0.05048231 7:0.016470854 +1 1:0.761329 2:0.015106 3:0.036254 5:0.023220968 7:0.017740037 +1 1:0.712329 2:0.068493 3:0.030822 5:0.035289908 6:0.039054039 7:0.017645341 +1 1:0.705314 2:0.057971 3:0.067633 5:0.060121062 7:0.018263226 +1 1:0.700637 2:0.057325 3:0.063694 5:0.017018771 6:0.020547021 7:0.01701103 +1 1:0.704663 2:0.031088 3:0.07772 4:0.0073800738 5:0.042036289 7:0.016807787 +1 1:0.700565 2:0.045198 3:0.056497 5:0.035245181 7:0.01457214 +1 1:0.705882 2:0.051903 3:0.058824 5:0.060657791 6:0.0081360081 7:0.023335305 +1 1:0.763407 2:0.012618 3:0.063091 5:0.0070892908 7:0.020235439 +1 1:0.752907 2:0.020349 3:0.034884 5:0.041551742 7:0.015899744 +1 1:0.789157 2:0.006024 3:0.060241 5:0.012158395 7:0.022516896 +1 1:0.732369 2:0.014467 3:0.065099 5:0.040455921 7:0.016252811 +1 1:0.763514 2:0.013514 3:0.047297 5:0.034037541 7:0.018045488 +1 1:0.767327 2:0.014851 3:0.024752 7:0.015636317 +1 1:0.706493 2:0.077922 3:0.044156 5:0.02472679 6:0.047265047 7:0.019100415 +1 1:0.765568 2:0.014652 3:0.051282 5:0.027991889 7:0.017845976 +1 1:0.726351 2:0.054054 3:0.040541 5:0.055454505 6:0.015939016 7:0.019384476 +1 1:0.724444 2:0.031111 3:0.026667 5:0.031994991 6:0.019314019 7:0.012628726 +1 1:0.751092 2:0.008734 3:0.069869 5:0.010168026 7:0.019517518 +1 1:0.726562 2:0.03125 3:0.070312 5:0.072547821 7:0.01957889 +1 1:0.73183 2:0.052632 3:0.06015 4:0.0073800738 5:0.020902599 6:0.0038250038 7:0.059951707 +1 1:0.785124 2:0.016529 3:0.107438 5:0.0053076499 7:0.070802256 +1 1:0.783784 2:0.040541 3:0.040541 5:0.021566055 6:0.011571012 7:0.021362061 +1 1:0.76873 2:0.009772 3:0.032573 5:0.0095791153 7:0.015452451 +1 1:0.752 2:0.016 3:0.044 5:0.043914839 7:0.016560976 +1 1:0.776699 2:0.014563 3:0.038835 5:0.024048425 7:0.018351884 +1 1:0.75 2:0.023438 3:0.042969 5:0.040023556 7:0.017744854 +1 1:0.745223 2:0.025478 3:0.057325 5:0.046494118 7:0.018681061 +1 1:0.736486 2:0.013514 3:0.047297 5:0.041879743 7:0.01466711 +1 1:0.645669 2:0.165354 3:0.031496 5:0.035580636 6:0.1002391 7:0.020117152 +1 1:0.757519 2:0.037594 3:0.031955 5:0.028096253 6:0.016959017 7:0.018246835 +1 1:0.77757 2:0.009346 3:0.024299 5:0.015803677 7:0.016127195 +1 1:0.730769 2:0.025641 3:0.044872 7:0.014696683 +1 1:0.723881 2:0.05597 3:0.041045 5:0.030593532 6:0.020520021 7:0.01663178 +1 1:0.772182 2:0.009592 3:0.035971 5:0.025636247 7:0.017005909 +1 1:0.776596 2:0.010638 3:0.026596 5:0.015430948 7:0.015665543 +1 1:0.491453 2:0.08547 3:0.175214 5:0.11647757 7:0.020012506 +1 1:0.712737 2:0.03794 3:0.04607 5:0.033098266 7:0.014888622 +1 1:0.691057 2:0.073171 3:0.04065 5:0.023004786 6:0.037038037 7:0.016061866 +1 1:0.775 2:0.0125 3:0.034375 5:0.024361517 7:0.017492378 +1 1:0.756345 2:0.035533 3:0.027919 5:0.018822775 7:0.018385543 +1 1:0.755725 2:0.020356 3:0.053435 5:0.025442428 7:0.018184073 +1 1:0.760331 2:0.033058 3:0.033058 5:0.019463868 6:0.015666016 7:0.019300543 +1 1:0.682692 2:0.033654 3:0.024038 5:0.067307262 7:0.012986634 +1 1:0.717742 2:0.112903 3:0.024194 5:0.062640705 6:0.037815038 7:0.023406768 +1 1:0.77037 2:0.007407 3:0.044444 5:0.019314776 7:0.017434506 +1 1:0.722222 2:0.027778 3:0.055556 7:0.014862805 +1 1:0.729211 2:0.025586 3:0.057569 5:0.073926915 7:0.015731445 +1 1:0.73262 2:0.026738 3:0.032086 5:0.036721184 7:0.013238555 +1 1:0.763359 2:0.022901 3:0.053435 5:0.016601315 7:0.020899274 +1 1:0.755789 2:0.027368 3:0.031579 5:0.023258241 6:0.014040014 7:0.016456994 +1 1:0.766667 2:0.030303 3:0.027273 5:0.029818258 6:0.012000012 7:0.018477457 +1 1:0.711268 2:0.028169 3:0.06338 5:0.038525189 7:0.016618 +1 1:0.748619 2:0.024862 3:0.052486 5:0.040403739 7:0.018646409 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.741935 2:0.032258 3:0.048387 5:0.022318966 7:0.016424073 +1 1:0.795699 2:0.008065 3:0.018817 5:0.0069625632 7:0.017555073 +1 1:0.783401 2:0.012146 3:0.04251 4:0.0036900369 5:0.027544616 7:0.020045421 +1 1:0.726667 2:0.04 3:0.04 7:0.015731707 +1 1:0.734807 2:0.016575 3:0.055249 5:0.028670255 7:0.017517854 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.770563 2:0.012987 3:0.021645 5:0.024972791 7:0.015758634 +1 1:0.726115 2:0.012739 3:0.019108 7:0.014137018 +1 1:0.752244 2:0.019749 3:0.057451 5:0.050184128 7:0.01788764 +1 1:0.786555 2:0.010084 3:0.033613 5:0.020567143 7:0.018569378 +1 1:0.778027 2:0.013453 3:0.026906 5:0.018874957 7:0.016200921 +1 1:0.739927 2:0.014652 3:0.043956 6:0.0082080082 7:0.016327171 +1 1:0.647541 2:0.139344 3:0.02459 4:0.0036900369 5:0.057489601 6:0.092544093 7:0.01944222 +1 1:0.736544 2:0.022663 3:0.03966 5:0.043773202 7:0.020590061 +1 1:0.793548 2:0.006452 3:0.045161 5:0.006880563 7:0.021321793 +1 1:0.768595 2:0.041322 3:0.016529 5:0.022520239 6:0.027189027 7:0.016680104 +1 1:0.727723 2:0.029703 3:0.039604 5:0.061351065 7:0.014670372 +1 1:0.746154 2:0.023077 3:0.053846 5:0.051130857 7:0.017096622 +1 1:0.758377 2:0.035273 3:0.024691 4:0.0036900369 5:0.039583737 6:0.010620011 7:0.018228159 +1 1:0.747826 2:0.026087 3:0.06087 5:0.041700833 7:0.018955463 +1 1:0.8 2:0.006897 3:0.034483 5:0.016310587 7:0.019217829 +1 1:0.781923 2:0.012912 3:0.020086 5:0.015699313 7:0.016613012 +1 1:0.749275 2:0.034783 3:0.055072 5:0.050571765 7:0.019538707 +1 1:0.736842 2:0.052632 3:0.048583 5:0.052547225 7:0.024513677 +1 1:0.751938 2:0.007752 3:0.023256 5:0.024518062 7:0.014369445 +1 1:0.776398 2:0.012422 3:0.037267 5:0.032233537 7:0.017516287 +1 1:0.735537 2:0.008264 3:0.057851 5:0.024204971 7:0.015521067 +1 1:0.733766 2:0.032468 3:0.064935 5:0.060053971 6:0.003021003 7:0.019658695 +1 1:0.775281 2:0.005618 3:0.022472 5:0.018450047 7:0.013839409 +1 1:0.733333 2:0.012121 3:0.060606 5:0.017577863 7:0.015668884 +1 1:0.752717 2:0.027174 3:0.038043 5:0.02892371 7:0.01708311 +1 1:0.734783 2:0.06087 3:0.047826 5:0.062491614 6:0.017964018 7:0.022136799 +1 1:0.775591 2:0.015748 3:0.051181 5:0.018159319 7:0.019709043 +1 1:0.746753 2:0.012987 3:0.032468 5:0.016862225 7:0.017500793 +1 1:0.74 2:0.03 3:0.03 5:0.030548805 7:0.014878049 +1 1:0.78344 2:0.008493 3:0.029724 5:0.011651484 7:0.016570866 +1 1:0.737819 2:0.020882 3:0.044084 5:0.012866578 7:0.016396921 +1 1:0.773399 2:0.014778 3:0.039409 5:0.017100771 6:0.0045870046 7:0.01964436 +1 1:0.770642 2:0.013761 3:0.03211 5:0.025270973 7:0.016502573 +1 1:0.763441 2:0.010753 3:0.037634 5:0.015527858 7:0.01573564 +1 1:0.763514 2:0.013514 3:0.047297 5:0.039867011 7:0.015408701 +1 1:0.658228 2:0.037975 3:0.050633 5:0.051197949 7:0.014047543 +1 1:0.767932 2:0.008439 3:0.054852 5:0.019284958 7:0.019887823 +1 1:0.709459 2:0.047297 3:0.054054 5:0.086882948 7:0.017674689 +1 1:0.731928 2:0.036145 3:0.063253 5:0.064511801 7:0.019100793 +1 1:0.684524 2:0.041667 3:0.077381 5:0.072257093 7:0.02246661 +1 1:0.735537 2:0.016529 3:0.057851 5:0.024518062 7:0.015319494 +1 1:0.78389 2:0.007859 3:0.031434 5:0.020999508 7:0.017010878 +1 1:0.779255 2:0.007979 3:0.031915 5:0.023101695 7:0.015697976 +1 1:0.770961 2:0.01636 3:0.026585 5:0.011226574 7:0.016559427 +1 1:0.722222 2:0.031746 3:0.039683 5:0.057049782 7:0.018970189 +1 1:0.762332 2:0.03139 3:0.053812 5:0.042938291 7:0.023734006 +1 1:0.773234 2:0.007435 3:0.018587 5:0.021864237 7:0.015459244 +1 1:0.759819 2:0.013595 3:0.036254 5:0.03268081 7:0.016809744 +1 1:0.729592 2:0.035714 3:0.030612 5:0.050594129 7:0.013750622 +1 1:0.776 2:0.012 3:0.036 5:0.021730055 7:0.016731707 +1 1:0.734694 2:0.040816 3:0.061224 5:0.077326197 7:0.019993366 +1 1:0.774359 2:0.005128 3:0.051282 5:0.013552398 7:0.01719825 +1 1:0.746269 2:0.029851 3:0.039801 5:0.041797743 6:0.011214011 7:0.016229823 +1 1:0.757396 2:0.023669 3:0.029586 7:0.01785972 +1 1:0.716667 2:0.035 3:0.071667 5:0.090416412 7:0.016758128 +1 1:0.721491 2:0.028509 3:0.061404 5:0.053329954 7:0.01682178 +1 1:0.712264 2:0.099057 3:0.023585 5:0.059353242 6:0.052548053 7:0.018062585 +1 1:0.794521 2:0.034247 3:0.027397 5:0.01309767 6:0.015816016 7:0.02376378 +1 1:0.704082 2:0.030612 3:0.081633 5:0.044906296 7:0.017214201 +1 1:0.72549 2:0.027451 3:0.05098 5:0.076849105 7:0.01623625 +1 1:0.726562 2:0.039062 3:0.054688 5:0.077251651 7:0.018387957 +1 1:0.769811 2:0.011321 3:0.045283 5:0.029236802 7:0.01760239 +1 1:0.707006 2:0.050955 3:0.076433 5:0.098519524 7:0.017632439 +1 1:0.735661 2:0.032419 3:0.029925 5:0.0391141 6:0.015741016 7:0.014491213 +1 1:0.738272 2:0.02716 3:0.041975 5:0.042274835 7:0.015928939 +1 1:0.715976 2:0.029586 3:0.059172 7:0.014792896 +1 1:0.752101 2:0.037815 3:0.02521 5:0.043087382 6:0.013005013 7:0.017729043 +1 1:0.731343 2:0.023454 3:0.046908 5:0.043922294 7:0.015445421 +1 1:0.765784 2:0.020367 3:0.038697 5:0.036721184 6:0.0042210042 7:0.017646915 +1 1:0.75945 2:0.010309 3:0.034364 5:0.020820598 7:0.015002933 +1 1:0.704698 2:0.026846 3:0.09396 5:0.017100771 7:0.017842524 +1 1:0.694915 2:0.029661 3:0.059322 5:0.037146095 6:0.004983005 7:0.015553951 +1 1:0.767442 2:0.015504 3:0.062016 5:0.033962996 7:0.020750616 +1 1:0.769759 2:0.013746 3:0.037801 5:0.029236802 7:0.016029671 +1 1:0.749536 2:0.016698 3:0.044527 5:0.020477688 7:0.016471335 +1 1:0.739617 2:0.025559 3:0.063898 5:0.066636351 7:0.017435518 +1 1:0.754587 2:0.029817 3:0.022936 5:0.020552234 6:0.0055140055 7:0.015215933 +1 1:0.821705 2:0.007752 3:0.062016 5:0.0070221997 7:0.050198524 +1 1:0.763485 2:0.016598 3:0.03112 5:0.021528782 6:0.0043320043 7:0.017521 +1 1:0.738462 2:0.015385 3:0.046154 5:0.028506254 7:0.01635397 +1 1:0.789157 2:0.006024 3:0.060241 5:0.012158395 7:0.022516896 +1 1:0.571429 2:0.126984 3:0.15873 5:0.081031115 6:0.016305016 7:0.0356175 +1 1:0.733333 2:0.013333 3:0.044444 5:0.022728967 7:0.017777774 +1 1:0.741483 2:0.032064 3:0.054108 5:0.05536505 7:0.023033872 +1 1:0.755258 2:0.013384 3:0.042065 5:0.010279844 7:0.01690528 +1 1:0.731308 2:0.053738 3:0.049065 5:0.049267216 6:0.023793024 7:0.021555165 +1 1:0.8 2:0.007407 3:0.022222 7:0.019692866 +1 1:0.784211 2:0.015789 3:0.018421 5:0.013843126 7:0.017281774 +1 1:0.755952 2:0.02381 3:0.029762 5:0.037272822 7:0.014518 +1 1:0.66881 2:0.028939 3:0.080386 5:0.04963249 7:0.014724335 8:0.023809524 +1 1:0.746269 2:0.022388 3:0.029851 7:0.015562433 +1 1:0.752988 2:0.01992 3:0.059761 5:0.028454072 7:0.019094354 +1 1:0.69746 2:0.04157 3:0.076212 5:0.097147884 7:0.01620853 +1 1:0.730435 2:0.047826 3:0.065217 5:0.051197949 7:0.019300104 +1 1:0.638889 2:0.161111 3:0.038889 5:0.026769341 6:0.11849112 7:0.018868567 +1 1:0.785965 2:0.003509 3:0.021053 5:0.0099667526 7:0.016003421 +1 1:0.738095 2:0.026786 3:0.026786 5:0.020149688 7:0.013429152 +1 1:0.745161 2:0.041935 3:0.064516 5:0.054932685 6:0.0012990013 7:0.022688829 +1 1:0.772532 2:0.012876 3:0.032189 5:0.028893892 7:0.016879512 +1 1:0.72293 2:0.031847 3:0.066879 5:0.034469906 7:0.016797421 +1 1:0.737885 2:0.022026 3:0.037445 5:0.026672432 7:0.015015579 +1 1:0.748387 2:0.025806 3:0.032258 7:0.017466561 +1 1:0.754522 2:0.023256 3:0.036176 6:0.015411015 7:0.018402976 +1 1:0.745098 2:0.02451 3:0.039216 5:0.029937531 7:0.01488522 +1 1:0.751678 2:0.040268 3:0.033557 5:0.03645282 6:0.014670015 7:0.016737604 +1 1:0.734694 2:0.035714 3:0.081633 5:0.055379959 7:0.02093703 +1 1:0.75 2:0.025 3:0.05 5:0.047179938 7:0.016056909 +1 1:0.705036 2:0.028777 3:0.064748 5:0.066956898 7:0.014651695 +1 1:0.739394 2:0.015152 3:0.051515 5:0.028819346 7:0.014338506 +1 1:0.756322 2:0.011494 3:0.03908 5:0.020805689 7:0.015068683 +1 1:0.733533 2:0.026946 3:0.026946 5:0.050638856 7:0.013436543 +1 1:0.763557 2:0.019523 3:0.02603 5:0.012054031 7:0.016361567 +1 1:0.775 2:0.025 3:0.1 5:0.012993306 7:0.087449183 +1 1:0.734807 2:0.016575 3:0.055249 5:0.028670255 7:0.017517854 +1 1:0.755102 2:0.023324 3:0.055394 5:0.027969526 7:0.018950439 +1 1:0.757098 2:0.015773 3:0.025237 5:0.019441504 7:0.014753402 +1 1:0.780172 2:0.017241 3:0.021552 5:0.012098758 7:0.016190073 +1 1:0.781705 2:0.014553 3:0.04158 5:0.018040046 7:0.020954817 +1 1:0.747126 2:0.051724 3:0.034483 5:0.013932581 6:0.033645034 7:0.01874825 +1 1:0.776596 2:0.010638 3:0.031915 5:0.027559525 7:0.017546707 +1 1:0.760956 2:0.011952 3:0.043825 5:0.030675533 7:0.017709646 +1 1:0.764463 2:0.008264 3:0.057851 5:0.020537325 7:0.018292683 +1 1:0.652068 2:0.07056 3:0.114355 5:0.16876388 7:0.019004805 +1 1:0.675127 2:0.050761 3:0.071066 5:0.092600599 7:0.01494986 +1 1:0.764957 2:0.012821 3:0.055556 5:0.021141145 7:0.027569317 +1 1:0.758621 2:0.013793 3:0.034483 5:0.019068776 7:0.01644239 +1 1:0.770235 2:0.031332 3:0.015666 5:0.028700073 6:0.017325017 7:0.016541427 +1 1:0.775148 2:0.005917 3:0.023669 5:0.017794045 7:0.015117622 +1 1:0.747706 2:0.016055 3:0.052752 5:0.030250622 7:0.017229805 +1 1:0.724907 2:0.033457 3:0.141264 4:0.0036900369 5:0.019881323 7:0.051001902 +1 1:0.705479 2:0.082192 3:0.027397 5:0.029698985 6:0.055776056 7:0.015724189 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.751309 2:0.031414 3:0.028796 5:0.03499918 6:0.0056340056 7:0.016999744 +1 1:0.790541 2:0.009009 3:0.036036 5:0.010063662 7:0.020352671 +1 1:0.770035 2:0.020906 3:0.02439 5:0.018755684 6:0.0037740038 7:0.016890457 +1 1:0.758621 2:0.027586 3:0.048276 5:0.047083029 7:0.019974768 +1 1:0.771429 2:0.052381 3:0.028571 5:0.030265532 6:0.024357024 7:0.02145761 +1 1:0.641026 2:0.043956 3:0.076923 4:0.0036900369 5:0.08959641 7:0.018583043 +1 1:0.776536 2:0.005587 3:0.044693 5:0.014528946 7:0.017475134 +1 1:0.7713 2:0.013453 3:0.03139 5:0.025017518 7:0.016296622 +1 1:0.741697 2:0.02583 3:0.055351 5:0.018293501 7:0.018337683 +1 1:0.776053 2:0.015521 3:0.039911 5:0.027186796 7:0.018536043 +1 1:0.755061 2:0.020243 3:0.034413 5:0.017123134 7:0.016120274 +1 1:0.769231 2:0.021978 3:0.027473 5:0.02892371 6:0.0058200058 7:0.017270835 +1 1:0.778626 2:0.015267 3:0.030534 5:0.019985687 7:0.017361756 +1 1:0.74003 2:0.031019 3:0.050222 5:0.045964844 6:0.0030840031 7:0.01752711 +1 1:0.772994 2:0.007828 3:0.027397 5:0.016444769 7:0.016228341 +1 1:0.762195 2:0.02439 3:0.018293 5:0.017212589 7:0.016099049 +1 1:0.706612 2:0.070248 3:0.020661 4:0.0073800738 5:0.034432633 6:0.034641035 7:0.021820195 +1 1:0.759036 2:0.018072 3:0.036145 7:0.015647957 +1 1:0.763636 2:0.010909 3:0.036364 5:0.019463868 7:0.016984482 +1 1:0.763359 2:0.012723 3:0.033079 5:0.03842828 7:0.015049957 +1 1:0.77551 2:0.010204 3:0.022959 5:0.022318966 6:0.002994003 7:0.015586116 +1 1:0.715736 2:0.017766 3:0.083756 5:0.046799755 7:0.017255787 +1 1:0.761658 2:0.031088 3:0.041451 4:0.0036900369 5:0.039032099 7:0.018103122 +1 1:0.75576 2:0.023041 3:0.0553 5:0.031860808 7:0.01972575 +1 1:0.780488 2:0.02439 3:0.060976 5:0.036482638 7:0.022791494 +1 1:0.706004 2:0.062112 3:0.070393 5:0.025509519 6:0.022587023 7:0.018444177 +1 1:0.732456 2:0.037281 3:0.076754 5:0.08471367 7:0.02000428 +1 1:0.773333 2:0.006667 3:0.02 7:0.014634146 +1 1:0.787115 2:0.011204 3:0.036415 5:0.02662025 7:0.019129604 +1 1:0.770186 2:0.024845 3:0.049689 5:0.044198113 7:0.019163762 +1 1:0.737643 2:0.015209 3:0.057034 5:0.036229183 7:0.019080957 +1 1:0.776978 2:0.007194 3:0.035971 5:0.021797146 7:0.015002634 +1 1:0.764706 2:0.032086 3:0.053476 5:0.022222057 6:0.0089430089 7:0.021879482 +1 1:0.570552 2:0.141104 3:0.147239 5:0.10962682 7:0.027981445 8:0.023809524 +1 1:0.762846 2:0.027668 3:0.023715 6:0.017805018 7:0.016244098 +1 1:0.772388 2:0.026119 3:0.037313 5:0.015840949 6:0.0063750064 7:0.02140972 +1 1:0.777251 2:0.028436 3:0.028436 5:0.023258241 6:0.014040014 7:0.018523872 +1 1:0.760933 2:0.014577 3:0.043732 5:0.030243168 7:0.017528262 +1 1:0.802703 2:0.002703 3:0.027027 5:0.0065823804 7:0.018655238 +1 1:0.788079 2:0.006623 3:0.02649 5:0.016750406 7:0.017969634 +1 1:0.704797 2:0.01845 3:0.073801 5:0.05271868 7:0.015907659 +1 1:0.794643 2:0.004464 3:0.053571 5:0.008967841 7:0.02262086 +1 1:0.750685 2:0.021918 3:0.041096 5:0.04450375 7:0.016789177 +1 1:0.793478 2:0.007246 3:0.025362 5:0.0092734782 7:0.017762457 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.759259 2:0.023148 3:0.050926 5:0.054015774 7:0.019478317 +1 1:0.753927 2:0.015707 3:0.073298 5:0.020820598 7:0.022857872 +1 1:0.713287 2:0.034965 3:0.041958 5:0.047634667 7:0.013346409 +1 1:0.725806 2:0.008065 3:0.080645 5:0.023444605 7:0.015637293 +1 1:0.752525 2:0.035354 3:0.025253 5:0.043258837 6:0.011604012 7:0.015921409 +1 1:0.721374 2:0.038168 3:0.049618 5:0.028707528 6:0.011553012 7:0.018129768 +1 1:0.763314 2:0.017751 3:0.035503 5:0.034432633 7:0.015622744 +1 1:0.795238 2:0.009524 3:0.028571 5:0.010831482 7:0.019976774 +1 1:0.751515 2:0.030303 3:0.036364 5:0.032770265 7:0.016814488 +1 1:0.768202 2:0.011887 3:0.034175 5:0.015893131 7:0.016997067 +1 1:0.789238 2:0.008969 3:0.035874 5:0.010667482 7:0.019112982 +1 1:0.766143 2:0.013962 3:0.031414 5:0.02010496 7:0.015781299 +1 1:0.747863 2:0.012821 3:0.047009 5:0.038361189 7:0.015191787 +1 1:0.727619 2:0.017143 3:0.032381 5:0.037578459 7:0.018432055 +1 1:0.741379 2:0.028736 3:0.045977 5:0.040366466 7:0.019414073 +1 1:0.738095 2:0.015873 3:0.063492 5:0.021297691 7:0.016937671 +1 1:0.72 2:0.011429 3:0.08 5:0.029639348 7:0.017526134 +1 1:0.782828 2:0.025253 3:0.040404 5:0.026404067 7:0.026084012 +1 1:0.707317 2:0.089431 3:0.01626 4:0.0036900369 5:0.055767596 6:0.052368052 7:0.019879043 +1 1:0.75576 2:0.023041 3:0.050691 5:0.011308574 7:0.018517476 +1 1:0.76259 2:0.014388 3:0.035971 5:0.02070878 7:0.015792244 +1 1:0.779528 2:0.007874 3:0.031496 7:0.017332439 +1 1:0.711111 2:0.037037 3:0.088889 5:0.053889046 7:0.018744354 +1 1:0.726415 2:0.051887 3:0.033019 5:0.027969526 6:0.022515023 7:0.015330189 +1 1:0.75625 2:0.015625 3:0.028125 5:0.0098474796 7:0.014424543 +1 1:0.778125 2:0.015625 3:0.0375 5:0.031219716 7:0.018197409 +1 1:0.797872 2:0.005319 3:0.029255 5:0.012583305 7:0.019217049 +1 1:0.69863 2:0.013699 3:0.089041 5:0.041186468 7:0.01511861 +1 1:0.776978 2:0.014388 3:0.035971 5:0.016459678 7:0.019871909 +1 1:0.732143 2:0.035714 3:0.065476 5:0.060359608 7:0.017929732 +1 1:0.759596 2:0.024242 3:0.028283 5:0.019627868 6:0.003951004 7:0.018711506 +1 1:0.781538 2:0.009231 3:0.049231 5:0.021990965 7:0.019080677 +1 1:0.765957 2:0.018237 3:0.021277 5:0.024600063 6:0.0033000033 7:0.016847061 +1 1:0.792157 2:0.007843 3:0.035294 5:0.018293501 7:0.019488287 +1 1:0.777778 2:0.01897 3:0.02981 5:0.020686416 6:0.0055500056 7:0.017863043 +1 1:0.768519 2:0.018519 3:0.035185 5:0.033642449 7:0.017513549 +1 1:0.745763 2:0.022599 3:0.039548 7:0.016432409 +1 1:0.797386 2:0.006536 3:0.104575 5:0.0094374786 7:0.03148414 +1 1:0.810256 2:0.006838 3:0.020513 5:0.011815485 7:0.019731085 8:0.047619048 +1 1:0.772616 2:0.00978 3:0.02934 5:0.028342254 7:0.015683701 +1 1:0.789474 2:0.015038 3:0.022556 5:0.0091243869 7:0.018728226 +1 1:0.694215 2:0.049587 3:0.082645 5:0.065197621 7:0.017284823 +1 1:0.751332 2:0.01421 3:0.031972 5:0.02720916 7:0.014837762 +1 1:0.796117 2:0.004854 3:0.024272 5:0.012635487 7:0.01746389 +1 1:0.739796 2:0.020408 3:0.045918 7:0.015368341 +1 1:0.761538 2:0.023077 3:0.069231 5:0.048409941 7:0.021669793 +1 1:0.719457 2:0.027149 3:0.036199 5:0.034566815 6:0.0046380046 7:0.017851232 +1 1:0.751908 2:0.019084 3:0.026718 5:0.011159483 7:0.015546451 +1 1:0.809187 2:0.003534 3:0.035336 5:0.0080360205 7:0.019994829 +1 1:0.790179 2:0.008929 3:0.040179 5:0.020939871 7:0.01938153 +1 1:0.727915 2:0.031802 3:0.045936 5:0.018942048 7:0.016956823 +1 1:0.744898 2:0.027211 3:0.047619 5:0.044108658 7:0.017525305 +1 1:0.72549 2:0.026144 3:0.039216 5:0.042118289 7:0.014108079 +1 1:0.631579 2:0.086124 3:0.07177 5:0.062431977 6:0.03015003 7:0.017417433 +1 1:0.777273 2:0.022727 3:0.051515 5:0.034626452 7:0.021877311 +1 1:0.718182 2:0.027273 3:0.045455 5:0.031189898 7:0.013248335 +1 1:0.757732 2:0.010309 3:0.036082 5:0.033277176 7:0.014080963 +1 1:0.696429 2:0.053571 3:0.083333 5:0.053628137 7:0.020180024 +1 1:0.726562 2:0.054688 3:0.046875 5:0.01951605 6:0.031413031 7:0.018197409 +1 1:0.793103 2:0.007663 3:0.049808 5:0.0079018383 7:0.022030652 +1 1:0.637097 2:0.145161 3:0.024194 4:0.0036900369 5:0.059166878 6:0.095238095 7:0.018587726 +1 1:0.713542 2:0.03125 3:0.046875 5:0.034037541 7:0.013910061 +1 1:0.594737 2:0.115789 3:0.031579 5:0.033128084 6:0.10666811 7:0.014441591 +1 1:0.776786 2:0.008929 3:0.040179 5:0.022728967 7:0.01785714 +1 1:0.796226 2:0.018868 3:0.041509 5:0.023198605 6:0.0031110031 7:0.022181317 +1 1:0.802083 2:0.006944 3:0.034722 5:0.014379855 7:0.021955451 +1 1:0.710938 2:0.03125 3:0.054688 5:0.025971702 6:0.01045201 7:0.013671878 +1 1:0.791837 2:0.004082 3:0.028571 5:0.010540754 7:0.017595817 +1 1:0.768293 2:0.020325 3:0.038618 5:0.035304817 7:0.01831747 +1 1:0.696552 2:0.07931 3:0.055172 5:0.090408957 6:0.01984502 7:0.019070646 +1 1:0.762238 2:0.01049 3:0.027972 5:0.021029326 7:0.015115982 +1 1:0.634146 2:0.03252 3:0.130081 5:0.070326361 7:0.015764427 +1 1:0.747811 2:0.022767 3:0.038529 5:0.041126832 6:0.0062070062 7:0.015484177 +1 1:0.750929 2:0.022305 3:0.04461 5:0.041879743 7:0.020174085 +1 1:0.761329 2:0.015106 3:0.036254 5:0.023220968 7:0.017740037 +1 1:0.75188 2:0.022556 3:0.037594 7:0.015358518 +1 1:0.790476 2:0.017143 3:0.019048 5:0.014089127 6:0.0056700057 7:0.018432055 +1 1:0.710744 2:0.033058 3:0.082645 5:0.063714162 7:0.017687963 +1 1:0.774648 2:0.014085 3:0.035211 5:0.020820598 7:0.015372726 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.746114 2:0.025907 3:0.025907 5:0.031122806 7:0.015133323 +1 1:0.767528 2:0.02214 3:0.02214 5:0.010168026 7:0.016492665 +1 1:0.740088 2:0.013216 3:0.057269 5:0.034037541 7:0.017648006 +1 1:0.773723 2:0.014599 3:0.036496 5:0.020477688 7:0.016200817 +1 1:0.76875 2:0.03125 3:0.03125 7:0.01878811 +1 1:0.760331 2:0.016529 3:0.033058 5:0.036810639 7:0.020409189 +1 1:0.710692 2:0.037736 3:0.081761 5:0.098519524 7:0.017410646 +1 1:0.768061 2:0.015209 3:0.019011 5:0.011450211 7:0.015093201 +1 1:0.790698 2:0.011628 3:0.03876 5:0.0084907489 7:0.020750616 +1 1:0.756906 2:0.038674 3:0.027624 5:0.026068612 6:0.015735016 7:0.01926964 +1 1:0.776423 2:0.020325 3:0.028455 5:0.02020187 7:0.018292683 +1 1:0.622144 2:0.110721 3:0.080844 5:0.083304758 6:0.021966022 7:0.027808738 +1 1:0.756906 2:0.016575 3:0.044199 5:0.047276848 7:0.015934512 +1 1:0.769022 2:0.01087 3:0.035326 5:0.022386057 7:0.01655289 +1 1:0.661202 2:0.027322 3:0.087432 4:0.0036900369 5:0.030183531 7:0.016460085 +1 1:0.677419 2:0.048387 3:0.08871 5:0.14358982 7:0.015317665 +1 1:0.75 2:0.012821 3:0.032051 5:0.035498636 7:0.016416512 +1 1:0.661654 2:0.067669 3:0.097744 5:0.091355687 6:0.0073530074 7:0.018705299 +1 1:0.767059 2:0.028235 3:0.042353 5:0.043467565 6:0.0043740044 7:0.01968436 +1 1:0.743304 2:0.020089 3:0.040179 5:0.014305309 7:0.014182274 +1 1:0.808429 2:0.003831 3:0.030651 5:0.0080732933 7:0.021563402 +1 1:0.771208 2:0.015424 3:0.030848 5:0.020671507 7:0.016960311 +1 1:0.796729 2:0.004673 3:0.021028 5:0.011360756 7:0.018691591 +1 1:0.759305 2:0.01737 3:0.029777 5:0.03697464 7:0.01525147 +1 1:0.749035 2:0.030888 3:0.057915 5:0.015550221 6:0.0041730042 7:0.033854415 +1 1:0.757143 2:0.021429 3:0.057143 5:0.017920773 7:0.01811847 +1 1:0.74606 2:0.012259 3:0.033275 4:0.0036900369 5:0.022863149 7:0.017406348 +1 1:0.74375 2:0.0125 3:0.047917 5:0.037779733 7:0.015040652 +1 1:0.775194 2:0.007752 3:0.062016 5:0.015527858 7:0.022688598 +1 1:0.809278 2:0.007732 3:0.036082 5:0.0054716503 7:0.021404323 +1 1:0.751295 2:0.022453 3:0.056995 5:0.055953961 7:0.018240024 +1 1:0.691824 2:0.012579 3:0.113208 5:0.035498636 7:0.016106768 +1 1:0.743671 2:0.031646 3:0.025316 5:0.019359504 6:0.0038970039 7:0.014857982 +1 1:0.792169 2:0.006024 3:0.036145 5:0.0067165626 7:0.020386427 +1 1:0.774536 2:0.013263 3:0.034483 5:0.03080226 7:0.019570421 +1 1:0.753247 2:0.025974 3:0.045455 5:0.015796222 7:0.018688628 +1 1:0.751553 2:0.031056 3:0.043478 5:0.050713402 7:0.016702012 +1 1:0.735537 2:0.008264 3:0.057851 5:0.024204971 7:0.015521067 +1 1:0.763006 2:0.023121 3:0.034682 5:0.030362441 7:0.017305793 +1 1:0.72619 2:0.035714 3:0.029762 5:0.044958478 6:0.0018090018 7:0.01504428 +1 1:0.703125 2:0.03125 3:0.078125 5:0.074545644 7:0.016673018 +1 1:0.736842 2:0.026316 3:0.047368 4:0.0036900369 5:0.045733753 7:0.015693195 +1 1:0.710526 2:0.040936 3:0.064327 5:0.084534761 7:0.01729425 +1 1:0.773438 2:0.015625 3:0.026042 5:0.013149852 6:0.0026460026 7:0.01800686 +1 1:0.721698 2:0.023585 3:0.04717 5:0.016243496 7:0.013201793 +1 1:0.773832 2:0.029907 3:0.020561 5:0.029959894 6:0.016074016 7:0.017016183 +1 1:0.701531 2:0.079082 3:0.066327 5:0.071720364 6:0.0067920068 7:0.027485689 +1 1:0.750877 2:0.035088 3:0.02807 5:0.030511532 6:0.012279012 7:0.0156825 +1 1:0.755 2:0.035 3:0.03 5:0.032785174 6:0.010554011 7:0.017332317 +1 1:0.696 2:0.048 3:0.056 5:0.08352094 7:0.017414634 +1 1:0.732394 2:0.037559 3:0.046948 5:0.038227006 6:0.0051270051 7:0.016746823 +1 1:0.80236 2:0.00295 3:0.035398 5:0.0062767432 7:0.021368445 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.79096 2:0.011299 3:0.045198 5:0.012486395 7:0.020566348 +1 1:0.659574 2:0.049645 3:0.095745 5:0.13518853 7:0.016692616 +1 1:0.738589 2:0.03527 3:0.049793 5:0.057183964 6:0.0020910021 7:0.018140878 +1 1:0.706161 2:0.056872 3:0.085308 5:0.020231688 6:0.0027150027 7:0.063894348 +1 1:0.761589 2:0.02649 3:0.059603 5:0.040590103 7:0.022250043 +1 1:0.767123 2:0.020548 3:0.061644 5:0.011524757 7:0.027021384 +1 1:0.705696 2:0.028481 3:0.056962 5:0.042304653 6:0.0068100068 7:0.016999848 +1 1:0.799031 2:0.007264 3:0.038741 7:0.020773049 +1 1:0.766467 2:0.017964 3:0.053892 5:0.029698985 7:0.018329195 +1 1:0.771523 2:0.023179 3:0.033113 5:0.015430948 7:0.019504116 +1 1:0.732484 2:0.025478 3:0.031847 5:0.041648651 7:0.013903994 +1 1:0.768166 2:0.034602 3:0.051903 5:0.041492106 7:0.022744537 +1 1:0.737052 2:0.011952 3:0.067729 5:0.019829141 7:0.027402585 +1 1:0.753968 2:0.02381 3:0.055556 5:0.037183367 7:0.019405732 +1 1:0.767932 2:0.008439 3:0.054852 5:0.019284958 7:0.019887823 +1 1:0.761194 2:0.0199 3:0.029851 5:0.027559525 7:0.016411841 +1 1:0.705479 2:0.054795 3:0.047945 5:0.040075738 6:0.024195024 7:0.01553625 +1 1:0.762295 2:0.028689 3:0.045082 5:0.010264935 6:0.016530017 7:0.018142744 +1 1:0.803738 2:0.009346 3:0.028037 5:0.010324572 7:0.020572146 +1 1:0.722581 2:0.051613 3:0.03871 5:0.069021812 6:0.0069450069 7:0.016994494 +1 1:0.775362 2:0.014493 3:0.021739 5:0.021990965 7:0.014978793 +1 1:0.769424 2:0.02005 3:0.037594 5:0.03088426 7:0.018445506 +1 1:0.755725 2:0.053435 3:0.038168 5:0.050027582 6:0.013422013 7:0.020806183 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.78481 2:0.015823 3:0.041139 5:0.022140056 7:0.019489043 +1 1:0.764368 2:0.017241 3:0.051724 5:0.041566651 7:0.018853378 +1 1:0.755973 2:0.013652 3:0.032423 5:0.032315537 7:0.014401067 +1 1:0.707006 2:0.063694 3:0.073248 5:0.067769445 6:0.012120012 7:0.019224793 +1 1:0.716312 2:0.01182 3:0.056738 5:0.033821359 7:0.015885372 +1 1:0.779188 2:0.017766 3:0.048223 5:0.028118617 7:0.028723537 +1 1:0.776224 2:0.020979 3:0.022727 5:0.018181683 6:0.0054870055 7:0.017482518 +1 1:0.789474 2:0.009288 3:0.021672 5:0.015259493 7:0.018443707 +1 1:0.69657 2:0.058047 3:0.044855 5:0.089812592 6:0.009036009 7:0.016024195 +1 1:0.727838 2:0.051322 3:0.076205 5:0.064824892 7:0.022901415 +1 1:0.769953 2:0.00939 3:0.030516 5:0.027507343 7:0.01551586 +1 1:0.707317 2:0.01626 3:0.113821 5:0.040515558 7:0.01824311 +1 1:0.734783 2:0.013043 3:0.03913 5:0.027060069 7:0.014607634 +1 1:0.756303 2:0.014006 3:0.02521 5:0.034864998 7:0.018258524 +1 1:0.805243 2:0.007491 3:0.037453 5:0.016713133 7:0.020370878 +1 1:0.775591 2:0.007874 3:0.031496 5:0.020067687 7:0.017836567 +1 1:0.771429 2:0.022857 3:0.034286 5:0.030675533 7:0.016933799 +1 1:0.656126 2:0.075099 3:0.051383 5:0.12187467 6:0.012261012 7:0.017690159 +1 1:0.739496 2:0.026891 3:0.045378 5:0.018278592 7:0.016714488 +1 1:0.780405 2:0.010135 3:0.02027 5:0.019113503 7:0.016067896 +1 1:0.74552 2:0.035842 3:0.039427 5:0.048976488 7:0.016631701 +1 1:0.724349 2:0.030628 3:0.047473 5:0.031994991 7:0.015229896 +1 1:0.769231 2:0.013986 3:0.027972 5:0.020149688 7:0.015776909 +1 1:0.768889 2:0.013333 3:0.055556 5:0.029915167 7:0.020257451 +1 1:0.713235 2:0.036765 3:0.036765 5:0.025442428 7:0.013136659 +1 1:0.789969 2:0.017241 3:0.029781 5:0.014596037 6:0.0058740059 7:0.019525573 +1 1:0.736508 2:0.028571 3:0.038095 5:0.038778644 6:0.0078030078 7:0.014885793 +1 1:0.758278 2:0.023179 3:0.029801 5:0.016586406 6:0.0033360033 7:0.018151348 +1 1:0.730769 2:0.038462 3:0.072115 5:0.040515558 7:0.021575982 +1 1:0.793413 2:0.008982 3:0.02994 5:0.013291488 7:0.020483427 +1 1:0.786517 2:0.018727 3:0.024345 5:0.013753671 6:0.0073800074 7:0.018566732 +1 1:0.783784 2:0.016216 3:0.054054 5:0.016586406 7:0.029630848 +1 1:0.756545 2:0.04712 3:0.036649 5:0.03790646 6:0.012711013 7:0.018835396 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.792373 2:0.025424 3:0.033898 5:0.0090125684 6:0.0072540073 7:0.021367299 +1 1:0.740047 2:0.023419 3:0.030445 5:0.022117693 7:0.014437085 +1 1:0.779685 2:0.007153 3:0.032904 5:0.019434049 7:0.01673122 +1 1:0.753086 2:0.018519 3:0.055556 5:0.034432633 7:0.016297799 +1 1:0.769939 2:0.030675 3:0.021472 5:0.026031339 6:0.017463017 7:0.016066884 +1 1:0.787879 2:0.007576 3:0.037879 5:0.018271137 7:0.018847006 +1 1:0.748201 2:0.02518 3:0.035971 5:0.043281201 7:0.015112299 +1 1:0.71746 2:0.025397 3:0.038095 5:0.042655018 7:0.01353078 +1 1:0.71134 2:0.051546 3:0.034364 5:0.047888122 6:0.0096360096 7:0.019570866 +1 1:0.790741 2:0.011111 3:0.031481 5:0.012449123 7:0.020280037 +1 1:0.755906 2:0.015748 3:0.03937 5:0.025352974 7:0.014115616 +1 1:0.691824 2:0.113208 3:0.018868 5:0.032621174 6:0.078774079 7:0.017525695 +1 1:0.748148 2:0.022222 3:0.066667 5:0.036810639 7:0.018292683 +1 1:0.769953 2:0.032864 3:0.028169 5:0.012046576 6:0.019386019 7:0.01772014 +1 1:0.755102 2:0.013605 3:0.027211 5:0.037369731 7:0.016550524 +1 1:0.764591 2:0.007782 3:0.025292 5:0.012605668 7:0.014033878 +1 1:0.737705 2:0.010929 3:0.065574 7:0.016393439 +1 1:0.770115 2:0.005747 3:0.04023 5:0.016787679 7:0.015559293 +1 1:0.69788 2:0.083039 3:0.035336 5:0.033538085 6:0.046272046 7:0.016762909 +1 1:0.781421 2:0.005464 3:0.032787 5:0.015341494 7:0.016193524 +1 1:0.72973 2:0.015015 3:0.045045 5:0.041126832 7:0.01327547 +1 1:0.748905 2:0.026277 3:0.027737 5:0.035431545 7:0.014981305 +1 1:0.799065 2:0.023364 3:0.014019 6:0.0085350085 7:0.020030774 +1 1:0.81 2:0.005 3:0.03 5:0.010913482 7:0.020823171 +1 1:0.761029 2:0.014706 3:0.033088 5:0.030593532 7:0.016387195 +1 1:0.75 2:0.02 3:0.065 5:0.024048425 7:0.018902439 +1 1:0.774194 2:0.008065 3:0.032258 5:0.022937695 7:0.015981512 +1 1:0.688995 2:0.028708 3:0.119617 4:0.022140221 5:0.050780493 7:0.021414402 +1 1:0.775281 2:0.005618 3:0.022472 5:0.018450047 7:0.013839409 +1 1:0.789157 2:0.024096 3:0.060241 5:0.021774783 7:0.037724067 +1 1:0.758065 2:0.024194 3:0.028226 5:0.034887362 7:0.015760226 +1 1:0.750636 2:0.025445 3:0.048346 5:0.053344863 7:0.017346244 +1 1:0.73224 2:0.021858 3:0.071038 5:0.015088038 7:0.016460085 +1 1:0.788119 2:0.00396 3:0.041584 5:0.0092287508 7:0.019512195 +1 1:0.773389 2:0.022869 3:0.033264 5:0.023742788 6:0.0076440076 7:0.01990264 +1 1:0.777397 2:0.020548 3:0.034247 5:0.024413699 7:0.019127963 +1 1:0.733871 2:0.072581 3:0.016129 5:0.020537325 6:0.04958705 7:0.017850116 +1 1:0.757576 2:0.016162 3:0.030303 5:0.010906028 6:0.0087780088 7:0.016839122 +1 1:0.72093 2:0.015504 3:0.077519 5:0.023593696 7:0.014936659 +1 1:0.755102 2:0.013605 3:0.027211 5:0.037369731 7:0.016550524 +1 1:0.765957 2:0.021277 3:0.055319 5:0.01909114 7:0.020264659 +1 1:0.747253 2:0.025641 3:0.032967 5:0.028632982 7:0.017443939 +1 1:0.765027 2:0.010929 3:0.043716 4:0.0036900369 5:0.013477852 7:0.018425963 +1 1:0.770833 2:0.034722 3:0.0625 5:0.03909919 7:0.024220866 +1 1:0.793249 2:0.016878 3:0.042194 5:0.026657522 7:0.021585878 +1 1:0.727273 2:0.019481 3:0.071429 5:0.04937158 7:0.017936329 +1 1:0.692833 2:0.075085 3:0.054608 5:0.064027254 6:0.033129033 7:0.016960793 +1 1:0.748252 2:0.027972 3:0.062937 5:0.05237577 7:0.018207402 +1 1:0.75 2:0.016667 3:0.041667 5:0.019985687 7:0.01895325 +1 1:0.735661 2:0.032419 3:0.029925 5:0.0391141 6:0.015741016 7:0.014491213 +1 1:0.803279 2:0.008197 3:0.032787 7:0.021141543 +1 1:0.760479 2:0.017964 3:0.02994 5:0.025882248 7:0.02103111 +1 1:0.730077 2:0.028278 3:0.046272 5:0.039233373 7:0.014891213 +1 1:0.704348 2:0.049275 3:0.057971 5:0.087889315 7:0.016489927 +1 1:0.718518 2:0.074074 3:0.051852 5:0.032837356 6:0.036345036 7:0.020505872 +1 1:0.772532 2:0.010014 3:0.027182 5:0.024518062 7:0.015911232 +1 1:0.792517 2:0.003401 3:0.034014 5:0.0081329298 7:0.019018585 +1 1:0.736181 2:0.017588 3:0.032663 5:0.032591356 7:0.014018262 +1 1:0.788151 2:0.021544 3:0.035907 5:0.011427847 6:0.0091980092 7:0.021423567 +1 1:0.7375 2:0.01875 3:0.03125 7:0.01257622 +1 1:0.695364 2:0.036424 3:0.076159 5:0.025181519 7:0.01792925 +1 1:0.746939 2:0.032653 3:0.053061 5:0.0098474796 6:0.0079260079 7:0.01884022 +1 1:0.740157 2:0.019685 3:0.066929 5:0.019642777 7:0.018220665 +1 1:0.75266 2:0.023936 3:0.037234 5:0.048409941 6:0.0064950065 7:0.014984433 +1 1:0.791139 2:0.009494 3:0.028481 5:0.016362769 7:0.017578726 +1 1:0.760391 2:0.01956 3:0.04401 5:0.045771026 7:0.016995646 +1 1:0.778196 2:0.011278 3:0.030075 5:0.021357327 7:0.016000366 +1 1:0.756614 2:0.026455 3:0.021164 5:0.015088038 7:0.015937543 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.800654 2:0.006536 3:0.03268 5:0.013433125 7:0.022118604 +1 1:0.791304 2:0.012174 3:0.031304 5:0.019888778 6:0.0016020016 7:0.019872744 +1 1:0.712446 2:0.015021 3:0.034335 5:0.026456249 7:0.018436616 +1 1:0.697987 2:0.026846 3:0.100671 5:0.014819674 7:0.020584384 +1 1:0.763043 2:0.021739 3:0.036957 5:0.035438999 7:0.016728524 +1 1:0.766423 2:0.007299 3:0.021898 5:0.025181519 7:0.013174293 +1 1:0.736573 2:0.035806 3:0.066496 5:0.065391439 7:0.01955586 +1 1:0.731872 2:0.01855 3:0.055649 5:0.054053047 7:0.015598652 +1 1:0.69802 2:0.094059 3:0.049505 5:0.094576059 6:0.01038001 7:0.026171213 +1 1:0.784314 2:0.011765 3:0.031373 5:0.020537325 7:0.017360116 +1 1:0.779703 2:0.019802 3:0.024752 5:0.0061872885 6:0.0074700075 7:0.01818703 +1 1:0.73494 2:0.012048 3:0.084337 5:0.029288984 7:0.018696738 +1 1:0.761603 2:0.018987 3:0.048523 5:0.010168026 6:0.01023301 7:0.018858701 +1 1:0.726619 2:0.014388 3:0.05036 5:0.043594293 7:0.015002634 +1 1:0.787645 2:0.011583 3:0.030888 5:0.02028387 7:0.01730389 +1 1:0.784343 2:0.007386 3:0.025111 5:0.012277668 7:0.016410274 +1 1:0.75 2:0.030488 3:0.036585 5:0.034753179 7:0.015950329 +1 1:0.716763 2:0.040462 3:0.052023 5:0.048827397 7:0.016142677 +1 1:0.796526 2:0.007444 3:0.027295 5:0.012553486 7:0.017974945 +1 1:0.73224 2:0.010929 3:0.027322 4:0.018450185 5:0.025315701 7:0.019625482 +1 1:0.783333 2:0.008333 3:0.033333 5:0.023004786 7:0.016463415 +1 1:0.785714 2:0.047619 3:0.015873 6:0.027843028 7:0.02085753 +1 1:0.75853 2:0.034121 3:0.026247 5:0.035603 6:0.017193017 7:0.016756287 +1 1:0.740132 2:0.042763 3:0.039474 5:0.041275923 6:0.013290013 7:0.018112165 +1 1:0.778524 2:0.006711 3:0.033557 5:0.016944225 7:0.01800622 +1 1:0.752475 2:0.019802 3:0.05198 5:0.051995587 7:0.01731164 +1 1:0.777778 2:0.012821 3:0.034188 5:0.020910053 7:0.018579323 +1 1:0.6875 2:0.09375 3:0.05 5:0.079987476 6:0.045063045 7:0.017759146 +1 1:0.738255 2:0.03132 3:0.06264 5:0.05938306 7:0.022262238 +1 1:0.74359 2:0.032967 3:0.047619 5:0.058622695 7:0.017041902 +1 1:0.757974 2:0.020638 3:0.033771 5:0.039382464 7:0.015158104 +1 1:0.782274 2:0.015414 3:0.025048 5:0.015416039 6:0.0020670021 7:0.017047323 +1 1:0.744589 2:0.021645 3:0.038961 5:0.027358251 7:0.014386018 +1 1:0.720588 2:0.022059 3:0.044118 4:0.0036900369 5:0.020537325 7:0.01627511 +1 1:0.75265 2:0.024735 3:0.045936 5:0.039389918 7:0.016310439 +1 1:0.741135 2:0.021277 3:0.046099 5:0.010384208 7:0.015524994 +1 1:0.755952 2:0.017857 3:0.047619 5:0.045361025 7:0.017893439 +1 1:0.77937 2:0.011461 3:0.034384 5:0.014253127 7:0.018275213 +1 1:0.719626 2:0.031153 3:0.049844 5:0.058466149 7:0.014531573 +1 1:0.8 2:0.011321 3:0.022642 5:0.0043311019 7:0.019788311 +1 1:0.680851 2:0.120567 3:0.028369 5:0.090468594 6:0.072816073 7:0.017816988 +1 1:0.705882 2:0.039216 3:0.05098 5:0.059718516 6:0.004005004 7:0.017910091 +1 1:0.738998 2:0.033384 3:0.034901 5:0.012083849 6:0.021069021 7:0.017126835 +1 1:0.7713 2:0.017937 3:0.044843 5:0.033329358 7:0.018347372 +1 1:0.774809 2:0.015267 3:0.038168 5:0.019985687 7:0.017361756 +1 1:0.756579 2:0.023026 3:0.029605 5:0.0180475 7:0.016567713 +1 1:0.658824 2:0.078431 3:0.058824 5:0.0061201974 6:0.012321012 7:0.058225732 +1 1:0.728137 2:0.028517 3:0.047529 5:0.034454997 7:0.020066305 +1 1:0.778004 2:0.01222 3:0.026477 5:0.021670419 7:0.017088073 +1 1:0.696581 2:0.055556 3:0.047009 4:0.0036900369 5:0.077147287 6:0.011643012 7:0.020142799 +1 1:0.798781 2:0.02439 3:0.030488 5:0.014335127 6:0.011538012 7:0.019333732 +1 1:0.732143 2:0.03125 3:0.053571 5:0.0069551086 6:0.0027990028 7:0.029181183 +1 1:0.703297 2:0.065934 3:0.104396 5:0.044488841 7:0.050522646 +1 1:0.781116 2:0.012876 3:0.042918 5:0.030593532 7:0.019130116 +1 1:0.779006 2:0.027624 3:0.022099 5:0.015028402 6:0.012096012 7:0.016709335 +1 1:0.789941 2:0.011834 3:0.047337 5:0.025658611 7:0.020962622 +1 1:0.730483 2:0.035316 3:0.04461 5:0.035476272 6:0.0071400071 7:0.019052043 +1 1:0.751553 2:0.024845 3:0.043478 5:0.050258673 7:0.016853506 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.777439 2:0.015244 3:0.039634 5:0.023370059 7:0.01779075 +1 1:0.715686 2:0.019608 3:0.03268 4:0.0036900369 5:0.052569588 7:0.014128006 +1 1:0.781784 2:0.01518 3:0.037951 5:0.027440252 7:0.018859628 +1 1:0.528846 2:0.067308 3:0.105769 4:0.0036900369 5:0.11749884 7:0.016738976 +1 1:0.753555 2:0.009479 3:0.061611 5:0.02456279 7:0.017541323 +1 1:0.738806 2:0.044776 3:0.052239 5:0.060851609 7:0.022297049 +1 1:0.772401 2:0.017921 3:0.03405 5:0.022743876 7:0.01791022 +1 1:0.758209 2:0.01194 3:0.020896 5:0.0097431157 7:0.01392428 +1 1:0.710227 2:0.028409 3:0.045455 5:0.053889046 7:0.014377774 +1 1:0.772425 2:0.019934 3:0.0299 5:0.025211337 7:0.017968561 +1 1:0.781885 2:0.009242 3:0.048059 5:0.020611871 7:0.020377799 +1 1:0.750877 2:0.026316 3:0.02807 5:0.037011912 7:0.015083439 +1 1:0.780612 2:0.02551 3:0.02551 5:0.0106973 7:0.021683677 +1 1:0.70892 2:0.056338 3:0.084507 5:0.01959805 6:0.0026280026 7:0.065326921 +1 1:0.747788 2:0.017699 3:0.053097 5:0.043594293 7:0.016147744 +1 1:0.738983 2:0.030508 3:0.057627 5:0.045361025 6:0.0060840061 7:0.020380323 +1 1:0.769737 2:0.006579 3:0.032895 5:0.019210413 7:0.015564829 +1 1:0.785185 2:0.02963 3:0.014815 5:0.019016594 6:0.015306015 7:0.017705512 +1 1:0.7713 2:0.013453 3:0.029148 5:0.017861136 6:0.0047910048 7:0.017116921 +1 1:0.817391 2:0.004348 3:0.021739 7:0.019485683 +1 1:0.761589 2:0.014901 3:0.029801 5:0.034417724 7:0.015304476 +1 1:0.789474 2:0.007519 3:0.037594 7:0.018751146 +1 1:0.796804 2:0.03653 3:0.022831 5:0.013917672 6:0.014934015 7:0.022371646 +1 1:0.617801 2:0.08377 3:0.068063 4:0.0036900369 5:0.0055238322 6:0.0027780028 7:0.17235985 +1 1:0.758475 2:0.012712 3:0.033898 5:0.038159915 7:0.015140555 +1 1:0.737931 2:0.029885 3:0.052874 5:0.059256333 7:0.017633866 +1 1:0.775862 2:0.010345 3:0.044828 5:0.026590431 7:0.017682927 +1 1:0.742991 2:0.051402 3:0.051402 5:0.050437583 6:0.0081180081 7:0.02105653 +1 1:0.74184 2:0.038576 3:0.035608 5:0.024331698 6:0.016323016 7:0.016628067 +1 1:0.786026 2:0.008734 3:0.030568 7:0.016908085 +1 1:0.748428 2:0.018868 3:0.044025 7:0.016183463 +1 1:0.775915 2:0.015244 3:0.035061 5:0.02626243 7:0.018469287 +1 1:0.682927 2:0.04878 3:0.065041 5:0.10353645 7:0.014277213 +1 1:0.792017 2:0.008403 3:0.035714 5:0.0097282066 6:0.001959002 7:0.019624927 +1 1:0.701149 2:0.049808 3:0.049808 4:0.0036900369 5:0.087702951 6:0.0078420078 7:0.017872165 +1 1:0.751938 2:0.015504 3:0.041344 5:0.045085206 7:0.015629927 +1 1:0.706522 2:0.016304 3:0.081522 5:0.015341494 7:0.016105512 +1 1:0.763052 2:0.012048 3:0.024096 5:0.021826965 7:0.016725439 +1 1:0.637097 2:0.153226 3:0.024194 4:0.0036900369 5:0.054284138 6:0.1019431 7:0.02025964 +1 1:0.728873 2:0.035211 3:0.042254 5:0.029542439 7:0.016253006 +1 1:0.766667 2:0.02 3:0.02 5:0.02036587 7:0.014878049 +1 1:0.780576 2:0.007194 3:0.061151 5:0.015102948 7:0.021648537 +1 1:0.719486 2:0.03212 3:0.03212 5:0.061231792 7:0.012717396 +1 1:0.768817 2:0.021505 3:0.037634 5:0.027455161 7:0.017800945 +1 1:0.742515 2:0.017964 3:0.047904 5:0.035580636 7:0.015298671 +1 1:0.746544 2:0.02765 3:0.046083 5:0.036900094 7:0.017028213 +1 1:0.705882 2:0.051903 3:0.058824 5:0.060657791 6:0.0081360081 7:0.023335305 +1 1:0.705215 2:0.038549 3:0.043084 5:0.081500753 6:0.0021870022 7:0.018970189 +1 1:0.728 2:0.04 3:0.04 5:0.06041179 7:0.01504878 +1 1:0.674603 2:0.031746 3:0.095238 5:0.070773635 7:0.015292293 +1 1:0.759336 2:0.016598 3:0.053942 5:0.028819346 7:0.01963364 +1 1:0.753994 2:0.019169 3:0.027157 5:0.024898245 7:0.014581549 +1 1:0.792157 2:0.003922 3:0.027451 5:0.0099667526 7:0.017886177 +1 1:0.736842 2:0.033493 3:0.023923 5:0.032129173 6:0.012930013 7:0.013537171 +1 1:0.74321 2:0.019753 3:0.051852 5:0.048007395 7:0.016365555 +1 1:0.744565 2:0.027174 3:0.021739 5:0.03516318 7:0.014050902 +1 1:0.751073 2:0.030043 3:0.030043 5:0.02448079 7:0.015937402 +1 1:0.708333 2:0.016667 3:0.083333 5:0.04809685 7:0.01575203 +1 1:0.790607 2:0.011742 3:0.029354 5:0.018330774 7:0.019414348 +1 1:0.775641 2:0.032051 3:0.012821 5:0.018181683 6:0.021951022 7:0.01602564 +1 1:0.737271 2:0.052953 3:0.075356 5:0.066874897 7:0.02630272 +1 1:0.777311 2:0.008403 3:0.021008 5:0.011524757 7:0.016576146 +1 1:0.731183 2:0.048387 3:0.080645 5:0.063714162 7:0.023013378 +1 1:0.773399 2:0.014778 3:0.039409 5:0.017100771 6:0.0045870046 7:0.01964436 +1 1:0.779874 2:0.018868 3:0.050314 5:0.029288984 7:0.019519866 +1 1:0.75475 2:0.018998 3:0.051813 5:0.020127324 7:0.019503768 +1 1:0.739884 2:0.034682 3:0.023121 5:0.05262177 7:0.014979555 8:0.023809524 +1 1:0.744108 2:0.030303 3:0.040404 5:0.028021708 7:0.016383348 +1 1:0.637097 2:0.145161 3:0.024194 4:0.0036900369 5:0.058853786 6:0.094737095 7:0.018686073 +1 1:0.779221 2:0.006494 3:0.032468 5:0.018591684 7:0.015877415 +1 1:0.740741 2:0.037037 3:0.050926 5:0.047925395 6:0.0042870043 7:0.019760616 +1 1:0.792793 2:0.022523 3:0.018018 5:0.010928391 6:0.013197013 7:0.018732146 +1 1:0.748201 2:0.010791 3:0.028777 5:0.022624603 7:0.014454293 +1 1:0.810526 2:0.005263 3:0.036842 7:0.02166239 +1 1:0.730769 2:0.030769 3:0.038462 5:0.059010332 7:0.017776738 +1 1:0.769882 2:0.010152 3:0.027073 5:0.021894056 7:0.01405225 +1 1:0.767391 2:0.019565 3:0.03913 5:0.037168458 7:0.018610817 +1 1:0.735376 2:0.02507 3:0.047354 5:0.059435242 7:0.014912701 +1 1:0.727455 2:0.042084 3:0.03006 5:0.041715743 6:0.019185019 7:0.015286671 +1 1:0.706977 2:0.04186 3:0.051163 4:0.0036900369 5:0.030183531 6:0.012147012 7:0.014010207 +1 1:0.765464 2:0.015464 3:0.043814 5:0.013515125 6:0.0054390054 7:0.017334043 +1 1:0.787004 2:0.018051 3:0.036101 5:0.00787202 6:0.0095040095 7:0.020846171 +1 1:0.752322 2:0.02322 3:0.0387 5:0.029482802 7:0.016706939 +1 1:0.708108 2:0.048649 3:0.043243 5:0.05048231 7:0.014601189 +1 1:0.770308 2:0.016807 3:0.042017 5:0.025181519 7:0.020222726 +1 1:0.746269 2:0.0199 3:0.044776 5:0.028133526 7:0.016078146 +1 1:0.769784 2:0.014388 3:0.05036 5:0.034753179 7:0.018819091 +1 1:0.753582 2:0.028653 3:0.022923 5:0.032949175 6:0.016575017 7:0.015811726 +1 1:0.699346 2:0.039216 3:0.052288 5:0.023295514 7:0.012753067 +1 1:0.758893 2:0.01581 3:0.039526 5:0.023817333 7:0.015087244 +1 1:0.715385 2:0.092308 3:0.034615 5:0.043288656 6:0.041811042 7:0.020192305 +1 1:0.786458 2:0.015625 3:0.057292 5:0.011360756 7:0.020833335 +1 1:0.727273 2:0.025 3:0.054545 5:0.024622426 7:0.016782152 +1 1:0.766807 2:0.014706 3:0.058824 5:0.032248446 7:0.020726585 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.744597 2:0.086444 3:0.043222 5:0.010667482 6:0.037215037 7:0.025109012 +1 1:0.764317 2:0.015419 3:0.039648 5:0.034454997 7:0.017433116 +1 1:0.793333 2:0.006667 3:0.046667 7:0.020528457 +1 1:0.804124 2:0.006873 3:0.041237 5:0.0069551086 7:0.022462494 +1 1:0.782946 2:0.015504 3:0.027132 5:0.018845139 7:0.018694463 +1 1:0.772964 2:0.017331 3:0.024263 5:0.01411149 7:0.016749799 +1 1:0.8 2:0.011321 3:0.022642 5:0.0043311019 7:0.019788311 +1 1:0.768971 2:0.028668 3:0.037099 5:0.028103708 6:0.0096930097 7:0.019094726 +1 1:0.788419 2:0.006682 3:0.057906 5:0.014618401 7:0.020777878 +1 1:0.77027 2:0.02027 3:0.040541 5:0.035327181 7:0.017386287 +1 1:0.745763 2:0.033898 3:0.033898 5:0.029236802 6:0.011766012 7:0.019765396 +1 1:0.623377 2:0.097403 3:0.071429 4:0.0073800738 5:0.15438403 7:0.026765915 +1 1:0.78501 2:0.011834 3:0.031558 5:0.019985687 7:0.017943909 +1 1:0.773438 2:0.013021 3:0.03125 5:0.028975892 7:0.016339561 +1 1:0.737395 2:0.035714 3:0.035714 5:0.05237577 6:0.0046830047 7:0.01640961 +1 1:0.762887 2:0.015464 3:0.030928 7:0.015338195 +1 1:0.738806 2:0.022388 3:0.08209 5:0.035752091 7:0.018975244 +1 1:0.740741 2:0.061728 3:0.020576 5:0.010018935 6:0.04032304 7:0.018669073 +1 1:0.741935 2:0.021505 3:0.064516 5:0.042192835 7:0.017374768 +1 1:0.7552 2:0.0208 3:0.016 5:0.025338064 7:0.01435122 +1 1:0.69802 2:0.034653 3:0.049505 5:0.03011644 6:0.0060600061 7:0.014942043 +1 1:0.779141 2:0.018405 3:0.03681 7:0.019040848 +1 1:0.777143 2:0.011429 3:0.048571 5:0.018874957 7:0.020644598 +1 1:0.755556 2:0.014815 3:0.037037 5:0.043594293 7:0.015447152 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.740741 2:0.030864 3:0.030864 5:0.054217047 6:0.0072720073 7:0.015526195 +1 1:0.753577 2:0.020668 3:0.022258 5:0.019657686 7:0.014705884 +1 1:0.77821 2:0.011673 3:0.035019 5:0.0098474796 7:0.017960518 +1 1:0.725664 2:0.022124 3:0.035398 5:0.028454072 7:0.014137707 +1 1:0.742857 2:0.028571 3:0.044898 5:0.046449391 7:0.015978098 +1 1:0.798611 2:0.006944 3:0.020833 7:0.017445799 +1 1:0.785311 2:0.014124 3:0.025424 5:0.014968765 6:0.006024006 7:0.017155848 +1 1:0.585987 2:0.101911 3:0.127389 5:0.022072965 6:0.0012690013 7:0.091812951 +1 1:0.647934 2:0.12562 3:0.041322 5:0.067881264 6:0.078543079 7:0.017708122 +1 1:0.783259 2:0.005979 3:0.028401 5:0.008043475 7:0.016889061 +1 1:0.768456 2:0.006711 3:0.050336 5:0.016623679 7:0.018354067 +1 1:0.764992 2:0.019449 3:0.035656 5:0.020291324 6:0.0048990049 7:0.018154323 +1 1:0.787736 2:0.018868 3:0.033019 5:0.010600391 6:0.0042660043 7:0.020219744 +1 1:0.770073 2:0.010949 3:0.032847 5:0.03080226 7:0.016156311 +1 1:0.757962 2:0.015924 3:0.038217 5:0.045845571 7:0.015787634 +1 1:0.782178 2:0.016502 3:0.031353 5:0.024778972 7:0.018161878 +1 1:0.530612 2:0.244898 3:0.047619 4:0.0036900369 5:0.052867771 6:0.15602716 7:0.017546043 +1 1:0.781915 2:0.015957 3:0.047872 5:0.023116604 7:0.020919823 +1 1:0.736842 2:0.02807 3:0.052632 5:0.028968437 7:0.016516902 +1 1:0.729323 2:0.022556 3:0.06015 5:0.040843559 7:0.016733909 +1 1:0.751656 2:0.019868 3:0.02649 5:0.021387145 7:0.014072848 +1 1:0.747475 2:0.015152 3:0.040404 5:0.01505822 7:0.015243902 +1 1:0.76431 2:0.023569 3:0.043771 5:0.042215198 7:0.018128439 +1 1:0.760722 2:0.024831 3:0.042889 5:0.033403903 6:0.0022410022 7:0.018430323 +1 1:0.71223 2:0.028777 3:0.05036 7:0.013291805 +1 1:0.753846 2:0.007692 3:0.053846 5:0.024204971 7:0.01444653 +1 1:0.79021 2:0.006993 3:0.041958 5:0.0075962012 7:0.020915061 +1 1:0.781395 2:0.013953 3:0.04186 5:0.02258733 7:0.018718091 +1 1:0.737881 2:0.039497 3:0.028725 5:0.048119213 6:0.0035220035 7:0.018653939 +1 1:0.770701 2:0.006369 3:0.063694 5:0.014558764 7:0.019885043 +1 1:0.708487 2:0.066421 3:0.02583 5:0.068030355 6:0.01955702 7:0.017257671 +1 1:0.739437 2:0.035211 3:0.049296 5:0.065175257 6:0.0032790033 7:0.019645311 +1 1:0.735185 2:0.024074 3:0.031481 5:0.03885319 6:0.0022350022 7:0.01516486 +1 1:0.785366 2:0.014634 3:0.034146 5:0.025315701 7:0.017519335 +1 1:0.729614 2:0.038627 3:0.042918 5:0.022796058 6:0.0091740092 7:0.017115043 +1 1:0.743945 2:0.027682 3:0.051903 5:0.035796818 7:0.017575323 +1 1:0.762295 2:0.028689 3:0.045082 5:0.010264935 6:0.016530017 7:0.018142744 +1 1:0.803231 2:0.007342 3:0.029369 5:0.013082761 7:0.020405787 +1 1:0.771084 2:0.018072 3:0.024096 5:0.017018771 7:0.016088744 +1 1:0.748837 2:0.032558 3:0.032558 5:0.038689189 6:0.0051900052 7:0.016392512 +1 1:0.731844 2:0.011173 3:0.117318 5:0.011159483 7:0.02275514 +1 1:0.76 2:0.0225 3:0.0275 5:0.028893892 6:0.0023250023 7:0.019664634 +1 1:0.702564 2:0.025641 3:0.092308 5:0.025658611 7:0.018167604 +1 1:0.785714 2:0.011278 3:0.037594 5:0.024518062 7:0.020905921 +1 1:0.735099 2:0.022075 3:0.046358 5:0.027432797 7:0.014631457 +1 1:0.768769 2:0.012012 3:0.024024 5:0.01899423 7:0.014374128 +1 1:0.785388 2:0.019787 3:0.03653 5:0.020425507 6:0.0041100041 7:0.020325201 +1 1:0.756691 2:0.004866 3:0.065693 5:0.012680214 7:0.017447037 +1 1:0.736842 2:0.037152 3:0.024768 5:0.047731576 6:0.012807013 7:0.017688591 +1 1:0.757216 2:0.018676 3:0.040747 5:0.027991889 6:0.0016080016 7:0.019296866 +1 1:0.763889 2:0.013889 3:0.020833 5:0.02036587 7:0.01549797 +1 1:0.783951 2:0.012346 3:0.055556 5:0.014364946 7:0.01953478 +1 1:0.765625 2:0.015625 3:0.054688 7:0.017625762 +1 1:0.754011 2:0.023173 3:0.039216 5:0.036475184 7:0.017770963 +1 1:0.744681 2:0.042553 3:0.042553 5:0.043303565 6:0.0074700075 7:0.019541384 +1 1:0.791139 2:0.009494 3:0.028481 5:0.016362769 7:0.017578726 +1 1:0.75817 2:0.039216 3:0.019608 5:0.019016594 6:0.022959023 7:0.015622512 +1 1:0.751592 2:0.006369 3:0.076433 5:0.015796222 7:0.018331518 +1 1:0.744966 2:0.026846 3:0.026846 5:0.041648651 7:0.014650512 +1 1:0.703226 2:0.045161 3:0.045161 5:0.040962832 7:0.014319433 +1 1:0.751244 2:0.014925 3:0.049751 5:0.028834255 7:0.015683774 +1 1:0.758089 2:0.026194 3:0.040062 5:0.018785502 6:0.0090720091 7:0.018640311 +1 1:0.752437 2:0.011696 3:0.064327 5:0.028491345 7:0.018661152 +1 1:0.680952 2:0.047619 3:0.052381 5:0.014819674 6:0.017892018 7:0.01460511 +1 1:0.778027 2:0.013453 3:0.026906 5:0.018874957 7:0.016200921 +1 1:0.764526 2:0.006116 3:0.055046 4:0.0036900369 5:0.015796222 7:0.017602744 +1 1:0.755844 2:0.025974 3:0.028571 5:0.028558436 7:0.016534683 +1 1:0.807018 2:0.004386 3:0.04386 5:0.0091467506 7:0.021796104 +1 1:0.680952 2:0.047619 3:0.052381 5:0.014819674 6:0.017892018 7:0.01460511 +1 1:0.796526 2:0.007444 3:0.027295 5:0.012553486 7:0.017974945 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.660714 2:0.053571 3:0.061224 4:0.0073800738 5:0.092734782 6:0.0057420057 7:0.016254976 +1 1:0.763538 2:0.01444 3:0.048736 4:0.0036900369 5:0.031398625 7:0.018292683 +1 1:0.735849 2:0.025157 3:0.031447 5:0.018136955 7:0.015761622 +1 1:0.766764 2:0.029155 3:0.03207 5:0.014618401 6:0.017646018 7:0.018132689 +1 1:0.763736 2:0.016484 3:0.049451 5:0.040590103 7:0.018460195 +1 1:0.716 2:0.084 3:0.052 5:0.047888122 6:0.028908029 7:0.022780488 +1 1:0.777397 2:0.030822 3:0.027397 5:0.016243496 6:0.013071013 7:0.019169732 +1 1:0.790055 2:0.01105 3:0.049724 5:0.012344759 7:0.020347665 +1 1:0.695853 2:0.059908 3:0.064516 5:0.096812428 7:0.017309207 +1 1:0.787115 2:0.005602 3:0.02521 5:0.015073129 7:0.016892122 +1 1:0.71978 2:0.049451 3:0.038462 6:0.035376035 7:0.014205305 +1 1:0.775132 2:0.007937 3:0.037037 5:0.019806778 7:0.01821203 +1 1:0.758427 2:0.050562 3:0.011236 5:0.024972791 6:0.025125025 7:0.020450811 +1 1:0.777012 2:0.009195 3:0.032184 5:0.011360756 7:0.018390805 +1 1:0.780069 2:0.017182 3:0.04811 5:0.039904283 7:0.019570866 +1 1:0.707736 2:0.068768 3:0.031519 5:0.019948414 6:0.04014304 7:0.019585573 +1 1:0.745283 2:0.061321 3:0.051887 5:0.047239575 6:0.0076050076 7:0.02269328 +1 1:0.773389 2:0.022869 3:0.033264 5:0.023742788 6:0.0076440076 7:0.01990264 +1 1:0.768645 2:0.015221 3:0.033486 5:0.012903851 7:0.016083823 +1 1:0.69869 2:0.039301 3:0.10917 5:0.018971866 7:0.020928744 +1 1:0.734884 2:0.023256 3:0.04186 5:0.014618401 7:0.014463982 +1 1:0.694779 2:0.076305 3:0.048193 5:0.0098772979 6:0.055629056 7:0.018488591 +1 1:0.77027 2:0.010811 3:0.027027 5:0.014648219 7:0.01677653 +1 1:0.78169 2:0.007042 3:0.021127 5:0.019314776 7:0.016575061 +1 1:0.739011 2:0.024725 3:0.035714 5:0.054709048 7:0.018259177 +1 1:0.698718 2:0.076923 3:0.051282 5:0.016526769 6:0.053214053 7:0.017628207 +1 1:0.762821 2:0.00641 3:0.025641 7:0.013484994 +1 1:0.766082 2:0.02924 3:0.023392 5:0.015624767 7:0.017008988 +1 1:0.75 2:0.031716 3:0.027985 5:0.030101531 7:0.016904805 +1 1:0.779221 2:0.004329 3:0.025974 5:0.012322395 7:0.015969805 +1 1:0.80663 2:0.005525 3:0.016575 7:0.019370701 +1 1:0.564286 2:0.214286 3:0.028571 4:0.0036900369 5:0.050944493 6:0.15034215 7:0.019120207 +1 1:0.75641 2:0.017949 3:0.033333 5:0.0071041999 7:0.016400878 +1 1:0.729469 2:0.043478 3:0.05314 5:0.055737778 6:0.011214011 7:0.015759396 +1 1:0.726872 2:0.039648 3:0.052863 5:0.049535581 6:0.00996601 7:0.016170622 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.743017 2:0.022346 3:0.055866 5:0.063714162 7:0.015942226 +1 1:0.769036 2:0.038071 3:0.022843 5:0.025658611 6:0.018072018 7:0.017983165 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.700637 2:0.070064 3:0.025478 5:0.079092929 6:0.031830032 7:0.014641915 +1 1:0.792398 2:0.005848 3:0.026316 5:0.015811131 7:0.016812866 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.79717 2:0.004717 3:0.023585 5:0.011852757 7:0.018091348 +1 1:0.791304 2:0.008696 3:0.026087 5:0.011062574 7:0.017868506 +1 1:0.764331 2:0.019108 3:0.057325 5:0.040664649 7:0.021360884 +1 1:0.761807 2:0.016427 3:0.026694 5:0.030548805 7:0.015275201 +1 1:0.755274 2:0.029536 3:0.033755 5:0.036564639 6:0.0021030021 7:0.018357006 +1 1:0.760391 2:0.01467 3:0.03912 5:0.032076991 7:0.017323634 +1 1:0.749141 2:0.020619 3:0.044674 5:0.019903687 7:0.015694409 +1 1:0.701149 2:0.049808 3:0.049808 4:0.0036900369 5:0.087702951 6:0.0078420078 7:0.017872165 +1 1:0.722826 2:0.038043 3:0.043478 6:0.011859012 7:0.016768293 +1 1:0.744898 2:0.027211 3:0.047619 5:0.044108658 7:0.017525305 +1 1:0.767677 2:0.010101 3:0.065657 5:0.011435302 7:0.020078835 +1 1:0.681614 2:0.044843 3:0.042601 5:0.038100279 6:0.025554026 7:0.01605053 +1 1:0.77451 2:0.009804 3:0.039216 5:0.027007887 7:0.01649928 +1 1:0.77551 2:0.035714 3:0.028061 5:0.026433885 6:0.0063840064 7:0.021932555 +1 1:0.751592 2:0.023355 3:0.042463 5:0.047045756 7:0.018460982 +1 1:0.73374 2:0.03252 3:0.038618 5:0.040142829 7:0.016111445 +1 1:0.585185 2:0.192593 3:0.022222 4:0.0036900369 5:0.056759054 6:0.12944113 7:0.017795848 +1 1:0.756303 2:0.014006 3:0.02521 5:0.034864998 7:0.018258524 +1 1:0.763736 2:0.016484 3:0.049451 5:0.040590103 7:0.018460195 +1 1:0.716 2:0.084 3:0.052 5:0.047888122 6:0.028908029 7:0.022780488 +1 1:0.752066 2:0.016529 3:0.123967 5:0.013932581 7:0.026960293 +1 1:0.71564 2:0.014218 3:0.080569 5:0.037459186 7:0.017252341 +1 1:0.764228 2:0.03252 3:0.04065 5:0.019359504 7:0.01908586 +1 1:0.763593 2:0.021277 3:0.035461 5:0.027007887 6:0.0081510082 7:0.015914201 +1 1:0.752688 2:0.014337 3:0.028674 5:0.021029326 7:0.015495238 +1 1:0.768595 2:0.012397 3:0.028926 5:0.026292249 7:0.014286433 +1 1:0.575 2:0.075 3:0.07 4:0.0036900369 5:0.18271137 7:0.018658537 +1 1:0.760181 2:0.016591 3:0.049774 5:0.040575194 7:0.018586982 +1 1:0.761755 2:0.025078 3:0.047022 5:0.035737182 7:0.019936543 +1 1:0.800725 2:0.018116 3:0.032609 5:0.014774947 7:0.022291445 +1 1:0.747826 2:0.024348 3:0.033043 5:0.041879743 7:0.015100744 +1 1:0.725111 2:0.029718 3:0.05052 5:0.044138476 7:0.015302793 +1 1:0.753846 2:0.015385 3:0.038462 5:0.025531883 7:0.013696061 +1 1:0.791837 2:0.004082 3:0.028571 5:0.010540754 7:0.017595817 +1 1:0.694656 2:0.015267 3:0.083969 5:0.04809685 7:0.014429341 +1 1:0.743191 2:0.027237 3:0.019455 5:0.038159915 7:0.01390339 +1 1:0.767196 2:0.010582 3:0.031746 5:0.014849492 7:0.01619564 +1 1:0.771242 2:0.013072 3:0.052288 5:0.024048425 7:0.018531805 +1 1:0.742905 2:0.015025 3:0.051753 5:0.04141756 7:0.016490902 +1 1:0.745704 2:0.030928 3:0.041237 5:0.03731755 6:0.0037560038 7:0.016742098 +1 1:0.756152 2:0.020134 3:0.029083 5:0.032725538 7:0.015537183 +1 1:0.758242 2:0.021978 3:0.06044 5:0.035550818 7:0.021073439 +1 1:0.693069 2:0.044554 3:0.074257 5:0.10536281 7:0.017085244 +1 1:0.754991 2:0.025408 3:0.052632 5:0.046695392 7:0.019432518 +1 1:0.712934 2:0.022082 3:0.072555 5:0.051108494 7:0.019639146 +1 1:0.759399 2:0.037594 3:0.015038 6:0.027273027 7:0.015129287 +1 1:0.713235 2:0.022059 3:0.066176 7:0.014930055 +1 1:0.803371 2:0.005618 3:0.033708 5:0.012262758 7:0.020827622 +1 1:0.766284 2:0.022989 3:0.049808 5:0.043698657 7:0.019928043 +1 1:0.763636 2:0.025455 3:0.029091 7:0.016518848 +1 1:0.770115 2:0.019157 3:0.049808 5:0.043952112 7:0.019811232 +1 1:0.738916 2:0.019704 3:0.054187 5:0.044071385 7:0.017782049 +1 1:0.794179 2:0.010395 3:0.035343 5:0.019866414 7:0.019027939 +1 1:0.736742 2:0.034091 3:0.049242 5:0.055253232 6:0.004044004 7:0.017137841 +1 1:0.741007 2:0.014388 3:0.021583 4:0.0036900369 5:0.040075738 7:0.016318652 +1 1:0.743961 2:0.024155 3:0.057971 5:0.059353242 7:0.018498878 +1 1:0.73545 2:0.026455 3:0.047619 4:0.0036900369 5:0.028454072 7:0.016905409 +1 1:0.77628 2:0.013477 3:0.032345 5:0.027760798 7:0.017651701 +1 1:0.801242 2:0.006211 3:0.031056 5:0.014282945 7:0.019769732 +1 1:0.726496 2:0.029915 3:0.08547 5:0.060039062 7:0.019413177 +1 1:0.722513 2:0.04712 3:0.031414 5:0.045085206 7:0.015834506 +1 1:0.794872 2:0.008547 3:0.042735 5:0.01951605 7:0.019908274 +1 1:0.778641 2:0.017476 3:0.019417 5:0.016392587 7:0.016149659 +1 1:0.740933 2:0.031088 3:0.041451 5:0.028782073 7:0.016365476 +1 1:0.772926 2:0.030568 3:0.026201 5:0.033836268 6:0.013617014 7:0.017600384 +1 1:0.753555 2:0.009479 3:0.061611 5:0.02456279 7:0.017541323 +1 1:0.742188 2:0.015625 3:0.039062 5:0.051764495 7:0.013719512 +1 1:0.764602 2:0.014159 3:0.037168 5:0.036057728 7:0.017850207 +1 1:0.795322 2:0.005848 3:0.038012 5:0.013045488 7:0.020378689 +1 1:0.764706 2:0.007353 3:0.080882 5:0.016713133 7:0.019996415 +1 1:0.714894 2:0.057447 3:0.048936 5:0.070564907 6:0.0081150081 7:0.01918786 +1 1:0.733906 2:0.034335 3:0.038627 5:0.037779733 7:0.015492512 +1 1:0.678125 2:0.109375 3:0.04375 5:0.035603 6:0.065904066 7:0.019950457 +1 1:0.669173 2:0.045113 3:0.075188 5:0.053247954 7:0.025673939 +1 1:0.749515 2:0.021359 3:0.031068 5:0.033962996 7:0.015593177 +1 1:0.756098 2:0.02439 3:0.039024 5:0.025144246 7:0.017638311 +1 1:0.793388 2:0.008264 3:0.020661 5:0.010555663 7:0.01778875 +1 1:0.783422 2:0.005348 3:0.016043 5:0.007290564 7:0.016662317 +1 1:0.755396 2:0.02518 3:0.035971 5:0.029385893 7:0.016691524 +1 1:0.756614 2:0.026455 3:0.021164 5:0.015088038 7:0.015937543 +1 1:0.772414 2:0.006897 3:0.041379 5:0.019113503 7:0.016400335 +1 1:0.673077 2:0.019231 3:0.102564 5:0.039546464 7:0.014735774 +1 1:0.806452 2:0.018433 3:0.02765 5:0.0086100219 6:0.0034650035 7:0.024334043 +1 1:0.723404 2:0.021277 3:0.055319 5:0.013731308 7:0.014089256 +1 1:0.734783 2:0.06087 3:0.047826 5:0.062491614 6:0.017964018 7:0.022136799 +1 1:0.72549 2:0.027451 3:0.05098 5:0.076849105 7:0.01623625 +1 1:0.779967 2:0.011494 3:0.024631 5:0.018159319 6:0.0018270018 7:0.016440384 +1 1:0.7866 2:0.01737 3:0.032258 5:0.017704591 7:0.019109726 +1 1:0.737589 2:0.060284 3:0.028369 5:0.037086458 6:0.02985003 7:0.017384537 +1 1:0.761364 2:0.011364 3:0.034091 5:0.025703338 7:0.015070677 +1 1:0.772512 2:0.009479 3:0.023697 5:0.013910217 7:0.015489537 +1 1:0.752717 2:0.035326 3:0.038043 5:0.013321307 6:0.018768019 7:0.018541226 +1 1:0.738516 2:0.031802 3:0.063604 5:0.0676949 7:0.018982159 +1 1:0.758333 2:0.025 3:0.041667 5:0.0463003 7:0.016361787 +1 1:0.758929 2:0.008929 3:0.041667 5:0.027104796 7:0.014971689 +1 1:0.699045 2:0.05414 3:0.079618 5:0.11845303 7:0.018331518 +1 1:0.735099 2:0.086093 3:0.019868 5:0.015796222 6:0.050847051 7:0.019059927 +1 1:0.746269 2:0.022388 3:0.029851 7:0.015562433 +1 1:0.720513 2:0.058974 3:0.025641 5:0.032218627 6:0.028521029 7:0.018089433 +1 1:0.757778 2:0.022222 3:0.044444 5:0.041283378 6:0.0023730024 7:0.017127372 +1 1:0.777344 2:0.017578 3:0.042969 5:0.018338228 6:0.0018450018 7:0.019364518 +1 1:0.728477 2:0.013245 3:0.07947 7:0.016798579 +1 1:0.767372 2:0.012085 3:0.030211 5:0.023742788 7:0.017353183 +1 1:0.740933 2:0.033679 3:0.046632 5:0.013380943 6:0.013464013 7:0.017597622 +1 1:0.731034 2:0.062069 3:0.110345 5:0.021789692 7:0.10071488 +1 1:0.797965 2:0.00436 3:0.023256 5:0.011472575 7:0.01727347 +1 1:0.75 2:0.02 3:0.065 5:0.024048425 7:0.018902439 +1 1:0.710744 2:0.066116 3:0.033058 5:0.056759054 6:0.015228015 7:0.019854866 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.793785 2:0.016949 3:0.036723 5:0.016422405 6:0.0022020022 7:0.02346011 +1 1:0.756677 2:0.032641 3:0.047478 5:0.022296602 6:0.014955015 7:0.018147933 +1 1:0.735294 2:0.026471 3:0.041176 5:0.032591356 7:0.01640961 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.734266 2:0.006993 3:0.062937 5:0.022058056 7:0.014412415 +1 1:0.723926 2:0.042945 3:0.042945 5:0.053121226 7:0.015748915 +1 1:0.734568 2:0.024691 3:0.049383 5:0.036184456 7:0.015507378 +1 1:0.747967 2:0.020325 3:0.036585 5:0.024063334 7:0.015355445 +1 1:0.803371 2:0.005618 3:0.033708 5:0.012262758 7:0.020827622 +1 1:0.774286 2:0.017143 3:0.028571 5:0.014804765 7:0.017543555 +1 1:0.787402 2:0.009843 3:0.031496 5:0.023295514 7:0.019204915 +1 1:0.794922 2:0.007812 3:0.033203 5:0.019128412 7:0.018566598 +1 1:0.752608 2:0.014903 3:0.031297 5:0.035103544 7:0.01543928 +1 1:0.736501 2:0.049676 3:0.043197 5:0.056617417 6:0.011391011 7:0.020808091 +1 1:0.804124 2:0.007364 3:0.04271 5:0.011405484 7:0.023483244 +1 1:0.77027 2:0.013514 3:0.114865 5:0.010898573 7:0.028180622 +1 1:0.729927 2:0.021898 3:0.043796 5:0.036900094 7:0.017981128 +1 1:0.719457 2:0.0181 3:0.036199 5:0.013530034 7:0.015202518 +1 1:0.772563 2:0.019856 3:0.050542 5:0.030757533 7:0.021341463 +1 1:0.756757 2:0.040541 3:0.031532 5:0.032889538 6:0.013236013 7:0.018677213 +1 1:0.78836 2:0.010582 3:0.037037 5:0.012762214 7:0.01884114 +1 1:0.766393 2:0.016393 3:0.02459 5:0.011398029 7:0.016343463 +1 1:0.774194 2:0.008065 3:0.032258 5:0.023668242 7:0.015489774 +1 1:0.797654 2:0.008798 3:0.035191 5:0.020746053 7:0.019276159 +1 1:0.73 2:0.02 3:0.055 5:0.015565131 7:0.014603659 +1 1:0.706522 2:0.016304 3:0.081522 5:0.015341494 7:0.016105512 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.762195 2:0.02439 3:0.018293 5:0.017212589 7:0.016099049 +1 1:0.758893 2:0.019763 3:0.031621 5:0.023407332 7:0.01535236 +1 1:0.75 2:0.016129 3:0.040323 5:0.046591028 7:0.01573564 +1 1:0.761905 2:0.014286 3:0.038095 5:0.013127488 7:0.016492451 +1 1:0.734043 2:0.015957 3:0.069149 5:0.015088038 7:0.016022317 +1 1:0.765152 2:0.030303 3:0.060606 5:0.034589179 7:0.019909463 +1 1:0.759399 2:0.030075 3:0.180451 5:0.0014909129 7:0.2289107 +1 1:0.746082 2:0.018809 3:0.062696 5:0.041141741 7:0.017317835 +1 1:0.780488 2:0.00813 3:0.02439 5:0.021730055 7:0.017003768 +1 1:0.688073 2:0.039755 3:0.094801 5:0.068321083 7:0.018311329 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.703364 2:0.033639 3:0.079511 5:0.095239515 7:0.016055049 +1 1:0.770073 2:0.014599 3:0.032847 5:0.029311347 7:0.016979707 +1 1:0.742515 2:0.017964 3:0.047904 5:0.035580636 7:0.015298671 +1 1:0.706493 2:0.077922 3:0.044156 5:0.02472679 6:0.047265047 7:0.019100415 +1 1:0.759009 2:0.040541 3:0.029279 5:0.017242408 6:0.020817021 7:0.017812018 +1 1:0.797386 2:0.013072 3:0.039216 5:0.013574762 7:0.021879482 +1 1:0.762195 2:0.02439 3:0.04878 5:0.025017518 7:0.022159427 +1 1:0.760714 2:0.010714 3:0.039286 5:0.032181355 7:0.015135018 +1 1:0.726708 2:0.043478 3:0.018634 5:0.054015774 6:0.021738022 7:0.015679445 +1 1:0.77069 2:0.010345 3:0.039655 5:0.016780225 7:0.018681665 +1 1:0.77619 2:0.011905 3:0.02619 5:0.02524861 7:0.017145762 +1 1:0.768856 2:0.009732 3:0.03163 5:0.028454072 7:0.015548037 +1 1:0.687861 2:0.092486 3:0.046243 5:0.014879311 6:0.065868066 7:0.017658256 +1 1:0.761494 2:0.022989 3:0.045977 5:0.0070147451 7:0.018625598 +1 1:0.729167 2:0.03869 3:0.047619 5:0.030839533 6:0.0093060093 7:0.017548634 +1 1:0.759591 2:0.015345 3:0.030691 5:0.03380645 7:0.013754598 +1 1:0.746725 2:0.037118 3:0.034934 5:0.052994499 6:0.0094800095 7:0.016854829 +1 1:0.73617 2:0.025532 3:0.055319 5:0.014484219 7:0.020031134 +1 1:0.780864 2:0.003086 3:0.027778 5:0.0089603864 7:0.015657933 +1 1:0.756098 2:0.00813 3:0.04878 5:0.026530795 7:0.013930201 +1 1:0.759036 2:0.018072 3:0.060241 5:0.043765748 7:0.018770201 8:0.023809524 +1 1:0.72093 2:0.034884 3:0.075581 5:0.053918865 7:0.019604366 +1 1:0.737991 2:0.030568 3:0.034934 5:0.025099518 7:0.015816378 +1 1:0.728155 2:0.029126 3:0.067961 5:0.050571765 6:0.0040710041 7:0.021815061 +1 1:0.705686 2:0.036789 3:0.046823 5:0.058973059 7:0.012888488 +1 1:0.758264 2:0.014463 3:0.024793 5:0.018666229 7:0.015092726 +1 1:0.721925 2:0.02139 3:0.042781 5:0.061992158 7:0.015684098 +1 1:0.746667 2:0.026667 3:0.113333 5:0.034350633 7:0.026463415 +1 1:0.773547 2:0.018036 3:0.028056 5:0.026814068 7:0.016985189 +1 1:0.790698 2:0.009302 3:0.026357 5:0.015423494 7:0.018273774 +1 1:0.695122 2:0.012195 3:0.103659 7:0.015392622 +1 1:0.8 2:0.010667 3:0.034667 5:0.017428772 7:0.020861787 +1 1:0.764228 2:0.00813 3:0.056911 5:0.01873332 7:0.019730317 +1 1:0.707692 2:0.030769 3:0.084615 5:0.036721184 7:0.019043152 +1 1:0.744472 2:0.022113 3:0.041769 5:0.021610782 6:0.0057960058 7:0.015506085 +1 1:0.793388 2:0.008264 3:0.049587 5:0.01822641 7:0.020610762 +1 1:0.775785 2:0.017937 3:0.042601 5:0.015341494 6:0.0020580021 7:0.01993328 +1 1:0.756757 2:0.016216 3:0.016216 5:0.017667318 7:0.01390903 +1 1:0.75 2:0.009434 3:0.028302 5:0.023176241 7:0.013877701 +1 1:0.71097 2:0.067511 3:0.044304 5:0.080039658 6:0.021474021 7:0.017971079 +1 1:0.766404 2:0.015748 3:0.020997 5:0.021715146 7:0.01648422 +1 1:0.776119 2:0.00995 3:0.029851 5:0.015527858 7:0.014561341 +1 1:0.808349 2:0.003795 3:0.030361 5:0.0086174765 7:0.020016659 8:0.023809524 +1 1:0.770335 2:0.0311 3:0.043062 5:0.021640601 6:0.017418017 7:0.02010153 +1 1:0.80236 2:0.00295 3:0.035398 5:0.0062767432 7:0.021368445 +1 1:0.758974 2:0.020513 3:0.025641 5:0.015498039 6:0.0062370062 7:0.015040652 +1 1:0.762295 2:0.02459 3:0.040984 7:0.017792884 +1 1:0.753086 2:0.018519 3:0.055556 5:0.034432633 7:0.016297799 +1 1:0.748718 2:0.020513 3:0.05641 5:0.016191314 7:0.02879925 +1 1:0.720833 2:0.035417 3:0.0375 4:0.0036900369 5:0.059353242 6:0.0023880024 7:0.015955287 +1 1:0.708571 2:0.045714 3:0.034286 5:0.035498636 7:0.014634146 +1 1:0.700637 2:0.070064 3:0.025478 5:0.079092929 6:0.031830032 7:0.014641915 +1 1:0.73251 2:0.041152 3:0.028807 5:0.045592116 7:0.01641072 +1 1:0.763819 2:0.005025 3:0.035176 5:0.013552398 7:0.016852555 +1 1:0.795455 2:0.005682 3:0.028409 7:0.018465909 +1 1:0.75 2:0.024752 3:0.029703 5:0.036683912 6:0.002952003 7:0.015334463 +1 1:0.686275 2:0.104575 3:0.03268 5:0.033880995 6:0.068181068 7:0.01753547 8:0.023809524 +1 1:0.778641 2:0.017476 3:0.019417 5:0.016392587 7:0.016149659 +1 1:0.748441 2:0.035343 3:0.027027 5:0.012031667 6:0.019371019 7:0.01570661 +1 1:0.703488 2:0.011628 3:0.075581 5:0.017667318 7:0.014960293 +1 1:0.760956 2:0.015936 3:0.047809 5:0.03140608 7:0.017296665 +1 1:0.738095 2:0.027778 3:0.047619 5:0.021267872 7:0.016961866 +1 1:0.776722 2:0.007126 3:0.028504 5:0.020514961 7:0.015787037 +1 1:0.721311 2:0.032787 3:0.054645 5:0.014588583 7:0.017026524 +1 1:0.731313 2:0.028283 3:0.028283 5:0.048290668 7:0.01521311 8:0.14285714 +1 1:0.778626 2:0.015267 3:0.030534 5:0.021357327 7:0.016244646 +1 1:0.751131 2:0.036199 3:0.027149 5:0.037839369 6:0.01015201 7:0.016306146 +1 1:0.718391 2:0.063218 3:0.08046 5:0.066457442 6:0.013374013 7:0.023584244 +1 1:0.778555 2:0.020979 3:0.02331 5:0.017555499 6:0.0070650071 7:0.018107909 +1 1:0.759375 2:0.025 3:0.015625 5:0.027171887 6:0.0036450036 7:0.015682165 +1 1:0.757669 2:0.027607 3:0.018405 5:0.018136955 6:0.0072990073 7:0.015374829 +1 1:0.722513 2:0.036649 3:0.036649 5:0.049475944 7:0.014429829 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.769231 2:0.014888 3:0.047146 5:0.015893131 7:0.035480848 +1 1:0.753425 2:0.013699 3:0.034247 5:0.023153877 7:0.013448043 +1 1:0.763485 2:0.016598 3:0.03112 5:0.021528782 6:0.0043320043 7:0.017521 +1 1:0.699531 2:0.061033 3:0.042254 5:0.012098758 6:0.0097410097 7:0.017634262 +1 1:0.693069 2:0.049505 3:0.024752 4:0.011070111 5:0.039032099 7:0.017296549 +1 1:0.773756 2:0.004525 3:0.0181 5:0.015468221 7:0.01329875 +1 1:0.773585 2:0.014151 3:0.023585 5:0.014335127 7:0.01495628 +1 1:0.761421 2:0.015228 3:0.035533 5:0.029997167 7:0.015383189 +1 1:0.745174 2:0.027027 3:0.025097 5:0.039710465 7:0.015467561 +1 1:0.773414 2:0.009063 3:0.060423 5:0.013932581 7:0.019711146 +1 1:0.717742 2:0.112903 3:0.024194 5:0.062640705 6:0.037815038 7:0.023406768 +1 1:0.766154 2:0.012308 3:0.036923 5:0.025762975 7:0.016285177 +1 1:0.731915 2:0.042553 3:0.034043 5:0.040441012 6:0.027126027 7:0.014348726 +1 1:0.646465 2:0.040404 3:0.065657 5:0.032621174 6:0.0065640066 7:0.014073665 +1 1:0.78934 2:0.007614 3:0.022843 5:0.014364946 7:0.016064134 +1 1:0.697987 2:0.026846 3:0.100671 5:0.014819674 7:0.020584384 +1 1:0.780576 2:0.007194 3:0.061151 5:0.015102948 7:0.021648537 +1 1:0.786364 2:0.009091 3:0.05 5:0.020015505 7:0.020648561 +1 1:0.761329 2:0.015106 3:0.036254 5:0.023220968 7:0.017740037 +1 1:0.764511 2:0.016584 3:0.054726 5:0.038368643 7:0.019647695 +1 1:0.760638 2:0.015957 3:0.042553 5:0.042036289 7:0.017254799 +1 1:0.755556 2:0.014815 3:0.007407 5:0.02070878 7:0.016260165 +1 1:0.697531 2:0.030864 3:0.04321 7:0.01163053 +1 1:0.777778 2:0.007407 3:0.02963 5:0.020589507 7:0.0163505 +1 1:0.677419 2:0.051613 3:0.051613 5:0.073807642 6:0.0074250074 7:0.015893 +1 1:0.795238 2:0.02381 3:0.057143 5:0.015691858 7:0.041376305 +1 1:0.763158 2:0.022556 3:0.071429 5:0.030548805 7:0.022373006 +1 1:0.8 2:0.007921 3:0.027723 5:0.0099891163 7:0.018027049 +1 1:0.772414 2:0.027586 3:0.034483 5:0.017003861 6:0.013683014 7:0.018439866 +1 1:0.753247 2:0.045455 3:0.058442 5:0.053151044 7:0.022212543 +1 1:0.771044 2:0.023569 3:0.063973 5:0.02789498 7:0.021947116 +1 1:0.763975 2:0.018634 3:0.037267 5:0.032412446 7:0.017421604 +1 1:0.730233 2:0.027907 3:0.037209 5:0.013358579 7:0.015825299 +1 1:0.748 2:0.032 3:0.04 5:0.010496027 7:0.017317073 +1 1:0.724638 2:0.036232 3:0.057971 4:0.0036900369 5:0.069208176 7:0.016657829 +1 1:0.792208 2:0.019481 3:0.045455 5:0.013008215 7:0.022687677 +1 1:0.665493 2:0.06338 3:0.098592 5:0.11557557 7:0.019387665 +1 1:0.757979 2:0.021277 3:0.029255 5:0.014953856 7:0.016168268 +1 1:0.73913 2:0.038043 3:0.054348 5:0.039032099 7:0.018988598 +1 1:0.67757 2:0.009346 3:0.158879 7:0.2513107 +1 1:0.717445 2:0.036855 3:0.068796 5:0.059584333 6:0.007992008 7:0.016869421 +1 1:0.780952 2:0.028571 3:0.028571 5:0.021894056 6:0.013215013 7:0.019773518 +1 1:0.771605 2:0.024691 3:0.030864 5:0.024413699 7:0.017238787 +1 1:0.744898 2:0.010204 3:0.056122 5:0.014305309 7:0.016208311 +1 1:0.765896 2:0.017341 3:0.026012 5:0.0081702026 7:0.016072183 +1 1:0.766284 2:0.019157 3:0.042146 5:0.040962832 7:0.017007756 +1 1:0.727273 2:0.035885 3:0.033493 5:0.036050274 6:0.011604012 7:0.015083439 +1 1:0.750751 2:0.027027 3:0.024024 5:0.026500977 7:0.015454476 +1 1:0.8 2:0.010667 3:0.034667 5:0.017428772 7:0.020861787 +1 1:0.745856 2:0.027624 3:0.055249 5:0.046769937 7:0.026849482 +1 1:0.784314 2:0.007843 3:0.019608 5:0.015214766 7:0.017575323 +1 1:0.7431 2:0.067941 3:0.023355 5:0.042543199 6:0.022827023 7:0.020415823 +1 1:0.754476 2:0.015345 3:0.048593 5:0.0067538354 7:0.01721664 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.761557 2:0.012165 3:0.036496 5:0.027328433 7:0.016185982 +1 1:0.691304 2:0.043478 3:0.073913 5:0.048409941 7:0.01633086 +1 1:0.764706 2:0.014706 3:0.044118 5:0.020313688 7:0.016454445 +1 1:0.763485 2:0.016598 3:0.03112 5:0.021528782 6:0.0043320043 7:0.017521 +1 1:0.791139 2:0.006329 3:0.012658 7:0.014935165 +1 1:0.779264 2:0.033445 3:0.036789 5:0.021275327 6:0.011418011 7:0.021433232 +1 1:0.780556 2:0.011111 3:0.033333 5:0.028640437 7:0.017632116 +1 1:0.689537 2:0.039451 3:0.034305 5:0.084445306 6:0.0037770038 7:0.016619256 +1 1:0.727273 2:0.020661 3:0.078512 5:0.020507507 7:0.018317878 +1 1:0.774436 2:0.022556 3:0.022556 7:0.018292683 +1 1:0.756039 2:0.021739 3:0.041063 5:0.019478777 6:0.0052260052 7:0.016908213 +1 1:0.761658 2:0.031088 3:0.041451 4:0.0036900369 5:0.039032099 7:0.018103122 +1 1:0.688073 2:0.039755 3:0.094801 5:0.068321083 7:0.018311329 +1 1:0.711268 2:0.035211 3:0.084507 5:0.068388174 7:0.018722091 +1 1:0.751412 2:0.050847 3:0.022599 5:0.046494118 6:0.024948025 7:0.016570207 +1 1:0.724265 2:0.058824 3:0.033088 5:0.049498308 6:0.027888028 7:0.016880378 +1 1:0.792793 2:0.014414 3:0.027027 5:0.016355314 7:0.020028567 +1 1:0.753383 2:0.03609 3:0.031579 5:0.022840785 6:0.015321015 7:0.017953421 +1 1:0.748137 2:0.011923 3:0.04769 5:0.014752583 6:0.0011880012 7:0.022954457 +1 1:0.741176 2:0.020588 3:0.041176 4:0.0036900369 5:0.039069372 7:0.017109037 +1 1:0.753363 2:0.013453 3:0.040359 5:0.02781298 7:0.014656018 +1 1:0.751479 2:0.017751 3:0.029586 5:0.032412446 7:0.016596915 +1 1:0.794702 2:0.013245 3:0.033113 5:0.014819674 7:0.020311744 +1 1:0.776 2:0.016 3:0.032 5:0.021424418 7:0.01697561 +1 1:0.74359 2:0.023077 3:0.028205 5:0.016116768 6:0.0064860065 7:0.014462165 +1 1:0.727778 2:0.011111 3:0.066667 5:0.014253127 7:0.017716799 +1 1:0.767606 2:0.028169 3:0.025822 5:0.023891879 6:0.0096150096 7:0.017863274 +1 1:0.75 2:0.0125 3:0.04375 5:0.019359504 7:0.014672256 +1 1:0.769928 2:0.014493 3:0.03442 5:0.029192074 7:0.016922939 +1 1:0.775915 2:0.015244 3:0.035061 5:0.02626243 7:0.018469287 +1 1:0.716895 2:0.027397 3:0.045662 4:0.0036900369 5:0.085518763 6:0.0057360057 7:0.014561756 +1 1:0.789474 2:0.009288 3:0.021672 5:0.015259493 7:0.018443707 +1 1:0.777551 2:0.008163 3:0.044898 5:0.014148763 7:0.01967397 +1 1:0.708738 2:0.067961 3:0.029126 5:0.025613883 6:0.048111048 7:0.017227091 +1 1:0.8 2:0.009756 3:0.034146 5:0.011524757 7:0.0192445 +1 1:0.747126 2:0.051724 3:0.034483 5:0.011345847 6:0.012177012 7:0.034535323 +1 1:0.740458 2:0.015267 3:0.061069 5:0.041298287 7:0.016803201 +1 1:0.744737 2:0.034211 3:0.026316 5:0.038189734 7:0.015661104 +1 1:0.771543 2:0.02004 3:0.028056 5:0.021528782 7:0.016924091 +1 1:0.798781 2:0.02439 3:0.030488 5:0.014335127 6:0.011538012 7:0.019333732 +1 1:0.784173 2:0.014388 3:0.028777 7:0.018512018 +1 1:0.790055 2:0.01105 3:0.022099 5:0.0069774723 6:0.0056190056 7:0.017989488 +1 1:0.774194 2:0.008065 3:0.024194 5:0.023742788 7:0.015440598 +1 1:0.756906 2:0.022099 3:0.033149 5:0.023638424 7:0.015934512 +1 1:0.748837 2:0.009302 3:0.060465 5:0.025054791 7:0.016874646 +1 1:0.747863 2:0.021368 3:0.047009 5:0.047709212 7:0.01628622 +1 1:0.761905 2:0.010582 3:0.031746 5:0.020067687 7:0.023970835 +1 1:0.7897 2:0.01073 3:0.032189 5:0.015371312 7:0.019038524 +1 1:0.7375 2:0.01875 3:0.0375 5:0.019985687 7:0.014214939 +1 1:0.79351 2:0.0059 3:0.044248 5:0.0066121986 7:0.020289232 +1 1:0.760976 2:0.019512 3:0.029268 5:0.026814068 7:0.016537774 +1 1:0.744417 2:0.032258 3:0.039702 5:0.049699581 7:0.018156512 +1 1:0.788396 2:0.017065 3:0.030717 5:0.016049677 7:0.019333226 +1 1:0.7875 2:0.0125 3:0.05 5:0.02781298 7:0.020426829 +1 1:0.796651 2:0.019139 3:0.026316 5:0.015423494 6:0.0062070062 7:0.021151823 +1 1:0.758491 2:0.022642 3:0.033962 5:0.010264935 7:0.016705018 +1 1:0.656 2:0.04 3:0.048 5:0.097319339 7:0.018682927 8:0.023809524 +1 1:0.743243 2:0.022523 3:0.033033 5:0.050266128 7:0.017651799 +1 1:0.725111 2:0.029718 3:0.05052 5:0.044138476 7:0.015302793 +1 1:0.782274 2:0.015414 3:0.025048 5:0.015416039 6:0.0020670021 7:0.017047323 +1 1:0.773784 2:0.010571 3:0.038055 5:0.016139132 7:0.017867274 8:0.023809524 +1 1:0.788591 2:0.006711 3:0.026846 5:0.017577863 7:0.017351451 +1 1:0.790123 2:0.006173 3:0.024691 5:0.016981498 7:0.01652364 +1 1:0.768683 2:0.010676 3:0.039146 5:0.017316953 7:0.018683274 +1 1:0.708333 2:0.013889 3:0.069444 5:0.041186468 7:0.015328591 +1 1:0.677419 2:0.08871 3:0.040323 5:0.10074098 6:0.03040503 7:0.01455547 +1 1:0.762195 2:0.02439 3:0.04878 5:0.025017518 7:0.022159427 +1 1:0.756098 2:0.02439 3:0.02439 7:0.015070396 +1 1:0.745455 2:0.016364 3:0.034545 5:0.036363365 7:0.018181817 +1 1:0.726667 2:0.033333 3:0.053333 5:0.072547821 7:0.016707317 +1 1:0.744361 2:0.028195 3:0.050752 5:0.020172051 7:0.016940213 +1 1:0.738916 2:0.029557 3:0.029557 5:0.03080226 7:0.014538024 +1 1:0.788151 2:0.021544 3:0.035907 5:0.011427847 6:0.0091980092 7:0.021423567 +1 1:0.752363 2:0.024575 3:0.032136 5:0.022810967 7:0.015065244 +1 1:0.767123 2:0.013699 3:0.034247 5:0.02662025 7:0.017540927 +1 1:0.764228 2:0.01626 3:0.01626 7:0.01511997 +1 1:0.783476 2:0.014245 3:0.037037 5:0.018986776 7:0.020464177 +1 1:0.764398 2:0.020942 3:0.062827 5:0.046084117 7:0.020655085 +1 1:0.75 2:0.023438 3:0.101562 4:0.0036900369 5:0.0092511145 7:0.038395579 +1 1:0.770781 2:0.007557 3:0.042821 5:0.019463868 7:0.017647604 +1 1:0.781609 2:0.013793 3:0.029885 5:0.016422405 6:0.0044040044 7:0.019091671 +1 1:0.774403 2:0.006508 3:0.0282 5:0.012262758 7:0.016083805 +1 1:0.77439 2:0.012195 3:0.018293 5:0.017831318 7:0.015541341 +1 1:0.762082 2:0.01487 3:0.04461 5:0.027440252 7:0.018474024 +1 1:0.78626 2:0.030534 3:0.030534 5:0.015468221 7:0.022435299 +1 1:0.742902 2:0.020505 3:0.044164 5:0.025971702 6:0.0034830035 7:0.016561512 +1 1:0.758929 2:0.008929 3:0.041667 5:0.027104796 7:0.014971689 +1 1:0.753138 2:0.025105 3:0.033473 5:0.011576939 7:0.01643025 +1 1:0.748936 2:0.014894 3:0.02766 5:0.038398461 7:0.01763103 +1 1:0.758993 2:0.028777 3:0.028777 5:0.034469906 6:0.0034680035 7:0.018972628 +1 1:0.77095 2:0.011173 3:0.027933 5:0.016310587 7:0.015567518 +1 1:0.724868 2:0.026455 3:0.071429 5:0.029892803 7:0.0201155 +1 1:0.787004 2:0.00722 3:0.025271 5:0.01951605 7:0.016817823 +1 1:0.763206 2:0.029144 3:0.041894 5:0.040493194 7:0.020447378 +1 1:0.767213 2:0.016393 3:0.029508 5:0.018681138 7:0.015953616 +1 1:0.704348 2:0.034783 3:0.03913 5:0.072726731 7:0.016304348 +1 1:0.744589 2:0.021645 3:0.038961 5:0.027358251 7:0.014386018 +1 1:0.751111 2:0.031111 3:0.035556 5:0.012762214 6:0.0051360051 7:0.015826561 +1 1:0.760234 2:0.01462 3:0.046784 5:0.01634786 7:0.016260165 +1 1:0.750794 2:0.028571 3:0.034921 5:0.02567352 7:0.016860238 +1 1:0.77561 2:0.029268 3:0.063415 5:0.028342254 7:0.023468171 +1 1:0.671642 2:0.129353 3:0.029851 5:0.034350633 6:0.082950083 7:0.019748817 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.766917 2:0.015038 3:0.037594 7:0.018063451 +1 1:0.731884 2:0.007246 3:0.065217 5:0.020939871 7:0.015729939 +1 1:0.775432 2:0.011516 3:0.028791 5:0.026642613 7:0.016373299 +1 1:0.785311 2:0.014124 3:0.025424 5:0.014968765 6:0.006024006 7:0.017155848 +1 1:0.714754 2:0.059016 3:0.032787 5:0.034790452 6:0.031506032 7:0.017133146 +1 1:0.805556 2:0.013889 3:0.020833 7:0.020494579 +1 1:0.767059 2:0.014118 3:0.037647 5:0.012508759 7:0.017101866 +1 1:0.747368 2:0.015789 3:0.047368 5:0.045361025 7:0.015821567 +1 1:0.764228 2:0.00813 3:0.04878 5:0.022289148 7:0.01658239 +1 1:0.763033 2:0.014218 3:0.047393 5:0.023705515 7:0.018177091 +1 1:0.673333 2:0.046667 3:0.12 5:0.097021156 7:0.018739835 +1 1:0.71464 2:0.032258 3:0.049628 5:0.046881756 7:0.016840165 +1 1:0.773994 2:0.021672 3:0.024768 5:0.015893131 6:0.0095940096 7:0.01770747 +1 1:0.774648 2:0.023474 3:0.028169 5:0.021513873 6:0.0043290043 7:0.019838543 +1 1:0.761364 2:0.034091 3:0.051136 5:0.032226082 7:0.024043793 +1 1:0.78733 2:0.00905 3:0.0181 7:0.016140604 +1 1:0.738516 2:0.024735 3:0.053004 5:0.048409941 7:0.016590537 +1 1:0.756579 2:0.046053 3:0.026316 5:0.026814068 6:0.016188016 7:0.022304238 +1 1:0.72973 2:0.023166 3:0.034749 5:0.012963488 7:0.013537055 +1 1:0.774359 2:0.020513 3:0.025641 5:0.019478777 6:0.0052260052 7:0.01794872 8:0.023809524 +1 1:0.688073 2:0.039755 3:0.094801 5:0.068321083 7:0.018311329 +1 1:0.770718 2:0.019337 3:0.041436 5:0.036601911 7:0.020583482 +1 1:0.710744 2:0.033058 3:0.049587 5:0.068842903 7:0.01909897 +1 1:0.668269 2:0.043269 3:0.043269 5:0.062752523 7:0.017413226 +1 1:0.796053 2:0.026316 3:0.039474 5:0.012590759 6:0.01013401 7:0.023748396 +1 1:0.717391 2:0.021739 3:0.065217 5:0.063535253 7:0.015553201 +1 1:0.74026 2:0.038961 3:0.064935 5:0.071407273 7:0.020668354 +1 1:0.757642 2:0.008734 3:0.026201 5:0.026814068 7:0.014804561 +1 1:0.741538 2:0.024615 3:0.064615 5:0.056423598 7:0.019831146 +1 1:0.693548 2:0.072581 3:0.08871 5:0.043445201 6:0.01049101 7:0.042191189 +1 1:0.674419 2:0.093023 3:0.03876 5:0.11380884 6:0.038169038 7:0.018576293 +1 1:0.742373 2:0.030508 3:0.030508 5:0.041298287 7:0.014923524 +1 1:0.75419 2:0.011173 3:0.053073 5:0.014104036 7:0.018003134 +1 1:0.738351 2:0.032258 3:0.032258 5:0.053479045 6:0.0043050043 7:0.015232976 +1 1:0.715 2:0.03 3:0.065 5:0.058816513 7:0.015457317 +1 1:0.75969 2:0.023256 3:0.031008 5:0.022386057 6:0.009009009 7:0.015740213 +1 1:0.724138 2:0.078818 3:0.039409 5:0.044570841 6:0.04035904 7:0.020094921 +1 1:0.780899 2:0.005618 3:0.033708 7:0.01805289 +1 1:0.712575 2:0.077844 3:0.05988 5:0.070594725 6:0.034092034 7:0.019278518 +1 1:0.710526 2:0.040936 3:0.064327 5:0.084534761 7:0.01729425 +1 1:0.805556 2:0.009259 3:0.023148 7:0.019619463 +1 1:0.773196 2:0.005155 3:0.046392 5:0.013858035 7:0.016909732 +1 1:0.782946 2:0.007752 3:0.054264 5:0.017876046 7:0.01971072 +1 1:0.653595 2:0.039216 3:0.052288 5:0.10994737 7:0.01351028 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.792 2:0.012 3:0.026 5:0.013872944 6:0.0037230037 7:0.019658537 +1 1:0.738197 2:0.025751 3:0.042918 5:0.048790124 7:0.01999372 +1 1:0.767888 2:0.015707 3:0.031414 5:0.022982422 6:0.0036990037 7:0.017260457 +1 1:0.749206 2:0.025397 3:0.050794 5:0.022892967 7:0.031513744 +1 1:0.762295 2:0.012295 3:0.032787 5:0.021148599 7:0.017617951 +1 1:0.739726 2:0.020548 3:0.075342 5:0.050370492 7:0.018543268 +1 1:0.785235 2:0.010067 3:0.040268 5:0.015691858 7:0.01943853 +1 1:0.765152 2:0.015152 3:0.034091 5:0.011025301 7:0.015613451 +1 1:0.747664 2:0.03271 3:0.037383 5:0.012941124 7:0.016412128 +1 1:0.743243 2:0.047297 3:0.054054 5:0.01505822 6:0.024243024 7:0.020393866 +1 1:0.661538 2:0.092308 3:0.1 5:0.075507283 7:0.050938091 +1 1:0.74359 2:0.041026 3:0.05641 5:0.053456682 6:0.0047820048 7:0.01962164 +1 1:0.786008 2:0.00823 3:0.037037 5:0.020678962 7:0.018091939 +1 1:0.771429 2:0.013187 3:0.035165 5:0.020835508 7:0.019177165 +1 1:0.773554 2:0.006612 3:0.036364 5:0.013835672 7:0.016287037 +1 1:0.693431 2:0.051095 3:0.043796 5:0.021670419 7:0.015310665 +1 1:0.572289 2:0.10241 3:0.204819 4:0.055350554 5:0.12793523 7:0.032104024 +1 1:0.754098 2:0.043716 3:0.027322 5:0.03790646 6:0.02034002 7:0.019658805 +1 1:0.769565 2:0.013043 3:0.03913 5:0.029937531 7:0.019803817 +1 1:0.754991 2:0.025408 3:0.052632 5:0.046695392 7:0.019432518 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.790146 2:0.020073 3:0.020073 5:0.01909114 6:0.011523012 7:0.017380274 +1 1:0.738149 2:0.029345 3:0.045147 5:0.058905968 6:0.0079020079 7:0.015677476 +1 1:0.733096 2:0.035587 3:0.042705 5:0.057713238 7:0.016817116 +1 1:0.659722 2:0.013889 3:0.138889 5:0.019113503 7:0.016514226 +1 1:0.785714 2:0.016129 3:0.032258 5:0.021424418 7:0.019557152 +1 1:0.753333 2:0.013333 3:0.106667 5:0.0050243764 7:0.060325201 +1 1:0.798578 2:0.016588 3:0.028436 5:0.01634786 6:0.0043860044 7:0.0197665 +1 1:0.78629 2:0.008065 3:0.028226 5:0.020619325 7:0.01777636 +1 1:0.742424 2:0.037879 3:0.026515 5:0.015423494 6:0.014484014 7:0.016745195 +1 1:0.767742 2:0.016129 3:0.03871 5:0.025472247 7:0.017269866 +1 1:0.685315 2:0.052448 3:0.020979 5:0.07308455 6:0.021009021 7:0.015222585 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.755208 2:0.026042 3:0.046875 5:0.051011584 7:0.018562628 +1 1:0.772871 2:0.009464 3:0.037855 5:0.026843887 7:0.016022927 +1 1:0.724409 2:0.062992 3:0.031496 5:0.069454177 6:0.027951028 7:0.015459957 +1 1:0.714286 2:0.026455 3:0.068783 5:0.063311616 7:0.015195512 +1 1:0.777523 2:0.006881 3:0.045872 5:0.015110402 7:0.02069814 +1 1:0.776 2:0.008 3:0.032 5:0.023295514 7:0.015609756 +1 1:0.76 2:0.025 3:0.04 4:0.0036900369 5:0.005784742 6:0.011646012 7:0.019634146 +1 1:0.76 2:0.011429 3:0.04 5:0.024875882 7:0.015662018 +1 1:0.707483 2:0.040816 3:0.081633 5:0.03516318 7:0.017587524 +1 1:0.752066 2:0.016529 3:0.016529 5:0.030056804 7:0.012497482 +1 1:0.652893 2:0.132231 3:0.024793 4:0.0036900369 5:0.05869724 6:0.086613087 7:0.019199756 +1 1:0.773585 2:0.012579 3:0.113208 5:0.0098102068 7:0.029145573 +1 1:0.625899 2:0.064748 3:0.028777 5:0.087292949 6:0.014052014 7:0.018731354 +1 1:0.734082 2:0.037453 3:0.06367 5:0.073010004 7:0.022152189 +1 1:0.748466 2:0.018405 3:0.042945 5:0.035110998 7:0.015886079 +1 1:0.767152 2:0.037422 3:0.031185 5:0.027074978 6:0.016344016 7:0.02094214 +1 1:0.791667 2:0.015152 3:0.037879 5:0.024331698 7:0.021225982 +1 1:0.759124 2:0.021898 3:0.036496 5:0.039755192 7:0.016690402 +1 1:0.768374 2:0.008909 3:0.020045 5:0.012732396 7:0.015902549 +1 1:0.765193 2:0.024862 3:0.038674 5:0.039971374 7:0.018848537 +1 1:0.746667 2:0.02 3:0.053333 5:0.037272822 7:0.016260165 +1 1:0.752322 2:0.03096 3:0.034056 5:0.034514633 6:0.0069450069 7:0.016310506 +1 1:0.722543 2:0.017341 3:0.052023 5:0.018971866 7:0.013851683 +1 1:0.770588 2:0.009804 3:0.039216 5:0.025323155 7:0.017599238 +1 1:0.69863 2:0.041096 3:0.041096 5:0.044108658 7:0.014116268 +1 1:0.80663 2:0.005525 3:0.016575 7:0.019370701 +1 1:0.720497 2:0.031056 3:0.074534 5:0.032621174 7:0.017307982 +1 1:0.786008 2:0.00823 3:0.041152 5:0.019694959 7:0.01899528 +1 1:0.797619 2:0.011905 3:0.019841 7:0.020397793 +1 1:0.747649 2:0.029781 3:0.021944 5:0.042595381 6:0.012468012 7:0.018397811 +1 1:0.793846 2:0.018462 3:0.036923 5:0.020462779 7:0.020506567 +1 1:0.742972 2:0.02008 3:0.048193 5:0.034089723 7:0.016064256 +1 1:0.744186 2:0.023256 3:0.032558 5:0.044459022 7:0.014265457 +1 1:0.729469 2:0.043478 3:0.028986 5:0.046799755 6:0.013452013 7:0.016422177 +1 1:0.725256 2:0.037543 3:0.054608 4:0.0036900369 5:0.023153877 6:0.015528016 7:0.02010322 +1 1:0.718563 2:0.041916 3:0.053892 4:0.011070111 5:0.086182219 6:0.0069360069 7:0.015791585 +1 1:0.705696 2:0.028481 3:0.056962 5:0.042304653 6:0.0068100068 7:0.016999848 +1 1:0.787234 2:0.012766 3:0.034043 5:0.019620414 7:0.019719774 +1 1:0.739837 2:0.01084 3:0.04336 5:0.014879311 7:0.016557604 +1 1:0.793548 2:0.006452 3:0.045161 5:0.006880563 7:0.021321793 +1 1:0.784091 2:0.017045 3:0.039773 5:0.023556424 7:0.021930433 +1 1:0.779762 2:0.005952 3:0.017857 5:0.014506582 7:0.018655634 +1 1:0.781553 2:0.009709 3:0.029126 5:0.02480879 7:0.017789488 +1 1:0.786408 2:0.009709 3:0.043689 5:0.021513873 7:0.020512671 +1 1:0.741497 2:0.020408 3:0.040816 5:0.03842828 7:0.016094244 +1 1:0.798507 2:0.007463 3:0.044776 5:0.015214766 7:0.022297049 +1 1:0.646465 2:0.138047 3:0.053872 5:0.014730219 6:0.08004008 7:0.020776878 +1 1:0.759644 2:0.011869 3:0.026706 5:0.017018771 7:0.015850037 +1 1:0.73743 2:0.022346 3:0.039106 5:0.016862225 7:0.015056549 +1 1:0.768194 2:0.040431 3:0.021563 5:0.013455489 6:0.024369024 7:0.018210506 +1 1:0.712446 2:0.042918 3:0.051502 4:0.0036900369 5:0.024972791 6:0.01005001 7:0.015623366 +1 1:0.782051 2:0.012821 3:0.025641 5:0.016221132 7:0.017960445 +1 1:0.720217 2:0.021661 3:0.068592 5:0.030198441 7:0.016300518 +1 1:0.717949 2:0.025641 3:0.064103 7:0.015361165 +1 1:0.752212 2:0.022124 3:0.026549 5:0.027455161 7:0.014650335 +1 1:0.760234 2:0.017544 3:0.040936 5:0.016206223 7:0.016402793 +1 1:0.748593 2:0.022514 3:0.0394 5:0.035811728 7:0.016668189 +1 1:0.753304 2:0.061674 3:0.017621 5:0.020149688 6:0.036486036 7:0.019877512 +1 1:0.769556 2:0.010571 3:0.033827 5:0.016765315 7:0.017196927 +1 1:0.813471 2:0.005181 3:0.031088 5:0.009772934 7:0.024105902 +1 1:0.715278 2:0.048611 3:0.059028 5:0.050653765 7:0.018694951 +1 1:0.747212 2:0.026022 3:0.02974 5:0.025867339 7:0.016331945 +1 1:0.762987 2:0.022727 3:0.032468 5:0.017704591 7:0.016669305 +1 1:0.709763 2:0.036939 3:0.044855 5:0.054410866 7:0.013224787 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.772455 2:0.005988 3:0.032934 5:0.016787679 7:0.016211482 +1 1:0.80315 2:0.007874 3:0.031496 7:0.019300939 +1 1:0.738255 2:0.013423 3:0.067114 5:0.036363365 7:0.016778524 +1 1:0.737374 2:0.037879 3:0.042929 5:0.06144052 6:0.0027480027 7:0.016814488 +1 1:0.703226 2:0.045161 3:0.096774 5:0.068895084 7:0.021282457 +1 1:0.771898 2:0.014599 3:0.036496 5:0.032904447 7:0.017647323 +1 1:0.727273 2:0.033058 3:0.082645 6:0.017823018 7:0.0254485 +1 1:0.700637 2:0.070064 3:0.025478 5:0.079092929 6:0.031830032 7:0.014641915 +1 1:0.799065 2:0.004673 3:0.028037 7:0.018093232 +1 1:0.715254 2:0.067797 3:0.033898 5:0.019165685 6:0.05013005 7:0.016081024 +1 1:0.750611 2:0.01956 3:0.0489 5:0.04483175 7:0.017353451 +1 1:0.74269 2:0.017544 3:0.046784 5:0.034119541 7:0.015582659 +1 1:0.754045 2:0.022654 3:0.022654 5:0.02070878 7:0.014207909 +1 1:0.742857 2:0.019048 3:0.071429 5:0.04424284 7:0.019570268 +1 1:0.769811 2:0.011321 3:0.041509 5:0.019016594 7:0.018039579 +1 1:0.77037 2:0.018519 3:0.02963 5:0.010182935 7:0.016531165 +1 1:0.779434 2:0.011923 3:0.031297 5:0.019493686 7:0.017374866 +1 1:0.721184 2:0.021807 3:0.070093 5:0.059368151 7:0.016697061 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.760784 2:0.019608 3:0.035294 5:0.022624603 6:0.0091050091 7:0.015758012 +1 1:0.759777 2:0.022346 3:0.022346 5:0.015997495 7:0.015874098 +1 1:0.742424 2:0.05303 3:0.060606 5:0.0095791153 6:0.015423015 7:0.035938652 +1 1:0.783654 2:0.004808 3:0.019231 7:0.016826921 +1 1:0.755814 2:0.020349 3:0.034884 5:0.042647563 7:0.015492061 +1 1:0.744186 2:0.023256 3:0.032558 5:0.044459022 7:0.014265457 +1 1:0.775401 2:0.005348 3:0.048128 7:0.018586146 +1 1:0.742475 2:0.026756 3:0.033445 5:0.044548477 7:0.020474756 +1 1:0.788961 2:0.00974 3:0.025974 5:0.022609694 7:0.019579506 8:0.023809524 +1 1:0.566038 2:0.106918 3:0.09434 5:0.2196562 7:0.020823744 +1 1:0.72093 2:0.032558 3:0.046512 5:0.029579712 7:0.014293817 +1 1:0.795539 2:0.007435 3:0.02974 5:0.017890955 7:0.018893372 +1 1:0.773973 2:0.006849 3:0.054795 5:0.016601315 7:0.018752085 +1 1:0.727679 2:0.03125 3:0.0625 5:0.075417828 7:0.017489659 +1 1:0.786885 2:0.005464 3:0.027322 5:0.014282945 7:0.017393043 +1 1:0.726984 2:0.034921 3:0.038095 5:0.029736258 7:0.01455672 +1 1:0.773723 2:0.012165 3:0.053528 5:0.018181683 7:0.024330902 +1 1:0.721311 2:0.02459 3:0.040984 5:0.029467893 7:0.012644945 +1 1:0.781942 2:0.010221 3:0.037479 5:0.0040925559 7:0.018905555 +1 1:0.753555 2:0.023697 3:0.023697 5:0.023079331 7:0.01866836 +1 1:0.704724 2:0.043307 3:0.082677 5:0.095813517 7:0.01867678 +1 1:0.762712 2:0.038741 3:0.050847 5:0.016019859 6:0.00080700081 7:0.054966634 +1 1:0.795732 2:0.006098 3:0.04878 7:0.022772902 +1 1:0.800687 2:0.013746 3:0.024055 5:0.033060993 7:0.018900341 8:0.023809524 +1 1:0.759825 2:0.026201 3:0.030568 5:0.023295514 6:0.0046890047 7:0.01704122 +1 1:0.755102 2:0.023324 3:0.055394 5:0.027969526 7:0.018950439 +1 1:0.790179 2:0.008929 3:0.040179 5:0.020939871 7:0.01938153 +1 1:0.777439 2:0.018293 3:0.04878 5:0.031219716 7:0.02219661 +1 1:0.765487 2:0.044248 3:0.026549 5:0.010399117 6:0.025104025 7:0.019344915 +1 1:0.609756 2:0.067073 3:0.067073 4:0.0036900369 5:0.1043639 6:0.012000012 7:0.018590122 +1 1:0.731884 2:0.043478 3:0.043478 5:0.035670091 7:0.018469427 +1 1:0.712389 2:0.044248 3:0.061947 5:0.078943837 7:0.017834018 +1 1:0.767068 2:0.014056 3:0.034137 5:0.033478449 7:0.016358116 +1 1:0.788779 2:0.013201 3:0.034653 5:0.0142904 6:0.0028740029 7:0.020999354 +1 1:0.782609 2:0.012422 3:0.043478 5:0.015729131 7:0.017951823 +1 1:0.718121 2:0.067114 3:0.033557 5:0.050594129 6:0.027150027 7:0.018088067 +1 1:0.807273 2:0.003636 3:0.029091 5:0.0074992918 7:0.022039909 +1 1:0.732 2:0.056 3:0.032 5:0.043340838 6:0.021801022 7:0.016780488 +1 1:0.770089 2:0.008929 3:0.029018 5:0.027007887 7:0.015026134 +1 1:0.784689 2:0.004785 3:0.033493 5:0.012382032 7:0.017563311 +1 1:0.783582 2:0.014925 3:0.029851 5:0.019985687 7:0.016973061 +1 1:0.753695 2:0.019704 3:0.029557 5:0.030996079 7:0.014447915 +1 1:0.731343 2:0.064677 3:0.034826 5:0.057429964 6:0.018489018 7:0.019688146 +1 1:0.771084 2:0.018072 3:0.024096 5:0.017018771 7:0.016088744 +1 1:0.765013 2:0.020888 3:0.020888 5:0.015155129 7:0.015665799 +1 1:0.767918 2:0.011945 3:0.037543 5:0.032822447 7:0.016544573 +1 1:0.758465 2:0.022573 3:0.027088 5:0.026433885 7:0.015526067 +1 1:0.773389 2:0.022869 3:0.033264 5:0.023742788 6:0.0076440076 7:0.01990264 +1 1:0.722222 2:0.039683 3:0.087302 5:0.062171067 7:0.021276939 +1 1:0.777778 2:0.005848 3:0.032164 5:0.017003861 7:0.01563614 +1 1:0.742547 2:0.059621 3:0.0271 5:0.048588851 6:0.027933028 7:0.017747372 +1 1:0.737589 2:0.028369 3:0.042553 5:0.020939871 7:0.015395262 +1 1:0.801546 2:0.002577 3:0.036082 5:0.0061649248 7:0.018999872 +1 1:0.706587 2:0.035928 3:0.035928 5:0.051175585 7:0.01595589 +1 1:0.73913 2:0.012422 3:0.043478 5:0.01762259 7:0.016020299 +1 1:0.771379 2:0.015707 3:0.029668 5:0.027663889 7:0.017207256 +1 1:0.73494 2:0.032129 3:0.054217 5:0.064221073 7:0.018476341 +1 1:0.658065 2:0.058065 3:0.051613 4:0.0036900369 5:0.1183263 7:0.019826909 +1 1:0.737336 2:0.018762 3:0.041276 5:0.043885021 7:0.01360225 +1 1:0.76 2:0.02 3:0.031429 5:0.0084534761 6:0.0068040068 7:0.015365854 +1 1:0.712644 2:0.034483 3:0.109195 4:0.011070111 5:0.033731904 7:0.023233811 +1 1:0.788945 2:0.01005 3:0.015075 7:0.016638067 +1 1:0.789174 2:0.011396 3:0.037037 5:0.025971702 7:0.019943018 +1 1:0.710623 2:0.007326 3:0.076923 5:0.020477688 7:0.016260165 +1 1:0.761538 2:0.02 3:0.027692 5:0.022318966 6:0.0017970018 7:0.015666043 +1 1:0.716216 2:0.044402 3:0.03668 5:0.027880071 6:0.022437022 7:0.015738299 +1 1:0.729323 2:0.022556 3:0.06015 5:0.040843559 7:0.016733909 +1 1:0.768473 2:0.009852 3:0.039409 5:0.025487156 7:0.017571787 +1 1:0.77027 2:0.006757 3:0.040541 5:0.0093182055 7:0.016479896 +1 1:0.7 2:0.05 3:0.03125 5:0.072726731 7:0.015625 +1 1:0.766667 2:0.008333 3:0.045833 5:0.02242333 7:0.016895323 +1 1:0.691964 2:0.049107 3:0.066964 5:0.0062021976 6:0.012480012 7:0.032719945 +1 1:0.741935 2:0.032258 3:0.048387 5:0.022318966 7:0.016424073 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.767327 2:0.024752 3:0.034653 6:0.015228015 7:0.017839896 +1 1:0.747525 2:0.019802 3:0.049505 5:0.025442428 7:0.017688963 +1 1:0.756322 2:0.011494 3:0.03908 5:0.020805689 7:0.015068683 +1 1:0.744125 2:0.023499 3:0.023499 5:0.026530795 6:0.0071160071 7:0.013421 +1 1:0.753894 2:0.024922 3:0.040498 5:0.024227334 7:0.01753286 +1 1:0.744526 2:0.036496 3:0.032847 5:0.02079078 6:0.016737017 7:0.015956024 +1 1:0.75098 2:0.029412 3:0.031373 5:0.020835508 6:0.0041940042 7:0.017109037 +1 1:0.787879 2:0.012121 3:0.042424 5:0.025270973 7:0.021803402 +1 1:0.760976 2:0.014634 3:0.034146 5:0.036013001 7:0.018471146 +1 1:0.764411 2:0.015038 3:0.030075 5:0.029177165 7:0.015618317 +1 1:0.768595 2:0.049587 3:0.024793 5:0.033128084 6:0.02000102 7:0.022676878 +1 1:0.747082 2:0.015564 3:0.050584 5:0.033880995 7:0.015659104 +1 1:0.793103 2:0.013793 3:0.031034 5:0.014446946 7:0.021698909 +1 1:0.744526 2:0.021898 3:0.014599 5:0.026814068 7:0.012373152 +1 1:0.625698 2:0.083799 3:0.050279 4:0.0036900369 5:0.14382091 6:0.0096450096 7:0.021188171 +1 1:0.760933 2:0.017493 3:0.049563 5:0.038890463 7:0.02044372 +1 1:0.775229 2:0.009174 3:0.06422 5:0.0096834792 7:0.021537256 +1 1:0.710623 2:0.007326 3:0.076923 5:0.020477688 7:0.016260165 +1 1:0.774411 2:0.020202 3:0.037037 5:0.033165357 7:0.018456927 +1 1:0.758475 2:0.016949 3:0.038136 5:0.036013001 7:0.016044854 +1 1:0.680952 2:0.047619 3:0.052381 5:0.014819674 6:0.017892018 7:0.01460511 +1 1:0.748 2:0.022 3:0.044 5:0.022438239 7:0.016207317 +1 1:0.76124 2:0.024806 3:0.04031 5:0.0427892 7:0.021412366 +1 1:0.778626 2:0.003817 3:0.019084 5:0.011129665 7:0.015593 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.762774 2:0.023723 3:0.029197 5:0.015050766 6:0.002019002 7:0.016534628 +1 1:0.69403 2:0.052239 3:0.037313 5:0.027402979 6:0.011028011 7:0.01237714 +1 1:0.780105 2:0.031414 3:0.057592 5:0.040165193 7:0.029625848 +1 1:0.787671 2:0.013699 3:0.047945 5:0.014760038 7:0.021090878 +1 1:0.737762 2:0.048951 3:0.027972 5:0.018092228 6:0.025485025 7:0.017567799 +1 1:0.761905 2:0.02381 3:0.047619 5:0.038323916 7:0.018825006 +1 1:0.684615 2:0.066667 3:0.046154 5:0.087777496 6:0.013587014 7:0.017260787 +1 1:0.779817 2:0.012232 3:0.036697 5:0.02908771 7:0.019113152 +1 1:0.767635 2:0.016598 3:0.041494 5:0.03970301 7:0.019001116 +1 1:0.753623 2:0.007246 3:0.065217 5:0.017876046 7:0.018425238 +1 1:0.762523 2:0.020408 3:0.033395 5:0.028468982 7:0.017772299 +1 1:0.733333 2:0.037037 3:0.037037 5:0.01951605 7:0.017253841 +1 1:0.763912 2:0.011804 3:0.047218 5:0.026657522 7:0.01725414 +1 1:0.8 2:0.006452 3:0.012903 7:0.018135329 +1 1:0.7713 2:0.013453 3:0.03139 5:0.025017518 7:0.016296622 +1 1:0.674419 2:0.093023 3:0.03876 5:0.11380884 6:0.038169038 7:0.018576293 +1 1:0.694656 2:0.022901 3:0.10687 5:0.020313688 7:0.017082482 +1 1:0.754902 2:0.019608 3:0.04902 5:0.054217047 7:0.016439506 +1 1:0.761905 2:0.019841 3:0.051587 5:0.046911574 7:0.019224256 +1 1:0.788419 2:0.008909 3:0.033408 5:0.010540754 7:0.019202561 +1 1:0.783217 2:0.011655 3:0.016317 5:0.0065078347 7:0.016274378 +1 1:0.765854 2:0.02439 3:0.039024 5:0.036601911 7:0.018173707 +1 1:0.779497 2:0.005803 3:0.038685 5:0.0141264 7:0.018670098 +1 1:0.78481 2:0.006329 3:0.025316 5:0.017100771 7:0.016826183 +1 1:0.780347 2:0.034682 3:0.034682 5:0.012784578 6:0.015438015 7:0.020548427 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.75122 2:0.017073 3:0.029268 5:0.021841874 7:0.01522903 +1 1:0.769406 2:0.022831 3:0.018265 5:0.013336216 7:0.015564091 +1 1:0.741379 2:0.025862 3:0.038793 5:0.023742788 6:0.0047760048 7:0.01650547 +1 1:0.721973 2:0.008969 3:0.049327 7:0.016159902 +1 1:0.788119 2:0.00396 3:0.041584 5:0.0092287508 7:0.019512195 +1 1:0.771717 2:0.014141 3:0.034343 5:0.034015177 7:0.016198573 +1 1:0.729167 2:0.03869 3:0.047619 5:0.030839533 6:0.0093060093 7:0.017548634 +1 1:0.670157 2:0.068063 3:0.104712 5:0.025293337 7:0.094081213 +1 1:0.707094 2:0.036613 3:0.075515 5:0.069372177 7:0.016492713 +1 1:0.758621 2:0.027586 3:0.027586 5:0.019314776 7:0.016232128 +1 1:0.724907 2:0.05948 3:0.037175 5:0.016862225 6:0.030543031 7:0.020038079 +1 1:0.781362 2:0.010753 3:0.046595 5:0.023347696 7:0.020937146 +1 1:0.770732 2:0.009756 3:0.043902 5:0.024309335 7:0.01824311 +1 1:0.78125 2:0.010417 3:0.020833 5:0.014849492 7:0.015942579 +1 1:0.702899 2:0.072464 3:0.043478 5:0.019411686 6:0.039063039 7:0.016967128 +1 1:0.774373 2:0.008357 3:0.02507 5:0.024331698 7:0.015609079 +1 1:0.755952 2:0.005952 3:0.041667 7:0.014663183 +1 1:0.773756 2:0.00905 3:0.029412 5:0.018792957 7:0.016416512 +1 1:0.669604 2:0.044053 3:0.044053 5:0.03875628 7:0.015499085 +1 1:0.757576 2:0.030303 3:0.098485 5:0.022937695 7:0.030025866 +1 1:0.739583 2:0.052083 3:0.036458 5:0.013753671 6:0.033210033 7:0.017212909 +1 1:0.77266 2:0.017831 3:0.034175 5:0.025882248 6:0.002976003 7:0.0182655 +1 1:0.746193 2:0.045685 3:0.030457 5:0.038689189 6:0.020760021 7:0.017890305 +1 1:0.753247 2:0.019481 3:0.058442 5:0.015028402 7:0.019638896 +1 1:0.769953 2:0.032864 3:0.028169 5:0.012046576 6:0.019386019 7:0.01772014 +1 1:0.760784 2:0.011765 3:0.039216 5:0.022520239 7:0.015829744 +1 1:0.730496 2:0.035461 3:0.049645 5:0.020037869 7:0.016087183 +1 1:0.788698 2:0.014742 3:0.027027 5:0.012568396 6:0.0025290025 7:0.017768323 +1 1:0.782178 2:0.029703 3:0.026403 5:0.023079331 6:0.012384012 7:0.019500122 +1 1:0.773333 2:0.006667 3:0.026667 5:0.018971866 7:0.01597561 +1 1:0.776243 2:0.008287 3:0.022099 5:0.016400042 7:0.01531128 +1 1:0.653543 2:0.055118 3:0.098425 5:0.14909129 7:0.014403689 +1 1:0.719457 2:0.027149 3:0.054299 5:0.026478613 7:0.015533604 +1 1:0.608247 2:0.051546 3:0.072165 5:0.10332772 7:0.015872518 +1 1:0.784314 2:0.009804 3:0.02451 5:0.013194579 7:0.016887854 +1 1:0.756614 2:0.026455 3:0.021164 5:0.015088038 7:0.015937543 +1 1:0.740741 2:0.024691 3:0.049383 5:0.019165685 7:0.014641677 +1 1:0.711111 2:0.04 3:0.031111 5:0.056363962 6:0.0085080085 7:0.014336043 +1 1:0.769048 2:0.019048 3:0.014286 5:0.014081672 7:0.015374567 +1 1:0.765385 2:0.013462 3:0.040385 5:0.030615896 7:0.017131799 +1 1:0.748092 2:0.022901 3:0.045802 5:0.043340838 7:0.016011915 +1 1:0.719626 2:0.031153 3:0.049844 5:0.058466149 7:0.014531573 +1 1:0.729508 2:0.057377 3:0.02459 5:0.066360533 6:0.026706027 7:0.016843262 +1 1:0.472 2:0.064 3:0.12 5:0.13762617 6:0.0092310092 7:0.015853659 +1 1:0.722997 2:0.043554 3:0.066202 5:0.059166878 6:0.0031740032 7:0.020077335 +1 1:0.798387 2:0.016129 3:0.032258 5:0.016422405 7:0.022324939 +1 1:0.722892 2:0.024096 3:0.028112 5:0.041603924 7:0.013162402 +1 1:0.738019 2:0.028754 3:0.044728 5:0.0089156591 6:0.010767011 7:0.01628614 +1 1:0.786301 2:0.005479 3:0.030137 5:0.01505822 7:0.016538591 +1 1:0.783715 2:0.022901 3:0.017812 5:0.019881323 6:0.010668011 7:0.017454848 +1 1:0.650538 2:0.091398 3:0.064516 5:0.10791973 6:0.012870013 7:0.020379841 +1 1:0.759804 2:0.041667 3:0.02451 5:0.025613883 6:0.020619021 7:0.017395982 +1 1:0.758621 2:0.035982 3:0.031484 5:0.029244256 6:0.011769012 7:0.018640073 +1 1:0.693182 2:0.0625 3:0.068182 5:0.082961848 6:0.0047700048 7:0.021791854 +1 1:0.756757 2:0.022523 3:0.04955 5:0.010004025 7:0.020462537 +1 1:0.728682 2:0.015504 3:0.069767 5:0.041999016 7:0.01678011 +1 1:0.754579 2:0.018315 3:0.032967 5:0.03063826 7:0.016304835 +1 1:0.735632 2:0.022989 3:0.086207 5:0.012680214 7:0.020605549 +1 1:0.786624 2:0.015924 3:0.022293 5:0.01651186 6:0.0066450066 7:0.017535341 +1 1:0.78672 2:0.016097 3:0.030181 5:0.019881323 7:0.018403104 +1 1:0.746939 2:0.02449 3:0.034694 5:0.034402815 7:0.016177201 +1 1:0.78392 2:0.015075 3:0.045226 5:0.033031175 7:0.020743963 +1 1:0.741935 2:0.032258 3:0.016129 5:0.02662025 7:0.013768689 +1 1:0.751131 2:0.0181 3:0.031674 5:0.014678037 7:0.014016116 +1 1:0.694087 2:0.048843 3:0.066838 5:0.092950964 6:0.004989005 7:0.018856982 +1 1:0.789298 2:0.003344 3:0.026756 5:0.0085802037 7:0.017721671 +1 1:0.761468 2:0.013761 3:0.045872 5:0.03739955 7:0.016726335 +1 1:0.758621 2:0.024138 3:0.051724 5:0.050765584 7:0.01852397 +1 1:0.730769 2:0.038462 3:0.046154 5:0.023295514 6:0.0093750094 7:0.015009384 +1 1:0.738255 2:0.016779 3:0.053691 5:0.019985687 7:0.015264366 +1 1:0.776536 2:0.005587 3:0.044693 5:0.014528946 7:0.017475134 +1 1:0.754045 2:0.024272 3:0.035599 5:0.024324244 6:0.0032640033 7:0.018144683 +1 1:0.747212 2:0.01487 3:0.055762 5:0.038279188 7:0.017657994 +1 1:0.751131 2:0.036199 3:0.027149 5:0.037839369 6:0.01015201 7:0.016306146 +1 1:0.718016 2:0.046997 3:0.057441 5:0.065108166 6:0.0052410052 7:0.018229 +1 1:0.748705 2:0.018135 3:0.033679 5:0.02190151 7:0.016128524 +1 1:0.726027 2:0.027397 3:0.054795 5:0.020313688 7:0.015327433 +1 1:0.738397 2:0.025316 3:0.050633 5:0.041589015 7:0.018447049 +1 1:0.752252 2:0.036036 3:0.045045 5:0.046449391 6:0.0093450093 7:0.017633488 +1 1:0.755245 2:0.01049 3:0.052448 5:0.019829141 7:0.01603275 +1 1:0.764026 2:0.016502 3:0.052805 5:0.0077900198 7:0.019258634 +1 1:0.737589 2:0.060284 3:0.028369 5:0.037086458 6:0.02985003 7:0.017384537 +1 1:0.769231 2:0.023669 3:0.035503 5:0.015691858 7:0.017138116 +1 1:0.758865 2:0.014184 3:0.042553 5:0.018874957 7:0.017081823 +1 1:0.729443 2:0.034483 3:0.039788 5:0.05407541 7:0.015607817 +1 1:0.756906 2:0.016575 3:0.071823 5:0.023780061 7:0.021122488 +1 1:0.75 2:0.015873 3:0.027778 5:0.012426759 7:0.014518 +1 1:0.743169 2:0.021858 3:0.060109 5:0.05296468 7:0.018759165 +1 1:0.750958 2:0.034483 3:0.045977 5:0.019016594 6:0.011481011 7:0.018316043 +1 1:0.74878 2:0.019512 3:0.046341 5:0.025576611 7:0.017340866 +1 1:0.783259 2:0.005979 3:0.028401 5:0.008043475 7:0.016889061 +1 1:0.778364 2:0.007916 3:0.039578 5:0.013753671 7:0.017439988 +1 1:0.775934 2:0.010373 3:0.03527 5:0.015639676 7:0.018090274 +1 1:0.767123 2:0.022831 3:0.054795 5:0.030846988 6:0.0082770083 7:0.020185988 +1 1:0.75122 2:0.017073 3:0.029268 5:0.021841874 7:0.01522903 +1 1:0.744186 2:0.015504 3:0.034884 5:0.035110998 7:0.015054829 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.772118 2:0.013405 3:0.045576 5:0.019165685 7:0.019077354 +1 1:0.782123 2:0.005587 3:0.027933 5:0.015594949 7:0.016282872 +1 1:0.749565 2:0.024348 3:0.029565 5:0.035938455 7:0.015397665 +1 1:0.717105 2:0.039474 3:0.046053 5:0.059793061 7:0.015003207 +1 1:0.734807 2:0.016575 3:0.055249 5:0.028670255 7:0.017517854 +1 1:0.783465 2:0.007874 3:0.027559 5:0.021543691 7:0.01661225 +1 1:0.748837 2:0.027907 3:0.05814 5:0.065197621 7:0.019455476 +1 1:0.708333 2:0.013889 3:0.069444 5:0.041186468 7:0.015328591 +1 1:0.772973 2:0.016216 3:0.037838 5:0.029698985 7:0.016545817 +1 1:0.734783 2:0.06087 3:0.047826 5:0.062491614 6:0.017964018 7:0.022136799 +1 1:0.751503 2:0.014028 3:0.04008 5:0.035051362 7:0.015592159 +1 1:0.776224 2:0.027972 3:0.055944 5:0.012508759 6:0.01006801 7:0.02541361 +1 1:0.788889 2:0.007407 3:0.044444 5:0.0085280217 7:0.01973803 +1 1:0.753213 2:0.028278 3:0.043702 5:0.052219224 6:0.0052530053 7:0.017900811 +1 1:0.785714 2:0.005952 3:0.02381 5:0.016713133 7:0.016187573 +1 1:0.757979 2:0.021277 3:0.029255 5:0.014953856 7:0.016168268 +1 1:0.776699 2:0.021359 3:0.040777 5:0.0091243869 7:0.019346439 +1 1:0.63522 2:0.144654 3:0.037736 5:0.08874659 6:0.0999991 7:0.016106768 +1 1:0.758123 2:0.01083 3:0.021661 5:0.027224069 7:0.015067799 +1 1:0.807229 2:0.004016 3:0.040161 5:0.0080062022 7:0.022798512 +1 1:0.777251 2:0.009479 3:0.018957 7:0.01511386 +1 1:0.60101 2:0.020202 3:0.080808 4:0.0036900369 5:0.052495043 7:0.013118994 +1 1:0.75576 2:0.023041 3:0.050691 5:0.011308574 7:0.018517476 +1 1:0.752475 2:0.014851 3:0.044554 7:0.015666506 +1 1:0.716981 2:0.037736 3:0.081761 5:0.036072637 7:0.047553305 +1 1:0.631579 2:0.086124 3:0.07177 5:0.062431977 6:0.03015003 7:0.017417433 +1 1:0.789238 2:0.004484 3:0.116592 5:0.0029892803 7:0.068139561 +1 1:0.77342 2:0.013072 3:0.041394 5:0.022251875 7:0.017801159 +1 1:0.721925 2:0.02139 3:0.042781 5:0.061992158 7:0.015684098 +1 1:0.708075 2:0.018634 3:0.055901 7:0.012460232 +1 1:0.788732 2:0.014085 3:0.049296 5:0.015624767 7:0.020482652 +1 1:0.746032 2:0.021164 3:0.031746 5:0.015997495 7:0.015034195 +1 1:0.776398 2:0.012422 3:0.037267 5:0.032270809 7:0.017497348 +1 1:0.711957 2:0.01087 3:0.086957 7:0.016569457 +1 1:0.715151 2:0.048485 3:0.056566 5:0.066606533 6:0.0041250041 7:0.017923134 +1 1:0.740032 2:0.028708 3:0.047847 5:0.039233373 7:0.018477457 +1 1:0.773852 2:0.028269 3:0.038869 5:0.022497875 6:0.006036006 7:0.021416872 +1 1:0.781609 2:0.019157 3:0.05364 5:0.029937531 7:0.023268854 +1 1:0.782178 2:0.009901 3:0.016502 5:0.0083043848 7:0.018071317 +1 1:0.761538 2:0.011538 3:0.061538 5:0.018450047 7:0.018949341 +1 1:0.776836 2:0.00565 3:0.042373 5:0.013656762 7:0.018809427 +1 1:0.775811 2:0.014749 3:0.044248 5:0.02121569 7:0.018958195 +1 1:0.736634 2:0.033663 3:0.035644 5:0.050221401 7:0.016131372 +1 1:0.786207 2:0.010345 3:0.027586 5:0.019568232 7:0.016021866 +1 1:0.717105 2:0.026316 3:0.092105 5:0.049587763 7:0.018092104 +1 1:0.655629 2:0.099338 3:0.10596 5:0.019650232 6:0.0094890095 7:0.076603134 8:0.023809524 +1 1:0.79021 2:0.006993 3:0.041958 5:0.0075962012 7:0.020915061 +1 1:0.776435 2:0.006042 3:0.02719 5:0.018591684 7:0.014774152 +1 1:0.762646 2:0.019455 3:0.035019 5:0.021543691 7:0.016418335 +1 1:0.726027 2:0.027397 3:0.03653 5:0.051414131 7:0.020185988 +1 1:0.761194 2:0.052239 3:0.007463 5:0.019463868 6:0.031332031 7:0.017428104 +1 1:0.708609 2:0.059603 3:0.033113 5:0.019672596 6:0.03957904 7:0.015304476 +1 1:0.751309 2:0.031414 3:0.028796 5:0.03499918 6:0.0056340056 7:0.016999744 +1 1:0.727915 2:0.031802 3:0.045936 5:0.018942048 7:0.016956823 +1 1:0.711735 2:0.020408 3:0.053571 5:0.038950099 7:0.01488614 +1 1:0.709459 2:0.054054 3:0.054054 5:0.017294589 7:0.017757085 +1 1:0.703488 2:0.011628 3:0.075581 5:0.017667318 7:0.014960293 +1 1:0.783476 2:0.011396 3:0.037037 5:0.02908771 7:0.017806268 +1 1:0.742138 2:0.034591 3:0.040881 5:0.026247521 6:0.007041007 7:0.01633686 +1 1:0.769874 2:0.016736 3:0.046025 5:0.04107465 7:0.018522299 +1 1:0.781155 2:0.006079 3:0.036474 5:0.0081702026 7:0.016902665 +1 1:0.773196 2:0.015464 3:0.041237 5:0.024518062 7:0.019109884 +1 1:0.651584 2:0.144796 3:0.040724 5:0.023258241 6:0.1029631 7:0.017685683 +1 1:0.77551 2:0.006279 3:0.047096 5:0.01154712 7:0.018541561 +1 1:0.769231 2:0.004525 3:0.031674 5:0.014394764 7:0.014292018 +1 1:0.719626 2:0.03271 3:0.046729 5:0.015244584 6:0.018405018 7:0.013933213 +1 1:0.761905 2:0.030812 3:0.019608 5:0.016221132 6:0.01958702 7:0.015696524 +1 1:0.753588 2:0.011962 3:0.035885 5:0.0061798339 6:0.004971005 7:0.017607073 +1 1:0.710623 2:0.007326 3:0.076923 5:0.020477688 7:0.016260165 +1 1:0.716418 2:0.056716 3:0.059701 5:0.058749422 6:0.013134013 7:0.020786311 +1 1:0.724551 2:0.023952 3:0.041916 5:0.051294858 7:0.015919378 +1 1:0.790576 2:0.010471 3:0.026178 5:0.013075306 7:0.018196909 +1 1:0.472 2:0.064 3:0.12 5:0.13762617 6:0.0092310092 7:0.015853659 +1 1:0.731405 2:0.020661 3:0.07438 5:0.044309931 7:0.016957268 +1 1:0.72314 2:0.028926 3:0.041322 5:0.032986448 6:0.0044250044 7:0.01708325 +1 1:0.768194 2:0.040431 3:0.021563 5:0.013455489 6:0.024369024 7:0.018210506 +1 1:0.768889 2:0.022222 3:0.028889 5:0.029028074 6:0.0046740047 7:0.017398372 +1 1:0.791139 2:0.009494 3:0.03481 5:0.0080732933 7:0.01781028 +1 1:0.767347 2:0.032653 3:0.042857 5:0.033582813 6:0.0067560068 7:0.022100549 +1 1:0.759036 2:0.040161 3:0.072289 5:0.049930673 7:0.036560878 +1 1:0.775432 2:0.011516 3:0.028791 5:0.026642613 7:0.016373299 +1 1:0.758687 2:0.021236 3:0.03668 5:0.032613719 7:0.018834165 +1 1:0.790741 2:0.011111 3:0.031481 5:0.012449123 7:0.020280037 +1 1:0.737668 2:0.05157 3:0.026906 5:0.042386653 6:0.024369024 7:0.016829817 +1 1:0.762836 2:0.00978 3:0.017115 7:0.01358161 +1 1:0.77619 2:0.004762 3:0.028571 5:0.013410761 7:0.016144018 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.726003 2:0.026178 3:0.052356 5:0.054015774 7:0.014685226 +1 1:0.739645 2:0.029586 3:0.059172 5:0.042677381 7:0.018906049 +1 1:0.777778 2:0.01897 3:0.02981 5:0.020686416 6:0.0055500056 7:0.017863043 +1 1:0.766234 2:0.024351 3:0.038961 5:0.038927735 7:0.01895589 +1 1:0.75 2:0.054167 3:0.05 5:0.045122478 6:0.021792022 7:0.020985774 +1 1:0.760135 2:0.013514 3:0.027027 5:0.031584989 7:0.014584707 +1 1:0.750779 2:0.028037 3:0.028037 5:0.040165193 6:0.0096990097 7:0.017627841 +1 1:0.705314 2:0.057971 3:0.067633 5:0.060121062 7:0.018263226 +1 1:0.738693 2:0.035176 3:0.025126 5:0.014014581 7:0.016301018 +1 1:0.750784 2:0.025078 3:0.032915 5:0.036698821 7:0.015530622 +1 1:0.755556 2:0.025926 3:0.055556 5:0.023765151 6:0.0063750064 7:0.021251128 +1 1:0.764045 2:0.011236 3:0.050562 5:0.028021708 7:0.018224171 +1 1:0.796178 2:0.006369 3:0.025478 7:0.018525713 +1 1:0.782082 2:0.007264 3:0.033898 5:0.011748394 7:0.018735604 +1 1:0.757098 2:0.028391 3:0.031546 5:0.038622098 6:0.0062190062 7:0.018561976 +1 1:0.758621 2:0.028736 3:0.028736 5:0.016489497 6:0.013275013 7:0.01583964 +1 1:0.768707 2:0.013605 3:0.027211 5:0.018494774 7:0.016716445 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.73224 2:0.016393 3:0.032787 5:0.046113936 7:0.016160201 +1 1:0.753149 2:0.030227 3:0.042821 5:0.024928063 6:0.0025080025 7:0.018369476 +1 1:0.744526 2:0.029197 3:0.036496 5:0.019933505 7:0.016645896 +1 1:0.763889 2:0.013889 3:0.052083 5:0.02609843 7:0.018144476 +1 1:0.762557 2:0.018265 3:0.03653 5:0.025442428 7:0.016315848 +1 1:0.736527 2:0.023952 3:0.041916 5:0.056908145 7:0.014349348 +1 1:0.775401 2:0.013369 3:0.040107 5:0.019068776 7:0.019124171 +1 1:0.75 2:0.035714 3:0.055195 5:0.020962235 6:0.0084360084 7:0.021123695 +1 1:0.719457 2:0.0181 3:0.036199 5:0.013530034 7:0.015202518 +1 1:0.75365 2:0.014599 3:0.060219 5:0.014036945 7:0.017725207 +1 1:0.704348 2:0.034783 3:0.03913 5:0.072726731 7:0.016304348 +1 1:0.753906 2:0.035156 3:0.050781 5:0.047358848 7:0.018745238 +1 1:0.758794 2:0.01005 3:0.040201 5:0.029997167 7:0.015228585 +1 1:0.753927 2:0.028796 3:0.02356 5:0.022840785 7:0.015626994 +1 1:0.69863 2:0.041096 3:0.041096 5:0.044108658 7:0.014116268 +1 1:0.746544 2:0.013825 3:0.046083 5:0.012784578 7:0.016381927 +1 1:0.758065 2:0.030466 3:0.030466 5:0.012963488 6:0.015651016 7:0.018849988 +1 1:0.726277 2:0.025547 3:0.047445 7:0.01453178 +1 1:0.763889 2:0.013889 3:0.020833 5:0.02036587 7:0.01549797 +1 1:0.773723 2:0.014599 3:0.036496 5:0.031189898 7:0.015956024 +1 1:0.795022 2:0.007321 3:0.035139 5:0.0063960163 7:0.020801341 +1 1:0.749403 2:0.02864 3:0.054893 5:0.029452984 6:0.002964003 7:0.029469116 +1 1:0.720222 2:0.036011 3:0.041551 5:0.032874629 7:0.015319909 +1 1:0.785992 2:0.015564 3:0.019455 5:0.010458754 7:0.016916579 +1 1:0.730897 2:0.033223 3:0.033223 5:0.0284168 7:0.015942793 +1 1:0.757962 2:0.012739 3:0.031847 5:0.037653005 7:0.015379835 +1 1:0.794118 2:0.019608 3:0.035948 5:0.0071862001 6:0.011571012 7:0.020663957 +1 1:0.777174 2:0.005435 3:0.043478 5:0.014253127 7:0.017331652 +1 1:0.720879 2:0.03956 3:0.050549 5:0.035118453 6:0.004038004 7:0.019914232 +1 1:0.753247 2:0.019481 3:0.032468 5:0.018971866 7:0.015560659 +1 1:0.764957 2:0.012821 3:0.038462 5:0.035610454 7:0.016364396 +1 1:0.8159 2:0.004184 3:0.033473 5:0.0089305682 7:0.021303195 +1 1:0.729508 2:0.032787 3:0.040984 5:0.052316133 7:0.014244305 +1 1:0.741935 2:0.010753 3:0.053763 5:0.021156054 7:0.017325598 8:0.023809524 +1 1:0.742105 2:0.026316 3:0.036842 5:0.030869351 7:0.01550064 +1 1:0.789474 2:0.017544 3:0.052632 5:0.035953364 7:0.022179433 +1 1:0.756691 2:0.004866 3:0.065693 5:0.012680214 7:0.017447037 +1 1:0.730233 2:0.027907 3:0.037209 5:0.013358579 7:0.015825299 +1 1:0.757919 2:0.013575 3:0.052036 5:0.034328269 7:0.01797539 +1 1:0.750742 2:0.014837 3:0.032641 5:0.019389322 7:0.013914018 +1 1:0.773414 2:0.009063 3:0.060423 5:0.013932581 7:0.019711146 +1 1:0.764463 2:0.016529 3:0.041322 5:0.009772934 7:0.019224957 +1 1:0.716814 2:0.044248 3:0.050885 5:0.080561478 6:0.0064830065 7:0.018724366 +1 1:0.796875 2:0.005208 3:0.03125 5:0.013701489 7:0.017276421 +1 1:0.795455 2:0.00974 3:0.032468 5:0.007171291 7:0.020589165 +1 1:0.757009 2:0.018692 3:0.040498 5:0.034790452 7:0.016279159 +1 1:0.703057 2:0.052402 3:0.043668 5:0.08634622 6:0.0057930058 7:0.013792738 +1 1:0.7 2:0.021429 3:0.085714 7:0.017073171 +1 1:0.772959 2:0.010204 3:0.033163 5:0.021342418 7:0.01630164 +1 1:0.731959 2:0.034364 3:0.051546 4:0.0036900369 5:0.035752091 7:0.017475482 +1 1:0.777174 2:0.005435 3:0.043478 5:0.014253127 7:0.017331652 +1 1:0.748 2:0.02 3:0.056 5:0.042781745 7:0.017 +1 1:0.69403 2:0.044776 3:0.074627 5:0.088217315 7:0.015380415 +1 1:0.737705 2:0.010929 3:0.065574 7:0.016393439 +1 1:0.72973 2:0.015015 3:0.045045 5:0.041126832 7:0.01327547 +1 1:0.58156 2:0.042553 3:0.035461 5:0.096186245 7:0.020108976 +1 1:0.797297 2:0.004505 3:0.027027 5:0.011450211 7:0.017880683 +1 1:0.782828 2:0.020202 3:0.020202 5:0.012352213 7:0.018585244 +1 1:0.755906 2:0.015748 3:0.03937 5:0.025352974 7:0.014115616 +1 1:0.761589 2:0.013245 3:0.02649 7:0.015748671 +1 1:0.787402 2:0.009843 3:0.031496 5:0.023295514 7:0.019204915 +1 1:0.763864 2:0.019678 3:0.037567 5:0.018815321 7:0.017289146 +1 1:0.759036 2:0.012048 3:0.024096 7:0.013076695 +1 1:0.769072 2:0.012371 3:0.03299 5:0.028304981 7:0.016557707 +1 1:0.717822 2:0.059406 3:0.044554 5:0.019188049 6:0.011583012 7:0.023454482 +1 1:0.746032 2:0.015873 3:0.039683 5:0.025613883 7:0.014082463 +1 1:0.730519 2:0.019481 3:0.058442 5:0.01762259 7:0.016748494 +1 1:0.777778 2:0.005848 3:0.032164 5:0.017003861 7:0.01563614 +1 1:0.761905 2:0.009524 3:0.02381 5:0.013507671 7:0.016027878 +1 1:0.760331 2:0.008264 3:0.033058 5:0.02720916 7:0.013807701 +1 1:0.774566 2:0.011561 3:0.038536 5:0.024361517 7:0.01797547 +1 1:0.754777 2:0.025478 3:0.02707 5:0.02464479 7:0.017622726 +1 1:0.726667 2:0.023333 3:0.043333 4:0.0036900369 5:0.02823789 6:0.0037890038 7:0.016097561 +1 1:0.749632 2:0.032401 3:0.04271 5:0.038748826 7:0.017277921 +1 1:0.743902 2:0.018293 3:0.060976 5:0.016564042 7:0.01673111 +1 1:0.784091 2:0.017045 3:0.039773 5:0.023556424 7:0.021930433 +1 1:0.776596 2:0.010638 3:0.031915 5:0.027559525 7:0.017546707 +1 1:0.763033 2:0.014218 3:0.047393 5:0.023705515 7:0.018177091 +1 1:0.773389 2:0.022869 3:0.033264 5:0.023742788 6:0.0076440076 7:0.01990264 +1 1:0.730104 2:0.020761 3:0.041522 5:0.049043579 7:0.01603511 +1 1:0.772414 2:0.003448 3:0.037931 5:0.0087889315 7:0.01783011 +1 1:0.765766 2:0.009009 3:0.045045 5:0.024204971 7:0.01691936 +1 1:0.74375 2:0.0125 3:0.047917 5:0.037779733 7:0.015040652 +1 1:0.704819 2:0.024096 3:0.054217 5:0.082372937 7:0.013297091 +1 1:0.716312 2:0.014184 3:0.078014 5:0.021238054 7:0.015179037 +1 1:0.777778 2:0.007937 3:0.043651 5:0.020537325 7:0.01756678 +1 1:0.769231 2:0.021978 3:0.027473 5:0.02892371 6:0.0058200058 7:0.017270835 +1 1:0.780269 2:0.013453 3:0.026906 5:0.012262758 7:0.016624738 +1 1:0.757475 2:0.023256 3:0.026578 5:0.018315865 6:0.0036870037 7:0.01648975 +1 1:0.773756 2:0.004525 3:0.0181 5:0.015468221 7:0.01329875 +1 1:0.747126 2:0.030651 3:0.034483 5:0.040962832 7:0.017007756 +1 1:0.642276 2:0.02439 3:0.081301 5:0.052129769 7:0.021267104 +1 1:0.746224 2:0.054381 3:0.015106 5:0.035670091 6:0.017226017 7:0.01925061 +1 1:0.771605 2:0.012346 3:0.040123 5:0.033925723 7:0.016542457 +1 1:0.766667 2:0.016667 3:0.033333 5:0.02412297 7:0.01570122 +1 1:0.806701 2:0.020619 3:0.025773 5:0.010771846 6:0.0086700087 7:0.021750061 +1 1:0.746667 2:0.033333 3:0.02 5:0.023004786 6:0.027777028 7:0.013170732 +1 1:0.767123 2:0.017123 3:0.047945 5:0.016713133 7:0.018626799 +1 1:0.793241 2:0.00994 3:0.04175 5:0.013366034 7:0.020280756 +1 1:0.73494 2:0.012048 3:0.084337 5:0.029288984 7:0.018696738 +1 1:0.728643 2:0.035176 3:0.070352 5:0.07916002 7:0.017312171 +1 1:0.685567 2:0.048969 3:0.054124 5:0.066114532 7:0.014175256 +1 1:0.748466 2:0.018405 3:0.079755 5:0.038890463 7:0.021509799 +1 1:0.781395 2:0.013953 3:0.04186 5:0.02258733 7:0.018718091 +1 1:0.730159 2:0.047619 3:0.063492 5:0.069431813 7:0.022861012 +1 1:0.787879 2:0.008658 3:0.060606 5:0.014700401 7:0.026765915 +1 1:0.645946 2:0.059459 3:0.045946 5:0.11503884 7:0.021357945 +1 1:0.741803 2:0.04918 3:0.040984 5:0.031584989 6:0.016950017 7:0.017692921 +1 1:0.756906 2:0.005525 3:0.038674 5:0.017138044 7:0.01465436 +1 1:0.742902 2:0.020505 3:0.044164 5:0.025971702 6:0.0034830035 7:0.016561512 +1 1:0.724907 2:0.05948 3:0.037175 5:0.016862225 6:0.030543031 7:0.020038079 +1 1:0.734644 2:0.027027 3:0.027027 5:0.028588255 6:0.0086280086 7:0.015625939 +1 1:0.811245 2:0.012048 3:0.024096 6:0.0074520075 7:0.019713 +1 1:0.753623 2:0.026915 3:0.045549 5:0.041790288 7:0.018014945 +1 1:0.743902 2:0.018293 3:0.060976 5:0.016564042 7:0.01673111 +1 1:0.711864 2:0.028249 3:0.067797 5:0.031189898 7:0.01646686 +1 1:0.731061 2:0.026515 3:0.07197 5:0.070229451 7:0.017160939 +1 1:0.752577 2:0.030928 3:0.027491 5:0.024846063 6:0.0066660067 7:0.018858433 +1 1:0.794872 2:0.005128 3:0.041026 5:0.01189003 7:0.019606006 +1 1:0.744472 2:0.022113 3:0.041769 5:0.021610782 6:0.0057960058 7:0.015506085 +1 1:0.76412 2:0.023256 3:0.026578 5:0.020172051 6:0.016239016 7:0.014970421 +1 1:0.726358 2:0.050302 3:0.072435 5:0.088008588 7:0.020783238 +1 1:0.734463 2:0.033898 3:0.050847 5:0.047783758 7:0.016122366 +1 1:0.688172 2:0.05914 3:0.05914 5:0.09728952 7:0.020095726 +1 1:0.728571 2:0.052381 3:0.1 5:0.026635159 6:0.0030630031 7:0.05688153 +1 1:0.807377 2:0.008197 3:0.036885 7:0.023540585 +1 1:0.738255 2:0.033557 3:0.040268 5:0.035752091 7:0.017064988 +1 1:0.727273 2:0.027972 3:0.062937 5:0.061798339 7:0.020573939 +1 1:0.784753 2:0.008969 3:0.03139 5:0.023630969 7:0.01725364 +1 1:0.69403 2:0.104478 3:0.029851 5:0.093882784 6:0.037782038 7:0.018065165 +1 1:0.746914 2:0.024691 3:0.049383 5:0.057489601 7:0.014641677 +1 1:0.758741 2:0.027972 3:0.038462 5:0.035580636 7:0.01786628 +1 1:0.773616 2:0.011401 3:0.026059 5:0.014081672 7:0.015770238 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.794408 2:0.008224 3:0.042763 5:0.016869679 7:0.022153805 +1 1:0.785448 2:0.011194 3:0.022388 5:0.0098176614 7:0.017280213 +1 1:0.763593 2:0.021277 3:0.035461 5:0.027007887 6:0.0081510082 7:0.015914201 +1 1:0.754753 2:0.022814 3:0.039924 5:0.04775394 7:0.018095616 +1 1:0.762533 2:0.023747 3:0.026385 5:0.0071116545 7:0.016860805 +1 1:0.754286 2:0.017143 3:0.04 5:0.03320263 7:0.015644598 +1 1:0.747126 2:0.028736 3:0.034483 5:0.015863313 6:0.0063840064 7:0.016470421 +1 1:0.731884 2:0.036232 3:0.050725 5:0.057198873 7:0.017276421 +1 1:0.758465 2:0.022573 3:0.047404 4:0.0036900369 5:0.051645222 7:0.017879756 +1 1:0.662857 2:0.045714 3:0.045714 5:0.10251517 7:0.017735189 +1 1:0.737668 2:0.05157 3:0.026906 5:0.042386653 6:0.024369024 7:0.016829817 +1 1:0.581967 2:0.106557 3:0.065574 5:0.18825012 6:0.0075750076 7:0.019792085 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.7713 2:0.017937 3:0.044843 5:0.033329358 7:0.018347372 +1 1:0.707736 2:0.068768 3:0.031519 5:0.019948414 6:0.04014304 7:0.019585573 +1 1:0.734266 2:0.034965 3:0.062937 5:0.033657358 7:0.018889646 +1 1:0.708738 2:0.067961 3:0.029126 5:0.025613883 6:0.048111048 7:0.017227091 +1 1:0.785567 2:0.012371 3:0.03299 5:0.019985687 7:0.01875786 +1 1:0.756933 2:0.021207 3:0.026101 5:0.033098266 6:0.004995005 7:0.01792464 +1 1:0.757925 2:0.014409 3:0.043228 5:0.029236802 7:0.017923665 +1 1:0.803279 2:0.02459 3:0.07377 5:0.010794209 7:0.069022396 +1 1:0.754412 2:0.019118 3:0.055882 5:0.027969526 7:0.019117646 +1 1:0.710345 2:0.027586 3:0.041379 4:0.0036900369 5:0.030138804 7:0.015601348 +1 1:0.786517 2:0.026217 3:0.037453 5:0.014968765 6:0.009036009 7:0.022745957 +1 1:0.76652 2:0.011013 3:0.028634 5:0.032270809 7:0.015512518 +1 1:0.762653 2:0.022688 3:0.034904 5:0.0089380228 7:0.01774997 +1 1:0.704434 2:0.049261 3:0.054187 5:0.077885289 7:0.020124957 +1 1:0.769697 2:0.018182 3:0.030303 5:0.031719172 7:0.017368811 +1 1:0.705479 2:0.082192 3:0.027397 5:0.029698985 6:0.055776056 7:0.015724189 +1 1:0.631902 2:0.030675 3:0.079755 5:0.030869351 7:0.018068232 +1 1:0.733456 2:0.038603 3:0.045956 5:0.036072637 6:0.012903013 7:0.02084828 +1 1:0.708487 2:0.066421 3:0.02583 5:0.068030355 6:0.01955702 7:0.017257671 +1 1:0.782369 2:0.011019 3:0.044077 5:0.025703338 7:0.019485317 +1 1:0.743243 2:0.022523 3:0.033033 5:0.035327181 7:0.015454476 +1 1:0.750903 2:0.01444 3:0.072202 5:0.017294589 7:0.018975079 +1 1:0.75122 2:0.019512 3:0.029268 5:0.029758621 7:0.014901841 +1 1:0.774704 2:0.011858 3:0.023715 5:0.022974968 7:0.015641567 +1 1:0.756039 2:0.021739 3:0.041063 5:0.019478777 6:0.0052260052 7:0.016908213 +1 1:0.74 2:0.02 3:0.033333 5:0.01104021 7:0.013719512 +1 1:0.700483 2:0.057971 3:0.05314 5:0.043422838 6:0.023301023 7:0.015170262 +1 1:0.744589 2:0.021645 3:0.038961 5:0.027358251 7:0.014386018 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.783688 2:0.007092 3:0.031915 5:0.0090125684 7:0.017881854 +1 1:0.740426 2:0.025532 3:0.06383 5:0.063624707 7:0.018240787 +1 1:0.758621 2:0.027586 3:0.048276 5:0.047083029 7:0.019974768 +1 1:0.721939 2:0.033163 3:0.043367 5:0.073643642 6:0.0032940033 7:0.01417061 +1 1:0.702703 2:0.040541 3:0.074324 5:0.06700908 7:0.018333884 +1 1:0.8 2:0.012121 3:0.036364 5:0.013552398 7:0.020325201 +1 1:0.770732 2:0.009756 3:0.043902 5:0.024309335 7:0.01824311 +1 1:0.785714 2:0.015306 3:0.020408 5:0.012784578 7:0.018137134 +1 1:0.727273 2:0.034091 3:0.042614 5:0.065838713 7:0.017651744 +1 1:0.707602 2:0.023392 3:0.093567 5:0.061231792 7:0.017365567 +1 1:0.767507 2:0.033613 3:0.042017 5:0.033016266 6:0.010629011 7:0.019283323 +1 1:0.715596 2:0.039755 3:0.055046 5:0.026560613 6:0.017814018 7:0.015700756 +1 1:0.722222 2:0.038889 3:0.05 5:0.048939215 7:0.01548103 +1 1:0.711656 2:0.042945 3:0.04908 5:0.018778048 7:0.014851116 +1 1:0.736842 2:0.029825 3:0.045614 5:0.041044832 7:0.015543433 +1 1:0.734043 2:0.015957 3:0.069149 5:0.015088038 7:0.016022317 +1 1:0.76 2:0.0225 3:0.0275 5:0.028893892 6:0.0023250023 7:0.019664634 +1 1:0.714286 2:0.032468 3:0.077922 5:0.0498114 7:0.017777951 +1 1:0.770335 2:0.009569 3:0.0311 5:0.013701489 7:0.015871165 +1 1:0.67658 2:0.026022 3:0.04461 5:0.024361517 7:0.013872518 8:0.047619048 +1 1:0.774306 2:0.017361 3:0.020833 5:0.0096536609 7:0.016344854 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.743802 2:0.033058 3:0.090909 5:0.045182115 7:0.024944567 +1 1:0.766667 2:0.025 3:0.033333 7:0.018191055 +1 1:0.721408 2:0.035191 3:0.061584 5:0.052390679 6:0.003012003 7:0.017809884 +1 1:0.790123 2:0.006173 3:0.024691 5:0.016981498 7:0.01652364 +1 1:0.745763 2:0.053672 3:0.028249 5:0.040769013 6:0.016407016 7:0.018895549 +1 1:0.787554 2:0.01073 3:0.01073 5:0.0063960163 7:0.015243902 +1 1:0.770492 2:0.016393 3:0.032787 5:0.028342254 7:0.017526323 +1 1:0.761092 2:0.020478 3:0.030717 5:0.030056804 7:0.015483226 +1 1:0.755776 2:0.013201 3:0.033003 5:0.030347532 7:0.01483136 +1 1:0.68323 2:0.018634 3:0.080745 5:0.059957062 7:0.014126646 +1 1:0.747312 2:0.010753 3:0.05914 5:0.015028402 7:0.016260165 +1 1:0.77686 2:0.008264 3:0.028926 5:0.022438239 7:0.016743098 +1 1:0.788779 2:0.008251 3:0.037954 5:0.019352049 7:0.019379378 +1 1:0.763889 2:0.013889 3:0.052083 5:0.02609843 7:0.018144476 +1 1:0.702602 2:0.048327 3:0.081784 5:0.085794582 7:0.017725994 +1 1:0.73224 2:0.010929 3:0.027322 4:0.018450185 5:0.025315701 7:0.019625482 +1 1:0.71659 2:0.034562 3:0.06682 5:0.069237994 7:0.018152189 +1 1:0.776824 2:0.017167 3:0.034335 5:0.021961147 7:0.017769287 +1 1:0.745636 2:0.024938 3:0.0399 5:0.039583737 6:0.0026550027 7:0.017182652 +1 1:0.768421 2:0.031579 3:0.031579 5:0.076983287 7:0.018645701 8:0.023809524 +1 1:0.729345 2:0.034188 3:0.068376 5:0.087360041 7:0.017788896 +1 1:0.749091 2:0.025455 3:0.036364 5:0.031495535 7:0.015742793 +1 1:0.71308 2:0.033755 3:0.054852 5:0.024443517 6:0.0098370098 7:0.015694146 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.768362 2:0.022599 3:0.036723 5:0.028864073 7:0.017793165 +1 1:0.764151 2:0.015723 3:0.037736 5:0.032308082 7:0.017698268 +1 1:0.7666 2:0.020121 3:0.044266 5:0.0052927407 7:0.017286646 +1 1:0.756757 2:0.033784 3:0.040541 5:0.030362441 7:0.020229073 +1 1:0.78626 2:0.030534 3:0.030534 5:0.015468221 7:0.022435299 +1 1:0.766962 2:0.0059 3:0.023599 5:0.019568232 7:0.013706024 +1 1:0.718254 2:0.041667 3:0.041667 5:0.066807806 6:0.008961009 7:0.016199671 +1 1:0.732323 2:0.015152 3:0.050505 5:0.041723197 7:0.01650653 +1 1:0.763333 2:0.02 3:0.043333 5:0.016623679 7:0.018231707 +1 1:0.755034 2:0.02349 3:0.030201 5:0.018136955 7:0.016819445 +1 1:0.72619 2:0.035714 3:0.059524 5:0.015863313 7:0.017058652 +1 1:0.516129 2:0.072581 3:0.104839 5:0.015527858 6:0.037500038 7:0.023603463 +1 1:0.782609 2:0.012422 3:0.02795 5:0.016735497 7:0.016872445 +1 1:0.759834 2:0.016563 3:0.028986 5:0.031935354 7:0.014732616 +1 1:0.622047 2:0.15748 3:0.023622 4:0.0036900369 5:0.057638692 6:0.1005151 7:0.018628768 +1 1:0.675 2:0.1 3:0.025 5:0.050370492 6:0.070947071 7:0.015040652 +1 1:0.759834 2:0.016563 3:0.028986 5:0.031935354 7:0.014732616 +1 1:0.6917 2:0.043478 3:0.079051 5:0.10619027 7:0.016918927 +1 1:0.781046 2:0.019608 3:0.022876 5:0.0080658387 6:0.0032460032 7:0.018412244 +1 1:0.765027 2:0.043716 3:0.021858 5:0.028729891 6:0.028902029 7:0.017293085 +1 1:0.682105 2:0.073684 3:0.075789 5:0.10725627 6:0.0039240039 7:0.019627726 +1 1:0.742489 2:0.025751 3:0.04721 5:0.048014849 7:0.016251439 +1 1:0.719048 2:0.050794 3:0.031746 5:0.066054895 6:0.011391011 7:0.015292293 +1 1:0.791045 2:0.007463 3:0.014925 5:0.020880235 7:0.016244994 8:0.023809524 +1 1:0.765957 2:0.012158 3:0.033435 5:0.0081552935 7:0.016939732 +1 1:0.78629 2:0.016129 3:0.024194 5:0.011196756 6:0.009009009 7:0.016374902 +1 1:0.762376 2:0.019802 3:0.024752 5:0.014938947 7:0.015062787 +1 1:0.745455 2:0.031818 3:0.05 5:0.046956301 7:0.01759978 +1 1:0.695652 2:0.050725 3:0.094203 5:0.12278413 7:0.01877872 +1 1:0.672 2:0.064 3:0.152 5:0.0029445529 6:0.0047400047 7:0.1235122 +1 1:0.722222 2:0.044444 3:0.033333 5:0.042655018 6:0.017166017 7:0.015785909 +1 1:0.754011 2:0.023173 3:0.039216 5:0.036475184 7:0.017770963 +1 1:0.764286 2:0.021429 3:0.035714 5:0.020254052 7:0.016027878 +1 1:0.748603 2:0.01676 3:0.044693 5:0.048939215 7:0.015567518 +1 1:0.78169 2:0.007042 3:0.021127 5:0.019314776 7:0.016575061 +1 1:0.768293 2:0.018293 3:0.036585 5:0.032554083 7:0.017028555 +1 1:0.753304 2:0.061674 3:0.017621 5:0.020149688 6:0.036486036 7:0.019877512 +1 1:0.763949 2:0.012876 3:0.025751 5:0.024890791 7:0.015675707 +1 1:0.730825 2:0.026049 3:0.04631 5:0.021722601 7:0.015142421 +1 1:0.688525 2:0.103825 3:0.060109 5:0.089454773 7:0.033320006 +1 1:0.784746 2:0.010169 3:0.028814 5:0.021424418 7:0.017982634 +1 1:0.727273 2:0.036364 3:0.04 4:0.0036900369 5:0.056617417 6:0.0075960076 7:0.017516628 +1 1:0.77931 2:0.017241 3:0.044828 5:0.030183531 7:0.020773762 +1 1:0.730769 2:0.030769 3:0.061538 5:0.06093361 7:0.017213884 +1 1:0.716511 2:0.034268 3:0.037383 4:0.0036900369 5:0.063781253 7:0.017760811 8:0.023809524 +1 1:0.735409 2:0.031128 3:0.046693 5:0.041999016 7:0.016845402 +1 1:0.668831 2:0.116883 3:0.071429 5:0.064824892 6:0.026088026 7:0.022766866 +1 1:0.753213 2:0.015424 3:0.048843 4:0.0036900369 5:0.041111923 7:0.01705436 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.766187 2:0.014388 3:0.035971 5:0.03731755 7:0.017525006 +1 1:0.690647 2:0.057554 3:0.043165 6:0.01973702 7:0.013335671 +1 1:0.656 2:0.04 3:0.048 5:0.097319339 7:0.018682927 8:0.023809524 +1 1:0.751579 2:0.016842 3:0.042105 5:0.052263951 7:0.014646982 +1 1:0.727723 2:0.027228 3:0.084158 5:0.0099220253 6:0.0013320013 7:0.068039122 +1 1:0.772532 2:0.021459 3:0.042918 5:0.010130753 6:0.012228012 7:0.019260963 +1 1:0.782178 2:0.00495 3:0.029703 5:0.013358579 7:0.016843756 +1 1:0.750611 2:0.01956 3:0.0489 5:0.04483175 7:0.017353451 +1 1:0.741117 2:0.010152 3:0.060914 5:0.027559525 7:0.016745079 +1 1:0.755725 2:0.020356 3:0.038168 5:0.020149688 7:0.017222116 +1 1:0.730769 2:0.038462 3:0.057692 5:0.068231628 7:0.017080988 +1 1:0.740964 2:0.024096 3:0.054217 5:0.034119541 7:0.016052012 +1 1:0.766962 2:0.0059 3:0.023599 5:0.019568232 7:0.013706024 +1 1:0.781362 2:0.010753 3:0.046595 5:0.023347696 7:0.020937146 +1 1:0.744681 2:0.017021 3:0.025532 5:0.026247521 6:0.0052830053 7:0.014737933 +1 1:0.764423 2:0.024038 3:0.028846 5:0.026575522 7:0.016445823 +1 1:0.788732 2:0.01006 3:0.020121 5:0.010570572 7:0.017298915 +1 1:0.757143 2:0.05 3:0.035714 5:0.01566204 6:0.018909019 7:0.020731707 +1 1:0.796053 2:0.013158 3:0.052632 5:0.024846063 7:0.024069317 +1 1:0.766764 2:0.029155 3:0.03207 5:0.014618401 6:0.017646018 7:0.018132689 +1 1:0.795252 2:0.011869 3:0.029674 6:0.0028830029 7:0.018835494 +1 1:0.748438 2:0.020312 3:0.042188 5:0.03021335 6:0.0052110052 7:0.016453884 +1 1:0.731959 2:0.036082 3:0.036082 5:0.030869351 7:0.015181043 +1 1:0.774359 2:0.020513 3:0.025641 5:0.019478777 6:0.0052260052 7:0.01794872 8:0.023809524 +1 1:0.734454 2:0.021849 3:0.036975 5:0.050504674 7:0.015126049 +1 1:0.72963 2:0.042593 3:0.07037 5:0.068872721 7:0.020776878 +1 1:0.687023 2:0.038168 3:0.099237 5:0.08693513 7:0.015965372 +1 1:0.719807 2:0.038647 3:0.082126 5:0.069454177 7:0.018970189 +1 1:0.769231 2:0.019231 3:0.034615 5:0.029698985 7:0.017659476 +1 1:0.742857 2:0.034286 3:0.022857 5:0.01754059 7:0.01480836 +1 1:0.746575 2:0.017123 3:0.030822 5:0.031674444 7:0.014742732 +1 1:0.7 2:0.021429 3:0.085714 7:0.017073171 +1 1:0.775 2:0.025 3:0.1 5:0.012993306 7:0.087449183 +1 1:0.770083 2:0.01662 3:0.030471 5:0.0071340182 7:0.017650835 +1 1:0.792763 2:0.008224 3:0.023026 5:0.012724941 7:0.01762075 +1 1:0.736486 2:0.02027 3:0.060811 5:0.053889046 7:0.01709789 +1 1:0.797654 2:0.008798 3:0.035191 5:0.020746053 7:0.019276159 +1 1:0.759804 2:0.041667 3:0.02451 5:0.025613883 6:0.020619021 7:0.017395982 +1 1:0.77459 2:0.012295 3:0.02459 5:0.025017518 7:0.014894043 +1 1:0.76 2:0.013333 3:0.048889 4:0.0036900369 5:0.021424418 7:0.018861787 +1 1:0.769424 2:0.032581 3:0.025063 5:0.030578623 6:0.017226017 7:0.01862889 +1 1:0.710744 2:0.033058 3:0.082645 5:0.063714162 7:0.017687963 +1 1:0.606557 2:0.032787 3:0.103825 5:0.053531227 7:0.018559244 +1 1:0.693694 2:0.051051 3:0.06006 5:0.071936547 6:0.010857011 7:0.015179817 +1 1:0.775701 2:0.009346 3:0.028037 5:0.026672432 7:0.015927738 +1 1:0.760784 2:0.019608 3:0.039216 5:0.033083357 7:0.016164512 +1 1:0.775194 2:0.007752 3:0.062016 5:0.015527858 7:0.022688598 +1 1:0.776744 2:0.023256 3:0.027907 5:0.021640601 6:0.0043530044 7:0.019540555 +1 1:0.76808 2:0.014963 3:0.029925 5:0.026910978 7:0.016848122 +1 1:0.785714 2:0.007937 3:0.039683 5:0.019314776 7:0.018679829 +1 1:0.735178 2:0.023715 3:0.059289 5:0.042356835 7:0.016967128 +1 1:0.775194 2:0.015504 3:0.054264 5:0.016750406 7:0.02103422 +1 1:0.754098 2:0.021077 3:0.046838 5:0.039561373 7:0.018835323 +1 1:0.716108 2:0.041467 3:0.076555 5:0.09532897 7:0.019012329 +1 1:0.792517 2:0.013605 3:0.027211 5:0.0081925663 7:0.018873402 +1 1:0.748634 2:0.016393 3:0.065574 5:0.025926975 7:0.019159 +1 1:0.789773 2:0.005682 3:0.028409 5:0.015117857 7:0.017080098 +1 1:0.760542 2:0.01506 3:0.024096 5:0.028558436 7:0.014380695 +1 1:0.696721 2:0.02459 3:0.090164 5:0.046017026 7:0.016193524 +1 1:0.762821 2:0.00641 3:0.025641 7:0.013484994 +1 1:0.752727 2:0.029091 3:0.032727 5:0.037272822 7:0.01773836 +1 1:0.766667 2:0.024242 3:0.039394 5:0.022952604 6:0.0030780031 7:0.01800628 +1 1:0.742604 2:0.02071 3:0.032544 5:0.036542275 7:0.014720738 +1 1:0.743326 2:0.051335 3:0.039014 5:0.035371908 6:0.016014016 7:0.021109829 +1 1:0.743169 2:0.021858 3:0.060109 5:0.05296468 7:0.018759165 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.768683 2:0.014235 3:0.02847 5:0.019441504 7:0.016643518 +1 1:0.758696 2:0.01087 3:0.043478 5:0.025442428 7:0.015535524 +1 1:0.735376 2:0.016713 3:0.05571 5:0.024279516 7:0.015643049 +1 1:0.746193 2:0.030457 3:0.040609 5:0.039375009 7:0.017580787 +1 1:0.774194 2:0.032258 3:0.016129 5:0.021357327 6:0.017193017 7:0.017161683 +1 1:0.715084 2:0.019553 3:0.030726 5:0.024413699 7:0.015601579 +1 1:0.761421 2:0.015228 3:0.035533 5:0.029997167 7:0.015383189 +1 1:0.764423 2:0.014423 3:0.057692 5:0.021327509 7:0.020491323 +1 1:0.756622 2:0.034768 3:0.043046 5:0.028558436 6:0.013137013 7:0.01844411 +1 1:0.781553 2:0.009709 3:0.029126 5:0.02480879 7:0.017789488 +1 1:0.691057 2:0.097561 3:0.03252 5:0.051175585 6:0.054921055 7:0.021663689 +1 1:0.732365 2:0.045643 3:0.056017 5:0.03302372 6:0.00094800095 7:0.039975707 +1 1:0.80663 2:0.005525 3:0.016575 7:0.019370701 +1 1:0.765432 2:0.019753 3:0.02963 5:0.013515125 7:0.016606445 +1 1:0.735202 2:0.012461 3:0.043614 5:0.040627376 7:0.013942707 +1 1:0.659864 2:0.081633 3:0.034014 5:0.11222101 6:0.019356019 7:0.019288201 +1 1:0.694215 2:0.024793 3:0.082645 5:0.07213782 7:0.015621854 +1 1:0.646617 2:0.06391 3:0.045113 5:0.090580412 6:0.014580015 7:0.018865762 +1 1:0.779018 2:0.03125 3:0.020089 5:0.0052778316 6:0.016986017 7:0.019231817 +1 1:0.77459 2:0.012295 3:0.02459 5:0.025017518 7:0.014894043 +1 2:0.716667 3:0.083333 6:0.66403266 7:0.012855689 +1 1:0.760933 2:0.014577 3:0.043732 5:0.030243168 7:0.017528262 +1 1:0.766779 2:0.021812 3:0.035235 5:0.049833763 7:0.018364299 8:0.023809524 +1 1:0.747698 2:0.009208 3:0.033149 5:0.026269885 7:0.015934512 +1 1:0.768 2:0.0208 3:0.032 5:0.021774783 7:0.016702439 +1 1:0.669231 2:0.115385 3:0.023077 4:0.0036900369 5:0.055357595 6:0.066831067 7:0.018949341 +1 1:0.807377 2:0.008197 3:0.032787 5:0.0088187497 7:0.021116555 +1 1:0.808642 2:0.012346 3:0.058642 5:0.0033918268 7:0.041403189 +1 1:0.734177 2:0.03038 3:0.027848 5:0.03423136 7:0.013445506 +1 1:0.735099 2:0.086093 3:0.019868 5:0.015796222 6:0.050847051 7:0.019059927 +1 1:0.758278 2:0.013245 3:0.043046 5:0.017876046 7:0.016838957 +1 1:0.761589 2:0.02649 3:0.059603 5:0.040590103 7:0.022250043 +1 1:0.782609 2:0.014493 3:0.033816 5:0.010540754 6:0.0042420042 7:0.02082597 +1 1:0.643411 2:0.023256 3:0.139535 5:0.01616895 7:0.021790506 +1 1:0.710345 2:0.027586 3:0.041379 4:0.0036900369 5:0.030138804 7:0.015601348 +1 1:0.70751 2:0.043478 3:0.027668 5:0.042513381 6:0.0057030057 7:0.01267714 +1 1:0.761506 2:0.037657 3:0.079498 5:0.015557676 6:0.0037560038 7:0.061128689 +1 1:0.760563 2:0.028169 3:0.035211 5:0.03663173 7:0.017476811 +1 1:0.78626 2:0.015267 3:0.10687 5:0.011159483 7:0.031092902 +1 1:0.731061 2:0.026515 3:0.07197 5:0.070229451 7:0.017160939 +1 1:0.760331 2:0.008264 3:0.033058 5:0.02720916 7:0.013807701 +1 1:0.747591 2:0.017341 3:0.034682 5:0.04218538 7:0.01453311 +1 1:0.756554 2:0.007491 3:0.048689 4:0.011070111 5:0.0096536609 7:0.017630402 +1 1:0.740741 2:0.024691 3:0.030864 7:0.014942787 +1 1:0.726644 2:0.027682 3:0.069204 5:0.034514633 7:0.018229384 +1 1:0.746479 2:0.00939 3:0.042254 5:0.027865162 7:0.01531547 +1 1:0.76901 2:0.014347 3:0.050215 5:0.03473827 7:0.018773841 +1 1:0.754839 2:0.019355 3:0.058065 5:0.052010496 7:0.016915817 +1 1:0.788151 2:0.021544 3:0.035907 5:0.011427847 6:0.0091980092 7:0.021423567 +1 1:0.787234 2:0.007979 3:0.031915 5:0.019896232 7:0.018227817 +1 1:0.753247 2:0.017316 3:0.038961 5:0.011629121 7:0.016920073 +1 1:0.735409 2:0.027237 3:0.054475 5:0.06246925 7:0.016987756 +1 1:0.703518 2:0.050251 3:0.060302 5:0.040150284 6:0.026931027 7:0.017067043 +1 1:0.790055 2:0.01105 3:0.033149 5:0.014118945 7:0.01778736 +1 1:0.726852 2:0.023148 3:0.064815 5:0.065972895 7:0.01594964 +1 1:0.7463 2:0.010571 3:0.048626 5:0.022058056 7:0.01742897 +1 1:0.761421 2:0.015228 3:0.045685 5:0.02823789 7:0.016342701 +1 1:0.73374 2:0.03252 3:0.038618 5:0.040142829 7:0.016111445 +1 1:0.753788 2:0.022727 3:0.026515 5:0.023817333 7:0.01445861 +1 1:0.732558 2:0.011628 3:0.063953 5:0.015997495 7:0.016520134 +1 1:0.731343 2:0.064677 3:0.034826 5:0.057429964 6:0.018489018 7:0.019688146 +1 1:0.712281 2:0.035088 3:0.049123 5:0.044906296 7:0.014206244 +1 1:0.759124 2:0.014599 3:0.021898 7:0.013953177 +1 1:0.711268 2:0.028169 3:0.06338 5:0.038525189 7:0.016618 +1 1:0.766667 2:0.028571 3:0.038095 5:0.011502393 6:0.0092580093 7:0.018815329 +1 1:0.765027 2:0.019126 3:0.038251 5:0.02686625 7:0.018492604 +1 1:0.783784 2:0.040541 3:0.040541 5:0.021566055 6:0.011571012 7:0.021362061 +1 1:0.773585 2:0.006289 3:0.025157 5:0.019314776 7:0.014802884 +1 1:0.743295 2:0.022989 3:0.030651 5:0.026202794 7:0.013293152 +1 1:0.7543 2:0.017199 3:0.056511 5:0.024913154 7:0.017933122 +1 1:0.769882 2:0.018613 3:0.027073 5:0.026992978 7:0.017095872 +1 1:0.76699 2:0.006472 3:0.042071 5:0.01275476 7:0.023068116 +1 1:0.778443 2:0.011976 3:0.03992 5:0.022184784 7:0.020446909 +1 1:0.761538 2:0.023077 3:0.023077 5:0.024764063 6:0.00996601 7:0.014118201 +1 1:0.695332 2:0.044226 3:0.056511 5:0.084937307 7:0.017094146 +1 1:0.759036 2:0.018072 3:0.060241 5:0.043765748 7:0.018770201 8:0.023809524 +1 1:0.743455 2:0.026178 3:0.052356 5:0.059047605 7:0.016121823 +1 1:0.762431 2:0.016575 3:0.033149 5:0.015371312 7:0.016338768 +1 1:0.699248 2:0.02005 3:0.050125 5:0.059696152 7:0.015266823 +1 1:0.746479 2:0.035211 3:0.035211 6:0.024063024 7:0.016059774 +1 1:0.786982 2:0.005917 3:0.02071 5:0.0082298391 7:0.016344348 +1 1:0.698925 2:0.016129 3:0.107527 5:0.029117529 7:0.016784683 +1 1:0.746479 2:0.035211 3:0.035211 6:0.024063024 7:0.016059774 +1 1:0.780439 2:0.015968 3:0.023952 5:0.018681138 6:0.0037590038 7:0.019424567 +1 1:0.699045 2:0.05414 3:0.079618 5:0.11845303 7:0.018331518 +1 1:0.768559 2:0.017467 3:0.034934 5:0.011174392 7:0.017760146 +1 1:0.773748 2:0.01209 3:0.025907 5:0.024406244 7:0.016081134 +1 1:0.777003 2:0.013937 3:0.029617 5:0.015639676 7:0.020257927 +1 1:0.792157 2:0.007843 3:0.035294 5:0.018293501 7:0.019488287 +1 1:0.764444 2:0.028889 3:0.024444 5:0.029415711 6:0.014208014 7:0.017168024 +1 1:0.757991 2:0.018265 3:0.050228 5:0.011852757 6:0.0095400095 7:0.017513085 +1 1:0.752577 2:0.034364 3:0.030928 5:0.017682227 6:0.014235014 7:0.017664067 +1 1:0.759009 2:0.040541 3:0.029279 5:0.017242408 6:0.020817021 7:0.017812018 +1 1:0.764505 2:0.013652 3:0.054608 5:0.025733156 7:0.018084573 +1 1:0.764192 2:0.017467 3:0.039301 5:0.023929152 7:0.016588561 +1 1:0.810458 2:0.026144 3:0.052288 5:0.0089380228 7:0.033237683 +1 1:0.585034 2:0.027211 3:0.095238 5:0.082596574 7:0.01497428 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.78 2:0.006667 3:0.026667 5:0.015184948 7:0.019959348 +1 1:0.710526 2:0.040936 3:0.064327 5:0.084534761 7:0.01729425 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.780193 2:0.009662 3:0.031401 5:0.026202794 7:0.016760927 +1 1:0.789474 2:0.007519 3:0.037594 7:0.018751146 +1 1:0.774143 2:0.010903 3:0.031153 5:0.023653333 7:0.017960262 +1 1:0.766917 2:0.007519 3:0.037594 5:0.019262594 7:0.01774253 +1 1:0.755495 2:0.016484 3:0.054945 5:0.033046084 7:0.018895738 +1 1:0.716418 2:0.074627 3:0.064677 5:0.050780493 6:0.016350016 7:0.022266713 +1 1:0.753873 2:0.032702 3:0.034423 5:0.025643702 6:0.0086010086 7:0.018303177 +1 1:0.75 2:0.022727 3:0.037879 5:0.024048425 7:0.01432003 +1 1:0.768145 2:0.012097 3:0.030242 5:0.016564042 7:0.016596183 +1 1:0.726351 2:0.054054 3:0.040541 5:0.055454505 6:0.015939016 7:0.019384476 +1 1:0.75 2:0.024194 3:0.040323 5:0.04732903 7:0.015489774 +1 1:0.767956 2:0.01105 3:0.044199 5:0.011539666 7:0.021762567 +1 1:0.785714 2:0.015306 3:0.020408 5:0.012784578 7:0.018137134 +1 1:0.774436 2:0.007519 3:0.097744 5:0.0084832943 7:0.040298921 +1 1:0.740385 2:0.038462 3:0.043269 5:0.025144246 6:0.02023502 7:0.017383909 +1 1:0.761719 2:0.023438 3:0.046875 5:0.025256064 6:0.002034002 7:0.017578122 +1 1:0.767059 2:0.014118 3:0.037647 5:0.012508759 7:0.017101866 +1 1:0.734914 2:0.036638 3:0.038793 5:0.063266888 6:0.0063660064 7:0.018581793 +1 1:0.77686 2:0.008264 3:0.028926 5:0.022438239 7:0.016743098 +1 1:0.756708 2:0.017889 3:0.041145 5:0.020164597 6:0.0040560041 7:0.016132902 +1 1:0.746615 2:0.017408 3:0.032882 5:0.025233701 7:0.017419921 +1 1:0.773234 2:0.018587 3:0.02974 5:0.017667318 7:0.019131384 +1 1:0.747346 2:0.027601 3:0.070064 5:0.040880831 7:0.025969652 +1 1:0.738499 2:0.01937 3:0.038741 5:0.048723033 7:0.015812317 +1 1:0.772379 2:0.02046 3:0.02046 5:0.02533061 6:0.01019401 7:0.018355061 +1 1:0.738462 2:0.015385 3:0.046154 5:0.028506254 7:0.01635397 +1 1:0.636364 2:0.082645 3:0.115702 5:0.1577684 7:0.019048579 +1 1:0.765432 2:0.015432 3:0.052469 5:0.026739523 7:0.02098389 +1 1:0.657952 2:0.063181 3:0.052288 5:0.029370984 6:0.037824038 7:0.016857963 +1 1:0.803738 2:0.009346 3:0.028037 5:0.010324572 7:0.020572146 +1 1:0.750996 2:0.02988 3:0.025896 5:0.021625691 7:0.016750073 +1 1:0.775362 2:0.007246 3:0.028986 5:0.021864237 7:0.015067159 +1 1:0.595238 2:0.071429 3:0.119048 5:0.21231345 7:0.015292293 +1 1:0.708633 2:0.061151 3:0.043165 5:0.058853786 6:0.023685024 7:0.016669591 +1 1:0.776557 2:0.012821 3:0.016484 5:0.011032755 7:0.015087555 +1 1:0.732984 2:0.04712 3:0.015707 5:0.047888122 6:0.019272019 7:0.014908695 +1 1:0.809886 2:0.003802 3:0.030418 5:0.0090498412 7:0.019104146 +1 1:0.753894 2:0.018692 3:0.034268 5:0.033254812 7:0.014901982 +1 1:0.789809 2:0.006369 3:0.031847 5:0.014148763 7:0.02046761 +1 1:0.769737 2:0.019737 3:0.026316 5:0.016564042 7:0.018051988 +1 1:0.759777 2:0.022346 3:0.03352 7:0.01580597 +1 1:0.743869 2:0.024523 3:0.059946 5:0.052823044 7:0.01875789 +1 1:0.695122 2:0.04878 3:0.030488 5:0.061738703 6:0.018633019 7:0.017958061 +1 1:0.768173 2:0.047151 3:0.053045 5:0.042222653 7:0.033842061 +1 1:0.763736 2:0.016484 3:0.038462 5:0.029937531 7:0.016684537 +1 1:0.767828 2:0.0199 3:0.034826 5:0.035893728 7:0.018899409 +1 1:0.784173 2:0.007194 3:0.035971 5:0.018919685 7:0.017283732 +1 1:0.755556 2:0.012698 3:0.044444 5:0.027708616 7:0.015621372 +1 1:0.731982 2:0.013514 3:0.063063 5:0.022885513 7:0.017894421 +1 1:0.748899 2:0.017621 3:0.030837 5:0.013962399 7:0.014344043 +1 1:0.802817 2:0.007042 3:0.049296 5:0.014036945 7:0.022801445 +1 1:0.723404 2:0.008511 3:0.106383 5:0.0099294798 7:0.01948625 +1 1:0.640244 2:0.042683 3:0.134146 5:0.05048231 7:0.016470854 +1 1:0.8 2:0.006452 3:0.012903 7:0.018135329 +1 1:0.737226 2:0.065693 3:0.10219 5:0.031301716 6:0.0018000018 7:0.074194409 +1 1:0.732394 2:0.014085 3:0.103286 7:0.024132604 +1 1:0.724638 2:0.038647 3:0.048309 5:0.026478613 6:0.0053280053 7:0.016584189 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.756944 2:0.013889 3:0.027778 5:0.03679573 7:0.01429822 +1 1:0.763736 2:0.032967 3:0.043956 5:0.023854606 7:0.020939427 +1 1:0.684492 2:0.048128 3:0.085561 5:0.05552905 7:0.01751011 +1 1:0.803371 2:0.005618 3:0.033708 5:0.012262758 7:0.020827622 +1 1:0.676349 2:0.087137 3:0.029046 5:0.064042163 6:0.046392046 7:0.014725232 +1 1:0.71097 2:0.067511 3:0.044304 5:0.080039658 6:0.021474021 7:0.017971079 +1 1:0.787234 2:0.007092 3:0.035461 5:0.01590804 7:0.020260335 +1 1:0.730964 2:0.055838 3:0.050761 5:0.069237994 6:0.0092880093 7:0.019995049 +1 1:0.763158 2:0.015038 3:0.022556 5:0.02242333 7:0.015243902 +1 1:0.78125 2:0.010417 3:0.027778 5:0.017480954 7:0.018059793 +1 1:0.789634 2:0.006098 3:0.033537 5:0.016139132 7:0.017177274 +1 1:0.753247 2:0.012987 3:0.025974 5:0.018591684 7:0.015877415 +1 1:0.769841 2:0.007937 3:0.02381 5:0.027007887 7:0.013356561 +1 1:0.7375 2:0.01875 3:0.0375 5:0.019985687 7:0.014214939 +1 1:0.772414 2:0.027586 3:0.034483 5:0.017003861 6:0.013683014 7:0.018439866 +1 1:0.790451 2:0.023873 3:0.02122 5:0.0060307426 6:0.0097080097 7:0.019990945 +1 1:0.739837 2:0.03252 3:0.04065 5:0.046881756 7:0.015764427 +1 1:0.683673 2:0.081633 3:0.066327 5:0.010086026 6:0.032475032 7:0.022990293 8:0.023809524 +1 1:0.762868 2:0.014706 3:0.042279 5:0.034812816 7:0.016801921 +1 1:0.737024 2:0.031142 3:0.041522 5:0.037228095 7:0.016900159 +1 1:0.727941 2:0.029412 3:0.0625 4:0.0036900369 5:0.022557512 7:0.059271884 +1 1:0.812865 2:0.011696 3:0.046784 5:0.010786755 7:0.024639854 +1 1:0.735409 2:0.027237 3:0.054475 5:0.06246925 7:0.016987756 +1 1:0.748603 2:0.03352 3:0.050279 5:0.026158067 6:0.015789016 7:0.019416817 +1 1:0.761538 2:0.015385 3:0.046154 5:0.022356239 7:0.015642591 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.749333 2:0.024 3:0.029333 5:0.023220968 7:0.015658537 +1 1:0.707094 2:0.036613 3:0.075515 5:0.069372177 7:0.016492713 +1 1:0.757009 2:0.012461 3:0.043614 5:0.031786263 7:0.017817793 +1 1:0.773196 2:0.015464 3:0.041237 5:0.024518062 7:0.019109884 +1 1:0.772727 2:0.011364 3:0.034091 5:0.016243496 7:0.015902165 +1 1:0.760563 2:0.030516 3:0.030516 5:0.030526441 7:0.017476811 +1 1:0.799419 2:0.011628 3:0.023256 5:0.0070818362 7:0.018664921 +1 1:0.742331 2:0.018405 3:0.08589 7:0.020612 +1 1:0.773723 2:0.014599 3:0.036496 5:0.020477688 7:0.016200817 +1 1:0.790588 2:0.014118 3:0.035294 5:0.015751495 7:0.02037303 +1 1:0.783422 2:0.008021 3:0.032086 5:0.013530034 7:0.01796661 +1 1:0.763573 2:0.033275 3:0.024518 5:0.0089529319 6:0.014415014 7:0.017780104 +1 1:0.70088 2:0.067449 3:0.055718 5:0.085772218 6:0.012552013 7:0.017094628 +1 1:0.75 2:0.022727 3:0.037879 7:0.014828159 +1 1:0.733906 2:0.025751 3:0.051502 5:0.026478613 7:0.014733591 +1 1:0.759834 2:0.016563 3:0.028986 5:0.031935354 7:0.014732616 +1 1:0.776536 2:0.005587 3:0.044693 5:0.014528946 7:0.017475134 +1 1:0.766423 2:0.010949 3:0.032847 5:0.027745889 7:0.017936622 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.793103 2:0.02682 3:0.034483 5:0.015132766 6:0.003045003 7:0.023011866 +1 1:0.796117 2:0.014563 3:0.058252 5:0.014655674 7:0.045169311 +1 1:0.787022 2:0.009983 3:0.036606 5:0.015572585 7:0.019429 +1 1:0.79538 2:0.009901 3:0.033003 5:0.013790944 7:0.021754006 +1 1:0.777778 2:0.005848 3:0.093567 5:0.0099518435 7:0.02670803 +1 1:0.760956 2:0.011952 3:0.043825 5:0.030675533 7:0.017709646 +1 1:0.733906 2:0.038627 3:0.034335 5:0.054895412 7:0.017769287 +1 1:0.767857 2:0.008929 3:0.035714 5:0.012240395 7:0.016577744 +1 1:0.779874 2:0.018868 3:0.050314 5:0.029288984 7:0.019519866 +1 1:0.798611 2:0.034722 3:0.041667 5:0.018338228 7:0.034425811 +1 1:0.644444 2:0.044444 3:0.074074 5:0.017577863 6:0.021225021 7:0.01915086 +1 1:0.75 2:0.027778 3:0.034722 5:0.039233373 7:0.016090787 +1 1:0.666667 2:0.016667 3:0.141667 5:0.020649143 7:0.018343494 +1 1:0.793258 2:0.008989 3:0.020225 5:0.0056505598 7:0.018087146 +1 1:0.775758 2:0.036364 3:0.018182 5:0.015304221 6:0.018480018 7:0.017997043 +1 1:0.706294 2:0.034965 3:0.06993 5:0.092257689 7:0.017226677 +1 1:0.765957 2:0.009456 3:0.030733 5:0.020060233 7:0.016072768 +1 1:0.625 2:0.083333 3:0.141667 5:0.074545644 7:0.020325201 +1 1:0.790698 2:0.009302 3:0.026357 5:0.015423494 7:0.018273774 +1 1:0.751073 2:0.030043 3:0.030043 5:0.02448079 7:0.015937402 +1 1:0.8 2:0.025 3:0.066667 5:0.009020023 7:0.083993902 +1 1:0.78169 2:0.007042 3:0.06338 5:0.016526769 7:0.019366195 +1 1:0.773006 2:0.009202 3:0.019939 5:0.017995319 7:0.015496409 +1 1:0.74359 2:0.038462 3:0.064103 5:0.041566651 7:0.021028768 +1 1:0.757812 2:0.03125 3:0.078125 5:0.063445798 7:0.022389482 +1 1:0.734266 2:0.027972 3:0.076923 5:0.032986448 7:0.019273409 +1 1:0.734454 2:0.021849 3:0.036975 5:0.050504674 7:0.015126049 +1 1:0.734568 2:0.037037 3:0.061728 5:0.043340838 7:0.01942186 +1 1:0.765957 2:0.034043 3:0.021277 5:0.010682391 6:0.0085950086 7:0.018111055 +1 1:0.740426 2:0.034043 3:0.03617 5:0.051891223 7:0.01677478 +1 1:0.695332 2:0.044226 3:0.056511 5:0.084937307 7:0.017094146 +1 1:0.775432 2:0.011516 3:0.028791 5:0.026642613 7:0.016373299 +1 1:0.732228 2:0.028436 3:0.035545 5:0.030429532 7:0.014160213 +1 1:0.775701 2:0.009346 3:0.035514 5:0.020440416 7:0.016628677 +1 1:0.770235 2:0.031332 3:0.015666 5:0.028700073 6:0.017325017 7:0.016541427 +1 1:0.780069 2:0.017182 3:0.04811 5:0.039904283 7:0.019570866 +1 1:0.782875 2:0.01682 3:0.03211 5:0.022289148 6:0.0044850045 7:0.018712238 +1 1:0.746106 2:0.020249 3:0.063863 5:0.051712313 7:0.017798799 +1 1:0.755906 2:0.055118 3:0.027559 5:0.025912066 6:0.024333024 7:0.020717305 +1 1:0.767442 2:0.013953 3:0.046512 5:0.023004786 6:0.0046290046 7:0.018377762 +1 1:0.786585 2:0.012195 3:0.034553 5:0.023176241 7:0.019928616 +1 1:0.767123 2:0.013699 3:0.034247 5:0.02662025 7:0.017540927 +1 1:0.716981 2:0.037736 3:0.081761 5:0.036072637 7:0.047553305 +1 1:0.745614 2:0.02193 3:0.030702 5:0.026433885 7:0.015083439 +1 1:0.700637 2:0.070064 3:0.025478 5:0.079092929 6:0.031830032 7:0.014641915 +1 1:0.740196 2:0.029412 3:0.034314 5:0.030302804 7:0.014705884 +1 1:0.708333 2:0.025 3:0.05 5:0.083446394 7:0.013617884 +1 1:0.778291 2:0.009238 3:0.025404 5:0.020880235 7:0.015081957 +1 1:0.772358 2:0.00813 3:0.04065 5:0.02036587 7:0.018143963 +1 1:0.789189 2:0.008108 3:0.02973 5:0.013589671 7:0.018078445 +1 1:0.635036 2:0.062044 3:0.047445 5:0.10864282 6:0.01008901 7:0.019850457 +1 1:0.772109 2:0.02381 3:0.018707 5:0.02335515 6:0.0075180075 7:0.016550524 +1 1:0.785311 2:0.014124 3:0.025424 5:0.014968765 6:0.006024006 7:0.017155848 +1 1:0.786765 2:0.003676 3:0.036765 5:0.0095120242 7:0.017575323 +1 1:0.765781 2:0.024917 3:0.031561 5:0.026404067 6:0.0088560089 7:0.01715825 +1 1:0.758621 2:0.024138 3:0.034483 5:0.028782073 6:0.0077220077 7:0.016337256 +1 1:0.796196 2:0.008152 3:0.035326 5:0.01275476 7:0.019369695 +1 1:0.758065 2:0.053763 3:0.053763 5:0.021260418 6:0.0085560086 7:0.03448728 +1 1:0.793103 2:0.013793 3:0.031034 5:0.014446946 7:0.021698909 +1 1:0.774725 2:0.010989 3:0.054945 5:0.012613123 7:0.019800323 +1 1:0.771429 2:0.012987 3:0.041558 5:0.032129173 7:0.018371872 +1 1:0.719595 2:0.023649 3:0.052365 4:0.0036900369 5:0.024652245 6:0.0028350028 7:0.021804963 +1 1:0.75969 2:0.013953 3:0.029457 5:0.027186796 7:0.015551146 +1 1:0.772036 2:0.006079 3:0.054711 5:0.015609858 7:0.017699604 +1 1:0.730263 2:0.013158 3:0.036184 5:0.028454072 7:0.015765402 +1 1:0.704797 2:0.01845 3:0.073801 5:0.05271868 7:0.015907659 +1 1:0.76 2:0.015 3:0.05 5:0.012941124 7:0.017560976 +1 1:0.679348 2:0.048913 3:0.097826 5:0.033008811 7:0.044903232 +1 1:0.744409 2:0.038339 3:0.041534 5:0.015304221 6:0.021561022 7:0.018974518 +1 1:0.784024 2:0.005917 3:0.026627 5:0.015945313 7:0.016867512 +1 1:0.782158 2:0.022822 3:0.029046 5:0.017868591 6:0.0053910054 7:0.021113756 +1 1:0.768707 2:0.020408 3:0.020408 5:0.018778048 7:0.016467561 +1 1:0.782178 2:0.021452 3:0.029703 5:0.023944061 6:0.0048180048 7:0.01879578 +1 1:0.70892 2:0.056338 3:0.084507 5:0.01959805 6:0.0026280026 7:0.065326921 +1 1:0.601124 2:0.022472 3:0.05618 5:0.062253068 7:0.016408604 +1 1:0.788671 2:0.006536 3:0.026144 5:0.017592772 7:0.01688453 +1 1:0.737052 2:0.031873 3:0.039841 5:0.032740447 6:0.0043920044 7:0.016592171 +1 1:0.735099 2:0.086093 3:0.019868 5:0.015796222 6:0.050847051 7:0.019059927 +1 1:0.741497 2:0.034014 3:0.061224 5:0.041007559 6:0.0066000066 7:0.018852665 +1 1:0.733871 2:0.043011 3:0.053763 5:0.069670359 7:0.017538683 +1 1:0.756701 2:0.020619 3:0.035052 5:0.03661682 7:0.017915512 +1 1:0.76 2:0.022857 3:0.045714 5:0.044995751 7:0.017317073 +1 1:0.75 2:0.025 3:0.065 5:0.048327941 7:0.018810976 +1 1:0.746741 2:0.042831 3:0.042831 5:0.03739955 6:0.015051015 7:0.020370622 +1 1:0.767442 2:0.027907 3:0.037209 4:0.0036900369 5:0.036490093 7:0.020277933 +1 1:0.721239 2:0.048673 3:0.035398 5:0.066561806 6:0.010713011 7:0.015109 +1 1:0.722222 2:0.064815 3:0.032407 5:0.036967185 6:0.044628045 7:0.017078817 +1 1:0.794595 2:0.005405 3:0.032432 5:0.012404395 7:0.019808835 +1 1:0.789474 2:0.019737 3:0.026316 5:0.012344759 7:0.02422978 +1 1:0.764706 2:0.013072 3:0.029412 5:0.018114592 7:0.016399652 +1 1:0.730114 2:0.03125 3:0.034091 5:0.045346115 7:0.014239189 +1 1:0.751724 2:0.027586 3:0.027586 5:0.018681138 7:0.016778805 +1 1:0.77628 2:0.013477 3:0.032345 5:0.027760798 7:0.017651701 +1 1:0.750779 2:0.021807 3:0.034268 5:0.018450047 6:0.011139011 7:0.015348378 +1 1:0.72067 2:0.03352 3:0.072626 5:0.092794418 7:0.016419128 +1 1:0.748299 2:0.022676 3:0.036281 5:0.024786427 6:0.0024930025 7:0.016633482 +1 1:0.759843 2:0.03937 3:0.047244 5:0.043795566 6:0.010575011 7:0.020429232 +1 1:0.76 2:0.015 3:0.05 5:0.012941124 7:0.017560976 +1 1:0.794118 2:0.012605 3:0.046218 5:0.0078645655 7:0.024287762 +1 1:0.770186 2:0.024845 3:0.049689 5:0.044198113 7:0.019163762 +1 1:0.741722 2:0.02649 3:0.046358 5:0.018681138 7:0.016112098 +1 1:0.782895 2:0.015351 3:0.017544 5:0.012016758 7:0.016594457 +1 1:0.746544 2:0.018433 3:0.0553 5:0.050027582 7:0.01674722 +1 1:0.726415 2:0.04717 3:0.034591 5:0.062886706 6:0.01012501 7:0.017046329 +1 1:0.768595 2:0.014876 3:0.028099 5:0.024204971 6:0.0038970039 7:0.015521067 +1 1:0.761589 2:0.013245 3:0.039735 5:0.035498636 7:0.016960104 +1 1:0.779487 2:0.005128 3:0.041026 7:0.017636024 +1 1:0.633452 2:0.088968 3:0.081851 5:0.038152461 6:0.03991804 7:0.021200415 +1 1:0.594737 2:0.115789 3:0.031579 5:0.033128084 6:0.10666811 7:0.014441591 +1 1:0.771429 2:0.052381 3:0.028571 5:0.030265532 6:0.024357024 7:0.02145761 +1 1:0.757511 2:0.021459 3:0.017167 5:0.025226246 6:0.0025380025 7:0.015466348 +1 1:0.764151 2:0.009434 3:0.023585 5:0.015624767 7:0.013719512 +1 1:0.769634 2:0.020942 3:0.031414 5:0.028506254 7:0.016696463 +1 1:0.737533 2:0.028871 3:0.034121 5:0.047701758 6:0.0054840055 7:0.017508482 +1 1:0.77561 2:0.029268 3:0.063415 5:0.028342254 7:0.023468171 +1 1:0.736742 2:0.034091 3:0.049242 5:0.055253232 6:0.004044004 7:0.017137841 +1 1:0.756098 2:0.02439 3:0.039024 5:0.025144246 7:0.017638311 +1 1:0.737705 2:0.010929 3:0.065574 7:0.016393439 +1 1:0.739659 2:0.026764 3:0.043796 5:0.028752255 6:0.0086790087 7:0.015384841 +1 1:0.777778 2:0.015152 3:0.022727 5:0.020425507 6:0.0027390027 7:0.016860683 +1 1:0.725806 2:0.024194 3:0.064516 5:0.023295514 7:0.01573564 +1 1:0.775701 2:0.006231 3:0.043614 5:0.013298943 7:0.021293976 +1 1:0.792531 2:0.004149 3:0.029046 5:0.010712209 7:0.017609555 +1 1:0.738532 2:0.013761 3:0.041284 5:0.030928988 7:0.013481762 +1 1:0.777778 2:0.005848 3:0.093567 5:0.0099518435 7:0.02670803 +1 1:0.818182 2:0.005348 3:0.037433 5:0.010667482 7:0.022792488 +1 1:0.764423 2:0.019231 3:0.014423 5:0.021588419 7:0.015185274 +1 1:0.779412 2:0.009804 3:0.039216 5:0.025397701 7:0.017545433 +1 1:0.793939 2:0.006061 3:0.036364 7:0.019438287 +1 1:0.782082 2:0.007264 3:0.033898 5:0.011748394 7:0.018735604 +1 1:0.789137 2:0.01278 3:0.041534 5:0.028975892 7:0.020045976 +1 1:0.762557 2:0.031963 3:0.022831 5:0.038689189 6:0.015570016 7:0.016093104 +1 1:0.75969 2:0.013953 3:0.029457 5:0.027186796 7:0.015551146 +1 1:0.740845 2:0.028169 3:0.047887 5:0.039397373 7:0.016248713 +1 1:0.75122 2:0.019512 3:0.029268 5:0.029758621 7:0.014901841 +1 1:0.734644 2:0.027027 3:0.027027 5:0.028588255 6:0.0086280086 7:0.015625939 +1 1:0.712389 2:0.044248 3:0.061947 5:0.078943837 7:0.017834018 +1 1:0.772344 2:0.020236 3:0.030354 5:0.017227498 7:0.017799122 +1 1:0.753247 2:0.025974 3:0.038961 5:0.018002773 6:0.0072450072 7:0.016392146 +1 1:0.748092 2:0.022901 3:0.045802 5:0.043340838 7:0.016011915 +1 1:0.743631 2:0.035032 3:0.033439 5:0.021670419 6:0.012210012 7:0.016700323 +1 1:0.776536 2:0.01676 3:0.01676 5:0.016101859 7:0.015771902 +1 1:0.767241 2:0.025862 3:0.034483 5:0.033336812 7:0.019589293 +1 1:0.766816 2:0.015695 3:0.022422 5:0.026508431 7:0.015380622 +1 1:0.671498 2:0.048309 3:0.072464 5:0.097229884 7:0.013550134 +1 1:0.653846 2:0.102564 3:0.051282 5:0.11785666 6:0.02964303 7:0.019777988 +1 1:0.746412 2:0.019139 3:0.047847 5:0.028454072 7:0.015287665 +1 1:0.778672 2:0.01006 3:0.024145 5:0.010637663 7:0.017200762 +1 1:0.780488 2:0.01897 3:0.0271 5:0.027082433 6:0.0081750082 7:0.018193537 +1 1:0.732143 2:0.0625 3:0.026786 5:0.04809685 6:0.019356019 7:0.02109647 +1 1:0.776371 2:0.012658 3:0.046414 5:0.030101531 7:0.019115982 +1 1:0.741259 2:0.034965 3:0.034965 5:0.036013001 7:0.017653079 +1 1:0.739726 2:0.020548 3:0.075342 5:0.050370492 7:0.018543268 +1 1:0.785714 2:0.007143 3:0.078571 5:0.013291488 7:0.024433799 +1 1:0.77266 2:0.017831 3:0.034175 5:0.025882248 6:0.002976003 7:0.0182655 +1 1:0.687023 2:0.061069 3:0.099237 5:0.12079376 7:0.020107988 +1 1:0.755556 2:0.016667 3:0.05 5:0.014417128 7:0.017513549 +1 1:0.744898 2:0.026531 3:0.018367 5:0.042237562 6:0.0084990085 7:0.017570933 +1 1:0.738983 2:0.037288 3:0.061017 5:0.063378707 7:0.019450189 +1 1:0.776722 2:0.016627 3:0.021378 5:0.019381868 7:0.016713982 +1 1:0.771812 2:0.020134 3:0.053691 5:0.033060993 7:0.018456378 +1 1:0.722054 2:0.030211 3:0.075529 5:0.079644566 7:0.017242652 +1 1:0.744604 2:0.039568 3:0.017986 5:0.033277176 6:0.0089280089 7:0.014739427 +1 1:0.740385 2:0.03125 3:0.045673 5:0.044145931 6:0.0076140076 7:0.01732528 +1 1:0.722727 2:0.077273 3:0.040909 5:0.030429532 6:0.044898045 7:0.020371396 +1 1:0.761905 2:0.017857 3:0.041667 5:0.033060993 7:0.016369049 +1 1:0.79476 2:0.008734 3:0.034934 5:0.020119869 7:0.019730537 +1 1:0.747664 2:0.023364 3:0.051402 5:0.0061127428 6:0.0073830074 7:0.017366652 +1 1:0.774143 2:0.010903 3:0.031153 5:0.023653333 7:0.017960262 +1 1:0.75 2:0.02451 3:0.039216 5:0.02730607 7:0.016319945 +1 1:0.75 2:0.024194 3:0.040323 5:0.04732903 7:0.015489774 +1 1:0.8 2:0.004762 3:0.02381 7:0.018292683 +1 1:0.753425 2:0.027397 3:0.023973 5:0.022490421 6:0.018099018 7:0.013844805 +1 1:0.74026 2:0.02381 3:0.028139 5:0.02268424 7:0.013013409 +1 1:0.772926 2:0.030568 3:0.026201 5:0.033836268 6:0.013617014 7:0.017600384 +1 1:0.757895 2:0.017544 3:0.024561 5:0.010399117 7:0.015340183 +1 1:0.684783 2:0.076087 3:0.038043 5:0.072376366 6:0.019416019 7:0.020479854 +1 1:0.768657 2:0.014925 3:0.029851 5:0.019829141 7:0.017109573 +1 1:0.739837 2:0.04878 3:0.04878 5:0.059957062 7:0.018490976 +1 1:0.781716 2:0.007463 3:0.04291 5:0.018181683 7:0.018656713 +1 1:0.727619 2:0.017143 3:0.032381 5:0.037578459 7:0.018432055 +1 1:0.73622 2:0.027559 3:0.051181 5:0.021238054 7:0.016852317 +1 1:0.761538 2:0.02 3:0.027692 5:0.022318966 6:0.0017970018 7:0.015666043 +1 1:0.771293 2:0.015773 3:0.056782 5:0.03140608 7:0.020543201 +1 1:0.741935 2:0.021505 3:0.064516 5:0.042192835 7:0.017374768 +1 1:0.728137 2:0.028517 3:0.047529 5:0.034454997 7:0.020066305 +1 1:0.753363 2:0.022422 3:0.022422 5:0.033821359 7:0.015066171 +1 1:0.793696 2:0.008596 3:0.022923 5:0.0070818362 7:0.018397512 +1 1:0.768627 2:0.015686 3:0.058824 5:0.018159319 7:0.019631756 +1 1:0.719409 2:0.033755 3:0.029536 5:0.054559957 6:0.0027450027 7:0.014060409 +1 1:0.736334 2:0.03537 3:0.032154 5:0.039755192 6:0.015999016 7:0.014704732 +1 1:0.798578 2:0.016588 3:0.028436 5:0.01634786 6:0.0043860044 7:0.0197665 +1 1:0.723077 2:0.024615 3:0.058462 5:0.024309335 7:0.017260787 +1 1:0.78972 2:0.014019 3:0.023364 5:0.0096536609 7:0.021996811 +1 1:0.757282 2:0.009709 3:0.121359 5:0.0084534761 7:0.02610703 +1 1:0.731132 2:0.028302 3:0.042453 5:0.02934862 7:0.014611134 +1 1:0.768595 2:0.011019 3:0.027548 5:0.028558436 7:0.017536787 +1 1:0.736559 2:0.024194 3:0.061828 5:0.052181951 6:0.003000003 7:0.016391293 +1 1:0.719388 2:0.035714 3:0.045918 5:0.049587763 7:0.01403061 +1 1:0.79538 2:0.009901 3:0.033003 5:0.013790944 7:0.021754006 +1 1:0.757812 2:0.027344 3:0.03125 4:0.0036900369 5:0.033083357 7:0.016101372 +1 1:0.75122 2:0.019512 3:0.029268 5:0.029758621 7:0.014901841 +1 1:0.75419 2:0.03352 3:0.106145 5:0.0081105661 6:0.0032640033 7:0.062610707 +1 1:0.710744 2:0.066116 3:0.033058 5:0.056759054 6:0.015228015 7:0.019854866 +1 1:0.784091 2:0.007576 3:0.045455 5:0.017726954 7:0.019424427 +1 1:0.725926 2:0.037037 3:0.037037 5:0.04450375 6:0.008955009 7:0.015130988 +1 1:0.723077 2:0.032692 3:0.034615 5:0.048879579 6:0.0073770074 7:0.014305817 +1 1:0.739796 2:0.02551 3:0.030612 5:0.045547389 7:0.015275012 +1 1:0.747899 2:0.016807 3:0.054622 5:0.033530631 7:0.017088543 +1 1:0.776074 2:0.016871 3:0.030675 5:0.027798071 7:0.017553866 +1 1:0.761044 2:0.018072 3:0.028112 5:0.02284824 7:0.015978549 +1 1:0.768657 2:0.014925 3:0.029851 5:0.019829141 7:0.017109573 +1 1:0.714953 2:0.023364 3:0.088785 5:0.048409941 7:0.01755186 +1 1:0.728426 2:0.027919 3:0.053299 5:0.022184784 7:0.015599854 +1 1:0.741333 2:0.016 3:0.069333 5:0.016586406 7:0.029235774 +1 1:0.726667 2:0.04 3:0.04 7:0.015731707 +1 1:0.796526 2:0.002481 3:0.034739 5:0.0060381972 7:0.018670945 +1 1:0.751131 2:0.0181 3:0.031674 5:0.014678037 7:0.014016116 +1 1:0.776423 2:0.00813 3:0.03252 5:0.023444605 7:0.015764427 +1 1:0.790055 2:0.01105 3:0.022099 5:0.0069774723 6:0.0056190056 7:0.017989488 +1 1:0.773723 2:0.012165 3:0.053528 5:0.018181683 7:0.024330902 +1 1:0.748052 2:0.025974 3:0.062338 5:0.05057922 7:0.018672793 +1 1:0.768061 2:0.015209 3:0.019011 5:0.011450211 7:0.015093201 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.741736 2:0.018595 3:0.041322 5:0.041879743 7:0.015697439 +1 1:0.746518 2:0.044568 3:0.027855 5:0.025748066 6:0.020724021 7:0.019668457 +1 1:0.740053 2:0.050398 3:0.02122 5:0.085116217 6:0.011418011 7:0.016998768 8:0.023809524 +1 1:0.783673 2:0.012245 3:0.008163 6:0.0082860083 7:0.018018915 +1 1:0.679671 2:0.032854 3:0.086242 5:0.082961848 7:0.015750988 +1 1:0.746575 2:0.034247 3:0.10274 5:0.017085862 7:0.054669232 +1 1:0.757798 2:0.018349 3:0.040367 5:0.046523937 7:0.016133366 +1 1:0.746725 2:0.017467 3:0.048035 5:0.0394421 7:0.015097451 +1 1:0.794702 2:0.013245 3:0.033113 5:0.014819674 7:0.020311744 +1 1:0.756701 2:0.020619 3:0.035052 5:0.03661682 7:0.017915512 +1 1:0.73743 2:0.020484 3:0.024209 5:0.040642285 7:0.014579646 +1 1:0.716418 2:0.056716 3:0.059701 5:0.058749422 6:0.013134013 7:0.020786311 +1 1:0.745614 2:0.02193 3:0.030702 5:0.026433885 7:0.015083439 +1 1:0.78821 2:0.008734 3:0.019651 5:0.012396941 7:0.016016079 +1 1:0.755396 2:0.02518 3:0.035971 5:0.029385893 7:0.016691524 +1 1:0.75 2:0.020833 3:0.033854 5:0.0393601 7:0.015037476 +1 1:0.741036 2:0.027888 3:0.031873 5:0.038159915 6:0.0051180051 7:0.014235738 +1 1:0.751412 2:0.016949 3:0.028249 5:0.016049677 6:0.0064590065 7:0.016001793 +1 1:0.730909 2:0.025455 3:0.043636 5:0.055797415 7:0.01481153 +1 1:0.769697 2:0.018182 3:0.054545 5:0.039650828 7:0.020842573 +1 1:0.705882 2:0.026144 3:0.078431 5:0.052010496 7:0.017136933 +1 1:0.777778 2:0.007576 3:0.040404 5:0.013291488 7:0.017276421 +1 1:0.658333 2:0.125 3:0.025 4:0.0036900369 5:0.058853786 6:0.078948079 7:0.019308945 +1 1:0.787302 2:0.009524 3:0.028571 5:0.0076483831 7:0.018873402 +1 1:0.787234 2:0.007092 3:0.035461 5:0.01590804 7:0.020260335 +1 1:0.754217 2:0.024096 3:0.026506 5:0.036683912 7:0.014928006 +1 1:0.730769 2:0.028846 3:0.033654 5:0.047686849 7:0.013748829 +1 1:0.794521 2:0.009132 3:0.050228 5:0.0092958418 7:0.022329884 +1 1:0.775 2:0.015909 3:0.015909 5:0.013612035 7:0.01517461 +1 1:0.767372 2:0.012085 3:0.030211 5:0.023742788 7:0.017353183 +1 1:0.792017 2:0.008403 3:0.035714 5:0.0097282066 6:0.001959002 7:0.019624927 +1 1:0.791139 2:0.009494 3:0.03481 5:0.0080732933 7:0.01781028 +1 1:0.785714 2:0.011278 3:0.037594 5:0.024518062 7:0.020905921 +1 1:0.73251 2:0.041152 3:0.028807 5:0.045592116 7:0.01641072 +1 1:0.738337 2:0.030426 3:0.024341 5:0.037794642 6:0.0076050076 7:0.01951714 +1 1:0.712264 2:0.037736 3:0.061321 5:0.080591296 7:0.015962951 +1 1:0.782383 2:0.005181 3:0.025907 5:0.013172215 7:0.017881963 +1 1:0.74415 2:0.046802 3:0.026521 5:0.044496295 6:0.01953302 7:0.017531677 +1 1:0.783784 2:0.008108 3:0.037838 5:0.020254052 7:0.018193805 +1 1:0.739394 2:0.024242 3:0.054545 5:0.062513977 7:0.017627494 +1 1:0.729358 2:0.03211 3:0.041284 5:0.041797743 7:0.014964201 +1 1:0.747082 2:0.023346 3:0.031128 5:0.038823372 7:0.018221506 +1 1:0.748466 2:0.018405 3:0.042945 5:0.035110998 7:0.015886079 +1 1:0.696203 2:0.054852 3:0.067511 5:0.093770966 6:0.0047160047 7:0.016363073 +1 1:0.765182 2:0.020243 3:0.036437 5:0.033731904 7:0.01636714 +1 1:0.762557 2:0.031963 3:0.027397 5:0.023116604 6:0.013953014 7:0.017958567 +1 1:0.768953 2:0.01444 3:0.037906 5:0.02258733 7:0.018160604 +1 1:0.744472 2:0.022113 3:0.041769 5:0.021610782 6:0.0057960058 7:0.015506085 +1 1:0.748344 2:0.02649 3:0.039735 5:0.019724777 7:0.015264091 +1 1:0.706161 2:0.056872 3:0.085308 5:0.020231688 6:0.0027150027 7:0.063894348 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.755853 2:0.013378 3:0.0301 7:0.014254835 +1 1:0.76555 2:0.023923 3:0.047847 6:0.0041550042 7:0.021064299 +1 1:0.757112 2:0.026258 3:0.021882 5:0.02438388 7:0.016317982 +1 1:0.731132 2:0.028302 3:0.042453 5:0.02934862 7:0.014611134 +1 1:0.72028 2:0.034965 3:0.048951 5:0.041529378 7:0.01530786 +1 1:0.75641 2:0.032051 3:0.064103 5:0.065279621 7:0.022318634 +1 1:0.742424 2:0.060606 3:0.034091 5:0.051294858 6:0.024084024 7:0.020140427 +1 1:0.710801 2:0.020906 3:0.055749 5:0.033351721 7:0.018993799 +1 1:0.699153 2:0.042373 3:0.072034 5:0.024972791 7:0.015424762 +1 1:0.752852 2:0.022814 3:0.026616 5:0.011614211 7:0.014884543 +1 1:0.77095 2:0.011173 3:0.027933 5:0.016310587 7:0.015567518 +1 1:0.765591 2:0.025806 3:0.012903 5:0.017846227 7:0.016430634 +1 1:0.715596 2:0.03211 3:0.052752 5:0.059166878 6:0.005952006 7:0.014097116 +1 1:0.74606 2:0.012259 3:0.033275 4:0.0036900369 5:0.022863149 7:0.017406348 +1 1:0.760263 2:0.021346 3:0.044335 5:0.029020619 7:0.018002323 +1 1:0.795699 2:0.018817 3:0.043011 5:0.017741863 6:0.0028560029 7:0.03443811 +1 1:0.775862 2:0.012931 3:0.012931 5:0.013455489 7:0.014560555 +1 1:0.767347 2:0.02449 3:0.02449 5:0.01138312 6:0.0091590092 7:0.01630164 +1 1:0.763949 2:0.008584 3:0.042918 5:0.023004786 7:0.016958024 +1 1:0.761589 2:0.013245 3:0.039735 5:0.035498636 7:0.016960104 +1 1:0.753213 2:0.015424 3:0.048843 4:0.0036900369 5:0.041111923 7:0.01705436 +1 1:0.75122 2:0.019512 3:0.029268 5:0.029758621 7:0.014901841 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.693548 2:0.048387 3:0.048387 5:0.082827665 7:0.013276945 +1 1:0.759399 2:0.030075 3:0.180451 5:0.0014909129 7:0.2289107 +1 1:0.773077 2:0.030769 3:0.069231 5:0.027671343 7:0.044230768 +1 1:0.726562 2:0.03125 3:0.070312 5:0.072547821 7:0.01957889 +1 1:0.778471 2:0.01092 3:0.034321 5:0.016467133 7:0.017227274 +1 1:0.751938 2:0.007752 3:0.046512 5:0.020477688 7:0.017205518 +1 1:0.748691 2:0.015707 3:0.065445 5:0.030205895 7:0.019697354 +1 1:0.751055 2:0.021097 3:0.042194 5:0.035438999 7:0.016234433 +1 1:0.766082 2:0.011696 3:0.046784 4:0.0073800738 5:0.032449719 7:0.01638497 +1 1:0.72549 2:0.026144 3:0.039216 5:0.042118289 7:0.014108079 +1 1:0.765896 2:0.017341 3:0.026012 5:0.0081702026 7:0.016072183 +1 1:0.721739 2:0.030435 3:0.056522 5:0.053531227 6:0.0053850054 7:0.014766701 +1 1:0.713115 2:0.04918 3:0.065574 5:0.041999016 6:0.016902017 7:0.017742902 +1 1:0.75493 2:0.025352 3:0.042254 5:0.03473827 7:0.018430091 +1 1:0.79096 2:0.011299 3:0.028249 5:0.014528946 7:0.017672591 +1 1:0.751204 2:0.019262 3:0.035313 5:0.037369731 7:0.01562072 +1 1:0.74026 2:0.02381 3:0.028139 5:0.02268424 7:0.013013409 +1 1:0.748166 2:0.017115 3:0.036675 5:0.03132408 7:0.014192854 +1 1:0.753535 2:0.018182 3:0.034343 5:0.016124223 7:0.017085488 +1 1:0.773585 2:0.012579 3:0.028302 5:0.02823789 7:0.015186378 +1 1:0.751634 2:0.028322 3:0.030501 5:0.023258241 6:0.021060021 7:0.017030659 +1 1:0.755319 2:0.015957 3:0.069149 5:0.026575522 6:0.0053490053 7:0.018195384 +1 1:0.723022 2:0.017986 3:0.032374 5:0.043914839 7:0.014892963 +1 1:0.764228 2:0.04065 3:0.056911 5:0.044287567 7:0.025034701 +1 1:0.77591 2:0.016807 3:0.028011 5:0.023004786 6:0.0030870031 7:0.016601762 +1 1:0.738255 2:0.020134 3:0.033557 5:0.0498114 7:0.01837453 +1 1:0.766284 2:0.019157 3:0.042146 5:0.040962832 7:0.017007756 +1 1:0.758261 2:0.015652 3:0.029565 5:0.010563118 7:0.014962884 +1 1:0.757576 2:0.022727 3:0.030303 5:0.023004786 7:0.014966738 +1 1:0.779817 2:0.012232 3:0.036697 5:0.02908771 7:0.019113152 +1 1:0.729107 2:0.051873 3:0.040346 5:0.035565727 6:0.022902023 7:0.018415689 +1 1:0.757576 2:0.018182 3:0.042424 5:0.048201214 7:0.017147079 +1 1:0.804714 2:0.006734 3:0.023569 5:0.0082745665 7:0.018497988 +1 1:0.767908 2:0.017192 3:0.034384 5:0.015244584 7:0.017087146 +1 1:0.759259 2:0.018519 3:0.037037 5:0.044369567 7:0.018970189 +1 1:0.780576 2:0.007194 3:0.02518 5:0.020343506 7:0.016077384 +1 1:0.773684 2:0.021053 3:0.021053 5:0.014118945 7:0.016944799 +1 1:0.607692 2:0.176923 3:0.023077 4:0.0036900369 5:0.055909233 6:0.12000012 7:0.018761726 +1 1:0.75 2:0.015873 3:0.027778 5:0.012426759 7:0.014518 +1 1:0.75641 2:0.022436 3:0.025641 5:0.028163344 7:0.015517512 +1 1:0.773973 2:0.006849 3:0.054795 5:0.016601315 7:0.018752085 +1 1:0.72314 2:0.03719 3:0.061983 5:0.032457174 7:0.017360409 +1 1:0.702899 2:0.028986 3:0.072464 5:0.088478225 7:0.014890421 +1 1:0.731458 2:0.053708 3:0.040921 5:0.026314612 6:0.034422034 7:0.01766889 +1 1:0.739796 2:0.020408 3:0.045918 7:0.015368341 +1 1:0.728051 2:0.062098 3:0.03212 5:0.043691202 6:0.030768031 7:0.017822634 +1 1:0.782609 2:0.007246 3:0.054348 5:0.016385133 7:0.020104274 +1 1:0.765385 2:0.007692 3:0.034615 7:0.017120073 +1 1:0.757974 2:0.016886 3:0.0394 5:0.032613719 7:0.018304122 +1 1:0.76378 2:0.062992 3:0.023622 6:0.027273027 7:0.021125409 +1 1:0.762943 2:0.021798 3:0.019074 5:0.0079912931 7:0.015501427 +1 1:0.722222 2:0.033333 3:0.05 5:0.034119541 6:0.0068640069 7:0.014803524 +1 1:0.790698 2:0.017442 3:0.040698 5:0.023079331 7:0.022901305 +1 1:0.76087 2:0.019565 3:0.023913 5:0.026225158 7:0.015071579 +1 1:0.736842 2:0.016194 3:0.064777 5:0.022900422 7:0.016070902 +1 1:0.73494 2:0.012048 3:0.078313 5:0.027917344 7:0.019615043 +1 1:0.768627 2:0.015686 3:0.058824 5:0.018159319 7:0.019631756 +1 1:0.773885 2:0.009554 3:0.035032 5:0.026843887 7:0.016176012 +1 1:0.78607 2:0.004975 3:0.0199 5:0.014819674 7:0.015259073 +1 1:0.781705 2:0.014553 3:0.04158 5:0.018040046 7:0.020954817 +1 1:0.730769 2:0.057692 3:0.032051 5:0.016139132 6:0.025974026 7:0.018058165 +1 1:0.72973 2:0.023166 3:0.034749 5:0.012963488 7:0.013537055 +1 1:0.731308 2:0.053738 3:0.049065 5:0.049267216 6:0.023793024 7:0.021555165 +1 1:0.781955 2:0.015038 3:0.035088 5:0.024972791 7:0.018246835 +1 1:0.75266 2:0.023936 3:0.037234 5:0.048409941 6:0.0064950065 7:0.014984433 +1 1:0.766807 2:0.014706 3:0.058824 5:0.032248446 7:0.020726585 +1 1:0.797814 2:0.019126 3:0.040984 5:0.015624767 7:0.023840463 +1 1:0.730909 2:0.025455 3:0.043636 5:0.055797415 7:0.01481153 +1 1:0.794776 2:0.007463 3:0.029851 5:0.018159319 7:0.01867947 +1 1:0.745 2:0.025 3:0.035 5:0.01582604 7:0.014359756 +1 1:0.735426 2:0.058296 3:0.026906 5:0.036967185 6:0.02975103 7:0.016542713 +1 1:0.732394 2:0.014085 3:0.103286 7:0.024132604 +1 1:0.771845 2:0.009709 3:0.029126 5:0.014849492 7:0.014859104 +1 1:0.727848 2:0.018987 3:0.082278 5:0.045226842 7:0.019083823 +1 1:0.738095 2:0.02381 3:0.042857 7:0.0141115 +1 1:0.731405 2:0.020661 3:0.07438 5:0.044309931 7:0.016957268 +1 1:0.766862 2:0.010264 3:0.033724 4:0.0036900369 5:0.020917508 6:0.0016830017 7:0.015932335 +1 1:0.737079 2:0.024719 3:0.031461 5:0.024600063 7:0.016607293 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.719731 2:0.033632 3:0.056054 5:0.072212366 7:0.018347372 +1 1:0.711268 2:0.028169 3:0.06338 5:0.038525189 7:0.016618 +1 1:0.736148 2:0.031662 3:0.036939 5:0.037995915 7:0.015782872 +1 1:0.770975 2:0.029478 3:0.034014 5:0.064168891 7:0.019274378 8:0.023809524 +1 1:0.746241 2:0.030075 3:0.031955 5:0.031122806 6:0.0041760042 7:0.016470293 +1 1:0.751412 2:0.033898 3:0.039548 5:0.028834255 7:0.01781039 +1 1:0.79375 2:0.0125 3:0.04375 5:0.020440416 7:0.020846037 +1 1:0.714286 2:0.018797 3:0.033835 5:0.051056312 7:0.016733909 +1 1:0.635135 2:0.079151 3:0.086873 5:0.12981378 7:0.022306713 +1 1:0.735632 2:0.028736 3:0.04023 5:0.03080226 6:0.0061980062 7:0.01696103 +1 1:0.783582 2:0.003731 3:0.037313 5:0.010279844 7:0.016495268 +1 1:0.77931 2:0.013793 3:0.041379 5:0.017339317 7:0.018082421 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.743455 2:0.020942 3:0.052356 5:0.011509847 6:0.0023160023 7:0.020671049 +1 1:0.752193 2:0.046053 3:0.032895 5:0.02516661 6:0.024309024 7:0.019803701 +1 1:0.771242 2:0.013072 3:0.052288 5:0.024048425 7:0.018531805 +1 1:0.700495 2:0.029703 3:0.074257 5:0.038264279 7:0.014700555 +1 1:0.722892 2:0.03012 3:0.066265 5:0.078302745 7:0.017484573 +1 1:0.692308 2:0.053254 3:0.076923 4:0.0036900369 5:0.086077855 6:0.013857014 7:0.015622744 +1 1:0.64 2:0.113333 3:0.06 5:0.037653005 6:0.083334083 7:0.016097561 +1 1:0.791798 2:0.006309 3:0.018927 5:0.0081702026 7:0.017542512 +1 1:0.669173 2:0.090226 3:0.06015 5:0.083014029 6:0.02004602 7:0.020585 +1 1:0.793388 2:0.008264 3:0.049587 5:0.01822641 7:0.020610762 +1 1:0.791667 2:0.010417 3:0.028274 5:0.017361681 6:0.0013980014 7:0.019481348 +1 1:0.78866 2:0.010309 3:0.030928 5:0.012806942 7:0.018292683 +1 1:0.774536 2:0.013263 3:0.034483 5:0.03080226 7:0.019570421 +1 1:0.783673 2:0.012245 3:0.008163 6:0.0082860083 7:0.018018915 +1 1:0.729965 2:0.034843 3:0.052265 5:0.027559525 7:0.017241012 +1 1:0.796009 2:0.013304 3:0.019956 5:0.010421481 6:0.0062880063 7:0.01934725 +1 1:0.742515 2:0.017964 3:0.071856 5:0.045830662 7:0.017818024 +1 1:0.771015 2:0.011594 3:0.023188 5:0.017480954 7:0.015076 +1 1:0.774059 2:0.01046 3:0.031381 5:0.022169875 7:0.01715736 +1 1:0.783333 2:0.016667 3:0.041667 5:0.014394764 7:0.02632114 +1 1:0.740157 2:0.062992 3:0.055118 5:0.057012509 6:0.022944023 7:0.025110427 +1 1:0.719626 2:0.040498 3:0.056075 5:0.025613883 6:0.0025770026 7:0.02211078 +1 1:0.708861 2:0.068038 3:0.026899 4:0.011070111 5:0.029818258 6:0.039000039 7:0.019296079 +1 1:0.762763 2:0.018018 3:0.039039 5:0.024070789 7:0.017010915 +1 1:0.765138 2:0.016514 3:0.033028 5:0.019620414 7:0.017006043 +1 1:0.745763 2:0.026634 3:0.029056 4:0.0036900369 5:0.029676621 6:0.0071670072 7:0.018543671 +1 1:0.72973 2:0.023166 3:0.034749 5:0.012963488 7:0.013537055 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.741117 2:0.045685 3:0.040609 5:0.023742788 6:0.019107019 7:0.019437909 +1 1:0.778571 2:0.007143 3:0.021429 5:0.021730055 7:0.014939024 +1 1:0.722973 2:0.033784 3:0.060811 5:0.072726731 7:0.01689189 +1 1:0.792763 2:0.008224 3:0.023026 5:0.012724941 7:0.01762075 +1 1:0.741176 2:0.017647 3:0.044118 5:0.029579712 7:0.013558104 +1 1:0.713483 2:0.022472 3:0.061798 5:0.032129173 7:0.015894768 +1 1:0.742236 2:0.024845 3:0.040373 5:0.046591028 7:0.01514922 +1 1:0.748387 2:0.025806 3:0.032258 7:0.017466561 +1 1:0.795745 2:0.004255 3:0.031915 5:0.010063662 7:0.01922678 +1 1:0.743961 2:0.019324 3:0.033816 7:0.014964061 +1 1:0.721068 2:0.026706 3:0.04451 4:0.0036900369 5:0.05082522 7:0.015922415 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.781609 2:0.013793 3:0.029885 5:0.016422405 6:0.0044040044 7:0.019091671 +1 1:0.755102 2:0.034014 3:0.027211 5:0.037936278 6:0.015267015 7:0.01630164 +1 1:0.771242 2:0.019608 3:0.026144 5:0.018636411 7:0.015941335 +1 1:0.685567 2:0.048969 3:0.054124 5:0.066114532 7:0.014175256 +1 1:0.77551 2:0.020408 3:0.040816 5:0.03320263 7:0.018624524 +1 1:0.785714 2:0.011278 3:0.037594 5:0.024518062 7:0.020905921 +1 1:0.753994 2:0.022364 3:0.033546 5:0.023079331 6:0.011145011 7:0.015730927 +1 1:0.773109 2:0.004202 3:0.033613 5:0.012083849 7:0.015807543 +1 1:0.762887 2:0.020619 3:0.037801 5:0.019389322 7:0.016113488 +1 1:0.626984 2:0.15873 3:0.015873 4:0.0036900369 5:0.058085966 6:0.1012981 7:0.018631439 +1 1:0.71134 2:0.044674 3:0.072165 5:0.090580412 7:0.017244994 +1 1:0.765586 2:0.012469 3:0.032419 5:0.028342254 7:0.015996591 +1 1:0.767742 2:0.016129 3:0.03871 5:0.025472247 7:0.017269866 +1 1:0.75 2:0.023438 3:0.023438 5:0.024682063 7:0.014386433 +1 1:0.752577 2:0.005155 3:0.030928 5:0.015199857 7:0.015416774 +1 1:0.794118 2:0.019608 3:0.035948 5:0.0071862001 6:0.011571012 7:0.020663957 +1 1:0.774381 2:0.010189 3:0.032023 5:0.026896068 7:0.017218732 +1 1:0.741463 2:0.073171 3:0.02439 5:0.059442697 6:0.038277038 7:0.018649616 +1 1:0.78187 2:0.011331 3:0.042493 5:0.021118781 7:0.018292683 +1 1:0.73913 2:0.01087 3:0.054348 4:0.0036900369 5:0.033128084 7:0.014912512 +1 1:0.777778 2:0.01897 3:0.02981 5:0.020686416 6:0.0055500056 7:0.017863043 +1 1:0.741319 2:0.015625 3:0.032986 4:0.0036900369 5:0.046687937 7:0.015212146 +1 1:0.779412 2:0.006303 3:0.031513 5:0.0057623783 7:0.016576146 +1 1:0.748603 2:0.01676 3:0.03352 5:0.016944225 7:0.014988421 +1 1:0.771429 2:0.052381 3:0.028571 5:0.030265532 6:0.024357024 7:0.02145761 +1 1:0.774359 2:0.020513 3:0.025641 5:0.019478777 6:0.0052260052 7:0.01794872 8:0.023809524 +1 1:0.780488 2:0.027875 3:0.034843 5:0.030362441 6:0.0061110061 7:0.020863433 +1 1:0.740964 2:0.033133 3:0.054217 5:0.014774947 7:0.018531445 +1 1:0.742424 2:0.022727 3:0.030303 5:0.033239903 7:0.013811902 +1 1:0.763314 2:0.017751 3:0.035503 5:0.033962996 7:0.015839226 +1 1:0.749186 2:0.022801 3:0.035831 5:0.025792793 7:0.017220146 +1 1:0.742857 2:0.033333 3:0.047619 5:0.04937158 7:0.017537744 +1 1:0.746154 2:0.023077 3:0.038462 5:0.024048425 7:0.014540335 +1 1:0.786127 2:0.008671 3:0.031792 5:0.021439327 7:0.018380799 +1 1:0.763158 2:0.013158 3:0.118421 5:0.011345847 7:0.026355909 +1 1:0.787037 2:0.018519 3:0.037037 5:0.021156054 7:0.019892354 +1 1:0.74026 2:0.024531 3:0.030303 5:0.045286479 7:0.014482805 +1 1:0.771784 2:0.008299 3:0.049793 5:0.020425507 7:0.018469793 +1 1:0.743243 2:0.02027 3:0.033784 5:0.022937695 7:0.013389915 +1 1:0.742515 2:0.011976 3:0.071856 5:0.029117529 7:0.018694317 +1 1:0.758993 2:0.017986 3:0.043165 5:0.019642777 7:0.016647659 +1 1:0.767263 2:0.023018 3:0.033248 5:0.032725538 7:0.017762457 +1 1:0.778598 2:0.01845 3:0.04797 5:0.038786099 7:0.021622713 +1 1:0.722449 2:0.032653 3:0.069388 5:0.062819614 7:0.017720256 +1 1:0.762712 2:0.025424 3:0.072034 5:0.021238054 7:0.036275317 +1 1:0.654676 2:0.043165 3:0.079137 5:0.020820598 7:0.015704512 +1 1:0.748837 2:0.027907 3:0.05814 5:0.065197621 7:0.019455476 +1 1:0.753165 2:0.012658 3:0.031646 5:0.020477688 7:0.014047543 +1 1:0.765027 2:0.019126 3:0.032787 5:0.035394272 7:0.017542982 +1 1:0.770455 2:0.013636 3:0.029545 5:0.030399714 7:0.016990024 +1 1:0.774194 2:0.008065 3:0.032258 5:0.021118781 7:0.017358378 +1 1:0.730233 2:0.027907 3:0.032558 5:0.015997495 7:0.01321611 +1 1:0.792531 2:0.004149 3:0.029046 5:0.010712209 7:0.017609555 +1 1:0.772152 2:0.009042 3:0.027125 5:0.015751495 7:0.01565739 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.723926 2:0.018405 3:0.055215 5:0.060441608 7:0.013841091 +1 1:0.713483 2:0.022472 3:0.061798 5:0.032129173 7:0.015894768 +1 1:0.784416 2:0.01039 3:0.025974 5:0.020880235 7:0.016962305 +1 1:0.765896 2:0.013006 3:0.031792 5:0.028103708 7:0.016362963 +1 1:0.663265 2:0.071429 3:0.086735 5:0.067642718 6:0.032667033 7:0.01714161 +1 1:0.763736 2:0.016484 3:0.049451 5:0.040590103 7:0.018460195 +1 1:0.788732 2:0.007825 3:0.029734 5:0.014700401 7:0.019351884 +1 1:0.798883 2:0.005587 3:0.027933 5:0.014446946 7:0.017577329 +1 1:0.681818 2:0.025974 3:0.090909 5:0.05869724 7:0.015085524 +1 1:0.758303 2:0.02952 3:0.031365 5:0.047015938 7:0.019620195 8:0.023809524 +1 1:0.761111 2:0.022222 3:0.022222 4:0.0036900369 5:0.013574762 6:0.010929011 7:0.018597561 +1 1:0.775 2:0.016667 3:0.058333 5:0.017704591 7:0.021392274 +1 1:0.751037 2:0.020747 3:0.033195 5:0.034454997 7:0.016420402 +1 1:0.772059 2:0.014706 3:0.040441 5:0.029042983 7:0.017261476 +1 1:0.734824 2:0.030351 3:0.043131 5:0.032069536 6:0.0055320055 7:0.015847811 +1 1:0.799419 2:0.011628 3:0.023256 5:0.0070818362 7:0.018664921 +1 1:0.754464 2:0.022321 3:0.058036 5:0.040627376 7:0.019980402 +1 1:0.774194 2:0.008065 3:0.024194 5:0.023742788 7:0.015440598 +1 1:0.730088 2:0.035398 3:0.039823 5:0.049826309 6:0.004011004 7:0.020181311 +1 1:0.732558 2:0.02907 3:0.034884 5:0.052867771 7:0.014995744 +1 1:0.765027 2:0.019126 3:0.032787 5:0.035394272 7:0.017542982 +1 1:0.767606 2:0.028169 3:0.035211 5:0.015997495 7:0.020010305 +1 1:0.739241 2:0.040506 3:0.03038 5:0.01215094 6:0.012225012 7:0.01894103 +1 1:0.753247 2:0.019481 3:0.058442 5:0.015028402 7:0.019638896 +1 1:0.74569 2:0.025862 3:0.034483 5:0.021610782 7:0.018134988 +1 1:0.742547 2:0.059621 3:0.0271 5:0.048588851 6:0.027933028 7:0.017747372 +1 1:0.725694 2:0.024306 3:0.041667 5:0.010801664 7:0.014608738 +1 1:0.756757 2:0.027027 3:0.040541 5:0.023630969 7:0.017331354 +1 1:0.736486 2:0.033784 3:0.054054 5:0.0323379 6:0.013014013 7:0.018993079 +1 1:0.778281 2:0.00905 3:0.040724 5:0.021148599 7:0.019451494 +1 1:0.670683 2:0.02008 3:0.052209 5:0.041350469 7:0.015452055 +1 1:0.76087 2:0.016304 3:0.048913 5:0.041648651 7:0.017795598 +1 1:0.782353 2:0.011765 3:0.029412 5:0.029937531 7:0.017862268 8:0.023809524 +1 1:0.71097 2:0.067511 3:0.044304 5:0.080039658 6:0.021474021 7:0.017971079 +1 1:0.751479 2:0.011834 3:0.12426 5:0.010570572 7:0.025436567 +1 1:0.734104 2:0.017341 3:0.028902 5:0.051525949 7:0.015296774 +1 1:0.724265 2:0.058824 3:0.033088 5:0.049498308 6:0.027888028 7:0.016880378 +1 1:0.791667 2:0.010417 3:0.028274 5:0.017361681 6:0.0013980014 7:0.019481348 +1 1:0.763407 2:0.012618 3:0.063091 5:0.0070892908 7:0.020235439 +1 1:0.784431 2:0.011976 3:0.02994 5:0.015430948 7:0.017635457 +1 1:0.768707 2:0.013605 3:0.027211 5:0.018494774 7:0.016716445 +1 1:0.694656 2:0.015267 3:0.083969 5:0.04809685 7:0.014429341 +1 1:0.785401 2:0.016058 3:0.026277 5:0.022154965 6:0.0044580045 7:0.017972226 +1 1:0.726316 2:0.036842 3:0.036842 5:0.047783758 7:0.015019256 +1 1:0.785124 2:0.016529 3:0.107438 5:0.0053076499 7:0.070802256 +1 1:0.711765 2:0.035294 3:0.058824 5:0.035416636 7:0.015100427 +1 1:0.722222 2:0.030864 3:0.04321 5:0.038525189 7:0.014566396 +1 1:0.717742 2:0.112903 3:0.024194 5:0.062640705 6:0.037815038 7:0.023406768 +1 1:0.753467 2:0.01849 3:0.026194 5:0.014394764 7:0.014600323 +1 1:0.741935 2:0.028226 3:0.052419 5:0.032181355 7:0.017087921 +1 1:0.781942 2:0.010221 3:0.037479 5:0.0040925559 7:0.018905555 +1 1:0.755294 2:0.014118 3:0.035294 5:0.04372102 7:0.014677189 +1 1:0.448476 2:0.08418 3:0.169811 4:0.011070111 5:0.16875643 7:0.020328152 +1 1:0.631902 2:0.030675 3:0.079755 5:0.030869351 7:0.018068232 +1 1:0.725962 2:0.057692 3:0.081731 5:0.019903687 6:0.0026700027 7:0.06587125 +1 1:0.77551 2:0.010204 3:0.022959 5:0.022318966 6:0.002994003 7:0.015586116 +1 1:0.725352 2:0.028169 3:0.049296 5:0.018919685 7:0.016918585 +1 1:0.722222 2:0.050505 3:0.050505 5:0.079786203 6:0.0045870046 7:0.020140427 8:0.023809524 +1 1:0.715686 2:0.026961 3:0.034314 5:0.024204971 6:0.0032460032 7:0.013809183 +1 1:0.769231 2:0.024725 3:0.06044 4:0.0036900369 5:0.042215198 7:0.020704902 +1 1:0.737179 2:0.019231 3:0.044872 5:0.015527858 7:0.018761726 +1 1:0.739247 2:0.026882 3:0.040323 5:0.031823536 7:0.01535864 +1 1:0.725714 2:0.028571 3:0.051429 5:0.070743816 7:0.014686409 +1 1:0.708333 2:0.025 3:0.05 5:0.083446394 7:0.013617884 +1 1:0.755556 2:0.02963 3:0.022222 5:0.010712209 7:0.015718159 +1 1:0.772908 2:0.021912 3:0.031873 5:0.035863909 6:0.0082470082 7:0.017673207 +1 1:0.812081 2:0.013423 3:0.026846 7:0.02271239 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.737349 2:0.045783 3:0.036145 5:0.05758651 6:0.015450015 7:0.01711725 +1 1:0.755556 2:0.014815 3:0.007407 5:0.02070878 7:0.016260165 +1 1:0.768271 2:0.01426 3:0.039216 5:0.032390082 7:0.01751011 +1 1:0.786127 2:0.011561 3:0.046243 5:0.023183695 7:0.022663189 +1 1:0.749469 2:0.036093 3:0.03397 5:0.03877119 6:0.0066870067 7:0.017425299 +1 1:0.774411 2:0.023569 3:0.050505 5:0.029862985 7:0.025622073 +1 1:0.718954 2:0.058824 3:0.039216 5:0.019068776 6:0.030690031 7:0.015582659 +1 1:0.765625 2:0.023438 3:0.03125 5:0.021797146 6:0.0087720088 7:0.016291921 +1 1:0.703704 2:0.051852 3:0.081481 5:0.108121 6:0.0022890023 7:0.019722976 +1 1:0.73031 2:0.031026 3:0.064439 4:0.0036900369 5:0.037429368 6:0.0025110025 7:0.017390421 +1 1:0.72449 2:0.017007 3:0.054422 5:0.037802096 7:0.02044964 +1 1:0.744361 2:0.037594 3:0.022556 5:0.020649143 6:0.024930025 7:0.016550524 +1 1:0.769663 2:0.033708 3:0.05618 6:0.013215013 7:0.023328311 +1 1:0.756906 2:0.005525 3:0.038674 5:0.017138044 7:0.01465436 +1 1:0.737548 2:0.028736 3:0.038314 5:0.048648487 7:0.016108305 +1 1:0.730667 2:0.037333 3:0.018667 5:0.01856932 6:0.011208011 7:0.013056909 +1 1:0.816 2:0.008 3:0.024 7:0.01995122 +1 1:0.703947 2:0.019737 3:0.092105 5:0.052994499 7:0.016928756 +1 1:0.748201 2:0.021583 3:0.014388 7:0.012853134 +1 1:0.761628 2:0.013566 3:0.025194 5:0.023832242 7:0.014783043 +1 1:0.778947 2:0.008421 3:0.037895 5:0.022035692 7:0.017368421 +1 1:0.753927 2:0.015707 3:0.073298 5:0.020820598 7:0.022857872 +1 1:0.789634 2:0.006098 3:0.033537 5:0.016139132 7:0.017177274 +1 1:0.760377 2:0.016981 3:0.032075 5:0.027939707 7:0.015347445 +1 1:0.732558 2:0.017442 3:0.046512 5:0.027477524 7:0.01442853 +1 1:0.759591 2:0.015345 3:0.030691 5:0.03380645 7:0.013754598 +1 1:0.724551 2:0.023952 3:0.041916 5:0.051294858 7:0.015919378 +1 1:0.755365 2:0.021459 3:0.034335 5:0.012553486 7:0.015544854 +1 1:0.792683 2:0.006098 3:0.033537 5:0.015430948 7:0.017958061 +1 1:0.752427 2:0.024272 3:0.063107 5:0.034618997 7:0.019121476 +1 1:0.762215 2:0.013029 3:0.035831 5:0.036721184 7:0.01612775 +1 1:0.753623 2:0.019324 3:0.033816 5:0.025397701 7:0.017291152 +1 1:0.785124 2:0.016529 3:0.107438 5:0.0053076499 7:0.070802256 +1 1:0.727273 2:0.036364 3:0.060606 5:0.031927899 7:0.017257945 +1 1:0.793313 2:0.00304 3:0.027356 5:0.0077303833 7:0.017866409 +1 1:0.745583 2:0.024735 3:0.031802 5:0.030056804 7:0.016030335 +1 1:0.699115 2:0.026549 3:0.066372 5:0.057698329 7:0.017429311 +1 1:0.791045 2:0.011194 3:0.022388 5:0.0089380228 7:0.018975244 +1 1:0.763949 2:0.034335 3:0.04721 5:0.019903687 6:0.016020016 7:0.019601171 +1 1:0.749254 2:0.038806 3:0.020896 5:0.033880995 6:0.01022701 7:0.016017476 +1 1:0.738095 2:0.02381 3:0.029101 5:0.020291324 6:0.0054450054 7:0.017776488 +1 1:0.753968 2:0.02381 3:0.071429 5:0.05237577 7:0.020663957 +1 1:0.75 2:0.024194 3:0.040323 5:0.04732903 7:0.015489774 +1 1:0.764368 2:0.005747 3:0.057471 5:0.014998584 7:0.017416598 +1 1:0.757895 2:0.017544 3:0.024561 5:0.010399117 7:0.015340183 +1 1:0.769802 2:0.007426 3:0.024752 5:0.014528946 7:0.01548539 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.764957 2:0.012821 3:0.038462 5:0.035610454 7:0.016364396 +1 1:0.736041 2:0.025381 3:0.045685 5:0.014879311 7:0.015506994 +1 1:0.721311 2:0.077283 3:0.023419 5:0.03132408 6:0.052941053 7:0.016993201 +1 1:0.756522 2:0.015942 3:0.037681 5:0.0074471099 7:0.017700604 +1 1:0.756757 2:0.003861 3:0.050193 7:0.015373384 +1 1:0.753927 2:0.018325 3:0.044503 5:0.040150284 7:0.01778189 +1 1:0.8 2:0.006452 3:0.012903 7:0.018135329 +1 1:0.776667 2:0.013333 3:0.023333 5:0.018517138 7:0.016361787 +1 1:0.734403 2:0.033868 3:0.02852 5:0.042968109 7:0.015086299 +1 1:0.775 2:0.0125 3:0.034375 5:0.024361517 7:0.017492378 +1 1:0.805447 2:0.003891 3:0.035019 5:0.0090796595 7:0.019478976 +1 1:0.754717 2:0.012579 3:0.050314 5:0.034119541 7:0.016758707 +1 1:0.742331 2:0.018405 3:0.08589 7:0.020612 +1 1:0.781609 2:0.011494 3:0.045977 5:0.026769341 7:0.019519201 +1 1:0.776471 2:0.011765 3:0.023529 7:0.015243902 +1 1:0.773585 2:0.014151 3:0.014151 6:0.0054150054 7:0.015934195 +1 1:0.740032 2:0.028708 3:0.047847 5:0.039233373 7:0.018477457 +1 1:0.743902 2:0.018293 3:0.060976 5:0.016564042 7:0.01673111 +1 1:0.734756 2:0.027439 3:0.073171 5:0.063893072 7:0.019519634 +1 1:0.717277 2:0.031414 3:0.010471 5:0.044198113 6:0.011859012 7:0.01615375 +1 1:0.776573 2:0.013015 3:0.045553 5:0.025233701 7:0.019536006 +1 1:0.740741 2:0.061728 3:0.020576 5:0.010018935 6:0.04032304 7:0.018669073 +1 1:0.769841 2:0.027778 3:0.039683 5:0.02781298 7:0.019454122 +1 1:0.77027 2:0.016892 3:0.035473 5:0.025971702 7:0.017736488 +1 1:0.744966 2:0.020134 3:0.04698 5:0.040075738 7:0.015223439 +1 1:0.751196 2:0.019139 3:0.057416 5:0.023630969 7:0.018409384 +1 1:0.750751 2:0.027027 3:0.024024 5:0.026500977 7:0.015454476 +1 1:0.764505 2:0.013652 3:0.054608 5:0.025733156 7:0.018084573 +1 1:0.8 2:0.007407 3:0.022222 7:0.019692866 +1 1:0.77541 2:0.018033 3:0.036066 5:0.027872616 7:0.018712512 +1 1:0.741758 2:0.027473 3:0.043956 5:0.030615896 7:0.016316 +1 1:0.646409 2:0.088398 3:0.066298 5:0.12889687 6:0.0086460086 7:0.023379598 +1 1:0.781609 2:0.011494 3:0.02682 5:0.010324572 7:0.016867585 +1 1:0.765957 2:0.007092 3:0.035461 5:0.022386057 7:0.014400622 +1 1:0.78836 2:0.007937 3:0.039683 5:0.019277504 7:0.018712091 +1 1:0.805556 2:0.006944 3:0.034722 5:0.01566204 7:0.020155829 +1 1:0.779255 2:0.007979 3:0.031915 5:0.023101695 7:0.015697976 +1 1:0.770718 2:0.016575 3:0.033149 5:0.021774783 7:0.017298884 +1 1:0.725664 2:0.026549 3:0.039823 5:0.026314612 7:0.015284372 +1 1:0.778689 2:0.008197 3:0.028689 5:0.023079331 7:0.016143543 +1 1:0.724551 2:0.023952 3:0.041916 5:0.051294858 7:0.015919378 +1 1:0.792049 2:0.009174 3:0.025994 4:0.011070111 5:0.019165685 7:0.018134183 +1 1:0.742009 2:0.025114 3:0.03653 5:0.034805361 7:0.014909787 +1 1:0.747126 2:0.051724 3:0.034483 5:0.011345847 6:0.012177012 7:0.034535323 +1 1:0.710407 2:0.045249 3:0.063348 5:0.08352094 7:0.019699811 +1 1:0.761317 2:0.012346 3:0.041152 7:0.017414433 +1 1:0.682028 2:0.087558 3:0.046083 5:0.059353242 6:0.038217038 7:0.017646396 +1 1:0.785331 2:0.0161 3:0.037567 5:0.025285883 7:0.01929622 +1 1:0.757225 2:0.014451 3:0.034682 5:0.026500977 7:0.014873817 +1 1:0.72 2:0.073333 3:0.04 5:0.085295126 6:0.027459027 7:0.017764226 +1 1:0.728571 2:0.039286 3:0.039286 5:0.037913915 6:0.0091560092 7:0.021406793 +1 1:0.774448 2:0.007886 3:0.029968 5:0.021744964 7:0.016484573 +1 1:0.770627 2:0.021452 3:0.039604 5:0.023556424 6:0.0047400047 7:0.019107701 +1 1:0.739837 2:0.03252 3:0.03252 5:0.04920758 7:0.015020823 +1 1:0.712544 2:0.04007 3:0.076655 5:0.092958418 7:0.017889012 +1 1:0.731707 2:0.034146 3:0.043902 5:0.039650828 6:0.0053190053 7:0.016775732 +1 1:0.783105 2:0.018265 3:0.03653 5:0.024696972 7:0.021007348 +1 1:0.693122 2:0.026455 3:0.126984 5:0.032084445 7:0.022486774 +1 1:0.781955 2:0.022556 3:0.045113 5:0.033128084 7:0.020630848 +1 1:0.756228 2:0.024911 3:0.039146 5:0.035729727 7:0.018108238 +1 1:0.739496 2:0.053221 3:0.033613 5:0.051563222 6:0.011859012 7:0.017284963 +1 1:0.801471 2:0.007353 3:0.051471 5:0.013984763 7:0.023897061 +1 1:0.767647 2:0.011765 3:0.044118 5:0.01232985 7:0.021682207 +1 1:0.785714 2:0.011278 3:0.037594 5:0.024518062 7:0.020905921 +1 1:0.778075 2:0.008021 3:0.024064 5:0.023519151 7:0.015504762 +1 1:0.743902 2:0.03252 3:0.03252 5:0.025352974 6:0.02040902 7:0.014574659 +1 1:0.77176 2:0.011605 3:0.038685 5:0.020440416 7:0.017207622 +1 1:0.729592 2:0.066327 3:0.020408 5:0.029177165 6:0.046968047 7:0.015897213 +1 1:0.720621 2:0.028825 3:0.064302 5:0.068179446 7:0.01773836 +1 1:0.741667 2:0.025 3:0.041667 5:0.04398193 7:0.01722561 +1 1:0.74114 2:0.030817 3:0.032357 5:0.037064094 6:0.0018660019 7:0.015117067 +1 1:0.735099 2:0.022075 3:0.046358 5:0.027432797 7:0.014631457 +1 1:0.756579 2:0.013158 3:0.026316 5:0.021118781 7:0.01416078 +1 1:0.790055 2:0.01105 3:0.049724 5:0.012344759 7:0.020347665 +1 1:0.752608 2:0.014903 3:0.031297 5:0.035103544 7:0.01543928 +1 1:0.760062 2:0.020124 3:0.043344 5:0.044615568 7:0.017348787 +1 1:0.790087 2:0.008746 3:0.023324 5:0.0072160184 7:0.018363793 +1 1:0.738602 2:0.030395 3:0.048632 5:0.048514305 7:0.017088 +1 1:0.797468 2:0.006329 3:0.056962 5:0.012143485 7:0.023695585 +1 1:0.733333 2:0.046667 3:0.04 5:0.019262594 6:0.031008031 7:0.015731707 +1 1:0.762987 2:0.022727 3:0.027597 5:0.022728967 6:0.0054870055 7:0.016233768 +1 1:0.729814 2:0.040373 3:0.02795 5:0.035245181 6:0.014184014 7:0.016020299 +1 1:0.685484 2:0.040323 3:0.064516 5:0.055215959 7:0.013276945 +1 1:0.758958 2:0.016287 3:0.058632 5:0.031353898 7:0.018888537 +1 1:0.722628 2:0.029197 3:0.087591 5:0.053918865 7:0.02461278 +1 1:0.76461 2:0.019481 3:0.035714 5:0.020567143 7:0.017936329 +1 1:0.761421 2:0.025381 3:0.06599 5:0.031234625 7:0.022161695 +1 1:0.75 2:0.021429 3:0.035714 5:0.020477688 7:0.015853659 +1 1:0.791667 2:0.008333 3:0.066667 5:0.014335127 7:0.026422762 +1 1:0.712575 2:0.077844 3:0.05988 5:0.070594725 6:0.034092034 7:0.019278518 +1 1:0.779874 2:0.037736 3:0.031447 5:0.026113339 6:0.010509011 7:0.02189753 +1 1:0.755034 2:0.018456 3:0.026846 5:0.039367555 6:0.003960004 7:0.015499671 +1 1:0.755906 2:0.023622 3:0.03937 5:0.042118289 7:0.016996354 +1 1:0.74613 2:0.037152 3:0.03096 5:0.02627734 6:0.021153021 7:0.016065091 +1 1:0.700273 2:0.059946 3:0.040872 5:0.020537325 6:0.03030303 7:0.018093311 +1 1:0.722222 2:0.038889 3:0.05 5:0.048939215 7:0.01548103 +1 1:0.74359 2:0.02849 3:0.039886 5:0.038666826 6:0.0031110031 7:0.016746579 +1 1:0.724138 2:0.028736 3:0.028736 5:0.020425507 7:0.01279086 +1 1:0.677852 2:0.09396 3:0.026846 5:0.073442369 6:0.044334044 7:0.016614829 +1 1:0.758025 2:0.022222 3:0.034568 6:0.013488013 7:0.016741945 +1 1:0.778378 2:0.010811 3:0.027027 5:0.014819674 7:0.016578774 +1 1:0.756966 2:0.020124 3:0.024768 5:0.004569648 7:0.015385488 8:0.047619048 +1 1:0.761092 2:0.017065 3:0.046075 5:0.0179655 7:0.017272951 +1 1:0.766292 2:0.026966 3:0.038202 5:0.033478449 6:0.0022470022 7:0.018306384 +1 1:0.824818 2:0.007299 3:0.051095 5:0.011539666 7:0.028752006 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.741758 2:0.013736 3:0.024725 5:0.028476436 7:0.017538866 +1 1:0.762295 2:0.008197 3:0.020492 5:0.024361517 7:0.015293884 +1 1:0.757576 2:0.022727 3:0.018939 5:0.03499918 6:0.0093900094 7:0.014758872 +1 1:0.630303 2:0.012121 3:0.048485 5:0.021543691 7:0.025572799 +1 1:0.8 2:0.010667 3:0.034667 5:0.017428772 7:0.020861787 +1 1:0.76087 2:0.007246 3:0.021739 5:0.023668242 7:0.013918348 +1 1:0.755725 2:0.053435 3:0.038168 5:0.050027582 6:0.013422013 7:0.020806183 +1 1:0.752174 2:0.021739 3:0.030435 5:0.034454997 7:0.017205726 +1 1:0.736842 2:0.026316 3:0.047368 4:0.0036900369 5:0.045733753 7:0.015693195 +1 1:0.753333 2:0.03 3:0.043333 5:0.016221132 6:0.0097920098 7:0.01867886 +1 1:0.70566 2:0.018868 3:0.056604 5:0.025099518 7:0.013667738 +1 1:0.763158 2:0.022556 3:0.06391 5:0.030742624 7:0.022235463 +1 1:0.728972 2:0.042056 3:0.037383 5:0.053821955 7:0.015785274 +1 1:0.752137 2:0.022792 3:0.039886 5:0.0079987476 6:0.0064380064 7:0.016190677 +1 1:0.693215 2:0.041298 3:0.073746 5:0.042744472 6:0.020643021 7:0.015684579 +1 1:0.782258 2:0.032258 3:0.016129 5:0.019210413 6:0.015465015 7:0.019079463 +1 1:0.790281 2:0.007673 3:0.038363 5:0.018032591 7:0.01933753 +1 1:0.756522 2:0.015942 3:0.037681 5:0.0074471099 7:0.017700604 +1 1:0.724265 2:0.058824 3:0.033088 5:0.049498308 6:0.027888028 7:0.016880378 +1 1:0.716049 2:0.037037 3:0.061728 5:0.05647578 7:0.016561274 +1 1:0.781095 2:0.014925 3:0.039801 5:0.031719172 6:0.0015960016 7:0.01901064 +1 1:0.754286 2:0.017143 3:0.04 5:0.03320263 7:0.015644598 +1 1:0.728571 2:0.052381 3:0.1 5:0.026635159 6:0.0030630031 7:0.05688153 +1 1:0.764151 2:0.017296 3:0.028302 5:0.026433885 7:0.016221811 +1 1:0.77208 2:0.019943 3:0.034188 5:0.020090051 7:0.019335 +1 1:0.696 2:0.104 3:0.016 4:0.0036900369 5:0.053247954 6:0.064287064 7:0.020487805 +1 1:0.778502 2:0.013029 3:0.019544 7:0.015154524 +1 1:0.730159 2:0.027778 3:0.039683 5:0.024972791 7:0.014445415 +1 1:0.759184 2:0.02449 3:0.061224 5:0.025792793 7:0.021577896 +1 1:0.764877 2:0.020319 3:0.030479 5:0.027134615 7:0.017018305 +1 1:0.792683 2:0.018293 3:0.054878 5:0.03362754 7:0.024724866 +1 1:0.730496 2:0.007092 3:0.06383 4:0.0036900369 5:0.022117693 7:0.014573604 +1 1:0.751196 2:0.019139 3:0.057416 5:0.023630969 7:0.018409384 +1 1:0.70303 2:0.030303 3:0.060606 5:0.041186468 7:0.013377677 +1 1:0.744417 2:0.032258 3:0.039702 5:0.049699581 7:0.018156512 +1 1:0.73 2:0.036667 3:0.043333 5:0.067948355 6:0.0078120078 7:0.015609756 +1 1:0.731707 2:0.036585 3:0.029268 5:0.029065347 7:0.015258774 +1 1:0.795775 2:0.007042 3:0.133803 7:0.099579183 +1 1:0.752475 2:0.009901 3:0.039604 5:0.0077974744 7:0.014428884 +1 1:0.765138 2:0.011009 3:0.034862 5:0.015624767 7:0.016010293 +1 1:0.755245 2:0.01049 3:0.052448 5:0.019829141 7:0.01603275 +1 1:0.77 2:0.02 3:0.035 5:0.025181519 7:0.01804878 +1 1:0.740741 2:0.030864 3:0.049383 5:0.062513977 7:0.017953927 +1 1:0.768657 2:0.014925 3:0.029851 5:0.019829141 7:0.017109573 +1 1:0.773885 2:0.009554 3:0.035032 5:0.026843887 7:0.016176012 +1 1:0.77305 2:0.010638 3:0.024823 5:0.022490421 7:0.014335756 +1 1:0.764992 2:0.019449 3:0.035656 5:0.020291324 6:0.0048990049 7:0.018154323 +1 1:0.769231 2:0.004525 3:0.031674 5:0.014394764 7:0.014292018 +1 1:0.746412 2:0.019139 3:0.047847 5:0.028454072 7:0.015287665 +1 1:0.73494 2:0.012048 3:0.084337 5:0.029288984 7:0.018696738 +1 1:0.757669 2:0.027607 3:0.018405 5:0.018136955 6:0.0072990073 7:0.015374829 +1 1:0.765027 2:0.013661 3:0.054645 5:0.032785174 7:0.018942421 +1 1:0.773852 2:0.010601 3:0.014134 5:0.011487484 7:0.013983451 +1 1:0.780105 2:0.015707 3:0.031414 7:0.01832461 +1 1:0.748252 2:0.027972 3:0.062937 5:0.05237577 7:0.018207402 +1 1:0.81383 2:0.015957 3:0.047872 5:0.016191314 7:0.029871561 +1 1:0.691824 2:0.113208 3:0.018868 5:0.032621174 6:0.078774079 7:0.017525695 +1 1:0.746082 2:0.018809 3:0.062696 5:0.041141741 7:0.017317835 +1 1:0.738956 2:0.040161 3:0.040161 5:0.042535745 6:0.012840013 7:0.017166226 +1 1:0.786517 2:0.01573 3:0.033708 5:0.019933505 7:0.020498768 +1 1:0.763066 2:0.02439 3:0.059233 5:0.042073562 7:0.022584348 +1 1:0.797386 2:0.013072 3:0.039216 5:0.013574762 7:0.021879482 +1 1:0.775 2:0.025 3:0.1 5:0.012993306 7:0.087449183 +1 1:0.73913 2:0.012422 3:0.043478 5:0.01762259 7:0.016020299 +1 1:0.721154 2:0.024038 3:0.048077 5:0.016034768 7:0.013631567 +1 1:0.729508 2:0.057377 3:0.02459 5:0.066360533 6:0.026706027 7:0.016843262 +1 1:0.748344 2:0.006623 3:0.059603 5:0.016824952 7:0.017888872 +1 1:0.726891 2:0.033613 3:0.037815 5:0.054217047 7:0.014091 +1 1:0.757143 2:0.021429 3:0.039286 5:0.029080256 7:0.016746512 +1 1:0.739394 2:0.054545 3:0.066667 5:0.057698329 6:0.0046440046 7:0.023872878 +1 1:0.792453 2:0.012579 3:0.040881 5:0.012083849 6:0.0024300024 7:0.023661604 +1 1:0.793241 2:0.00994 3:0.04175 5:0.013366034 7:0.020280756 +1 1:0.746193 2:0.030457 3:0.040609 5:0.039375009 7:0.017580787 +1 1:0.75 2:0.01087 3:0.070652 7:0.018657213 +1 1:0.750725 2:0.04058 3:0.049275 5:0.033396449 6:0.0053760054 7:0.019724287 +1 1:0.808163 2:0.008163 3:0.028571 5:0.0088932954 7:0.020856146 +1 1:0.748344 2:0.013245 3:0.039735 5:0.036810639 7:0.016354384 +1 1:0.757447 2:0.017021 3:0.025532 7:0.014686043 +1 1:0.763819 2:0.005025 3:0.035176 5:0.013552398 7:0.016852555 +1 1:0.704301 2:0.039427 3:0.073477 5:0.10747246 7:0.016675409 +1 1:0.646809 2:0.025532 3:0.07234 5:0.042677381 7:0.013596262 +1 1:0.770492 2:0.010929 3:0.038251 5:0.031584989 7:0.015727043 +1 1:0.763043 2:0.021739 3:0.036957 5:0.035438999 7:0.016728524 +1 1:0.575342 2:0.123288 3:0.034247 5:0.15945313 6:0.048129048 7:0.01561978 +1 1:0.736041 2:0.025381 3:0.045685 5:0.014879311 7:0.015506994 +1 1:0.753247 2:0.021645 3:0.021645 5:0.01326167 7:0.014834756 +1 1:0.727419 2:0.020968 3:0.066129 5:0.048149032 7:0.018273012 +1 1:0.783186 2:0.013274 3:0.044248 5:0.030973715 7:0.019479817 +1 1:0.741627 2:0.023923 3:0.059809 5:0.037116276 6:0.0024900025 7:0.017577896 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.750693 2:0.030471 3:0.049861 5:0.05296468 7:0.019018988 +1 1:0.708738 2:0.067961 3:0.029126 5:0.025613883 6:0.048111048 7:0.017227091 +1 1:0.747082 2:0.023346 3:0.031128 5:0.038823372 7:0.018221506 +1 1:0.760784 2:0.027451 3:0.035294 5:0.019135867 7:0.018627451 +1 1:0.760417 2:0.020833 3:0.038194 5:0.038376098 7:0.016450713 +1 1:0.747899 2:0.048319 3:0.039916 5:0.095634607 6:0.0038490038 7:0.019970793 8:0.023809524 +1 1:0.784466 2:0.013592 3:0.060194 5:0.028513709 7:0.021667061 +1 1:0.773784 2:0.014799 3:0.02537 5:0.011882576 7:0.016178518 +1 1:0.804487 2:0.00641 3:0.032051 5:0.014200945 7:0.02052064 +1 1:0.682081 2:0.057803 3:0.052023 5:0.082984211 7:0.018997604 +1 1:0.769022 2:0.01087 3:0.035326 5:0.022386057 7:0.01655289 +1 1:0.805556 2:0.013889 3:0.020833 7:0.020494579 +1 1:0.728916 2:0.058233 3:0.040161 5:0.031510444 6:0.023550024 7:0.020276226 +1 1:0.792049 2:0.009174 3:0.039755 5:0.014491673 7:0.019187738 +1 1:0.74569 2:0.064655 3:0.025862 5:0.0284168 6:0.038118038 7:0.020684396 +1 1:0.780488 2:0.02439 3:0.04065 5:0.0179655 7:0.020573073 +1 1:0.747525 2:0.024752 3:0.029703 6:0.0062250062 7:0.014549628 +1 1:0.813008 2:0.00813 3:0.056911 5:0.014446946 7:0.025580012 +1 1:0.781457 2:0.006623 3:0.02649 5:0.019672596 7:0.015304476 +1 1:0.544715 2:0.097561 3:0.105691 5:0.16205478 7:0.0205235 +1 1:0.710407 2:0.045249 3:0.063348 5:0.08352094 7:0.019699811 +1 1:0.762222 2:0.031111 3:0.04 5:0.042058653 6:0.0021150021 7:0.019214091 +1 1:0.74359 2:0.041026 3:0.05641 5:0.053456682 6:0.0047820048 7:0.01962164 +1 1:0.744589 2:0.008658 3:0.034632 5:0.02934862 7:0.013409354 +1 1:0.739326 2:0.031461 3:0.017978 5:0.029490257 7:0.01385311 +1 1:0.797834 2:0.00361 3:0.075812 7:0.035550762 +1 1:0.708955 2:0.089552 3:0.044776 5:0.016385133 6:0.059340059 7:0.020704402 +1 1:0.765027 2:0.005464 3:0.060109 7:0.018059445 +1 1:0.806701 2:0.020619 3:0.025773 5:0.010771846 6:0.0086700087 7:0.021750061 +1 1:0.718412 2:0.018051 3:0.028881 5:0.05092213 7:0.016113409 +1 1:0.753535 2:0.018182 3:0.034343 5:0.016124223 7:0.017085488 +1 1:0.772834 2:0.018735 3:0.044496 5:0.036259001 7:0.020548921 +1 1:0.757764 2:0.012422 3:0.049689 5:0.030302804 7:0.018633543 +1 1:0.768116 2:0.023188 3:0.028986 5:0.015945313 6:0.0064170064 7:0.016525274 +1 1:0.708333 2:0.016667 3:0.141667 5:0.03663173 7:0.020680896 +1 1:0.778761 2:0.013274 3:0.036873 5:0.017316953 7:0.019353909 +1 1:0.765668 2:0.019074 3:0.032698 5:0.028640437 7:0.017295805 +1 1:0.757225 2:0.023121 3:0.034682 5:0.030869351 7:0.017023829 +1 1:0.759878 2:0.039514 3:0.021277 5:0.016116768 6:0.019458019 7:0.017143598 +1 1:0.755556 2:0.02963 3:0.022222 7:0.015808488 +1 1:0.710938 2:0.039062 3:0.054688 5:0.048723033 7:0.014576982 +1 1:0.732558 2:0.023256 3:0.02907 5:0.032621174 7:0.016201079 +1 1:0.703488 2:0.011628 3:0.075581 5:0.017667318 7:0.014960293 +1 1:0.780488 2:0.00813 3:0.02439 5:0.021730055 7:0.017003768 +1 1:0.716263 2:0.034602 3:0.044983 5:0.022796058 7:0.013798634 +1 1:0.780161 2:0.010724 3:0.029491 5:0.02018696 7:0.01811286 +1 1:0.785311 2:0.022599 3:0.045198 6:0.0084750085 7:0.024390244 +1 1:0.69863 2:0.013699 3:0.089041 5:0.041186468 7:0.01511861 +1 1:0.761538 2:0.023077 3:0.023077 5:0.024764063 6:0.00996601 7:0.014118201 +1 1:0.763077 2:0.024615 3:0.061538 5:0.04184247 7:0.020056287 +1 1:0.722513 2:0.026178 3:0.04712 5:0.055320323 6:0.011133011 7:0.017207256 +1 1:0.766667 2:0.016667 3:0.033333 5:0.025017518 7:0.015142274 +1 1:0.778196 2:0.018797 3:0.037594 5:0.026814068 7:0.019117915 +1 1:0.509434 2:0.251572 3:0.053459 5:0.054477957 6:0.1973192 7:0.015742445 +1 1:0.768683 2:0.014235 3:0.02847 5:0.019441504 7:0.016643518 +1 1:0.74934 2:0.015831 3:0.065963 5:0.019650232 7:0.018308774 +1 1:0.777778 2:0.031746 3:0.026455 5:0.024972791 6:0.01005001 7:0.019260549 +1 1:0.656 2:0.048 3:0.08 5:0.10649591 7:0.013658537 +1 1:0.78481 2:0.018987 3:0.018987 5:0.014417128 6:0.0058020058 7:0.019952146 +1 1:0.770781 2:0.007557 3:0.042821 5:0.019463868 7:0.017647604 +1 1:0.741433 2:0.018692 3:0.034268 5:0.028968437 6:0.0038850039 7:0.014664537 +1 1:0.74359 2:0.025641 3:0.05641 5:0.013149852 7:0.017729829 +1 1:0.756487 2:0.021956 3:0.031936 5:0.020254052 6:0.002037002 7:0.01791539 +1 1:0.737307 2:0.037528 3:0.055188 4:0.0036900369 5:0.02660534 6:0.017130017 7:0.018858018 +1 1:0.773554 2:0.006612 3:0.036364 5:0.013835672 7:0.016287037 +1 1:0.738095 2:0.02381 3:0.042857 7:0.0141115 +1 1:0.773519 2:0.010453 3:0.020906 5:0.018494774 7:0.017124159 +1 1:0.780877 2:0.007968 3:0.027888 5:0.011174392 7:0.016203482 +1 1:0.752747 2:0.032967 3:0.032967 5:0.02900571 7:0.017220585 +1 1:0.763587 2:0.024457 3:0.046196 5:0.02480879 6:0.0074880075 7:0.019916488 +1 1:0.758755 2:0.033074 3:0.033074 4:0.0036900369 5:0.031473171 6:0.0079170079 7:0.022480305 +1 1:0.702128 2:0.037234 3:0.069149 4:0.0036900369 5:0.067612899 6:0.013605014 7:0.014303323 +1 1:0.774799 2:0.016086 3:0.040214 5:0.027060069 6:0.0027210027 7:0.01801478 +1 1:0.73913 2:0.033597 3:0.021739 5:0.024145334 7:0.014882384 +1 1:0.774648 2:0.014085 3:0.03662 5:0.020999508 7:0.018292683 +1 1:0.76699 2:0.05178 3:0.02589 5:0.036900094 6:0.023763024 7:0.019930537 +1 1:0.75 2:0.018692 3:0.03972 5:0.026985523 7:0.015742537 +1 1:0.747312 2:0.026882 3:0.032258 5:0.034805361 7:0.017555073 +1 1:0.714286 2:0.032468 3:0.090909 5:0.074992918 7:0.019678494 +1 1:0.791139 2:0.031646 3:0.031646 5:0.013530034 6:0.016335016 7:0.02126428 +1 1:0.766323 2:0.015464 3:0.030928 5:0.019031503 7:0.016417317 +1 1:0.755102 2:0.015306 3:0.022959 5:0.026307158 7:0.01322175 +1 1:0.762763 2:0.012012 3:0.042042 5:0.01711568 7:0.015948878 +1 1:0.751152 2:0.013825 3:0.046083 5:0.041037377 7:0.015314152 +1 1:0.763889 2:0.013889 3:0.048611 5:0.017294589 7:0.018250341 +1 1:0.782946 2:0.007752 3:0.03876 5:0.019068776 7:0.018481756 +1 1:0.784753 2:0.008969 3:0.03139 5:0.023630969 7:0.01725364 +1 1:0.772926 2:0.030568 3:0.026201 5:0.033836268 6:0.013617014 7:0.017600384 +1 1:0.626984 2:0.15873 3:0.02381 4:0.0036900369 5:0.056334143 6:0.10579211 7:0.019212159 +1 1:0.671533 2:0.043796 3:0.116788 5:0.097319339 7:0.017046463 +1 1:0.787062 2:0.037736 3:0.024259 5:0.015840949 6:0.016998017 7:0.02320689 +1 1:0.78481 2:0.018987 3:0.018987 5:0.015758949 6:0.0063420063 7:0.018254091 +1 1:0.762295 2:0.032787 3:0.02459 5:0.021059145 6:0.0084750085 7:0.017692921 +1 1:0.748031 2:0.023622 3:0.047244 5:0.023668242 7:0.015123872 +1 1:0.701413 2:0.022968 3:0.070671 4:0.0073800738 5:0.021849328 6:0.0035160035 7:0.018378866 +1 1:0.753247 2:0.032468 3:0.019481 5:0.037369731 6:0.015039015 7:0.015798226 +1 1:0.701695 2:0.033898 3:0.074576 5:0.047724121 7:0.016143037 +1 1:0.732143 2:0.02381 3:0.059524 5:0.014849492 7:0.018220091 +1 1:0.755102 2:0.013605 3:0.027211 5:0.037369731 7:0.016550524 +1 1:0.750779 2:0.021807 3:0.034268 5:0.018450047 6:0.011139011 7:0.015348378 +1 1:0.76901 2:0.014347 3:0.050215 5:0.03473827 7:0.018773841 +1 1:0.715278 2:0.048611 3:0.059028 5:0.050653765 7:0.018694951 +1 1:0.760252 2:0.018927 3:0.050473 5:0.031256989 7:0.01835039 +1 1:0.75266 2:0.023936 3:0.037234 5:0.048409941 6:0.0064950065 7:0.014984433 +1 1:0.760504 2:0.008403 3:0.063025 5:0.020425507 7:0.018702604 +1 1:0.768473 2:0.009852 3:0.039409 5:0.025487156 7:0.017571787 +1 1:0.791878 2:0.015228 3:0.040609 5:0.02096969 7:0.022006933 +1 1:0.729614 2:0.021459 3:0.038627 5:0.013530034 7:0.014419555 +1 1:0.770787 2:0.01573 3:0.035955 5:0.03088426 7:0.01653878 +1 1:0.775281 2:0.005618 3:0.022472 5:0.018450047 7:0.013839409 +1 1:0.773399 2:0.014778 3:0.039409 5:0.017100771 6:0.0045870046 7:0.01964436 +1 1:0.719008 2:0.008264 3:0.024793 5:0.028021708 7:0.013404555 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.780822 2:0.004566 3:0.03653 5:0.011092392 7:0.018710323 +1 1:0.747253 2:0.025641 3:0.032967 5:0.028632982 7:0.017443939 +1 1:0.764706 2:0.017647 3:0.064706 5:0.037653005 7:0.021305598 +1 1:0.748837 2:0.027907 3:0.05814 5:0.065197621 7:0.019455476 +1 1:0.757778 2:0.022222 3:0.037778 5:0.029162256 7:0.017317073 +1 1:0.781377 2:0.008097 3:0.040486 5:0.0092138416 7:0.019971366 +1 1:0.559322 2:0.112994 3:0.146893 5:0.16627406 7:0.018533829 +1 1:0.786008 2:0.00823 3:0.037037 5:0.020678962 7:0.018091939 +1 1:0.738255 2:0.020134 3:0.053691 5:0.039867011 7:0.015305287 +1 1:0.746835 2:0.037975 3:0.044304 5:0.047381212 6:0.012711013 7:0.0182155 +1 1:0.703125 2:0.041667 3:0.078125 5:0.085518763 7:0.0166095 +1 1:0.777293 2:0.030568 3:0.034934 5:0.019724777 7:0.020129939 +1 1:0.74168 2:0.012678 3:0.052298 5:0.021238054 7:0.02035097 +1 1:0.744548 2:0.024922 3:0.037383 5:0.03499918 7:0.016184183 +1 1:0.734848 2:0.015152 3:0.049242 5:0.023258241 7:0.014805061 +1 1:0.721649 2:0.043814 3:0.048969 5:0.056744144 6:0.0028530029 7:0.016516848 +1 1:0.806897 2:0.006897 3:0.055172 5:0.0083267485 7:0.037636671 +1 1:0.798851 2:0.017241 3:0.022989 5:0.012985851 6:0.0052260052 7:0.020114945 +1 1:0.744144 2:0.023423 3:0.032432 5:0.015304221 7:0.016051415 +1 1:0.781395 2:0.013953 3:0.04186 5:0.02258733 7:0.018718091 +1 1:0.739326 2:0.031461 3:0.017978 5:0.029490257 7:0.01385311 +1 1:0.723404 2:0.042553 3:0.035461 5:0.067359444 6:0.009036009 7:0.014357378 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.733333 2:0.012121 3:0.060606 5:0.017577863 7:0.015668884 +1 1:0.779967 2:0.011494 3:0.024631 5:0.018159319 6:0.0018270018 7:0.016440384 +1 1:0.791123 2:0.015666 3:0.023499 5:0.012143485 7:0.019550402 +1 1:0.769461 2:0.020958 3:0.032934 5:0.029549893 7:0.018420476 +1 1:0.734234 2:0.016517 3:0.055556 5:0.0074843827 6:0.0015060015 7:0.018246902 +1 1:0.762987 2:0.012987 3:0.022727 5:0.02070878 7:0.014254037 +1 1:0.775701 2:0.009346 3:0.035514 5:0.020440416 7:0.016628677 +1 1:0.743243 2:0.02027 3:0.033784 5:0.022937695 7:0.013389915 +1 1:0.733728 2:0.065089 3:0.029586 5:0.0072309275 6:0.046557047 7:0.018599366 +1 1:0.683099 2:0.049296 3:0.098592 5:0.12394704 7:0.018077982 +1 1:0.752688 2:0.016129 3:0.043011 5:0.029639348 7:0.01648964 +1 1:0.754789 2:0.015326 3:0.061303 5:0.032166446 7:0.021656854 +1 1:0.704797 2:0.01845 3:0.073801 5:0.05271868 7:0.015907659 +1 1:0.77707 2:0.014862 3:0.025478 5:0.017995319 7:0.016091866 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.696581 2:0.055556 3:0.047009 4:0.0036900369 5:0.077147287 6:0.011643012 7:0.020142799 +1 1:0.770718 2:0.019337 3:0.041436 5:0.036601911 7:0.020583482 +1 1:0.736842 2:0.015038 3:0.052632 7:0.018017604 +1 1:0.716667 2:0.041667 3:0.033333 5:0.058466149 7:0.012957317 +1 1:0.700483 2:0.057971 3:0.05314 5:0.043422838 6:0.023301023 7:0.015170262 +1 1:0.762527 2:0.015251 3:0.058824 5:0.029959894 7:0.019833677 +1 1:0.785714 2:0.010204 3:0.027211 5:0.017644954 7:0.017525305 +1 1:0.684615 2:0.066667 3:0.046154 5:0.087777496 6:0.013587014 7:0.017260787 +1 1:0.764331 2:0.012739 3:0.025478 5:0.018494774 7:0.015651701 +1 1:0.769841 2:0.015873 3:0.034392 4:0.0036900369 5:0.012620578 6:0.0050790051 7:0.019050848 +1 1:0.718593 2:0.01005 3:0.020101 5:0.030429532 7:0.015014098 +1 1:0.75 2:0.031746 3:0.031746 5:0.045942481 6:0.013866014 7:0.01570364 +1 1:0.767857 2:0.017857 3:0.035714 5:0.033657358 7:0.016078689 +1 1:0.751678 2:0.020134 3:0.026846 5:0.020999508 7:0.014527744 +1 1:0.762195 2:0.02439 3:0.04878 5:0.025017518 7:0.022159427 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.768061 2:0.015209 3:0.019011 5:0.011450211 7:0.015093201 +1 1:0.751163 2:0.027907 3:0.02093 5:0.028729891 6:0.0028890029 7:0.014719232 +1 1:0.767123 2:0.017123 3:0.030822 5:0.0096685701 7:0.016100067 +1 1:0.749035 2:0.027027 3:0.034749 5:0.032732992 6:0.0094110094 7:0.018763537 +1 1:0.75 2:0.024194 3:0.032258 5:0.023966425 7:0.015293079 +1 1:0.767568 2:0.010811 3:0.027027 5:0.015863313 7:0.015491098 +1 1:0.770563 2:0.012987 3:0.021645 5:0.024972791 7:0.015758634 +1 1:0.766917 2:0.037594 3:0.015038 5:0.021670419 6:0.017442017 7:0.015771134 +1 1:0.759494 2:0.012658 3:0.044304 4:0.0036900369 7:0.015938561 +1 1:0.757322 2:0.012552 3:0.062762 5:0.018636411 7:0.030615366 +1 1:0.775735 2:0.011029 3:0.022059 5:0.011025301 7:0.015154232 +1 1:0.698113 2:0.012579 3:0.069182 5:0.044369567 7:0.012885415 +1 1:0.764463 2:0.016529 3:0.045455 5:0.042595381 7:0.017637573 +1 1:0.757925 2:0.017291 3:0.0317 5:0.040336648 7:0.016236732 +1 1:0.758242 2:0.021978 3:0.06044 5:0.035550818 7:0.021073439 +1 1:0.70624 2:0.045662 3:0.04414 5:0.065928168 6:0.0088440088 7:0.015740433 +1 1:0.741525 2:0.016949 3:0.067797 5:0.01951605 7:0.019739561 +1 1:0.73494 2:0.012048 3:0.078313 5:0.027917344 7:0.019615043 +1 1:0.77492 2:0.009646 3:0.032154 5:0.027335888 7:0.016037957 +1 1:0.712329 2:0.020548 3:0.082192 5:0.016139132 7:0.019295024 +1 1:0.752717 2:0.035326 3:0.038043 5:0.013321307 6:0.018768019 7:0.018541226 +1 1:0.775934 2:0.010373 3:0.03527 5:0.015639676 7:0.018090274 +1 1:0.764706 2:0.023529 3:0.041176 5:0.029937531 7:0.017862268 +1 1:0.748869 2:0.022624 3:0.047511 5:0.034879907 7:0.020637896 +1 1:0.74677 2:0.02584 3:0.046512 5:0.033851177 7:0.017347323 +1 1:0.772487 2:0.021164 3:0.037037 5:0.025576611 7:0.018808878 +1 1:0.779614 2:0.011019 3:0.033058 5:0.013731308 6:0.0027630028 7:0.018242287 +1 1:0.719222 2:0.030238 3:0.038877 4:0.0036900369 5:0.013157306 6:0.0079440079 7:0.014921244 +1 1:0.771429 2:0.012987 3:0.041558 5:0.032129173 7:0.018371872 +1 1:0.783654 2:0.004808 3:0.019231 7:0.016826921 +1 1:0.684685 2:0.042042 3:0.039039 5:0.06144052 7:0.013330402 +1 1:0.656442 2:0.06135 3:0.104294 5:0.17416844 7:0.016010774 +1 1:0.727848 2:0.031646 3:0.056962 5:0.034276087 7:0.016787591 +1 1:0.753555 2:0.009479 3:0.061611 5:0.02456279 7:0.017541323 +1 1:0.740964 2:0.036145 3:0.069277 5:0.074955645 7:0.020092567 +1 1:0.72332 2:0.019763 3:0.063241 5:0.0071563819 7:0.025113274 +1 1:0.77619 2:0.011111 3:0.036508 5:0.024659699 7:0.017557104 +1 1:0.735849 2:0.028302 3:0.037736 5:0.044995751 6:0.006036006 7:0.014294756 +1 1:0.750733 2:0.014663 3:0.041056 5:0.034954453 7:0.015252841 +1 1:0.712281 2:0.035088 3:0.049123 5:0.044906296 7:0.014206244 +1 1:0.772727 2:0.012626 3:0.037879 5:0.022572421 7:0.020340604 +1 1:0.762048 2:0.03012 3:0.027108 5:0.022796058 6:0.0091740092 7:0.018017189 +1 1:0.729167 2:0.03869 3:0.047619 5:0.030839533 6:0.0093060093 7:0.017548634 +1 1:0.753521 2:0.042254 3:0.025822 5:0.041380287 6:0.014274014 7:0.018049354 +1 1:0.804487 2:0.00641 3:0.032051 5:0.014200945 7:0.02052064 +1 1:0.755682 2:0.022727 3:0.056818 5:0.026158067 7:0.01974778 +1 1:0.743631 2:0.035032 3:0.033439 5:0.021670419 6:0.012210012 7:0.016700323 +1 1:0.709163 2:0.047809 3:0.043825 5:0.011576939 6:0.032610033 7:0.015644738 +1 1:0.770245 2:0.032015 3:0.050847 5:0.031473171 6:0.011082011 7:0.021760598 +1 1:0.793333 2:0.013333 3:0.046667 5:0.029467893 7:0.020569104 +1 1:0.8 2:0.010667 3:0.034667 5:0.017428772 7:0.020861787 +1 1:0.782946 2:0.015504 3:0.033592 5:0.019031503 7:0.018513268 +1 1:0.770073 2:0.014599 3:0.018248 5:0.011196756 7:0.014821079 +1 1:0.754098 2:0.02459 3:0.02459 7:0.01534386 +1 1:0.789189 2:0.005405 3:0.027027 5:0.014648219 7:0.01677653 +1 1:0.683871 2:0.088172 3:0.049462 5:0.037011912 6:0.046809047 7:0.018489378 +1 1:0.756098 2:0.03252 3:0.03252 5:0.045316297 6:0.0091200091 7:0.016309738 +1 1:0.691558 2:0.025974 3:0.068182 5:0.062342522 7:0.016570317 +1 1:0.745856 2:0.027624 3:0.038674 5:0.031122806 7:0.01613664 +1 1:0.701149 2:0.049808 3:0.049808 4:0.0036900369 5:0.087702951 6:0.0078420078 7:0.017872165 +1 1:0.785965 2:0.003509 3:0.021053 5:0.0099667526 7:0.016003421 +1 1:0.747059 2:0.020588 3:0.038235 5:0.017562954 7:0.01522597 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.787234 2:0.015957 3:0.024823 5:0.017272226 7:0.018660268 +1 1:0.778656 2:0.019763 3:0.039526 5:0.029423166 7:0.018316787 +1 1:0.773504 2:0.017094 3:0.042735 5:0.031584989 7:0.01844903 +1 1:0.783654 2:0.033654 3:0.014423 5:0.011524757 6:0.018546019 7:0.018966933 +1 1:0.791916 2:0.01497 3:0.02994 5:0.0106973 7:0.019077695 +1 1:0.786487 2:0.010811 3:0.02973 5:0.019702414 7:0.018704683 +1 1:0.779456 2:0.012085 3:0.018127 5:0.017294589 7:0.015879451 +1 1:0.775819 2:0.015113 3:0.025189 5:0.020552234 7:0.016710695 +1 1:0.694444 2:0.0625 3:0.0625 5:0.073516914 7:0.021468494 +1 1:0.782082 2:0.007264 3:0.033898 5:0.011748394 7:0.018735604 +1 1:0.767081 2:0.012422 3:0.040373 5:0.020537325 7:0.020621878 +1 1:0.78135 2:0.022508 3:0.038585 5:0.026888614 6:0.0054090054 7:0.02174339 +1 1:0.761364 2:0.018939 3:0.056818 5:0.027783162 7:0.018592939 +1 1:0.785185 2:0.02963 3:0.014815 5:0.019016594 6:0.015306015 7:0.017705512 +1 1:0.771605 2:0.012346 3:0.055556 5:0.013910217 7:0.020174646 +1 1:0.724868 2:0.026455 3:0.071429 5:0.029892803 7:0.0201155 +1 1:0.717647 2:0.047059 3:0.076471 5:0.078608382 7:0.020408896 +1 1:0.782258 2:0.032258 3:0.016129 5:0.019210413 6:0.015465015 7:0.019079463 +1 1:0.754032 2:0.018145 3:0.030242 5:0.039404828 7:0.013953085 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.752907 2:0.020349 3:0.034884 5:0.041551742 7:0.015899744 +1 1:0.596078 2:0.094118 3:0.129412 5:0.079816021 7:0.022333811 +1 1:0.797101 2:0.006441 3:0.040258 5:0.013753671 7:0.021287457 +1 1:0.769097 2:0.026042 3:0.020833 5:0.023988788 6:0.0077220077 7:0.016450713 +1 1:0.777012 2:0.016092 3:0.029885 5:0.0056952872 7:0.01834875 +1 1:0.775578 2:0.016502 3:0.052805 5:0.034864998 7:0.021512518 +1 1:0.810526 2:0.005263 3:0.036842 7:0.02166239 +1 1:0.724409 2:0.062992 3:0.031496 5:0.069454177 6:0.027951028 7:0.015459957 +1 1:0.742331 2:0.026074 3:0.052147 5:0.04586048 7:0.01672153 +1 1:0.749333 2:0.024 3:0.029333 5:0.023220968 7:0.015658537 +1 1:0.781482 2:0.011111 3:0.033333 5:0.018382956 7:0.018315268 +1 1:0.782271 2:0.010886 3:0.03888 5:0.014663128 7:0.019288396 +1 1:0.744186 2:0.01938 3:0.050388 5:0.011211665 7:0.015716579 +1 1:0.73913 2:0.035326 3:0.065217 5:0.074672372 7:0.019850213 +1 1:0.763485 2:0.016598 3:0.03112 5:0.021528782 6:0.0043320043 7:0.017521 +1 1:0.741047 2:0.027548 3:0.035813 5:0.038070461 7:0.016444939 +1 1:0.764463 2:0.016529 3:0.041322 5:0.009772934 7:0.019224957 +1 1:0.726804 2:0.037801 3:0.060137 5:0.0096536609 6:0.00035400035 7:0.089001341 8:0.023809524 +1 1:0.781204 2:0.010279 3:0.030837 5:0.015371312 7:0.017370439 +1 1:0.769042 2:0.012285 3:0.036855 5:0.032158991 7:0.017363817 +1 1:0.79021 2:0.006993 3:0.041958 5:0.017018771 7:0.018676445 +1 1:0.792079 2:0.005941 3:0.023762 5:0.0098027522 7:0.018365128 +1 1:0.734756 2:0.027439 3:0.073171 5:0.063893072 7:0.019519634 +1 1:0.779967 2:0.011494 3:0.024631 5:0.018159319 6:0.0018270018 7:0.016440384 +1 1:0.775758 2:0.006061 3:0.036364 5:0.01762259 7:0.015631927 +1 1:0.794457 2:0.006928 3:0.025404 5:0.011785666 7:0.01781389 +1 1:0.745455 2:0.030303 3:0.036364 5:0.043691202 7:0.016814488 +1 1:0.803456 2:0.008639 3:0.038877 5:0.018025137 7:0.021782646 +1 1:0.749175 2:0.013201 3:0.059406 5:0.031927899 7:0.01879578 +1 1:0.754923 2:0.037199 3:0.035011 5:0.033456085 6:0.017952018 7:0.017839037 +1 1:0.787425 2:0.008982 3:0.035928 5:0.021036781 7:0.019406311 +1 1:0.769821 2:0.025575 3:0.040921 5:0.026322067 6:0.0084750085 7:0.022082213 +1 1:0.682927 2:0.089431 3:0.03252 5:0.050370492 6:0.070947071 7:0.014673805 +1 1:0.729508 2:0.057377 3:0.02459 5:0.066360533 6:0.026706027 7:0.016843262 +1 1:0.779141 2:0.018405 3:0.03681 7:0.019040848 +1 1:0.767296 2:0.028302 3:0.022013 5:0.022520239 6:0.012084012 7:0.0190405 +1 1:0.706161 2:0.052133 3:0.040284 5:0.028424254 6:0.028599029 7:0.015157207 +1 1:0.733871 2:0.048387 3:0.024194 5:0.027007887 6:0.032610033 7:0.013571988 +1 1:0.735484 2:0.058065 3:0.058065 5:0.03063826 6:0.016437016 7:0.028717543 +1 1:0.714286 2:0.040816 3:0.054422 5:0.040843559 7:0.015140201 +1 1:0.765542 2:0.010657 3:0.021314 5:0.016019859 7:0.015119354 +1 1:0.768473 2:0.009852 3:0.019704 7:0.01408747 +1 1:0.785047 2:0.006231 3:0.040498 5:0.016362769 7:0.017304915 +1 1:0.68593 2:0.042714 3:0.090452 5:0.10343954 7:0.016561463 +1 1:0.683544 2:0.075949 3:0.054852 5:0.065779077 6:0.030882031 7:0.01749511 +1 1:0.734177 2:0.028481 3:0.037975 5:0.019016594 7:0.015128128 +1 1:0.773585 2:0.018868 3:0.037736 5:0.030347532 7:0.021197652 +1 1:0.759936 2:0.014308 3:0.034976 5:0.03106317 7:0.016286012 +1 1:0.764706 2:0.026144 3:0.019608 5:0.0179655 7:0.016539134 +1 1:0.785714 2:0.010714 3:0.035714 5:0.023370059 6:0.0031350031 7:0.020840591 +1 1:0.776923 2:0.007692 3:0.038462 5:0.019016594 7:0.018386494 +1 1:0.693252 2:0.042945 3:0.042945 5:0.020425507 7:0.013654049 +1 1:0.753623 2:0.007246 3:0.065217 5:0.017876046 7:0.018425238 +1 1:0.704545 2:0.039773 3:0.0625 5:0.047888122 7:0.016179323 +1 1:0.767908 2:0.011461 3:0.037249 5:0.023563878 7:0.016580476 +1 1:0.771596 2:0.010249 3:0.040996 5:0.016094405 7:0.016542872 +1 1:0.744856 2:0.024691 3:0.037037 5:0.035722273 7:0.015708122 +1 1:0.76947 2:0.018692 3:0.05296 5:0.017026225 7:0.033261152 +1 1:0.766667 2:0.055556 3:0.072222 5:0.030832078 7:0.073712738 +1 1:0.756849 2:0.023973 3:0.047945 5:0.051585586 7:0.018104744 +1 1:0.741551 2:0.027833 3:0.071571 5:0.055014685 7:0.019711 +1 1:0.806854 2:0.003115 3:0.040498 5:0.0062320159 7:0.02271864 +1 1:0.785441 2:0.005747 3:0.032567 5:0.0093256601 7:0.018678159 +1 1:0.780576 2:0.007194 3:0.061151 5:0.015102948 7:0.021648537 +1 1:0.739617 2:0.025559 3:0.063898 5:0.066636351 7:0.017435518 +1 1:0.764407 2:0.025424 3:0.020339 5:0.0180475 6:0.0090810091 7:0.017073171 +1 1:0.740614 2:0.030717 3:0.037543 5:0.052055223 7:0.014900524 +1 1:0.78125 2:0.025735 3:0.023897 5:0.017771682 6:0.0053640054 7:0.018808287 +1 1:0.715976 2:0.017751 3:0.035503 5:0.014968765 7:0.017967963 +1 1:0.804469 2:0.005587 3:0.050279 5:0.011554575 7:0.021971659 +1 1:0.797357 2:0.008811 3:0.035242 5:0.019985687 7:0.020038683 +1 1:0.753807 2:0.030457 3:0.043147 5:0.036072637 7:0.019190293 +1 1:0.758209 2:0.01194 3:0.020896 5:0.0097431157 7:0.01392428 +1 1:0.786127 2:0.011561 3:0.046243 5:0.023183695 7:0.022663189 +1 1:0.768212 2:0.013245 3:0.043046 5:0.03439536 7:0.01750525 +1 1:0.733925 2:0.026608 3:0.026608 5:0.032382628 6:0.0052140052 7:0.015561622 +1 1:0.719828 2:0.025862 3:0.056034 5:0.025748066 6:0.0051810052 7:0.015217622 +1 1:0.79902 2:0.004902 3:0.034314 5:0.010667482 7:0.020893116 +1 1:0.708738 2:0.067961 3:0.029126 5:0.025613883 6:0.048111048 7:0.017227091 +1 1:0.743243 2:0.022523 3:0.033033 5:0.035327181 7:0.015454476 +1 1:0.770787 2:0.01573 3:0.035955 5:0.03088426 7:0.01653878 +1 1:0.738095 2:0.031746 3:0.039683 5:0.022058056 7:0.016356951 +1 1:0.787234 2:0.015957 3:0.024823 5:0.017272226 7:0.018660268 +1 1:0.783105 2:0.018265 3:0.03653 5:0.024696972 7:0.021007348 +1 1:0.707602 2:0.023392 3:0.093567 5:0.061231792 7:0.017365567 +1 1:0.729167 2:0.041667 3:0.057292 5:0.076849105 7:0.018483232 +1 1:0.802867 2:0.007168 3:0.032258 5:0.014961311 7:0.021778567 +1 1:0.768559 2:0.017467 3:0.026201 5:0.025748066 7:0.015416976 +1 1:0.722513 2:0.031414 3:0.04712 5:0.036102456 7:0.01318478 +1 1:0.762295 2:0.012295 3:0.032787 5:0.021148599 7:0.017617951 +1 1:0.672131 2:0.110656 3:0.032787 4:0.0036900369 5:0.021864237 6:0.087978088 7:0.017043183 +1 1:0.737828 2:0.071161 3:0.026217 5:0.053889046 6:0.032529033 7:0.018954963 +1 1:0.791837 2:0.004082 3:0.028571 5:0.010540754 7:0.017595817 +1 1:0.8 2:0.011321 3:0.022642 5:0.0043311019 7:0.019788311 +1 1:0.782946 2:0.007752 3:0.054264 5:0.017876046 7:0.01971072 +1 1:0.727891 2:0.020408 3:0.040816 5:0.023370059 7:0.013232122 +1 1:0.726619 2:0.043165 3:0.035971 5:0.04107465 6:0.016530017 7:0.015923848 +1 1:0.647541 2:0.057377 3:0.147541 5:0.027089887 7:0.082516994 +1 1:0.734568 2:0.024691 3:0.049383 5:0.036184456 7:0.015507378 +1 1:0.715116 2:0.011628 3:0.023256 5:0.034432633 7:0.015350256 +1 1:0.786618 2:0.012658 3:0.025316 5:0.013157306 7:0.018744762 +1 1:0.724138 2:0.022989 3:0.072797 5:0.054895412 7:0.015863 +1 1:0.768 2:0.016 3:0.032 5:0.022251875 7:0.016341463 +1 1:0.776398 2:0.006211 3:0.049689 5:0.016034768 7:0.01761097 +1 1:0.722513 2:0.036649 3:0.036649 5:0.049475944 7:0.014429829 +1 1:0.759804 2:0.019608 3:0.029412 5:0.027708616 7:0.016080823 +1 1:0.764228 2:0.02439 3:0.028455 5:0.021864237 7:0.016904622 +1 1:0.716535 2:0.015748 3:0.141732 5:0.016422405 7:0.021797579 +1 1:0.749175 2:0.039604 3:0.056106 5:0.022564967 6:0.015135015 7:0.019942848 +1 1:0.74269 2:0.011696 3:0.038012 5:0.02730607 7:0.014602055 +1 1:0.72119 2:0.022305 3:0.055762 5:0.03516318 7:0.014416537 +1 1:0.736607 2:0.035714 3:0.035714 5:0.04852176 6:0.0071010071 7:0.01533464 +1 1:0.777778 2:0.017544 3:0.040936 5:0.028834255 7:0.018435317 +1 1:0.727273 2:0.038123 3:0.035191 5:0.062267977 6:0.010740011 7:0.014984622 +1 1:0.472 2:0.064 3:0.12 5:0.13762617 6:0.0092310092 7:0.015853659 +1 1:0.730496 2:0.007092 3:0.06383 4:0.0036900369 5:0.022117693 7:0.014573604 +1 1:0.77605 2:0.009331 3:0.03888 5:0.0249877 7:0.016974549 +1 1:0.775194 2:0.01292 3:0.056848 5:0.0091318414 7:0.038586378 +1 1:0.727891 2:0.020408 3:0.040816 5:0.023370059 7:0.013232122 +1 1:0.726519 2:0.035912 3:0.046961 5:0.040336648 7:0.015563939 +1 1:0.73251 2:0.041152 3:0.028807 5:0.045592116 7:0.01641072 +1 1:0.746377 2:0.021739 3:0.057971 5:0.019165685 7:0.017188055 +1 1:0.7866 2:0.01737 3:0.032258 5:0.017704591 7:0.019109726 +1 1:0.681818 2:0.045455 3:0.103896 5:0.082641301 7:0.01785714 +1 1:0.738854 2:0.019108 3:0.050955 5:0.036810639 7:0.015729378 +1 1:0.76087 2:0.019565 3:0.023913 5:0.026225158 7:0.015071579 +1 1:0.753112 2:0.016598 3:0.03527 5:0.022117693 6:0.0022260022 7:0.017052927 +1 1:0.762712 2:0.00565 3:0.056497 7:0.018189335 +1 1:0.615854 2:0.097561 3:0.079268 5:0.11801321 6:0.03957904 7:0.014091317 +1 1:0.684615 2:0.066667 3:0.046154 5:0.087777496 6:0.013587014 7:0.017260787 +1 1:0.780488 2:0.00813 3:0.03252 5:0.023891879 7:0.015466982 +1 1:0.769231 2:0.019943 3:0.037037 5:0.023079331 6:0.0061920062 7:0.016833439 +1 1:0.77458 2:0.009592 3:0.05036 5:0.010913482 7:0.019974262 +1 1:0.747126 2:0.028736 3:0.045977 5:0.030243168 7:0.017276421 +1 1:0.722892 2:0.024096 3:0.028112 5:0.041603924 7:0.013162402 +1 1:0.754717 2:0.028302 3:0.056604 5:0.046740119 7:0.018350207 +1 1:0.806867 2:0.008584 3:0.04721 5:0.016459678 7:0.023709829 +1 1:0.727273 2:0.033058 3:0.082645 6:0.017823018 7:0.0254485 +1 1:0.761421 2:0.015228 3:0.045685 5:0.02823789 7:0.016342701 +1 1:0.75265 2:0.024735 3:0.045936 5:0.039389918 7:0.016310439 +1 1:0.762463 2:0.020528 3:0.038123 5:0.041223741 7:0.019401329 +1 1:0.777778 2:0.017544 3:0.040936 5:0.028834255 7:0.018435317 +1 1:0.739514 2:0.039735 3:0.024283 5:0.034447542 6:0.022182022 7:0.014564152 +1 1:0.780328 2:0.019672 3:0.036066 5:0.015609858 7:0.019092366 +1 1:0.788732 2:0.007825 3:0.029734 5:0.014700401 7:0.019351884 +1 1:0.729508 2:0.016393 3:0.07377 5:0.02258733 7:0.016493402 +1 1:0.772414 2:0.02069 3:0.041379 5:0.03106317 7:0.02018503 +1 1:0.773585 2:0.012579 3:0.113208 5:0.0098102068 7:0.029145573 +1 1:0.739437 2:0.014085 3:0.06338 5:0.037272822 7:0.017176226 +1 1:0.66242 2:0.063694 3:0.063694 5:0.073994007 7:0.015651701 +1 1:0.76947 2:0.028037 3:0.037383 5:0.033217539 7:0.02131297 +1 1:0.756014 2:0.017182 3:0.044674 5:0.018025137 7:0.017328805 +1 1:0.668508 2:0.055249 3:0.116022 5:0.012635487 6:0.0067800068 7:0.059628079 +1 1:0.781753 2:0.012522 3:0.033989 5:0.018397865 7:0.017681835 +1 1:0.735786 2:0.026756 3:0.023411 5:0.046419573 6:0.0037350037 7:0.016375726 +1 1:0.738971 2:0.011029 3:0.040441 5:0.032129173 7:0.015602585 +1 1:0.732558 2:0.02907 3:0.034884 5:0.052867771 7:0.014995744 +1 1:0.75 2:0.02381 3:0.077381 5:0.030869351 7:0.035060976 +1 1:0.731624 2:0.018803 3:0.068376 4:0.014760148 5:0.01737659 7:0.017886177 +1 1:0.781991 2:0.004739 3:0.023697 7:0.017078951 +1 1:0.785714 2:0.008929 3:0.040179 5:0.010369299 7:0.019572079 +1 1:0.706522 2:0.016304 3:0.081522 5:0.015341494 7:0.016105512 +1 1:0.740506 2:0.031646 3:0.050633 5:0.032062082 7:0.017945354 +1 1:0.729412 2:0.041176 3:0.029412 5:0.055215959 6:0.014814015 7:0.014526543 +1 1:0.77665 2:0.030457 3:0.030457 5:0.022289148 6:0.013452013 7:0.020706945 +1 1:0.774648 2:0.014085 3:0.035211 5:0.020820598 7:0.015372726 +1 1:0.740964 2:0.033133 3:0.054217 5:0.014774947 7:0.018531445 +1 1:0.772358 2:0.018293 3:0.02439 5:0.017294589 6:0.006960007 7:0.016024689 +1 1:0.774194 2:0.008065 3:0.032258 5:0.023668242 7:0.015489774 +1 1:0.764706 2:0.007353 3:0.080882 5:0.016713133 7:0.019996415 +1 1:0.730047 2:0.032864 3:0.042254 5:0.024622426 7:0.017333677 +1 1:0.765625 2:0.03125 3:0.101562 5:0.014946402 7:0.071265244 +1 1:0.745946 2:0.027027 3:0.07027 5:0.049535581 7:0.019841793 +1 1:0.731707 2:0.019164 3:0.041812 5:0.044608114 7:0.015976884 +1 1:0.748503 2:0.011976 3:0.047904 5:0.035707364 7:0.015243902 +1 1:0.786765 2:0.007353 3:0.029412 5:0.018778048 7:0.0177995 +1 1:0.741935 2:0.010753 3:0.053763 5:0.021156054 7:0.017325598 8:0.023809524 +1 1:0.781671 2:0.010782 3:0.024259 5:0.014834583 7:0.016517652 +1 1:0.777778 2:0.007937 3:0.02381 7:0.015001933 +1 1:0.772819 2:0.006085 3:0.032454 5:0.013298943 7:0.020803445 +1 1:0.74613 2:0.021672 3:0.034056 5:0.0099294798 6:0.007989008 7:0.014177299 +1 1:0.756881 2:0.018349 3:0.059633 5:0.045666662 7:0.018264713 +1 1:0.741866 2:0.030369 3:0.030369 5:0.024622426 6:0.012387012 7:0.016017671 +1 1:0.766667 2:0.016667 3:0.033333 5:0.02412297 7:0.01570122 +1 1:0.74026 2:0.038961 3:0.064935 5:0.071407273 7:0.020668354 +1 1:0.773663 2:0.004115 3:0.016461 5:0.013753671 7:0.013600323 +1 1:0.737307 2:0.037528 3:0.055188 4:0.0036900369 5:0.02660534 6:0.017130017 7:0.018858018 +1 1:0.751634 2:0.006536 3:0.039216 7:0.014028378 +1 1:0.778325 2:0.014778 3:0.019704 5:0.013984763 6:0.0056280056 7:0.016009854 +1 1:0.751152 2:0.018433 3:0.043779 5:0.032240991 7:0.016241427 +1 1:0.698864 2:0.068182 3:0.039773 5:0.068268901 6:0.016485016 7:0.018916299 +1 1:0.727536 2:0.02029 3:0.057971 4:0.0036900369 5:0.041275923 7:0.015959701 +1 1:0.760736 2:0.02454 3:0.042945 5:0.031860808 7:0.01750711 +1 1:0.795752 2:0.006536 3:0.027778 5:0.016340405 7:0.018183085 +1 1:0.771863 2:0.022814 3:0.019011 5:0.018778048 6:0.0075570076 7:0.018408604 +1 1:0.774799 2:0.016086 3:0.040214 5:0.027060069 6:0.0027210027 7:0.01801478 +1 1:0.701863 2:0.024845 3:0.037267 5:0.037272822 7:0.01514922 +1 1:0.782609 2:0.036232 3:0.014493 5:0.019210413 6:0.023196023 7:0.017143866 +1 1:0.736264 2:0.027473 3:0.049451 5:0.030675533 7:0.0162825 +1 1:0.747082 2:0.031128 3:0.042802 5:0.053710137 6:0.0086460086 7:0.016465787 +1 1:0.781116 2:0.012876 3:0.042918 5:0.030593532 7:0.019130116 +1 1:0.7 2:0.0125 3:0.075 7:0.014710366 +1 1:0.746518 2:0.038997 3:0.05571 5:0.03790646 7:0.020042122 +1 1:0.806854 2:0.003115 3:0.040498 5:0.0062320159 7:0.02271864 +1 1:0.742739 2:0.03112 3:0.047718 5:0.049915763 6:0.0022320022 7:0.017002329 +1 1:0.741483 2:0.032064 3:0.054108 5:0.05536505 7:0.023033872 +1 1:0.752941 2:0.023529 3:0.039216 5:0.047030847 7:0.015160207 +1 1:0.778452 2:0.015175 3:0.042489 5:0.023630969 7:0.020430067 +1 1:0.777778 2:0.013889 3:0.041667 5:0.01754059 7:0.017996274 +1 1:0.79096 2:0.011299 3:0.062147 5:0.020880235 7:0.024596939 +1 1:0.734266 2:0.034965 3:0.062937 5:0.033657358 7:0.018889646 +1 1:0.748373 2:0.032538 3:0.02603 5:0.030429532 6:0.0097950098 7:0.016202848 +1 1:0.795566 2:0.012315 3:0.019704 5:0.0059636515 7:0.01877328 +1 1:0.763975 2:0.018634 3:0.074534 5:0.027559525 7:0.020489323 +1 1:0.708333 2:0.047619 3:0.059524 5:0.094963696 6:0.0063690064 7:0.017094945 +1 1:0.727915 2:0.031802 3:0.045936 5:0.018942048 7:0.016956823 +1 1:0.794118 2:0.005882 3:0.029412 5:0.01582604 7:0.016893829 +1 1:0.780488 2:0.014634 3:0.02439 5:0.013626944 6:0.0054840055 7:0.016270079 +1 1:0.752577 2:0.034364 3:0.030928 5:0.017682227 6:0.014235014 7:0.017664067 +1 1:0.809187 2:0.003534 3:0.035336 5:0.0080360205 7:0.019994829 +1 1:0.752193 2:0.046053 3:0.032895 5:0.02516661 6:0.024309024 7:0.019803701 +1 1:0.646288 2:0.061135 3:0.069869 5:0.089656046 6:0.025773026 7:0.01549686 +1 1:0.777126 2:0.026393 3:0.029326 5:0.013589671 6:0.0082050082 7:0.019615909 +1 1:0.687296 2:0.043974 3:0.052117 5:0.10249281 7:0.018779299 +1 1:0.782396 2:0.022005 3:0.026895 5:0.011793121 6:0.0047460047 7:0.018844299 +1 1:0.756757 2:0.033784 3:0.040541 5:0.030362441 7:0.020229073 +1 1:0.732456 2:0.037281 3:0.076754 5:0.08471367 7:0.02000428 +1 1:0.790433 2:0.01139 3:0.031891 5:0.019985687 7:0.020723372 +1 1:0.794833 2:0.010638 3:0.030395 5:0.010928391 6:0.0029340029 7:0.01895989 +1 1:0.790837 2:0.011952 3:0.031873 5:0.014342582 7:0.018936451 +1 1:0.790179 2:0.004464 3:0.026786 5:0.011740939 7:0.017285494 +1 1:0.790607 2:0.011742 3:0.029354 5:0.018330774 7:0.019414348 +1 1:0.782609 2:0.007246 3:0.043478 5:0.016332951 7:0.020170555 +1 1:0.695652 2:0.050725 3:0.094203 5:0.12278413 7:0.01877872 +1 1:0.782123 2:0.005587 3:0.027933 5:0.015594949 7:0.016282872 +1 1:0.776224 2:0.020979 3:0.041958 5:0.015430948 7:0.020595256 +1 1:0.784866 2:0.017804 3:0.031157 5:0.020753507 6:0.0027840028 7:0.019495909 +1 1:0.781553 2:0.009709 3:0.029126 5:0.02480879 7:0.017789488 +1 1:0.787736 2:0.018868 3:0.033019 5:0.010600391 6:0.0042660043 7:0.020219744 +1 1:0.743243 2:0.047297 3:0.054054 5:0.01505822 6:0.024243024 7:0.020393866 +1 1:0.759259 2:0.015432 3:0.030864 5:0.032449719 7:0.017295244 +1 1:0.712281 2:0.035088 3:0.049123 5:0.044906296 7:0.014206244 +1 1:0.774359 2:0.005128 3:0.051282 5:0.013552398 7:0.01719825 +1 1:0.75 2:0.02459 3:0.057377 5:0.028595709 6:0.0038370038 7:0.019542183 +1 1:0.761905 2:0.020408 3:0.047619 5:0.033128084 7:0.018666 +1 1:0.715278 2:0.055556 3:0.055556 5:0.052741043 7:0.017953927 +1 1:0.67658 2:0.078067 3:0.04461 5:0.096536609 6:0.017265017 7:0.015753921 +1 1:0.79405 2:0.006865 3:0.020595 5:0.011621666 7:0.017901994 +1 1:0.743961 2:0.024155 3:0.057971 5:0.059353242 7:0.018498878 +1 1:0.754011 2:0.023173 3:0.039216 5:0.036475184 7:0.017770963 +1 1:0.746939 2:0.02449 3:0.034694 5:0.034402815 7:0.016177201 +1 1:0.697183 2:0.056338 3:0.049296 5:0.021730055 7:0.014728616 +1 1:0.743056 2:0.055556 3:0.0625 5:0.014096581 6:0.0068070068 7:0.055978994 +1 1:0.780105 2:0.015707 3:0.031414 5:0.024324244 7:0.019569659 +1 1:0.70922 2:0.06383 3:0.078014 5:0.075149464 7:0.021449573 +1 1:0.731343 2:0.029851 3:0.039801 5:0.027455161 6:0.022098022 7:0.016472518 +1 1:0.797814 2:0.019126 3:0.040984 5:0.015624767 7:0.023840463 +1 1:0.790698 2:0.011628 3:0.03876 5:0.017808954 7:0.019781622 +1 1:0.796875 2:0.005208 3:0.03125 5:0.013701489 7:0.017276421 +1 1:0.726708 2:0.043478 3:0.018634 5:0.054015774 6:0.021738022 7:0.015679445 +1 1:0.739617 2:0.025559 3:0.063898 5:0.066636351 7:0.017435518 +1 1:0.806867 2:0.008584 3:0.04721 5:0.016459678 7:0.023709829 +1 1:0.742857 2:0.028571 3:0.042857 5:0.015527858 6:0.012501013 7:0.020905921 +1 1:0.8 2:0.006667 3:0.04 5:0.014528946 7:0.020853659 +1 1:0.757143 2:0.021429 3:0.057143 5:0.017920773 7:0.01811847 +1 1:0.730469 2:0.015625 3:0.050781 5:0.052591952 7:0.013505146 +1 1:0.739806 2:0.038835 3:0.040777 5:0.0428712 6:0.0086280086 7:0.016469335 +1 1:0.759259 2:0.012346 3:0.04321 5:0.030675533 7:0.018292683 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.770718 2:0.01105 3:0.041436 5:0.0073502005 7:0.017079909 +1 1:0.73125 2:0.025 3:0.0375 5:0.042453744 6:0.0034170034 7:0.016730183 +1 1:0.766129 2:0.008065 3:0.040323 5:0.021178418 7:0.017309207 +1 1:0.760606 2:0.027273 3:0.060606 5:0.028275163 7:0.038968957 +1 1:0.751196 2:0.023923 3:0.019139 5:0.029579712 7:0.014704165 +1 1:0.75 2:0.033333 3:0.075 5:0.025576611 6:0.0051450051 7:0.029623982 +1 1:0.767327 2:0.039604 3:0.029703 5:0.023556424 6:0.018957019 7:0.019107701 +1 1:0.762523 2:0.020408 3:0.033395 5:0.028468982 7:0.017772299 +1 1:0.73743 2:0.022346 3:0.039106 5:0.016862225 7:0.015056549 +1 1:0.747899 2:0.016807 3:0.054622 5:0.033530631 7:0.017088543 +1 1:0.805907 2:0.004219 3:0.025316 5:0.00855784 7:0.022409183 +1 1:0.763407 2:0.012618 3:0.063091 5:0.0070892908 7:0.020235439 +1 1:0.748752 2:0.026622 3:0.03827 5:0.050713402 6:0.0017010017 7:0.017897 +1 1:0.80663 2:0.005525 3:0.016575 7:0.019370701 +1 1:0.770563 2:0.012987 3:0.021645 5:0.024972791 7:0.015758634 +1 1:0.722433 2:0.026616 3:0.064639 5:0.041015013 7:0.016855238 +1 1:0.765281 2:0.01467 3:0.036675 5:0.032188809 7:0.017264 +1 1:0.56 2:0.168889 3:0.115556 5:0.19509341 6:0.028926029 7:0.019674799 +1 1:0.757812 2:0.015625 3:0.0625 5:0.017704591 7:0.020055256 +1 1:0.760465 2:0.02093 3:0.034884 5:0.025054791 7:0.016874646 +1 1:0.763744 2:0.022288 3:0.023774 5:0.053710137 7:0.017604104 8:0.023809524 +1 1:0.770115 2:0.063218 3:0.017241 5:0.025144246 6:0.035412035 7:0.020780768 +1 1:0.726891 2:0.033613 3:0.037815 5:0.054217047 7:0.014091 +1 1:0.749361 2:0.023018 3:0.033248 5:0.022960058 7:0.015189323 +1 1:0.768443 2:0.016393 3:0.030738 5:0.02875971 7:0.016193524 +1 1:0.763636 2:0.020455 3:0.056818 5:0.022318966 6:0.0035940036 7:0.023143018 +1 1:0.725664 2:0.026549 3:0.063717 5:0.055558869 7:0.015929201 +1 1:0.788809 2:0.01083 3:0.036101 5:0.020015505 7:0.02049397 +1 1:0.797834 2:0.00361 3:0.075812 7:0.035550762 +1 1:0.745509 2:0.023952 3:0.032934 5:0.0083938395 7:0.016211482 +1 1:0.770492 2:0.016393 3:0.032787 5:0.032501901 7:0.017193122 +1 1:0.744275 2:0.030534 3:0.015267 5:0.022758785 6:0.0091590092 7:0.015243902 +1 1:0.702899 2:0.028986 3:0.072464 5:0.088478225 7:0.014890421 +1 1:0.763593 2:0.021277 3:0.035461 5:0.027007887 6:0.0081510082 7:0.015914201 +1 1:0.769795 2:0.01173 3:0.032258 5:0.018599138 7:0.017917171 +1 1:0.75 2:0.02451 3:0.026961 5:0.027559525 6:0.0027720028 7:0.016170494 +1 1:0.740157 2:0.019685 3:0.066929 5:0.019642777 7:0.018220665 +1 1:0.753894 2:0.024922 3:0.040498 5:0.024227334 7:0.01753286 +1 1:0.706161 2:0.056872 3:0.085308 5:0.020231688 6:0.0027150027 7:0.063894348 +1 1:0.774194 2:0.021505 3:0.026882 5:0.025509519 6:0.0025650026 7:0.019161421 +1 1:0.679054 2:0.094595 3:0.030405 5:0.029542439 6:0.071334071 7:0.015594098 +1 1:0.77116 2:0.00627 3:0.037618 7:0.015712207 +1 1:0.768519 2:0.018519 3:0.035185 5:0.033642449 7:0.017513549 +1 1:0.735192 2:0.031359 3:0.052265 5:0.067247626 7:0.016486787 +1 1:0.770718 2:0.01105 3:0.041436 5:0.0073502005 7:0.017079909 +1 1:0.772 2:0.012 3:0.044 5:0.018338228 7:0.019829268 +1 1:0.740984 2:0.029508 3:0.059016 5:0.03491718 7:0.017073171 +1 1:0.74359 2:0.025641 3:0.029915 5:0.04022483 7:0.01448822 +1 1:0.69112 2:0.050193 3:0.081081 4:0.0036900369 5:0.027171887 6:0.014580015 7:0.019375646 +1 1:0.705696 2:0.028481 3:0.056962 5:0.042304653 6:0.0068100068 7:0.016999848 +1 1:0.757366 2:0.020797 3:0.055459 5:0.050117037 7:0.018863341 +1 1:0.76412 2:0.023256 3:0.026578 5:0.020172051 6:0.016239016 7:0.014970421 +1 1:0.77264 2:0.019268 3:0.026975 5:0.019918596 7:0.017587762 +1 1:0.778443 2:0.005988 3:0.035928 5:0.016564042 7:0.016430555 +1 1:0.719101 2:0.031461 3:0.049438 4:0.0036900369 5:0.042088471 6:0.0084690085 7:0.01941628 +1 1:0.77265 2:0.02735 3:0.025641 5:0.013149852 6:0.0070560071 7:0.017729829 +1 1:0.780347 2:0.00578 3:0.104046 5:0.0062096522 7:0.042330463 +1 1:0.771277 2:0.010638 3:0.037234 5:0.02807389 7:0.017222366 +1 1:0.748366 2:0.022876 3:0.042484 5:0.035796818 7:0.016598915 +1 1:0.662983 2:0.11326 3:0.038674 5:0.057661056 6:0.076242076 7:0.015243902 +1 1:0.781327 2:0.029484 3:0.044226 5:0.014789856 6:0.011904012 7:0.022652366 +1 1:0.77551 2:0.013605 3:0.034014 5:0.019068776 7:0.016218683 +1 1:0.78481 2:0.018987 3:0.018987 5:0.015758949 6:0.0063420063 7:0.018254091 +1 1:0.707692 2:0.015385 3:0.061538 7:0.013086305 +1 1:0.68 2:0.066667 3:0.066667 5:0.065779077 6:0.022059022 7:0.018428183 +1 1:0.73913 2:0.01087 3:0.086957 5:0.025442428 7:0.019419409 +1 1:0.767123 2:0.020548 3:0.061644 5:0.011524757 7:0.027021384 +1 1:0.767081 2:0.012422 3:0.040373 5:0.020537325 7:0.020621878 +1 1:0.771993 2:0.012567 3:0.021544 5:0.019053867 7:0.017132287 +1 1:0.719486 2:0.03212 3:0.03212 5:0.061231792 7:0.012717396 +1 1:0.755287 2:0.021148 3:0.054381 5:0.045361025 7:0.018163732 +1 1:0.738602 2:0.030395 3:0.048632 5:0.048514305 7:0.017088 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.782258 2:0.008065 3:0.032258 5:0.023220968 7:0.015784817 +1 1:0.72973 2:0.031532 3:0.027027 5:0.015371312 7:0.01332125 +1 1:0.764805 2:0.011844 3:0.047377 5:0.012739851 7:0.030178287 +1 1:0.684211 2:0.022556 3:0.067669 7:0.014624976 +1 1:0.746377 2:0.036232 3:0.043478 5:0.033426267 7:0.01970661 +1 1:0.691057 2:0.073171 3:0.04065 5:0.023004786 6:0.037038037 7:0.016061866 +1 1:0.773994 2:0.021672 3:0.024768 5:0.015893131 6:0.0095940096 7:0.01770747 +1 1:0.698413 2:0.021164 3:0.100529 5:0.0394421 7:0.018292683 +1 1:0.790451 2:0.023873 3:0.02122 5:0.0060307426 6:0.0097080097 7:0.019990945 +1 1:0.784661 2:0.00885 3:0.038348 5:0.014379855 7:0.018652421 +1 1:0.765193 2:0.013812 3:0.041436 5:0.036505002 7:0.017197817 +1 1:0.757979 2:0.021277 3:0.029255 5:0.014953856 7:0.016168268 +1 1:0.740991 2:0.074324 3:0.036036 5:0.048059577 6:0.030948031 7:0.021300262 +1 1:0.707483 2:0.054422 3:0.034014 5:0.066956898 6:0.035928036 7:0.013854323 +1 1:0.758389 2:0.033557 3:0.033557 5:0.016034768 6:0.0064530065 7:0.019029299 +1 1:0.755474 2:0.040146 3:0.040146 5:0.031420989 6:0.0094830095 7:0.021118927 +1 1:0.792683 2:0.018293 3:0.054878 5:0.03362754 7:0.024724866 +1 1:0.78903 2:0.008439 3:0.033755 5:0.017436226 7:0.02199753 +1 1:0.672862 2:0.042751 3:0.10223 5:0.10506463 7:0.016887299 +1 1:0.69863 2:0.041096 3:0.041096 5:0.044108658 7:0.014116268 +1 1:0.725275 2:0.043956 3:0.049451 5:0.064124163 6:0.012903013 7:0.015578933 +1 1:0.732673 2:0.054455 3:0.061881 5:0.057087054 6:0.011487011 7:0.023650689 +1 1:0.707254 2:0.03886 3:0.028497 5:0.054545048 6:0.012195012 7:0.019430049 +1 1:0.781163 2:0.019391 3:0.038781 5:0.023183695 7:0.021721506 +1 1:0.744472 2:0.022113 3:0.041769 5:0.021610782 6:0.0057960058 7:0.015506085 +1 1:0.796296 2:0.018519 3:0.030864 5:0.01360458 7:0.020626317 +1 1:0.729614 2:0.027897 3:0.051502 5:0.040239739 6:0.01012201 7:0.019391817 +1 1:0.76411 2:0.021708 3:0.030391 5:0.020075142 7:0.016386646 +1 1:0.710938 2:0.03125 3:0.070312 5:0.094061694 7:0.015100988 +1 1:0.693252 2:0.042945 3:0.042945 5:0.020425507 7:0.013654049 +1 1:0.774942 2:0.018561 3:0.023202 5:0.04321411 7:0.019523512 8:0.023809524 +1 1:0.761523 2:0.01002 3:0.024048 5:0.013298943 7:0.013698128 +1 1:0.743902 2:0.03252 3:0.03252 5:0.025352974 6:0.02040902 7:0.014574659 +1 1:0.751189 2:0.023772 3:0.026941 5:0.033470994 7:0.015065128 +1 1:0.757396 2:0.023669 3:0.029586 7:0.01785972 +1 1:0.763889 2:0.009259 3:0.032407 5:0.028454072 7:0.014792232 +1 1:0.752232 2:0.024554 3:0.022321 5:0.019791869 7:0.015380006 +1 1:0.783251 2:0.022167 3:0.044335 5:0.020924962 7:0.021401537 +1 1:0.763298 2:0.031915 3:0.045213 5:0.015281857 6:0.0046140046 7:0.031639207 +1 1:0.761905 2:0.022556 3:0.050125 5:0.028431709 7:0.020034841 +1 1:0.727273 2:0.016529 3:0.07438 5:0.020820598 7:0.01804072 +1 1:0.79096 2:0.011299 3:0.045198 5:0.012486395 7:0.020566348 +1 1:0.777551 2:0.008163 3:0.044898 5:0.014148763 7:0.01967397 +1 1:0.711111 2:0.035556 3:0.04 5:0.053054135 7:0.015230354 +1 1:0.770408 2:0.020408 3:0.035714 5:0.026389158 7:0.017577152 +1 1:0.745763 2:0.028249 3:0.045198 5:0.013477852 7:0.019050573 +1 1:0.71464 2:0.032258 3:0.049628 5:0.046881756 7:0.016840165 +1 1:0.740586 2:0.029289 3:0.033473 5:0.013030579 7:0.014593329 +1 1:0.700454 2:0.033283 3:0.054463 5:0.023787515 7:0.014455189 +1 1:0.76875 2:0.00625 3:0.025 5:0.018636411 7:0.015243902 +1 1:0.760331 2:0.041322 3:0.03719 6:0.01994702 7:0.018947793 +1 1:0.782946 2:0.007752 3:0.03876 5:0.019068776 7:0.018481756 +1 1:0.755396 2:0.043165 3:0.079137 5:0.010399117 6:0.0083670084 7:0.031452884 +1 1:0.763285 2:0.012882 3:0.030596 5:0.026672432 7:0.01646636 +1 1:0.713568 2:0.045226 3:0.045226 5:0.072726731 6:0.0097560098 7:0.01884422 +1 1:0.78626 2:0.015267 3:0.10687 5:0.011159483 7:0.031092902 +1 1:0.804487 2:0.00641 3:0.032051 5:0.014200945 7:0.02052064 +1 1:0.717277 2:0.031414 3:0.010471 5:0.044198113 6:0.011859012 7:0.01615375 +1 1:0.746939 2:0.02449 3:0.032653 5:0.034037541 7:0.016351421 +1 1:0.76082 2:0.020501 3:0.034169 5:0.017689681 7:0.01755653 +1 1:0.741627 2:0.023923 3:0.059809 5:0.037116276 6:0.0024900025 7:0.017577896 +1 1:0.743056 2:0.020833 3:0.03125 5:0.022222057 7:0.01420647 +1 1:0.688172 2:0.05914 3:0.05914 5:0.09728952 7:0.020095726 +1 1:0.730964 2:0.015228 3:0.025381 5:0.047179938 7:0.014671287 +1 1:0.741935 2:0.024194 3:0.048387 7:0.01534225 +1 1:0.776031 2:0.015717 3:0.02947 5:0.021118781 7:0.016915043 +1 1:0.74359 2:0.038462 3:0.064103 5:0.041566651 7:0.021028768 +1 1:0.76129 2:0.019355 3:0.032258 5:0.018136955 7:0.016168372 +1 1:0.752066 2:0.016529 3:0.041322 5:0.02258733 7:0.016629713 +1 1:0.738462 2:0.015385 3:0.046154 5:0.028506254 7:0.01635397 +1 1:0.807971 2:0.021739 3:0.039855 5:0.0054716503 6:0.0044010044 7:0.030112232 +1 1:0.753521 2:0.018779 3:0.042254 5:0.041566651 7:0.015401354 +1 1:0.769461 2:0.017964 3:0.032934 5:0.023787515 7:0.017160799 +1 1:0.761111 2:0.022222 3:0.022222 4:0.0036900369 5:0.013574762 6:0.010929011 7:0.018597561 +1 1:0.733888 2:0.04158 3:0.058212 5:0.046240663 6:0.0082710083 7:0.018394098 +1 1:0.734982 2:0.021201 3:0.035336 5:0.05621487 7:0.014285098 +1 1:0.744966 2:0.026846 3:0.033557 7:0.014159439 +1 1:0.737082 2:0.018237 3:0.056231 5:0.036281365 7:0.020942988 +1 1:0.721519 2:0.046414 3:0.033755 5:0.025636247 6:0.023217023 7:0.014960896 +1 1:0.728571 2:0.052381 3:0.1 5:0.026635159 6:0.0030630031 7:0.05688153 +1 1:0.776699 2:0.009709 3:0.026699 5:0.014528946 7:0.015184701 +1 1:0.789157 2:0.024096 3:0.060241 5:0.021774783 7:0.037724067 +1 1:0.704797 2:0.01845 3:0.073801 5:0.05271868 7:0.015907659 +1 1:0.775424 2:0.004237 3:0.016949 5:0.013313852 7:0.014468787 +1 1:0.681818 2:0.051948 3:0.090909 5:0.095366243 7:0.018569848 +1 1:0.757009 2:0.023364 3:0.042056 5:0.046017026 7:0.01846364 +1 1:0.74552 2:0.032258 3:0.043011 5:0.054082865 7:0.018074134 +1 1:0.780488 2:0.00813 3:0.02439 5:0.021730055 7:0.017003768 +1 1:0.738439 2:0.021676 3:0.073699 5:0.052741043 7:0.01868039 +1 1:0.747649 2:0.029781 3:0.021944 5:0.042595381 6:0.012468012 7:0.018397811 +1 1:0.742188 2:0.03125 3:0.042969 5:0.019933505 7:0.017816311 +1 1:0.785714 2:0.007519 3:0.030075 5:0.020395688 7:0.016756829 +1 1:0.766949 2:0.016949 3:0.033898 5:0.034194087 7:0.016897476 +1 1:0.783607 2:0.016393 3:0.022951 5:0.0078869292 7:0.018892445 +1 1:0.763314 2:0.017751 3:0.035503 5:0.033962996 7:0.015839226 +1 1:0.734095 2:0.057096 3:0.047308 5:0.059166878 6:0.00091500092 7:0.03258664 +1 1:0.721925 2:0.02139 3:0.042781 5:0.061992158 7:0.015684098 +1 1:0.705314 2:0.057971 3:0.067633 5:0.060121062 7:0.018263226 +1 1:0.759399 2:0.032581 3:0.042607 5:0.038495371 6:0.012909013 7:0.017757811 +1 1:0.787162 2:0.010135 3:0.033784 5:0.0087516586 7:0.017551085 +1 1:0.765027 2:0.005464 3:0.060109 7:0.018059445 +1 1:0.746269 2:0.014925 3:0.074627 5:0.03106317 7:0.021842012 +1 1:0.746154 2:0.023077 3:0.053846 5:0.051130857 7:0.017096622 +1 1:0.75 2:0.025974 3:0.032468 5:0.037503914 7:0.015738835 +1 1:0.788525 2:0.004918 3:0.019672 5:0.013515125 7:0.016543384 +1 1:0.697715 2:0.040422 3:0.042179 5:0.048283214 6:0.011658012 7:0.016545927 +1 1:0.772358 2:0.018293 3:0.02439 5:0.017294589 6:0.006960007 7:0.016024689 +1 1:0.784588 2:0.003503 3:0.008757 5:0.0057623783 7:0.01380761 +1 1:0.747788 2:0.017699 3:0.053097 5:0.043594293 7:0.016147744 +1 1:0.69403 2:0.044776 3:0.074627 5:0.088217315 7:0.015380415 +1 1:0.725888 2:0.071066 3:0.055838 5:0.044906296 6:0.036144036 7:0.020552183 +1 1:0.758294 2:0.014218 3:0.037915 5:0.031801172 7:0.015807421 +1 1:0.747423 2:0.036082 3:0.06701 5:0.081530571 7:0.020115665 8:0.023809524 +1 1:0.781395 2:0.009302 3:0.04186 5:0.02070878 7:0.020419738 +1 1:0.741333 2:0.016 3:0.069333 5:0.016586406 7:0.029235774 +1 1:0.759644 2:0.014837 3:0.029674 5:0.025971702 7:0.015578634 +1 1:0.780528 2:0.013201 3:0.031353 5:0.017242408 7:0.017397165 +1 1:0.78821 2:0.008734 3:0.019651 5:0.012396941 7:0.016016079 +1 1:0.664688 2:0.083086 3:0.065282 5:0.11272047 6:0.021168021 7:0.017948902 +1 1:0.70625 2:0.0375 3:0.05625 5:0.079726567 7:0.014253049 +1 1:0.780488 2:0.02439 3:0.03252 5:0.027074978 6:0.0036330036 7:0.020473921 +1 1:0.771972 2:0.009501 3:0.054632 5:0.016839861 7:0.01923411 +1 1:0.760479 2:0.011976 3:0.047904 5:0.0323379 7:0.016832189 +1 1:0.776923 2:0.010769 3:0.04 4:0.0036900369 5:0.020746053 7:0.02022514 +1 1:0.721925 2:0.02139 3:0.042781 5:0.061992158 7:0.015684098 +1 1:0.756447 2:0.025788 3:0.034384 5:0.039568828 6:0.0031860032 7:0.016458171 +1 1:0.748344 2:0.013245 3:0.066225 5:0.033128084 7:0.018171537 +1 1:0.693989 2:0.081967 3:0.04918 5:0.051481222 6:0.029007029 7:0.024123683 +1 1:0.724211 2:0.037895 3:0.056842 5:0.078966201 7:0.018177152 +1 1:0.802703 2:0.002703 3:0.027027 5:0.0065823804 7:0.018655238 +1 1:0.64 2:0.12 3:0.086667 5:0.14683256 7:0.026829268 +1 1:0.732394 2:0.018779 3:0.075117 5:0.023966425 7:0.017806024 +1 1:0.778947 2:0.008421 3:0.037895 5:0.022035692 7:0.017368421 +1 1:0.798507 2:0.007463 3:0.044776 5:0.015214766 7:0.022297049 +1 1:0.729167 2:0.015625 3:0.057292 5:0.032911902 7:0.014386433 +1 1:0.792453 2:0.028302 3:0.040094 5:0.021595873 6:0.006951007 7:0.024821677 +1 1:0.767347 2:0.012245 3:0.028571 5:0.025531883 7:0.014534591 +1 1:0.762763 2:0.033033 3:0.054054 5:0.052867771 6:0.0026610027 7:0.020654799 +1 1:0.765464 2:0.015464 3:0.043814 5:0.013515125 6:0.0054390054 7:0.017334043 +1 1:0.448476 2:0.08418 3:0.169811 4:0.011070111 5:0.16875643 7:0.020328152 +1 1:0.75942 2:0.008696 3:0.042029 5:0.0079167474 7:0.016648994 +1 1:0.759804 2:0.019608 3:0.029412 5:0.027708616 7:0.016080823 +1 1:0.736842 2:0.033835 3:0.052632 5:0.048283214 7:0.017696683 +1 1:0.728643 2:0.035176 3:0.070352 5:0.07916002 7:0.017312171 +1 1:0.732044 2:0.030387 3:0.069061 5:0.072890731 7:0.018949604 +1 1:0.72332 2:0.019763 3:0.063241 5:0.0071563819 7:0.025113274 +1 1:0.727273 2:0.038961 3:0.038961 5:0.061775975 7:0.014333226 +1 1:0.746454 2:0.033688 3:0.035461 5:0.04123865 6:0.0073770074 7:0.017589951 +1 1:0.68 2:0.074286 3:0.051429 5:0.032062082 6:0.038709039 7:0.016202091 +1 1:0.760791 2:0.021583 3:0.039568 5:0.033880995 7:0.016888927 +1 1:0.743243 2:0.022523 3:0.033033 5:0.035327181 7:0.015454476 +1 1:0.762712 2:0.021186 3:0.033898 5:0.022520239 7:0.017104177 +1 1:0.789969 2:0.017241 3:0.029781 5:0.014596037 6:0.0058740059 7:0.019525573 +1 1:0.759494 2:0.018987 3:0.029536 5:0.025099518 7:0.015282494 +1 1:0.736686 2:0.023669 3:0.04142 5:0.060821791 7:0.015478421 +1 1:0.717762 2:0.017032 3:0.080292 5:0.041514469 7:0.018648744 +1 1:0.766667 2:0.009524 3:0.057143 5:0.019955869 7:0.021689896 +1 1:0.783626 2:0.011696 3:0.023392 5:0.015184948 7:0.017508201 +1 1:0.773973 2:0.015982 3:0.045662 5:0.036929912 7:0.019670896 +1 1:0.786585 2:0.012195 3:0.042683 5:0.029117529 7:0.019036287 +1 1:0.752066 2:0.024793 3:0.11157 5:0.015572585 7:0.060295305 +1 1:0.786441 2:0.008475 3:0.030508 5:0.01626586 7:0.01894378 +1 1:0.781671 2:0.010782 3:0.024259 5:0.014834583 7:0.016517652 +1 1:0.775926 2:0.016667 3:0.038889 5:0.023504242 7:0.017908762 +1 1:0.721068 2:0.026706 3:0.04451 4:0.0036900369 5:0.05082522 7:0.015922415 +1 1:0.801242 2:0.006211 3:0.031056 5:0.014282945 7:0.019769732 +1 1:0.763285 2:0.012882 3:0.030596 5:0.026672432 7:0.01646636 +1 1:0.728507 2:0.031674 3:0.058824 5:0.074918373 7:0.016471689 +1 1:0.764331 2:0.019108 3:0.057325 5:0.040664649 7:0.021360884 +1 1:0.731278 2:0.022026 3:0.035242 5:0.056908145 7:0.017594287 +1 1:0.811069 2:0.005725 3:0.028626 5:0.0082894756 7:0.020922549 +1 1:0.691729 2:0.052632 3:0.097744 5:0.12758487 7:0.018751146 +1 1:0.768041 2:0.010309 3:0.046392 5:0.027358251 7:0.017129744 +1 1:0.67086 2:0.081761 3:0.039832 5:0.097147884 6:0.024690025 7:0.018637829 +1 1:0.790378 2:0.006873 3:0.027491 5:0.018204046 7:0.017161177 +1 1:0.770492 2:0.023419 3:0.023419 5:0.018546956 7:0.017221683 +1 1:0.730337 2:0.042135 3:0.044944 5:0.058883604 6:0.0023700024 7:0.021684024 +1 1:0.773723 2:0.014599 3:0.036496 5:0.020477688 7:0.016200817 +1 1:0.761773 2:0.01662 3:0.030471 5:0.015878222 7:0.015860415 +1 1:0.793939 2:0.006061 3:0.036364 7:0.019438287 +1 1:0.759615 2:0.014423 3:0.043269 5:0.039300464 7:0.016680348 +1 1:0.706195 2:0.031858 3:0.070796 5:0.093964785 7:0.015411183 +1 1:0.758929 2:0.022321 3:0.040179 5:0.034454997 7:0.017666591 +1 1:0.807692 2:0.007692 3:0.076923 7:0.068011256 +1 1:0.782946 2:0.007752 3:0.03876 5:0.019068776 7:0.018481756 +1 1:0.72973 2:0.023166 3:0.034749 5:0.012963488 7:0.013537055 +1 1:0.73913 2:0.01087 3:0.086957 5:0.025442428 7:0.019419409 +1 1:0.702128 2:0.042553 3:0.069149 5:0.044839205 7:0.043137 +1 1:0.764172 2:0.020408 3:0.029478 5:0.019672596 7:0.015720921 +1 1:0.774704 2:0.013834 3:0.027668 5:0.01933714 6:0.0038910039 7:0.018581896 +1 1:0.725694 2:0.024306 3:0.041667 5:0.010801664 7:0.014608738 +1 1:0.670391 2:0.050279 3:0.072626 5:0.038525189 7:0.013182994 +1 1:0.716535 2:0.047244 3:0.031496 5:0.050541947 6:0.02034002 7:0.014163628 +1 1:0.796491 2:0.014035 3:0.045614 5:0.020977144 7:0.022807018 +1 1:0.752 2:0.008 3:0.032 5:0.025181519 7:0.014439024 +1 1:0.76652 2:0.017621 3:0.035242 5:0.037459186 7:0.021381756 +1 1:0.752137 2:0.045584 3:0.031339 5:0.048052122 6:0.022098022 7:0.018865957 +1 1:0.731844 2:0.011173 3:0.117318 5:0.011159483 7:0.02275514 +1 1:0.770609 2:0.007168 3:0.032258 5:0.0090274775 7:0.018052274 +1 1:0.764877 2:0.020319 3:0.030479 5:0.027134615 7:0.017018305 +1 1:0.776271 2:0.013559 3:0.030508 5:0.02823789 7:0.016370402 +1 1:0.709265 2:0.028754 3:0.025559 5:0.0091840234 6:0.014778015 7:0.015818591 +1 1:0.756522 2:0.02029 3:0.017391 5:0.01745859 7:0.015093671 +1 1:0.775735 2:0.011029 3:0.022059 5:0.011025301 7:0.015154232 +1 1:0.737991 2:0.030568 3:0.034934 5:0.025099518 7:0.015816378 +1 1:0.770492 2:0.010246 3:0.038934 5:0.020910053 7:0.017817872 +1 1:0.677966 2:0.022599 3:0.045198 4:0.0036900369 5:0.050370492 7:0.015295579 +1 1:0.717791 2:0.067485 3:0.030675 6:0.047835048 7:0.016422268 +1 1:0.769697 2:0.018182 3:0.054545 5:0.039650828 7:0.020842573 +1 1:0.76815 2:0.009368 3:0.042155 5:0.024540426 7:0.017350201 +1 1:0.751244 2:0.014925 3:0.049751 5:0.028834255 7:0.015683774 +1 1:0.705455 2:0.049091 3:0.078182 4:0.0036900369 5:0.10020426 7:0.018968957 +1 1:0.775934 2:0.010373 3:0.03527 5:0.015639676 7:0.018090274 +1 1:0.75 2:0.007353 3:0.066176 5:0.020090051 7:0.016633787 +1 1:0.788671 2:0.026144 3:0.030501 5:0.0090498412 6:0.0036420036 7:0.021892768 +1 1:0.772222 2:0.027778 3:0.061111 5:0.035110998 7:0.021578591 +1 1:0.708861 2:0.037975 3:0.044304 5:0.061269065 7:0.01408614 +1 1:0.746753 2:0.028139 3:0.034632 5:0.017779136 7:0.016603317 +1 1:0.777439 2:0.018293 3:0.04878 5:0.031219716 7:0.02219661 +1 1:0.746479 2:0.032864 3:0.065728 5:0.053016862 7:0.020124811 +1 1:0.789655 2:0.02069 3:0.043103 5:0.026478613 7:0.02367536 +1 1:0.751055 2:0.023207 3:0.063291 5:0.027119705 6:0.0031200031 7:0.024750439 +1 1:0.763158 2:0.041353 3:0.090226 6:0.001953002 7:0.17593527 +1 1:0.710623 2:0.054945 3:0.03663 5:0.076290012 6:0.017544018 7:0.015277409 +1 1:0.747387 2:0.022648 3:0.052265 5:0.050884857 7:0.01867511 +1 1:0.777778 2:0.015873 3:0.063492 5:0.03516318 7:0.020518774 +1 1:0.660934 2:0.041769 3:0.036855 5:0.10064407 7:0.016644695 +1 1:0.799065 2:0.023364 3:0.014019 6:0.0085350085 7:0.020030774 +1 1:0.767828 2:0.0199 3:0.034826 5:0.035893728 7:0.018899409 +1 1:0.737475 2:0.032064 3:0.03006 5:0.030779897 7:0.01479789 +1 1:0.720365 2:0.036474 3:0.054711 5:0.053180863 7:0.015586774 +1 1:0.771208 2:0.015424 3:0.030848 5:0.020671507 7:0.016960311 +1 1:0.772512 2:0.014218 3:0.056872 5:0.012098758 7:0.017801409 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.596078 2:0.094118 3:0.129412 5:0.079816021 7:0.022333811 +1 1:0.743119 2:0.036697 3:0.036697 5:0.038279188 6:0.0077010077 7:0.021788994 +1 1:0.764423 2:0.014423 3:0.048077 5:0.036013001 7:0.018204738 +1 1:0.75 2:0.017857 3:0.05 5:0.020090051 7:0.016158537 +1 1:0.768707 2:0.020408 3:0.020408 5:0.018591684 7:0.016633482 +1 1:0.75265 2:0.028269 3:0.042403 5:0.018159319 6:0.010962011 7:0.01768939 +1 1:0.720117 2:0.027697 3:0.053936 5:0.0085652945 7:0.015466116 +1 1:0.750605 2:0.014528 3:0.050847 7:0.015959957 +1 1:0.773756 2:0.00905 3:0.029412 5:0.018792957 7:0.016416512 +1 1:0.775915 2:0.015244 3:0.035061 5:0.02626243 7:0.018469287 +1 1:0.625 2:0.083333 3:0.141667 5:0.074545644 7:0.020325201 +1 1:0.75 2:0.016129 3:0.040323 5:0.046591028 7:0.01573564 +1 1:0.639053 2:0.106509 3:0.035503 5:0.12346995 6:0.043479043 7:0.017426756 +1 1:0.775591 2:0.015748 3:0.017717 5:0.01669077 7:0.016084116 +1 1:0.753065 2:0.021016 3:0.035026 5:0.019247685 7:0.016541372 +1 1:0.73125 2:0.025 3:0.05 5:0.029385893 7:0.014500762 +1 1:0.746032 2:0.015873 3:0.039683 5:0.025613883 7:0.014082463 +1 1:0.757282 2:0.009709 3:0.121359 5:0.0084534761 7:0.02610703 +1 1:0.752336 2:0.023364 3:0.042056 5:0.026478613 7:0.016041713 +1 1:0.729981 2:0.031657 3:0.040968 5:0.036564639 6:0.0063060063 7:0.01620339 +1 1:0.773286 2:0.017575 3:0.02812 5:0.022863149 7:0.01746753 +1 1:0.716484 2:0.032967 3:0.076923 5:0.070072906 7:0.018533909 +1 1:0.731861 2:0.033123 3:0.036278 5:0.027358251 6:0.011010011 7:0.01572478 +1 1:0.77439 2:0.012195 3:0.018293 5:0.017831318 7:0.015541341 +1 1:0.764007 2:0.016978 3:0.039049 4:0.0073800738 5:0.040537921 7:0.017133213 +1 1:0.777778 2:0.009259 3:0.018519 7:0.016467177 +1 1:0.795322 2:0.005848 3:0.038012 5:0.013045488 7:0.020378689 +1 1:0.779043 2:0.015945 3:0.052392 5:0.025576611 7:0.024293018 +1 1:0.770787 2:0.01573 3:0.035955 5:0.03088426 7:0.01653878 +1 1:0.74026 2:0.024531 3:0.030303 5:0.045286479 7:0.014482805 +1 1:0.681818 2:0.068182 3:0.106061 5:0.044026658 7:0.023466372 +1 1:0.783088 2:0.036765 3:0.007353 5:0.0088709317 6:0.021429021 7:0.018830701 +1 1:0.74477 2:0.020921 3:0.046025 5:0.023183695 7:0.016404738 +1 1:0.787162 2:0.010135 3:0.033784 5:0.0087516586 7:0.017551085 +1 1:0.732719 2:0.046083 3:0.029954 5:0.09918298 7:0.020062945 8:0.023809524 +1 1:0.795786 2:0.006483 3:0.02269 5:0.0085205671 7:0.017294543 +1 1:0.69863 2:0.054795 3:0.047945 5:0.018971866 6:0.022902023 7:0.016413299 +1 1:0.761194 2:0.014925 3:0.052239 5:0.02020187 7:0.016791043 +1 1:0.747826 2:0.028986 3:0.046377 5:0.0082372937 6:0.013260013 7:0.015995049 +1 1:0.763393 2:0.053571 3:0.035714 5:0.044421749 6:0.017877018 7:0.022838634 +1 1:0.77561 2:0.029268 3:0.063415 5:0.028342254 7:0.023468171 +1 1:0.747253 2:0.016484 3:0.043956 5:0.032203718 7:0.015511927 +1 1:0.779592 2:0.020408 3:0.044898 5:0.03380645 7:0.02195122 +1 1:0.737024 2:0.020761 3:0.031142 5:0.020649143 7:0.015233354 +1 1:0.768293 2:0.027439 3:0.027439 5:0.023891879 6:0.0032040032 7:0.017400354 +1 1:0.770833 2:0.013021 3:0.036458 5:0.034671179 7:0.017069994 +1 1:0.790146 2:0.020073 3:0.020073 5:0.01909114 6:0.011523012 7:0.017380274 +1 1:0.727848 2:0.031646 3:0.037975 5:0.041879743 7:0.013738811 +1 1:0.756098 2:0.009756 3:0.053659 5:0.023258241 7:0.01906603 +1 1:0.740558 2:0.047619 3:0.054187 5:0.069059085 6:0.0058500059 7:0.020535463 +1 1:0.790514 2:0.007905 3:0.039526 5:0.019284958 7:0.018630098 +1 1:0.801242 2:0.006211 3:0.031056 5:0.014282945 7:0.019769732 +1 1:0.780142 2:0.028369 3:0.028369 5:0.016459678 6:0.0066240066 7:0.019590037 +1 1:0.768212 2:0.021523 3:0.048013 5:0.031771354 6:0.0015990016 7:0.018948878 +1 1:0.783654 2:0.004808 3:0.019231 7:0.016826921 +1 1:0.777778 2:0.019324 3:0.048309 5:0.039129009 7:0.022446091 +1 1:0.772994 2:0.007828 3:0.027397 5:0.016444769 7:0.016228341 +1 1:0.764275 2:0.013177 3:0.04246 5:0.028267708 7:0.016480378 +1 1:0.711268 2:0.014085 3:0.070423 7:0.013483341 +1 1:0.734597 2:0.037915 3:0.052133 5:0.035670091 7:0.018119293 +1 1:0.784024 2:0.023669 3:0.023669 5:0.02002296 6:0.0080580081 7:0.020150817 +1 1:0.77551 2:0.020408 3:0.040816 5:0.03320263 7:0.018624524 +1 1:0.741935 2:0.048387 3:0.048387 5:0.046449391 6:0.014019014 7:0.021046421 +1 1:0.739703 2:0.031301 3:0.051071 5:0.016571497 6:0.0033360033 7:0.018071683 +1 1:0.733333 2:0.014286 3:0.07619 5:0.022796058 7:0.018989549 +1 1:0.711111 2:0.011111 3:0.061111 5:0.03842828 7:0.013143628 +1 1:0.688073 2:0.039755 3:0.094801 5:0.068321083 7:0.018311329 +1 1:0.771605 2:0.012346 3:0.049383 5:0.01505822 7:0.018631439 +1 1:0.726027 2:0.027397 3:0.054795 5:0.020313688 7:0.015327433 +1 1:0.736041 2:0.050761 3:0.040609 5:0.034782998 6:0.013998014 7:0.019902189 +1 1:0.780347 2:0.034682 3:0.034682 5:0.012784578 6:0.015438015 7:0.020548427 +1 1:0.739837 2:0.01084 3:0.04336 5:0.014879311 7:0.016557604 +1 1:0.816667 2:0.008333 3:0.058333 5:0.0084162032 7:0.045020323 +1 1:0.786982 2:0.011834 3:0.029586 5:0.016526769 7:0.016272189 +1 1:0.762346 2:0.018519 3:0.046296 5:0.029378438 7:0.019101927 +1 1:0.598485 2:0.189394 3:0.022727 4:0.0036900369 5:0.05467923 6:0.13203013 7:0.018893201 +1 1:0.76699 2:0.004854 3:0.043689 5:0.014446946 7:0.0152735 +1 1:0.718841 2:0.046377 3:0.046377 5:0.056841054 6:0.0098040098 7:0.016224817 +1 1:0.756098 2:0.012195 3:0.04878 5:0.018136955 7:0.015281085 +1 1:0.758065 2:0.010753 3:0.064516 5:0.012963488 7:0.018849988 +1 1:0.779487 2:0.005128 3:0.041026 7:0.017636024 +1 1:0.8 2:0.013043 3:0.013043 7:0.019777305 +1 1:0.779468 2:0.007605 3:0.022814 5:0.021767328 7:0.015881482 +1 1:0.721763 2:0.060606 3:0.057851 5:0.036072637 6:0.026613027 7:0.020829134 +1 1:0.788618 2:0.012195 3:0.03252 5:0.01677277 7:0.022035494 +1 1:0.77551 2:0.010204 3:0.022959 5:0.022318966 6:0.002994003 7:0.015586116 +1 1:0.756966 2:0.020124 3:0.024768 5:0.004569648 7:0.015385488 8:0.047619048 +1 1:0.783654 2:0.004808 3:0.019231 7:0.016826921 +1 1:0.740458 2:0.030534 3:0.038168 5:0.020589507 7:0.01684975 +1 1:0.78836 2:0.007937 3:0.039683 5:0.019277504 7:0.018712091 +1 1:0.779043 2:0.015945 3:0.052392 5:0.025576611 7:0.024293018 +1 1:0.806084 2:0.003802 3:0.019011 7:0.019614207 +1 1:0.773994 2:0.021672 3:0.024768 5:0.015893131 6:0.0095940096 7:0.01770747 +1 1:0.759494 2:0.014467 3:0.025316 5:0.0053151044 7:0.015469945 +1 1:0.774194 2:0.008065 3:0.024194 5:0.023742788 7:0.015440598 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.752711 2:0.019523 3:0.043384 5:0.029862985 7:0.016507061 +1 1:0.624114 2:0.113475 3:0.070922 5:0.070326361 6:0.056604057 7:0.018335927 +1 1:0.786585 2:0.012195 3:0.02439 5:0.016549133 7:0.016749701 +1 1:0.716814 2:0.029499 3:0.067847 5:0.083476212 7:0.016062305 +1 1:0.721311 2:0.02459 3:0.065574 5:0.024279516 7:0.01534386 +1 1:0.756579 2:0.019737 3:0.059211 5:0.016824952 7:0.017771183 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.718254 2:0.041667 3:0.041667 5:0.066807806 6:0.008961009 7:0.016199671 +1 1:0.733444 2:0.05298 3:0.023179 5:0.044265204 6:0.014253014 7:0.017000488 +1 1:0.737154 2:0.025692 3:0.037549 5:0.040545376 7:0.015509012 +1 1:0.730769 2:0.064103 3:0.064103 5:0.047709212 6:0.019200019 7:0.024429329 +1 1:0.773554 2:0.006612 3:0.036364 5:0.013835672 7:0.016287037 +1 1:0.745763 2:0.020716 3:0.037665 4:0.0036900369 5:0.039896829 7:0.015019982 +1 1:0.741497 2:0.034014 3:0.07483 5:0.042677381 7:0.021735524 +1 1:0.708763 2:0.059278 3:0.041237 5:0.043773202 6:0.027684028 7:0.018732713 +1 1:0.747573 2:0.019417 3:0.05178 5:0.054149956 7:0.016299628 +1 1:0.789744 2:0.011966 3:0.041026 5:0.026978069 7:0.020158433 +1 1:0.769231 2:0.027972 3:0.041958 5:0.030675533 7:0.020723177 +1 1:0.643836 2:0.136986 3:0.075342 5:0.091407869 6:0.02043602 7:0.03065486 +1 1:0.740741 2:0.014815 3:0.037037 7:0.014408311 +1 1:0.787709 2:0.005587 3:0.027933 5:0.015028402 7:0.016896037 +1 1:0.756677 2:0.008902 3:0.032641 5:0.021506418 7:0.015678152 +1 1:0.792517 2:0.013605 3:0.027211 5:0.0081925663 7:0.018873402 +1 1:0.734146 2:0.053659 3:0.041463 5:0.06024779 6:0.017634018 7:0.020240927 +1 1:0.781003 2:0.007916 3:0.026385 5:0.021610782 7:0.016651652 +1 1:0.747573 2:0.019417 3:0.05178 5:0.054149956 7:0.016299628 +1 1:0.762887 2:0.015464 3:0.030928 5:0.015430948 7:0.015181043 +1 1:0.774336 2:0.015487 3:0.035398 4:0.0073800738 5:0.02549461 6:0.0020520021 7:0.01972264 +1 1:0.71746 2:0.050794 3:0.019048 5:0.049826309 6:0.012033012 7:0.014479287 +1 1:0.710383 2:0.038251 3:0.071038 5:0.091467506 7:0.016293482 +1 1:0.751724 2:0.02069 3:0.034483 7:0.014802354 +1 1:0.509677 2:0.277419 3:0.025806 4:0.0036900369 5:0.044459022 6:0.1968182 7:0.019787567 +1 1:0.751304 2:0.027826 3:0.052174 5:0.051876314 6:0.0016050016 7:0.019809122 +1 1:0.735385 2:0.035385 3:0.032308 5:0.038823372 6:0.01041601 7:0.016210134 +1 1:0.736749 2:0.026502 3:0.04417 5:0.034604088 6:0.007959008 7:0.016245799 +1 1:0.776398 2:0.006211 3:0.043478 5:0.015863313 7:0.017800335 +1 1:0.743649 2:0.020785 3:0.032333 5:0.037951188 7:0.019362927 +1 1:0.798246 2:0.013158 3:0.026316 5:0.0095120242 7:0.020967049 +1 1:0.777778 2:0.01897 3:0.02981 5:0.020686416 6:0.0055500056 7:0.017863043 +1 1:0.74 2:0.026667 3:0.076667 5:0.046158663 7:0.019695122 +1 1:0.772959 2:0.012755 3:0.030612 5:0.028133526 7:0.016488305 +1 1:0.751142 2:0.043379 3:0.02968 5:0.012188213 6:0.026982027 7:0.017025841 +1 1:0.744 2:0.04 3:0.048 5:0.041879743 7:0.017365854 +1 1:0.755869 2:0.00939 3:0.042254 5:0.013805853 7:0.015458604 +1 1:0.759777 2:0.022346 3:0.022346 5:0.015997495 7:0.015874098 +1 1:0.766784 2:0.017668 3:0.045936 5:0.033538085 7:0.01915453 +1 1:0.749141 2:0.020619 3:0.044674 5:0.019903687 7:0.015694409 +1 1:0.770492 2:0.021858 3:0.027322 5:0.015304221 6:0.012321012 7:0.016226841 +1 1:0.75945 2:0.020619 3:0.027491 5:0.0086696584 7:0.018020287 +1 1:0.784091 2:0.017045 3:0.039773 5:0.023556424 7:0.021930433 +1 1:0.766667 2:0.013333 3:0.033333 7:0.015081299 +1 1:0.780488 2:0.01897 3:0.0271 5:0.027082433 6:0.0081750082 7:0.018193537 +1 1:0.747525 2:0.019802 3:0.049505 5:0.025442428 7:0.017688963 +1 1:0.796009 2:0.013304 3:0.019956 5:0.010421481 6:0.0062880063 7:0.01934725 +1 1:0.748744 2:0.022613 3:0.035176 5:0.027581888 7:0.016561463 +1 1:0.786942 2:0.013746 3:0.034364 5:0.023712969 7:0.019759451 +1 1:0.739884 2:0.034682 3:0.046243 5:0.0463003 7:0.022698433 +1 1:0.783784 2:0.006757 3:0.040541 5:0.016824952 7:0.018251482 +1 1:0.762376 2:0.019802 3:0.029703 5:0.014148763 7:0.015907994 +1 1:0.779851 2:0.009328 3:0.027985 5:0.019829141 7:0.017109573 +1 1:0.763033 2:0.014218 3:0.047393 5:0.023705515 7:0.018177091 +1 1:0.751678 2:0.033557 3:0.036913 5:0.042595381 6:0.0034290034 7:0.017903915 +1 1:0.794521 2:0.010959 3:0.016438 5:0.006656926 6:0.0026790027 7:0.018710323 +1 1:0.755906 2:0.015748 3:0.03937 5:0.025352974 7:0.014115616 +1 1:0.784024 2:0.005917 3:0.026627 5:0.015945313 7:0.016867512 +1 1:0.71371 2:0.024194 3:0.08871 5:0.0096909338 7:0.037839299 +1 1:0.755556 2:0.005556 3:0.05 5:0.015565131 7:0.016226287 +1 1:0.79084 2:0.006107 3:0.045802 5:0.0064705619 7:0.021439213 +1 1:0.734737 2:0.042105 3:0.04 5:0.048879579 6:0.0098370098 7:0.019576378 +1 1:0.792829 2:0.011952 3:0.035857 5:0.018591684 7:0.019483043 +1 1:0.776831 2:0.011925 3:0.025554 5:0.022699149 6:0.0018270018 7:0.017056549 +1 1:0.720497 2:0.037267 3:0.062112 5:0.055767596 7:0.015187091 +1 1:0.742857 2:0.028571 3:0.042857 5:0.015527858 6:0.012501013 7:0.020905921 +1 1:0.512397 2:0.206612 3:0.132231 6:0.027816028 7:0.10869785 +1 1:0.769737 2:0.019737 3:0.026316 5:0.016564042 7:0.018051988 +1 1:0.745763 2:0.028249 3:0.045198 5:0.013477852 7:0.019050573 +1 1:0.760116 2:0.014451 3:0.026012 5:0.017316953 7:0.015173409 +1 1:0.77957 2:0.016129 3:0.032258 5:0.026389158 7:0.018522159 +1 1:0.779412 2:0.009804 3:0.02451 5:0.014394764 7:0.015483024 +1 1:0.772 2:0.01 3:0.03 5:0.023668242 7:0.015365854 +1 1:0.75431 2:0.025862 3:0.025862 5:0.034589179 6:0.006960007 7:0.016991695 +1 1:0.75 2:0.02381 3:0.077381 5:0.030869351 7:0.035060976 +1 1:0.764706 2:0.02521 3:0.05042 5:0.019314776 7:0.01977864 +1 1:0.771523 2:0.023179 3:0.033113 5:0.015430948 7:0.019504116 +1 1:0.73262 2:0.026738 3:0.032086 5:0.036721184 7:0.013238555 +1 1:0.73494 2:0.012048 3:0.084337 5:0.029288984 7:0.018696738 +1 1:0.810458 2:0.026144 3:0.052288 5:0.0089380228 7:0.033237683 +1 1:0.730693 2:0.033663 3:0.033663 5:0.023780061 7:0.015141268 +1 1:0.718841 2:0.046377 3:0.046377 5:0.056841054 6:0.0098040098 7:0.016224817 +1 1:0.705882 2:0.038062 3:0.055363 5:0.088008588 7:0.017870707 +1 1:0.755889 2:0.047109 3:0.029979 5:0.028729891 6:0.025047025 7:0.020329555 +1 1:0.769697 2:0.006061 3:0.030303 5:0.018919685 7:0.014560238 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.705882 2:0.042017 3:0.084034 5:0.021923874 7:0.017421604 +1 1:0.74613 2:0.037152 3:0.03096 5:0.02627734 6:0.021153021 7:0.016065091 +1 1:0.743295 2:0.034483 3:0.019157 5:0.023370059 7:0.014905146 +1 1:0.746032 2:0.02381 3:0.039683 5:0.048723033 7:0.01480836 +1 1:0.475806 2:0.064516 3:0.120968 5:0.13636635 6:0.0091470091 7:0.01612903 +1 1:0.805907 2:0.004219 3:0.025316 5:0.00855784 7:0.022409183 +1 1:0.763636 2:0.020455 3:0.056818 5:0.022318966 6:0.0035940036 7:0.023143018 +1 1:0.760125 2:0.028037 3:0.040498 4:0.0036900369 5:0.045487752 7:0.024903122 +1 1:0.757009 2:0.018692 3:0.028037 5:0.027559525 7:0.01541486 +1 1:0.71097 2:0.067511 3:0.044304 5:0.080039658 6:0.021474021 7:0.017971079 +1 1:0.774059 2:0.029289 3:0.020921 5:0.01104021 6:0.013332013 7:0.017221146 +1 1:0.789116 2:0.013605 3:0.054422 5:0.012441668 7:0.024846524 +1 1:0.719486 2:0.03212 3:0.03212 5:0.061231792 7:0.012717396 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.777439 2:0.015244 3:0.039634 5:0.023370059 7:0.01779075 +1 1:0.76259 2:0.014388 3:0.057554 5:0.031994991 7:0.020442183 +1 1:0.753333 2:0.03 3:0.043333 5:0.016221132 6:0.0097920098 7:0.01867886 +1 1:0.765152 2:0.037879 3:0.045455 5:0.034037541 6:0.0068490068 7:0.020232817 +1 1:0.647541 2:0.139344 3:0.02459 4:0.0036900369 5:0.057489601 6:0.092544093 7:0.01944222 +1 1:0.773196 2:0.014433 3:0.039175 5:0.031391171 7:0.017915512 +1 1:0.777379 2:0.016158 3:0.028725 5:0.017674772 7:0.018467835 +1 1:0.759657 2:0.021459 3:0.030043 5:0.03483518 7:0.016801006 +1 1:0.759336 2:0.012448 3:0.041494 5:0.022520239 7:0.016749317 +1 1:0.786555 2:0.010084 3:0.033613 5:0.020567143 7:0.018569378 +1 1:0.730769 2:0.046154 3:0.038462 5:0.058853786 7:0.01782364 +1 1:0.764368 2:0.017241 3:0.051724 5:0.041566651 7:0.018853378 +1 1:0.753199 2:0.02011 3:0.023766 5:0.01737659 7:0.014346549 +1 1:0.689441 2:0.024845 3:0.111801 4:0.0073800738 5:0.031584989 7:0.017876079 +1 1:0.73 2:0.03 3:0.055 5:0.0463003 6:0.012423012 7:0.01472561 +1 1:0.757638 2:0.020367 3:0.032587 5:0.036721184 7:0.017646915 +1 1:0.651568 2:0.010453 3:0.069686 5:0.011755848 7:0.013469872 +1 1:0.74188 2:0.041026 3:0.032479 4:0.018450185 5:0.019903687 6:0.032043032 7:0.015613927 +1 1:0.707736 2:0.068768 3:0.031519 5:0.019948414 6:0.04014304 7:0.019585573 +1 1:0.739645 2:0.017751 3:0.04142 5:0.024667154 7:0.014540335 +1 1:0.751256 2:0.025126 3:0.035176 5:0.033098266 7:0.01725089 +1 1:0.740506 2:0.028481 3:0.056962 5:0.0080882024 6:0.0065070065 7:0.017790988 +1 1:0.742038 2:0.035032 3:0.066879 5:0.062178522 7:0.020953085 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.738693 2:0.027638 3:0.070352 5:0.062223249 7:0.018353963 +1 1:0.777778 2:0.019608 3:0.045752 5:0.032554083 7:0.018252829 +1 1:0.714801 2:0.028881 3:0.057762 5:0.054015774 7:0.015188872 +1 1:0.725275 2:0.032967 3:0.045788 5:0.039233373 7:0.01485303 +1 1:0.636364 2:0.082645 3:0.115702 5:0.1577684 7:0.019048579 +1 1:0.770764 2:0.016611 3:0.023256 5:0.023347696 7:0.019406854 +1 1:0.720222 2:0.036011 3:0.041551 5:0.032874629 7:0.015319909 +1 1:0.769042 2:0.012285 3:0.036855 5:0.032158991 7:0.017363817 +1 1:0.791165 2:0.02008 3:0.036145 5:0.014760038 6:0.002970003 7:0.024733079 +1 1:0.77605 2:0.009331 3:0.03888 5:0.0249877 7:0.016974549 +1 1:0.756757 2:0.021236 3:0.042471 5:0.025651156 7:0.017103774 +1 1:0.770642 2:0.041284 3:0.050459 5:0.0029892803 6:0.0072210072 7:0.069730366 +1 1:0.832168 2:0.006993 3:0.048951 7:0.0390585 +1 1:0.75625 2:0.015625 3:0.028125 5:0.0098474796 7:0.014424543 +1 1:0.782383 2:0.015544 3:0.036269 5:0.027060069 7:0.017408061 +1 1:0.685484 2:0.048387 3:0.072581 5:0.048245941 6:0.0097080097 7:0.015194726 +1 1:0.709172 2:0.082774 3:0.04698 5:0.07308455 6:0.021672022 7:0.026436402 +1 1:0.73494 2:0.032129 3:0.054217 5:0.064221073 7:0.018476341 +1 1:0.758491 2:0.022642 3:0.033962 5:0.010264935 7:0.016705018 +1 1:0.737127 2:0.03252 3:0.03523 5:0.031555171 7:0.015615707 +1 1:0.773333 2:0.013333 3:0.04 5:0.018681138 7:0.016219512 +1 1:0.726115 2:0.050955 3:0.146497 5:0.010458754 6:0.0021030021 7:0.11076589 +1 1:0.725275 2:0.043956 3:0.049451 5:0.064124163 6:0.012903013 7:0.015578933 +1 1:0.693122 2:0.042328 3:0.074074 5:0.096186245 7:0.015001933 +1 1:0.760116 2:0.028902 3:0.026012 5:0.022960058 7:0.017164811 +1 1:0.733189 2:0.0282 3:0.0282 5:0.042237562 6:0.011331011 7:0.014007195 +1 1:0.733051 2:0.04661 3:0.033898 5:0.03516318 6:0.028302028 7:0.016432409 +1 1:0.792291 2:0.010707 3:0.029979 5:0.0051361949 7:0.018958585 +1 1:0.726361 2:0.025788 3:0.038682 4:0.025830258 5:0.027656434 6:0.0031800032 7:0.016484378 +1 1:0.75188 2:0.015038 3:0.052632 5:0.013910217 7:0.024573628 +1 1:0.790514 2:0.007905 3:0.039526 5:0.015878222 7:0.022630866 +1 1:0.75 2:0.027778 3:0.027778 5:0.033880995 6:0.013635014 7:0.014905146 +1 1:0.660714 2:0.017857 3:0.053571 5:0.045182115 7:0.01796603 +1 1:0.739884 2:0.046243 3:0.037572 4:0.0036900369 5:0.025926975 6:0.013044013 7:0.020266457 +1 1:0.788671 2:0.026144 3:0.030501 5:0.0090498412 6:0.0036420036 7:0.021892768 +1 1:0.734694 2:0.053061 3:0.044898 5:0.032479537 6:0.016341016 7:0.022847189 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.741497 2:0.034014 3:0.061224 5:0.041007559 6:0.0066000066 7:0.018852665 +1 1:0.770492 2:0.016393 3:0.032787 5:0.030384805 7:0.01839264 +1 1:0.725 2:0.02 3:0.075 5:0.039725374 7:0.017164634 +1 1:0.730469 2:0.015625 3:0.050781 5:0.052591952 7:0.013505146 +1 1:0.67655 2:0.040431 3:0.105121 5:0.096894428 7:0.018966537 +1 1:0.753289 2:0.064145 3:0.024671 5:0.04321411 6:0.023187023 7:0.020759787 +1 1:0.755187 2:0.020747 3:0.053942 5:0.032129173 7:0.017609555 +1 1:0.748634 2:0.04918 3:0.038251 5:0.025613883 6:0.030927031 7:0.019392244 +1 1:0.766323 2:0.020619 3:0.034364 5:0.02900571 6:0.0077820078 7:0.016155396 +1 1:0.719626 2:0.040498 3:0.056075 5:0.025613883 6:0.0025770026 7:0.02211078 +1 1:0.74359 2:0.025641 3:0.043956 5:0.047239575 6:0.0038010038 7:0.017622622 +1 1:0.639594 2:0.116751 3:0.055838 5:0.10649591 6:0.055101055 7:0.015166524 8:0.023809524 +1 1:0.765464 2:0.015464 3:0.043814 5:0.013515125 6:0.0054390054 7:0.017334043 +1 1:0.78934 2:0.002538 3:0.022843 5:0.0066941989 7:0.017240311 +1 1:0.773176 2:0.017751 3:0.047337 5:0.032613719 7:0.019242793 +1 1:0.741379 2:0.022989 3:0.028736 5:0.038525189 7:0.013561817 +1 1:0.764852 2:0.014851 3:0.039604 5:0.04184247 7:0.016134384 +1 1:0.784091 2:0.017045 3:0.039773 5:0.023556424 7:0.021930433 +1 1:0.716418 2:0.056716 3:0.059701 5:0.058749422 6:0.013134013 7:0.020786311 +1 1:0.78673 2:0.014218 3:0.037915 5:0.02609843 7:0.024765921 +1 1:0.742754 2:0.014493 3:0.068841 5:0.027574434 7:0.01791711 +1 1:0.756233 2:0.022161 3:0.038781 5:0.03679573 7:0.017110329 +1 1:0.80791 2:0.011299 3:0.045198 5:0.016101859 7:0.031900232 +1 1:0.722513 2:0.031414 3:0.04712 5:0.036102456 7:0.01318478 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.76087 2:0.016304 3:0.048913 5:0.041648651 7:0.017795598 +1 1:0.755814 2:0.013566 3:0.02907 5:0.031115352 7:0.014156738 +1 1:0.745146 2:0.014563 3:0.038835 5:0.038622098 7:0.014281909 +1 1:0.774194 2:0.016129 3:0.024194 5:0.022184784 7:0.016522421 +1 1:0.774086 2:0.013289 3:0.036545 5:0.016698224 7:0.018090104 +1 1:0.779255 2:0.007979 3:0.034574 5:0.019948414 7:0.018179165 +1 1:0.738889 2:0.022222 3:0.044444 4:0.0036900369 5:0.030675533 7:0.016463415 +1 1:0.773006 2:0.006135 3:0.04908 5:0.016310587 7:0.017095616 +1 1:0.737342 2:0.053797 3:0.031646 5:0.031622262 6:0.028632029 7:0.018196201 +1 1:0.761745 2:0.033557 3:0.030201 5:0.022564967 7:0.020277457 +1 1:0.758278 2:0.023179 3:0.05298 5:0.020589507 7:0.021926988 +1 1:0.762626 2:0.030303 3:0.035354 5:0.038495371 6:0.01032601 7:0.017892335 +1 1:0.720238 2:0.02381 3:0.059524 5:0.063177434 7:0.017131244 +1 1:0.697885 2:0.039275 3:0.07855 5:0.10686118 7:0.016063665 +1 1:0.714953 2:0.023364 3:0.088785 5:0.048409941 7:0.01755186 +1 1:0.782178 2:0.016502 3:0.031353 5:0.024778972 7:0.018161878 +1 1:0.759036 2:0.024096 3:0.032129 5:0.031905536 6:0.0085590086 7:0.017166226 +1 1:0.698676 2:0.086093 3:0.036424 5:0.049043579 6:0.042762043 7:0.018413829 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.720739 2:0.043121 3:0.051335 5:0.069886542 6:0.0037500038 7:0.020033055 +1 1:0.735294 2:0.010695 3:0.050802 5:0.027358251 7:0.017770963 +1 1:0.72118 2:0.018767 3:0.045576 4:0.0036900369 5:0.039061918 7:0.018717713 +1 1:0.776224 2:0.020979 3:0.020979 5:0.018822775 7:0.016885555 +1 1:0.757396 2:0.008876 3:0.026627 5:0.017577863 7:0.015298024 +1 1:0.765957 2:0.012766 3:0.038298 5:0.032792629 7:0.017695902 +1 1:0.796053 2:0.026316 3:0.039474 5:0.012590759 6:0.01013401 7:0.023748396 +1 1:0.776053 2:0.015521 3:0.039911 5:0.027186796 7:0.018536043 +1 1:0.783784 2:0.018018 3:0.058559 5:0.010846391 7:0.037766427 +1 1:0.770686 2:0.014184 3:0.018913 5:0.021692782 7:0.014861902 +1 1:0.742021 2:0.029255 3:0.053191 5:0.04073174 6:0.0054630055 7:0.017806177 +1 1:0.73236 2:0.026764 3:0.038929 5:0.030026986 7:0.014732061 +1 1:0.712446 2:0.015021 3:0.034335 5:0.026456249 7:0.018436616 +1 1:0.749367 2:0.027848 3:0.022785 5:0.036900094 7:0.015591232 +1 1:0.720588 2:0.022059 3:0.066176 5:0.022184784 7:0.015064561 +1 1:0.739726 2:0.020548 3:0.075342 5:0.050370492 7:0.018543268 +1 1:0.782082 2:0.007264 3:0.033898 5:0.011748394 7:0.018735604 +1 1:0.728324 2:0.011561 3:0.057803 5:0.017667318 7:0.014873817 +1 1:0.743802 2:0.041322 3:0.024793 5:0.019113503 6:0.023076023 7:0.019653293 +1 1:0.59204 2:0.029851 3:0.149254 5:0.0012300031 7:0.18429196 +1 1:0.776596 2:0.021277 3:0.042553 5:0.024495699 7:0.019741396 +1 1:0.668831 2:0.116883 3:0.071429 5:0.064824892 6:0.026088026 7:0.022766866 +1 1:0.787879 2:0.030303 3:0.030303 5:0.024324244 6:0.0097890098 7:0.022653366 +1 1:0.755776 2:0.019802 3:0.056106 5:0.024741699 7:0.018192061 +1 1:0.728873 2:0.035211 3:0.042254 5:0.029542439 7:0.016253006 +1 1:0.776699 2:0.024272 3:0.019417 5:0.012874033 6:0.01036201 7:0.017138293 +1 1:0.764444 2:0.035556 3:0.04 5:0.039233373 6:0.0078960079 7:0.020596207 +1 1:0.761538 2:0.011538 3:0.061538 5:0.018450047 7:0.018949341 +1 1:0.77095 2:0.01676 3:0.027933 5:0.014282945 7:0.017781713 +1 1:0.72549 2:0.027451 3:0.05098 5:0.076849105 7:0.01623625 +1 1:0.787234 2:0.015957 3:0.024823 5:0.017272226 7:0.018660268 +1 1:0.7751 2:0.024096 3:0.044177 5:0.0074023825 6:0.005958006 7:0.024659616 +1 1:0.7751 2:0.016064 3:0.032129 5:0.026396613 7:0.017288665 +1 1:0.788235 2:0.017647 3:0.035294 5:0.014036945 7:0.019045909 +1 1:0.778509 2:0.006579 3:0.024123 5:0.019143321 7:0.015618317 +1 1:0.783582 2:0.007463 3:0.026119 5:0.019672596 7:0.017246085 +1 1:0.707736 2:0.068768 3:0.031519 5:0.019948414 6:0.04014304 7:0.019585573 +1 1:0.715084 2:0.019553 3:0.030726 5:0.024413699 7:0.015601579 +1 1:0.75 2:0.025602 3:0.036145 5:0.035036453 6:0.0088140088 7:0.015629591 +1 1:0.768473 2:0.009852 3:0.039409 5:0.025487156 7:0.017571787 +1 1:0.69403 2:0.104478 3:0.029851 5:0.093882784 6:0.037782038 7:0.018065165 +1 1:0.754601 2:0.047035 3:0.030675 5:0.04911067 6:0.01976402 7:0.018928628 +1 1:0.732558 2:0.02907 3:0.034884 5:0.052867771 7:0.014995744 +1 1:0.7833 2:0.007952 3:0.021869 5:0.017085862 7:0.015868207 +1 1:0.796262 2:0.005607 3:0.039252 5:0.013157306 7:0.019375427 +1 1:0.792157 2:0.003922 3:0.027451 5:0.0099667526 7:0.017886177 +1 1:0.688235 2:0.052941 3:0.052941 5:0.095813517 7:0.013952652 +1 1:0.732026 2:0.03268 3:0.028322 5:0.033187721 6:0.0026700027 7:0.014918433 +1 1:0.759554 2:0.014331 3:0.047771 5:0.024443517 7:0.017768372 +1 1:0.75122 2:0.017073 3:0.029268 5:0.021841874 7:0.01522903 +1 1:0.737533 2:0.028871 3:0.034121 5:0.047701758 6:0.0054840055 7:0.017508482 +1 1:0.766423 2:0.007299 3:0.043796 5:0.017943137 7:0.01849297 +1 1:0.772532 2:0.01073 3:0.032189 5:0.015915495 7:0.01838428 +1 1:0.719212 2:0.009852 3:0.064039 5:0.028021708 7:0.015979817 +1 1:0.784615 2:0.015385 3:0.107692 5:0.011062574 7:0.031613512 +1 1:0.769663 2:0.033708 3:0.05618 6:0.013215013 7:0.023328311 +1 1:0.715278 2:0.013889 3:0.069444 5:0.020768417 7:0.015201561 +1 1:0.733766 2:0.032468 3:0.064935 5:0.060053971 6:0.003021003 7:0.019658695 +1 1:0.723608 2:0.026871 3:0.069098 5:0.069118721 7:0.017672396 +1 1:0.742138 2:0.025157 3:0.050314 5:0.036363365 7:0.015723268 +1 1:0.788288 2:0.003003 3:0.034535 5:0.0074992918 7:0.018201128 +1 1:0.787736 2:0.018868 3:0.033019 5:0.010600391 6:0.0042660043 7:0.020219744 +1 1:0.773006 2:0.006135 3:0.04908 5:0.016310587 7:0.017095616 +1 1:0.792899 2:0.005917 3:0.035503 5:0.013574762 7:0.019808055 +1 1:0.720588 2:0.022059 3:0.066176 5:0.022184784 7:0.015064561 +1 1:0.7251 2:0.031873 3:0.027888 5:0.024279516 7:0.014915945 +1 1:0.768 2:0.016 3:0.04 7:0.01697561 +1 1:0.772871 2:0.009464 3:0.037855 5:0.026843887 7:0.016022927 +1 1:0.78972 2:0.009346 3:0.028037 7:0.017523366 +1 1:0.75873 2:0.050794 3:0.025397 5:0.038309007 6:0.024666025 7:0.018834689 +1 1:0.766839 2:0.015544 3:0.036269 5:0.014618401 7:0.016112726 +1 1:0.780328 2:0.019672 3:0.036066 5:0.015609858 7:0.019092366 +1 1:0.719298 2:0.05848 3:0.040936 5:0.058466149 6:0.029412029 7:0.018185707 +1 1:0.747126 2:0.005747 3:0.051724 5:0.017294589 7:0.015103726 +1 1:0.763359 2:0.022901 3:0.035623 5:0.035327181 7:0.016368768 +1 1:0.75974 2:0.019481 3:0.019481 7:0.014452012 +1 1:0.764992 2:0.019449 3:0.035656 5:0.020291324 6:0.0048990049 7:0.018154323 +1 1:0.763557 2:0.019523 3:0.02603 5:0.012054031 7:0.016361567 +1 1:0.763314 2:0.017751 3:0.035503 5:0.033962996 7:0.015839226 +1 1:0.783626 2:0.005848 3:0.02924 5:0.013984763 7:0.019005848 +1 1:0.727473 2:0.026374 3:0.057143 5:0.032807538 7:0.015223799 +1 1:0.73741 2:0.021583 3:0.039568 5:0.023295514 7:0.014037549 +1 1:0.747126 2:0.005747 3:0.051724 5:0.017294589 7:0.015103726 +1 1:0.791907 2:0.00578 3:0.046243 5:0.012180758 7:0.021570561 +1 1:0.791878 2:0.005076 3:0.025381 5:0.011964576 7:0.019283146 +1 1:0.719745 2:0.031847 3:0.057325 5:0.03645282 7:0.015884732 +1 1:0.695652 2:0.05314 3:0.038647 5:0.058421421 6:0.018810019 7:0.018793451 +1 1:0.664286 2:0.042857 3:0.092857 5:0.1339138 7:0.014547037 +1 1:0.747253 2:0.018315 3:0.040293 5:0.021894056 7:0.015210396 +1 1:0.753846 2:0.007692 3:0.053846 5:0.024204971 7:0.01444653 +1 1:0.751092 2:0.026201 3:0.030568 5:0.013194579 7:0.015044201 +1 1:0.752089 2:0.022284 3:0.030641 5:0.025733156 7:0.014759835 +1 1:0.720257 2:0.045016 3:0.054662 5:0.03021335 6:0.018237018 7:0.019351421 +1 1:0.768041 2:0.0189 3:0.041237 5:0.040053375 7:0.019497524 +1 1:0.734756 2:0.027439 3:0.073171 5:0.063893072 7:0.019519634 +1 1:0.794643 2:0.011161 3:0.022321 5:0.010913482 7:0.018592116 +1 1:0.753846 2:0.020513 3:0.035897 5:0.026575522 7:0.017542213 +1 1:0.775244 2:0.006515 3:0.065147 5:0.012956033 7:0.02286089 +1 1:0.794872 2:0.008547 3:0.042735 5:0.01951605 7:0.019908274 +1 1:0.680203 2:0.040609 3:0.040609 5:0.094188422 7:0.017147457 +1 1:0.777778 2:0.005848 3:0.093567 5:0.0099518435 7:0.02670803 +1 1:0.769231 2:0.032389 3:0.044534 5:0.037414459 7:0.019675128 +1 1:0.737952 2:0.021084 3:0.048193 5:0.017704591 7:0.015464293 +1 1:0.75122 2:0.017073 3:0.029268 5:0.021841874 7:0.01522903 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.780488 2:0.01897 3:0.0271 5:0.027082433 6:0.0081750082 7:0.018193537 +1 1:0.746193 2:0.020305 3:0.038071 5:0.046263027 7:0.019948622 +1 1:0.792969 2:0.019531 3:0.027344 5:0.018136955 6:0.0072990073 7:0.01957889 +1 1:0.781768 2:0.005525 3:0.027624 5:0.014394764 7:0.017450476 +1 1:0.769231 2:0.021978 3:0.027473 5:0.02892371 6:0.0058200058 7:0.017270835 +1 1:0.801471 2:0.003676 3:0.025735 5:0.0093405692 7:0.017889171 +1 1:0.778 2:0.02 3:0.05 4:0.0036900369 5:0.035729727 7:0.020353659 +1 1:0.788079 2:0.013245 3:0.02649 5:0.016310587 7:0.018454207 +1 1:0.739837 2:0.03252 3:0.04065 5:0.046881756 7:0.015764427 +1 1:0.768856 2:0.009732 3:0.03163 5:0.028454072 7:0.015548037 +1 1:0.654676 2:0.043165 3:0.079137 5:0.020820598 7:0.015704512 +1 1:0.746781 2:0.025751 3:0.04721 5:0.023407332 7:0.016670159 +1 1:0.646465 2:0.040404 3:0.065657 5:0.032621174 6:0.0065640066 7:0.014073665 +1 1:0.73578 2:0.014679 3:0.073394 5:0.038696644 7:0.017240994 +1 1:0.745283 2:0.061321 3:0.051887 5:0.047239575 6:0.0076050076 7:0.02269328 +1 1:0.763949 2:0.017167 3:0.06867 5:0.0081851117 7:0.04768136 +1 1:0.77193 2:0.014035 3:0.031579 5:0.029154801 7:0.016409927 +1 1:0.735849 2:0.025157 3:0.081761 4:0.0036900369 5:0.028342254 7:0.020171805 +1 1:0.77605 2:0.009331 3:0.03888 5:0.0249877 7:0.016974549 +1 1:0.765101 2:0.020134 3:0.067114 5:0.028729891 7:0.021239159 +1 1:0.734982 2:0.024735 3:0.024735 7:0.014069634 +1 1:0.765152 2:0.015152 3:0.040404 5:0.020291324 7:0.016968463 +1 1:0.735294 2:0.015686 3:0.052941 5:0.023258241 7:0.015327598 8:0.023809524 +1 1:0.747649 2:0.029781 3:0.021944 5:0.042595381 6:0.012468012 7:0.018397811 +1 1:0.777228 2:0.014851 3:0.024752 5:0.016817497 6:0.0045120045 7:0.020073652 +1 1:0.757576 2:0.020202 3:0.032828 5:0.0074471099 7:0.01541328 +1 1:0.752475 2:0.019802 3:0.05198 5:0.051995587 7:0.01731164 +1 1:0.705314 2:0.057971 3:0.067633 5:0.060121062 7:0.018263226 +1 1:0.790795 2:0.041841 3:0.046025 5:0.0065301984 6:0.015777016 7:0.02911011 +1 1:0.772988 2:0.017241 3:0.034483 5:0.0067836536 7:0.019256378 +1 1:0.727941 2:0.014706 3:0.058824 5:0.042722109 7:0.015647415 +1 1:0.755102 2:0.020408 3:0.034014 5:0.03132408 7:0.01480836 +1 1:0.746412 2:0.023923 3:0.062201 5:0.03080226 7:0.021181 +1 1:0.726667 2:0.023333 3:0.043333 4:0.0036900369 5:0.02823789 6:0.0037890038 7:0.016097561 +1 1:0.690367 2:0.045872 3:0.094037 5:0.10165044 7:0.018460506 +1 1:0.797386 2:0.006536 3:0.104575 5:0.0094374786 7:0.03148414 +1 1:0.739884 2:0.028902 3:0.034682 5:0.045920117 7:0.017164811 +1 1:0.785714 2:0.025974 3:0.045455 5:0.016526769 6:0.0066510067 7:0.026785713 +1 1:0.753541 2:0.01983 3:0.042493 5:0.040694467 7:0.015822567 +1 1:0.703518 2:0.095477 3:0.045226 5:0.022900422 6:0.055299055 7:0.019947299 +1 1:0.766667 2:0.016667 3:0.033333 5:0.02412297 7:0.01570122 +1 1:0.728571 2:0.052381 3:0.1 5:0.026635159 6:0.0030630031 7:0.05688153 +1 1:0.770227 2:0.012945 3:0.042071 5:0.035670091 7:0.016496963 +1 1:0.728155 2:0.029126 3:0.067961 5:0.050571765 6:0.0040710041 7:0.021815061 +1 1:0.725888 2:0.071066 3:0.055838 5:0.044906296 6:0.036144036 7:0.020552183 +1 1:0.716418 2:0.034826 3:0.049751 5:0.052778316 7:0.017139909 +1 1:0.779434 2:0.011923 3:0.031297 5:0.019493686 7:0.017374866 +1 1:0.76087 2:0.050725 3:0.021739 5:0.031786263 6:0.019191019 7:0.020722872 +1 1:0.771982 2:0.019374 3:0.023845 5:0.023630969 6:0.0015840016 7:0.017202207 +1 1:0.780973 2:0.011062 3:0.028761 5:0.016310587 7:0.018495037 +1 1:0.672862 2:0.042751 3:0.10223 5:0.10506463 7:0.016887299 +1 1:0.75265 2:0.021201 3:0.031802 5:0.034589179 6:0.0034800035 7:0.01857278 +1 1:0.80597 2:0.014925 3:0.097015 5:0.0096909338 7:0.03499272 +1 1:0.756173 2:0.015432 3:0.037037 5:0.017100771 7:0.01641072 +1 1:0.760135 2:0.013514 3:0.027027 5:0.031584989 7:0.014584707 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.747082 2:0.027237 3:0.058366 5:0.015117857 6:0.002028002 7:0.035090634 +1 1:0.747331 2:0.032028 3:0.071174 5:0.029661712 7:0.032722854 +1 1:0.742515 2:0.071856 3:0.02994 5:0.056155234 6:0.022599023 7:0.019388055 +1 1:0.804444 2:0.004444 3:0.035556 7:0.021598915 +1 1:0.777778 2:0.005051 3:0.075758 7:0.02340478 +1 1:0.753623 2:0.019324 3:0.033816 5:0.025397701 7:0.017291152 +1 1:0.781609 2:0.022989 3:0.057471 5:0.034454997 7:0.022743201 +1 1:0.727554 2:0.024768 3:0.04644 5:0.04587539 7:0.018405951 +1 1:0.779599 2:0.010929 3:0.040073 5:0.025300792 7:0.019636591 +1 1:0.705696 2:0.028481 3:0.056962 5:0.042304653 6:0.0068100068 7:0.016999848 +1 1:0.789062 2:0.03125 3:0.015625 6:0.014118014 7:0.020245805 +1 1:0.741722 2:0.033113 3:0.046358 5:0.045346115 7:0.016596671 +1 1:0.763994 2:0.028744 3:0.030257 5:0.029296438 6:0.0091710092 7:0.021124683 +1 1:0.738272 2:0.02716 3:0.041975 5:0.042274835 7:0.015928939 +1 1:0.723077 2:0.046154 3:0.046154 5:0.066755624 7:0.015712945 +1 1:0.77451 2:0.009804 3:0.039216 5:0.027007887 7:0.01649928 +1 1:0.755952 2:0.017857 3:0.029762 7:0.014699476 +1 1:0.765957 2:0.02305 3:0.019504 5:0.024152789 7:0.016681805 +1 1:0.723776 2:0.052448 3:0.031469 5:0.037228095 6:0.014982015 7:0.017077433 +1 1:0.734375 2:0.026563 3:0.028125 5:0.026769341 6:0.012567013 7:0.015920354 +1 1:0.787781 2:0.009646 3:0.045016 5:0.0068432901 7:0.021351268 +1 1:0.742297 2:0.019608 3:0.047619 5:0.0074769281 7:0.017028762 +1 1:0.755102 2:0.034014 3:0.034014 5:0.035289908 6:0.010650011 7:0.017525305 +1 1:0.67451 2:0.064706 3:0.064706 5:0.11125937 6:0.0040710041 7:0.017623146 +1 1:0.792079 2:0.009901 3:0.033003 5:0.022058056 7:0.020405701 +1 1:0.782178 2:0.014851 3:0.034653 5:0.026344431 7:0.017085244 +1 1:0.789333 2:0.016 3:0.04 5:0.022728967 7:0.021333335 +1 1:0.755556 2:0.02963 3:0.022222 7:0.015808488 +1 1:0.739696 2:0.021692 3:0.052061 5:0.044227931 7:0.020065079 +1 1:0.758403 2:0.018908 3:0.035714 5:0.038912826 7:0.017178213 +1 1:0.753968 2:0.02381 3:0.055556 5:0.037183367 7:0.019405732 +1 1:0.761905 2:0.014286 3:0.033333 5:0.027402979 7:0.015795585 +1 1:0.792517 2:0.003401 3:0.034014 5:0.0081329298 7:0.019018585 +1 1:0.737226 2:0.029197 3:0.047445 5:0.028782073 7:0.017291256 +1 1:0.75 2:0.02459 3:0.057377 5:0.028595709 6:0.0038370038 7:0.019542183 +1 1:0.71978 2:0.035714 3:0.041209 5:0.039867011 6:0.012834013 7:0.015662689 +1 1:0.737542 2:0.026578 3:0.026578 5:0.030384805 7:0.014909652 +1 1:0.768707 2:0.013605 3:0.027211 5:0.018494774 7:0.016716445 +1 1:0.543284 2:0.023881 3:0.137313 4:0.0036900369 5:0.028811892 7:0.018838732 +1 1:0.769231 2:0.019231 3:0.032051 5:0.029758621 7:0.019582555 +1 1:0.73545 2:0.026455 3:0.042328 5:0.032554083 7:0.014776098 +1 1:0.741935 2:0.028226 3:0.052419 5:0.032181355 7:0.017087921 +1 1:0.757062 2:0.028249 3:0.033898 5:0.033426267 6:0.0067260067 7:0.015364476 +1 1:0.719008 2:0.041322 3:0.057851 5:0.024518062 7:0.015319494 +1 1:0.751121 2:0.024664 3:0.060538 5:0.025300792 7:0.02013836 +1 1:0.700483 2:0.057971 3:0.05314 5:0.043422838 6:0.023301023 7:0.015170262 +1 1:0.763955 2:0.038278 3:0.038278 5:0.040351557 6:0.0059070059 7:0.019761152 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.752608 2:0.014903 3:0.031297 5:0.035103544 7:0.01543928 +1 1:0.678322 2:0.076923 3:0.048951 5:0.079644566 6:0.012822013 7:0.019955652 +1 1:0.758333 2:0.026667 3:0.026667 5:0.017868591 7:0.016961384 +1 1:0.748106 2:0.024621 3:0.024621 5:0.029631894 7:0.014527902 +1 1:0.711656 2:0.03681 3:0.07362 5:0.049259762 7:0.01698339 +1 1:0.741497 2:0.013605 3:0.040816 5:0.038726462 7:0.015969805 +1 1:0.682081 2:0.057803 3:0.052023 5:0.082984211 7:0.018997604 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.67086 2:0.081761 3:0.039832 5:0.097147884 6:0.024690025 7:0.018637829 +1 1:0.784247 2:0.013699 3:0.027397 5:0.0083267485 7:0.018689439 +1 1:0.556355 2:0.211031 3:0.043165 5:0.022863149 6:0.14493914 7:0.019067671 +1 1:0.739837 2:0.04065 3:0.04065 5:0.054813412 7:0.020226055 +1 1:0.705521 2:0.042945 3:0.06135 5:0.070997272 7:0.015711506 +1 1:0.705128 2:0.032051 3:0.051282 5:0.043467565 7:0.013406817 +1 1:0.740385 2:0.026442 3:0.026442 5:0.032024809 6:0.012888013 7:0.013646226 +1 1:0.754753 2:0.022814 3:0.039924 5:0.04775394 7:0.018095616 +1 1:0.784768 2:0.019868 3:0.023179 7:0.018858018 +1 1:0.734742 2:0.028169 3:0.044601 7:0.01621722 +1 1:0.787736 2:0.023585 3:0.056604 5:0.01976205 7:0.054245287 +1 1:0.77129 2:0.026764 3:0.024331 5:0.02533061 6:0.0050970051 7:0.017461872 +1 1:0.684615 2:0.046154 3:0.092308 5:0.1090901 7:0.019230768 +1 1:0.760331 2:0.008264 3:0.033058 5:0.02720916 7:0.013807701 +1 1:0.747423 2:0.030928 3:0.056701 5:0.057966693 7:0.020209957 +1 1:0.689655 2:0.108374 3:0.019704 5:0.013984763 6:0.09005709 7:0.016009854 +1 1:0.742424 2:0.030303 3:0.060606 5:0.036721184 6:0.0073890074 7:0.018754622 +1 1:0.700273 2:0.059946 3:0.040872 5:0.020537325 6:0.03030303 7:0.018093311 +1 1:0.796178 2:0.006369 3:0.025478 7:0.018525713 +1 1:0.782051 2:0.022436 3:0.038462 5:0.021841874 7:0.020012506 +1 1:0.727273 2:0.016529 3:0.07438 7:0.015823421 +1 1:0.718391 2:0.031609 3:0.071839 5:0.051719768 7:0.020202549 +1 1:0.733333 2:0.024561 3:0.042105 5:0.022289148 7:0.01431322 +1 1:0.758621 2:0.027586 3:0.110345 5:0.033031175 7:0.028469299 +1 1:0.75 2:0.02459 3:0.057377 5:0.028595709 6:0.0038370038 7:0.019542183 +1 1:0.775 2:0.02 3:0.03 5:0.025442428 7:0.017865854 +1 1:0.772277 2:0.014851 3:0.024752 5:0.014089127 7:0.015968366 +1 1:0.706612 2:0.070248 3:0.020661 4:0.0073800738 5:0.034432633 6:0.034641035 7:0.021820195 +1 1:0.716981 2:0.012579 3:0.075472 5:0.037272822 7:0.015339774 +1 1:0.713542 2:0.03125 3:0.046875 5:0.034037541 7:0.013910061 +1 1:0.778524 2:0.013423 3:0.087248 5:0.011815485 7:0.025822561 +1 1:0.735178 2:0.011858 3:0.063241 5:0.035893728 7:0.015014945 +1 1:0.731308 2:0.053738 3:0.049065 5:0.049267216 6:0.023793024 7:0.021555165 +1 1:0.747387 2:0.022648 3:0.052265 5:0.050884857 7:0.01867511 +1 1:0.745875 2:0.026403 3:0.039604 5:0.028058981 6:0.0075270075 7:0.016038799 +1 1:0.783673 2:0.020408 3:0.040816 5:0.027574434 7:0.020184171 +1 1:0.772021 2:0.005181 3:0.031088 7:0.014912171 +1 1:0.761394 2:0.016086 3:0.048257 5:0.040403739 7:0.018096518 +1 1:0.782609 2:0.012422 3:0.037267 5:0.015729131 7:0.017951823 +1 1:0.733591 2:0.030888 3:0.023166 5:0.023891879 6:0.014424014 7:0.014690646 +1 1:0.730061 2:0.04908 3:0.03681 5:0.057899602 6:0.011649012 7:0.019265299 +1 1:0.725714 2:0.028571 3:0.051429 5:0.070743816 7:0.014686409 +1 1:0.764065 2:0.021779 3:0.036298 5:0.029154801 6:0.0033510034 7:0.019808774 +1 1:0.748447 2:0.018634 3:0.037267 5:0.0092287508 7:0.015300713 +1 1:0.772085 2:0.028269 3:0.077739 5:0.023630969 7:0.027191244 +1 1:0.75 2:0.021552 3:0.060345 5:0.039032099 7:0.020079896 +1 1:0.648855 2:0.076336 3:0.099237 5:0.12964233 6:0.017391017 7:0.016058463 +1 1:0.726882 2:0.027957 3:0.073118 5:0.017697136 7:0.066273274 +1 1:0.766667 2:0.02 3:0.02 5:0.02036587 7:0.014878049 +1 1:0.763889 2:0.025794 3:0.049603 5:0.021573509 6:0.0028950029 7:0.037625823 +1 1:0.731928 2:0.036145 3:0.063253 5:0.064511801 7:0.019100793 +1 1:0.721491 2:0.028509 3:0.061404 5:0.053329954 7:0.01682178 +1 1:0.765182 2:0.030364 3:0.02834 5:0.032822447 6:0.0075480075 7:0.01962575 +1 1:0.768271 2:0.01426 3:0.039216 5:0.032390082 7:0.01751011 +1 1:0.728571 2:0.039286 3:0.039286 5:0.037913915 6:0.0091560092 7:0.021406793 +1 1:0.733154 2:0.021563 3:0.056604 5:0.022453148 7:0.016369732 +1 1:0.668269 2:0.043269 3:0.043269 5:0.062752523 7:0.017413226 +1 1:0.719149 2:0.031915 3:0.042553 5:0.039061918 6:0.013101013 7:0.014854695 +1 1:0.774725 2:0.016484 3:0.032967 5:0.030183531 7:0.016550524 +1 1:0.727848 2:0.031646 3:0.037975 5:0.041879743 7:0.013738811 +1 1:0.723577 2:0.03252 3:0.03252 5:0.059166878 7:0.012492561 +1 1:0.74581 2:0.022346 3:0.030726 5:0.03663173 7:0.013864287 +1 1:0.761682 2:0.042056 3:0.03271 5:0.023630969 6:0.014262014 7:0.017979256 +1 1:0.746094 2:0.011719 3:0.074219 5:0.019188049 7:0.018507049 +1 1:0.790323 2:0.005376 3:0.032258 7:0.018095988 +1 1:0.75 2:0.021552 3:0.060345 5:0.039032099 7:0.020079896 +1 1:0.721774 2:0.03629 3:0.052419 5:0.034402815 7:0.015981512 +1 1:0.7 2:0.033333 3:0.075 4:0.0036900369 5:0.056759054 7:0.020020323 +1 1:0.739837 2:0.03252 3:0.04065 5:0.046881756 7:0.015764427 +1 1:0.76129 2:0.012903 3:0.025806 5:0.031100443 7:0.014142409 +1 1:0.738095 2:0.02381 3:0.029101 5:0.020291324 6:0.0054450054 7:0.017776488 +1 1:0.7 2:0.035294 3:0.058824 5:0.037086458 7:0.014418939 +1 1:0.777439 2:0.018293 3:0.04878 5:0.031219716 7:0.02219661 +1 1:0.75 2:0.010638 3:0.047872 5:0.016139132 7:0.014984433 +1 1:0.725 2:0.02 3:0.075 5:0.039725374 7:0.017164634 +1 1:0.782946 2:0.015504 3:0.033592 5:0.019031503 7:0.018513268 +1 1:0.732824 2:0.045802 3:0.045802 5:0.03867428 6:0.0077820078 7:0.017943585 +1 1:0.74552 2:0.032258 3:0.043011 5:0.054082865 7:0.018074134 +1 1:0.740458 2:0.030534 3:0.038168 5:0.020589507 7:0.01684975 +1 1:0.799065 2:0.004673 3:0.028037 7:0.018093232 +1 1:0.727536 2:0.02029 3:0.057971 4:0.0036900369 5:0.041275923 7:0.015959701 +1 1:0.783673 2:0.016327 3:0.028571 5:0.019463868 7:0.019064213 +1 1:0.761538 2:0.030769 3:0.038462 5:0.028275163 6:0.0037920038 7:0.018550659 +1 1:0.759494 2:0.014467 3:0.025316 5:0.0053151044 7:0.015469945 +1 1:0.69697 2:0.09596 3:0.025253 5:0.066800352 6:0.043011043 7:0.017184037 +1 1:0.747881 2:0.027542 3:0.025424 5:0.038003369 7:0.015205146 +1 1:0.787736 2:0.023585 3:0.056604 5:0.01976205 7:0.054245287 +1 1:0.806854 2:0.003115 3:0.040498 5:0.0062320159 7:0.02271864 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.764706 2:0.011029 3:0.036765 5:0.021208236 7:0.015759506 +1 1:0.72885 2:0.036876 3:0.039046 4:0.0036900369 5:0.057743056 7:0.018782073 +1 1:0.742931 2:0.028278 3:0.066838 5:0.066129441 7:0.019436957 +1 1:0.719939 2:0.025875 3:0.068493 5:0.054656866 7:0.016455061 +1 1:0.742857 2:0.019048 3:0.071429 5:0.04424284 7:0.019570268 +1 1:0.691781 2:0.075342 3:0.041096 5:0.075112191 6:0.03022803 7:0.016580354 +1 1:0.770073 2:0.014599 3:0.032847 5:0.029311347 7:0.016979707 +1 1:0.788066 2:0.006173 3:0.024691 5:0.016370223 7:0.017138415 +1 1:0.661049 2:0.033708 3:0.093633 5:0.032576447 7:0.018292683 8:0.023809524 +1 1:0.720588 2:0.029412 3:0.044118 5:0.071220909 7:0.014078195 +1 1:0.767742 2:0.016129 3:0.03871 5:0.025472247 7:0.017269866 +1 1:0.792453 2:0.013477 3:0.053908 5:0.0098772979 6:0.0013260013 7:0.037209915 +1 1:0.765625 2:0.028125 3:0.021875 5:0.023593696 7:0.018064024 +1 1:0.744541 2:0.026201 3:0.030568 5:0.015028402 6:0.014112014 7:0.019810415 +1 1:0.671642 2:0.014925 3:0.126866 5:0.044772114 7:0.015152896 +1 1:0.691489 2:0.049645 3:0.031915 5:0.028379527 6:0.019035019 7:0.017038573 +1 1:0.743802 2:0.041322 3:0.024793 5:0.019113503 6:0.023076023 7:0.019653293 +1 1:0.753165 2:0.079114 3:0.022152 5:0.019776959 6:0.047745048 7:0.021823866 +1 1:0.758197 2:0.020492 3:0.032787 5:0.023407332 7:0.015918634 +1 1:0.769759 2:0.034364 3:0.054983 5:0.036900094 7:0.025396024 +1 1:0.74375 2:0.03125 3:0.04375 5:0.052994499 7:0.016082317 +1 1:0.785714 2:0.010714 3:0.035714 5:0.023370059 6:0.0031350031 7:0.020840591 +1 1:0.722628 2:0.029197 3:0.087591 5:0.053918865 7:0.02461278 +1 1:0.770833 2:0.013021 3:0.036458 5:0.034671179 7:0.017069994 +1 1:0.766497 2:0.010152 3:0.050761 5:0.028946074 7:0.015940323 +1 1:0.739645 2:0.033531 3:0.033531 5:0.032718083 7:0.016440567 +1 1:0.739927 2:0.025641 3:0.065934 4:0.011070111 5:0.042163016 7:0.019744482 +1 1:0.753555 2:0.009479 3:0.061611 5:0.02456279 7:0.017541323 +1 1:0.759259 2:0.018519 3:0.041667 5:0.040150284 7:0.015723805 +1 1:0.746753 2:0.045455 3:0.029221 5:0.026657522 6:0.028605029 7:0.016609915 +1 1:0.806867 2:0.008584 3:0.04721 5:0.016459678 7:0.023709829 +1 1:0.79771 2:0.01145 3:0.015267 7:0.01782722 +1 1:0.655629 2:0.099338 3:0.10596 5:0.019650232 6:0.0094890095 7:0.076603134 8:0.023809524 +1 1:0.755474 2:0.040146 3:0.014599 5:0.018450047 6:0.018564019 7:0.017981128 +1 1:0.804469 2:0.005587 3:0.050279 5:0.011554575 7:0.021971659 +1 1:0.773148 2:0.050926 3:0.027778 5:0.010115844 6:0.024423024 7:0.020805104 +1 1:0.78836 2:0.007937 3:0.039683 5:0.019277504 7:0.018712091 +1 1:0.748299 2:0.020408 3:0.031746 5:0.037146095 6:0.0024930025 7:0.016647311 +1 1:0.764228 2:0.00813 3:0.04065 7:0.014574659 +1 1:0.716667 2:0.033333 3:0.05 5:0.053054135 6:0.0053370053 7:0.019037939 +1 1:0.786585 2:0.006098 3:0.030488 7:0.01658239 +1 1:0.770642 2:0.041284 3:0.050459 5:0.0029892803 6:0.0072210072 7:0.069730366 +1 1:0.765385 2:0.013462 3:0.040385 5:0.030615896 7:0.017131799 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.742138 2:0.025157 3:0.050314 5:0.036363365 7:0.015723268 +1 1:0.773438 2:0.013021 3:0.026042 5:0.0069923814 7:0.016927085 +1 1:0.779661 2:0.011299 3:0.031073 5:0.023638424 7:0.01629461 +1 1:0.685567 2:0.005155 3:0.113402 5:0.013216943 7:0.017726933 +1 1:0.761628 2:0.011628 3:0.034884 5:0.036542275 7:0.014463982 +1 1:0.692112 2:0.050891 3:0.096692 5:0.099175525 7:0.020992366 +1 1:0.706349 2:0.035714 3:0.075397 5:0.067262535 6:0.0045120045 7:0.016090787 +1 1:0.743304 2:0.020089 3:0.040179 5:0.014305309 7:0.014182274 +1 1:0.748052 2:0.025974 3:0.062338 5:0.05057922 7:0.018672793 +1 1:0.771331 2:0.010239 3:0.023891 5:0.010756936 7:0.014421878 +1 1:0.727811 2:0.017751 3:0.059172 5:0.033277176 7:0.016163945 +1 1:0.731481 2:0.027778 3:0.046296 5:0.065972895 7:0.01594964 +1 1:0.728507 2:0.031674 3:0.058824 5:0.074918373 7:0.016471689 +1 1:0.775 2:0.0125 3:0.0375 5:0.023101695 7:0.018445122 +1 1:0.741228 2:0.02193 3:0.030702 5:0.026478613 7:0.015056695 +1 1:0.764368 2:0.017241 3:0.051724 5:0.041566651 7:0.018853378 +1 1:0.768262 2:0.025189 3:0.027708 5:0.020060233 6:0.010761011 7:0.01712539 +1 1:0.798768 2:0.00616 3:0.030801 5:0.015170039 7:0.018455451 +1 1:0.728477 2:0.013245 3:0.07947 5:0.017056043 7:0.017646585 +1 1:0.683544 2:0.075949 3:0.054852 5:0.065779077 6:0.030882031 7:0.01749511 +1 1:0.764706 2:0.017157 3:0.034314 5:0.027663889 7:0.016110713 +1 1:0.746137 2:0.046358 3:0.024283 5:0.039680646 6:0.015969016 7:0.017700427 +1 1:0.791878 2:0.015228 3:0.050761 5:0.021357327 7:0.032406835 +1 1:0.770642 2:0.013761 3:0.03211 5:0.025270973 7:0.016502573 +1 1:0.661111 2:0.077778 3:0.088889 5:0.099838981 7:0.030352305 +1 1:0.740991 2:0.074324 3:0.036036 5:0.048059577 6:0.030948031 7:0.021300262 +1 1:0.762774 2:0.012774 3:0.043796 5:0.014357491 7:0.017335768 +1 1:0.655629 2:0.099338 3:0.10596 5:0.019650232 6:0.0094890095 7:0.076603134 8:0.023809524 +1 1:0.734807 2:0.052486 3:0.030387 5:0.035804273 6:0.031701032 7:0.017534701 +1 1:0.682081 2:0.057803 3:0.052023 5:0.082984211 7:0.018997604 +1 1:0.753425 2:0.020548 3:0.034247 5:0.021178418 7:0.01470097 +1 1:0.73494 2:0.012048 3:0.084337 5:0.029288984 7:0.018696738 +1 1:0.763636 2:0.021818 3:0.043636 5:0.017480954 7:0.018913524 +1 1:0.752896 2:0.023166 3:0.03861 5:0.011062574 7:0.015867787 +1 1:0.781609 2:0.013793 3:0.029885 5:0.016422405 6:0.0044040044 7:0.019091671 +1 1:0.76204 2:0.028329 3:0.03966 5:0.020313688 6:0.0027240027 7:0.019018171 +1 1:0.785714 2:0.011278 3:0.037594 5:0.024518062 7:0.020905921 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.768519 2:0.02963 3:0.027778 5:0.027224069 6:0.012780013 7:0.018552396 +1 1:0.780105 2:0.010471 3:0.026178 5:0.015624767 7:0.015227939 +1 1:0.740964 2:0.024096 3:0.054217 5:0.034119541 7:0.016052012 +1 1:0.731405 2:0.028926 3:0.03719 5:0.053054135 7:0.014160451 +1 1:0.698925 2:0.048387 3:0.032258 5:0.082462392 6:0.013275013 7:0.014817732 +1 1:0.725962 2:0.057692 3:0.081731 5:0.019903687 6:0.0026700027 7:0.06587125 +1 1:0.731861 2:0.033123 3:0.036278 5:0.027358251 6:0.011010011 7:0.01572478 +1 1:0.753894 2:0.020249 3:0.031153 5:0.03080226 6:0.0035430035 7:0.016089201 +1 1:0.738532 2:0.013761 3:0.050459 5:0.02720916 7:0.015327817 +1 1:0.762069 2:0.024138 3:0.024138 5:0.028021708 7:0.016778805 +1 1:0.752456 2:0.009823 3:0.041257 5:0.011666393 7:0.015309793 +1 1:0.794595 2:0.013514 3:0.043243 5:0.026582977 7:0.023104811 +1 1:0.774336 2:0.015487 3:0.022124 5:0.012978397 6:0.0052230052 7:0.015500213 +1 1:0.738182 2:0.036364 3:0.047273 5:0.047910486 6:0.0038550039 7:0.017250555 +1 1:0.772021 2:0.015544 3:0.031088 5:0.028893892 7:0.016302287 +1 1:0.786301 2:0.005479 3:0.030137 5:0.01505822 7:0.016538591 +1 1:0.746241 2:0.030075 3:0.031955 5:0.031122806 6:0.0041760042 7:0.016470293 +1 1:0.742029 2:0.02029 3:0.037681 5:0.023220968 6:0.0031140031 7:0.017020146 +1 1:0.753676 2:0.027574 3:0.033088 5:0.03063826 7:0.019088506 +1 1:0.731405 2:0.028926 3:0.03719 5:0.053054135 7:0.014160451 +1 1:0.687023 2:0.061069 3:0.099237 5:0.12079376 7:0.020107988 +1 1:0.767568 2:0.010811 3:0.081081 5:0.0097952977 7:0.025082396 +1 1:0.778761 2:0.013274 3:0.036873 5:0.017316953 7:0.019353909 +1 1:0.770677 2:0.018797 3:0.037594 5:0.027142069 7:0.018888683 +1 1:0.69103 2:0.076412 3:0.056478 5:0.072532912 6:0.012972013 7:0.018738354 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.780105 2:0.031414 3:0.057592 5:0.040165193 7:0.029625848 +1 1:0.775785 2:0.013453 3:0.044843 5:0.0093554784 7:0.021792628 +1 1:0.636943 2:0.063694 3:0.10828 5:0.096186245 6:0.025806026 7:0.018059652 +1 1:0.75 2:0.047297 3:0.047297 5:0.0463003 7:0.019899476 +1 1:0.674797 2:0.075203 3:0.058943 5:0.11770012 6:0.0067680068 7:0.016483244 +1 1:0.751938 2:0.007752 3:0.046512 5:0.020477688 7:0.017205518 +1 1:0.779412 2:0.006303 3:0.031513 5:0.0057623783 7:0.016576146 +1 1:0.707483 2:0.05102 3:0.088435 5:0.10715191 7:0.020200762 +1 1:0.778393 2:0.022161 3:0.022161 5:0.02036587 6:0.0054630055 7:0.018546043 +1 1:0.775148 2:0.005917 3:0.023669 5:0.017794045 7:0.015117622 +1 1:0.728464 2:0.043071 3:0.05618 5:0.041313196 6:0.0036960037 7:0.01854389 +1 1:0.762836 2:0.00978 3:0.017115 7:0.01358161 +1 1:0.80303 2:0.015152 3:0.015152 7:0.018847006 +1 1:0.746241 2:0.030075 3:0.031955 5:0.031122806 6:0.0041760042 7:0.016470293 +1 1:0.775862 2:0.028736 3:0.04023 5:0.016385133 6:0.0087900088 7:0.023917159 +1 1:0.751412 2:0.050847 3:0.039548 5:0.044906296 6:0.018072018 7:0.022874463 +1 1:0.786127 2:0.008671 3:0.031792 5:0.021439327 7:0.018380799 +1 1:0.774468 2:0.025532 3:0.06383 5:0.011994394 6:0.0016080016 7:0.04839128 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.777559 2:0.015748 3:0.025591 5:0.015594949 7:0.017212409 +1 1:0.761421 2:0.013536 3:0.033841 5:0.0091542051 7:0.016806982 +1 1:0.768519 2:0.046296 3:0.074074 5:0.016653497 6:0.0038280038 7:0.058980726 +1 1:0.7 2:0.025714 3:0.068571 5:0.069424359 7:0.014965159 +1 1:0.79085 2:0.009804 3:0.035948 5:0.011793121 7:0.018890482 +1 1:0.758123 2:0.01083 3:0.021661 5:0.027224069 7:0.015067799 +1 1:0.752768 2:0.02952 3:0.02583 5:0.030220804 7:0.016650165 +1 1:0.777523 2:0.006881 3:0.045872 5:0.015110402 7:0.02069814 +1 1:0.759657 2:0.021459 3:0.030043 5:0.03483518 7:0.016801006 +1 1:0.752577 2:0.016495 3:0.026804 5:0.038361189 7:0.014659293 +1 1:0.719064 2:0.036789 3:0.046823 5:0.073263459 7:0.016600049 +1 1:0.754854 2:0.021845 3:0.033981 5:0.028640437 7:0.015406701 +1 1:0.690789 2:0.032895 3:0.046053 6:0.022728023 7:0.01588575 +1 1:0.743842 2:0.014778 3:0.064039 5:0.026202794 7:0.017091195 +1 1:0.586614 2:0.137795 3:0.055118 5:0.10780046 6:0.043383043 7:0.021581524 +1 1:0.758794 2:0.015075 3:0.040201 5:0.025099518 7:0.018200762 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.779685 2:0.007153 3:0.032904 5:0.019434049 7:0.01673122 +1 1:0.674699 2:0.096386 3:0.054217 5:0.0463003 6:0.04968905 7:0.017741701 +1 1:0.719008 2:0.041322 3:0.057851 5:0.024518062 7:0.015319494 +1 1:0.799065 2:0.023364 3:0.014019 6:0.0085350085 7:0.020030774 +1 1:0.768683 2:0.014235 3:0.02847 5:0.019441504 7:0.016643518 +1 1:0.761589 2:0.013245 3:0.039735 5:0.038525189 7:0.015627524 +1 1:0.768374 2:0.008909 3:0.020045 5:0.012732396 7:0.015902549 +1 1:0.760417 2:0.010417 3:0.041667 5:0.010063662 7:0.015688518 +1 1:0.728571 2:0.052381 3:0.1 5:0.026635159 6:0.0030630031 7:0.05688153 +1 1:0.759259 2:0.020833 3:0.032407 5:0.027328433 7:0.015399165 +1 1:0.741319 2:0.015625 3:0.032986 4:0.0036900369 5:0.046687937 7:0.015212146 +1 1:0.748166 2:0.017115 3:0.036675 5:0.03132408 7:0.014192854 +1 1:0.754098 2:0.02459 3:0.045082 5:0.02242333 7:0.016618354 +1 1:0.776256 2:0.009132 3:0.021309 5:0.013477852 7:0.015397037 +1 1:0.761468 2:0.013761 3:0.041284 5:0.039867011 7:0.015691433 +1 1:0.764463 2:0.016529 3:0.03719 5:0.035550818 7:0.015848622 +1 1:0.764706 2:0.007353 3:0.080882 5:0.016713133 7:0.019996415 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.786942 2:0.013746 3:0.034364 5:0.023712969 7:0.019759451 +1 1:0.762987 2:0.012987 3:0.022727 5:0.02070878 7:0.014254037 +1 1:0.761029 2:0.014706 3:0.033088 5:0.030593532 7:0.016387195 +1 1:0.765472 2:0.013029 3:0.032573 5:0.026344431 7:0.016862634 +1 1:0.774704 2:0.011858 3:0.039526 5:0.031584989 7:0.01706353 +1 1:0.781609 2:0.005747 3:0.022989 5:0.017018771 7:0.01534903 +1 1:0.781818 2:0.006061 3:0.024242 5:0.016101859 7:0.017110128 +1 1:0.758721 2:0.020349 3:0.055233 5:0.027380615 7:0.019303037 +1 1:0.708633 2:0.061151 3:0.043165 5:0.058853786 6:0.023685024 7:0.016669591 +1 1:0.759657 2:0.021459 3:0.030043 5:0.03483518 7:0.016801006 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.751553 2:0.024845 3:0.043478 5:0.050258673 7:0.016853506 +1 1:0.788396 2:0.008532 3:0.030717 5:0.020470234 7:0.01894822 +1 1:0.756233 2:0.00554 3:0.058172 5:0.0071563819 7:0.017600165 +1 1:0.732558 2:0.017442 3:0.046512 5:0.027477524 7:0.01442853 +1 1:0.715976 2:0.029586 3:0.059172 7:0.014792896 +1 1:0.676056 2:0.105634 3:0.084507 5:0.11398774 7:0.028083134 +1 1:0.733577 2:0.025547 3:0.036496 5:0.042841382 7:0.019360872 +1 1:0.766404 2:0.015748 3:0.020997 5:0.021715146 7:0.01648422 +1 1:0.776371 2:0.012658 3:0.046414 5:0.030101531 7:0.019115982 +1 1:0.747967 2:0.020325 3:0.036585 5:0.024063334 7:0.015355445 +1 1:0.694175 2:0.053398 3:0.053398 5:0.074247462 6:0.005976006 7:0.014859104 +1 1:0.792899 2:0.011834 3:0.029586 5:0.013552398 7:0.019844134 +1 1:0.764045 2:0.030899 3:0.033708 5:0.012985851 7:0.019662921 +1 1:0.655629 2:0.099338 3:0.10596 5:0.019650232 6:0.0094890095 7:0.076603134 8:0.023809524 +1 1:0.744681 2:0.042553 3:0.042553 5:0.043303565 6:0.0074700075 7:0.019541384 +1 1:0.726115 2:0.070064 3:0.063694 5:0.066658715 7:0.026060274 +1 1:0.748971 2:0.00823 3:0.041152 5:0.0098623887 7:0.018970189 +1 1:0.781759 2:0.016287 3:0.032573 5:0.023198605 7:0.019146738 +1 1:0.803704 2:0.018519 3:0.025926 6:0.0064440064 7:0.021025293 +1 1:0.792929 2:0.017677 3:0.035354 5:0.021715146 7:0.021141293 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.762136 2:0.029126 3:0.019417 5:0.025576611 6:0.01029301 7:0.017256689 +1 1:0.748175 2:0.025547 3:0.036496 5:0.039598646 7:0.016757165 +1 1:0.690289 2:0.036745 3:0.057743 4:0.0036900369 5:0.075298555 7:0.020597274 +1 1:0.758621 2:0.028736 3:0.051724 5:0.051764495 7:0.02018503 +1 1:0.773077 2:0.030769 3:0.069231 5:0.027671343 7:0.044230768 +1 1:0.729858 2:0.037915 3:0.047393 5:0.050541947 6:0.0050850051 7:0.017050055 +1 1:0.75 2:0.047297 3:0.047297 5:0.0463003 7:0.019899476 +1 1:0.772549 2:0.011765 3:0.054902 5:0.026068612 7:0.0205165 +1 1:0.740426 2:0.025532 3:0.06383 5:0.063624707 7:0.018240787 +1 1:0.76875 2:0.03125 3:0.04375 5:0.030198441 6:0.0034710035 7:0.032926829 +1 1:0.782967 2:0.013736 3:0.057692 5:0.029676621 7:0.021039933 +1 1:0.754717 2:0.012579 3:0.056604 5:0.032203718 7:0.017755793 +1 1:0.73224 2:0.046448 3:0.02459 5:0.023370059 6:0.028212028 7:0.015943622 +1 1:0.717514 2:0.039548 3:0.033898 5:0.054149956 7:0.01422764 +1 1:0.731034 2:0.048276 3:0.034483 5:0.057049782 6:0.015306015 7:0.016484439 +1 1:0.7713 2:0.013453 3:0.03139 5:0.025017518 7:0.016296622 +1 1:0.735294 2:0.029412 3:0.044118 7:0.015512915 +1 1:0.726776 2:0.060109 3:0.087432 5:0.035327181 6:0.0047400047 7:0.042183128 +1 1:0.731023 2:0.041254 3:0.029703 5:0.054485411 6:0.007974008 7:0.01514328 +1 1:0.746575 2:0.027397 3:0.082192 4:0.0036900369 5:0.014760038 7:0.021090878 +1 1:0.780702 2:0.01462 3:0.040936 5:0.029549893 7:0.017989585 +1 1:0.747664 2:0.014019 3:0.042056 5:0.046017026 7:0.013847732 +1 1:0.726776 2:0.043716 3:0.04918 5:0.041111923 6:0.011028011 7:0.018126085 +1 1:0.775785 2:0.013453 3:0.03139 5:0.024242244 7:0.016816146 +1 1:0.794595 2:0.005405 3:0.032432 5:0.012404395 7:0.019808835 +1 1:0.776243 2:0.008287 3:0.022099 5:0.016400042 7:0.01531128 +1 1:0.789062 2:0.03125 3:0.015625 6:0.014118014 7:0.020245805 +1 1:0.728051 2:0.062098 3:0.03212 5:0.043691202 6:0.030768031 7:0.017822634 +1 1:0.755448 2:0.021792 3:0.026634 5:0.0060680154 7:0.01813028 +1 1:0.777586 2:0.012069 3:0.037931 5:0.024860972 7:0.018912951 +1 1:0.657658 2:0.006006 3:0.051051 5:0.018614047 7:0.01466711 +1 1:0.780985 2:0.01528 3:0.028862 5:0.0085802037 7:0.01798211 +1 1:0.769036 2:0.038071 3:0.022843 5:0.025658611 6:0.018072018 7:0.017983165 +1 1:0.601124 2:0.022472 3:0.05618 5:0.062253068 7:0.016408604 +1 1:0.698262 2:0.07109 3:0.053712 5:0.06374398 6:0.015090015 7:0.01915 +1 1:0.784946 2:0.009217 3:0.026114 5:0.020090051 7:0.017374768 +1 1:0.774457 2:0.013587 3:0.038043 5:0.018271137 7:0.020281018 +1 1:0.775578 2:0.016502 3:0.052805 5:0.034864998 7:0.021512518 +1 1:0.767391 2:0.015217 3:0.028261 5:0.024786427 7:0.015946445 +1 1:0.759146 2:0.02439 3:0.045732 5:0.030772442 6:0.0061920062 7:0.018013829 +1 1:0.81295 2:0.019185 3:0.023981 5:0.03277772 6:0.0018840019 7:0.023278939 8:0.023809524 +1 1:0.743649 2:0.020785 3:0.032333 5:0.037951188 7:0.019362927 +1 1:0.737778 2:0.044444 3:0.048889 4:0.0036900369 5:0.070885453 6:0.014262014 7:0.017100274 +1 1:0.787736 2:0.009434 3:0.018868 5:0.012553486 7:0.017084677 +1 1:0.759036 2:0.02008 3:0.036145 5:0.044906296 6:0.0045180045 7:0.016260165 +1 1:0.751479 2:0.023669 3:0.035503 5:0.016713133 7:0.016091787 +1 1:0.774834 2:0.006623 3:0.072848 5:0.0075291101 7:0.03997739 +1 1:0.782271 2:0.010886 3:0.03888 5:0.014663128 7:0.019288396 +1 1:0.746269 2:0.0199 3:0.044776 5:0.028133526 7:0.016078146 +1 1:0.631579 2:0.086124 3:0.07177 5:0.062431977 6:0.03015003 7:0.017417433 +1 1:0.761905 2:0.019048 3:0.047619 5:0.035670091 7:0.018205573 +1 1:0.7625 2:0.05625 3:0.09375 5:0.023705515 7:0.083879573 +1 1:0.780645 2:0.012903 3:0.021505 5:0.011405484 7:0.017138738 +1 1:0.764881 2:0.014881 3:0.032738 5:0.023056968 7:0.017603079 +1 1:0.745763 2:0.028249 3:0.045198 5:0.013477852 7:0.019050573 +1 1:0.738095 2:0.027778 3:0.027778 5:0.039934102 7:0.013550134 +1 1:0.718121 2:0.033557 3:0.033557 5:0.043340838 7:0.014077591 +1 1:0.797386 2:0.013072 3:0.039216 5:0.013574762 7:0.021879482 +1 1:0.767361 2:0.024306 3:0.034722 5:0.017056043 6:0.0068640069 7:0.018504402 +1 1:0.767528 2:0.02214 3:0.02214 5:0.010168026 7:0.016492665 +1 1:0.748603 2:0.019553 3:0.041899 5:0.034000268 7:0.014937323 +1 1:0.763359 2:0.012723 3:0.033079 5:0.03842828 7:0.015049957 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.758089 2:0.026194 3:0.040062 5:0.018785502 6:0.0090720091 7:0.018640311 +1 1:0.77 2:0.026 3:0.028 5:0.020753507 6:0.0041760042 7:0.01752439 +1 1:0.722101 2:0.032823 3:0.041575 5:0.067881264 7:0.016117841 +1 1:0.68323 2:0.018634 3:0.080745 5:0.059957062 7:0.014126646 +1 1:0.695312 2:0.039062 3:0.050781 4:0.011070111 5:0.089044772 7:0.013957695 +1 1:0.755932 2:0.013559 3:0.040678 5:0.038927735 7:0.015832988 +1 1:0.756044 2:0.01978 3:0.057143 4:0.0036900369 5:0.047686849 7:0.018855537 +1 1:0.703488 2:0.052326 3:0.05814 5:0.086681675 7:0.021341463 +1 1:0.670732 2:0.081301 3:0.044715 5:0.034618997 6:0.046440046 7:0.016012293 +1 1:0.789474 2:0.009569 3:0.07177 5:0.0045621934 7:0.047701018 +1 1:0.758794 2:0.025126 3:0.030151 5:0.027917344 7:0.016362299 +1 1:0.809187 2:0.003534 3:0.035336 5:0.0080360205 7:0.019994829 +1 1:0.72449 2:0.017007 3:0.054422 5:0.037802096 7:0.02044964 +1 1:0.780303 2:0.007576 3:0.022727 5:0.020649143 7:0.016675902 +1 1:0.730159 2:0.071429 3:0.031746 5:0.042595381 6:0.042858043 7:0.016937671 +1 1:0.743191 2:0.027237 3:0.019455 5:0.038159915 7:0.01390339 +1 1:0.677852 2:0.09396 3:0.026846 5:0.073442369 6:0.044334044 7:0.016614829 +1 1:0.727838 2:0.051322 3:0.076205 5:0.064824892 7:0.022901415 +1 1:0.759494 2:0.016878 3:0.059072 5:0.030846988 7:0.018652878 +1 1:0.772541 2:0.014344 3:0.036885 5:0.029959894 7:0.018655037 +1 1:0.73348 2:0.024229 3:0.035242 5:0.022058056 7:0.01361878 +1 1:0.728238 2:0.031847 3:0.031847 5:0.045182115 6:0.0025980026 7:0.014952616 +1 1:0.710744 2:0.033058 3:0.082645 5:0.063714162 7:0.017687963 +1 1:0.741379 2:0.028736 3:0.04023 5:0.047783758 7:0.016400335 8:0.023809524 +1 1:0.75 2:0.021277 3:0.037234 5:0.023742788 7:0.020368445 +1 1:0.758671 2:0.028902 3:0.024566 5:0.019068776 6:0.0061380061 7:0.017226494 +1 1:0.7691 2:0.023769 3:0.027165 5:0.025099518 7:0.01844797 +1 1:0.773399 2:0.014778 3:0.039409 5:0.017100771 6:0.0045870046 7:0.01964436 +1 1:0.782857 2:0.011429 3:0.057143 5:0.025926975 7:0.020034841 +1 1:0.690909 2:0.031818 3:0.05 5:0.064713074 7:0.015964524 +1 1:0.76644 2:0.011338 3:0.024943 5:0.028290072 7:0.014573311 +1 1:0.51497 2:0.065868 3:0.113772 5:0.13052942 7:0.018767341 +1 1:0.779592 2:0.020408 3:0.044898 5:0.03380645 7:0.02195122 +1 1:0.773109 2:0.008403 3:0.033613 5:0.022251875 7:0.017165402 +1 1:0.768519 2:0.046296 3:0.074074 5:0.016653497 6:0.0038280038 7:0.058980726 +1 1:0.75 2:0.021552 3:0.060345 5:0.039032099 7:0.020079896 +1 1:0.752 2:0.016 3:0.04 5:0.022728967 7:0.016 +1 1:0.762215 2:0.013029 3:0.035831 5:0.036721184 7:0.01612775 +1 1:0.758748 2:0.023941 3:0.027624 5:0.023966425 7:0.017461707 +1 1:0.73913 2:0.034783 3:0.037681 5:0.050087218 6:0.0033600034 7:0.015782963 +1 1:0.731618 2:0.033088 3:0.036765 5:0.048014849 7:0.013921268 +1 1:0.761506 2:0.037657 3:0.079498 5:0.015557676 6:0.0037560038 7:0.061128689 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.61157 2:0.07438 3:0.066116 5:0.11380884 6:0.015267015 7:0.019804476 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.684058 2:0.055072 3:0.081159 4:0.0036900369 5:0.10353645 6:0.0096150096 7:0.016542945 +1 1:0.71978 2:0.049451 3:0.038462 6:0.035376035 7:0.014205305 +1 1:0.703704 2:0.02963 3:0.066667 5:0.098735706 7:0.01364047 +1 1:0.732673 2:0.024752 3:0.019802 5:0.037183367 7:0.012104567 +1 1:0.797101 2:0.006441 3:0.040258 5:0.013753671 7:0.021287457 +1 1:0.740506 2:0.044304 3:0.03481 5:0.037653005 6:0.015153015 7:0.019103116 +1 1:0.693252 2:0.042945 3:0.042945 5:0.020425507 7:0.013654049 +1 1:0.790451 2:0.023873 3:0.02122 5:0.0060307426 6:0.0097080097 7:0.019990945 +1 1:0.776699 2:0.014563 3:0.038835 5:0.024048425 7:0.018351884 +1 1:0.564286 2:0.228571 3:0.021429 4:0.0036900369 5:0.050258673 6:0.16179916 7:0.01938153 +1 1:0.703963 2:0.020979 3:0.04662 5:0.035632818 7:0.014867244 8:0.047619048 +1 1:0.64898 2:0.122449 3:0.044898 4:0.0036900369 5:0.034566815 6:0.097371097 7:0.016102537 +1 1:0.780347 2:0.00578 3:0.104046 5:0.0062096522 7:0.042330463 +1 1:0.800554 2:0.00554 3:0.041551 5:0.011390574 7:0.022109994 +1 1:0.756757 2:0.048649 3:0.021622 6:0.033333033 7:0.017798287 +1 1:0.793939 2:0.006061 3:0.036364 7:0.019438287 +1 1:0.781784 2:0.01518 3:0.037951 5:0.027440252 7:0.018859628 +1 1:0.768707 2:0.013605 3:0.027211 5:0.018494774 7:0.016716445 +1 1:0.773019 2:0.008565 3:0.027837 5:0.011107301 7:0.017522329 +1 1:0.766807 2:0.014706 3:0.058824 5:0.032248446 7:0.020726585 +1 1:0.752066 2:0.016529 3:0.041322 5:0.02258733 7:0.016629713 +1 1:0.803279 2:0.008197 3:0.032787 7:0.021141543 +1 1:0.764085 2:0.024648 3:0.035211 5:0.018382956 7:0.017412402 +1 1:0.761787 2:0.024814 3:0.024814 5:0.019113503 7:0.017702598 +1 1:0.779221 2:0.017316 3:0.030303 5:0.023630969 7:0.01665611 +1 1:0.770073 2:0.032847 3:0.036496 5:0.032837356 6:0.013215013 7:0.020206518 +1 1:0.767956 2:0.01105 3:0.044199 5:0.011539666 7:0.021762567 +1 1:0.702222 2:0.075556 3:0.022222 5:0.08454967 6:0.03969904 7:0.014336043 +1 1:0.767442 2:0.015504 3:0.062016 5:0.033962996 7:0.020750616 +1 1:0.725762 2:0.033241 3:0.049861 5:0.067083625 6:0.0033750034 7:0.015015878 +1 1:0.732558 2:0.02907 3:0.034884 5:0.052867771 7:0.014995744 +1 1:0.809211 2:0.003289 3:0.026316 5:0.0074396553 7:0.020097884 +1 1:0.773936 2:0.013298 3:0.034574 5:0.013589671 7:0.017789957 +1 1:0.75 2:0.024194 3:0.040323 5:0.023519151 7:0.015588122 +1 1:0.780105 2:0.031414 3:0.057592 5:0.040165193 7:0.029625848 +1 1:0.754098 2:0.027322 3:0.060109 5:0.050027582 7:0.019858726 +1 1:0.724958 2:0.033956 3:0.027165 5:0.038115188 7:0.014172427 +1 1:0.77937 2:0.014327 3:0.034384 5:0.014305309 7:0.018205323 +1 1:0.74569 2:0.064655 3:0.025862 5:0.0284168 6:0.038118038 7:0.020684396 +1 1:0.748031 2:0.03937 3:0.03937 6:0.0082200082 7:0.017524488 +1 1:0.761364 2:0.022727 3:0.028409 5:0.033426267 7:0.015451774 +1 1:0.721374 2:0.019084 3:0.045802 5:0.044705023 7:0.015523183 +1 1:0.687023 2:0.038168 3:0.099237 5:0.08693513 7:0.015965372 +1 1:0.700617 2:0.037037 3:0.052469 5:0.055633414 7:0.015130988 +1 1:0.755102 2:0.020408 3:0.020408 7:0.013787957 +1 1:0.751111 2:0.031111 3:0.035556 5:0.012762214 6:0.0051360051 7:0.015826561 +1 1:0.780702 2:0.01462 3:0.040936 5:0.029549893 7:0.017989585 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.75 2:0.014286 3:0.021429 7:0.01241289 +1 1:0.748503 2:0.011976 3:0.047904 5:0.035707364 7:0.015243902 +1 1:0.708154 2:0.051502 3:0.038627 5:0.085354763 6:0.017175017 7:0.01371297 +1 1:0.6917 2:0.043478 3:0.079051 5:0.10619027 7:0.016918927 +1 1:0.754286 2:0.017143 3:0.04 5:0.03320263 7:0.015644598 +1 1:0.774266 2:0.022573 3:0.047404 5:0.013977308 6:0.0075000075 7:0.022022793 +1 1:0.738806 2:0.041045 3:0.026119 5:0.041999016 7:0.016153988 +1 1:0.788235 2:0.015686 3:0.058824 5:0.029997167 7:0.02376853 +1 1:0.778761 2:0.004425 3:0.035398 5:0.011815485 7:0.017024604 +1 1:0.75814 2:0.027907 3:0.046512 5:0.02310915 6:0.0013290013 7:0.032019287 +1 1:0.774381 2:0.010189 3:0.032023 5:0.026896068 7:0.017218732 +1 1:0.73913 2:0.046823 3:0.033445 5:0.045621934 6:0.022032022 7:0.016661226 +1 1:0.713115 2:0.040984 3:0.081967 5:0.019314776 6:0.015543016 7:0.01929228 +1 1:0.768489 2:0.019293 3:0.027331 5:0.012710032 6:0.0034080034 7:0.017253549 +1 1:0.745583 2:0.014134 3:0.053004 5:0.026247521 7:0.018357323 +1 1:0.76338 2:0.019718 3:0.028169 5:0.031860808 7:0.016076951 +1 1:0.742331 2:0.02454 3:0.03681 5:0.017495863 7:0.015935957 +1 1:0.729167 2:0.026786 3:0.059524 5:0.032412446 7:0.016695701 +1 1:0.68 2:0.066667 3:0.066667 5:0.065779077 6:0.022059022 7:0.018428183 +1 1:0.775432 2:0.011516 3:0.028791 5:0.026642613 7:0.016373299 +1 1:0.788235 2:0.017647 3:0.023529 6:0.011835012 7:0.018185079 +1 1:0.769231 2:0.00905 3:0.027149 5:0.021640601 7:0.019010043 +1 1:0.792517 2:0.003401 3:0.034014 5:0.0081329298 7:0.019018585 +1 1:0.788396 2:0.017065 3:0.030717 5:0.016049677 7:0.019333226 +1 1:0.792711 2:0.006834 3:0.036446 5:0.015490585 7:0.020056671 +1 1:0.74938 2:0.024814 3:0.029777 5:0.034671179 6:0.0055800056 7:0.016265207 +1 1:0.72093 2:0.034884 3:0.069767 5:0.093964785 7:0.016874646 +1 1:0.78125 2:0.015625 3:0.021875 5:0.0081702026 7:0.017378049 +1 1:0.713568 2:0.045226 3:0.045226 5:0.072726731 6:0.0097560098 7:0.01884422 +1 1:0.760949 2:0.027372 3:0.034672 5:0.038622098 7:0.017179988 +1 1:0.755319 2:0.015957 3:0.069149 5:0.026575522 6:0.0053490053 7:0.018195384 +1 1:0.759657 2:0.021459 3:0.030043 5:0.03483518 7:0.016801006 +1 1:0.735426 2:0.058296 3:0.035874 5:0.029900258 6:0.004011004 7:0.020452805 +1 1:0.723881 2:0.029851 3:0.044776 5:0.046449391 7:0.014606841 +1 1:0.709172 2:0.082774 3:0.04698 5:0.07308455 6:0.021672022 7:0.026436402 +1 1:0.78481 2:0.006329 3:0.025316 5:0.017100771 7:0.016826183 +1 1:0.691489 2:0.049645 3:0.031915 5:0.028379527 6:0.019035019 7:0.017038573 +1 1:0.758377 2:0.035273 3:0.024691 4:0.0036900369 5:0.039583737 6:0.010620011 7:0.018228159 +1 1:0.739806 2:0.038835 3:0.040777 5:0.0428712 6:0.0086280086 7:0.016469335 +1 1:0.752427 2:0.024272 3:0.063107 5:0.034618997 7:0.019121476 +1 1:0.762248 2:0.017291 3:0.033141 5:0.020589507 6:0.0033150033 7:0.01590286 +1 1:0.739645 2:0.017751 3:0.04142 5:0.024667154 7:0.014540335 +1 1:0.774194 2:0.032258 3:0.016129 5:0.021357327 6:0.017193017 7:0.017161683 +1 1:0.76 2:0.058182 3:0.047273 5:0.03183099 6:0.015372015 7:0.025964524 +1 1:0.61157 2:0.008264 3:0.115702 5:0.020149688 7:0.018645433 +1 1:0.530612 2:0.244898 3:0.047619 4:0.0036900369 5:0.052867771 6:0.15602716 7:0.017546043 +1 1:0.766129 2:0.012097 3:0.040323 5:0.029311347 7:0.018759835 +1 1:0.770349 2:0.017442 3:0.026163 5:0.01540113 7:0.01715825 +1 1:0.767152 2:0.018711 3:0.045738 5:0.031957718 7:0.02070128 8:0.023809524 +1 1:0.716216 2:0.033784 3:0.074324 5:0.066263623 7:0.018539878 +1 1:0.76087 2:0.034783 3:0.052174 5:0.028782073 7:0.020599152 +1 1:0.771226 2:0.014151 3:0.044811 5:0.030779897 7:0.017415439 +1 1:0.736142 2:0.031042 3:0.031042 5:0.033642449 7:0.014980262 +1 1:0.768456 2:0.006711 3:0.050336 5:0.016623679 7:0.018354067 +1 1:0.715084 2:0.027933 3:0.067039 5:0.079473111 7:0.015976293 +1 1:0.772182 2:0.009592 3:0.035971 5:0.025636247 7:0.017005909 +1 1:0.760563 2:0.016901 3:0.050704 5:0.042513381 7:0.01806939 +1 1:0.75188 2:0.011278 3:0.045113 5:0.010555663 7:0.01618375 +1 1:0.736501 2:0.049676 3:0.043197 5:0.056617417 6:0.011391011 7:0.020808091 +1 1:0.771154 2:0.009615 3:0.026923 5:0.013269125 7:0.019758445 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.721311 2:0.02459 3:0.065574 5:0.024279516 7:0.01534386 +1 1:0.754522 2:0.028424 3:0.023256 5:0.03269572 6:0.010527011 7:0.017961805 +1 1:0.759162 2:0.015707 3:0.057592 5:0.026292249 7:0.018101134 +1 1:0.757669 2:0.039877 3:0.027607 5:0.031219716 6:0.015708016 7:0.017862488 +1 1:0.74269 2:0.011696 3:0.038012 5:0.02730607 7:0.014602055 +1 1:0.789883 2:0.027237 3:0.035019 5:0.016221132 6:0.0097920098 7:0.021804122 +1 1:0.717391 2:0.021739 3:0.048913 5:0.019359504 7:0.012758482 +1 1:0.769424 2:0.012531 3:0.025063 5:0.014133854 7:0.016122622 +1 1:0.765376 2:0.015945 3:0.029613 5:0.026292249 6:0.0026460026 7:0.015750872 +1 1:0.747253 2:0.025641 3:0.032967 5:0.028632982 7:0.017443939 +1 1:0.709924 2:0.038168 3:0.057252 5:0.076849105 7:0.015802457 +1 1:0.734597 2:0.023697 3:0.061611 5:0.03875628 7:0.016674372 +1 1:0.781716 2:0.007463 3:0.04291 5:0.018181683 7:0.018656713 +1 1:0.774194 2:0.016129 3:0.064516 5:0.035841546 7:0.020456335 +1 1:0.764331 2:0.019108 3:0.028662 5:0.01616895 7:0.017904305 +1 1:0.75 2:0.053571 3:0.047619 5:0.011651484 6:0.0093750094 7:0.023228805 +1 1:0.812865 2:0.011696 3:0.046784 5:0.010786755 7:0.024639854 +1 1:0.789883 2:0.019455 3:0.035019 5:0.020149688 6:0.0032430032 7:0.021946476 +1 1:0.805405 2:0.005405 3:0.040541 5:0.01130112 7:0.021736982 +1 1:0.765766 2:0.015015 3:0.04955 5:0.03447736 7:0.019794183 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.772632 2:0.008421 3:0.029474 5:0.012441668 7:0.015378689 +1 1:0.772894 2:0.014652 3:0.047619 5:0.026247521 7:0.01902975 +1 1:0.743902 2:0.036585 3:0.018293 5:0.019463868 7:0.014240037 +1 1:0.779935 2:0.016181 3:0.035599 5:0.024361517 7:0.018115085 +1 1:0.780564 2:0.021944 3:0.015674 5:0.017316953 6:0.01045201 7:0.016457677 +1 1:0.749141 2:0.027491 3:0.051546 5:0.04202138 7:0.018586037 +1 1:0.774319 2:0.019455 3:0.031128 5:0.020395688 7:0.017343646 +1 1:0.769578 2:0.012048 3:0.046687 5:0.017823864 7:0.019201805 +1 1:0.760684 2:0.025641 3:0.042735 5:0.020850417 7:0.018631439 +1 1:0.719457 2:0.067873 3:0.108597 5:0.050124491 7:0.028721994 +1 1:0.671533 2:0.014599 3:0.094891 5:0.048566487 7:0.013663878 +1 1:0.780488 2:0.02439 3:0.060976 5:0.036482638 7:0.022791494 +1 1:0.777778 2:0.020833 3:0.03125 5:0.026433885 7:0.017911585 +1 1:0.77 2:0.02 3:0.03 5:0.012441668 7:0.018262195 +1 1:0.708995 2:0.074074 3:0.05291 5:0.066263623 6:0.017778018 7:0.021777006 +1 1:0.744681 2:0.023404 3:0.038298 5:0.049736854 7:0.015555268 +1 1:0.631902 2:0.030675 3:0.079755 5:0.030869351 7:0.018068232 +1 1:0.77551 2:0.008163 3:0.028571 5:0.023593696 7:0.01572922 +1 1:0.772277 2:0.014851 3:0.024752 5:0.014089127 7:0.015968366 +1 1:0.753213 2:0.015424 3:0.048843 4:0.0036900369 5:0.041111923 7:0.01705436 +1 1:0.777251 2:0.028436 3:0.028436 5:0.023258241 6:0.014040014 7:0.018523872 +1 1:0.786408 2:0.009709 3:0.02589 5:0.0083416576 7:0.017641488 +1 1:0.79085 2:0.019608 3:0.039216 6:0.01033501 7:0.023134866 +1 1:0.710623 2:0.007326 3:0.076923 5:0.020477688 7:0.016260165 +1 1:0.768116 2:0.023188 3:0.028986 5:0.015945313 6:0.0064170064 7:0.016525274 +1 1:0.782895 2:0.015351 3:0.017544 5:0.012016758 7:0.016594457 +1 1:0.791878 2:0.005076 3:0.025381 5:0.011964576 7:0.019283146 +1 1:0.687679 2:0.108883 3:0.048711 5:0.086212038 6:0.037008037 7:0.022660561 +1 1:0.720096 2:0.04067 3:0.04067 5:0.055737778 6:0.0056070056 7:0.015608591 +1 1:0.681081 2:0.081081 3:0.048649 5:0.014171127 6:0.045627046 7:0.017336848 +1 1:0.769406 2:0.022831 3:0.018265 5:0.013336216 7:0.015564091 +1 1:0.740806 2:0.017513 3:0.073555 5:0.039561373 7:0.018111146 +1 1:0.689441 2:0.024845 3:0.111801 4:0.0073800738 5:0.031584989 7:0.017876079 +1 1:0.787736 2:0.033019 3:0.018868 5:0.010496027 6:0.012675013 7:0.020421079 +1 1:0.762248 2:0.017291 3:0.033141 5:0.020589507 6:0.0033150033 7:0.01590286 +1 1:0.726098 2:0.043928 3:0.041344 5:0.042722109 6:0.014328014 7:0.0164965 +1 1:0.780864 2:0.003086 3:0.027778 5:0.0089603864 7:0.015657933 +1 1:0.783193 2:0.010084 3:0.036975 5:0.020813144 7:0.018354171 +1 1:0.781553 2:0.009709 3:0.029126 5:0.02480879 7:0.017789488 +1 1:0.727273 2:0.019481 3:0.071429 5:0.04937158 7:0.017936329 +1 1:0.734403 2:0.033868 3:0.02852 5:0.042968109 7:0.015086299 +1 1:0.756303 2:0.021008 3:0.054622 5:0.028021708 7:0.020444762 +1 1:0.780822 2:0.006849 3:0.020548 5:0.0097580248 7:0.01595389 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.741538 2:0.024615 3:0.064615 5:0.056423598 7:0.019831146 +1 1:0.586614 2:0.137795 3:0.055118 5:0.10780046 6:0.043383043 7:0.021581524 +1 1:0.799065 2:0.023364 3:0.014019 6:0.0085350085 7:0.020030774 +1 1:0.813559 2:0.004843 3:0.062954 5:0.0038912826 7:0.028287957 +1 1:0.772401 2:0.017921 3:0.03405 5:0.022743876 7:0.01791022 +1 1:0.7669 2:0.009324 3:0.039627 5:0.019359504 7:0.016416512 +1 1:0.745399 2:0.01227 3:0.02454 5:0.025502065 7:0.016403561 +1 1:0.769912 2:0.017699 3:0.048673 5:0.039598646 7:0.020316207 +1 1:0.793313 2:0.012158 3:0.039514 5:0.022810967 7:0.024223439 +1 1:0.771429 2:0.014286 3:0.028571 5:0.025099518 7:0.017247384 +1 1:0.753316 2:0.01061 3:0.039788 5:0.033500813 7:0.014394774 +1 1:0.696335 2:0.057592 3:0.031414 4:0.0036900369 5:0.056796326 6:0.017142017 7:0.016760311 +1 1:0.729508 2:0.057377 3:0.02459 5:0.066360533 6:0.026706027 7:0.016843262 +1 1:0.779703 2:0.019802 3:0.024752 5:0.0061872885 6:0.0074700075 7:0.01818703 +1 1:0.718427 2:0.049689 3:0.031056 5:0.050281037 6:0.022767023 7:0.014972482 +1 1:0.783333 2:0.016667 3:0.041667 5:0.014394764 7:0.02632114 +1 1:0.685567 2:0.048969 3:0.054124 5:0.066114532 7:0.014175256 +1 1:0.746667 2:0.026667 3:0.113333 5:0.034350633 7:0.026463415 +1 1:0.730263 2:0.013158 3:0.036184 5:0.028454072 7:0.015765402 +1 1:0.77551 2:0.010204 3:0.022959 5:0.022318966 6:0.002994003 7:0.015586116 +1 1:0.740196 2:0.029412 3:0.034314 5:0.030302804 7:0.014705884 +1 1:0.671875 2:0.101562 3:0.054688 5:0.059957062 6:0.064344064 7:0.017768671 +1 1:0.801471 2:0.003676 3:0.025735 5:0.0093405692 7:0.017889171 +1 1:0.733333 2:0.012121 3:0.060606 5:0.017577863 7:0.015668884 +1 1:0.752941 2:0.043137 3:0.031373 5:0.038875554 6:0.011733012 7:0.018340506 +1 1:0.77551 2:0.013605 3:0.034014 5:0.019068776 7:0.016218683 +1 1:0.732283 2:0.041995 3:0.028871 5:0.047127756 6:0.012645013 7:0.01518789 +1 1:0.752294 2:0.073394 3:0.036697 5:0.033948086 6:0.019125019 7:0.030711567 +1 1:0.770115 2:0.019157 3:0.049808 5:0.043952112 7:0.019811232 +1 1:0.778281 2:0.0181 3:0.022624 5:0.012531123 7:0.016416512 +1 1:0.765625 2:0.015625 3:0.052083 5:0.040008647 7:0.017752793 +1 1:0.771008 2:0.018908 3:0.02521 5:0.02831989 6:0.0045600046 7:0.016857963 +1 1:0.726667 2:0.013333 3:0.06 5:0.018874957 7:0.016056909 +1 1:0.767296 2:0.006289 3:0.050314 7:0.016375207 +1 1:0.783626 2:0.011696 3:0.023392 5:0.015184948 7:0.017508201 +1 1:0.782609 2:0.036232 3:0.014493 5:0.019210413 6:0.023196023 7:0.017143866 +1 1:0.756554 2:0.007491 3:0.048689 4:0.011070111 5:0.0096536609 7:0.017630402 +1 1:0.78972 2:0.009346 3:0.023364 5:0.01265785 7:0.016782543 +1 1:0.754647 2:0.011152 3:0.04461 5:0.02096969 7:0.016116604 +1 1:0.769841 2:0.015873 3:0.047619 5:0.030869351 7:0.023373982 +1 1:0.784866 2:0.017804 3:0.031157 5:0.020753507 6:0.0027840028 7:0.019495909 +1 1:0.645669 2:0.165354 3:0.031496 5:0.035580636 6:0.1002391 7:0.020117152 +1 1:0.758209 2:0.01194 3:0.020896 5:0.0097431157 7:0.01392428 +1 1:0.756345 2:0.025381 3:0.030457 5:0.028290072 6:0.0056940057 7:0.01631175 +1 1:0.738095 2:0.066667 3:0.02619 5:0.0097058429 6:0.035157035 7:0.022299652 +1 1:0.711864 2:0.062147 3:0.042373 5:0.04937158 6:0.043047043 7:0.015605622 +1 1:0.788396 2:0.008532 3:0.030717 5:0.020470234 7:0.01894822 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.729097 2:0.023411 3:0.056856 5:0.048849761 7:0.015559994 +1 1:0.791139 2:0.009494 3:0.028481 5:0.016362769 7:0.017578726 +1 1:0.724868 2:0.026455 3:0.071429 5:0.029892803 7:0.0201155 +1 1:0.741641 2:0.033435 3:0.033435 5:0.018755684 6:0.018867019 7:0.014734226 +1 1:0.761006 2:0.037736 3:0.054507 5:0.048350305 6:0.0032430032 7:0.023648823 +1 1:0.761494 2:0.031609 3:0.022989 5:0.021752419 7:0.018012335 +1 1:0.730061 2:0.02454 3:0.067485 5:0.047478121 7:0.017619329 +1 1:0.763578 2:0.015974 3:0.028754 5:0.033277176 7:0.017455 +1 1:0.772908 2:0.021912 3:0.031873 5:0.035863909 6:0.0082470082 7:0.017673207 +1 1:0.787671 2:0.006849 3:0.054795 5:0.0068507447 7:0.022719677 +1 1:0.789137 2:0.01278 3:0.041534 5:0.028975892 7:0.020045976 +1 1:0.676647 2:0.02994 3:0.053892 5:0.017138044 6:0.0068970069 7:0.015882866 +1 1:0.709184 2:0.045918 3:0.05102 5:0.062856887 6:0.0050580051 7:0.018448232 +1 1:0.76054 2:0.020236 3:0.037099 5:0.038271734 7:0.018025335 +1 1:0.792873 2:0.008909 3:0.026726 5:0.016787679 7:0.018088976 +1 1:0.738095 2:0.02381 3:0.042857 7:0.0141115 +1 1:0.756545 2:0.04712 3:0.036649 5:0.03790646 6:0.012711013 7:0.018835396 +1 1:0.748175 2:0.025547 3:0.036496 5:0.039598646 7:0.016757165 +1 1:0.783259 2:0.005979 3:0.028401 5:0.008043475 7:0.016889061 +1 1:0.639498 2:0.087774 3:0.034483 5:0.0089454773 6:0.0063000063 7:0.095573061 +1 1:0.741811 2:0.026975 3:0.040462 5:0.026322067 7:0.016636122 +1 1:0.769231 2:0.020979 3:0.041958 5:0.034037541 7:0.018676445 +1 1:0.748344 2:0.022075 3:0.057395 5:0.038286643 7:0.018346524 +1 1:0.748276 2:0.024138 3:0.041379 5:0.034156814 7:0.018355762 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.748344 2:0.013245 3:0.066225 5:0.033128084 7:0.018171537 +1 1:0.744648 2:0.021407 3:0.067278 5:0.050735766 7:0.019178415 +1 1:0.71978 2:0.049451 3:0.038462 6:0.035376035 7:0.014205305 +1 1:0.772964 2:0.017331 3:0.024263 5:0.01411149 7:0.016749799 +1 1:0.754286 2:0.017143 3:0.04 5:0.03320263 7:0.015644598 +1 1:0.706199 2:0.048518 3:0.067385 5:0.055946506 6:0.0084420084 7:0.017520213 +1 1:0.722581 2:0.051613 3:0.012903 5:0.019829141 6:0.031914032 7:0.014791506 +1 1:0.766667 2:0.016667 3:0.033333 5:0.02412297 7:0.01570122 +1 1:0.704819 2:0.024096 3:0.054217 5:0.082372937 7:0.013297091 +1 1:0.775194 2:0.011628 3:0.042636 5:0.0086920221 7:0.020277933 +1 1:0.78 2:0.005 3:0.02 5:0.013008215 7:0.017469512 +1 1:0.722581 2:0.045161 3:0.064516 5:0.082641301 7:0.017741939 +1 1:0.766917 2:0.017544 3:0.027569 5:0.029206983 7:0.01560303 +1 1:0.757576 2:0.016162 3:0.030303 5:0.010906028 6:0.0087780088 7:0.016839122 +1 1:0.764228 2:0.03252 3:0.04065 5:0.019359504 7:0.01908586 +1 1:0.727941 2:0.014706 3:0.058824 5:0.042722109 7:0.015647415 +1 1:0.722222 2:0.050505 3:0.035354 5:0.071541455 6:0.017274017 7:0.016044591 +1 1:0.737226 2:0.029197 3:0.051095 5:0.020880235 7:0.015889262 +1 1:0.762222 2:0.031111 3:0.04 5:0.042058653 6:0.0021150021 7:0.019214091 +1 1:0.754768 2:0.019074 3:0.046322 5:0.020999508 7:0.017694555 +1 1:0.713115 2:0.016393 3:0.02459 5:0.047783758 7:0.015593762 +1 1:0.763949 2:0.017167 3:0.06867 5:0.0081851117 7:0.04768136 +1 1:0.763889 2:0.013889 3:0.052083 5:0.02609843 7:0.018144476 +1 1:0.764706 2:0.017647 3:0.064706 5:0.037653005 7:0.021305598 +1 1:0.746032 2:0.015873 3:0.039683 5:0.025613883 7:0.014082463 +1 1:0.775148 2:0.011834 3:0.029586 7:0.016741232 +1 1:0.769874 2:0.016736 3:0.046025 5:0.04107465 7:0.018522299 +1 1:0.666667 2:0.028986 3:0.072464 5:0.049587763 7:0.019927537 +1 1:0.790281 2:0.007673 3:0.038363 5:0.018032591 7:0.01933753 +1 1:0.761658 2:0.031088 3:0.041451 4:0.0036900369 5:0.039032099 7:0.018103122 +1 1:0.760234 2:0.005848 3:0.052632 5:0.016422405 7:0.016188848 +1 1:0.773756 2:0.0181 3:0.040724 5:0.022728967 7:0.018099549 +1 1:0.709402 2:0.038462 3:0.068376 5:0.062752523 7:0.015478421 +1 1:0.697987 2:0.026846 3:0.100671 5:0.014819674 7:0.020584384 +1 1:0.735433 2:0.040945 3:0.03937 5:0.054537593 6:0.011817012 7:0.017063567 +1 1:0.742489 2:0.025751 3:0.042918 5:0.040008647 7:0.014628915 +1 1:0.754579 2:0.051282 3:0.043956 5:0.0391141 6:0.015741016 7:0.021285628 +1 1:0.743869 2:0.024523 3:0.059946 5:0.052823044 7:0.01875789 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.770073 2:0.010949 3:0.032847 5:0.03080226 7:0.016156311 +1 1:0.719512 2:0.041812 3:0.045296 5:0.068783266 6:0.0034590035 7:0.018420159 +1 1:0.774194 2:0.008065 3:0.024194 5:0.023742788 7:0.015440598 +1 1:0.734095 2:0.057096 3:0.047308 5:0.059166878 6:0.00091500092 7:0.03258664 +1 1:0.745679 2:0.022222 3:0.041975 5:0.055424687 7:0.016199939 +1 1:0.727941 2:0.044118 3:0.040441 5:0.048790124 6:0.0078540079 7:0.017126976 +1 1:0.761329 2:0.021148 3:0.02719 5:0.017480954 7:0.015713652 +1 1:0.692632 2:0.075789 3:0.050526 5:0.074247462 6:0.025896026 7:0.019332476 +1 1:0.743295 2:0.034483 3:0.065134 5:0.024600063 7:0.049551445 +1 1:0.742623 2:0.032787 3:0.040984 5:0.053628137 7:0.016673329 +1 1:0.689537 2:0.039451 3:0.034305 5:0.084445306 6:0.0037770038 7:0.016619256 +1 1:0.784849 2:0.009091 3:0.033333 5:0.016101859 7:0.017110128 +1 1:0.770186 2:0.018634 3:0.062112 5:0.042841382 7:0.019769732 +1 1:0.743455 2:0.031414 3:0.044503 5:0.027082433 6:0.0054510055 7:0.017574384 +1 1:0.779904 2:0.019139 3:0.062201 5:0.0394421 7:0.02205625 +1 1:0.752727 2:0.029091 3:0.032727 5:0.037272822 7:0.01773836 +1 1:0.775229 2:0.018349 3:0.041284 5:0.03499918 7:0.017873128 +1 1:0.771429 2:0.017857 3:0.035714 5:0.017316953 7:0.01875 +1 1:0.775551 2:0.01002 3:0.03006 5:0.020954781 7:0.017388433 +1 1:0.7775 2:0.015 3:0.0425 5:0.017950591 7:0.018993902 +1 1:0.64 2:0.113333 3:0.06 5:0.037653005 6:0.083334083 7:0.016097561 +1 1:0.714765 2:0.040268 3:0.060403 5:0.054947594 7:0.016655756 +1 1:0.772727 2:0.018939 3:0.022727 5:0.019642777 7:0.017530488 +1 1:0.75576 2:0.023041 3:0.050691 5:0.011308574 7:0.018517476 +1 1:0.748815 2:0.014218 3:0.037915 5:0.014968765 7:0.014391402 +1 1:0.72 2:0.02 3:0.06 5:0.020589507 7:0.014715445 +1 1:0.785924 2:0.008798 3:0.035191 5:0.022520239 7:0.017756244 +1 1:0.75 2:0.02551 3:0.035714 5:0.028506254 7:0.01627053 +1 1:0.732719 2:0.046083 3:0.029954 5:0.09918298 7:0.020062945 8:0.023809524 +1 1:0.772093 2:0.027907 3:0.027907 5:0.023116604 7:0.018292683 +1 1:0.73617 2:0.025532 3:0.055319 5:0.014484219 7:0.020031134 +1 1:0.772549 2:0.011765 3:0.054902 5:0.026068612 7:0.0205165 +1 1:0.740157 2:0.031496 3:0.047244 5:0.045040478 7:0.015892067 +1 1:0.744898 2:0.026531 3:0.018367 5:0.042237562 6:0.0084990085 7:0.017570933 +1 1:0.788204 2:0.005362 3:0.024129 5:0.0074694736 7:0.016314652 +1 1:0.755 2:0.04 3:0.08 5:0.013895308 6:0.0083880084 7:0.032713415 +1 1:0.783784 2:0.018018 3:0.058559 5:0.010846391 7:0.037766427 +1 1:0.796657 2:0.005571 3:0.027855 5:0.014118945 7:0.017936 +1 1:0.764026 2:0.016502 3:0.052805 5:0.0077900198 7:0.019258634 +1 1:0.74188 2:0.041026 3:0.032479 4:0.018450185 5:0.019903687 6:0.032043032 7:0.015613927 +1 1:0.762048 2:0.018072 3:0.027108 5:0.017354226 7:0.015776518 +1 1:0.719149 2:0.025532 3:0.046809 5:0.058235057 7:0.013284896 +1 1:0.748092 2:0.022901 3:0.076336 5:0.018494774 7:0.018758146 +1 1:0.777778 2:0.007937 3:0.02381 7:0.015001933 +1 1:0.762963 2:0.022222 3:0.059259 5:0.036273911 7:0.018563689 +1 1:0.652893 2:0.132231 3:0.024793 4:0.0036900369 5:0.05869724 6:0.086613087 7:0.019199756 +1 1:0.757098 2:0.015773 3:0.025237 5:0.019441504 7:0.014753402 +1 1:0.720588 2:0.022059 3:0.044118 4:0.0036900369 5:0.020537325 7:0.01627511 +1 1:0.67451 2:0.064706 3:0.064706 5:0.11125937 6:0.0040710041 7:0.017623146 +1 1:0.778894 2:0.005025 3:0.035176 5:0.013455489 7:0.016975122 +1 1:0.764706 2:0.008403 3:0.054622 5:0.010145662 7:0.018830701 +1 1:0.784884 2:0.005814 3:0.040698 5:0.015624767 7:0.016910098 +1 1:0.697561 2:0.097561 3:0.039024 5:0.067560717 6:0.036255036 7:0.019690659 +1 1:0.756839 2:0.033435 3:0.033435 5:0.022408421 6:0.018036018 7:0.018496555 +1 1:0.730964 2:0.020305 3:0.050761 5:0.063714162 7:0.014485573 +1 1:0.70428 2:0.054475 3:0.077821 5:0.097319339 7:0.018174055 +1 1:0.56 2:0.168889 3:0.115556 5:0.19509341 6:0.028926029 7:0.019674799 +1 1:0.732143 2:0.017857 3:0.035714 5:0.021178418 7:0.012775841 +1 1:0.811594 2:0.007246 3:0.036232 7:0.021518207 +1 1:0.728571 2:0.039286 3:0.039286 5:0.037913915 6:0.0091560092 7:0.021406793 +1 1:0.731707 2:0.018293 3:0.054878 5:0.048939215 7:0.016991372 +1 1:0.787535 2:0.014164 3:0.045326 5:0.017749318 7:0.021764665 +1 1:0.744856 2:0.022634 3:0.034979 5:0.040769013 7:0.016059421 +1 1:0.678322 2:0.076923 3:0.048951 5:0.079644566 6:0.012822013 7:0.019955652 +1 1:0.759657 2:0.021459 3:0.030043 5:0.03483518 7:0.016801006 +1 1:0.753968 2:0.087302 3:0.031746 5:0.05082522 6:0.034092034 7:0.021293073 +1 1:0.759009 2:0.040541 3:0.029279 5:0.017242408 6:0.020817021 7:0.017812018 +1 1:0.734234 2:0.016517 3:0.055556 5:0.0074843827 6:0.0015060015 7:0.018246902 +1 1:0.664062 2:0.0625 3:0.039062 5:0.067978173 6:0.018237018 7:0.015672634 +1 1:0.793313 2:0.00304 3:0.027356 5:0.0077303833 7:0.017866409 +1 1:0.7251 2:0.037849 3:0.071713 5:0.082268573 7:0.019811 +1 1:0.723404 2:0.01773 3:0.070922 4:0.0036900369 5:0.033657358 7:0.019157585 +1 1:0.761628 2:0.011628 3:0.037791 5:0.0249877 7:0.015864293 +1 1:0.711111 2:0.011111 3:0.061111 5:0.03842828 7:0.013143628 +1 1:0.796117 2:0.014563 3:0.058252 5:0.014655674 7:0.045169311 +1 1:0.726562 2:0.023438 3:0.0625 5:0.062819614 7:0.016958841 +1 1:0.72 2:0.026667 3:0.053333 5:0.068842903 7:0.015406506 +1 1:0.744681 2:0.024823 3:0.046099 5:0.039680646 6:0.003993004 7:0.016249354 +1 1:0.753535 2:0.018182 3:0.034343 5:0.016124223 7:0.017085488 +1 1:0.713768 2:0.032609 3:0.054348 5:0.055797415 7:0.014757866 +1 1:0.774436 2:0.015038 3:0.048872 5:0.0046516482 7:0.036722902 +1 1:0.754717 2:0.012579 3:0.050314 5:0.034119541 7:0.016758707 +1 1:0.739247 2:0.010753 3:0.037634 5:0.036273911 7:0.01347364 +1 1:0.768293 2:0.020325 3:0.036585 5:0.0097580248 7:0.01893714 +1 1:0.726287 2:0.03252 3:0.03523 5:0.026433885 6:0.0035460035 7:0.013979774 +1 1:0.764228 2:0.02439 3:0.03252 5:0.01873332 7:0.019730317 +1 1:0.772926 2:0.030568 3:0.026201 5:0.033836268 6:0.013617014 7:0.017600384 +1 1:0.710407 2:0.045249 3:0.063348 5:0.08352094 7:0.019699811 +1 1:0.773006 2:0.030675 3:0.067485 5:0.017652409 7:0.047396378 +1 1:0.746073 2:0.052356 3:0.028796 5:0.047821031 6:0.019245019 7:0.019904866 +1 1:0.764826 2:0.010225 3:0.02863 5:0.02456279 7:0.015137915 +1 1:0.784173 2:0.007194 3:0.02518 5:0.020067687 7:0.01629672 +1 1:0.737052 2:0.011952 3:0.067729 5:0.019829141 7:0.027402585 +1 1:0.792453 2:0.028302 3:0.040094 5:0.021595873 6:0.006951007 7:0.024821677 +1 1:0.785714 2:0.008929 3:0.03125 5:0.012121122 7:0.016741073 +1 1:0.732484 2:0.028662 3:0.066879 5:0.063445798 7:0.018253848 +1 1:0.731844 2:0.011173 3:0.117318 5:0.011159483 7:0.02275514 +1 1:0.792793 2:0.022523 3:0.018018 5:0.010928391 6:0.013197013 7:0.018732146 +1 1:0.760331 2:0.008264 3:0.033058 5:0.02720916 7:0.013807701 +1 1:0.769784 2:0.021583 3:0.064748 5:0.044369567 7:0.02210914 +1 1:0.744361 2:0.037594 3:0.022556 5:0.020649143 6:0.024930025 7:0.016550524 +1 1:0.746032 2:0.026455 3:0.037037 5:0.034194087 7:0.014066329 +1 1:0.786885 2:0.005464 3:0.027322 5:0.014282945 7:0.017393043 +1 1:0.78836 2:0.010582 3:0.037037 5:0.012762214 7:0.01884114 +1 1:0.710383 2:0.010929 3:0.071038 5:0.029288984 7:0.016959884 +1 1:0.773128 2:0.011013 3:0.019824 5:0.021327509 7:0.018776189 +1 1:0.743017 2:0.022346 3:0.044693 5:0.029520075 7:0.017202616 +1 1:0.755906 2:0.031496 3:0.070866 5:0.067307262 7:0.021269445 +1 1:0.775148 2:0.005917 3:0.023669 5:0.017794045 7:0.015117622 +1 1:0.786026 2:0.008734 3:0.030568 7:0.016908085 +1 1:0.762048 2:0.03012 3:0.027108 5:0.022796058 6:0.0091740092 7:0.018017189 +1 1:0.738182 2:0.036364 3:0.047273 5:0.047910486 6:0.0038550039 7:0.017250555 +1 1:0.78125 2:0.007812 3:0.03125 7:0.015386817 +1 1:0.718182 2:0.040909 3:0.040909 5:0.054910322 7:0.01504989 +1 1:0.730769 2:0.046154 3:0.038462 5:0.058853786 7:0.01782364 +1 1:0.752 2:0.034 3:0.036 5:0.039919193 6:0.008031008 7:0.018219512 +1 1:0.752381 2:0.019048 3:0.042857 5:0.041879743 7:0.015505226 +1 1:0.741379 2:0.028736 3:0.04023 5:0.047783758 7:0.016400335 8:0.023809524 +1 1:0.674699 2:0.096386 3:0.054217 5:0.0463003 6:0.04968905 7:0.017741701 +1 1:0.791946 2:0.006711 3:0.033557 5:0.017413863 7:0.01751514 +1 1:0.756098 2:0.014634 3:0.043902 5:0.02464479 7:0.017995244 +1 1:0.791123 2:0.015666 3:0.023499 5:0.012143485 7:0.019550402 +1 1:0.786517 2:0.026217 3:0.037453 5:0.014968765 6:0.009036009 7:0.022745957 +1 1:0.768212 2:0.016556 3:0.031457 5:0.03191299 7:0.016505817 +1 1:0.770308 2:0.016807 3:0.042017 5:0.025181519 7:0.020222726 +1 1:0.793651 2:0.015873 3:0.039683 5:0.016206223 7:0.022260939 +1 1:0.797101 2:0.006441 3:0.040258 5:0.013753671 7:0.021287457 +1 1:0.765472 2:0.037459 3:0.026059 5:0.024450971 6:0.01968302 7:0.018163579 +1 1:0.809524 2:0.007937 3:0.071429 5:0.0081105661 7:0.044473482 +1 1:0.766917 2:0.017544 3:0.027569 5:0.029206983 7:0.01560303 +1 1:0.659722 2:0.013889 3:0.138889 5:0.019113503 7:0.016514226 +1 1:0.75431 2:0.021552 3:0.060345 5:0.029900258 7:0.019659378 +1 1:0.748387 2:0.025806 3:0.032258 7:0.017466561 +1 1:0.747059 2:0.023529 3:0.047059 5:0.03106317 7:0.01721664 +1 1:0.785479 2:0.019802 3:0.016502 6:0.0065850066 7:0.018332933 +1 1:0.798479 2:0.007605 3:0.041825 5:0.01634786 7:0.021144396 +1 1:0.751543 2:0.020062 3:0.03858 5:0.046069208 7:0.015225085 +1 1:0.76431 2:0.023569 3:0.043771 5:0.042215198 7:0.018128439 +1 1:0.751295 2:0.025907 3:0.025907 5:0.016139132 7:0.014596232 +1 1:0.722727 2:0.077273 3:0.040909 5:0.030429532 6:0.044898045 7:0.020371396 +1 1:0.783784 2:0.006757 3:0.033784 5:0.01754059 7:0.01750989 +1 1:0.792157 2:0.003922 3:0.027451 5:0.0099667526 7:0.017886177 +1 1:0.772727 2:0.020455 3:0.022727 5:0.018509683 7:0.016740579 +1 1:0.771791 2:0.015848 3:0.030111 5:0.02910262 7:0.017326354 +1 1:0.686391 2:0.029586 3:0.088757 5:0.071675637 7:0.015009384 +1 1:0.742081 2:0.024887 3:0.049774 5:0.025039882 7:0.016430305 +1 1:0.776596 2:0.010638 3:0.026596 5:0.015430948 7:0.015665543 +1 1:0.666147 2:0.095164 3:0.039002 5:0.034432633 6:0.051963052 7:0.01647578 +1 1:0.756923 2:0.021538 3:0.049231 5:0.031256989 7:0.017898689 +1 1:0.763285 2:0.012882 3:0.030596 5:0.026672432 7:0.01646636 +1 1:0.77451 2:0.009804 3:0.053922 5:0.024846063 7:0.017934 +1 1:0.740933 2:0.031088 3:0.041451 5:0.028782073 7:0.016365476 +1 1:0.737319 2:0.028986 3:0.038043 5:0.044675205 6:0.0044940045 7:0.014746817 +1 1:0.783333 2:0.008333 3:0.033333 5:0.023004786 7:0.016463415 +1 1:0.697248 2:0.045872 3:0.06422 5:0.060523609 6:0.0040590041 7:0.020670171 +1 1:0.763636 2:0.012121 3:0.048485 7:0.019401329 +1 1:0.760965 2:0.02193 3:0.032895 5:0.01840532 6:0.0049380049 7:0.016246793 +1 1:0.706522 2:0.057971 3:0.025362 5:0.032650992 6:0.017517018 7:0.015133439 +1 1:0.724138 2:0.056034 3:0.021552 5:0.068142173 6:0.032907033 7:0.014376579 +1 1:0.762238 2:0.01049 3:0.027972 5:0.021029326 7:0.015115982 +1 1:0.80203 2:0.010152 3:0.035533 5:0.010309663 7:0.02237836 +1 1:0.80597 2:0.00995 3:0.029851 5:0.010622754 7:0.021295957 +1 1:0.746412 2:0.023923 3:0.062201 5:0.03080226 7:0.021181 +1 1:0.768067 2:0.015126 3:0.031933 5:0.017823864 7:0.017144909 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.776952 2:0.01487 3:0.022305 5:0.020589507 7:0.01641128 +1 1:0.75052 2:0.022869 3:0.049896 5:0.057743056 7:0.018001116 +1 1:0.793413 2:0.008982 3:0.02994 5:0.013291488 7:0.020483427 +1 1:0.726872 2:0.030837 3:0.030837 5:0.046591028 7:0.012893518 +1 1:0.733456 2:0.038603 3:0.045956 5:0.036072637 6:0.012903013 7:0.02084828 +1 1:0.77931 2:0.013793 3:0.041379 5:0.033962996 7:0.01846089 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.709459 2:0.087838 3:0.040541 5:0.016243496 6:0.052287052 7:0.018910677 +1 1:0.780576 2:0.007194 3:0.061151 5:0.015102948 7:0.021648537 +1 1:0.743243 2:0.022523 3:0.033033 5:0.050266128 7:0.017651799 +1 1:0.794677 2:0.003802 3:0.028517 5:0.0047112847 7:0.018339055 +1 1:0.774086 2:0.026578 3:0.036545 5:0.024257153 7:0.018677579 +1 1:0.705696 2:0.028481 3:0.056962 5:0.042304653 6:0.0068100068 7:0.016999848 +1 1:0.701531 2:0.079082 3:0.066327 5:0.071720364 6:0.0067920068 7:0.027485689 +1 1:0.742857 2:0.028571 3:0.044898 5:0.046449391 7:0.015978098 +1 1:0.753521 2:0.018779 3:0.042254 5:0.041566651 7:0.015401354 +1 1:0.791667 2:0.009259 3:0.037037 5:0.011077483 7:0.018998421 +1 1:0.788235 2:0.017647 3:0.023529 6:0.011835012 7:0.018185079 +1 1:0.784722 2:0.013889 3:0.111111 5:0.0099294798 7:0.031800476 +1 1:0.768182 2:0.022727 3:0.040909 5:0.010443845 7:0.01978936 +1 1:0.75753 2:0.013554 3:0.036145 5:0.030764987 7:0.015574494 +1 1:0.772994 2:0.007828 3:0.027397 5:0.016444769 7:0.016228341 +1 1:0.776294 2:0.006678 3:0.03172 5:0.018427683 7:0.016470543 +1 1:0.778761 2:0.004425 3:0.035398 5:0.011815485 7:0.017024604 +1 1:0.68 2:0.053333 3:0.031111 5:0.071817274 6:0.023121023 7:0.014065043 +1 1:0.776053 2:0.015521 3:0.039911 5:0.027186796 7:0.018536043 +1 1:0.755172 2:0.010345 3:0.051724 5:0.017794045 7:0.017619848 +1 1:0.762332 2:0.03139 3:0.053812 5:0.042938291 7:0.023734006 +1 1:0.738532 2:0.013761 3:0.050459 5:0.02720916 7:0.015327817 +1 1:0.696335 2:0.057592 3:0.031414 4:0.0036900369 5:0.056796326 6:0.017142017 7:0.016760311 +1 1:0.794118 2:0.006787 3:0.029412 5:0.016019859 7:0.01925836 +1 1:0.732906 2:0.032051 3:0.044872 5:0.053352318 7:0.020025537 +1 1:0.813559 2:0.004237 3:0.025424 7:0.020333817 +1 1:0.778711 2:0.014006 3:0.036415 5:0.013969854 7:0.018224366 +1 1:0.776596 2:0.010638 3:0.031915 5:0.02781298 7:0.017384537 +1 1:0.757322 2:0.012552 3:0.062762 5:0.018636411 7:0.030615366 +1 1:0.709877 2:0.08642 3:0.018519 5:0.042215198 6:0.061155061 7:0.016617738 +1 1:0.757974 2:0.016886 3:0.0394 5:0.032613719 7:0.018304122 +1 1:0.727273 2:0.019481 3:0.071429 5:0.04937158 7:0.017936329 +1 1:0.733577 2:0.029197 3:0.040146 5:0.022087874 7:0.015021366 +1 1:0.777372 2:0.010949 3:0.041971 5:0.018472411 7:0.017958878 +1 1:0.728 2:0.04 3:0.04 5:0.046017026 6:0.0061740062 7:0.015804878 +1 1:0.775862 2:0.007184 3:0.03592 5:0.016221132 7:0.01610247 +1 1:0.776224 2:0.027972 3:0.055944 5:0.012508759 6:0.01006801 7:0.02541361 +1 1:0.788151 2:0.021544 3:0.035907 5:0.011427847 6:0.0091980092 7:0.021423567 +1 1:0.767677 2:0.018182 3:0.066667 5:0.033828813 7:0.021717171 +1 1:0.728155 2:0.029126 3:0.033981 5:0.041566651 7:0.015924695 +1 1:0.767296 2:0.006289 3:0.041929 5:0.01727968 7:0.01654139 +1 1:0.743243 2:0.023649 3:0.047297 5:0.035371908 7:0.017365689 +1 1:0.708661 2:0.047244 3:0.055118 5:0.049043579 7:0.014595738 +1 1:0.740458 2:0.053435 3:0.030534 5:0.037653005 6:0.037878038 7:0.018432323 +1 1:0.777311 2:0.008403 3:0.021008 5:0.011524757 7:0.016576146 +1 1:0.783883 2:0.007326 3:0.040293 5:0.0093331147 7:0.017845976 +1 1:0.738693 2:0.045226 3:0.075377 5:0.017384044 6:0.0027990028 7:0.065694329 +1 1:0.752308 2:0.024615 3:0.032308 5:0.045845571 6:0.0036900037 7:0.015253287 +1 1:0.737542 2:0.026578 3:0.026578 5:0.030384805 7:0.014909652 +1 1:0.750693 2:0.030471 3:0.049861 5:0.05296468 7:0.019018988 +1 1:0.779762 2:0.011905 3:0.041667 5:0.027865162 7:0.019417829 +1 1:0.764826 2:0.010225 3:0.02863 5:0.02456279 7:0.015137915 +1 1:0.76386 2:0.01848 3:0.014374 5:0.018360592 7:0.015250165 +1 1:0.763557 2:0.036876 3:0.045553 5:0.038279188 6:0.011553012 7:0.020607378 +1 1:0.721311 2:0.040984 3:0.04918 5:0.023153877 7:0.016093561 +1 1:0.746835 2:0.021097 3:0.046414 5:0.025181519 6:0.01013401 7:0.015231037 +1 1:0.730539 2:0.023952 3:0.053892 5:0.018002773 7:0.01511611 +1 1:0.729508 2:0.016393 3:0.07377 5:0.02258733 7:0.016493402 +1 1:0.741866 2:0.030369 3:0.030369 5:0.024622426 6:0.012387012 7:0.016017671 +1 1:0.722449 2:0.032653 3:0.069388 5:0.062819614 7:0.017720256 +1 1:0.757862 2:0.022013 3:0.028302 5:0.021715146 6:0.0058260058 7:0.019749963 +1 1:0.753731 2:0.014925 3:0.037313 5:0.047179938 7:0.014379323 +1 1:0.742029 2:0.04058 3:0.031884 5:0.052495043 6:0.012072012 7:0.017568043 +1 1:0.716814 2:0.044248 3:0.050885 5:0.080561478 6:0.0064830065 7:0.018724366 +1 1:0.744681 2:0.017021 3:0.025532 5:0.026247521 6:0.0052830053 7:0.014737933 +1 1:0.772093 2:0.018605 3:0.106977 5:0.02268424 7:0.027963701 +1 1:0.617188 2:0.171875 3:0.023438 4:0.0036900369 5:0.053501409 6:0.11483411 7:0.019912348 +1 1:0.788235 2:0.017647 3:0.035294 5:0.014036945 7:0.019045909 +1 1:0.772727 2:0.007576 3:0.037879 5:0.02096969 7:0.016421841 +1 1:0.727848 2:0.018987 3:0.082278 5:0.045226842 7:0.019083823 +1 1:0.780718 2:0.011342 3:0.035917 5:0.024264607 7:0.017704829 +1 1:0.738095 2:0.029762 3:0.035714 5:0.017339317 7:0.015606854 +1 1:0.752852 2:0.022814 3:0.038023 5:0.04321411 7:0.015997402 +1 1:0.594737 2:0.115789 3:0.031579 5:0.033128084 6:0.10666811 7:0.014441591 +1 1:0.75 2:0.027273 3:0.036364 5:0.012806942 6:0.01030801 7:0.016130823 +1 1:0.789174 2:0.011396 3:0.037037 5:0.025971702 7:0.019943018 +1 1:0.760618 2:0.007722 3:0.030888 5:0.011293665 7:0.015538189 +1 1:0.75188 2:0.015038 3:0.030075 5:0.026068612 7:0.013112049 +1 1:0.773764 2:0.011407 3:0.024715 5:0.021976056 7:0.01573078 +1 1:0.737589 2:0.023641 3:0.037825 5:0.022117693 7:0.014573604 +1 1:0.743902 2:0.036585 3:0.060976 5:0.054813412 7:0.020226055 +1 1:0.780645 2:0.012903 3:0.032258 5:0.015117857 7:0.019394177 +1 1:0.768657 2:0.014925 3:0.027363 5:0.019881323 7:0.017064067 +1 1:0.6875 2:0.054688 3:0.09375 5:0.027402979 7:0.09070122 +1 1:0.766082 2:0.011696 3:0.023392 5:0.017212589 7:0.015440024 +1 1:0.761658 2:0.010363 3:0.036269 5:0.0075514738 7:0.015591433 +1 1:0.738318 2:0.05296 3:0.037383 5:0.054582321 6:0.028242028 7:0.018159713 +1 1:0.770701 2:0.012739 3:0.050955 5:0.016034768 7:0.018059652 +1 1:0.75 2:0.023585 3:0.028302 5:0.014678037 7:0.014611134 +1 1:0.757812 2:0.007812 3:0.0625 7:0.017292305 +1 1:0.729614 2:0.025751 3:0.04721 5:0.025792793 7:0.01512614 +1 1:0.782271 2:0.010886 3:0.03888 5:0.014663128 7:0.019288396 +1 1:0.798883 2:0.005587 3:0.027933 7:0.016487262 +1 1:0.732523 2:0.033435 3:0.045593 5:0.058369239 6:0.0033570034 7:0.016569055 +1 1:0.704167 2:0.020833 3:0.054167 5:0.046926483 7:0.014126018 +1 1:0.727768 2:0.029038 3:0.045372 5:0.033843723 6:0.0038910039 7:0.017064317 +1 1:0.748 2:0.022 3:0.044 5:0.022438239 7:0.016207317 +1 1:0.758621 2:0.024138 3:0.034483 5:0.028782073 6:0.0077220077 7:0.016337256 +1 1:0.743169 2:0.021858 3:0.060109 5:0.05296468 7:0.018759165 +1 1:0.719457 2:0.058824 3:0.090498 5:0.060337244 7:0.030680939 +1 1:0.69802 2:0.034653 3:0.049505 5:0.03011644 6:0.0060600061 7:0.014942043 +1 1:0.767528 2:0.02214 3:0.02214 5:0.010168026 7:0.016492665 +1 1:0.747573 2:0.019417 3:0.05178 5:0.054149956 7:0.016299628 +1 1:0.757106 2:0.023256 3:0.036176 5:0.028454072 7:0.016512256 +1 1:0.706667 2:0.07 3:0.04 5:0.05048231 6:0.02031602 7:0.018008128 +1 1:0.756228 2:0.024911 3:0.039146 5:0.035729727 7:0.018108238 +1 1:0.731132 2:0.033019 3:0.04717 5:0.039032099 7:0.016480671 +1 1:0.755245 2:0.020979 3:0.027972 5:0.021670419 7:0.014668256 +1 1:0.776515 2:0.015152 3:0.056818 5:0.032062082 7:0.021480043 +1 1:0.697987 2:0.026846 3:0.100671 5:0.014819674 7:0.020584384 +1 1:0.755068 2:0.023649 3:0.038851 5:0.022386057 6:0.0036030036 7:0.01714939 +1 1:0.781609 2:0.013793 3:0.029885 5:0.016422405 6:0.0044040044 7:0.019091671 +1 1:0.751979 2:0.01847 3:0.031662 5:0.044794478 7:0.018743165 +1 1:0.795775 2:0.007042 3:0.133803 7:0.099579183 +1 1:0.738095 2:0.02381 3:0.039683 7:0.015098726 +1 1:0.794521 2:0.009132 3:0.027397 5:0.012046576 7:0.017234659 +1 1:0.742671 2:0.009772 3:0.029316 5:0.021923874 7:0.013506 +1 1:0.7251 2:0.027888 3:0.043825 5:0.025748066 7:0.014065689 +1 1:0.727273 2:0.016529 3:0.132231 5:0.033500813 7:0.022424915 +1 1:0.800633 2:0.006329 3:0.031646 5:0.01540113 7:0.018678604 +1 1:0.739464 2:0.015326 3:0.030651 5:0.044705023 7:0.015582659 8:0.023809524 +1 1:0.756863 2:0.015686 3:0.039216 4:0.0036900369 5:0.010496027 7:0.016977524 +1 1:0.796875 2:0.015625 3:0.025 5:0.036721184 7:0.019340701 8:0.023809524 +1 1:0.77821 2:0.015564 3:0.046693 5:0.028819346 7:0.018411311 +1 1:0.793522 2:0.008097 3:0.032389 5:0.019851505 7:0.018539549 +1 1:0.732143 2:0.025 3:0.060714 5:0.039494282 7:0.01644164 +1 1:0.772947 2:0.019324 3:0.043478 5:0.036072637 7:0.018263226 +1 1:0.706161 2:0.056872 3:0.085308 5:0.020231688 6:0.0027150027 7:0.063894348 +1 1:0.764286 2:0.028571 3:0.028571 5:0.018315865 7:0.017726482 +1 1:0.726619 2:0.014388 3:0.05036 5:0.043594293 7:0.015002634 +1 1:0.740933 2:0.031088 3:0.041451 5:0.028782073 7:0.016365476 +1 1:0.732026 2:0.03268 3:0.028322 5:0.033187721 6:0.0026700027 7:0.014918433 +1 1:0.743802 2:0.041322 3:0.024793 5:0.019113503 6:0.023076023 7:0.019653293 +1 1:0.77757 2:0.009346 3:0.024299 5:0.015803677 7:0.016127195 +1 1:0.715151 2:0.048485 3:0.056566 5:0.066606533 6:0.0041250041 7:0.017923134 +1 1:0.755258 2:0.013384 3:0.042065 5:0.010279844 7:0.01690528 +1 1:0.758333 2:0.016667 3:0.066667 4:0.0036900369 5:0.024793881 7:0.022916665 +1 1:0.742515 2:0.011976 3:0.071856 5:0.029117529 7:0.018694317 +1 1:0.702703 2:0.043919 3:0.047297 5:0.044973387 7:0.013657713 +1 1:0.776453 2:0.011923 3:0.023845 5:0.023481878 7:0.017311256 +1 1:0.69802 2:0.034653 3:0.079208 5:0.038227006 6:0.0051270051 7:0.017658774 +1 1:0.69863 2:0.013699 3:0.089041 5:0.041186468 7:0.01511861 +1 1:0.774834 2:0.019868 3:0.019868 5:0.018778048 7:0.016031335 +1 1:0.771704 2:0.009646 3:0.048232 5:0.022818422 7:0.019214177 +1 1:0.719033 2:0.036254 3:0.042296 5:0.05801142 7:0.014203079 +1 1:0.696697 2:0.048048 3:0.039039 5:0.06991636 7:0.01561928 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.72 2:0.033333 3:0.093333 5:0.055946506 7:0.021666665 +1 1:0.780451 2:0.019549 3:0.030075 5:0.027171887 6:0.0041010041 7:0.020126537 +1 1:0.773585 2:0.018868 3:0.033019 5:0.025270973 7:0.016969628 +1 1:0.757732 2:0.015464 3:0.030928 5:0.028834255 7:0.016249683 +1 1:0.756881 2:0.041284 3:0.041284 5:0.038801008 6:0.0078060078 7:0.021495299 +1 1:0.722772 2:0.029703 3:0.039604 5:0.03320263 7:0.013553488 +1 1:0.742706 2:0.023873 3:0.039788 5:0.015028402 7:0.016044512 +1 1:0.75 2:0.024 3:0.03 5:0.017876046 7:0.015256098 +1 1:0.736508 2:0.020635 3:0.038095 5:0.013805853 6:0.0018510019 7:0.015679445 +1 1:0.75 2:0.02551 3:0.071429 4:0.0036900369 5:0.057429964 7:0.02019039 +1 1:0.708955 2:0.089552 3:0.044776 5:0.016385133 6:0.059340059 7:0.020704402 +1 1:0.768489 2:0.012862 3:0.041801 5:0.0248237 7:0.01766528 +1 1:0.761194 2:0.052239 3:0.007463 5:0.019463868 6:0.031332031 7:0.017428104 +1 1:0.75 2:0.027778 3:0.046296 5:0.03362754 6:0.0045120045 7:0.018772585 +1 1:0.741135 2:0.021277 3:0.046099 5:0.010384208 7:0.015524994 +1 1:0.781116 2:0.012876 3:0.042918 5:0.030593532 7:0.019130116 +1 1:0.762821 2:0.019231 3:0.032051 5:0.017316953 7:0.016826921 +1 1:0.731861 2:0.031546 3:0.047319 5:0.048216123 7:0.014868817 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.784375 2:0.009375 3:0.03125 5:0.016243496 7:0.017492378 +1 1:0.711111 2:0.022222 3:0.088889 5:0.018002773 7:0.018699189 +1 1:0.789474 2:0.007177 3:0.026316 5:0.012456577 7:0.017461195 +1 1:0.741135 2:0.021277 3:0.046099 5:0.010384208 7:0.015524994 +1 1:0.776923 2:0.009615 3:0.019231 5:0.011025301 7:0.015853659 +1 1:0.750452 2:0.012658 3:0.03255 5:0.021327509 7:0.015414811 +1 1:0.784314 2:0.015686 3:0.035294 5:0.018614047 7:0.019153512 +1 1:0.715976 2:0.017751 3:0.035503 5:0.014968765 7:0.017967963 +1 1:0.774359 2:0.010256 3:0.046154 5:0.025352974 7:0.018386494 +1 1:0.743243 2:0.030405 3:0.043919 5:0.017831318 7:0.017221488 +1 1:0.701107 2:0.02952 3:0.053506 4:0.011070111 5:0.021208236 7:0.015817659 +1 1:0.740157 2:0.062992 3:0.055118 5:0.057012509 6:0.022944023 7:0.025110427 +1 1:0.685279 2:0.054146 3:0.094755 5:0.11582902 7:0.018591884 +1 1:0.780105 2:0.031414 3:0.057592 5:0.040165193 7:0.029625848 +1 1:0.767296 2:0.028302 3:0.022013 5:0.022520239 6:0.012084012 7:0.0190405 +1 1:0.736842 2:0.024561 3:0.049123 5:0.025912066 6:0.0034770035 7:0.018463841 +1 1:0.75 2:0.033654 3:0.028846 5:0.039792465 6:0.010677011 7:0.01647514 +1 1:0.726619 2:0.035971 3:0.079137 5:0.082462392 7:0.019828043 +1 1:0.745161 2:0.041935 3:0.064516 5:0.054932685 6:0.0012990013 7:0.022688829 +1 1:0.727928 2:0.025225 3:0.05045 5:0.026068612 7:0.015710829 +1 1:0.730189 2:0.035849 3:0.032075 5:0.029743712 7:0.014415555 +1 1:0.795455 2:0.022727 3:0.025974 5:0.013716399 6:0.0055200055 7:0.02151964 +1 1:0.772973 2:0.014414 3:0.045045 5:0.016869679 7:0.02426939 +1 1:0.75265 2:0.028269 3:0.042403 5:0.018159319 6:0.010962011 7:0.01768939 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.770701 2:0.012739 3:0.044586 5:0.033314448 7:0.017379988 +1 1:0.663912 2:0.041322 3:0.071625 4:0.0073800738 5:0.043765748 7:0.017167238 +1 1:0.771429 2:0.014286 3:0.028571 5:0.020425507 7:0.015897213 +1 1:0.69802 2:0.034653 3:0.079208 5:0.038227006 6:0.0051270051 7:0.017658774 +1 1:0.742331 2:0.067485 3:0.01227 5:0.03269572 6:0.052632053 7:0.017058207 +1 1:0.781609 2:0.013793 3:0.029885 5:0.016422405 6:0.0044040044 7:0.019091671 +1 1:0.71875 2:0.03125 3:0.049107 5:0.025099518 7:0.016169427 +1 1:0.757991 2:0.015982 3:0.045662 5:0.030205895 7:0.017178976 +1 1:0.736486 2:0.013514 3:0.047297 5:0.041879743 7:0.01466711 +1 1:0.770053 2:0.010695 3:0.034759 5:0.03080226 7:0.015781921 +1 1:0.74477 2:0.025105 3:0.062762 5:0.044816841 7:0.02546178 +1 1:0.737662 2:0.020779 3:0.046753 5:0.053739955 7:0.015378524 +1 1:0.773913 2:0.013043 3:0.028986 5:0.021402054 7:0.018469427 +1 1:0.659722 2:0.013889 3:0.138889 5:0.019113503 7:0.016514226 +1 1:0.754098 2:0.010929 3:0.04918 5:0.014819674 7:0.016759963 +1 1:0.780645 2:0.012903 3:0.032258 5:0.015117857 7:0.019394177 +1 1:0.77551 2:0.027211 3:0.027211 5:0.016526769 7:0.018707482 +1 1:0.770764 2:0.016611 3:0.046512 5:0.01566204 7:0.019285311 +1 1:0.777379 2:0.016158 3:0.028725 5:0.017674772 7:0.018467835 +1 1:0.741463 2:0.029268 3:0.04878 5:0.030548805 6:0.0081960082 7:0.021772756 +1 1:0.775281 2:0.005618 3:0.022472 5:0.018450047 7:0.013839409 +1 1:0.776042 2:0.005208 3:0.03125 5:0.014909129 7:0.015879067 +1 1:0.741551 2:0.027833 3:0.071571 5:0.055014685 7:0.019711 +1 1:0.742775 2:0.034682 3:0.052023 5:0.029534984 6:0.0023760024 7:0.022240238 +1 1:0.756989 2:0.019355 3:0.04086 5:0.042915927 7:0.015945451 +1 1:0.759124 2:0.014599 3:0.058394 5:0.018591684 7:0.017847604 +1 1:0.699386 2:0.018405 3:0.07362 5:0.058540694 7:0.014289988 +1 1:0.756098 2:0.02439 3:0.03252 5:0.028148435 6:0.0067980068 7:0.016408884 +1 1:0.727273 2:0.016529 3:0.07438 5:0.020820598 7:0.01804072 +1 1:0.628205 2:0.121795 3:0.070513 4:0.0073800738 5:0.017212589 6:0.076212076 7:0.01692464 +1 1:0.757576 2:0.037879 3:0.037879 5:0.025159155 6:0.0033750034 7:0.020533073 +1 1:0.767647 2:0.014706 3:0.035294 5:0.024204971 7:0.016571018 +1 1:0.723164 2:0.022599 3:0.073446 5:0.043512293 7:0.017707043 +1 1:0.777385 2:0.031802 3:0.038869 5:0.022840785 6:0.0061290061 7:0.021093683 +1 1:0.753036 2:0.016194 3:0.060729 5:0.030511532 7:0.018095189 +1 1:0.796429 2:0.003571 3:0.017857 5:0.0092958418 7:0.017465159 +1 1:0.768293 2:0.015244 3:0.033537 5:0.033769177 7:0.016415079 +1 1:0.790541 2:0.010135 3:0.016892 5:0.0087591132 7:0.017530488 +1 1:0.738149 2:0.029345 3:0.045147 5:0.058905968 6:0.0079020079 7:0.015677476 +1 1:0.755382 2:0.02544 3:0.056751 5:0.044011748 7:0.022230439 +1 1:0.733855 2:0.013699 3:0.074364 5:0.030056804 7:0.017755713 +1 1:0.793939 2:0.006061 3:0.036364 7:0.019438287 +1 1:0.716019 2:0.043689 3:0.048544 5:0.027455161 6:0.0055260055 7:0.016072695 +1 1:0.776744 2:0.023256 3:0.027907 5:0.021640601 6:0.0043530044 7:0.019540555 +1 1:0.732984 2:0.04712 3:0.015707 5:0.047888122 6:0.019272019 7:0.014908695 +1 1:0.748252 2:0.041958 3:0.020979 5:0.039755192 6:0.015999016 7:0.01599011 +1 1:0.790909 2:0.009091 3:0.027273 5:0.011964576 7:0.017267183 +1 1:0.7669 2:0.013986 3:0.030303 5:0.019359504 7:0.016416512 +1 1:0.77 2:0.02 3:0.035 5:0.025181519 7:0.01804878 +1 1:0.741228 2:0.02193 3:0.030702 5:0.026478613 7:0.015056695 +1 1:0.728522 2:0.030928 3:0.037801 5:0.050176673 6:0.0067320067 7:0.014007628 +1 1:0.770115 2:0.005747 3:0.04023 5:0.016787679 7:0.015559293 +1 1:0.775862 2:0.010345 3:0.044828 5:0.026590431 7:0.017682927 +1 1:0.724719 2:0.02809 3:0.067416 5:0.030302804 7:0.016853933 +1 1:0.789474 2:0.007519 3:0.037594 7:0.018751146 +1 1:0.70068 2:0.013605 3:0.068027 5:0.020939871 7:0.014766884 +1 1:0.718254 2:0.087302 3:0.051587 5:0.049080852 6:0.022221022 7:0.029398957 +1 1:0.753425 2:0.006849 3:0.034247 5:0.017413863 7:0.017875043 +1 1:0.730496 2:0.021277 3:0.021277 7:0.011762671 +1 1:0.724891 2:0.056769 3:0.061135 5:0.02593443 6:0.014613015 7:0.03826286 +1 1:0.749403 2:0.02864 3:0.054893 5:0.029452984 6:0.002964003 7:0.029469116 +1 1:0.800738 2:0.00738 3:0.02952 5:0.010749482 7:0.023411482 +1 1:0.751773 2:0.02305 3:0.031915 5:0.044369567 6:0.0066960067 7:0.01453036 +1 1:0.691589 2:0.065421 3:0.037383 4:0.0036900369 5:0.054120138 6:0.032667033 7:0.015699793 +1 1:0.746562 2:0.035363 3:0.037328 5:0.037116276 6:0.0042660043 7:0.016843165 +1 1:0.761905 2:0.004762 3:0.02381 5:0.013880399 7:0.015592335 +1 1:0.657143 2:0.064286 3:0.042857 5:0.088530407 6:0.014253014 7:0.018336238 +1 1:0.758364 2:0.02974 3:0.048327 5:0.044004294 7:0.019199384 +1 1:0.739437 2:0.028169 3:0.070423 5:0.043937203 7:0.02185675 +1 1:0.772414 2:0.013793 3:0.055172 5:0.017056043 7:0.018376787 +1 1:0.776025 2:0.006309 3:0.031546 5:0.018427683 7:0.015561287 +1 1:0.748299 2:0.013605 3:0.054422 5:0.036900094 7:0.016757921 +1 1:0.767986 2:0.007194 3:0.026978 5:0.022624603 7:0.014454293 +1 1:0.788235 2:0.017647 3:0.035294 5:0.014036945 7:0.019045909 +1 1:0.753788 2:0.030303 3:0.034091 5:0.020477688 6:0.012363012 7:0.016814488 +1 1:0.769231 2:0.014514 3:0.059507 5:0.029042983 7:0.020443201 +1 1:0.765625 2:0.024554 3:0.037946 5:0.040545376 6:0.0046620047 7:0.017516878 +1 1:0.771654 2:0.023622 3:0.03937 5:0.019672596 7:0.018196659 +1 1:0.703125 2:0.041667 3:0.078125 5:0.085518763 7:0.0166095 +1 1:0.713235 2:0.051471 3:0.066176 5:0.05647578 6:0.0075750076 7:0.017754665 +1 1:0.766129 2:0.008065 3:0.024194 5:0.025442428 7:0.014407945 +1 1:0.716418 2:0.074627 3:0.064677 5:0.050780493 6:0.016350016 7:0.022266713 +1 1:0.631902 2:0.030675 3:0.079755 5:0.030869351 7:0.018068232 +1 1:0.71223 2:0.028777 3:0.05036 7:0.013291805 +1 1:0.702128 2:0.021277 3:0.049645 5:0.026433885 7:0.012195122 +1 1:0.77176 2:0.011605 3:0.038685 5:0.020440416 7:0.017207622 +1 1:0.779043 2:0.015945 3:0.052392 5:0.025576611 7:0.024293018 +1 1:0.772414 2:0.013793 3:0.034483 5:0.016906952 7:0.018544994 +1 1:0.765537 2:0.014124 3:0.022599 5:0.016824952 7:0.015261128 +1 1:0.8 2:0.011321 3:0.022642 5:0.0043311019 7:0.019788311 +1 1:0.789398 2:0.005731 3:0.022923 5:0.014543855 7:0.017908311 +1 1:0.761261 2:0.004505 3:0.018018 5:0.011010392 7:0.018594817 +1 1:0.778912 2:0.003401 3:0.020408 5:0.0094971151 7:0.016280902 +1 1:0.763393 2:0.053571 3:0.035714 5:0.044421749 6:0.017877018 7:0.022838634 +1 1:0.777397 2:0.020548 3:0.034247 5:0.024413699 7:0.019127963 +1 1:0.776224 2:0.013986 3:0.031469 5:0.01909114 7:0.01665103 +1 1:0.72028 2:0.034965 3:0.048951 5:0.041529378 7:0.01530786 +1 1:0.75 2:0.012821 3:0.032051 5:0.035498636 7:0.016416512 +1 1:0.774359 2:0.020513 3:0.025641 5:0.019478777 6:0.0052260052 7:0.01794872 8:0.023809524 +1 1:0.68 2:0.074286 3:0.051429 5:0.032062082 6:0.038709039 7:0.016202091 +1 1:0.705426 2:0.062016 3:0.046512 5:0.068388174 6:0.036696037 7:0.01545661 +1 1:0.793333 2:0.006667 3:0.043333 5:0.015758949 7:0.01922764 +1 1:0.744966 2:0.020134 3:0.04698 5:0.040075738 7:0.015223439 +1 1:0.753333 2:0.026667 3:0.033333 5:0.037459186 7:0.01617886 +1 1:0.76506 2:0.018072 3:0.03012 5:0.025352974 7:0.016198939 +1 1:0.762346 2:0.018519 3:0.046296 5:0.029378438 7:0.019101927 +1 1:0.64 2:0.113333 3:0.06 5:0.037653005 6:0.083334083 7:0.016097561 +1 1:0.757812 2:0.015625 3:0.046875 5:0.046881756 7:0.015148628 +1 1:0.695418 2:0.070081 3:0.043127 5:0.039583737 6:0.029205029 7:0.018572085 +1 1:0.736742 2:0.034091 3:0.049242 5:0.055253232 6:0.004044004 7:0.017137841 +1 1:0.787709 2:0.011173 3:0.044693 5:0.012963488 7:0.01958714 +1 1:0.784141 2:0.004405 3:0.048458 5:0.0090349321 7:0.022160738 +1 1:0.72 2:0.016 3:0.064 5:0.044369567 7:0.016390244 +1 1:0.748148 2:0.02963 3:0.037037 5:0.021424418 7:0.015718159 +1 1:0.797101 2:0.009662 3:0.038647 5:0.022184784 7:0.019794982 +1 1:0.727723 2:0.009901 3:0.059406 5:0.015088038 7:0.014911854 +1 1:0.721311 2:0.077283 3:0.023419 5:0.03132408 6:0.052941053 7:0.016993201 +1 1:0.786325 2:0.008547 3:0.037037 5:0.013291488 7:0.019491348 +1 1:0.709184 2:0.045918 3:0.05102 5:0.062856887 6:0.0050580051 7:0.018448232 +1 1:0.674074 2:0.125926 3:0.014815 4:0.0036900369 5:0.051891223 6:0.083526084 7:0.01946703 +1 1:0.714754 2:0.059016 3:0.032787 5:0.034790452 6:0.031506032 7:0.017133146 +1 1:0.768421 2:0.017544 3:0.029825 5:0.019352049 7:0.016484811 +1 1:0.763699 2:0.020548 3:0.030822 5:0.023653333 6:0.0038070038 7:0.016455061 +1 1:0.675762 2:0.046549 3:0.054575 5:0.041052286 6:0.016521017 7:0.017773951 +1 1:0.79638 2:0.011312 3:0.024887 5:0.010563118 6:0.0042510043 7:0.019465293 +1 1:0.779412 2:0.014706 3:0.041176 5:0.018949503 7:0.021162122 +1 1:0.773481 2:0.016575 3:0.033149 5:0.014148763 7:0.017753671 +1 1:0.718204 2:0.0399 3:0.054863 5:0.06666617 7:0.018703244 +1 1:0.778495 2:0.027957 3:0.051613 5:0.040254648 6:0.0016200016 7:0.024285341 +1 1:0.726562 2:0.023438 3:0.0625 5:0.062819614 7:0.016958841 +1 1:0.792398 2:0.01462 3:0.04386 5:0.0056580144 7:0.023480957 +1 1:0.75641 2:0.017094 3:0.042735 5:0.022222057 7:0.017484884 +1 1:0.740741 2:0.024691 3:0.024691 5:0.042237562 7:0.013286659 +1 1:0.743902 2:0.036585 3:0.036585 5:0.03080226 6:0.018594019 7:0.017995244 +1 1:0.472 2:0.064 3:0.12 5:0.13762617 6:0.0092310092 7:0.015853659 +1 1:0.70679 2:0.049383 3:0.061728 5:0.031152625 6:0.0012540013 7:0.045035378 +1 1:0.740458 2:0.053435 3:0.030534 5:0.037653005 6:0.037878038 7:0.018432323 +1 1:0.777778 2:0.019608 3:0.045752 5:0.032554083 7:0.018252829 +1 1:0.75969 2:0.013953 3:0.029457 5:0.027186796 7:0.015551146 +1 1:0.690141 2:0.093897 3:0.037559 5:0.055633414 6:0.031344031 7:0.019180122 +1 1:0.768657 2:0.014925 3:0.029851 5:0.019829141 7:0.017109573 +1 1:0.708487 2:0.01476 3:0.051661 4:0.0036900369 5:0.031584989 6:0.0031770032 7:0.021240213 +1 1:0.796258 2:0.004158 3:0.027027 5:0.01035439 7:0.018254652 +1 1:0.776824 2:0.017167 3:0.034335 5:0.021961147 7:0.017769287 +1 1:0.769585 2:0.013825 3:0.041475 5:0.023668242 7:0.017702598 +1 1:0.736318 2:0.024876 3:0.064677 5:0.065972895 7:0.017139909 +1 1:0.75419 2:0.03352 3:0.106145 5:0.0081105661 6:0.0032640033 7:0.062610707 +1 1:0.769585 2:0.013825 3:0.041475 5:0.023668242 7:0.017702598 +1 1:0.739394 2:0.024242 3:0.054545 5:0.062513977 7:0.017627494 +1 1:0.777429 2:0.017241 3:0.028213 5:0.023727879 6:0.0031830032 7:0.018015518 +1 1:0.758209 2:0.01194 3:0.020896 5:0.0097431157 7:0.01392428 +1 1:0.622951 2:0.07377 3:0.106557 5:0.051496131 6:0.01036201 7:0.028938427 +1 1:0.775148 2:0.005917 3:0.023669 5:0.017794045 7:0.015117622 +1 1:0.759596 2:0.012121 3:0.060606 5:0.023839697 7:0.02310914 +1 1:0.689922 2:0.007752 3:0.100775 5:0.023079331 7:0.015267537 +1 1:0.662069 2:0.075862 3:0.048276 5:0.059323424 6:0.03978904 7:0.015853659 +1 1:0.776025 2:0.006309 3:0.031546 5:0.018427683 7:0.015561287 +1 1:0.773585 2:0.014151 3:0.023585 5:0.014335127 7:0.01495628 +1 1:0.789731 2:0.007335 3:0.031785 5:0.012292577 7:0.018083963 +1 1:0.752033 2:0.02439 3:0.04065 5:0.050571765 7:0.018267896 +1 1:0.770781 2:0.020151 3:0.042821 5:0.032576447 7:0.021088037 +1 1:0.770115 2:0.019157 3:0.049808 5:0.043952112 7:0.019811232 +1 1:0.763423 2:0.035235 3:0.036913 5:0.03542409 6:0.012672013 7:0.019377146 +1 1:0.782816 2:0.009547 3:0.026253 5:0.013239306 7:0.016386287 +1 1:0.741007 2:0.035971 3:0.064748 5:0.06700908 7:0.01952097 +1 1:0.760684 2:0.025641 3:0.042735 5:0.020850417 7:0.018631439 +1 1:0.764463 2:0.016529 3:0.045455 5:0.042595381 7:0.017637573 +1 1:0.734568 2:0.040123 3:0.030864 5:0.035796818 6:0.0036000036 7:0.015676756 +1 1:0.6875 2:0.09375 3:0.05 5:0.079987476 6:0.045063045 7:0.017759146 +1 1:0.566667 2:0.114286 3:0.071429 5:0.20707289 6:0.0083340083 7:0.020905921 +1 1:0.758721 2:0.014535 3:0.037791 5:0.039606101 7:0.016679665 +1 1:0.755 2:0.045 3:0.035 5:0.036721184 6:0.01970402 7:0.018567073 +1 1:0.784173 2:0.007194 3:0.02518 5:0.020067687 7:0.01629672 +1 1:0.623377 2:0.084416 3:0.081169 5:0.11801321 6:0.0026400026 7:0.0225095 +1 1:0.736501 2:0.049676 3:0.043197 5:0.056617417 6:0.011391011 7:0.020808091 +1 1:0.794872 2:0.010256 3:0.020513 7:0.017166982 +1 1:0.757991 2:0.015982 3:0.045662 5:0.030205895 7:0.017178976 +1 1:0.789744 2:0.005128 3:0.030769 5:0.014998584 7:0.015540963 +1 1:0.73913 2:0.046823 3:0.033445 5:0.045621934 6:0.022032022 7:0.016661226 +1 1:0.69084 2:0.038168 3:0.091603 5:0.071094181 7:0.017082482 +1 1:0.770609 2:0.007168 3:0.032258 5:0.0090274775 7:0.018052274 +1 1:0.811765 2:0.011765 3:0.035294 5:0.012001849 7:0.02227403 +1 1:0.758364 2:0.026022 3:0.037175 5:0.010279844 6:0.020691021 7:0.016433945 +1 1:0.776699 2:0.014563 3:0.038835 5:0.024048425 7:0.018351884 +1 1:0.722581 2:0.025806 3:0.129032 5:0.0038987372 6:0.0031350031 7:0.075255701 +1 1:0.787879 2:0.008658 3:0.060606 5:0.014700401 7:0.026765915 +1 1:0.738889 2:0.033333 3:0.027778 5:0.034276087 7:0.014735774 +1 1:0.780702 2:0.008772 3:0.026316 5:0.015386221 7:0.017276421 +1 1:0.77686 2:0.016529 3:0.016529 7:0.01612578 +1 1:0.764211 2:0.016842 3:0.021053 5:0.025904611 7:0.014775354 +1 1:0.723301 2:0.058252 3:0.082524 5:0.020552234 6:0.0027570028 7:0.064409189 +1 1:0.760234 2:0.017544 3:0.070175 5:0.035550818 7:0.022429043 +1 1:0.739726 2:0.054795 3:0.027397 5:0.024361517 6:0.01960802 7:0.017039762 +1 1:0.776786 2:0.017857 3:0.034226 5:0.026538249 7:0.02038872 +1 1:0.735099 2:0.086093 3:0.019868 5:0.015796222 6:0.050847051 7:0.019059927 +1 1:0.743945 2:0.024221 3:0.044983 5:0.047910486 7:0.01641489 +1 1:0.74732 2:0.02144 3:0.039816 5:0.0045323752 7:0.015369963 +1 1:0.792899 2:0.005917 3:0.035503 5:0.013574762 7:0.019808055 +1 1:0.753149 2:0.030227 3:0.042821 5:0.024928063 6:0.0025080025 7:0.018369476 +1 1:0.807377 2:0.008197 3:0.032787 5:0.0088187497 7:0.021116555 +1 1:0.721003 2:0.034483 3:0.037618 5:0.038927735 7:0.014641793 +1 1:0.738189 2:0.031496 3:0.043307 5:0.032390082 6:0.0065160065 7:0.016576244 +1 1:0.75 2:0.040323 3:0.056452 5:0.028811892 6:0.0057960058 7:0.025447482 +1 1:0.753695 2:0.019704 3:0.029557 5:0.030996079 7:0.014447915 +1 1:0.76875 2:0.025 3:0.025 5:0.016638588 7:0.017073171 +1 1:0.721184 2:0.021807 3:0.070093 5:0.059368151 7:0.016697061 +1 1:0.786585 2:0.012195 3:0.042683 5:0.029117529 7:0.019036287 +1 1:0.710744 2:0.033058 3:0.082645 5:0.063714162 7:0.017687963 +1 1:0.78424 2:0.009381 3:0.035647 5:0.0091318414 7:0.018670207 +1 1:0.704348 2:0.049275 3:0.057971 5:0.087889315 7:0.016489927 +1 1:0.741722 2:0.039735 3:0.02649 6:0.016086016 7:0.015062189 +1 1:0.76054 2:0.020236 3:0.037099 5:0.038271734 7:0.018025335 +1 1:0.748619 2:0.027624 3:0.035912 5:0.028893892 7:0.017383104 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.758416 2:0.023762 3:0.035644 5:0.030161168 7:0.017906305 +1 1:0.687783 2:0.054299 3:0.076923 5:0.047865758 7:0.017189055 +1 1:0.747967 2:0.03252 3:0.036585 5:0.044906296 7:0.016458457 +1 1:0.757225 2:0.023121 3:0.034682 5:0.030869351 7:0.017023829 +1 1:0.746193 2:0.030457 3:0.045685 5:0.025017518 7:0.018447445 +1 1:0.789474 2:0.017544 3:0.052632 5:0.035953364 7:0.022179433 +1 1:0.735537 2:0.033058 3:0.057851 5:0.064452164 7:0.017486396 +1 1:0.770235 2:0.013055 3:0.031332 5:0.021946238 7:0.016223012 +1 1:0.747826 2:0.03913 3:0.030435 5:0.04920758 6:0.0099000099 7:0.01606575 +1 1:0.742382 2:0.036011 3:0.033241 5:0.037369731 6:0.012531013 7:0.020218226 +1 1:0.69403 2:0.104478 3:0.029851 5:0.093882784 6:0.037782038 7:0.018065165 +1 1:0.771982 2:0.019374 3:0.023845 5:0.023630969 6:0.0015840016 7:0.017202207 +1 1:0.769912 2:0.019912 3:0.04646 5:0.028044071 7:0.021516835 +1 1:0.697368 2:0.100877 3:0.026316 5:0.063893072 6:0.034287034 7:0.018720579 +1 1:0.759494 2:0.022152 3:0.031646 5:0.028021708 7:0.015398268 +1 1:0.713287 2:0.034965 3:0.041958 5:0.047634667 7:0.013346409 +1 1:0.748954 2:0.037657 3:0.020921 5:0.011062574 6:0.0089010089 7:0.017195634 +1 1:0.772727 2:0.010101 3:0.025253 5:0.015214766 7:0.015089921 +1 1:0.678161 2:0.118774 3:0.045977 5:0.074269825 6:0.052305052 7:0.018759927 +1 1:0.797954 2:0.023018 3:0.017903 5:0.0056803781 6:0.011424011 7:0.020475951 +1 1:0.761194 2:0.007463 3:0.029851 7:0.01392428 +1 1:0.75 2:0.033654 3:0.043269 5:0.03483518 7:0.01882036 +1 1:0.704724 2:0.043307 3:0.082677 5:0.095813517 7:0.01867678 +1 1:0.786585 2:0.012195 3:0.034553 5:0.023176241 7:0.019928616 +1 1:0.760383 2:0.025559 3:0.044728 5:0.023966425 6:0.0032160032 7:0.018175799 +1 1:0.702128 2:0.042553 3:0.06383 5:0.064638528 7:0.014962811 +1 1:0.754601 2:0.02045 3:0.038855 5:0.025613883 7:0.018143049 +1 1:0.766129 2:0.008065 3:0.040323 5:0.021178418 7:0.017309207 +1 1:0.756098 2:0.009756 3:0.053659 5:0.023258241 7:0.01906603 +1 1:0.761733 2:0.025271 3:0.064982 5:0.049915763 7:0.019723518 +1 1:0.741758 2:0.032967 3:0.038462 5:0.031517898 7:0.015846957 +1 1:0.761557 2:0.012165 3:0.036496 5:0.027328433 7:0.016185982 +1 1:0.778711 2:0.014006 3:0.036415 5:0.013969854 7:0.018224366 +1 1:0.720588 2:0.036765 3:0.051471 5:0.062118885 7:0.016140604 +1 1:0.769424 2:0.012531 3:0.025063 5:0.014133854 7:0.016122622 +1 1:0.806854 2:0.003115 3:0.040498 5:0.0062320159 7:0.02271864 +1 1:0.75 2:0.021429 3:0.057143 5:0.01873332 7:0.017334494 +1 1:0.751479 2:0.011834 3:0.12426 5:0.010570572 7:0.025436567 +1 1:0.770115 2:0.011494 3:0.04023 5:0.020268961 7:0.017182976 +1 1:0.738095 2:0.02381 3:0.029101 5:0.020291324 6:0.0054450054 7:0.017776488 +1 1:0.734807 2:0.016575 3:0.055249 5:0.028670255 7:0.017517854 +1 1:0.699346 2:0.039216 3:0.052288 5:0.023295514 7:0.012753067 +1 1:0.758772 2:0.008772 3:0.061404 5:0.0095791153 7:0.020806591 +1 1:0.750973 2:0.066148 3:0.07393 5:0.042386653 6:0.0085290085 7:0.033382366 +1 1:0.763593 2:0.014184 3:0.033097 5:0.020164597 6:0.0054090054 7:0.015986274 +1 1:0.781609 2:0.019157 3:0.05364 5:0.029937531 7:0.023268854 +1 1:0.766962 2:0.0059 3:0.023599 5:0.019568232 7:0.013706024 +1 1:0.741935 2:0.024194 3:0.048387 7:0.01534225 +1 1:0.765625 2:0.024554 3:0.037946 5:0.040545376 6:0.0046620047 7:0.017516878 +1 1:0.769802 2:0.007426 3:0.024752 5:0.014528946 7:0.01548539 +1 1:0.698061 2:0.044321 3:0.041551 5:0.059845243 6:0.013761014 7:0.014728738 +1 1:0.761557 2:0.012165 3:0.036496 5:0.027328433 7:0.016185982 +1 1:0.741294 2:0.044776 3:0.054726 5:0.045942481 6:0.013866014 7:0.019688146 +1 1:0.730679 2:0.051522 3:0.030445 5:0.025531883 6:0.035958036 7:0.016679043 +1 1:0.773481 2:0.022099 3:0.060773 5:0.046158663 7:0.021762567 +1 1:0.766917 2:0.015038 3:0.06015 5:0.026001521 7:0.019713921 +1 1:0.72467 2:0.022026 3:0.063877 5:0.061351065 7:0.01631836 +1 1:0.710407 2:0.045249 3:0.063348 5:0.08352094 7:0.019699811 +1 1:0.647541 2:0.057377 3:0.147541 5:0.027089887 7:0.082516994 +1 1:0.741722 2:0.006623 3:0.033113 5:0.010100935 7:0.014900665 +1 1:0.757576 2:0.025974 3:0.051948 5:0.04176047 7:0.018847006 +1 1:0.704082 2:0.030612 3:0.081633 5:0.044906296 7:0.017214201 +1 1:0.731343 2:0.029851 3:0.044776 5:0.046017026 7:0.014743354 +1 1:0.759336 2:0.016598 3:0.053942 5:0.028819346 7:0.01963364 +1 1:0.703448 2:0.082759 3:0.062069 5:0.04698612 6:0.031512032 7:0.020016823 8:0.023809524 +1 1:0.712934 2:0.022082 3:0.072555 5:0.051108494 7:0.019639146 +1 1:0.724138 2:0.078818 3:0.039409 5:0.044570841 6:0.04035904 7:0.020094921 +1 1:0.676617 2:0.106965 3:0.049751 5:0.038942645 6:0.047016047 7:0.020325201 +1 1:0.722997 2:0.041812 3:0.027875 5:0.053628137 6:0.00996001 7:0.019195634 +1 1:0.717105 2:0.039474 3:0.046053 5:0.059793061 7:0.015003207 +1 1:0.773852 2:0.007067 3:0.028269 5:0.010100935 7:0.015901061 +1 1:0.769928 2:0.014493 3:0.03442 5:0.029192074 7:0.016922939 +1 1:0.674419 2:0.069767 3:0.069767 5:0.026717159 6:0.037635038 7:0.015825299 +1 1:0.76092 2:0.022989 3:0.034483 5:0.022922786 6:0.0092250092 7:0.018236616 +1 1:0.778524 2:0.020134 3:0.040268 5:0.030675533 7:0.019888689 +1 1:0.8 2:0.006522 3:0.026087 5:0.010667482 7:0.01853128 +1 1:0.765432 2:0.019753 3:0.02963 5:0.013515125 7:0.016606445 +1 1:0.77712 2:0.005917 3:0.029586 5:0.010980573 7:0.016332323 +1 1:0.722488 2:0.028708 3:0.062201 5:0.027663889 7:0.015725287 +1 1:0.509524 2:0.228571 3:0.085714 5:0.17749318 6:0.085713086 7:0.018292683 +1 1:0.648649 2:0.03861 3:0.096525 5:0.056334143 7:0.018692909 +1 1:0.682667 2:0.034667 3:0.088 5:0.019359504 6:0.0025980026 7:0.05635772 +1 1:0.777778 2:0.020833 3:0.03125 5:0.026433885 7:0.017911585 +1 1:0.7343 2:0.057971 3:0.019324 4:0.0036900369 5:0.039867011 6:0.032085032 7:0.016525274 +1 1:0.742857 2:0.042857 3:0.05 5:0.015691858 6:0.012633013 7:0.020688152 +1 1:0.781116 2:0.017167 3:0.051502 5:0.027440252 7:0.021328378 +1 1:0.762195 2:0.02439 3:0.02439 5:0.01616895 7:0.017140098 +1 1:0.780822 2:0.013699 3:0.035225 5:0.026172976 7:0.01699203 +1 1:0.746988 2:0.024096 3:0.054217 5:0.032770265 7:0.016713195 +1 1:0.7825 2:0.0275 3:0.0475 5:0.02010496 7:0.022606707 +1 1:0.726358 2:0.028169 3:0.052314 5:0.0285808 7:0.015998427 +1 1:0.747396 2:0.013021 3:0.041667 5:0.029028074 7:0.02038872 +1 1:0.726351 2:0.054054 3:0.040541 5:0.055454505 6:0.015939016 7:0.019384476 +1 1:0.715789 2:0.036842 3:0.052632 5:0.045457934 7:0.015789476 +1 1:0.793558 2:0.008785 3:0.035139 5:0.013969854 7:0.023818878 +1 1:0.76699 2:0.017799 3:0.037217 5:0.024928063 7:0.017700689 +1 1:0.766667 2:0.029167 3:0.05 5:0.04064974 7:0.023297762 +1 1:0.747368 2:0.024561 3:0.038596 5:0.039546464 7:0.016131793 +1 1:0.777778 2:0.020468 3:0.02924 5:0.0068581993 6:0.0027600028 7:0.019380262 +1 1:0.720588 2:0.080882 3:0.058824 5:0.08634622 6:0.023166023 7:0.023224537 +1 1:0.756044 2:0.01978 3:0.057143 4:0.0036900369 5:0.047686849 7:0.018855537 +1 1:0.788679 2:0.003774 3:0.033962 5:0.0099294798 7:0.017280256 +1 1:0.756757 2:0.032432 3:0.018919 5:0.023690606 6:0.0095340095 7:0.015557018 +1 1:0.717949 2:0.035897 3:0.051282 5:0.04698612 7:0.014884305 +1 1:0.758377 2:0.035273 3:0.024691 4:0.0036900369 5:0.039583737 6:0.010620011 7:0.018228159 +1 1:0.795539 2:0.007435 3:0.037175 5:0.0085951128 7:0.019652732 +1 1:0.784416 2:0.01039 3:0.025974 5:0.020880235 7:0.016962305 +1 1:0.763949 2:0.012876 3:0.025751 5:0.024890791 7:0.015675707 +1 1:0.818182 2:0.005348 3:0.037433 5:0.010667482 7:0.022792488 +1 1:0.745679 2:0.05679 3:0.02963 5:0.048447214 6:0.024369024 7:0.018533573 +1 1:0.77381 2:0.017857 3:0.02381 5:0.015960222 7:0.016949768 +1 1:0.731884 2:0.036232 3:0.050725 5:0.057198873 7:0.017276421 +1 1:0.755556 2:0.005556 3:0.05 5:0.015565131 7:0.016226287 +1 1:0.8 2:0.006667 3:0.04 5:0.014528946 7:0.020853659 +1 1:0.780488 2:0.02439 3:0.03252 5:0.027074978 6:0.0036330036 7:0.020473921 +1 1:0.774799 2:0.016086 3:0.040214 5:0.027060069 6:0.0027210027 7:0.01801478 +1 1:0.772871 2:0.009464 3:0.037855 5:0.026843887 7:0.016022927 +1 1:0.755725 2:0.019084 3:0.049618 5:0.029154801 7:0.017850494 +1 1:0.730061 2:0.02454 3:0.067485 5:0.047478121 7:0.017619329 +1 1:0.80663 2:0.005525 3:0.016575 7:0.019370701 +1 1:0.727941 2:0.014706 3:0.058824 5:0.042722109 7:0.015647415 +1 1:0.792079 2:0.005941 3:0.023762 5:0.0098027522 7:0.018365128 +1 1:0.704819 2:0.024096 3:0.054217 5:0.082372937 7:0.013297091 +1 1:0.763593 2:0.021277 3:0.035461 5:0.027007887 6:0.0081510082 7:0.015914201 +1 1:0.786408 2:0.009709 3:0.02589 5:0.0083416576 7:0.017641488 +1 1:0.752688 2:0.016129 3:0.043011 5:0.029639348 7:0.01648964 +1 1:0.749455 2:0.017429 3:0.04793 5:0.036393184 7:0.016326585 +1 1:0.776824 2:0.017167 3:0.034335 5:0.021961147 7:0.017769287 +1 1:0.720137 2:0.027304 3:0.040956 5:0.050437583 7:0.015379171 +1 1:0.770035 2:0.017422 3:0.027875 5:0.01873332 7:0.016911701 +1 1:0.735202 2:0.012461 3:0.043614 5:0.040627376 7:0.013942707 +1 1:0.760479 2:0.011976 3:0.047904 5:0.0323379 7:0.016832189 +1 1:0.655462 2:0.084034 3:0.046218 5:0.034089723 6:0.045732046 7:0.016806726 +1 1:0.746789 2:0.049541 3:0.027523 5:0.0089827501 6:0.028917029 7:0.018572384 +1 1:0.773109 2:0.008403 3:0.033613 5:0.022251875 7:0.017165402 +1 1:0.721311 2:0.035768 3:0.029806 5:0.041164105 6:0.0082830083 7:0.016457055 +1 1:0.761364 2:0.017045 3:0.051136 5:0.014678037 7:0.01759978 +1 1:0.746835 2:0.025316 3:0.037975 5:0.018315865 7:0.015707006 +1 1:0.716049 2:0.028807 3:0.061728 5:0.038957554 7:0.014403293 +1 1:0.729885 2:0.022989 3:0.045977 5:0.05262177 7:0.01489347 +1 1:0.727273 2:0.014354 3:0.057416 5:0.029758621 7:0.01461664 +1 1:0.762763 2:0.012012 3:0.042042 5:0.01711568 7:0.015948878 +1 1:0.744737 2:0.034211 3:0.026316 5:0.038189734 7:0.015661104 +1 1:0.776074 2:0.016871 3:0.030675 5:0.027798071 7:0.017553866 +1 1:0.756622 2:0.034768 3:0.043046 5:0.028558436 6:0.013137013 7:0.01844411 +1 1:0.752252 2:0.036036 3:0.045045 5:0.046449391 6:0.0093450093 7:0.017633488 +1 1:0.712544 2:0.04007 3:0.076655 5:0.092958418 7:0.017889012 +1 1:0.722581 2:0.051613 3:0.012903 5:0.019829141 6:0.031914032 7:0.014791506 +1 1:0.755973 2:0.013652 3:0.032423 5:0.032315537 7:0.014401067 +1 1:0.758523 2:0.025568 3:0.036932 5:0.022095329 7:0.017530488 +1 1:0.727273 2:0.048951 3:0.048951 5:0.066412715 6:0.0066810067 7:0.019145488 +1 1:0.769585 2:0.013825 3:0.041475 5:0.023668242 7:0.017702598 +1 1:0.742424 2:0.022727 3:0.045455 5:0.045316297 7:0.015197707 +1 1:0.761739 2:0.013913 3:0.041739 5:0.014663128 7:0.016171793 +1 1:0.782609 2:0.007246 3:0.028986 5:0.022117693 7:0.014890421 +-1 1:0.723404 2:0.007092 3:0.035461 7:0.013795189 8:0.095238095 +-1 1:0.681818 2:0.045455 3:0.022727 6:0.027273027 7:0.015243902 +-1 1:0.663366 3:0.069307 7:0.01243661 8:0.023809524 +-1 1:0.616279 2:0.034884 3:0.145349 5:0.015028402 7:0.017583665 +-1 1:0.713235 2:0.029412 3:0.036765 4:0.0036900369 5:0.065197621 7:0.015378409 +-1 1:0.987448 7:0.18078375 +-1 1:1 7:0.10670732 +-1 1:0.925 7:0.03902439 8:0.023809524 +-1 1:0.82 3:0.12 4:0.05904059 7:0.085243902 +-1 1:0.880952 3:0.071429 4:0.036900369 7:0.065040652 +-1 1:0.68942 2:0.071672 3:0.023891 6:0.066273066 7:0.014130524 8:0.047619048 +-1 1:0.648148 2:0.111111 3:0.055556 4:0.0073800738 6:0.084507085 7:0.016034329 +-1 1:0.730769 3:0.115385 4:0.0073800738 7:0.022514073 +-1 1:1 4:0.055350554 7:0.076219512 +-1 1:0.661765 2:0.029412 3:0.132353 4:0.025830258 7:0.018382354 8:0.023809524 +-1 1:0.794118 3:0.117647 4:0.011070111 7:0.036047348 +-1 1:0.68 2:0.1 3:0.04 4:0.014760148 5:0.080158931 6:0.032259032 7:0.022682927 +-1 1:0.803468 3:0.023121 4:0.0036900369 7:0.017763994 +-1 1:0.823529 3:0.044118 7:0.042144909 +-1 1:0.68 7:0.0085365854 +-1 1:0.833333 3:0.041667 4:0.0073800738 7:0.016768293 +-1 1:0.734694 3:0.061224 4:0.0036900369 7:0.012319561 8:0.023809524 +-1 1:0.797546 2:0.030675 3:0.02454 4:0.0036900369 6:0.018405018 7:0.024390244 +-1 1:0.829268 7:0.015913146 +-1 1:0.818182 7:0.014781963 8:0.023809524 +-1 1:0.714724 2:0.067485 3:0.04908 6:0.046602047 7:0.019265299 +-1 1:0.844828 7:0.019396555 +-1 1:0.857143 3:0.028571 7:0.030662024 +-1 1:0.894737 7:0.023748396 +-1 1:0.620155 2:0.046512 3:0.093023 5:0.039971374 6:0.016086016 7:0.017630933 +-1 1:0.77095 3:0.03352 4:0.014760148 7:0.014886226 8:0.095238095 +-1 1:0.707071 2:0.010101 3:0.090909 4:0.033210332 5:0.013313852 7:0.017245628 8:0.047619048 +-1 1:0.711111 3:0.044444 7:0.021002707 8:0.023809524 +-1 1:0.8 7:0.01195122 +-1 1:0.607143 2:0.107143 3:0.142857 5:0.093182055 6:0.075000075 7:0.017421604 8:0.023809524 +-1 1:0.735849 3:0.056604 4:0.011070111 7:0.0190405 8:0.023809524 +-1 1:0.9375 2:0.0625 4:0.0073800738 5:0.054813412 7:0.051829268 +-1 1:0.690909 2:0.109091 3:0.018182 4:0.0036900369 6:0.1016941 7:0.016352549 8:0.023809524 +-1 1:0.714286 2:0.017857 3:0.089286 4:0.014760148 5:0.055215959 7:0.014699476 +-1 1:0.941176 4:0.022140221 7:0.02618364 +-1 1:1 4:0.033210332 7:0.042682927 +-1 1:0.777778 3:0.123457 4:0.14391144 7:0.077235774 +-1 1:0.773333 2:0.106667 3:0.106667 4:0.20295203 5:0.0038540098 6:0.010854011 7:0.15731707 +-1 1:0.909091 4:0.033210332 7:0.027439024 +-1 1:0.864865 4:0.036900369 7:0.02010547 +-1 1:0.844444 4:0.022140221 7:0.019647695 +-1 1:0.875 3:0.083333 4:0.036900369 7:0.038109756 +-1 1:0.521739 2:0.23913 3:0.130435 4:0.018450185 5:0.11959358 6:0.11229911 7:0.024787909 +-1 1:0.68254 2:0.031746 3:0.063492 4:0.014760148 5:0.054410866 7:0.013259774 8:0.047619048 +-1 1:0.734694 3:0.081633 4:0.018450185 7:0.026007963 +-1 1:0.666667 2:0.222222 3:0.037037 4:0.011070111 5:0.10425954 6:0.062937063 7:0.032294488 +-1 1:0.807692 3:0.076923 4:0.011070111 7:0.020168854 +-1 1:0.888889 4:0.014760148 7:0.018970189 +-1 1:0.947368 4:0.014760148 7:0.02920411 +-1 1:1 4:0.033210332 7:0.045731707 +-1 1:0.820895 4:0.044280443 7:0.026938482 +-1 1:0.717647 2:0.023529 3:0.105882 4:0.025830258 6:0.01017001 7:0.021162122 +-1 1:0.777778 3:0.055556 4:0.0073800738 7:0.01388889 +-1 1:0.862745 3:0.019608 4:0.0036900369 7:0.028455287 +-1 1:0.846154 4:0.0036900369 7:0.016885555 +-1 1:0.719101 2:0.022472 3:0.05618 6:0.014286014 7:0.0143875 +-1 1:0.920635 4:0.11070111 7:0.077719707 +-1 1:0.666667 2:0.031746 3:0.142857 4:0.018450185 7:0.022260939 +-1 1:0.630435 3:0.152174 4:0.0073800738 7:0.012460232 +-1 1:0.746667 3:0.026667 4:0.0073800738 7:0.017479677 +-1 1:0.620915 2:0.107843 3:0.071895 4:0.011070111 5:0.12128576 6:0.033792034 7:0.015921409 +-1 1:0.521739 2:0.043478 3:0.173913 5:0.085682764 7:0.023064689 +-1 1:0.761905 3:0.035714 7:0.013646921 +-1 1:0.802469 7:0.013023189 8:0.047619048 +-1 1:0.878788 2:0.060606 3:0.060606 4:0.0036900369 6:0.0053490053 7:0.10365854 +-1 1:0.854839 7:0.020751378 +-1 1:0.75 3:0.088235 4:0.011070111 7:0.018561695 +-1 1:0.76 3:0.08 4:0.0073800738 7:0.014634146 +-1 1:0.730769 2:0.038462 3:0.038462 7:0.011960598 +-1 1:0.8 3:0.133333 7:0.029268293 +-1 1:0.733333 3:0.088889 7:0.014498646 8:0.023809524 +-1 1:0.676471 3:0.088235 7:0.011298421 +-1 1:0.702899 3:0.108696 4:0.014760148 7:0.017541537 8:0.023809524 +-1 1:0.813333 3:0.04 7:0.026178866 +-1 1:0.703704 2:0.047619 3:0.060847 4:0.011070111 5:0.014879311 6:0.02994003 7:0.016163378 +-1 1:0.724551 2:0.041916 3:0.02994 4:0.0073800738 6:0.036321036 7:0.015079598 +-1 1:0.804348 7:0.012857902 8:0.047619048 +-1 1:0.716216 3:0.101351 4:0.014760148 7:0.01882828 +-1 1:0.681564 2:0.019553 3:0.044693 5:0.042804109 7:0.017798744 +-1 1:0.792453 7:0.013057988 8:0.047619048 +-1 1:0.754717 2:0.009434 5:0.034350633 7:0.012482744 8:0.11904762 +-1 1:0.857143 7:0.013501744 +-1 1:0.771812 2:0.026846 3:0.013423 6:0.015267015 7:0.016082829 +-1 1:0.863636 3:0.045455 7:0.023835921 +-1 1:0.602941 2:0.176471 3:0.102941 5:0.026910978 6:0.097473097 7:0.024838591 +-1 1:0.797521 2:0.012397 3:0.03719 4:0.011070111 5:0.025733156 7:0.021895787 +-1 1:0.842105 7:0.013799744 +-1 1:0.933333 7:0.038414634 +-1 1:0.813953 3:0.011628 7:0.01563386 +-1 1:0.62963 2:0.111111 3:0.074074 6:0.085713086 7:0.015808488 +-1 1:0.767442 2:0.046512 3:0.046512 5:0.10499754 7:0.020136128 +-1 1:0.730469 2:0.058594 3:0.035156 5:0.081694572 6:0.0041100041 7:0.017387573 +-1 1:0.825581 2:0.017442 3:0.011628 6:0.0088380088 7:0.024071189 8:0.023809524 +-1 1:0.728814 2:0.056497 3:0.050847 5:0.1110581 7:0.018499378 8:0.023809524 +-1 1:0.773585 7:0.011504829 8:0.071428571 +-1 1:0.818182 7:0.012195122 8:0.047619048 +-1 1:0.681159 2:0.046377 3:0.06087 4:0.025830258 5:0.023712969 6:0.031812032 7:0.016666665 8:0.023809524 +-1 1:0.75 3:0.05 7:0.013841463 +-1 1:0.698413 3:0.047619 4:0.011070111 7:0.03290747 +-1 1:0.704434 2:0.039409 3:0.064039 4:0.0073800738 5:0.08471367 7:0.015859665 8:0.023809524 +-1 1:0.986842 7:0.15645057 +-1 1:0.710526 2:0.035088 3:0.057018 6:0.031143031 7:0.015457854 8:0.071428571 +-1 1:0.691667 2:0.025 3:0.1 4:0.011070111 6:0.016392016 7:0.018597561 +-1 1:0.791209 7:0.012865183 +-1 1:0.6 2:0.1 3:0.15 5:0.13553889 6:0.054546055 7:0.016768293 +-1 1:0.657143 2:0.095238 6:0.077142077 7:0.020325201 +-1 1:0.611111 2:0.111111 3:0.138889 5:0.048723033 7:0.025914634 +-1 1:0.586957 2:0.119565 3:0.152174 5:0.13594889 6:0.027357027 7:0.021805409 +-1 1:0.747967 3:0.073171 7:0.020126909 8:0.047619048 +-1 1:0.811388 2:0.010676 3:0.035587 5:0.005665469 6:0.0022800023 7:0.028534848 +-1 1:0.75 3:0.02381 4:0.0036900369 7:0.012340299 8:0.095238095 +-1 1:0.785714 3:0.035714 7:0.01883711 8:0.023809524 +-1 1:0.666667 2:0.037037 3:0.160494 5:0.048879579 7:0.022959951 +-1 1:0.695652 3:0.173913 7:0.017232238 +-1 1:0.725389 2:0.025907 3:0.072539 5:0.04321411 7:0.021799573 8:0.047619048 +-1 1:0.738095 3:0.238095 4:0.0073800738 7:0.10844948 +-1 1:0.76 3:0.06 7:0.016219512 +-1 1:0.730769 2:0.038462 3:0.153846 7:0.042917451 +-1 1:0.689655 3:0.068966 7:0.01198486 +-1 1:0.904762 3:0.047619 7:0.036585366 +-1 1:0.674419 2:0.023256 3:0.139535 5:0.058235057 7:0.018150878 +-1 1:0.778788 3:0.018182 7:0.014726537 8:0.071428571 +-1 1:0.680851 2:0.085106 3:0.12766 5:0.058235057 7:0.033212244 +-1 1:0.767123 3:0.054795 4:0.0073800738 7:0.017791512 8:0.023809524 +-1 1:0.740741 7:0.0092592622 8:0.023809524 +-1 1:0.59375 2:0.28125 3:0.09375 4:0.0036900369 5:0.028454072 6:0.08015408 7:0.04992378 +-1 1:0.64 2:0.05 3:0.13 5:0.018919685 6:0.022842023 7:0.02402439 +-1 1:0.703704 2:0.037037 3:0.037037 5:0.040515558 7:0.01385125 +-1 1:0.647059 2:0.078431 3:0.058824 5:0.14153981 6:0.018987019 7:0.018890482 +-1 1:0.759259 3:0.046296 7:0.016316622 8:0.095238095 +-1 1:0.700483 2:0.120773 3:0.009662 5:0.0038241916 6:0.033846034 7:0.057440793 +-1 1:0.766667 3:0.055556 4:0.0036900369 7:0.02161247 8:0.047619048 +-1 1:0.738095 3:0.095238 4:0.011070111 7:0.023954701 8:0.023809524 +-1 1:0.75 3:0.25 4:0.0073800738 7:0.039634146 +-1 1:0.723404 3:0.074468 7:0.013103268 8:0.023809524 +-1 1:0.77 7:0.012926829 8:0.023809524 +-1 1:0.609756 2:0.292683 3:0.04878 4:0.0036900369 5:0.078198381 6:0.083916084 7:0.042534207 +-1 1:0.584906 2:0.169811 3:0.113208 4:0.011070111 5:0.15370566 6:0.046392046 7:0.022319372 +-1 1:0.688797 2:0.06639 3:0.033195 4:0.0073800738 5:0.052867771 6:0.031914032 7:0.014269811 +-1 1:0.714286 3:0.081633 4:0.0073800738 7:0.016799402 8:0.047619048 +-1 1:0.807229 2:0.024096 5:0.055424687 7:0.019761976 +-1 1:0.714286 2:0.071429 3:0.214286 5:0.070997272 7:0.045731707 +-1 1:0.540541 2:0.081081 3:0.189189 5:0.096186245 7:0.025543835 +-1 1:0.685714 2:0.114286 3:0.057143 4:0.0036900369 5:0.10212008 6:0.020547021 7:0.025435543 +-1 1:0.763975 2:0.006211 3:0.062112 7:0.017573098 +-1 1:1 7:0.054878049 +-1 1:0.7 2:0.05 3:0.1 7:0.015853659 8:0.023809524 +-1 1:0.769737 2:0.006579 3:0.042763 7:0.015845634 +-1 1:0.729167 2:0.020833 3:0.072917 5:0.030928988 6:0.012447012 7:0.015307421 +-1 1:0.753968 3:0.095238 7:0.022502902 +-1 1:0.661017 2:0.050847 3:0.067797 5:0.057787783 6:0.023256023 7:0.013331957 8:0.047619048 +-1 1:0.795455 3:0.090909 4:0.0073800738 7:0.021480043 +-1 1:0.718919 3:0.054054 7:0.012755439 8:0.047619048 +-1 1:0.714286 3:0.183673 7:0.036336488 8:0.023809524 +-1 1:0.666667 3:0.111111 7:0.010614274 +-1 1:0.622222 2:0.111111 3:0.066667 5:0.12220267 6:0.049179049 7:0.016531165 +-1 1:0.686391 2:0.08284 3:0.053254 4:0.0073800738 5:0.015468221 6:0.062241062 7:0.017390677 +-1 1:0.796117 3:0.067961 4:0.0036900369 7:0.030191811 +-1 1:0.587302 2:0.126984 3:0.095238 5:0.2555872 6:0.017142017 7:0.016937671 8:0.023809524 +-1 1:0.733333 3:0.074074 4:0.0036900369 7:0.013866305 +-1 1:0.578947 2:0.105263 3:0.157895 5:0.3467267 7:0.013799744 +-1 1:0.862069 3:0.034483 7:0.024390244 +-1 1:0.823529 7:0.011477762 +-1 1:0.754967 3:0.05298 4:0.014760148 7:0.016838957 +-1 1:0.930435 7:0.10922588 +-1 1:0.580645 2:0.193548 3:0.048387 5:0.46857156 7:0.01721086 +-1 1:0.712963 2:0.064815 3:0.046296 5:0.082596574 7:0.020381659 8:0.023809524 +-1 1:0.756757 7:0.01466711 8:0.047619048 +-1 1:0.733333 2:0.014141 3:0.092929 4:0.033210332 6:0.0065250065 7:0.033973884 +-1 1:0.575 2:0.125 3:0.09375 4:0.011070111 5:0.026389158 6:0.063717064 7:0.021532012 +-1 1:0.759725 2:0.032037 5:0.0072831094 6:0.038085038 7:0.014288104 8:0.047619048 +-1 1:0.835938 3:0.03125 4:0.11070111 7:0.046065171 8:0.023809524 +-1 1:0.803279 3:0.032787 4:0.05904059 7:0.030287884 8:0.047619048 +-1 1:0.826087 7:0.013520677 +-1 1:0.72973 2:0.027027 3:0.040541 5:0.0463003 7:0.013266317 +-1 1:0.736842 3:0.105263 7:0.017008988 +-1 1:0.715976 2:0.023669 3:0.071006 4:0.0036900369 5:0.01326167 6:0.010677011 7:0.020277098 +-1 1:0.986486 7:0.15828938 +-1 1:0.777778 2:0.013468 5:0.010585481 6:0.012783013 7:0.014453476 8:0.047619048 +-1 1:0.907692 7:0.12326454 +-1 1:0.75 3:0.071429 7:0.01796603 +-1 1:0.787879 2:0.030303 6:0.042858043 7:0.01293422 +-1 1:0.68 2:0.02 3:0.12 4:0.0073800738 5:0.062118885 7:0.014634146 8:0.023809524 +-1 1:0.740484 2:0.017301 3:0.058824 4:0.018450185 5:0.0087516586 6:0.007041007 7:0.017976201 8:0.047619048 +-1 1:1 7:0.082317073 +-1 1:0.818182 3:0.136364 7:0.049057652 +-1 1:0.744526 2:0.021898 3:0.10219 5:0.032934266 7:0.030220756 8:0.023809524 +-1 1:0.72 2:0.07 6:0.043956044 7:0.016646341 +-1 1:0.722222 3:0.166667 4:0.0073800738 7:0.017953927 +-1 1:0.692308 3:0.153846 4:0.011070111 7:0.019387116 8:0.023809524 +-1 1:0.746269 2:0.014925 3:0.074627 5:0.033731904 7:0.020112848 8:0.023809524 +-1 1:0.75 3:0.125 4:0.0073800738 7:0.019245427 +-1 1:0.769231 3:0.115385 7:0.020637896 +-1 1:0.814815 7:0.013211384 8:0.023809524 +-1 1:0.866667 3:0.133333 7:0.048780488 +-1 1:0.769231 2:0.102564 5:0.2225262 7:0.020950591 +-1 1:0.875 7:0.015625 +-1 1:0.75 2:0.0625 3:0.041667 6:0.03999904 7:0.019054878 +-1 1:0.71028 2:0.074766 3:0.018692 5:0.024928063 6:0.04013404 7:0.017038982 8:0.047619048 +-1 1:0.76087 2:0.01087 3:0.065217 4:0.0036900369 5:0.029579712 7:0.016702012 +-1 1:0.653061 2:0.076531 3:0.056122 4:0.0036900369 5:0.014558764 6:0.064452064 7:0.015928323 8:0.023809524 +-1 1:0.805556 7:0.013042006 +-1 1:0.827586 7:0.013877207 +-1 1:0.782609 3:0.021739 7:0.014713677 8:0.071428571 +-1 1:0.791667 3:0.041667 7:0.01549797 8:0.023809524 +-1 1:0.764706 3:0.176471 7:0.03479197 +-1 1:0.962963 7:0.1472448 8:0.023809524 +-1 1:0.75 7:0.02195122 +-1 1:0.795918 3:0.081633 4:0.0073800738 7:0.023768043 +-1 1:0.833333 7:0.016999262 +-1 1:0.781726 7:0.012411787 8:0.023809524 +-1 1:0.8 3:0.054545 7:0.019290463 +-1 1:0.778409 7:0.012680152 8:0.023809524 +-1 1:0.733333 3:0.083333 7:0.014176829 +-1 1:0.8 7:0.012804878 8:0.023809524 +-1 1:0.761905 2:0.063492 3:0.047619 5:0.06186543 6:0.012447012 7:0.023325591 +-1 1:0.723404 3:0.010638 7:0.013751945 8:0.095238095 +-1 1:0.730769 3:0.057692 4:0.011070111 7:0.017667293 8:0.023809524 +-1 1:0.517241 2:0.103448 3:0.068966 5:0.40660922 7:0.011564341 +-1 1:0.781818 7:0.01452328 8:0.095238095 +-1 1:0.761905 2:0.027211 3:0.037415 5:0.03380645 6:0.01020301 7:0.018292683 8:0.023809524 +-1 1:0.681818 2:0.030303 3:0.060606 4:0.0073800738 5:0.093472783 7:0.014735774 8:0.095238095 +-1 1:0.842105 7:0.013157896 +-1 1:0.656109 2:0.085973 3:0.067873 4:0.0073800738 5:0.051861405 6:0.046956047 7:0.015864695 +-1 1:0.791667 7:0.010924799 +-1 1:0.958333 7:0.039634146 +-1 1:0.801347 3:0.010101 7:0.018231091 8:0.047619048 +-1 1:0.638889 2:0.055556 3:0.111111 4:0.014760148 6:0.035928036 7:0.014142951 +-1 1:0.677419 3:0.096774 7:0.024390244 +-1 1:0.75 3:0.15625 4:0.014760148 7:0.03125 +-1 1:0.784232 2:0.008299 5:0.023929152 7:0.015762573 8:0.14285714 +-1 1:0.843137 7:0.016618841 8:0.023809524 +-1 1:0.558824 7:0.029053085 +-1 1:0.725 3:0.05 7:0.014481707 8:0.023809524 +-1 1:0.833333 2:0.055556 5:0.1461691 7:0.017276421 +-1 1:0.8 2:0.025 3:0.1 4:0.011070111 5:0.029467893 7:0.038567073 8:0.023809524 +-1 1:0.842105 7:0.013478817 +-1 1:0.767442 3:0.116279 7:0.023114012 +-1 1:0.677419 2:0.075269 3:0.096774 5:0.027611707 6:0.044445044 7:0.017702598 +-1 1:0.814815 2:0.037037 5:0.094359877 7:0.017841012 +-1 1:0.612245 2:0.061224 3:0.142857 5:0.096186245 6:0.019356019 7:0.019288201 +-1 1:0.620253 2:0.151899 3:0.063291 5:0.03080226 6:0.11157011 7:0.018678604 8:0.023809524 +-1 1:0.684932 2:0.105023 3:0.022831 4:0.0036900369 5:0.040880831 6:0.087750088 7:0.015229982 +-1 1:0.767045 2:0.005682 3:0.005682 7:0.011779378 8:0.095238095 +-1 1:0.758621 3:0.12069 4:0.0036900369 7:0.021446591 +-1 1:0.763441 2:0.032258 3:0.010753 6:0.028170028 7:0.013965384 +-1 1:0.777778 3:0.035088 7:0.015404366 8:0.023809524 +-1 1:0.7 2:0.133333 3:0.033333 6:0.075630076 7:0.024186994 +-1 1:0.797468 3:0.025316 7:0.015359677 +-1 1:0.933333 3:0.033333 4:0.0036900369 7:0.054268293 +-1 1:1 7:0.1554878 +-1 1:0.727273 2:0.006993 3:0.083916 4:0.011070111 5:0.013828217 7:0.022983116 +-1 1:0.764925 2:0.007463 3:0.037313 5:0.021826965 7:0.015539677 8:0.047619048 +-1 1:0.694051 2:0.065156 3:0.031161 4:0.011070111 5:0.019411686 6:0.058593059 7:0.013266079 +-1 1:0.65 2:0.133333 3:0.083333 4:0.0036900369 6:0.06030306 7:0.020223579 +-1 1:0.868421 3:0.078947 4:0.066420664 7:0.052150189 +-1 1:0.655172 3:0.022989 7:0.021236335 +-1 1:0.823529 2:0.117647 4:0.029520295 6:0.061857062 7:0.03479197 +-1 1:1 7:0.048780488 +-1 1:0.782609 3:0.086957 7:0.021076354 8:0.023809524 +-1 1:0.709677 3:0.129032 7:0.015538945 +-1 1:0.771144 2:0.014925 3:0.049751 6:0.0093030093 7:0.019566799 8:0.023809524 +-1 1:0.628571 2:0.185714 6:0.13580114 7:0.02116725 +-1 1:0.7625 2:0.04375 6:0.033783034 7:0.016920732 +-1 1:0.707143 2:0.007143 3:0.05 7:0.030400695 +-1 1:0.75 3:0.027778 7:0.011517616 +-1 1:0.735632 3:0.045977 7:0.013036165 8:0.023809524 +-1 1:0.705128 3:0.153846 7:0.023999372 +-1 1:0.928571 7:0.023954701 +-1 1:0.648649 3:0.126126 7:0.015216439 +-1 1:0.719298 3:0.070175 4:0.0073800738 7:0.01390672 8:0.047619048 +-1 1:0.690909 2:0.018182 3:0.072727 4:0.0036900369 5:0.071675637 7:0.011529933 8:0.023809524 +-1 1:0.701493 3:0.149254 4:0.025830258 7:0.025118311 +-1 1:0.716049 2:0.012346 3:0.061728 7:0.013324299 +-1 1:0.646154 2:0.169231 3:0.084615 5:0.090662413 6:0.028377028 7:0.034709189 +-1 1:0.709677 2:0.048387 3:0.048387 5:0.039867011 6:0.048129048 7:0.01839103 +-1 1:0.681818 2:0.045455 3:0.136364 5:0.13553889 7:0.015243902 +-1 1:0.627273 2:0.127273 3:0.054545 5:0.073561642 6:0.049341049 7:0.016851439 8:0.023809524 +-1 1:0.571429 2:0.238095 5:0.55909233 6:0.075000075 7:0.011614402 +-1 1:0.784314 2:0.078431 3:0.058824 5:0.076327285 6:0.01023901 7:0.035031085 +-1 1:0.871795 7:0.018292683 +-1 1:0.75102 2:0.016327 3:0.02449 5:0.05195086 7:0.014285713 +-1 1:0.788991 3:0.045872 7:0.016894159 +-1 1:0.439024 2:0.195122 3:0.121951 4:0.0073800738 5:0.6286956 7:0.012343841 8:0.071428571 +-1 1:0.680851 2:0.056738 3:0.06383 4:0.0036900369 5:0.018271137 6:0.036765037 7:0.017644006 +-1 1:0.887255 2:0.088235 6:0.0085860086 7:0.16708512 +-1 1:0.6875 3:0.1875 4:0.0073800738 7:0.01867378 +-1 1:0.714286 3:0.111111 4:0.011070111 7:0.016550524 8:0.023809524 +-1 1:0.777778 3:0.047009 7:0.018892018 8:0.047619048 +-1 1:0.681818 3:0.045455 7:0.019955652 +-1 1:0.525 2:0.25 3:0.083333 4:0.011070111 5:0.078056744 6:0.089004089 7:0.029115854 +-1 1:0.616822 2:0.084112 3:0.11215 4:0.0073800738 5:0.092600599 6:0.018633019 7:0.018349671 8:0.023809524 +-1 1:0.75 3:0.083333 7:0.013973579 +-1 1:0.862069 3:0.034483 7:0.054457524 +-1 1:0.804348 3:0.028986 7:0.016525274 +-1 1:0.797521 2:0.016529 3:0.016529 5:0.038823372 7:0.019350939 +-1 1:0.987805 7:0.16965349 +-1 1:0.77551 3:0.05102 7:0.016052762 +-1 1:0.745614 3:0.078947 7:0.018399659 8:0.071428571 +-1 1:0.963636 7:0.056651884 +-1 1:0.755319 3:0.010638 7:0.014011415 +-1 1:0.775 3:0.008333 7:0.013770323 +-1 1:0.730245 2:0.032698 3:0.027248 5:0.026463704 6:0.010650011 7:0.014039341 +-1 1:0.769912 3:0.119469 4:0.1697417 7:0.074465787 +-1 1:0.529412 2:0.352941 3:0.058824 5:0.098087159 6:0.15789616 7:0.027259683 +-1 1:0.8 7:0.014634146 +-1 1:0.736264 2:0.032967 3:0.06044 4:0.011070111 5:0.057899602 7:0.017254085 +-1 1:0.660377 3:0.188679 4:0.0036900369 7:0.019328116 +-1 1:0.697674 2:0.063123 3:0.053156 5:0.090356775 6:0.018183018 7:0.016712585 8:0.11904762 +-1 1:0.666667 2:0.037037 3:0.185185 4:0.0073800738 5:0.059636515 7:0.028229451 +-1 1:0.647059 2:0.147059 3:0.088235 4:0.0073800738 5:0.31857081 7:0.02098278 +-1 1:0.586207 2:0.137931 3:0.137931 5:0.096812428 6:0.077922078 7:0.032380152 +-1 1:0.833333 3:0.083333 7:0.019308945 +-1 1:0.803922 3:0.019608 7:0.017455762 8:0.023809524 +-1 1:0.631579 2:0.210526 6:0.21951322 7:0.013157896 +-1 1:0.735294 3:0.044118 4:0.0036900369 7:0.012105451 8:0.071428571 +-1 1:0.708738 2:0.067961 3:0.058252 5:0.023891879 6:0.028845029 7:0.01847028 +-1 1:0.684211 3:0.131579 4:0.0036900369 7:0.01331836 +-1 1:0.525 2:0.075 3:0.15 5:0.08874659 7:0.012804878 +-1 1:0.578947 2:0.105263 3:0.052632 5:0.23295514 7:0.010269579 +-1 1:0.721519 2:0.012658 3:0.139241 4:0.0073800738 5:0.021484055 7:0.026782957 +-1 1:0.74 3:0.04 4:0.0036900369 7:0.011707317 +-1 1:0.735849 2:0.009434 3:0.028302 7:0.015186378 8:0.071428571 +-1 1:0.731481 2:0.009259 3:0.055556 5:0.028782073 7:0.014622854 +-1 1:0.73913 2:0.043478 3:0.059783 5:0.040560285 6:0.0065280065 7:0.030454665 +-1 1:0.637363 2:0.010989 3:0.131868 6:0.012294012 7:0.016349506 +-1 1:0.650794 2:0.063492 3:0.126984 4:0.0036900369 5:0.17962518 7:0.016066591 8:0.023809524 +-1 1:0.566667 2:0.1 3:0.033333 6:0.06976807 7:0.017479677 +-1 1:0.644444 2:0.2 3:0.088889 5:0.016675861 6:0.04026904 7:0.060569104 +-1 1:0.773913 3:0.017391 7:0.013653232 8:0.095238095 +-1 1:0.875 7:0.01867378 8:0.023809524 +-1 1:0.682927 3:0.097561 4:0.0036900369 7:0.017102915 +-1 1:0.671642 2:0.074627 3:0.067164 4:0.0036900369 5:0.094844423 6:0.0076350076 7:0.017883146 +-1 1:0.77305 3:0.021277 7:0.017644006 +-1 1:0.933333 2:0.066667 5:0.062118885 7:0.048780488 +-1 1:0.797468 3:0.012658 4:0.0073800738 7:0.01481939 +-1 1:0.714286 3:0.142857 4:0.022140221 7:0.045731707 +-1 1:0.933333 3:0.066667 7:0.048780488 +-1 1:1 7:0.073170732 +-1 1:0.882353 7:0.071556671 +-1 1:0.972973 3:0.004505 7:0.1722149 +-1 1:0.682353 3:0.058824 4:0.0073800738 7:0.015351506 +-1 1:0.672131 2:0.008197 3:0.07377 4:0.0036900369 5:0.027007887 7:0.013794482 +-1 1:0.781513 3:0.008403 7:0.01337364 8:0.047619048 +-1 1:0.787879 3:0.010101 7:0.014535598 +-1 1:0.772727 2:0.012987 3:0.012987 6:0.0071430071 7:0.016629713 8:0.023809524 +-1 1:0.530612 2:0.193878 3:0.102041 5:0.25355955 6:0.030612031 7:0.018292683 +-1 1:0.885714 7:0.026655049 8:0.023809524 +-1 1:0.724868 2:0.021164 3:0.084656 4:0.0036900369 6:0.014130014 7:0.020551037 8:0.047619048 +-1 1:0.774194 7:0.010621555 8:0.023809524 +-1 1:0.684073 2:0.08094 3:0.02611 5:0.10905282 6:0.043887044 7:0.015235939 +-1 1:0.708333 2:0.013889 3:0.138889 7:0.02938686 8:0.023809524 +-1 1:0.784615 7:0.012476549 8:0.047619048 +-1 1:1 7:0.042682927 +-1 1:0.756757 2:0.009009 3:0.054054 5:0.025971702 7:0.015765768 8:0.095238095 +-1 1:0.681818 2:0.015152 3:0.136364 4:0.0036900369 5:0.013656762 7:0.050443457 8:0.023809524 +-1 1:0.794118 7:0.02618364 8:0.023809524 +-1 1:0.75 2:0.125 6:0.078948079 7:0.019308945 +-1 1:0.724138 2:0.034483 3:0.062069 5:0.077855471 7:0.01610597 8:0.023809524 +-1 1:0.816327 7:0.016177201 8:0.023809524 +-1 1:0.925 4:0.036900369 7:0.037195122 +-1 1:0.824324 7:0.016809494 +-1 1:0.596774 2:0.032258 3:0.177419 5:0.043087382 7:0.017014165 +-1 1:0.726316 2:0.021053 3:0.073684 6:0.011070011 7:0.017394098 +-1 1:0.769231 7:0.011843341 8:0.023809524 +-1 1:0.74359 2:0.025641 3:0.051282 5:0.06160452 7:0.018918073 +-1 1:0.785047 3:0.028037 7:0.015158421 +-1 1:0.569444 2:0.125 3:0.069444 6:0.071007071 7:0.014312329 +-1 1:0.712042 3:0.052356 4:0.0036900369 7:0.015323713 8:0.047619048 +-1 1:0.666667 2:0.107692 3:0.030769 5:0.069409449 6:0.061452061 7:0.016791744 +-1 1:0.8 3:0.025 4:0.0036900369 7:0.017759146 8:0.047619048 +-1 1:0.78125 3:0.010417 7:0.021023884 +-1 1:0.690476 2:0.095238 3:0.02381 5:0.081918209 6:0.032967033 7:0.013211384 +-1 1:0.619718 2:0.056338 3:0.098592 5:0.095984972 6:0.025752026 7:0.020010305 8:0.071428571 +-1 1:0.848485 3:0.015152 7:0.025776055 8:0.023809524 +-1 1:0.813953 7:0.01290414 8:0.023809524 +-1 1:0.833333 2:0.083333 3:0.083333 5:0.095574971 7:0.039634146 +-1 1:0.762712 3:0.101695 4:0.0073800738 7:0.022633317 +-1 1:0.759494 3:0.050633 7:0.015282494 +-1 1:0.72973 2:0.027027 3:0.054054 6:0.036144036 7:0.013678311 +-1 1:0.769231 2:0.051282 6:0.034092034 7:0.013758598 +-1 1:0.787879 7:0.011640799 8:0.023809524 +-1 1:0.733333 3:0.07619 4:0.0036900369 7:0.019802555 8:0.047619048 +-1 1:0.73913 3:0.026087 7:0.014793213 +-1 1:0.916667 7:0.019308945 +-1 1:0.647059 2:0.058824 3:0.147059 4:0.0036900369 5:0.13805108 7:0.019368726 +-1 1:0.694444 2:0.027778 3:0.111111 4:0.0073800738 5:0.078466745 7:0.016090787 +-1 1:0.709924 2:0.007634 3:0.122137 4:0.018450185 5:0.01745859 7:0.019875256 8:0.047619048 +-1 1:0.366667 2:0.3 3:0.083333 5:0.34143396 6:0.20610621 7:0.013313006 +-1 1:0.731707 3:0.121951 4:0.011070111 7:0.018590122 8:0.023809524 +-1 1:0.796296 3:0.037037 4:0.0036900369 7:0.021228549 8:0.023809524 +-1 1:0.684211 3:0.210526 7:0.01893453 +-1 1:0.712121 2:0.030303 3:0.075758 5:0.038622098 7:0.017830744 8:0.023809524 +-1 1:0.722222 2:0.083333 6:0.081081081 7:0.012533878 +-1 1:0.746835 2:0.037975 3:0.031646 5:0.064541619 7:0.017829579 +-1 1:0.644444 3:0.066667 7:0.012601628 8:0.047619048 +-1 1:0.788462 7:0.012546902 8:0.071428571 +-1 1:0.8 3:0.066667 7:0.028963415 +-1 1:0.783333 2:0.005556 3:0.013889 5:0.016638588 7:0.015176152 8:0.047619048 +-1 1:0.738462 3:0.015385 7:0.013227018 8:0.095238095 +-1 1:0.744444 3:0.055556 4:0.0073800738 7:0.012601628 8:0.023809524 +-1 1:0.694444 2:0.046296 3:0.018519 4:0.0036900369 6:0.051501052 7:0.013154927 8:0.023809524 +-1 1:0.73913 3:0.130435 7:0.018292683 +-1 1:0.72 2:0.02 3:0.06 5:0.05605087 7:0.016219512 8:0.023809524 +-1 1:0.751553 3:0.068323 4:0.029520295 7:0.01761097 8:0.023809524 +-1 1:0.652482 2:0.042553 3:0.120567 6:0.031578032 7:0.01643314 +-1 1:0.794872 2:0.025641 3:0.051282 5:0.045457934 7:0.025641024 +-1 1:0.514286 2:0.142857 3:0.228571 4:0.0073800738 5:0.24643299 7:0.02108014 +-1 1:0.79 3:0.01 7:0.014420732 +-1 1:0.583333 2:0.145833 3:0.083333 4:0.0073800738 5:0.45375934 7:0.014608738 +-1 1:0.659091 3:0.136364 7:0.019124171 8:0.023809524 +-1 1:0.636364 2:0.121212 3:0.030303 6:0.1046521 7:0.015890616 +-1 1:0.8 7:0.013133207 8:0.047619048 +-1 1:0.69697 3:0.121212 7:0.015890616 8:0.047619048 +-1 1:0.795455 7:0.014966738 8:0.071428571 +-1 1:0.715953 2:0.015564 3:0.070039 4:0.0036900369 7:0.013689854 +-1 1:0.604317 2:0.143885 3:0.079137 4:0.014760148 6:0.092199092 7:0.018555884 +-1 1:0.85 7:0.01402439 +-1 1:0.831776 7:0.019147482 +-1 1:0.826667 7:0.016585366 8:0.047619048 +-1 1:0.671875 2:0.03125 3:0.078125 5:0.038227006 7:0.018578506 +-1 1:0.73494 3:0.060241 4:0.0036900369 7:0.012342049 +-1 1:0.708333 3:0.125 7:0.014481707 8:0.023809524 +-1 1:0.592593 2:0.098765 3:0.160494 4:0.029520295 5:0.1183263 6:0.035715036 7:0.018970189 +-1 1:0.754386 3:0.017544 7:0.014334616 8:0.023809524 +-1 1:0.769231 2:0.010989 3:0.021978 6:0.0066240066 7:0.015176896 +-1 1:0.696078 3:0.127451 4:0.018450185 7:0.016021043 +-1 1:0.650794 2:0.111111 3:0.047619 6:0.11029511 7:0.013162988 +-1 1:0.5 2:0.194444 3:0.055556 5:0.22936949 6:0.18461418 7:0.011009488 8:0.023809524 +-1 1:0.833333 7:0.014481707 8:0.023809524 +-1 1:0.807692 3:0.019231 7:0.014540335 8:0.023809524 +-1 1:0.708661 2:0.047244 3:0.007874 6:0.044943045 7:0.01281928 8:0.047619048 +-1 1:0.756757 2:0.027027 3:0.040541 5:0.078056744 7:0.015738299 +-1 1:0.806452 3:0.010753 4:0.0036900369 7:0.014358774 8:0.023809524 +-1 1:0.716763 2:0.092486 3:0.040462 5:0.10962682 6:0.016044016 7:0.026364018 +-1 1:0.783333 7:0.014532518 8:0.095238095 +-1 1:0.714286 2:0.035714 3:0.071429 5:0.08471367 7:0.019163762 8:0.023809524 +-1 1:0.820513 7:0.013445902 +-1 1:0.833333 7:0.012533878 +-1 1:0.752381 3:0.047619 7:0.012833915 8:0.047619048 +-1 1:0.8 7:0.012682927 +-1 1:0.714286 7:0.015098726 +-1 1:0.733333 3:0.013333 7:0.013170732 +-1 1:0.857143 7:0.013501744 +-1 1:0.807692 7:0.01242964 +-1 1:0.678571 2:0.035714 3:0.071429 7:0.011977354 8:0.023809524 +-1 1:0.6875 2:0.0625 3:0.166667 6:0.012072012 7:0.063135165 +-1 1:0.809524 7:0.01422764 +-1 1:0.785714 7:0.011904762 +-1 1:0.697674 2:0.011628 3:0.093023 4:0.011070111 7:0.014960293 8:0.047619048 +-1 1:0.650602 2:0.120482 3:0.036145 5:0.30740387 6:0.015465015 7:0.014252128 +-1 1:0.761905 7:0.0098722439 8:0.047619048 +-1 1:0.730769 7:0.0092636037 8:0.023809524 +-1 1:0.8 7:0.012398372 +-1 1:0.8125 3:0.0625 7:0.018292683 +-1 1:0.827586 7:0.013036165 +-1 1:0.770992 3:0.045802 7:0.015593 8:0.095238095 +-1 1:0.846154 7:0.012664165 +-1 1:0.818182 7:0.011917957 +-1 1:0.786885 7:0.011695323 8:0.047619048 +-1 1:0.793651 7:0.012291909 +-1 1:0.725275 3:0.043956 7:0.011391049 +-1 1:0.666667 3:0.166667 4:0.0073800738 7:0.013211384 +-1 1:0.732394 3:0.084507 7:0.016231537 +-1 1:0.758621 3:0.034483 7:0.010513037 8:0.047619048 +-1 1:0.76 3:0.08 7:0.013902439 +-1 1:0.715596 2:0.009174 3:0.110092 4:0.0036900369 7:0.019243677 +-1 1:0.75 3:0.0625 7:0.013528963 +-1 1:1 7:0.051829268 +-1 1:0.680851 2:0.053191 3:0.042553 4:0.011070111 5:0.12742832 7:0.015179037 8:0.095238095 +-1 1:0.790419 3:0.005988 7:0.014385866 +-1 1:0.805556 3:0.055556 4:0.0036900369 7:0.020663957 +-1 1:0.761194 2:0.029851 3:0.029851 5:0.08471367 7:0.016017476 +-1 1:0.614618 2:0.122924 3:0.076412 4:0.040590406 5:0.0082298391 6:0.072849073 7:0.018353457 +-1 1:0.73224 2:0.021858 3:0.081967 4:0.014760148 5:0.035670091 7:0.02089164 8:0.023809524 +-1 1:0.736842 2:0.052632 3:0.052632 5:0.15861077 7:0.015083439 +-1 1:0.727273 3:0.090909 7:0.013488543 +-1 1:0.823529 2:0.058824 5:0.15213275 7:0.017575323 +-1 1:0.772727 3:0.090909 4:0.0073800738 7:0.01926275 +-1 1:0.777778 3:0.166667 7:0.037601628 +-1 1:0.83871 7:0.014358774 +-1 1:0.788991 2:0.036697 3:0.018349 5:0.049766672 6:0.004005004 7:0.020949878 +-1 1:0.712121 2:0.045455 3:0.045455 4:0.0036900369 6:0.041097041 7:0.013488543 8:0.023809524 +-1 1:0.747253 3:0.087912 4:0.0073800738 7:0.018828732 8:0.023809524 +-1 1:0.904762 7:0.027293848 +-1 1:0.756757 3:0.040541 7:0.013513512 8:0.023809524 +-1 1:0.607143 2:0.035714 3:0.107143 4:0.0073800738 5:0.071675637 7:0.022648085 8:0.023809524 +-1 1:0.761905 3:0.031746 7:0.013356561 8:0.047619048 +-1 1:0.772727 2:0.015152 5:0.059636515 7:0.011548409 +-1 1:0.842105 7:0.013799744 +-1 1:0.814815 7:0.012420957 8:0.047619048 +-1 1:0.833333 7:0.014566396 8:0.023809524 +-1 1:0.825688 7:0.01812486 8:0.11904762 +-1 1:0.75 7:0.01410061 8:0.023809524 +-1 1:0.726496 3:0.059829 4:0.0036900369 7:0.015739006 8:0.047619048 +-1 1:0.695187 2:0.016043 3:0.090909 5:0.034037541 7:0.014281988 8:0.071428571 +-1 1:0.672131 2:0.016393 3:0.114754 7:0.014394244 8:0.023809524 +-1 1:0.756098 3:0.04878 7:0.015169543 8:0.023809524 +-1 1:0.740741 7:0.013550134 +-1 1:0.8 7:0.011498256 +-1 1:0.629032 2:0.016129 3:0.129032 7:0.031766323 +-1 1:0.882353 7:0.021879482 +-1 1:0.8 7:0.01097561 +-1 1:0.759259 3:0.037037 4:0.0036900369 7:0.011969287 +-1 1:0.74026 3:0.051948 7:0.014491604 8:0.023809524 +-1 1:0.726496 3:0.025641 7:0.011778195 8:0.095238095 +-1 1:0.777778 3:0.022222 7:0.013550134 +-1 1:0.733333 3:0.1 7:0.016666665 +-1 1:0.75 7:0.0081300793 8:0.023809524 +-1 1:0.803922 7:0.021281683 +-1 1:0.774648 3:0.035211 4:0.011070111 7:0.018335622 8:0.071428571 +-1 1:0.758621 3:0.034483 4:0.0036900369 7:0.019764506 8:0.047619048 +-1 1:0.833333 7:0.012195122 8:0.023809524 +-1 1:0.777778 7:0.0094850976 8:0.047619048 +-1 1:0.791667 7:0.010670732 +-1 1:0.828571 7:0.016289201 8:0.023809524 +-1 1:0.7 7:0.014329268 8:0.023809524 +-1 1:0.689655 2:0.103448 3:0.034483 5:0.15213275 6:0.01020301 7:0.020605549 8:0.023809524 +-1 1:0.818182 3:0.018182 7:0.016629713 +-1 1:0.811765 7:0.015853659 8:0.047619048 +-1 1:0.733333 3:0.066667 7:0.01117886 +-1 1:0.612903 2:0.16129 5:0.29523057 7:0.01986625 +-1 1:0.666667 2:0.043478 3:0.101449 5:0.086182219 7:0.015288085 +-1 1:0.816667 2:0.05 5:0.091281141 7:0.024898372 +-1 1:0.8 7:0.014430896 8:0.023809524 +-1 1:0.789474 7:0.010269579 +-1 1:0.875 7:0.016768293 +-1 1:0.72973 3:0.108108 7:0.020270268 +-1 1:0.764706 3:0.039216 7:0.014945 8:0.023809524 +-1 1:0.700787 3:0.07874 7:0.015363933 +-1 1:0.823529 7:0.012195122 8:0.023809524 +-1 1:0.85 7:0.017835366 +-1 1:0.696078 2:0.039216 3:0.04902 5:0.06186543 7:0.014406982 8:0.047619048 +-1 1:0.722222 3:0.111111 4:0.0036900369 7:0.013211384 +-1 1:0.790698 3:0.046512 4:0.0073800738 7:0.035450933 +-1 1:0.75 2:0.083333 3:0.083333 7:0.024390244 +-1 1:0.633333 2:0.088889 3:0.111111 4:0.011070111 6:0.068181068 7:0.017886177 +-1 1:0.793478 7:0.012857902 8:0.071428571 +-1 1:0.8 7:0.011991872 +-1 1:0.636364 2:0.045455 3:0.181818 4:0.0036900369 5:0.10074098 7:0.020509976 8:0.023809524 +-1 1:1 7:0.054878049 +-1 1:0.6875 2:0.046875 3:0.0625 4:0.0036900369 5:0.081031115 7:0.017530488 +-1 1:0.685185 3:0.055556 7:0.01163053 8:0.047619048 +-1 1:0.785714 3:0.047619 7:0.015389079 +-1 1:0.721311 3:0.032787 7:0.011495402 8:0.023809524 +-1 1:0.722973 2:0.027027 3:0.047297 5:0.042118289 7:0.014584707 +-1 1:0.837838 7:0.015655902 +-1 1:0.769841 3:0.02381 7:0.01359853 8:0.071428571 +-1 1:0.7 2:0.042857 3:0.028571 5:0.11557557 7:0.011236933 +-1 1:0.725664 3:0.088496 4:0.0036900369 7:0.01678178 8:0.023809524 +-1 1:0.772727 7:0.015659646 +-1 1:0.704478 2:0.080597 3:0.041791 5:0.072443457 6:0.034986035 7:0.018729524 8:0.023809524 +-1 1:0.791045 3:0.014925 7:0.013651256 8:0.023809524 +-1 1:0.69697 3:0.060606 7:0.016444939 +-1 1:0.761905 3:0.015873 7:0.010646537 +-1 1:0.82243 7:0.014189652 8:0.023809524 +-1 1:0.726872 2:0.022026 3:0.070485 5:0.012486395 6:0.015075015 7:0.016036317 +-1 1:0.807692 7:0.012781427 8:0.023809524 +-1 1:0.827586 3:0.068966 7:0.022497896 +-1 1:0.761194 3:0.044776 4:0.0036900369 7:0.014197305 8:0.023809524 +-1 1:1 7:0.042682927 +-1 1:0.675258 2:0.128866 4:0.0073800738 6:0.12605113 7:0.014961024 8:0.023809524 +-1 1:0.836735 3:0.040816 7:0.022648085 +-1 1:0.846154 7:0.012195122 +-1 1:0.675325 3:0.155844 7:0.019401329 +-1 1:0.630769 2:0.061538 6:0.081819082 7:0.010318951 8:0.023809524 +-1 1:0.647059 2:0.029412 5:0.13078288 7:0.010222384 8:0.023809524 +-1 1:0.75 3:0.05 7:0.013567073 8:0.023809524 +-1 1:0.727273 2:0.022727 5:0.082827665 7:0.012472287 8:0.023809524 +-1 1:0.855072 2:0.014493 5:0.028782073 7:0.022887945 +-1 1:0.806452 2:0.096774 5:0.048409941 6:0.058443058 7:0.03029111 +-1 1:0.984615 7:0.17335835 +-1 1:0.706897 3:0.051724 7:0.009777122 +-1 1:0.75 2:0.035714 3:0.053571 5:0.094359877 7:0.017203835 +-1 1:0.719444 2:0.002778 3:0.094444 6:0.0028230028 7:0.018004744 8:0.047619048 +-1 1:0.684211 3:0.052632 7:0.010269579 +-1 1:0.642857 2:0.02381 3:0.142857 4:0.0036900369 5:0.067158171 7:0.016114982 8:0.047619048 +-1 1:0.607383 2:0.057047 3:0.191275 5:0.052040314 7:0.023449012 +-1 1:0.607843 2:0.078431 3:0.156863 5:0.14713074 6:0.039474039 7:0.018173122 +-1 1:0.572581 2:0.241935 3:0.056452 4:0.040590406 5:0.017600227 6:0.081465081 7:0.041650274 +-1 1:0.691589 2:0.009346 3:0.093458 4:0.0036900369 5:0.022251875 7:0.019090494 +-1 1:0.75 3:0.010204 7:0.01169736 8:0.023809524 +-1 1:0.732143 7:0.010561848 +-1 1:0.713793 2:0.034483 3:0.055172 4:0.0036900369 5:0.046784846 7:0.020100927 8:0.023809524 +-1 1:0.712644 2:0.034483 3:0.045977 6:0.032610033 7:0.012895994 8:0.047619048 +-1 1:0.72028 3:0.048951 7:0.019870372 +-1 1:0.761905 3:0.040816 4:0.0036900369 7:0.015223165 +-1 1:0.743902 7:0.011674598 8:0.047619048 +-1 1:0.802083 3:0.010417 7:0.013528963 +-1 1:0.791667 3:0.010417 7:0.013719512 +-1 1:0.826923 7:0.015478421 8:0.023809524 +-1 1:0.794872 3:0.038462 7:0.017745463 +-1 1:0.823529 3:0.019608 7:0.015423244 +-1 1:0.62963 3:0.148148 7:0.019196024 +-1 1:0.802083 7:0.012766768 +-1 1:0.793103 7:0.012931037 8:0.047619048 +-1 1:0.75 3:0.15625 4:0.014760148 7:0.029153963 +-1 1:0.75 3:0.038462 4:0.0036900369 7:0.013015945 8:0.047619048 +-1 1:0.75 2:0.026042 3:0.03125 6:0.016452016 7:0.017371695 8:0.023809524 +-1 1:0.688525 3:0.163934 4:0.0036900369 7:0.021391445 8:0.023809524 +-1 1:0.795918 3:0.040816 7:0.015928323 8:0.047619048 +-1 1:0.795699 3:0.021505 7:0.014686598 8:0.047619048 +-1 1:0.724638 3:0.028986 7:0.013167195 +-1 1:0.686275 2:0.117647 6:0.11320811 7:0.01267336 8:0.023809524 +-1 1:0.76259 3:0.093525 4:0.04797048 7:0.031979293 +-1 1:0.745098 2:0.019608 3:0.058824 4:0.0036900369 5:0.05734051 7:0.015542805 +-1 1:0.8 3:0.1 7:0.020426829 +-1 1:0.823529 7:0.011836439 +-1 1:0.76652 2:0.004405 3:0.008811 5:0.015863313 7:0.012624909 +-1 1:0.722689 3:0.092437 4:0.022140221 7:0.015781921 +-1 1:0.735294 3:0.073529 4:0.033210332 7:0.016006098 +-1 1:0.731707 3:0.097561 4:0.0036900369 7:0.017697799 +-1 1:0.863636 7:0.019678494 +-1 1:0.735294 7:0.014705884 8:0.047619048 +-1 1:0.851852 3:0.074074 7:0.029584463 +-1 1:0.770642 7:0.014208994 8:0.023809524 +-1 1:0.818182 2:0.006494 3:0.038961 5:0.010496027 7:0.028112134 8:0.023809524 +-1 1:0.788732 7:0.013655104 +-1 1:0.698113 2:0.037736 3:0.09434 4:0.011070111 5:0.042595381 7:0.020133457 +-1 1:0.990826 7:1 +-1 1:0.54902 2:0.019608 3:0.156863 5:0.0642658 7:0.013868963 +-1 1:0.727273 2:0.018182 3:0.036364 7:0.013414634 +-1 1:0.8 3:0.025 7:0.014176829 +-1 1:0.75 7:0.013836774 +-1 1:0.444444 2:0.416667 3:0.027778 4:0.014760148 5:0.14713074 6:0.17763318 7:0.025745256 +-1 1:0.811024 7:0.016132128 +-1 1:0.8 3:0.15 7:0.043292683 +-1 1:0.967742 7:0.052124317 +-1 1:0.777778 3:0.066667 4:0.0073800738 7:0.021544713 8:0.047619048 +-1 1:0.76259 2:0.014388 3:0.021583 7:0.014432354 +-1 1:0.770833 3:0.083333 4:0.0073800738 7:0.019944104 +-1 1:0.761905 2:0.095238 5:0.13805108 6:0.055557056 7:0.015679445 +-1 1:0.734694 3:0.040816 7:0.012319561 +-1 1:0.725 2:0.042857 3:0.007143 5:0.011614211 6:0.032709033 7:0.013980835 +-1 1:0.764706 2:0.058824 3:0.058824 7:0.018651366 +-1 1:0.741071 2:0.017857 3:0.008929 5:0.066561806 7:0.012195122 8:0.023809524 +-1 1:0.466667 2:0.133333 3:0.133333 5:0.13311616 7:0.022764226 +-1 1:0.52 2:0.2 3:0.08 5:0.061105065 6:0.049179049 7:0.029756098 +-1 1:0.768116 3:0.028986 7:0.016083421 +-1 1:0.769231 7:0.020168854 +-1 1:0.756522 2:0.008696 3:0.026087 5:0.012046576 6:0.0048480048 7:0.01641039 8:0.047619048 +-1 1:0.769231 7:0.011882427 8:0.023809524 +-1 1:0.8 7:0.011463415 +-1 1:0.778409 3:0.011364 7:0.014758872 8:0.047619048 +-1 1:0.833333 7:0.012195122 +-1 1:0.833333 7:0.01575203 8:0.023809524 +-1 1:0.6875 2:0.109375 3:0.0625 4:0.025830258 6:0.076923077 7:0.022294207 +-1 1:0.75 3:0.1875 7:0.025152439 +-1 1:0.75 3:0.083333 4:0.0073800738 7:0.018419713 +-1 1:0.69697 2:0.121212 3:0.090909 5:0.093182055 7:0.029563933 +-1 1:0.694915 2:0.016949 3:0.152542 7:0.024390244 8:0.023809524 +-1 1:0.766839 2:0.025907 3:0.031088 5:0.025531883 6:0.01027501 7:0.018450652 8:0.047619048 +-1 1:0.666667 7:0.0091463415 +-1 1:0.621951 2:0.182927 6:0.17875518 7:0.014351573 +-1 1:0.740741 3:0.111111 7:0.021002707 +-1 1:0.804878 7:0.015392622 8:0.071428571 +-1 1:0.754717 3:0.122642 4:0.011070111 7:0.028186841 +-1 1:0.754386 2:0.04386 3:0.052632 5:0.051891223 7:0.023053061 +-1 1:0.953488 7:0.050907543 +-1 1:0.846154 7:0.012195122 +-1 1:0.827586 7:0.013246427 +-1 1:0.65625 2:0.1 3:0.03125 5:0.20759471 6:0.015189015 7:0.015053354 +-1 1:0.787037 3:0.037037 7:0.017332878 +-1 1:0.72956 2:0.031447 3:0.037736 4:0.0036900369 5:0.050713402 6:0.0068040068 7:0.016912104 +-1 1:0.78169 2:0.007042 5:0.024443517 7:0.013096872 8:0.047619048 +-1 1:0.821429 3:0.142857 4:0.0036900369 7:0.045296165 +-1 1:0.754717 3:0.037736 7:0.019328116 +-1 1:0.711268 3:0.049296 7:0.012281006 8:0.047619048 +-1 1:0.661017 2:0.033898 3:0.033898 7:0.022323274 8:0.023809524 +-1 1:0.454545 2:0.318182 3:0.045455 5:0.31721408 6:0.19149019 7:0.01302661 +-1 1:0.661458 2:0.088542 3:0.052083 4:0.0036900369 5:0.067158171 6:0.047298047 7:0.01410061 +-1 1:0.863636 7:0.016906872 +-1 1:0.588235 2:0.088235 3:0.088235 5:0.082827665 6:0.033333033 7:0.016140604 +-1 1:0.826087 3:0.173913 4:0.011070111 7:0.073170732 +-1 1:0.655172 2:0.068966 3:0.155172 4:0.0036900369 5:0.092794418 7:0.025336415 +-1 1:0.694444 2:0.194444 5:0.1972105 6:0.031746032 7:0.032012195 +-1 1:0.770492 3:0.032787 7:0.013994402 8:0.047619048 +-1 1:0.9 7:0.034146341 +-1 1:0.625 7:0.026676829 +-1 1:0.928571 3:0.035714 7:0.054878049 +-1 1:0.846154 7:0.013133207 +-1 1:0.75 3:0.018519 7:0.014171183 8:0.095238095 +-1 1:0.666667 2:0.074074 4:0.0073800738 6:0.091371091 7:0.011122402 8:0.047619048 +-1 1:0.634146 2:0.097561 3:0.109756 4:0.0036900369 5:0.095984972 6:0.038628039 7:0.017325994 +-1 1:0.75 2:0.027778 3:0.111111 5:0.054813412 7:0.023035232 +-1 1:0.752475 3:0.039604 4:0.0036900369 7:0.012859213 +-1 1:0.928571 7:0.044860628 +-1 1:1 7:0.042682927 +-1 1:0.743056 3:0.118056 4:0.044280443 7:0.025745256 +-1 1:0.607843 2:0.176471 3:0.039216 6:0.11059811 7:0.025944524 +-1 1:0.68 2:0.1 3:0.05 4:0.0073800738 6:0.077778078 7:0.016463415 8:0.047619048 +-1 1:0.833333 7:0.02811653 +-1 1:0.795918 3:0.081633 7:0.02252364 +-1 1:0.666667 2:0.047619 3:0.142857 5:0.12023467 7:0.018002323 +-1 1:0.686275 2:0.009804 3:0.117647 4:0.0036900369 5:0.030928988 7:0.014406982 8:0.047619048 +-1 1:0.73913 3:0.043478 4:0.0036900369 7:0.025715799 +-1 1:0.764706 2:0.016807 3:0.05042 4:0.0073800738 5:0.019083685 6:0.0051180051 7:0.020017762 +-1 1:0.677966 2:0.101695 3:0.067797 5:0.15370566 6:0.015465015 7:0.02004961 +-1 1:0.875 7:0.076219512 +-1 1:0.807692 7:0.011491555 +-1 1:0.78 7:0.027113823 8:0.071428571 +-1 1:0.77931 3:0.048276 7:0.0205635 8:0.071428571 +-1 1:0.833333 7:0.017445799 +-1 1:0.721893 2:0.04142 3:0.059172 5:0.080680751 7:0.016669073 8:0.047619048 +-1 1:0.666667 2:0.055556 3:0.092593 5:0.10573554 7:0.015921409 +-1 1:0.793103 2:0.022989 3:0.022989 5:0.025971702 7:0.020114945 8:0.047619048 +-1 1:0.866667 7:0.01422764 +-1 1:0.769231 3:0.192308 7:0.056519701 +-1 1:0.666667 2:0.087719 3:0.070175 5:0.22761767 7:0.014013695 +-1 1:0.637681 2:0.057971 3:0.072464 5:0.14244182 7:0.013874159 +-1 1:0.625 3:0.125 7:0.026676829 +-1 1:0.759036 3:0.036145 7:0.013590951 +-1 1:0.697674 2:0.139535 3:0.023256 5:0.35781909 7:0.01772547 +-1 1:0.789474 3:0.157895 4:0.0036900369 7:0.030166884 +-1 1:0.736364 2:0.009091 3:0.036364 4:0.0036900369 5:0.029467893 7:0.01402439 +-1 1:0.781022 2:0.029197 3:0.014599 6:0.024456024 7:0.016378848 +-1 1:0.734043 2:0.010638 3:0.053191 7:0.016087183 8:0.023809524 +-1 1:1 7:0.039634146 +-1 1:0.777778 2:0.011696 3:0.005848 5:0.042595381 7:0.01248039 8:0.11904762 +-1 1:0.634146 2:0.04878 3:0.073171 5:0.085682764 7:0.012938726 8:0.071428571 +-1 1:0.822695 7:0.015697976 8:0.023809524 +-1 1:0.7603 2:0.003745 3:0.048689 5:0.0099667526 6:0.004011004 7:0.017082305 +-1 1:0.789116 2:0.013605 3:0.013605 5:0.019165685 7:0.016135726 +-1 1:0.916667 7:0.021341463 +-1 1:0.846154 7:0.021106945 8:0.023809524 +-1 1:0.732143 2:0.017857 3:0.053571 5:0.043594293 7:0.018619335 +-1 1:0.73913 2:0.130435 5:0.2631014 7:0.022534463 +-1 1:0.789474 2:0.052632 3:0.052632 5:0.10212008 7:0.02342747 +-1 1:0.807018 3:0.017544 7:0.026208811 +-1 1:0.712963 3:0.111111 4:0.014760148 7:0.019139567 8:0.023809524 +-1 1:0.781818 2:0.018182 3:0.090909 4:0.011070111 5:0.029818258 7:0.027716189 8:0.023809524 +-1 1:0.670034 2:0.063973 3:0.063973 5:0.12127831 6:0.0032550033 7:0.018929128 +-1 1:0.722222 3:0.138889 7:0.022527098 +-1 1:0.75 7:0.022103659 8:0.023809524 +-1 1:1 7:0.13414634 +-1 1:0.9375 4:0.014760148 7:0.024390244 +-1 1:0.723577 2:0.02439 3:0.073171 5:0.057198873 7:0.019383305 8:0.047619048 +-1 1:0.76087 7:0.011863732 +-1 1:0.737705 2:0.016393 3:0.057377 4:0.018450185 5:0.04809685 7:0.015493805 +-1 1:0.705882 7:0.017575323 +-1 1:0.794872 3:0.025641 4:0.0036900369 7:0.01360225 +-1 1:0.68932 2:0.067961 3:0.087379 5:0.016564042 6:0.033333033 7:0.026639829 +-1 1:0.809524 3:0.031746 7:0.019647695 +-1 1:0.670886 2:0.063291 3:0.101266 6:0.017391017 7:0.026628591 +-1 1:0.819635 3:0.002283 7:0.016009579 +-1 1:0.828571 7:0.01393728 +-1 1:0.72093 3:0.162791 4:0.011070111 7:0.023255811 +-1 1:0.631579 2:0.210526 3:0.052632 4:0.011070111 6:0.15789616 7:0.018292683 +-1 1:0.755556 2:0.033333 3:0.022222 5:0.013656762 6:0.021978022 7:0.018495933 8:0.047619048 +-1 1:0.791667 3:0.010417 7:0.014291159 +-1 1:0.777778 3:0.088889 7:0.033197835 +-1 1:0.882353 7:0.018830701 +-1 1:0.875 7:0.016006098 +-1 1:0.733333 2:0.133333 3:0.066667 5:0.26623231 7:0.022764226 +-1 1:0.916667 7:0.019308945 +-1 1:0.783133 7:0.015133707 +-1 1:0.875 7:0.016768293 +-1 1:0.576923 2:0.192308 3:0.115385 4:0.0036900369 5:0.094359877 6:0.15189915 7:0.018527201 +-1 1:0.8 3:0.133333 7:0.022764226 +-1 1:0.760736 2:0.006135 3:0.04908 4:0.0073800738 5:0.016824952 7:0.016571896 +-1 1:0.820513 2:0.025641 3:0.025641 5:0.060605609 7:0.019230768 +-1 1:0.8125 7:0.013465445 +-1 1:0.803922 7:0.01649928 8:0.023809524 +-1 1:0.742424 3:0.030303 7:0.016629713 8:0.047619048 +-1 1:0.706897 3:0.086207 4:0.011070111 7:0.018923463 8:0.023809524 +-1 1:0.72 3:0.12 4:0.0073800738 7:0.017317073 +-1 1:0.783333 3:0.05 7:0.018597561 +-1 1:0.78125 7:0.011242378 8:0.023809524 +-1 1:0.7 2:0.04 3:0.02 5:0.10649591 7:0.012804878 8:0.023809524 +-1 1:0.769231 7:0.011315665 8:0.071428571 +-1 1:0.791667 3:0.022727 7:0.015659646 8:0.023809524 +-1 1:0.733333 3:0.133333 4:0.018450185 7:0.020325201 +-1 1:0.682692 2:0.038462 3:0.067308 5:0.07308455 7:0.011960598 +-1 1:0.794326 7:0.013665457 8:0.095238095 +-1 1:0.8 7:0.023257841 8:0.023809524 +-1 1:0.77551 7:0.012195122 8:0.095238095 +-1 1:0.84375 7:0.017244665 8:0.023809524 +-1 1:0.650602 2:0.048193 3:0.096386 4:0.025830258 5:0.09165387 7:0.01792536 8:0.071428571 +-1 1:0.714634 2:0.056098 3:0.046341 4:0.014760148 5:0.091624051 6:0.010536011 7:0.016939323 8:0.023809524 +-1 1:0.814286 2:0.007143 3:0.010714 5:0.016862225 7:0.019250872 8:0.095238095 +-1 1:0.758772 3:0.02193 7:0.013452073 8:0.071428571 +-1 1:0.758772 3:0.02193 7:0.013532305 8:0.071428571 +-1 1:0.792453 7:0.012080073 8:0.047619048 +-1 1:0.762887 3:0.020619 7:0.012446567 8:0.023809524 +-1 1:0.666667 3:0.142857 4:0.0036900369 7:0.01393728 8:0.023809524 +-1 1:0.767857 3:0.035714 7:0.017421604 8:0.071428571 +-1 1:0.806452 7:0.01573564 8:0.023809524 +-1 1:0.772321 3:0.03125 4:0.0036900369 7:0.016550524 8:0.047619048 +-1 1:0.756098 2:0.012195 3:0.060976 4:0.011070111 7:0.015169543 +-1 1:0.666667 2:0.047619 3:0.047619 7:0.020615561 +-1 1:0.74 7:0.012926829 +-1 1:0.692308 2:0.192308 3:0.038462 5:0.016243496 6:0.065358065 7:0.053822701 +-1 1:0.80137 3:0.027397 7:0.017415634 +-1 1:0.778626 3:0.038168 4:0.0073800738 7:0.016105006 +-1 1:0.747899 3:0.042017 4:0.0073800738 7:0.021059646 +-1 1:0.736842 7:0.019897305 +-1 1:0.729412 2:0.058824 3:0.047059 5:0.16205478 7:0.01649928 +-1 1:0.684211 2:0.052632 7:0.019897305 +-1 1:0.928571 7:0.021341463 +-1 1:0.753425 2:0.054795 3:0.027397 5:0.13492762 7:0.018459738 +-1 1:0.714286 3:0.142857 4:0.0036900369 7:0.013501744 +-1 1:0.76 7:0.015853659 +-1 1:0.846154 7:0.012195122 +-1 1:0.8125 3:0.0625 7:0.041031506 8:0.023809524 +-1 1:0.75 7:0.01328397 8:0.023809524 +-1 1:0.646707 2:0.149701 3:0.02994 6:0.084210084 7:0.020812037 8:0.023809524 +-1 1:0.831461 7:0.016990957 +-1 1:0.928571 7:0.045731707 +-1 1:0.844444 7:0.016531165 8:0.047619048 +-1 1:0.761194 3:0.134328 4:0.025830258 7:0.037586457 +-1 1:0.678571 2:0.017857 3:0.160714 4:0.0036900369 7:0.02275697 +-1 1:0.666667 3:0.111111 7:0.027439024 +-1 1:0.709677 2:0.012903 3:0.032258 4:0.0036900369 5:0.020999508 7:0.013965384 +-1 1:0.789474 7:0.011713738 +-1 1:0.822581 4:0.011070111 7:0.014358774 8:0.023809524 +-1 1:0.677419 2:0.032258 3:0.080645 4:0.0073800738 6:0.02013302 7:0.014653817 +-1 1:0.988889 7:0.15345528 +-1 1:0.72 3:0.14 7:0.023414634 +-1 1:0.777778 3:0.079365 7:0.019938055 +-1 1:0.62963 2:0.08642 3:0.08642 4:0.0036900369 5:0.11959358 6:0.048129048 7:0.014077085 8:0.047619048 +-1 1:0.833333 3:0.166667 7:0.057926829 +-1 1:0.814815 3:0.037037 7:0.016711835 +-1 1:0.75 3:0.060811 7:0.015655902 8:0.071428571 +-1 1:0.782609 2:0.043478 5:0.1461691 7:0.013520677 +-1 1:0.765217 3:0.078261 7:0.01956522 +-1 1:0.78882 2:0.006211 3:0.024845 5:0.017495863 7:0.016133921 +-1 1:0.727273 2:0.025253 3:0.065657 6:0.014469014 7:0.019154963 8:0.023809524 +-1 1:0.761905 7:0.013356561 +-1 1:0.990566 4:0.10701107 7:0.24246435 +-1 1:0.708861 7:0.012117939 +-1 1:0.745946 2:0.027027 3:0.045946 4:0.011070111 5:0.026314612 6:0.0026490026 7:0.01867172 +-1 1:1 7:0.10060976 +-1 1:0.733333 2:0.022222 3:0.044444 7:0.011924122 +-1 1:0.712644 2:0.028736 3:0.086207 5:0.023481878 6:0.0047250047 7:0.022252591 8:0.023809524 +-1 1:0.846154 7:0.014071293 +-1 1:0.826087 7:0.012990457 +-1 1:0.588608 2:0.221519 3:0.044304 4:0.036900369 5:0.070661816 6:0.12796213 7:0.024428835 +-1 1:0.8 2:0.066667 3:0.066667 7:0.023170732 +-1 1:0.821429 7:0.013501744 +-1 1:0.922481 7:0.042186616 +-1 1:0.922481 7:0.042186616 +-1 1:0.692308 3:0.153846 4:0.0036900369 7:0.012664165 +-1 1:0.642857 7:0.014372823 +-1 1:0.813953 7:0.016165628 +-1 1:0.746988 4:0.014760148 7:0.013811341 8:0.095238095 +-1 1:0.757576 3:0.040404 7:0.02673072 +-1 1:0.666667 3:0.166667 4:0.0073800738 7:0.014905146 +-1 1:0.767442 3:0.007752 7:0.014936659 +-1 1:0.71875 2:0.010417 3:0.052083 4:0.0036900369 5:0.02934862 7:0.016133128 +-1 1:0.771739 3:0.065217 7:0.018955463 +-1 1:0.743119 2:0.027523 3:0.073394 5:0.047478121 7:0.017565451 +-1 1:0.60177 2:0.19469 3:0.044248 5:0.022184784 6:0.15178515 7:0.018130799 +-1 1:0.764706 3:0.235294 4:0.0073800738 7:0.054878049 +-1 1:0.770297 2:0.021782 3:0.025743 5:0.031450807 6:0.0036180036 7:0.020031396 8:0.047619048 +-1 1:0.705882 2:0.058824 3:0.058824 5:0.20147451 7:0.013271165 +-1 1:0.714286 7:0.016840884 +-1 1:0.752475 2:0.009901 3:0.039604 7:0.014851488 +-1 1:0.736842 7:0.01363928 +-1 1:0.711111 3:0.022222 7:0.013685634 8:0.023809524 +-1 1:0.538462 2:0.128205 3:0.025641 5:0.10962682 6:0.088236088 7:0.010631646 +-1 1:0.674419 2:0.023256 3:0.093023 4:0.0073800738 7:0.013329555 8:0.023809524 +-1 1:0.59375 2:0.15625 3:0.0625 4:0.0036900369 5:0.108039 6:0.13043413 7:0.013147866 +-1 1:0.763636 2:0.018182 3:0.036364 5:0.05237577 7:0.01577975 +-1 1:0.823529 7:0.011477762 +-1 1:0.75 3:0.166667 4:0.0073800738 7:0.034552848 +-1 1:0.774194 2:0.032258 3:0.032258 5:0.10074098 7:0.01455547 +-1 1:0.784897 2:0.009153 3:0.016018 5:0.027082433 7:0.015362506 +-1 1:0.826923 3:0.019231 7:0.016885555 8:0.023809524 +-1 1:0.517241 2:0.068966 3:0.206897 4:0.011070111 5:0.14335873 7:0.010933555 +-1 1:0.84375 7:0.015815549 +-1 1:0.644231 2:0.048077 3:0.048077 5:0.20822835 7:0.010494841 8:0.11904762 +-1 1:0.713636 2:0.045455 3:0.027273 4:0.0036900369 5:0.015893131 6:0.012792013 7:0.01299889 8:0.047619048 +-1 1:0.733333 3:0.08 4:0.011070111 7:0.017317073 +-1 1:0.882353 7:0.018651366 +-1 1:0.773333 3:0.013333 7:0.012276421 +-1 1:0.767442 3:0.046512 7:0.014747591 +-1 1:0.567568 2:0.162162 3:0.099099 5:0.20216033 6:0.11186411 7:0.016205232 +-1 1:0.807692 2:0.038462 3:0.019231 5:0.085436763 7:0.020462006 +-1 1:0.777778 7:0.012420957 8:0.071428571 +-1 1:0.658824 2:0.035294 3:0.082353 4:0.0073800738 5:0.071332727 6:0.028707029 7:0.014992823 8:0.047619048 +-1 1:0.80597 2:0.029851 3:0.014925 6:0.029127029 7:0.018747726 +-1 1:0.732558 3:0.093023 7:0.015243902 +-1 1:0.790323 3:0.064516 7:0.031766323 +-1 1:0.701493 2:0.044776 3:0.104478 4:0.011070111 6:0.028845029 7:0.018929744 +-1 1:0.78 2:0.02 3:0.02 5:0.06160452 7:0.014756098 +-1 1:0.6 2:0.14 3:0.14 4:0.0036900369 5:0.20803453 7:0.026219512 +-1 1:0.744 3:0.056 7:0.015121951 8:0.023809524 +-1 1:0.780488 3:0.073171 7:0.024985128 +-1 1:0.806452 7:0.011605037 +-1 1:0.77095 2:0.027933 3:0.022346 5:0.077654198 7:0.016351 +-1 1:0.730769 3:0.134615 7:0.019699811 +-1 1:0.608696 2:0.173913 3:0.043478 5:0.42195816 7:0.014050902 +-1 1:0.767313 2:0.01662 3:0.019391 4:0.0036900369 5:0.049535581 7:0.015252348 8:0.023809524 +-1 1:0.709677 2:0.053763 3:0.064516 5:0.10425954 7:0.01875164 8:0.023809524 +-1 1:0.760274 2:0.006849 3:0.027397 4:0.0036900369 5:0.022863149 7:0.013615104 8:0.11904762 +-1 1:0.571429 2:0.071429 3:0.119048 5:0.29818258 7:0.0108885 8:0.023809524 +-1 1:0.705882 7:0.01649928 +-1 1:0.8125 7:0.01410061 8:0.023809524 +-1 1:0.709677 2:0.016129 3:0.048387 5:0.054813412 7:0.013375293 +-1 1:0.727273 3:0.018182 7:0.012195122 +-1 1:0.682836 2:0.093284 3:0.037313 5:0.076066375 6:0.045918046 7:0.01783764 +-1 1:0.785047 7:0.012195122 8:0.023809524 +-1 1:0.772152 3:0.075949 4:0.0036900369 7:0.020685396 +-1 1:0.805755 3:0.05036 7:0.02131953 +-1 1:0.809524 7:0.015679445 8:0.023809524 +-1 1:0.795918 3:0.081633 7:0.025385762 +-1 1:0.783673 2:0.040816 3:0.008163 5:0.10499754 7:0.017670482 +-1 1:0.748299 2:0.020408 3:0.040816 5:0.021059145 7:0.014683921 +-1 1:0.795699 7:0.014621037 +-1 1:0.837209 7:0.01545661 +-1 1:0.75641 2:0.025641 3:0.051282 5:0.030928988 7:0.018839902 +-1 1:0.782609 3:0.086957 7:0.017762457 +-1 1:0.538462 2:0.153846 5:0.17336335 7:0.020168854 +-1 1:0.763636 3:0.036364 7:0.013192902 8:0.023809524 +-1 1:0.781711 2:0.011799 3:0.014749 5:0.0085131126 7:0.01575653 +-1 1:0.79 7:0.013231707 +-1 1:0.725 3:0.066667 4:0.0073800738 7:0.014176829 8:0.023809524 +-1 1:0.796875 4:0.0073800738 7:0.012480945 8:0.023809524 +-1 1:0.730337 2:0.044944 3:0.022472 4:0.0036900369 5:0.074918373 6:0.015075015 7:0.013633872 +-1 1:0.696296 2:0.103704 3:0.02963 5:0.17517481 6:0.031332031 7:0.017299006 +-1 1:0.696078 2:0.083333 3:0.02451 4:0.0036900369 5:0.027663889 6:0.072357072 7:0.016110713 8:0.023809524 +-1 1:0.710843 3:0.048193 4:0.0073800738 7:0.013076695 8:0.023809524 +-1 1:1 7:0.094512195 +-1 1:0.879121 2:0.010989 3:0.010989 7:0.10720987 8:0.023809524 +-1 1:0.756098 3:0.085366 4:0.0073800738 7:0.01970553 8:0.023809524 +-1 1:0.785714 3:0.014286 7:0.014982579 8:0.023809524 +-1 1:0.634615 2:0.147436 3:0.038462 5:0.067158171 6:0.081081081 7:0.021693244 +-1 1:0.754098 2:0.032787 3:0.04918 4:0.0036900369 5:0.036542275 7:0.020391841 8:0.023809524 +-1 1:0.721569 3:0.105882 7:0.026972744 +-1 1:1 7:0.091463415 +-1 1:0.821429 7:0.013501744 +-1 1:0.75 7:0.011263549 8:0.095238095 +-1 1:0.746988 3:0.072289 4:0.011070111 7:0.015354098 8:0.023809524 +-1 1:0.752525 2:0.010101 3:0.090909 4:0.022140221 5:0.01856932 7:0.024728994 8:0.023809524 +-1 1:0.784431 3:0.011976 4:0.0036900369 7:0.0147875 8:0.047619048 +-1 1:0.705882 2:0.044118 3:0.029412 5:0.15530094 7:0.012912482 8:0.023809524 +-1 1:0.5 2:0.25 3:0.166667 4:0.0036900369 5:0.15530094 6:0.062499062 7:0.024390244 +-1 1:0.807692 3:0.076923 4:0.025830258 7:0.024859287 +-1 1:0.693333 2:0.026667 3:0.04 6:0.028302028 7:0.017235774 +-1 1:0.692308 7:0.0084427744 +-1 1:0.666667 3:0.095238 4:0.0036900369 7:0.011614402 8:0.023809524 +-1 1:0.673469 3:0.061224 7:0.01630164 +-1 1:0.78125 3:0.052083 7:0.018356201 +-1 1:0.808511 2:0.042553 5:0.099391708 7:0.019460299 +-1 1:0.923077 3:0.076923 7:0.042682927 +-1 1:0.698413 2:0.063492 3:0.087302 5:0.059397969 6:0.005976006 7:0.024293457 +-1 1:0.76129 3:0.058065 7:0.014988201 +-1 1:0.675676 2:0.054054 3:0.027027 5:0.14065272 7:0.017468689 8:0.023809524 +-1 1:0.824561 3:0.078947 7:0.032306372 +-1 1:0.75 3:0.071429 7:0.016986061 +-1 1:0.884615 7:0.018292683 +-1 1:0.714286 3:0.142857 4:0.011070111 7:0.017131244 +-1 1:0.615385 2:0.057692 3:0.115385 5:0.062640705 7:0.01395403 +-1 1:0.790323 3:0.016129 7:0.01308025 8:0.023809524 +-1 1:0.747899 3:0.092437 7:0.027720841 +-1 1:0.671642 2:0.044776 3:0.119403 4:0.011070111 6:0.030768031 7:0.017746634 +-1 1:0.694444 2:0.083333 3:0.055556 5:0.1183263 7:0.021341463 +-1 1:0.746269 3:0.134328 7:0.029122677 +-1 1:0.758621 3:0.137931 7:0.024810762 +-1 1:0.777778 2:0.010101 3:0.020202 5:0.03080226 7:0.014905146 +-1 1:0.88 3:0.04 7:0.027804878 +-1 1:0.704403 2:0.006289 3:0.125786 4:0.0073800738 7:0.021552384 +-1 1:0.658537 2:0.02439 3:0.097561 5:0.070326361 7:0.015764427 +-1 1:0.707317 2:0.03252 3:0.065041 4:0.0036900369 6:0.022059022 7:0.013484037 +-1 1:0.76 3:0.06 4:0.0073800738 7:0.015 8:0.023809524 +-1 1:0.711111 3:0.133333 4:0.0036900369 7:0.016937671 +-1 1:0.730337 2:0.044944 3:0.011236 6:0.018072018 7:0.034118939 +-1 1:0.712871 2:0.029703 3:0.069307 4:0.011070111 5:0.041298287 7:0.02179425 +-1 1:0.693878 2:0.061224 3:0.081633 4:0.0073800738 5:0.10649591 6:0.021429021 7:0.017421604 +-1 1:0.6875 2:0.058036 3:0.098214 4:0.022140221 5:0.085250399 7:0.021423128 +-1 1:0.775 3:0.025 7:0.011890244 +-1 1:0.744681 3:0.053191 7:0.015568238 8:0.047619048 +-1 1:0.742424 2:0.015152 3:0.075758 7:0.01607539 8:0.023809524 +-1 1:0.647059 3:0.058824 7:0.01040172 8:0.023809524 +-1 1:0.816327 7:0.01393728 8:0.023809524 +-1 1:0.736842 7:0.018078732 8:0.023809524 +-1 1:0.679775 3:0.101124 4:0.011070111 7:0.020142506 8:0.023809524 +-1 1:0.797753 3:0.022472 7:0.020622085 +-1 1:0.686869 3:0.030303 7:0.030610988 +-1 1:0.916667 7:0.018292683 +-1 1:0.658537 2:0.170732 3:0.02439 5:0.44984569 7:0.017251634 +-1 1:0.645161 2:0.064516 3:0.064516 5:0.08874659 6:0.035715036 7:0.016522421 +-1 1:0.666667 2:0.066667 3:0.133333 5:0.16565533 7:0.018292683 +-1 1:0.666667 2:0.037037 3:0.148148 4:0.011070111 5:0.092034052 7:0.018292683 +-1 1:0.842105 2:0.052632 3:0.026316 5:0.038033188 6:0.030612031 7:0.031450579 +-1 1:0.731707 3:0.097561 4:0.0036900369 7:0.07450922 +-1 1:0.985075 7:0.16845649 +-1 1:1 4:0.05904059 7:0.097560976 +-1 1:0.567568 2:0.009009 3:0.045045 7:0.028620085 +-1 1:0.798354 2:0.020576 3:0.032922 5:0.045398297 7:0.020601226 +-1 1:0.888889 7:0.021341463 +-1 1:0.722892 2:0.048193 3:0.072289 4:0.0073800738 6:0.021201021 7:0.020790482 +-1 1:1 4:0.036900369 7:0.054878049 +-1 1:0.769231 2:0.153846 4:0.014760148 5:0.2923382 7:0.023921201 +-1 1:0.838462 4:0.040590406 7:0.023405256 8:0.047619048 +-1 1:0.748344 3:0.059603 4:0.018450185 7:0.020755939 8:0.071428571 +-1 1:0.655502 2:0.066986 3:0.07177 4:0.0073800738 5:0.066084714 6:0.03989404 7:0.016454665 8:0.071428571 +-1 1:0.926829 4:0.062730627 7:0.060380726 +-1 1:0.719008 2:0.016529 3:0.057851 4:0.0036900369 7:0.016831287 +-1 1:0.729592 3:0.056122 7:0.02093703 8:0.023809524 +-1 1:0.689655 3:0.103448 7:0.013456689 8:0.023809524 +-1 1:0.702128 3:0.042553 7:0.012973537 +-1 1:0.730769 3:0.192308 4:0.036900369 7:0.042448402 +-1 1:0.743902 2:0.012195 3:0.097561 4:0.022140221 5:0.02823789 7:0.019631171 +-1 1:0.823529 3:0.058824 4:0.0036900369 7:0.018651366 8:0.023809524 +-1 1:0.671233 2:0.027397 3:0.164384 4:0.025830258 7:0.023220848 +-1 1:0.857143 3:0.095238 4:0.0036900369 7:0.033101043 +-1 1:0.772727 2:0.019481 3:0.032468 4:0.0036900369 5:0.030302804 7:0.019480518 8:0.023809524 +-1 1:0.710526 3:0.157895 4:0.0036900369 7:0.046373555 +-1 1:0.744681 2:0.042553 3:0.06383 5:0.11043937 7:0.017514268 +-1 1:0.717391 2:0.043478 3:0.043478 4:0.0036900369 6:0.061224061 7:0.012990457 +-1 1:0.712329 2:0.018265 3:0.077626 4:0.0036900369 6:0.018108018 7:0.013837841 +-1 1:0.755102 2:0.020408 3:0.071429 4:0.0073800738 6:0.0098670099 7:0.018914884 +-1 1:0.659341 2:0.043956 3:0.065934 6:0.039474039 7:0.015277409 +-1 1:0.731707 3:0.073171 7:0.013087451 +-1 1:0.73913 2:0.043478 3:0.043478 4:0.0036900369 7:0.013255567 +-1 1:0.853659 4:0.0036900369 7:0.017251634 +-1 1:0.747126 2:0.034483 3:0.057471 5:0.095984972 7:0.01633025 +-1 1:0.73913 4:0.0036900369 7:0.018822909 +-1 1:0.809524 3:0.047619 4:0.0036900369 7:0.01480836 +-1 1:0.666667 3:0.111111 7:0.010162604 +-1 1:0.643836 2:0.041096 3:0.136986 4:0.0073800738 6:0.032085032 7:0.01561978 +-1 1:0.663551 2:0.046729 3:0.093458 5:0.031189898 6:0.037656038 7:0.013619787 +-1 1:0.870968 4:0.011070111 7:0.02025964 8:0.023809524 +-1 1:0.844444 3:0.066667 4:0.025830258 7:0.076964768 +-1 1:0.865385 4:0.022140221 7:0.019113506 8:0.023809524 +-1 1:0.685714 2:0.014286 3:0.071429 5:0.048409941 7:0.013414634 +-1 1:0.764706 3:0.235294 4:0.014760148 7:0.054878049 +-1 1:0.66 2:0.07 3:0.11 4:0.025830258 5:0.13977308 7:0.019512195 8:0.023809524 +-1 1:0.669643 2:0.116071 3:0.035714 4:0.011070111 5:0.024048425 6:0.067743068 7:0.016877177 +-1 1:0.844156 4:0.073800738 7:0.016392146 +-1 1:0.756757 3:0.054054 4:0.014760148 7:0.022907055 8:0.023809524 +-1 1:0.748718 3:0.015385 4:0.0073800738 7:0.012726701 8:0.023809524 +-1 1:0.621622 2:0.081081 3:0.108108 4:0.014760148 5:0.24046934 7:0.015326305 8:0.047619048 +-1 1:0.731707 3:0.121951 4:0.018450185 7:0.04045211 +-1 1:0.666667 2:0.111111 3:0.111111 4:0.011070111 5:0.05734051 6:0.023076023 7:0.02201897 +-1 1:1 4:0.051660517 7:0.06097561 +-1 1:0.825397 2:0.003968 3:0.015873 4:0.018450185 7:0.019768683 8:0.023809524 +-1 1:0.631579 2:0.157895 3:0.105263 4:0.014760148 5:0.2366526 7:0.020218226 +-1 1:0.791667 3:0.041667 4:0.018450185 7:0.017403457 8:0.023809524 +-1 1:0.714286 3:0.035714 4:0.025830258 7:0.022865854 +-1 1:0.714286 7:0.0071864085 +-1 1:1 4:0.04797048 7:0.057926829 +-1 1:1 4:0.10332103 7:0.13414634 +-1 1:0.810345 4:0.051660517 7:0.019133726 +-1 1:0.736842 2:0.052632 3:0.105263 4:0.029520295 7:0.02342747 +-1 1:0.77193 2:0.017544 4:0.033210332 7:0.016046213 8:0.047619048 +-1 1:0.878049 4:0.033210332 7:0.02379536 +-1 1:0.878788 3:0.030303 4:0.040590406 7:0.028824835 +-1 1:0.9 2:0.05 3:0.05 4:0.05904059 5:0.035498636 7:0.06402439 +-1 1:0.836364 2:0.018182 4:0.062730627 7:0.032372506 8:0.023809524 +-1 1:0.946429 4:0.13653137 7:0.10137195 +-1 1:1 4:0.084870849 7:0.082317073 +-1 1:0.684211 7:0.0062580244 +-1 1:0.947368 4:0.12546125 7:0.089644848 +-1 1:0.897959 3:0.081633 4:0.14760148 7:0.075161768 +-1 1:0.670423 2:0.002817 5:0.020090051 7:0.006372378 +-1 1:0.680851 7:0.0064867683 +-1 1:0.848485 3:0.090909 4:0.14391144 7:0.095898006 8:0.023809524 +-1 1:0.764706 2:0.039216 3:0.039216 4:0.077490775 5:0.058928332 7:0.030248683 +-1 1:0.84874 3:0.02521 4:0.10332103 7:0.053494567 +-1 1:0.910714 4:0.073800738 7:0.065004354 +-1 1:0.875 4:0.05904059 7:0.031758128 +-1 1:0.941176 3:0.029412 4:0.1697417 7:0.1510043 +-1 1:0.659722 2:0.125 3:0.0625 4:0.092250923 5:0.098571705 6:0.03966904 7:0.025618226 +-1 1:0.804878 3:0.073171 4:0.055350554 7:0.028851872 8:0.023809524 +-1 1:0.851064 4:0.040590406 7:0.045666841 8:0.095238095 +-1 1:0.741935 3:0.048387 4:0.036900369 7:0.033536585 8:0.023809524 +-1 1:0.614286 2:0.171429 3:0.071429 4:0.011070111 6:0.11785812 7:0.024390244 +-1 1:0.888889 3:0.055556 4:0.033210332 7:0.031504067 +-1 1:0.741935 2:0.032258 3:0.032258 4:0.033210332 7:0.019669549 8:0.023809524 +-1 1:1 4:0.036900369 7:0.051829268 +-1 1:0.692308 2:0.076923 3:0.076923 4:0.036900369 7:0.026891805 +-1 1:1 4:0.051660517 7:0.06097561 +-1 1:0.790323 3:0.048387 4:0.029520295 7:0.019079463 +-1 1:0.723404 2:0.12766 3:0.06383 4:0.029520295 5:0.059010332 6:0.023748024 7:0.049169689 +-1 1:0.7 2:0.0125 3:0.05 4:0.029520295 7:0.014405488 +-1 1:0.78 3:0.02 4:0.029520295 7:0.018292683 +-1 1:0.772727 2:0.136364 4:0.022140221 6:0.10843511 7:0.023004433 +-1 1:0.779412 2:0.014706 3:0.058824 4:0.029520295 5:0.031450807 7:0.021251793 +-1 1:0.741935 2:0.096774 4:0.022140221 5:0.081918209 6:0.032967033 7:0.017899293 +-1 1:0.735294 2:0.029412 3:0.117647 4:0.025830258 7:0.029232421 +-1 1:0.76 3:0.057143 4:0.033210332 7:0.01578397 +-1 1:0.88 4:0.025830258 7:0.02097561 +-1 1:0.801724 3:0.051724 4:0.025830258 7:0.020237591 +-1 1:0.682464 2:0.104265 3:0.028436 4:0.025830258 5:0.12042849 6:0.038772039 7:0.017888104 +-1 1:0.896552 4:0.022140221 7:0.022287634 8:0.023809524 +-1 1:0.956522 4:0.022140221 7:0.03605514 +-1 1:1 4:0.044280443 7:0.067073171 +-1 1:1 4:0.044280443 7:0.054878049 +-1 1:1 4:0.044280443 7:0.06402439 +-1 1:0.739726 2:0.123288 4:0.044280443 6:0.073620074 7:0.027230207 +-1 1:0.844444 4:0.018450185 7:0.017479677 8:0.023809524 +-1 1:0.875 4:0.022140221 7:0.021036585 +-1 1:0.8 3:0.1 4:0.022140221 7:0.024085366 +-1 1:0.652174 3:0.173913 4:0.018450185 7:0.015641567 +-1 1:0.766667 3:0.066667 4:0.022140221 7:0.016260165 +-1 1:0.733333 2:0.026667 3:0.066667 4:0.014760148 5:0.03516318 7:0.017235774 8:0.023809524 +-1 1:0.84 4:0.018450185 7:0.016829268 +-1 1:0.764706 2:0.029412 3:0.029412 4:0.018450185 7:0.01488522 +-1 1:0.714286 2:0.128571 3:0.028571 4:0.0036900369 6:0.076641077 7:0.023867598 +-1 1:0.711864 3:0.101695 4:0.022140221 7:0.020152957 8:0.047619048 +-1 1:0.9 4:0.029520295 7:0.020426829 +-1 1:0.833333 3:0.02381 4:0.018450185 7:0.020470384 +-1 1:0.660377 2:0.150943 3:0.018868 6:0.15789616 7:0.015301427 8:0.023809524 +-1 1:0.762887 3:0.041237 4:0.029520295 7:0.017381189 +-1 1:0.655172 2:0.137931 3:0.068966 4:0.014760148 6:0.063831064 7:0.019764506 +-1 1:0.684211 3:0.105263 4:0.044280443 7:0.021074024 +-1 1:0.785714 2:0.004762 4:0.044280443 5:0.0084534761 7:0.025609756 8:0.023809524 +-1 1:0.818182 4:0.018450185 7:0.014781963 +-1 1:0.777372 3:0.051095 4:0.055350554 7:0.017914366 +-1 1:0.663717 2:0.064897 3:0.115044 4:0.040590406 6:0.014124014 7:0.038204189 +-1 1:0.638037 2:0.104294 3:0.110429 4:0.014760148 5:0.038622098 6:0.051813052 7:0.021659433 +-1 1:0.8 4:0.018450185 7:0.012979098 8:0.071428571 +-1 1:0.623377 2:0.051948 3:0.090909 4:0.014760148 5:0.049699581 7:0.011878366 +-1 1:0.830769 3:0.015385 4:0.011070111 7:0.02120075 +-1 1:0.717391 4:0.018450185 7:0.023064689 +-1 1:0.714286 2:0.119048 3:0.071429 4:0.018450185 6:0.047619048 7:0.027439024 +-1 1:0.732394 2:0.014085 3:0.084507 4:0.029520295 5:0.034350633 7:0.018636207 +-1 1:0.852941 3:0.029412 4:0.018450185 7:0.022776183 8:0.023809524 +-1 1:0.88 3:0.12 4:0.014760148 7:0.079268293 +-1 1:0.891892 4:0.040590406 7:0.024719841 +-1 1:0.769231 3:0.153846 4:0.022140221 7:0.020168854 +-1 1:0.809524 4:0.014760148 7:0.013501744 8:0.047619048 +-1 1:0.723881 2:0.007463 3:0.037313 4:0.011070111 7:0.013150707 8:0.047619048 +-1 1:0.745902 2:0.016393 3:0.045082 4:0.014760148 5:0.033180266 6:0.0044520045 7:0.016843262 8:0.023809524 +-1 1:0.798077 3:0.009615 4:0.011070111 7:0.014716226 +-1 1:0.703704 2:0.037037 3:0.074074 4:0.011070111 7:0.013324299 +-1 1:0.804348 2:0.021739 4:0.011070111 6:0.024999025 7:0.015906683 +-1 1:0.777778 3:0.083333 4:0.014760148 7:0.019139567 +-1 1:0.72973 3:0.108108 4:0.011070111 7:0.015655902 +-1 1:0.788462 3:0.019231 4:0.011070111 7:0.01325047 8:0.047619048 +-1 1:0.751773 2:0.007092 3:0.042553 4:0.014760148 7:0.013405982 +-1 1:0.75 2:0.083333 4:0.011070111 6:0.055557056 7:0.013719512 +-1 1:0.85 4:0.011070111 7:0.014329268 +-1 1:0.714286 2:0.071429 3:0.071429 4:0.011070111 7:0.01480836 +-1 1:0.679487 2:0.076923 3:0.064103 4:0.014760148 6:0.043479043 7:0.016181988 +-1 1:0.691176 2:0.058824 3:0.073529 4:0.014760148 5:0.040962832 6:0.032967033 7:0.016319945 +-1 1:0.724138 3:0.086207 4:0.018450185 7:0.01650547 8:0.047619048 +-1 1:0.757282 3:0.048544 4:0.011070111 7:0.016635091 +-1 1:0.794118 3:0.058824 4:0.011070111 7:0.016678622 +-1 1:0.760714 2:0.021429 3:0.05 4:0.0073800738 5:0.026910978 7:0.018096689 +-1 1:0.685185 2:0.055556 3:0.101852 6:0.047922048 7:0.017671634 +-1 1:0.819672 4:0.011070111 7:0.016393439 +-1 1:0.663462 2:0.076923 3:0.086538 4:0.022140221 5:0.055424687 6:0.044610045 7:0.015771579 +-1 1:0.85 4:0.011070111 7:0.018292683 +-1 1:0.725 3:0.083333 4:0.011070111 7:0.01722561 8:0.071428571 +-1 1:0.679389 2:0.076336 3:0.061069 4:0.011070111 5:0.12355941 7:0.01684975 +-1 1:0.780488 3:0.097561 4:0.011070111 7:0.023349195 +-1 1:0.857143 4:0.011070111 7:0.015098726 8:0.023809524 +-1 1:0.693878 2:0.081633 3:0.061224 4:0.011070111 6:0.045114045 7:0.016550524 8:0.023809524 +-1 1:0.846154 3:0.025641 4:0.011070111 7:0.020637896 +-1 1:0.758621 3:0.068966 4:0.014760148 7:0.014297732 +-1 1:0.7375 3:0.075 4:0.025830258 7:0.016310976 8:0.047619048 +-1 1:0.647059 2:0.088235 3:0.117647 4:0.014760148 5:0.15213275 7:0.017575323 +-1 1:0.736842 2:0.105263 3:0.105263 4:0.0036900369 5:0.081918209 6:0.032967033 7:0.02920411 +-1 1:0.764706 3:0.176471 4:0.018450185 7:0.02618364 +-1 1:0.706897 2:0.103448 3:0.103448 4:0.014760148 5:0.04176047 6:0.042018042 7:0.037531537 8:0.023809524 +-1 1:0.926829 4:0.05904059 7:0.056811421 +-1 1:0.827586 2:0.034483 3:0.103448 4:0.040590406 5:0.02720916 7:0.057611439 +-1 1:1 4:0.10332103 7:0.1554878 +-1 1:0.88 4:0.011070111 7:0.020731707 +-1 1:0.631579 2:0.236842 3:0.105263 4:0.0073800738 5:0.039129009 6:0.031497031 7:0.061136073 +-1 1:0.659574 2:0.106383 3:0.021277 5:0.07308455 6:0.11764812 7:0.013233006 8:0.047619048 +-1 1:0.80303 4:0.0073800738 7:0.017368811 +-1 1:0.758621 3:0.068966 4:0.022140221 7:0.01471825 8:0.023809524 +-1 1:0.75 3:0.045455 4:0.011070111 7:0.01759978 8:0.023809524 +-1 1:0.736842 4:0.0073800738 7:0.019576378 +-1 1:0.811966 4:0.0036900369 7:0.014383988 +-1 1:0.785714 3:0.014286 4:0.0036900369 7:0.012456445 +-1 1:0.692308 2:0.102564 3:0.076923 4:0.0036900369 6:0.061224061 7:0.022983116 +-1 1:0.820513 4:0.0036900369 7:0.019699811 +-1 1:0.755102 3:0.020408 4:0.0036900369 7:0.01319064 +-1 1:0.774775 2:0.009009 3:0.013514 4:0.0036900369 5:0.029997167 7:0.013650848 8:0.071428571 +-1 1:0.694915 2:0.016949 3:0.084746 4:0.0036900369 7:0.012608518 +-1 1:0.711538 2:0.057692 3:0.028846 6:0.024897025 7:0.014129927 8:0.023809524 +-1 1:0.790698 3:0.023256 4:0.0036900369 7:0.012762335 8:0.023809524 +-1 1:0.730769 3:0.096154 4:0.0073800738 7:0.016064726 8:0.023809524 +-1 1:0.7 2:0.04 3:0.05 4:0.0073800738 5:0.052129769 6:0.013986014 7:0.013079268 +-1 1:0.770492 3:0.016393 4:0.0036900369 7:0.011895244 8:0.023809524 +-1 1:0.747126 3:0.034483 4:0.0036900369 7:0.016049902 +-1 1:0.815789 4:0.0036900369 7:0.01283697 +-1 1:0.739496 3:0.092437 4:0.018450185 7:0.017729043 8:0.023809524 +-1 1:0.822917 3:0.041667 4:0.0036900369 7:0.025152439 +-1 1:0.653333 2:0.044444 3:0.115556 4:0.073800738 5:0.023042059 6:0.027822028 7:0.017533878 +-1 1:0.75 2:0.1 5:0.33131066 7:0.013719512 +-1 1:0.673077 3:0.019231 4:0.0036900369 7:0.015361165 +-1 1:0.5625 2:0.25 5:0.77115978 6:0.1034491 7:0.011051829 +-1 1:0.833333 3:0.041667 4:0.0073800738 7:0.02527947 +-1 1:0.789474 3:0.026316 4:0.0036900369 7:0.012516049 +-1 1:0.75 3:0.15 4:0.0073800738 7:0.025 +-1 1:0.727273 3:0.060606 4:0.0073800738 7:0.012102732 8:0.023809524 +-1 1:0.769231 2:0.019231 6:0.025425025 7:0.013836774 8:0.047619048 +-1 1:0.726829 2:0.014634 3:0.092683 4:0.029520295 5:0.020619325 7:0.021505055 8:0.023809524 +-1 1:0.5625 2:0.125 3:0.125 5:0.074545644 6:0.09000009 7:0.01270325 +-1 1:0.823529 4:0.0036900369 7:0.011477762 +-1 1:0.809524 4:0.0036900369 7:0.013356561 +-1 1:0.741935 3:0.096774 4:0.0036900369 7:0.016325726 +-1 1:0.791667 3:0.083333 4:0.0073800738 7:0.024644311 +-1 1:0.806818 3:0.045455 4:0.0036900369 7:0.020579268 +-1 1:0.733333 2:0.022222 3:0.044444 4:0.0073800738 6:0.011538012 7:0.017615177 +-1 1:0.79661 4:0.0036900369 7:0.012918561 8:0.023809524 +-1 1:0.688889 2:0.044444 3:0.066667 5:0.043087382 7:0.023441738 8:0.023809524 +-1 1:0.785714 3:0.071429 4:0.0036900369 7:0.013501744 +-1 1:0.677419 2:0.091398 3:0.091398 4:0.014760148 5:0.009258569 6:0.044721045 7:0.026389982 +-1 1:0.866667 4:0.0036900369 7:0.01422764 +-1 1:0.771536 3:0.026217 4:0.025830258 7:0.014318994 8:0.023809524 +-1 1:0.944444 4:0.0036900369 7:0.034214091 +-1 1:0.809091 4:0.0036900369 7:0.014190689 +-1 1:0.76699 3:0.043689 4:0.0036900369 7:0.015362305 +-1 1:0.79085 3:0.013072 4:0.014760148 7:0.015861628 +-1 1:0.8 2:0.033333 3:0.016667 4:0.0036900369 6:0.016128016 7:0.018902439 +-1 1:0.6 2:0.1 3:0.1 5:0.12424523 6:0.05000105 7:0.012195122 +-1 1:0.707317 2:0.00813 3:0.138211 4:0.0036900369 7:0.022109854 +-1 1:0.825688 4:0.0036900369 7:0.016950104 8:0.047619048 +-1 1:0.789474 3:0.052632 4:0.0036900369 7:0.013157896 +-1 1:0.806452 3:0.032258 4:0.0036900369 7:0.014162079 +-1 1:0.762763 3:0.048048 4:0.0036900369 7:0.015875634 +-1 1:0.74375 2:0.01875 3:0.06875 4:0.0036900369 6:0.013824014 7:0.016539634 +-1 1:0.763889 3:0.041667 4:0.0036900369 7:0.01388889 8:0.023809524 +-1 1:0.826087 4:0.0036900369 7:0.014581122 +-1 1:0.724138 2:0.011494 3:0.068966 4:0.0073800738 7:0.01422764 8:0.023809524 +-1 1:0.75 2:0.052632 6:0.053571054 7:0.013478817 8:0.023809524 +-1 1:0.781609 2:0.007663 3:0.022989 4:0.0036900369 5:0.021088963 7:0.016517146 8:0.023809524 +-1 1:0.732394 3:0.070423 4:0.011070111 7:0.022243213 8:0.023809524 +-1 1:0.733333 3:0.066667 4:0.0036900369 7:0.011788616 8:0.023809524 +-1 1:0.772727 3:0.090909 4:0.0073800738 7:0.017184037 8:0.023809524 +-1 1:0.777778 3:0.055556 4:0.0036900369 7:0.013211384 8:0.023809524 +-1 1:0.693603 2:0.060606 3:0.026936 4:0.0036900369 6:0.061224061 7:0.013077933 8:0.023809524 +-1 1:0.55814 2:0.139535 3:0.139535 4:0.0036900369 5:0.061105065 6:0.049179049 7:0.017300055 +-1 1:0.683824 2:0.022059 3:0.088235 4:0.0036900369 5:0.039233373 7:0.017037305 8:0.023809524 +-1 1:0.617886 2:0.134146 3:0.036585 5:0.014618401 6:0.13529414 7:0.012641287 +-1 1:0.820513 3:0.025641 4:0.0036900369 7:0.016103817 8:0.023809524 +-1 1:0.729412 2:0.011765 3:0.070588 4:0.0036900369 7:0.013845049 8:0.023809524 +-1 1:0.77027 7:0.01293672 +-1 1:0.647059 3:0.117647 4:0.0073800738 7:0.0093256829 8:0.023809524 +-1 1:0.646465 2:0.030303 3:0.080808 4:0.0073800738 7:0.013426951 8:0.047619048 +-1 1:0.792453 4:0.0036900369 7:0.013230555 8:0.023809524 +-1 1:0.8 3:0.025 7:0.018445122 +-1 1:0.79397 3:0.005025 7:0.013788457 +-1 1:0.774194 3:0.064516 4:0.0073800738 7:0.016522421 8:0.047619048 +-1 1:0.723404 2:0.049645 3:0.070922 4:0.036900369 5:0.052495043 6:0.021126021 7:0.018422421 +-1 1:0.833333 3:0.025641 4:0.014760148 7:0.021185116 +-1 1:1 7:0.048780488 +-1 1:0.789474 3:0.210526 4:0.018450185 7:0.06097561 +-1 1:0.718543 2:0.056291 6:0.052299052 7:0.012740268 8:0.047619048 +-1 1:0.769231 2:0.019231 3:0.032051 5:0.034119541 6:0.0068640069 7:0.017080988 8:0.023809524 +-1 1:0.666667 7:0.019308945 +-1 1:0.8125 7:0.019817073 +-1 1:0.745098 3:0.068627 7:0.015303683 8:0.047619048 +-1 1:0.747768 3:0.006696 7:0.013869232 8:0.095238095 +-1 1:0.769231 2:0.015385 3:0.038462 4:0.0036900369 5:0.03774246 6:0.0075960076 7:0.018527201 8:0.071428571 +-1 1:0.560976 2:0.268293 3:0.073171 5:0.032129173 6:0.1034491 7:0.034503268 +-1 1:0.512821 2:0.128205 3:0.064103 5:0.090356775 6:0.036363036 7:0.012898689 8:0.023809524 +-1 1:0.666667 2:0.055556 3:0.074074 5:0.061105065 7:0.027551939 +-1 1:0.711207 3:0.12931 4:0.022140221 7:0.01834525 8:0.023809524 +-1 1:0.909091 2:0.036364 5:0.0062245613 6:0.005013005 7:0.1327051 +-1 1:0.77686 2:0.024793 3:0.024793 6:0.015831016 7:0.01909897 8:0.023809524 +-1 1:0.636364 2:0.030303 3:0.171717 4:0.018450185 5:0.05467923 7:0.025190933 8:0.023809524 +-1 1:0.732394 2:0.021127 3:0.049296 5:0.037839369 7:0.016918585 8:0.047619048 +-1 1:0.75 3:0.047619 7:0.016840884 8:0.023809524 +-1 1:0.828829 3:0.027027 7:0.022083061 +-1 1:0.763636 3:0.030303 7:0.014745012 8:0.047619048 +-1 1:0.691057 2:0.113821 3:0.00813 5:0.016601315 6:0.073497073 7:0.022258579 8:0.047619048 +-1 1:0.85 7:0.014634146 +-1 1:0.532468 2:0.207792 3:0.038961 5:0.59297333 7:0.01393728 +-1 1:0.705882 3:0.091503 4:0.014760148 7:0.018252829 +-1 1:0.6 2:0.28 3:0.04 5:0.19617432 6:0.10526411 7:0.027804878 +-1 1:0.728261 2:0.01087 3:0.086957 5:0.027507343 7:0.017961293 +-1 1:0.772727 7:0.0094235061 +-1 1:0.711111 2:0.044444 3:0.044444 5:0.16751897 7:0.012059622 +-1 1:0.8 7:0.012195122 +-1 1:0.646341 2:0.036585 3:0.170732 5:0.05869724 7:0.028331348 +-1 1:0.75 2:0.055556 3:0.027778 6:0.024195024 7:0.021002707 +-1 1:0.732558 2:0.011628 3:0.046512 7:0.014605787 +-1 1:0.75 3:0.083333 4:0.0036900369 7:0.013973579 +-1 1:0.734286 2:0.045714 3:0.025714 5:0.050884857 6:0.013653014 7:0.015313591 +-1 1:0.707792 2:0.045455 3:0.084416 4:0.0036900369 5:0.044995751 7:0.019678494 +-1 1:0.646154 2:0.046154 3:0.169231 4:0.0073800738 5:0.05734051 7:0.024390244 +-1 1:0.659341 3:0.10989 7:0.014138299 +-1 1:0.734375 2:0.03125 3:0.03125 5:0.10353645 7:0.013719512 +-1 1:0.728261 3:0.021739 7:0.011399787 8:0.023809524 +-1 1:0.723577 2:0.04065 3:0.02439 6:0.047619048 7:0.012492561 +-1 1:0.761388 3:0.041215 7:0.015858951 8:0.023809524 +-1 1:0.730769 2:0.038462 3:0.076923 7:0.015478421 +-1 1:0.734177 3:0.151899 4:0.011070111 7:0.030950909 +-1 1:0.916667 7:0.019308945 +-1 1:0.695652 2:0.086957 3:0.086957 7:0.018822909 +-1 1:0.782609 3:0.108696 7:0.024787909 +-1 1:0.882353 7:0.018651366 +-1 1:0.759036 3:0.036145 4:0.0036900369 7:0.012268585 8:0.023809524 +-1 1:0.866667 7:0.014634146 +-1 1:0.697674 2:0.011628 3:0.093023 4:0.0036900369 6:0.0077910078 7:0.01364861 +-1 1:0.707547 2:0.018868 3:0.04717 6:0.013101013 7:0.01317303 8:0.047619048 +-1 1:0.625 2:0.125 3:0.05 5:0.087702951 6:0.10588211 7:0.012957317 8:0.023809524 +-1 1:0.841509 3:0.007547 7:0.019397146 8:0.047619048 +-1 1:0.752688 3:0.086022 4:0.014760148 7:0.017440335 +-1 1:0.743119 2:0.009174 3:0.073394 5:0.022661876 7:0.018404567 8:0.047619048 +-1 1:0.796296 7:0.012985549 8:0.023809524 +-1 1:0.795918 7:0.012070683 +-1 1:0.75 3:0.208333 7:0.054878049 +-1 1:0.722222 3:0.111111 7:0.015243902 +-1 1:0.783333 3:0.008333 7:0.016107726 +-1 1:0.70229 2:0.076336 3:0.030534 5:0.069237994 6:0.055728056 7:0.015034445 8:0.023809524 +-1 1:0.759259 3:0.018519 7:0.010727189 8:0.023809524 +-1 1:0.7125 3:0.0625 7:0.017454268 +-1 1:0.666667 2:0.05102 3:0.081633 5:0.16066077 7:0.014435043 +-1 1:0.814815 7:0.011743451 +-1 1:0.72 7:0.017804878 +-1 1:0.730769 3:0.153846 7:0.019699811 +-1 1:0.8125 2:0.0625 3:0.0625 5:0.10649591 7:0.026676829 +-1 1:0.901961 7:0.037422287 8:0.023809524 +-1 1:0.70197 2:0.029557 3:0.066502 5:0.06160452 7:0.014538024 8:0.047619048 +-1 1:0.768166 2:0.034602 3:0.027682 4:0.0036900369 5:0.055894324 6:0.0084360084 7:0.022512451 8:0.047619048 +-1 1:0.764706 3:0.039216 7:0.013211384 +-1 1:0.774194 2:0.016129 3:0.032258 7:0.014653817 +-1 1:0.782609 3:0.032609 7:0.014779957 +-1 1:0.75 7:0.019163762 +-1 1:0.854839 3:0.016129 7:0.022226591 +-1 1:0.740157 2:0.007874 3:0.062992 5:0.017018771 7:0.021029384 8:0.047619048 +-1 1:0.725806 2:0.016129 3:0.08871 4:0.014760148 5:0.016944225 7:0.021636506 +-1 1:0.8125 7:0.011051829 8:0.023809524 +-1 1:0.807692 7:0.011960598 8:0.047619048 +-1 1:0.731343 2:0.014925 3:0.037313 7:0.014515835 +-1 1:0.791139 2:0.012658 3:0.025316 4:0.0073800738 5:0.034350633 7:0.016748994 +-1 1:0.751825 2:0.021898 3:0.051095 4:0.014760148 5:0.0501394 7:0.019850457 8:0.023809524 +-1 1:0.774603 7:0.014324427 8:0.071428571 +-1 1:0.793478 3:0.032609 4:0.0073800738 7:0.015972957 +-1 1:0.666667 3:0.133333 4:0.011070111 7:0.015447152 8:0.023809524 +-1 1:0.772727 3:0.022727 7:0.013442348 8:0.023809524 +-1 1:0.722222 2:0.055556 3:0.055556 5:0.20147451 7:0.012533878 +-1 1:0.8 7:0.01097561 8:0.023809524 +-1 1:0.862069 7:0.01682086 +-1 1:0.722798 2:0.056995 3:0.020725 5:0.083759486 6:0.016854017 7:0.01687097 +-1 1:0.771429 3:0.028571 7:0.020731707 +-1 1:0.709091 2:0.063636 3:0.027273 6:0.047469047 7:0.017516628 +-1 1:0.701613 2:0.016129 3:0.056452 5:0.024204971 7:0.015145555 8:0.047619048 +-1 1:0.805556 3:0.083333 7:0.02320461 +-1 1:0.692308 3:0.153846 7:0.013133207 +-1 1:0.815789 7:0.015645055 8:0.071428571 +-1 1:0.75 2:0.1 5:0.3042655 7:0.014939024 +-1 1:0.791667 3:0.041667 7:0.015879067 +-1 1:0.689655 2:0.068966 3:0.103448 5:0.026433885 6:0.053190053 7:0.019764506 +-1 1:0.714286 2:0.040816 3:0.102041 5:0.051414131 7:0.018043805 +-1 1:0.689655 2:0.068966 3:0.103448 4:0.0073800738 5:0.12288104 7:0.019133726 +-1 1:0.757143 2:0.014286 3:0.028571 7:0.014372823 8:0.023809524 +-1 1:0.923077 7:0.034474671 +-1 1:0.692308 3:0.038462 7:0.012898689 +-1 1:0.765432 7:0.011894006 8:0.047619048 +-1 1:0.666667 2:0.060606 3:0.121212 7:0.017368811 +-1 1:0.737705 2:0.032787 3:0.032787 4:0.0036900369 5:0.10425954 7:0.01429428 8:0.023809524 +-1 1:0.764706 3:0.068627 7:0.016917744 +-1 1:0.796296 7:0.015018067 8:0.023809524 +-1 1:0.822222 7:0.016531165 +-1 1:0.846154 7:0.013133207 +-1 1:0.662162 2:0.040541 3:0.135135 4:0.011070111 5:0.031860808 7:0.019281476 +-1 1:0.733333 2:0.025 3:0.083333 5:0.06144052 7:0.018495933 +-1 1:0.684211 2:0.068421 3:0.031579 5:0.11778957 6:0.027087027 7:0.014216945 +-1 1:0.736842 3:0.078947 4:0.014760148 7:0.019094994 +-1 1:0.764706 3:0.039216 7:0.014347201 +-1 1:0.758065 2:0.008065 3:0.040323 7:0.014457122 +-1 1:0.708333 3:0.091667 7:0.013211384 +-1 1:0.79703 3:0.044554 7:0.029733152 8:0.023809524 +-1 1:0.765625 2:0.007812 3:0.023438 5:0.026814068 7:0.01324314 +-1 1:0.60241 2:0.048193 3:0.192771 5:0.097446066 7:0.022480165 +-1 1:0.666667 2:0.014493 3:0.115942 5:0.042356835 7:0.015553201 +-1 1:0.776081 2:0.017812 3:0.017812 5:0.031510444 6:0.0025350025 7:0.018354744 +-1 1:0.693069 2:0.009901 3:0.054455 5:0.033351721 7:0.013493116 8:0.047619048 +-1 1:0.795455 7:0.011917957 +-1 1:0.74026 2:0.012987 7:0.011086476 8:0.095238095 +-1 1:0.763636 3:0.045455 4:0.0073800738 7:0.017405762 8:0.023809524 +-1 1:0.770186 3:0.037267 7:0.016626268 8:0.071428571 +-1 1:0.727273 3:0.072727 7:0.0135255 8:0.023809524 +-1 1:0.788235 7:0.016929701 8:0.095238095 +-1 1:0.73224 3:0.016393 7:0.013061439 8:0.071428571 +-1 1:0.740331 2:0.01105 3:0.027624 4:0.0036900369 5:0.01762259 7:0.014250104 8:0.023809524 +-1 1:0.784 3:0.032 7:0.017902439 +-1 1:0.662651 2:0.036145 3:0.108434 4:0.0036900369 5:0.036900094 7:0.014839848 +-1 1:0.730539 3:0.047904 4:0.011070111 7:0.012304659 +-1 1:0.826087 7:0.018955463 +-1 1:0.741935 3:0.064516 7:0.012391817 +-1 1:0.803922 7:0.012792921 8:0.023809524 +-1 1:0.653846 2:0.038462 3:0.153846 4:0.011070111 5:0.085682764 7:0.020403378 8:0.023809524 +-1 1:0.775362 2:0.021739 3:0.050725 4:0.0073800738 5:0.015758949 6:0.0063420063 7:0.02089961 +-1 1:0.711712 2:0.027027 3:0.09009 5:0.04107465 7:0.019940671 8:0.023809524 +-1 1:0.763975 3:0.012422 7:0.013028329 8:0.095238095 +-1 1:0.72381 2:0.009524 3:0.085714 4:0.018450185 7:0.015447152 8:0.047619048 +-1 1:0.788079 3:0.013245 7:0.014981427 8:0.071428571 +-1 1:0.742647 3:0.051471 7:0.013719512 8:0.047619048 +-1 1:0.787037 3:0.027778 7:0.014679317 +-1 1:0.80226 7:0.014503238 8:0.023809524 +-1 1:0.785714 3:0.142857 4:0.0036900369 7:0.026567945 +-1 1:0.620915 2:0.091503 3:0.045752 5:0.018002773 6:0.072465072 7:0.01649928 +-1 1:0.608974 2:0.089744 3:0.044872 5:0.017018771 6:0.068493068 7:0.017120073 +-1 1:0.66113 2:0.093023 3:0.066445 5:0.093606966 6:0.044520045 7:0.017745726 8:0.095238095 +-1 1:0.797834 3:0.021661 7:0.016201463 +-1 1:0.789474 7:0.012772787 8:0.095238095 +-1 1:0.719101 2:0.022472 3:0.067416 5:0.017794045 6:0.014319014 7:0.01435325 +-1 1:0.741935 7:0.015014427 +-1 1:0.913043 7:0.032078476 +-1 1:0.792208 7:0.012591067 +-1 1:0.774194 3:0.032258 7:0.017112512 8:0.047619048 +-1 1:0.706522 2:0.054348 3:0.043478 5:0.037459186 6:0.015075015 7:0.019783933 +-1 1:0.752613 3:0.041812 7:0.013724823 8:0.023809524 +-1 1:0.755448 2:0.016949 3:0.038741 4:0.0073800738 5:0.011964576 6:0.0048150048 7:0.01839603 8:0.047619048 +-1 1:0.756757 3:0.054054 7:0.012030323 +-1 1:0.772414 3:0.013793 7:0.013540793 8:0.047619048 +-1 1:0.732143 3:0.080357 7:0.015788329 +-1 1:0.603896 2:0.090909 3:0.045455 5:0.01762259 6:0.070923071 7:0.016748494 +-1 1:0.603896 2:0.090909 3:0.045455 6:0.072465072 7:0.016392146 +-1 1:0.713004 3:0.116592 4:0.018450185 7:0.019878598 8:0.023809524 +-1 1:0.781457 3:0.02649 7:0.014617994 +-1 1:0.732984 2:0.005236 3:0.036649 4:0.0036900369 7:0.012961305 8:0.095238095 +-1 1:0.598765 2:0.197531 3:0.037037 5:0.044369567 6:0.13690514 7:0.018970189 +-1 1:0.516667 2:0.133333 3:0.1 5:0.4701072 7:0.011280488 8:0.023809524 +-1 1:0.688312 2:0.051948 3:0.051948 5:0.043087382 6:0.017340017 7:0.013699713 +-1 1:0.735294 2:0.029412 3:0.044118 5:0.089812592 7:0.01488522 +-1 1:0.773026 3:0.059211 7:0.020057768 8:0.023809524 +-1 1:0.686275 2:0.009804 3:0.078431 7:0.013988524 8:0.047619048 +-1 1:0.754601 3:0.01227 7:0.01223253 8:0.095238095 +-1 1:0.658537 2:0.00813 3:0.154472 5:0.023153877 7:0.01596272 +-1 1:0.67 3:0.123333 4:0.029520295 7:0.022784555 8:0.023809524 +-1 1:0.666667 2:0.04902 3:0.127451 4:0.011070111 5:0.046881756 6:0.018867019 7:0.019010043 8:0.023809524 +-1 1:0.75 3:0.25 7:0.039634146 +-1 1:0.704225 2:0.014085 3:0.051643 5:0.013828217 7:0.015429976 8:0.047619048 +-1 1:0.653928 2:0.093418 3:0.031847 4:0.0073800738 5:0.013194579 6:0.082302082 7:0.01462897 8:0.023809524 +-1 1:0.703125 2:0.026042 3:0.09375 5:0.02524861 6:0.0025410025 7:0.018753177 +-1 1:0.75 3:0.032407 4:0.0036900369 7:0.015032183 +-1 1:0.816568 3:0.017751 7:0.018382884 8:0.071428571 +-1 1:0.604027 2:0.100671 3:0.04698 5:0.03842828 6:0.077319077 7:0.015878213 +-1 1:0.592105 2:0.098684 3:0.046053 5:0.035923546 6:0.072288072 7:0.016647945 +-1 1:0.708861 2:0.063291 3:0.031646 5:0.10751718 6:0.014424014 7:0.016054335 +-1 1:0.758065 2:0.029954 3:0.020737 5:0.076707468 6:0.0028050028 7:0.01501911 8:0.023809524 +-1 1:0.712329 3:0.054795 7:0.011944537 8:0.047619048 +-1 1:0.704762 3:0.142857 4:0.036900369 7:0.021254354 8:0.023809524 +-1 1:0.729958 2:0.025316 3:0.050633 4:0.014760148 5:0.059166878 7:0.019450445 8:0.023809524 +-1 1:0.738739 3:0.072072 7:0.019061744 8:0.023809524 +-1 1:0.75 3:0.027778 7:0.018462061 +-1 1:0.793333 3:0.033333 7:0.01882114 8:0.023809524 +-1 1:0.695652 2:0.026087 3:0.113043 7:0.021049841 +-1 1:0.666667 2:0.023256 3:0.131783 4:0.018450185 5:0.030996079 7:0.022735866 +-1 1:0.697436 2:0.102564 3:0.005128 6:0.10800011 7:0.015634774 8:0.023809524 +-1 1:0.632184 2:0.045977 3:0.137931 6:0.0074370074 7:0.084805159 +-1 1:0.684932 2:0.068493 3:0.09589 4:0.014760148 5:0.055014685 6:0.022140022 7:0.022636152 +-1 1:0.789474 7:0.012034659 8:0.023809524 +-1 1:0.770833 7:0.01225864 8:0.11904762 +-1 1:0.674603 2:0.02381 3:0.079365 5:0.051414131 7:0.014034067 8:0.023809524 +-1 1:0.726415 3:0.028302 4:0.0036900369 7:0.011619878 8:0.047619048 +-1 1:0.75 2:0.008929 3:0.0625 5:0.027507343 7:0.014753921 +-1 1:0.771429 2:0.028571 3:0.071429 4:0.0036900369 5:0.026910978 7:0.024128921 +-1 1:0.745098 2:0.022059 3:0.02451 6:0.022851023 7:0.013734457 8:0.047619048 +-1 1:0.814815 7:0.013324299 +-1 1:0.734177 2:0.012658 3:0.063291 4:0.0073800738 5:0.040962832 7:0.014047543 8:0.023809524 +-1 1:0.782258 7:0.013104841 8:0.023809524 +-1 1:0.704545 2:0.068182 3:0.022727 5:0.073807642 6:0.044553045 7:0.013996677 +-1 1:0.726027 3:0.09589 7:0.016956232 8:0.023809524 +-1 1:0.68254 2:0.015873 3:0.126984 5:0.047478121 7:0.015195512 8:0.023809524 +-1 1:0.771574 3:0.020305 7:0.013154634 8:0.071428571 +-1 1:0.625 2:0.111111 3:0.069444 4:0.0073800738 6:0.086208086 7:0.014735774 +-1 1:0.7375 3:0.1375 4:0.0073800738 7:0.027591463 +-1 1:0.696429 2:0.035714 3:0.089286 4:0.014760148 6:0.030612031 7:0.016006098 +-1 1:0.666667 2:0.156863 3:0.039216 4:0.033210332 6:0.10659911 7:0.023553323 +-1 1:0.715909 3:0.147727 4:0.036900369 7:0.024320951 +-1 1:0.933333 7:0.029268293 +-1 1:1 4:0.081180812 7:0.13414634 +-1 1:0.722222 2:0.166667 3:0.027778 5:0.029818258 6:0.06000006 7:0.042344177 +-1 1:0.903226 7:0.030881195 +-1 1:0.708333 2:0.026042 3:0.083333 4:0.0036900369 5:0.029818258 6:0.006000006 7:0.015879067 +-1 1:0.654545 3:0.054545 7:0.011031043 8:0.023809524 +-1 1:0.747634 2:0.028391 3:0.022082 5:0.020850417 6:0.012588013 7:0.013753177 +-1 1:0.727273 3:0.064935 7:0.018847006 8:0.047619048 +-1 1:0.759615 2:0.028846 3:0.086538 5:0.030615896 7:0.028553006 +-1 1:0.65873 2:0.087302 3:0.063492 4:0.0073800738 5:0.13471889 6:0.018072018 7:0.016066591 +-1 1:0.75576 2:0.013825 3:0.096774 5:0.0078794746 7:0.026581994 +-1 1:0.710526 2:0.026316 3:0.092105 4:0.0036900369 5:0.032837356 7:0.018212451 +-1 1:0.692308 2:0.019231 3:0.115385 4:0.014760148 6:0.017544018 7:0.020051591 8:0.023809524 +-1 1:0.760204 3:0.05102 4:0.0036900369 7:0.018541561 +-1 1:0.78 3:0.02 7:0.015853659 +-1 1:0.738046 2:0.04158 3:0.022869 5:0.1196234 7:0.015009384 +-1 1:0.732601 2:0.025641 3:0.014652 5:0.086681675 7:0.013445902 8:0.11904762 +-1 1:0.684814 2:0.051576 3:0.057307 5:0.064966529 6:0.0032670033 7:0.01603886 +-1 1:0.771739 3:0.01087 7:0.013586957 8:0.023809524 +-1 1:0.646341 2:0.182927 5:0.0786382 6:0.15822916 7:0.017623439 8:0.023809524 +-1 1:0.705882 3:0.019608 7:0.011836439 +-1 1:0.629139 2:0.119205 3:0.072848 5:0.069670359 6:0.07009207 7:0.017283152 8:0.023809524 +-1 1:0.825 7:0.01722561 8:0.023809524 +-1 1:0.724138 7:0.0098822561 +-1 1:0.65 2:0.05 3:0.175 4:0.025830258 5:0.081918209 7:0.027743902 8:0.023809524 +-1 1:0.757143 3:0.057143 4:0.018450185 7:0.016724738 8:0.071428571 +-1 1:0.7625 3:0.1125 7:0.029039634 +-1 1:0.619048 2:0.047619 3:0.238095 5:0.085682764 7:0.025261323 +-1 1:0.752336 2:0.014019 3:0.081776 4:0.0036900369 5:0.0071862001 6:0.0014460014 7:0.029561774 8:0.047619048 +-1 1:0.77381 3:0.02381 7:0.013501744 +-1 1:0.771028 2:0.028037 3:0.037383 5:0.043527202 7:0.019517896 +-1 1:0.757937 2:0.011905 3:0.047619 5:0.019486231 7:0.018510451 +-1 1:0.638436 2:0.074919 3:0.100977 5:0.058756877 6:0.026601027 7:0.020159689 8:0.023809524 +-1 1:0.846154 3:0.076923 7:0.020168854 +-1 1:0.724299 3:0.037383 7:0.017209939 8:0.071428571 +-1 1:0.67 2:0.05 3:0.08 5:0.12071922 7:0.015060976 +-1 1:0.617284 2:0.012346 3:0.061728 7:0.0097109329 8:0.023809524 +-1 1:0.797872 3:0.021277 7:0.016216921 8:0.047619048 +-1 1:0.765432 2:0.024691 3:0.024691 5:0.080591296 7:0.01392653 +-1 1:0.767857 3:0.053571 7:0.017530488 8:0.023809524 +-1 1:0.727612 2:0.003731 3:0.041045 4:0.0036900369 5:0.010600391 7:0.01599472 +-1 1:0.75 2:0.0325 3:0.0375 4:0.0036900369 5:0.02353406 6:0.011838012 7:0.019314024 8:0.071428571 +-1 1:0.866667 3:0.044444 7:0.062330622 +-1 1:0.659091 3:0.136364 7:0.011779378 +-1 1:0.719298 3:0.070175 7:0.016688061 +-1 1:0.745342 2:0.031056 3:0.037267 4:0.0036900369 5:0.072376366 7:0.015603695 +-1 1:0.773333 2:0.013333 3:0.013333 5:0.0098251159 6:0.003954004 7:0.015426829 +-1 1:0.6 2:0.090323 3:0.109677 5:0.043765748 6:0.058707059 7:0.02010228 +-1 1:0.652174 2:0.043478 3:0.173913 5:0.048566487 7:0.027129726 +-1 1:0.675889 2:0.071146 3:0.039526 4:0.011070111 5:0.08624931 6:0.04958705 7:0.014581122 8:0.071428571 +-1 1:0.642857 3:0.142857 7:0.0095818841 +-1 1:0.676056 2:0.042254 3:0.098592 5:0.089812592 7:0.014256268 +-1 1:0.75 2:0.022727 5:0.0642658 7:0.01607539 +-1 1:0.786207 3:0.013793 7:0.014213622 8:0.023809524 +-1 1:0.933333 7:0.029268293 +-1 1:0.707317 2:0.036585 3:0.097561 6:0.015228015 7:0.029298037 +-1 1:0.745928 3:0.052117 7:0.015670933 8:0.023809524 +-1 1:0.762887 3:0.051546 7:0.014143829 +-1 1:0.672414 3:0.155172 7:0.019028598 +-1 1:0.916667 3:0.083333 4:0.0036900369 7:0.076219512 +-1 1:0.74026 3:0.051948 7:0.014333226 8:0.047619048 +-1 1:0.661157 2:0.099174 3:0.057851 4:0.0073800738 5:0.046017026 6:0.064815065 7:0.016327354 +-1 1:0.755556 2:0.027778 3:0.027778 4:0.0036900369 6:0.025263025 7:0.016090787 +-1 1:0.780488 3:0.04878 4:0.0036900369 7:0.014574659 8:0.023809524 +-1 1:0.698276 2:0.060345 3:0.051724 5:0.16205478 7:0.014507988 +-1 1:0.758242 2:0.021978 3:0.087912 4:0.0073800738 7:0.022179043 +-1 1:0.8 3:0.0125 7:0.013643293 +-1 1:0.738095 3:0.047619 7:0.013211384 +-1 1:0.690909 2:0.072727 3:0.054545 5:0.17071698 7:0.01452328 +-1 1:0.84 7:0.013902439 +-1 1:0.727273 3:0.040404 7:0.010901701 +-1 1:0.729167 2:0.114583 3:0.03125 5:0.13181161 7:0.032329774 8:0.023809524 +-1 1:0.752066 3:0.016529 4:0.0073800738 7:0.013253378 8:0.047619048 +-1 1:0.765823 2:0.012658 5:0.049863581 7:0.011539055 8:0.071428571 +-1 1:0.638462 2:0.061538 3:0.107692 6:0.053097053 7:0.015900561 +-1 1:0.674699 2:0.084337 3:0.072289 5:0.059875062 6:0.024096024 7:0.018292683 +-1 1:0.790909 3:0.045455 4:0.022140221 7:0.023004433 +-1 1:0.836735 7:0.017421604 +-1 1:0.842105 3:0.105263 7:0.0317715 +-1 1:0.748963 2:0.03527 3:0.041494 4:0.0036900369 5:0.056632326 7:0.018317982 8:0.071428571 +-1 1:0.894737 7:0.019576378 +-1 1:0.823529 3:0.176471 4:0.0073800738 7:0.054878049 +-1 1:0.767442 2:0.046512 3:0.046512 5:0.04937158 7:0.021412366 +-1 1:0.675 2:0.075 3:0.025 5:0.059166878 6:0.023811024 7:0.019207317 +-1 1:0.495833 2:0.145833 3:0.158333 4:0.022140221 5:0.14049618 6:0.03991204 7:0.022916665 +-1 1:0.736842 3:0.078947 7:0.013157896 +-1 1:0.777778 7:0.02168022 +-1 1:0.723404 3:0.117021 4:0.0036900369 7:0.021341463 8:0.023809524 +-1 1:0.65 2:0.0875 3:0.1625 5:0.068015446 6:0.0054750055 7:0.041768293 +-1 1:0.666667 2:0.047619 3:0.047619 7:0.033101043 +-1 1:0.8 7:0.014452518 8:0.023809524 +-1 1:0.703704 2:0.037037 3:0.074074 7:0.015808488 +-1 1:0.793103 7:0.011354079 +-1 1:0.781726 3:0.005076 7:0.014207006 8:0.047619048 +-1 1:0.775 3:0.025 7:0.013948171 +-1 1:0.72093 2:0.046512 3:0.046512 5:0.16031041 7:0.01318775 +-1 1:0.785714 7:0.010235189 +-1 1:0.702128 2:0.021277 3:0.085106 7:0.016865591 8:0.023809524 +-1 1:0.708333 3:0.041667 7:0.009527439 8:0.023809524 +-1 1:0.725806 2:0.032258 3:0.032258 7:0.011900079 +-1 1:0.740741 3:0.074074 7:0.014905146 8:0.023809524 +-1 1:0.726141 2:0.016598 3:0.058091 4:0.011070111 5:0.053531227 7:0.014092701 8:0.047619048 +-1 1:0.775 3:0.1125 4:0.0073800738 7:0.027210366 +-1 1:0.71875 3:0.0625 4:0.0036900369 7:0.011242378 8:0.023809524 +-1 1:0.816092 7:0.01583964 +-1 1:0.678571 3:0.142857 7:0.013719512 +-1 1:0.759259 7:0.011856366 8:0.023809524 +-1 1:0.771429 3:0.071429 7:0.018466896 +-1 1:0.734694 3:0.081633 7:0.016052762 8:0.023809524 +-1 1:0.866667 7:0.019512195 +-1 1:0.803922 7:0.012553805 +-1 1:0.762673 2:0.025346 3:0.02765 5:0.025904611 6:0.015639016 7:0.016171183 +-1 1:0.631579 2:0.052632 3:0.105263 5:0.2042327 7:0.011713738 8:0.023809524 +-1 1:0.639175 2:0.010309 3:0.134021 5:0.036013001 7:0.013012323 +-1 1:0.717557 2:0.030534 3:0.038168 4:0.0073800738 6:0.030822031 7:0.013591512 +-1 1:0.714286 3:0.122449 7:0.018292683 +-1 1:0.694444 2:0.055556 3:0.027778 6:0.043479043 7:0.011686994 +-1 1:0.75 2:0.017857 3:0.071429 5:0.047783758 7:0.016986061 +-1 1:0.769231 7:0.0093808659 8:0.023809524 +-1 1:0.769231 7:0.0089118171 8:0.023809524 +-1 1:0.608696 3:0.130435 4:0.0036900369 7:0.017497348 +-1 1:0.857143 7:0.019599305 +-1 1:0.65798 2:0.013029 3:0.114007 5:0.012277668 7:0.024112177 +-1 1:0.794118 7:0.012284793 +-1 1:0.744828 2:0.006897 3:0.068966 4:0.014760148 5:0.019016594 7:0.016484439 8:0.047619048 +-1 1:0.73913 3:0.086957 7:0.015641567 +-1 1:0.807453 3:0.012422 7:0.018747159 +-1 1:0.775 3:0.1 7:0.022865854 +-1 1:0.862069 2:0.068966 3:0.068966 4:0.0036900369 6:0.0068970069 7:0.091463415 +-1 1:0.684932 3:0.136986 4:0.0073800738 7:0.018292683 8:0.023809524 +-1 1:0.724576 2:0.038136 3:0.04661 4:0.0036900369 5:0.021864237 6:0.026394026 7:0.017620921 8:0.071428571 +-1 1:0.780822 3:0.013699 7:0.014116268 8:0.11904762 +-1 1:0.647059 2:0.058824 3:0.130719 4:0.0036900369 5:0.026530795 6:0.010677011 7:0.022397579 +-1 1:0.733813 2:0.028777 3:0.05036 4:0.011070111 5:0.0642658 7:0.015265835 +-1 1:0.767296 7:0.013614049 8:0.071428571 +-1 1:0.718447 2:0.019417 3:0.072816 4:0.025830258 5:0.01309767 7:0.016842293 8:0.023809524 +-1 1:0.81457 3:0.006623 7:0.018494591 8:0.047619048 +-1 1:0.787879 2:0.020202 3:0.020202 5:0.023004786 6:0.0092580093 7:0.019955652 +-1 1:0.732283 2:0.047244 3:0.047244 4:0.0073800738 6:0.041097041 7:0.017524488 +-1 1:0.722222 3:0.055556 7:0.019986451 +-1 1:0.793388 2:0.016529 3:0.041322 5:0.017138044 7:0.021920982 +-1 1:0.72 3:0.1 4:0.0073800738 7:0.014756098 +-1 1:0.770419 2:0.015453 3:0.048565 5:0.016310587 6:0.0016410016 7:0.02460561 +-1 1:0.689076 2:0.05042 3:0.042017 5:0.11785666 7:0.01296372 8:0.023809524 +-1 1:0.649123 3:0.175439 4:0.011070111 7:0.023855372 +-1 1:0.74359 2:0.025641 3:0.051282 5:0.036721184 7:0.015869293 8:0.023809524 +-1 1:0.756522 3:0.034783 4:0.0036900369 7:0.012566274 8:0.023809524 +-1 1:0.702703 3:0.108108 4:0.011070111 7:0.013678311 8:0.023809524 +-1 1:0.783784 2:0.006757 3:0.013514 5:0.020939871 7:0.01466711 +-1 1:0.782609 2:0.028986 3:0.028986 5:0.036542275 7:0.018027573 +-1 1:0.763736 3:0.010989 7:0.011893591 +-1 1:0.828571 3:0.028571 7:0.019686409 +-1 1:0.770335 3:0.014354 7:0.014485354 +-1 1:0.72 2:0.08 3:0.08 5:0.060121062 7:0.030243902 +-1 1:0.792453 3:0.018868 4:0.0036900369 7:0.014783707 +-1 1:0.767123 3:0.045662 7:0.01865464 8:0.023809524 +-1 1:0.719298 2:0.035088 3:0.052632 5:0.052867771 7:0.015083439 8:0.023809524 +-1 1:0.594595 2:0.117117 3:0.081081 5:0.029236802 6:0.10588211 7:0.014007909 +-1 1:0.620155 2:0.085271 3:0.108527 5:0.06246925 6:0.025140025 7:0.016921915 8:0.023809524 +-1 1:0.628099 2:0.090909 3:0.132231 4:0.0073800738 6:0.048951049 7:0.021618628 +-1 1:0.809524 7:0.013356561 +-1 1:0.721854 2:0.033113 3:0.059603 6:0.0075960076 7:0.015950573 8:0.023809524 +-1 1:0.573864 2:0.130682 3:0.096591 4:0.011070111 5:0.076379467 6:0.061476061 7:0.016906872 +-1 1:0.628931 2:0.188679 3:0.012579 5:0.048245941 6:0.055017055 7:0.035549933 +-1 1:0.818182 7:0.013303768 +-1 1:0.8125 7:0.012957317 8:0.023809524 +-1 1:0.619048 2:0.095238 3:0.047619 7:0.011324043 +-1 1:0.666667 2:0.041667 3:0.125 5:0.077117469 7:0.018419713 +-1 1:0.795455 3:0.007576 7:0.014828159 +-1 1:0.708333 2:0.041667 7:0.0094004085 +-1 1:0.625 2:0.09375 3:0.015625 6:0.11904912 7:0.012004573 +-1 1:0.729167 2:0.020833 3:0.083333 4:0.0036900369 7:0.023628049 +-1 1:0.655172 2:0.017241 3:0.086207 7:0.018502945 +-1 1:0.806604 3:0.014151 4:0.0036900369 7:0.017918774 8:0.023809524 +-1 1:0.755102 2:0.061224 6:0.048780049 7:0.015306122 +-1 1:0.822222 7:0.016124659 8:0.023809524 +-1 1:0.755274 3:0.029536 7:0.013713079 +-1 1:0.625 2:0.125 3:0.075 4:0.0036900369 6:0.11538612 7:0.015853659 +-1 1:0.76 2:0.04 5:0.069021812 7:0.013170732 +-1 1:0.789954 7:0.014116268 8:0.023809524 +-1 1:0.786885 2:0.005464 3:0.043716 4:0.095940959 5:0.0040925559 7:0.030321207 8:0.023809524 +-1 1:0.691781 2:0.041096 3:0.09589 5:0.047865758 7:0.026019043 +-1 1:0.649123 2:0.04386 3:0.157895 4:0.0036900369 6:0.0067410067 7:0.023801884 +-1 1:0.666667 3:0.051282 7:0.011413384 +-1 1:0.764706 3:0.009804 7:0.016080823 +-1 1:0.767442 3:0.046512 4:0.0036900369 7:0.014463982 +-1 1:0.777778 2:0.034722 3:0.013889 5:0.017704591 6:0.014253014 7:0.017826896 8:0.023809524 +-1 1:0.688623 2:0.038922 3:0.07485 4:0.014760148 5:0.031957718 6:0.012861013 7:0.017033006 +-1 1:0.689189 2:0.013514 7:0.014749506 +-1 1:0.708333 2:0.041667 3:0.0625 7:0.01549797 +-1 1:0.714286 3:0.053571 7:0.01241289 +-1 1:0.78 3:0.02 7:0.013902439 +-1 1:0.741935 7:0.01573564 +-1 1:0.791045 3:0.029851 7:0.020476884 +-1 1:0.798781 2:0.018293 3:0.006098 6:0.013158013 7:0.016954195 +-1 1:0.78 7:0.012195122 +-1 1:0.730769 3:0.053846 4:0.022140221 7:0.017542213 +-1 1:0.8125 7:0.011432927 8:0.023809524 +-1 1:0.629032 2:0.129032 3:0.096774 5:0.074985464 6:0.03017703 7:0.023465774 +-1 1:0.803279 7:0.013294683 +-1 1:0.631579 3:0.157895 4:0.0073800738 7:0.023748396 +-1 1:0.744681 3:0.06383 7:0.016216921 8:0.023809524 +-1 1:0.735294 3:0.088235 7:0.015781921 +-1 1:0.759259 3:0.018519 7:0.011969287 +-1 1:0.711538 2:0.057692 3:0.057692 5:0.11557557 7:0.01512664 +-1 1:0.6875 3:0.125 7:0.011051829 +-1 1:0.85 7:0.015853659 +-1 1:0.794118 7:0.01201578 +-1 1:0.74026 3:0.064935 7:0.014729171 8:0.023809524 +-1 1:0.684211 2:0.026316 3:0.052632 7:0.013264872 +-1 1:0.708995 2:0.137566 5:0.24816245 7:0.024712866 +-1 1:0.781609 2:0.005747 3:0.028736 5:0.014789856 7:0.017661902 8:0.023809524 +-1 1:0.757764 3:0.093168 4:0.0073800738 7:0.024011512 8:0.023809524 +-1 1:0.683871 2:0.045161 3:0.070968 4:0.0036900369 5:0.05647578 6:0.0075750076 7:0.015578287 +-1 1:0.627451 3:0.098039 7:0.016021043 8:0.023809524 +-1 1:0.783019 7:0.01242522 8:0.023809524 +-1 1:0.774194 3:0.032258 7:0.012785207 +-1 1:0.801324 7:0.013931512 8:0.023809524 +-1 1:0.833333 7:0.011686994 +-1 1:0.776471 2:0.035294 3:0.023529 5:0.050027582 7:0.021377329 +-1 1:0.714286 7:0.0095818841 8:0.023809524 +-1 1:0.765957 3:0.021277 7:0.011676183 8:0.023809524 +-1 1:0.769231 3:0.057692 7:0.028904787 8:0.023809524 +-1 1:0.717742 3:0.072581 4:0.0036900369 7:0.013326122 8:0.047619048 +-1 1:0.745928 2:0.039088 3:0.029316 6:0.025671026 7:0.016246921 +-1 1:0.728682 2:0.054264 3:0.031008 5:0.089275864 7:0.015787482 +-1 1:0.769231 7:0.016768293 +-1 1:0.777778 3:0.074074 7:0.016937671 +-1 1:0.773371 3:0.042493 7:0.017152628 8:0.023809524 +-1 1:0.686047 2:0.011628 3:0.05814 7:0.013471354 8:0.047619048 +-1 1:0.638095 2:0.133333 3:0.028571 6:0.14285714 7:0.014634146 +-1 1:0.696891 2:0.062176 3:0.041451 4:0.018450185 6:0.055047055 7:0.015496652 8:0.023809524 +-1 1:0.807692 7:0.01360225 +-1 1:0.660606 2:0.042424 3:0.090909 5:0.040291921 6:0.016215016 7:0.013673317 +-1 1:0.738095 3:0.059524 7:0.018002323 8:0.023809524 +-1 1:0.775862 3:0.051724 7:0.021867116 +-1 1:0.772358 2:0.01626 3:0.00813 6:0.0094950095 7:0.01566528 8:0.023809524 +-1 1:0.75641 3:0.012821 7:0.012273293 +-1 1:0.824561 7:0.017329909 8:0.047619048 +-1 1:0.713043 3:0.052174 7:0.012142098 8:0.023809524 +-1 1:0.771654 2:0.023622 3:0.027559 5:0.019672596 7:0.018196659 8:0.023809524 +-1 1:0.684783 2:0.021739 3:0.076087 4:0.0036900369 7:0.015840402 +-1 1:0.7125 2:0.025 3:0.075 7:0.01554878 +-1 1:0.736842 2:0.052632 3:0.026316 5:0.08471367 7:0.014120665 +-1 1:0.693122 2:0.05291 3:0.026455 6:0.052896053 7:0.012808104 +-1 1:0.675 3:0.125 7:0.017682927 8:0.023809524 +-1 1:0.757576 3:0.045455 7:0.013858091 +-1 1:0.76971 2:0.006224 3:0.026971 5:0.019568232 7:0.014459567 8:0.047619048 +-1 1:0.725191 3:0.114504 7:0.019782165 8:0.023809524 +-1 1:0.759259 2:0.018519 3:0.037037 7:0.016260165 +-1 1:0.77551 3:0.020408 7:0.014123945 8:0.047619048 +-1 1:0.727273 3:0.045455 7:0.012610866 +-1 1:0.754386 7:0.010911427 8:0.023809524 +-1 1:0.75 3:0.083333 7:0.016260165 +-1 1:0.740741 2:0.037037 3:0.037037 7:0.01377597 +-1 1:0.666667 3:0.114943 7:0.01534903 +-1 1:0.75 7:0.012093494 8:0.095238095 +-1 1:0.695652 2:0.028986 3:0.072464 4:0.011070111 5:0.045733753 7:0.014404384 8:0.023809524 +-1 1:0.74359 3:0.076923 4:0.0073800738 7:0.015556598 +-1 1:0.784257 2:0.020408 3:0.03207 5:0.028834255 7:0.018381567 +-1 1:0.805556 3:0.055556 4:0.062730627 7:0.031334689 +-1 1:0.809917 3:0.033058 7:0.02716186 +-1 1:0.787234 7:0.012930287 8:0.023809524 +-1 1:0.770992 2:0.038168 3:0.045802 5:0.07590983 7:0.02285422 +-1 1:0.725564 2:0.037594 3:0.011278 5:0.091870052 6:0.0052830053 7:0.013020354 +-1 1:0.715789 2:0.010526 3:0.084211 4:0.0073800738 7:0.01598203 +-1 1:0.724014 2:0.02509 3:0.078853 4:0.077490775 6:0.017793018 7:0.018423811 8:0.023809524 +-1 1:0.748503 2:0.02994 3:0.023952 5:0.033962996 7:0.016028915 +-1 1:0.638889 2:0.138889 3:0.055556 5:0.076066375 6:0.061224061 7:0.016598915 +-1 1:0.754098 7:0.011145543 8:0.047619048 +-1 1:0.792793 2:0.009009 3:0.009009 4:0.0036900369 7:0.015051634 +-1 1:0.746914 3:0.080247 4:0.018450185 7:0.020701598 +-1 1:0.681159 3:0.130435 7:0.018027573 +-1 1:0.651163 2:0.102326 3:0.023256 5:0.05801142 6:0.052530053 7:0.014577427 8:0.023809524 +-1 1:0.779661 3:0.067797 4:0.0036900369 7:0.019842909 +-1 1:0.854167 7:0.021849591 +-1 1:0.762887 7:0.011377921 +-1 1:0.758621 3:0.034483 7:0.013561817 8:0.023809524 +-1 1:0.809524 7:0.012775841 +-1 1:0.826087 7:0.013785793 +-1 1:0.783784 2:0.005405 3:0.027027 7:0.015721817 +-1 1:0.776 3:0.036 7:0.015902439 8:0.071428571 +-1 1:0.818182 7:0.014551 8:0.023809524 +-1 1:0.746667 3:0.053333 7:0.013902439 8:0.047619048 +-1 1:0.733333 3:0.1 4:0.0073800738 7:0.017073171 8:0.023809524 +-1 1:0.68932 2:0.048544 3:0.087379 5:0.022318966 6:0.008982009 7:0.019772671 +-1 1:0.714286 3:0.071429 7:0.012304006 8:0.023809524 +-1 1:0.753247 2:0.006494 3:0.077922 4:0.0073800738 7:0.01999525 8:0.023809524 +-1 1:0.724138 3:0.005747 7:0.013351555 8:0.095238095 +-1 1:0.733333 7:0.0089430915 8:0.071428571 +-1 1:0.692308 3:0.053846 7:0.013086305 8:0.071428571 +-1 1:0.666667 7:0.015243902 +-1 1:0.806723 7:0.01521828 8:0.047619048 +-1 1:0.818182 7:0.015521067 8:0.047619048 +-1 1:0.692308 2:0.030769 3:0.123077 5:0.058466149 6:0.023529024 7:0.023921201 8:0.047619048 +-1 1:0.768473 2:0.019704 3:0.019704 4:0.022140221 6:0.017046017 7:0.015859665 8:0.023809524 +-1 1:0.711712 2:0.009009 3:0.027027 5:0.030183531 7:0.013568445 +-1 1:0.764706 2:0.016807 3:0.046218 4:0.0036900369 6:0.012840013 7:0.017959622 8:0.023809524 +-1 1:0.651163 2:0.046512 3:0.085271 5:0.039546464 6:0.007959008 7:0.017820006 +-1 1:0.721992 2:0.062241 3:0.037344 4:0.0036900369 5:0.048335396 6:0.032421032 7:0.017558951 +-1 1:0.807273 3:0.007273 7:0.016807098 +-1 1:0.768786 2:0.052023 3:0.023121 5:0.091064959 6:0.036648037 7:0.02019597 +-1 1:0.735849 3:0.037736 7:0.014496085 +-1 1:0.781563 3:0.03006 7:0.015763232 +-1 1:0.723077 2:0.015385 3:0.061538 5:0.043340838 7:0.016135085 8:0.023809524 +-1 1:0.8 7:0.012872628 +-1 1:0.734043 2:0.042553 3:0.047872 5:0.10039807 7:0.019265701 +-1 1:0.829268 7:0.01673111 +-1 1:0.637931 2:0.060345 3:0.142241 5:0.0046292845 6:0.0018630019 7:0.08465622 +-1 1:0.825 4:0.025830258 7:0.031554878 +-1 1:0.634441 2:0.081571 3:0.114804 5:0.040008647 6:0.032199032 7:0.02059539 8:0.023809524 +-1 1:0.722222 2:0.025926 3:0.055556 5:0.036721184 6:0.011085011 7:0.018337848 8:0.023809524 +-1 1:0.666667 3:0.133333 4:0.0036900369 7:0.014634146 +-1 1:0.705263 3:0.105263 4:0.0073800738 7:0.015147622 +-1 1:0.780822 3:0.020548 7:0.014721854 8:0.023809524 +-1 1:0.740741 7:0.010388439 +-1 1:0.647059 7:0.01649928 +-1 1:0.764706 3:0.058824 7:0.014705884 +-1 1:0.454545 2:0.136364 3:0.136364 5:0.13553889 7:0.015243902 +-1 1:0.675439 2:0.04386 3:0.087719 5:0.062640705 7:0.019094994 +-1 1:0.763514 3:0.006757 7:0.013225116 8:0.023809524 +-1 1:0.753695 3:0.049261 4:0.025830258 7:0.019434098 +-1 1:0.978102 4:0.036900369 7:0.22333987 +-1 1:0.65 2:0.1 3:0.05 5:0.056908145 6:0.068703069 7:0.013313006 +-1 1:0.568421 2:0.2 3:0.052632 5:0.020037869 6:0.11290211 7:0.023876762 +-1 1:0.73913 3:0.031056 7:0.013634299 +-1 1:0.782123 7:0.013285189 8:0.071428571 +-1 1:0.76087 2:0.014493 3:0.043478 4:0.0036900369 5:0.020149688 7:0.01634853 +-1 1:0.794479 3:0.009202 7:0.014084244 8:0.071428571 +-1 1:0.761364 7:0.011779378 8:0.047619048 +-1 1:0.755396 2:0.026379 3:0.023981 5:0.070728907 7:0.015412061 +-1 1:0.722973 2:0.02027 3:0.081081 5:0.029288984 7:0.020970665 +-1 1:0.685714 2:0.071429 3:0.057143 6:0.015957016 7:0.016376305 +-1 1:0.773333 3:0.026667 7:0.013983738 +-1 1:0.739837 3:0.02439 7:0.012244695 +-1 1:0.798611 3:0.006944 7:0.014651085 8:0.023809524 +-1 1:0.730769 7:0.010787994 +-1 1:0.78341 2:0.018433 3:0.023041 5:0.025658611 7:0.016325726 +-1 1:0.787129 2:0.00495 3:0.009901 7:0.014459067 8:0.047619048 +-1 1:0.765432 3:0.049383 7:0.014378201 +-1 1:0.746753 3:0.038961 4:0.011070111 7:0.013066201 8:0.023809524 +-1 1:0.772727 3:0.015152 7:0.012749445 8:0.023809524 +-1 1:0.666667 2:0.106061 3:0.090909 6:0.063558064 7:0.021803402 +-1 1:0.7 2:0.066667 3:0.033333 7:0.01382114 +-1 1:0.833333 7:0.016405341 +-1 1:0.645161 2:0.040323 3:0.177419 5:0.014200945 6:0.0057150057 7:0.025816287 +-1 1:0.7 3:0.111538 7:0.020755159 +-1 1:0.737705 3:0.016393 7:0.011145543 +-1 1:0.808333 7:0.01722561 +-1 1:0.8 7:0.013082043 +-1 1:0.78125 3:0.0625 7:0.023818598 +-1 1:0.738095 2:0.095238 3:0.047619 6:0.031689032 7:0.041231128 +-1 1:0.948276 7:0.17987805 +-1 1:0.84 3:0.02 7:0.020731707 +-1 1:0.759494 2:0.033755 3:0.033755 5:0.0392781 6:0.0087810088 7:0.021971799 +-1 1:0.761246 2:0.017301 3:0.010381 5:0.023668242 7:0.013292262 8:0.023809524 +-1 1:0.75 3:0.035714 7:0.011977354 +-1 1:0.730769 2:0.038462 3:0.076923 7:0.018058165 +-1 1:0.69863 2:0.082192 3:0.068493 5:0.066859988 6:0.026907027 7:0.018626799 +-1 1:0.771028 2:0.023364 3:0.014019 5:0.051235221 7:0.016583085 +-1 1:0.761905 2:0.02381 3:0.047619 7:0.025696866 8:0.023809524 +-1 1:0.527778 2:0.25 5:0.11125937 6:0.22388122 7:0.011348238 +-1 1:0.705128 2:0.053846 3:0.089744 4:0.0036900369 5:0.071787455 6:0.017778018 7:0.021106945 +-1 1:0.75 3:0.028846 7:0.012546902 8:0.023809524 +-1 1:0.696721 2:0.016393 3:0.07377 5:0.030548805 7:0.012195122 +-1 1:0.803571 7:0.012739549 +-1 1:0.705628 2:0.030303 3:0.073593 5:0.037332459 6:0.005007005 7:0.015811427 8:0.023809524 +-1 1:0.703704 2:0.037037 3:0.111111 7:0.018292683 +-1 1:0.813953 7:0.016638305 +-1 1:0.738095 3:0.071429 4:0.011070111 7:0.020688152 8:0.071428571 +-1 1:0.820513 7:0.016416512 8:0.023809524 +-1 1:0.77095 2:0.01676 3:0.011173 6:0.014742015 7:0.013864287 8:0.023809524 +-1 1:0.725118 2:0.066351 3:0.052133 5:0.12130067 6:0.0044370044 7:0.019535311 +-1 1:0.614035 2:0.096491 3:0.100877 4:0.0036900369 5:0.07110909 6:0.042924043 7:0.01682178 +-1 1:0.790698 3:0.054264 4:0.011070111 7:0.018245415 +-1 1:0.6 2:0.11 3:0.07 5:0.02934862 6:0.070866071 7:0.015487805 8:0.023809524 +-1 1:0.802469 3:0.049383 7:0.02250828 +-1 1:0.742188 3:0.0625 4:0.0073800738 7:0.017197024 +-1 1:0.771429 3:0.028571 7:0.017421604 +-1 1:0.612903 2:0.064516 3:0.096774 7:0.010228165 +-1 1:0.79661 2:0.033898 3:0.033898 5:0.03269572 7:0.023563457 +-1 1:0.730769 2:0.038462 7:0.010318951 +-1 1:0.660194 2:0.058252 3:0.087379 5:0.12808433 6:0.01030801 7:0.017227091 +-1 1:0.725352 3:0.084507 4:0.025830258 7:0.021126762 8:0.047619048 +-1 1:0.636364 3:0.045455 7:0.016491128 +-1 1:0.810127 3:0.037975 7:0.021457238 +-1 1:0.736077 2:0.016949 3:0.101695 4:0.0036900369 5:0.0078272927 7:0.028125555 +-1 1:0.8 7:0.01097561 8:0.023809524 +-1 1:0.84 7:0.016097561 8:0.023809524 +-1 1:0.777778 7:0.011856366 +-1 1:0.780488 3:0.04878 7:0.015615707 +-1 1:0.594595 2:0.102703 3:0.113514 4:0.0073800738 5:0.076222921 6:0.061350061 7:0.016117335 +-1 1:0.77095 3:0.022346 7:0.016453195 8:0.023809524 +-1 1:0.820513 7:0.014540335 +-1 1:0.772152 2:0.025316 7:0.014124732 8:0.023809524 +-1 1:0.731343 7:0.010921006 8:0.023809524 +-1 1:0.788462 7:0.014169012 +-1 1:0.664 2:0.024 3:0.096 4:0.0036900369 5:0.027507343 7:0.013219512 +-1 1:0.681818 3:0.136364 4:0.0073800738 7:0.014412415 +-1 1:0.780255 3:0.031847 7:0.016564396 +-1 1:0.698413 3:0.142857 4:0.0036900369 7:0.019938055 +-1 1:0.79918 7:0.012994805 +-1 1:0.652174 2:0.130435 3:0.043478 5:0.27107778 7:0.014581122 +-1 1:0.818182 7:0.012749445 +-1 1:0.709677 2:0.010753 3:0.096774 7:0.014489902 +-1 1:0.794979 2:0.006276 3:0.025105 6:0.0040560041 7:0.01886672 +-1 1:0.57377 2:0.131148 3:0.081967 4:0.011070111 5:0.058235057 6:0.093750094 7:0.012794884 +-1 1:0.555556 2:0.222222 5:0.80832824 7:0.01124661 +-1 1:0.692708 2:0.067708 3:0.020833 4:0.0036900369 6:0.066831067 7:0.012830287 8:0.023809524 +-1 1:0.806452 7:0.012195122 +-1 1:0.730337 2:0.011236 3:0.05618 5:0.033731904 7:0.015141134 8:0.047619048 +-1 1:0.585938 2:0.195312 3:0.03125 6:0.15297615 7:0.016815927 +-1 1:0.696721 3:0.090164 4:0.044280443 7:0.01741803 8:0.047619048 +-1 1:0.75974 2:0.006494 3:0.032468 7:0.014768768 8:0.023809524 +-1 1:0.755556 7:0.010569104 8:0.047619048 +-1 1:0.65625 2:0.125 5:0.097446066 6:0.078432078 7:0.014576982 +-1 1:0.784615 2:0.015385 5:0.055633414 7:0.012570354 8:0.047619048 +-1 1:0.657895 2:0.026316 3:0.078947 7:0.013157896 +-1 1:0.72619 3:0.119048 4:0.011070111 7:0.026204994 8:0.047619048 +-1 1:0.657143 2:0.028571 3:0.121429 4:0.0036900369 7:0.019337982 +-1 1:0.736842 2:0.070175 3:0.017544 5:0.14153981 7:0.016902012 +-1 1:0.803571 7:0.014699476 8:0.023809524 +-1 1:0.761905 3:0.02381 7:0.012049939 8:0.023809524 +-1 1:0.709677 3:0.086022 4:0.0036900369 7:0.015079988 +-1 1:0.765957 3:0.034043 7:0.015905555 8:0.047619048 +-1 1:0.677966 3:0.161017 4:0.044280443 7:0.023253409 +-1 1:0.70936 2:0.024631 3:0.078818 4:0.011070111 6:0.012228012 7:0.022107415 +-1 1:0.69906 2:0.059561 3:0.059561 5:0.083289848 6:0.013407013 7:0.017107579 8:0.023809524 +-1 1:0.714286 7:0.012630665 +-1 1:0.697674 3:0.116279 4:0.011070111 7:0.014747591 +-1 1:0.8125 3:0.0625 7:0.020579268 +-1 1:0.666667 3:0.142857 7:0.011614402 +-1 1:0.737327 2:0.013825 3:0.050691 7:0.01573564 +-1 1:0.787234 3:0.014184 7:0.01448711 +-1 1:0.717391 3:0.086957 7:0.014050902 +-1 1:0.625668 2:0.128342 3:0.042781 6:0.10983911 7:0.014249378 +-1 1:0.823529 2:0.058824 7:0.023672884 +-1 1:0.701754 3:0.157895 4:0.029520295 7:0.023106549 +-1 1:0.622951 2:0.147541 3:0.016393 5:0.052495043 6:0.12676213 7:0.014194323 +-1 1:0.791367 3:0.007194 7:0.01397175 8:0.095238095 +-1 1:0.8 7:0.018077476 +-1 1:0.8 7:0.018408829 +-1 1:0.629032 2:0.016129 3:0.16129 4:0.022140221 5:0.031860808 7:0.023013378 +-1 1:0.727273 3:0.136364 4:0.0036900369 7:0.023004433 8:0.023809524 +-1 1:0.727273 3:0.045455 4:0.0036900369 7:0.012056543 8:0.047619048 +-1 1:0.701818 2:0.043636 3:0.072727 4:0.0036900369 5:0.06160452 6:0.0041310041 7:0.016097561 +-1 1:0.709091 3:0.078788 4:0.0073800738 7:0.016260165 +-1 1:0.743902 2:0.060976 3:0.036585 5:0.088396225 7:0.018813207 +-1 1:0.652174 2:0.043478 3:0.130435 7:0.014050902 +-1 1:0.719335 2:0.024948 3:0.04158 4:0.014760148 5:0.022184784 7:0.017037677 +-1 1:0.727273 3:0.090909 7:0.015243902 +-1 1:0.714286 2:0.028571 3:0.085714 5:0.077654198 7:0.016724738 +-1 1:0.722222 3:0.111111 7:0.01388889 +-1 1:0.545455 2:0.181818 3:0.090909 4:0.0036900369 5:0.46591028 7:0.015521067 +-1 1:0.744681 2:0.053191 3:0.010638 5:0.097229884 6:0.013044013 7:0.014919567 +-1 1:0.669355 2:0.040323 3:0.104839 4:0.011070111 6:0.027189027 7:0.016276555 8:0.023809524 +-1 1:0.739884 2:0.00578 3:0.046243 4:0.0036900369 7:0.014098409 8:0.071428571 +-1 1:0.739669 3:0.057851 7:0.01373211 8:0.023809524 +-1 1:0.669291 7:0.025254463 +-1 1:0.68932 2:0.097087 3:0.038835 5:0.1370298 6:0.022059022 7:0.016102299 +-1 1:0.73913 3:0.086957 7:0.013785793 +-1 1:0.757576 3:0.045455 4:0.0036900369 7:0.016629713 8:0.023809524 +-1 1:0.762987 2:0.006494 3:0.025974 5:0.010399117 7:0.014194646 8:0.095238095 +-1 1:0.741176 3:0.011765 7:0.01083214 8:0.047619048 +-1 1:0.674419 2:0.081395 3:0.081395 5:0.11337647 7:0.018647195 +-1 1:0.703704 2:0.111111 6:0.1034491 7:0.013098463 +-1 1:0.721854 2:0.006623 3:0.112583 7:0.020513652 +-1 1:0.738095 3:0.071429 4:0.0073800738 7:0.013646921 +-1 1:0.707317 2:0.014634 3:0.034146 5:0.024160243 7:0.018352171 8:0.095238095 +-1 1:0.72973 3:0.094595 7:0.016809494 +-1 1:0.753623 3:0.028986 7:0.015022976 8:0.023809524 +-1 1:0.76 3:0.04 7:0.015487805 +-1 1:0.776316 2:0.013158 5:0.045182115 7:0.013238128 8:0.023809524 +-1 1:0.735849 3:0.103774 4:0.029520295 7:0.018177634 +-1 1:0.883721 3:0.023256 7:0.06175553 8:0.023809524 +-1 1:0.685714 3:0.133333 7:0.021515677 +-1 1:0.634921 2:0.063492 3:0.111111 4:0.011070111 5:0.14810729 7:0.014614787 +-1 1:0.714286 3:0.035714 7:0.013719512 +-1 1:0.732394 2:0.014085 3:0.098592 4:0.0036900369 7:0.023874957 +-1 1:0.631579 2:0.042105 3:0.115789 7:0.013671372 8:0.023809524 +-1 1:0.75641 7:0.010631646 8:0.023809524 +-1 1:0.766667 3:0.066667 4:0.0073800738 7:0.018394311 +-1 1:0.649123 2:0.04386 3:0.131579 4:0.018450185 6:0.035295035 7:0.018185707 +-1 1:0.770492 3:0.02459 7:0.013094762 +-1 1:0.765957 3:0.06383 4:0.0036900369 7:0.015179037 +-1 1:0.650602 2:0.024096 3:0.072289 7:0.013076695 +-1 1:0.8 7:0.01270325 8:0.023809524 +-1 1:0.78 3:0.04 7:0.01597561 +-1 1:0.696 3:0.104 7:0.015170732 +-1 1:0.760417 3:0.020833 4:0.0036900369 7:0.012893799 8:0.023809524 +-1 1:0.747748 3:0.036036 7:0.011920457 +-1 1:0.754717 7:0.010929591 +-1 1:0.717647 3:0.082353 4:0.011070111 7:0.013916787 +-1 1:0.56391 2:0.105263 3:0.12782 4:0.0036900369 5:0.14959074 6:0.01003201 7:0.013708049 +-1 1:0.802632 7:0.014762518 8:0.023809524 +-1 1:0.758621 3:0.034483 4:0.0073800738 7:0.012195122 +-1 1:0.760252 2:0.018927 3:0.012618 5:0.051764495 7:0.013849348 8:0.071428571 +-1 1:0.789474 7:0.010911427 +-1 1:0.809524 3:0.015873 7:0.016744098 +-1 1:0.608696 2:0.043478 3:0.043478 7:0.015111348 +-1 1:0.635514 2:0.102804 3:0.046729 6:0.087867088 7:0.013619787 +-1 1:0.74477 2:0.008368 3:0.054393 5:0.022974968 6:0.0046230046 7:0.016557811 8:0.095238095 +-1 1:0.666667 2:0.055556 3:0.111111 7:0.01422764 +-1 1:0.6 2:0.033333 3:0.2 4:0.0073800738 5:0.098087159 7:0.015447152 +-1 1:0.761905 3:0.047619 7:0.012195122 +-1 1:0.666667 2:0.111111 3:0.055556 5:0.18181683 6:0.073170073 7:0.01388889 +-1 1:0.638298 2:0.010638 3:0.12766 4:0.033210332 7:0.015243902 +-1 1:0.716049 3:0.098765 7:0.014528756 +-1 1:0.761905 7:0.010452963 +-1 1:0.625 2:0.1875 3:0.0625 6:0.048387048 7:0.023628049 +-1 1:0.666667 3:0.133333 7:0.01395664 8:0.023809524 +-1 1:0.735849 3:0.075472 7:0.016451909 8:0.047619048 +-1 1:0.714286 3:0.095238 7:0.012485482 8:0.047619048 +-1 1:0.740741 3:0.092593 4:0.0073800738 7:0.017502256 8:0.047619048 +-1 1:0.688889 2:0.022222 3:0.066667 5:0.043847748 7:0.011517616 8:0.023809524 +-1 1:0.746269 2:0.014925 3:0.044776 7:0.015198396 8:0.047619048 +-1 1:0.630435 2:0.043478 3:0.043478 5:0.070326361 7:0.014050902 8:0.047619048 +-1 1:0.692308 3:0.102564 7:0.019387116 8:0.023809524 +-1 1:0.845161 3:0.019355 7:0.071007085 8:0.071428571 +-1 1:0.776923 3:0.030769 7:0.014821762 8:0.047619048 +-1 1:0.733333 2:0.033333 7:0.0097560976 8:0.047619048 +-1 1:0.8 7:0.011707317 8:0.023809524 +-1 1:0.8125 7:0.012195122 8:0.023809524 +-1 1:0.705882 3:0.058824 7:0.010043043 8:0.023809524 +-1 1:0.75 3:0.0625 7:0.012195122 8:0.023809524 +-1 1:0.761905 2:0.015873 3:0.031746 7:0.014905146 8:0.047619048 +-1 1:0.766667 7:0.011788616 8:0.023809524 +-1 1:0.775862 7:0.011459207 8:0.047619048 +-1 1:0.714286 2:0.010989 3:0.054945 4:0.0073800738 7:0.014339317 8:0.023809524 +-1 1:0.708333 7:0.0094004085 8:0.047619048 +-1 1:0.693333 2:0.066667 3:0.04 5:0.18871975 7:0.01284553 8:0.023809524 +-1 1:0.8 3:0.1 7:0.020121951 +-1 1:0.752066 3:0.049587 4:0.0073800738 7:0.01773836 8:0.047619048 +-1 1:0.666667 2:0.060606 3:0.090909 5:0.079301656 6:0.031914032 7:0.017368811 8:0.023809524 +-1 1:0.810811 7:0.01384311 8:0.023809524 +-1 1:0.766234 7:0.011244854 8:0.047619048 +-1 1:0.714286 2:0.02381 3:0.095238 7:0.016550524 +-1 1:0.804878 7:0.012492561 +-1 1:0.73913 3:0.086957 7:0.014581122 +-1 1:0.774648 7:0.012882171 8:0.071428571 +-1 1:0.661765 3:0.088235 4:0.022140221 7:0.018696195 +-1 1:0.739583 3:0.041667 7:0.014672256 +-1 1:0.770677 3:0.030075 4:0.0073800738 7:0.015816982 8:0.071428571 +-1 1:0.722222 2:0.022222 3:0.044444 5:0.03842828 7:0.013143628 +-1 1:0.686567 2:0.104478 6:0.11392511 7:0.014379323 +-1 1:0.684211 2:0.052632 3:0.052632 5:0.21298436 7:0.011232348 +-1 1:0.774194 7:0.0096380793 8:0.023809524 +-1 1:0.746988 2:0.024096 3:0.048193 4:0.0073800738 5:0.032270809 7:0.016970323 +-1 1:0.686567 3:0.104478 7:0.013651256 +-1 1:0.806452 3:0.010753 7:0.017014165 +-1 1:0.747253 3:0.076923 7:0.018292683 +-1 1:0.710145 7:0.012327677 8:0.023809524 +-1 1:0.771277 2:0.021277 3:0.005319 5:0.034037541 7:0.014206018 8:0.023809524 +-1 1:0.722222 2:0.018519 3:0.074074 4:0.0036900369 5:0.053054135 7:0.015864951 +-1 1:0.727273 3:0.054545 4:0.0036900369 7:0.014634146 8:0.023809524 +-1 1:0.857143 7:0.021123695 +-1 1:0.787879 7:0.011086476 8:0.023809524 +-1 1:0.810345 7:0.013982335 8:0.071428571 +-1 1:0.823529 7:0.012912482 +-1 1:0.710526 3:0.078947 7:0.016046213 +-1 1:0.854545 2:0.018182 4:0.04797048 7:0.028824835 +-1 1:0.8 7:0.0097560976 +-1 1:0.691964 3:0.03125 7:0.01968097 8:0.023809524 +-1 1:0.683673 2:0.040816 3:0.071429 5:0.069342358 7:0.013377299 +-1 1:0.657895 2:0.026316 3:0.157895 7:0.015564829 +-1 1:0.690476 2:0.119048 6:0.12796213 7:0.015316494 8:0.023809524 +-1 1:0.74 3:0.04 7:0.011097561 +-1 1:0.679389 2:0.061069 3:0.053435 4:0.0073800738 6:0.058065058 7:0.014429341 8:0.023809524 +-1 1:0.789474 3:0.017544 7:0.013799744 +-1 1:0.740525 2:0.026239 3:0.043732 5:0.0078272927 6:0.012606013 7:0.016923841 8:0.047619048 +-1 1:0.761905 3:0.019048 7:0.012195122 8:0.023809524 +-1 1:0.777778 7:0.010501354 +-1 1:0.75 3:0.068182 7:0.014065963 +-1 1:0.629214 2:0.044944 3:0.202247 4:0.0073800738 5:0.060605609 7:0.025280902 +-1 1:0.821429 7:0.024825787 8:0.023809524 +-1 1:0.847826 7:0.036320256 8:0.023809524 +-1 1:0.777202 2:0.005181 3:0.005181 5:0.015155129 7:0.015544043 +-1 1:0.705882 3:0.039216 4:0.0036900369 7:0.015423244 8:0.023809524 +-1 1:0.731707 2:0.02439 3:0.04878 6:0.015000015 7:0.014872098 8:0.023809524 +-1 1:0.846154 7:0.015712945 8:0.023809524 +-1 1:0.693069 2:0.039604 3:0.049505 5:0.091281141 7:0.014791116 +-1 1:0.666667 2:0.014493 3:0.101449 4:0.0036900369 5:0.044637932 7:0.014757866 +-1 1:0.652459 2:0.127869 3:0.052459 5:0.0063587435 6:0.063939064 7:0.023450622 +-1 1:0.75 2:0.004237 3:0.038136 7:0.013435305 8:0.023809524 +-1 1:0.732323 2:0.015152 3:0.080808 4:0.0036900369 5:0.021484055 6:0.0043230043 7:0.021372256 +-1 1:0.793296 3:0.027933 7:0.019825591 +-1 1:0.767196 2:0.013228 3:0.042328 5:0.017980409 7:0.020067104 8:0.023809524 +-1 1:0.776952 2:0.022305 3:0.052045 5:0.020671507 7:0.02452625 +-1 1:0.791667 7:0.01117886 +-1 1:0.75 3:0.035714 7:0.01241289 +-1 1:0.727273 3:0.045455 7:0.011779378 8:0.023809524 +-1 1:0.678571 3:0.071429 7:0.024608012 +-1 1:0.631579 2:0.134868 3:0.059211 4:0.014760148 5:0.023034604 6:0.08959809 7:0.019476091 +-1 1:0.757143 2:0.014286 3:0.028571 7:0.012456445 +-1 1:0.739726 2:0.054795 3:0.041096 4:0.0036900369 5:0.072376366 6:0.014562015 7:0.017206817 +-1 1:0.721154 3:0.182692 4:0.05904059 7:0.10260319 +-1 1:0.666667 3:0.2 7:0.020731707 +-1 1:0.785714 3:0.02381 7:0.016550524 8:0.095238095 +-1 1:0.755556 7:0.010298104 8:0.071428571 +-1 1:0.755274 2:0.012658 3:0.042194 6:0.0094350094 7:0.016363073 8:0.023809524 +-1 1:0.627778 2:0.105556 3:0.038889 6:0.098484098 7:0.013414634 +-1 1:0.720588 2:0.007353 3:0.022059 7:0.013226329 +-1 1:0.685315 2:0.020979 3:0.041958 6:0.0098670099 7:0.012962646 +-1 1:0.782979 2:0.019149 3:0.025532 5:0.030928988 7:0.018759732 +-1 1:0.69697 3:0.121212 7:0.014597189 +-1 1:0.715953 2:0.003891 3:0.070039 5:0.0095120242 7:0.018601122 +-1 1:0.713043 2:0.008696 5:0.019829141 7:0.019936372 8:0.047619048 +-1 1:0.774194 3:0.008065 7:0.012539341 +-1 1:0.766667 7:0.011890244 8:0.047619048 +-1 1:0.754386 2:0.026316 3:0.017544 4:0.0036900369 6:0.026979027 7:0.014869488 +-1 1:0.631579 2:0.039474 3:0.065789 7:0.011071884 8:0.023809524 +-1 1:0.791667 3:0.041667 7:0.01702236 +-1 1:0.660714 2:0.103175 3:0.061508 5:0.044213022 6:0.048042048 7:0.020397793 +-1 1:0.697674 2:0.046512 3:0.116279 4:0.0036900369 5:0.046017026 7:0.022972207 +-1 1:0.804348 7:0.014448567 8:0.023809524 +-1 1:0.825 7:0.01554878 +-1 1:0.66443 2:0.073826 3:0.040268 5:0.12180758 6:0.01960802 7:0.012522506 +-1 1:0.693069 2:0.029703 3:0.108911 7:0.020707555 +-1 1:0.742537 2:0.029851 3:0.041045 5:0.052793225 7:0.016062976 +-1 1:0.761905 3:0.047619 4:0.0073800738 7:0.014614787 +-1 1:0.762791 7:0.014407262 +-1 1:0.8 3:0.033333 7:0.015243902 +-1 1:0.773196 2:0.015464 3:0.025773 7:0.022944433 8:0.023809524 +-1 1:0.752577 2:0.020619 3:0.082474 4:0.0036900369 7:0.022315817 +-1 1:0.742857 7:0.011904762 8:0.023809524 +-1 1:0.782609 2:0.021739 7:0.014448567 +-1 1:0.741667 3:0.058333 7:0.014329268 8:0.047619048 +-1 1:0.788991 3:0.045872 7:0.02735511 8:0.023809524 +-1 1:0.717391 2:0.038043 3:0.048913 4:0.0073800738 5:0.067769445 6:0.0068190068 7:0.014581122 +-1 1:0.790576 2:0.005236 3:0.015707 7:0.016856085 8:0.023809524 +-1 1:0.708861 2:0.012658 3:0.126582 4:0.0073800738 7:0.018832976 +-1 1:0.721698 3:0.09434 7:0.016624482 8:0.023809524 +-1 1:0.728261 3:0.043478 4:0.011070111 7:0.012062567 +-1 1:0.742424 3:0.030303 4:0.0036900369 7:0.011640799 +-1 1:0.788079 7:0.014173799 8:0.023809524 +-1 1:0.757812 7:0.012814402 +-1 1:0.735294 2:0.029412 3:0.029412 5:0.11295156 7:0.011836439 +-1 1:0.857143 3:0.02381 7:0.020905921 +-1 1:1 7:0.045731707 +-1 1:0.758065 2:0.048387 3:0.032258 6:0.046752047 7:0.018931945 +-1 1:0.663636 2:0.072727 3:0.090909 5:0.16941989 7:0.017073171 +-1 1:0.742424 2:0.045455 3:0.045455 5:0.081470935 7:0.016906872 +-1 1:0.782609 3:0.043478 7:0.015111348 +-1 1:0.790323 2:0.016129 3:0.032258 5:0.040515558 7:0.018095988 +-1 1:0.73913 3:0.065217 4:0.0036900369 7:0.016436902 +-1 1:0.765101 3:0.04698 4:0.011070111 7:0.015796366 8:0.047619048 +-1 1:0.752212 2:0.00885 3:0.00885 7:0.014623354 +-1 1:0.575 2:0.0375 3:0.2125 5:0.096812428 7:0.017606707 +-1 1:0.652174 2:0.043478 3:0.173913 4:0.0036900369 5:0.1183263 7:0.016702012 +-1 1:0.761194 2:0.014925 3:0.014925 7:0.012832183 +-1 1:0.759259 3:0.064815 7:0.017050585 +-1 1:0.740132 2:0.049342 3:0.019737 5:0.055454505 6:0.0095640096 7:0.01887436 +-1 1:0.773196 3:0.030928 7:0.014018104 +-1 1:0.680412 2:0.046392 3:0.103093 5:0.058197785 7:0.022142945 8:0.071428571 +-1 1:0.81407 3:0.005025 7:0.016454226 +-1 1:0.782297 3:0.007177 7:0.012909909 +-1 1:0.8 2:0.075 3:0.075 5:0.020254052 7:0.056097561 +-1 1:0.740458 2:0.007634 3:0.061069 4:0.0036900369 7:0.014941354 +-1 1:0.786517 3:0.033708 7:0.016031793 +-1 1:0.782258 3:0.016129 7:0.014162079 8:0.023809524 +-1 1:0.748744 2:0.030151 3:0.035176 5:0.025054791 7:0.018231402 +-1 1:0.794479 3:0.015337 7:0.016253927 +-1 1:0.682119 2:0.066225 3:0.039735 4:0.0073800738 5:0.1495162 6:0.0085950086 7:0.014093037 +-1 1:0.767742 3:0.022581 7:0.014929189 8:0.095238095 +-1 1:0.8 7:0.013597561 +-1 1:0.814815 2:0.018519 3:0.018519 7:0.046183378 +-1 1:0.698413 2:0.027778 3:0.051587 5:0.025352974 6:0.015306015 7:0.01422764 8:0.071428571 +-1 1:0.738095 3:0.095238 7:0.019744482 +-1 1:0.736842 2:0.008772 3:0.04386 4:0.0036900369 7:0.01422764 8:0.023809524 +-1 1:0.767442 2:0.015504 3:0.031008 5:0.018546956 7:0.019001701 8:0.047619048 +-1 1:0.692841 2:0.050808 3:0.036952 5:0.040515558 6:0.027174027 7:0.015546671 8:0.047619048 +-1 1:0.795181 3:0.014458 7:0.017749043 +-1 1:0.810811 3:0.027027 7:0.017139091 +-1 1:0.697211 2:0.083665 3:0.079681 5:0.1729608 7:0.020940628 +-1 1:0.72 2:0.02 3:0.06 5:0.043847748 7:0.020731707 +-1 1:0.736842 3:0.105263 7:0.016046213 8:0.023809524 +-1 1:0.666667 2:0.078431 3:0.039216 5:0.15423494 7:0.017336201 +-1 1:0.64257 2:0.100402 3:0.076305 4:0.0036900369 5:0.043236474 6:0.052203052 7:0.021108823 8:0.047619048 +-1 1:0.764706 3:0.058824 7:0.012195122 8:0.047619048 +-1 1:0.757143 2:0.014286 7:0.012282232 8:0.023809524 +-1 1:0.782609 2:0.014493 7:0.012283494 8:0.023809524 +-1 1:0.678832 2:0.065693 3:0.051095 5:0.083655122 6:0.011223011 7:0.017847604 8:0.095238095 +-1 1:0.634146 2:0.073171 3:0.121951 5:0.099391708 7:0.022308152 +-1 1:0.745387 2:0.04797 3:0.01476 5:0.11549357 7:0.015975159 8:0.071428571 +-1 1:0.742857 3:0.057143 7:0.015331012 +-1 1:0.6875 3:0.145833 7:0.01575203 +-1 1:0.767857 3:0.026786 7:0.013773957 +-1 1:0.723684 3:0.092105 7:0.014602055 +-1 1:0.709402 3:0.008547 7:0.011100689 +-1 1:0.741935 3:0.032258 4:0.0036900369 7:0.017014165 8:0.023809524 +-1 1:0.786885 3:0.057377 4:0.0073800738 7:0.020191927 +-1 1:0.68 3:0.12 7:0.017317073 +-1 1:0.793103 3:0.034483 7:0.01471825 +-1 1:0.785992 2:0.003891 3:0.003891 5:0.010115844 7:0.017486 +-1 1:0.770878 3:0.029979 7:0.015211262 +-1 1:0.809091 3:0.045455 7:0.021895787 8:0.023809524 +-1 1:0.741935 3:0.064516 7:0.014162079 +-1 1:0.736842 3:0.105263 7:0.014120665 +-1 1:0.785714 3:0.011905 7:0.013429152 8:0.023809524 +-1 1:0.634921 2:0.031746 3:0.126984 4:0.018450185 5:0.050713402 7:0.01422764 +-1 1:0.652174 2:0.043478 3:0.057971 6:0.043164043 7:0.012283494 8:0.023809524 +-1 1:0.745763 2:0.016949 3:0.033898 5:0.058235057 7:0.01322861 +-1 1:0.637168 2:0.035398 3:0.115044 4:0.018450185 5:0.026717159 7:0.015055043 +-1 1:0.79562 2:0.00365 3:0.021898 5:0.0097058429 7:0.017090976 +-1 1:0.774775 3:0.018018 7:0.013128982 +-1 1:0.742268 2:0.010309 3:0.041237 5:0.030548805 7:0.015338195 +-1 1:0.746835 2:0.021097 3:0.033755 5:0.012985851 6:0.01045201 7:0.014767933 8:0.047619048 +-1 1:0.753027 2:0.007264 3:0.058111 4:0.0036900369 5:0.0063736526 6:0.0051270051 7:0.017273963 +-1 1:0.758794 3:0.060302 7:0.015657555 +-1 1:0.746835 3:0.012658 7:0.017443652 8:0.047619048 +-1 1:0.7 3:0.1 4:0.0036900369 7:0.012195122 +-1 1:0.798643 2:0.002262 3:0.011312 7:0.015478421 8:0.023809524 +-1 1:0.730159 2:0.047619 3:0.02381 5:0.055424687 6:0.0055770056 7:0.026035616 +-1 1:0.777778 7:0.011065945 +-1 1:0.742574 2:0.039604 5:0.034350633 6:0.027651028 7:0.013100701 +-1 1:0.780488 3:0.04878 7:0.014872098 +-1 1:0.780952 7:0.015621372 +-1 1:0.678571 3:0.071429 7:0.017421604 +-1 1:0.743902 2:0.04878 3:0.060976 5:0.023742788 6:0.028662029 7:0.023349195 +-1 1:0.737288 2:0.016949 3:0.067797 4:0.0036900369 7:0.024648616 +-1 1:0.681818 2:0.090909 3:0.045455 6:0.046155046 7:0.018015518 +-1 1:0.776316 3:0.026316 7:0.014602055 +-1 1:0.813471 7:0.015512445 8:0.023809524 +-1 1:0.72807 2:0.026316 3:0.035088 5:0.047179938 7:0.016902012 +-1 1:0.789899 3:0.008081 7:0.014560238 +-1 1:0.770538 2:0.031161 3:0.008499 5:0.06862672 6:0.0034530035 7:0.015010707 +-1 1:0.792 7:0.013902439 8:0.023809524 +-1 1:0.731707 2:0.02439 3:0.02439 7:0.013682329 8:0.023809524 +-1 1:0.555556 2:0.055556 3:0.111111 5:0.24046934 7:0.010501354 +-1 1:0.776699 7:0.01296472 +-1 1:0.760163 2:0.012195 3:0.02439 5:0.038227006 6:0.0051270051 7:0.014500299 +-1 1:0.783626 2:0.011696 3:0.011696 5:0.015863313 7:0.016759378 8:0.023809524 +-1 1:0.8 7:0.013445902 8:0.023809524 +-1 1:0.792793 3:0.013514 7:0.016479896 8:0.023809524 +-1 1:0.788177 2:0.009852 3:0.009852 5:0.015155129 7:0.014778323 +-1 1:0.807339 3:0.027523 7:0.017957037 +-1 1:0.775 3:0.01875 7:0.013490854 +-1 1:0.802632 3:0.013158 7:0.013960207 +-1 1:0.693333 2:0.026667 3:0.073333 4:0.0073800738 6:0.026706027 7:0.013699189 +-1 1:0.732143 2:0.035714 3:0.017857 6:0.040542041 7:0.016114982 +-1 1:0.766055 2:0.03211 3:0.018349 5:0.075298555 7:0.016614457 +-1 1:0.774194 7:0.012195122 8:0.047619048 +-1 1:0.647059 3:0.117647 4:0.018450185 7:0.015901482 8:0.023809524 +-1 1:0.733333 3:0.066667 7:0.01382114 8:0.047619048 +-1 1:0.637931 2:0.086207 3:0.051724 5:0.27107778 7:0.011564341 8:0.023809524 +-1 1:0.714628 2:0.031175 3:0.064748 5:0.060441608 7:0.016230915 8:0.095238095 +-1 1:0.771689 3:0.027397 7:0.01422764 8:0.095238095 +-1 1:0.733333 3:0.1 4:0.0073800738 7:0.032994579 +-1 1:0.766234 3:0.045455 4:0.0036900369 7:0.017025659 +-1 1:0.815789 7:0.014762518 +-1 1:0.75 2:0.071429 7:0.016986061 +-1 1:0.775 3:0.066667 4:0.011070111 7:0.020630079 8:0.023809524 +-1 1:0.777778 2:0.022222 7:0.01395664 8:0.023809524 +-1 1:0.671642 2:0.014925 3:0.149254 4:0.025830258 7:0.018110665 +-1 1:0.740741 3:0.037037 7:0.013550134 +-1 1:0.6875 2:0.015625 3:0.0625 7:0.015148628 +-1 1:0.8 7:0.013482384 +-1 1:0.65 2:0.2 3:0.025 5:0.18543974 6:0.014925015 7:0.030640244 +-1 1:0.792793 3:0.009009 7:0.014804439 +-1 1:0.766447 3:0.026316 7:0.014943037 +-1 1:0.757143 2:0.016327 3:0.018367 4:0.0036900369 5:0.036780821 7:0.015131909 8:0.11904762 +-1 1:0.805556 7:0.012533878 +-1 1:0.790323 7:0.012391817 +-1 1:0.78481 2:0.025316 3:0.025316 5:0.063714162 7:0.018061128 +-1 1:0.692308 3:0.134615 4:0.011070111 7:0.017002811 8:0.023809524 +-1 1:0.833333 7:0.01422764 +-1 1:0.754237 2:0.016949 3:0.029661 5:0.013291488 7:0.014494628 +-1 1:0.688889 2:0.048148 3:0.081481 5:0.052644134 6:0.021186021 7:0.015989159 +-1 1:0.647059 2:0.014706 3:0.117647 4:0.0073800738 5:0.027007887 7:0.024748927 +-1 1:0.805556 7:0.012872628 +-1 1:0.74026 3:0.038961 7:0.013963677 8:0.047619048 +-1 1:0.666667 3:0.137255 4:0.0073800738 7:0.01566236 8:0.023809524 +-1 1:0.768519 7:0.013719512 8:0.023809524 +-1 1:0.796875 3:0.015625 7:0.013910061 +-1 1:0.824074 2:0.009259 3:0.009259 5:0.02412297 7:0.017445799 +-1 1:0.742857 3:0.057143 7:0.012804878 +-1 1:0.75188 3:0.067669 7:0.017673756 +-1 1:0.776 3:0.032 7:0.014682927 +-1 1:0.787234 7:0.012065384 +-1 1:0.711538 2:0.038462 3:0.134615 4:0.011070111 5:0.027507343 7:0.031777671 8:0.023809524 +-1 1:0.652174 2:0.07971 3:0.065217 5:0.018002773 6:0.050724051 7:0.018292683 8:0.047619048 +-1 1:0.744186 3:0.116279 4:0.014760148 7:0.022688598 +-1 1:0.712121 2:0.060606 3:0.075758 5:0.1090901 7:0.018939396 +-1 1:0.673077 2:0.038462 3:0.096154 4:0.0036900369 5:0.064824892 6:0.052173052 7:0.013484994 +-1 1:0.830189 7:0.015301427 8:0.023809524 +-1 1:0.837838 7:0.015491098 +-1 1:0.730496 2:0.049645 3:0.024823 5:0.14230763 6:0.0044040044 7:0.014724963 +-1 1:0.776119 2:0.007463 3:0.029851 5:0.022728967 7:0.014925372 +-1 1:0.698925 2:0.043011 3:0.064516 5:0.053098862 6:0.017094017 7:0.01534225 +-1 1:0.818182 7:0.013620524 +-1 1:0.759399 3:0.041353 4:0.0036900369 7:0.014877134 8:0.023809524 +-1 1:0.666667 2:0.172222 3:0.088889 4:0.029520295 6:0.02952303 7:0.089498646 +-1 1:0.64 2:0.06 3:0.06 6:0.081081081 7:0.013536585 +-1 1:0.762712 7:0.012711866 8:0.047619048 +-1 1:0.733333 7:0.0087398354 8:0.023809524 +-1 1:0.709091 2:0.054545 3:0.109091 5:0.066859988 7:0.024722835 +-1 1:0.792308 3:0.015385 7:0.014212006 +-1 1:0.707071 3:0.020202 4:0.0036900369 7:0.01084011 8:0.023809524 +-1 1:0.736842 2:0.037594 3:0.022556 5:0.061775975 6:0.0082860083 7:0.016596372 8:0.047619048 +-1 1:0.875 3:0.125 7:0.17378049 +-1 1:0.756757 7:0.018457482 +-1 1:0.795775 2:0.011737 3:0.00939 6:0.010677011 7:0.016088402 +-1 1:0.778947 7:0.015211811 8:0.047619048 +-1 1:0.793103 3:0.024341 7:0.017340323 +-1 1:0.748062 2:0.05814 3:0.042636 5:0.061798339 6:0.0093270093 7:0.022806768 +-1 1:0.750567 3:0.052154 4:0.0036900369 7:0.017186549 +-1 1:0.590643 2:0.140351 3:0.05848 4:0.014760148 5:0.23918715 6:0.12032112 7:0.013336189 8:0.047619048 +-1 1:0.823529 7:0.016857963 +-1 1:0.833333 7:0.017421604 8:0.023809524 +-1 1:0.745763 3:0.084746 7:0.015812317 8:0.023809524 +-1 1:0.685714 3:0.085714 7:0.011498256 8:0.023809524 +-1 1:0.772727 3:0.020202 7:0.013642524 8:0.023809524 +-1 1:0.692308 2:0.030769 3:0.061538 7:0.013320823 +-1 1:0.793103 3:0.051724 7:0.019343988 8:0.023809524 +-1 1:0.72 3:0.16 7:0.01902439 8:0.023809524 +-1 1:0.706107 2:0.068702 3:0.072519 5:0.066785443 6:0.023517024 7:0.020782909 +-1 1:0.71134 2:0.041237 3:0.072165 6:0.02000102 7:0.018858433 +-1 1:0.814815 7:0.017615177 +-1 1:0.709677 3:0.193548 4:0.0073800738 7:0.03147128 +-1 1:0.894737 7:0.021181 +-1 1:0.711111 3:0.111111 7:0.016531165 +-1 1:0.809045 2:0.002513 5:0.0076036557 7:0.015014098 8:0.023809524 +-1 1:0.73 2:0.03 3:0.07 5:0.055842142 7:0.016280488 +-1 1:0.809524 7:0.012630665 +-1 1:0.833333 7:0.015389079 8:0.023809524 +-1 1:0.638298 2:0.12766 3:0.095745 4:0.011070111 5:0.020090051 6:0.064689065 7:0.024065909 +-1 1:0.785714 7:0.010017421 8:0.047619048 +-1 1:0.742424 2:0.030303 3:0.090909 7:0.024113079 +-1 1:0.803279 3:0.065574 4:0.011070111 7:0.024290287 +-1 1:0.734767 3:0.064516 7:0.017003232 +-1 1:0.734767 3:0.064516 7:0.016937671 +-1 1:0.792079 2:0.009901 5:0.030548805 7:0.014730744 +-1 1:0.776699 3:0.019417 7:0.016102299 +-1 1:0.76699 7:0.011011128 8:0.023809524 +-1 1:0.772201 3:0.034749 7:0.016291555 +-1 1:0.842105 7:0.020218226 8:0.023809524 +-1 1:0.792208 7:0.013541335 8:0.071428571 +-1 1:0.609195 2:0.195402 5:0.037086458 6:0.17910318 7:0.01408747 +-1 1:0.705882 3:0.176471 7:0.018651366 +-1 1:0.757282 3:0.019417 7:0.013083116 8:0.023809524 +-1 1:0.75 3:0.125 4:0.0036900369 7:0.020579268 +-1 1:0.759494 2:0.012658 3:0.050633 4:0.0036900369 5:0.033426267 7:0.017212104 8:0.023809524 +-1 1:0.7 3:0.091667 7:0.014430896 +-1 1:0.803571 4:0.0036900369 7:0.015810104 +-1 1:0.755556 3:0.05 7:0.014397018 +-1 1:0.742857 2:0.019048 3:0.071429 4:0.0073800738 5:0.031018443 6:0.0041610042 7:0.020934957 8:0.047619048 +-1 1:0.734177 3:0.050633 4:0.0036900369 7:0.013430073 8:0.023809524 +-1 1:0.710843 2:0.012048 3:0.036145 4:0.0073800738 7:0.015721421 8:0.023809524 +-1 1:0.791667 7:0.010924799 +-1 1:0.805556 7:0.013550134 +-1 1:0.698413 2:0.015873 3:0.015873 5:0.065391439 7:0.011033683 +-1 1:0.80303 3:0.015152 7:0.014689579 +-1 1:0.697842 2:0.064748 3:0.057554 5:0.033060993 6:0.013305013 7:0.019784171 +-1 1:0.757576 3:0.022727 7:0.012472287 8:0.047619048 +-1 1:0.759162 2:0.010471 3:0.04712 5:0.013194579 7:0.018037287 +-1 1:0.695652 2:0.01087 3:0.097826 7:0.015509012 +-1 1:0.764151 2:0.037736 3:0.037736 4:0.0073800738 6:0.026163026 7:0.019788311 +-1 1:0.742424 3:0.045455 7:0.012102732 +-1 1:0.71831 2:0.042254 3:0.056338 7:0.014513915 +-1 1:0.795455 7:0.012195122 8:0.023809524 +-1 1:0.774775 3:0.045045 4:0.011070111 7:0.015600963 +-1 1:0.8 7:0.010731707 +-1 1:0.793651 2:0.047619 3:0.015873 5:0.058928332 6:0.011859012 7:0.02448703 +-1 1:0.757576 2:0.045455 3:0.015152 5:0.055633414 6:0.011193011 7:0.024759793 +-1 1:0.714286 2:0.054422 3:0.061224 4:0.011070111 6:0.045000045 7:0.016592 +-1 1:0.535714 2:0.169643 3:0.142857 4:0.04797048 5:0.287366 7:0.024009146 +-1 1:0.746988 3:0.060241 4:0.011070111 7:0.016456067 8:0.047619048 +-1 1:0.790123 3:0.028807 7:0.016661646 8:0.023809524 +-1 1:0.675325 2:0.077922 3:0.064935 6:0.076530077 7:0.015521067 +-1 1:0.75 2:0.055556 7:0.01388889 +-1 1:0.769784 2:0.007194 3:0.032374 4:0.0073800738 7:0.01566064 +-1 1:0.744792 3:0.03125 7:0.01378303 +-1 1:0.75 7:0.0087652439 +-1 1:0.714286 2:0.017857 3:0.053571 7:0.012630665 +-1 1:0.771429 7:0.010801396 +-1 1:0.809524 7:0.013066201 +-1 1:0.713768 2:0.014493 3:0.050725 5:0.040075738 7:0.012327677 8:0.023809524 +-1 1:0.794118 7:0.012912482 +-1 1:0.75 3:0.035714 7:0.0108885 8:0.023809524 +-1 1:0.794118 3:0.088235 7:0.028873744 +-1 1:0.78125 7:0.01086128 +-1 1:0.78125 3:0.03125 7:0.014291159 +-1 1:0.748201 2:0.028777 3:0.043165 5:0.061105065 7:0.016055451 +-1 1:0.712644 2:0.011494 3:0.057471 7:0.012966079 +-1 1:0.782609 3:0.021739 7:0.015509012 8:0.023809524 +-1 1:0.773333 3:0.04 7:0.01902439 +-1 1:0.784091 3:0.028409 4:0.018450185 7:0.016006098 8:0.047619048 +-1 1:0.789474 2:0.017544 3:0.017544 7:0.016153189 +-1 1:0.8125 7:0.014862805 +-1 1:0.730337 3:0.067416 7:0.013222799 +-1 1:0.753846 7:0.014071293 +-1 1:0.726457 3:0.085202 7:0.017089579 8:0.071428571 +-1 1:0.760479 3:0.047904 7:0.01635753 +-1 1:0.619048 2:0.126984 3:0.047619 6:0.11029511 7:0.013162988 +-1 1:0.776923 3:0.023077 7:0.014165104 +-1 1:0.722892 3:0.120482 4:0.033210332 7:0.021525122 +-1 1:0.7625 3:0.025 7:0.01402439 8:0.023809524 +-1 1:0.72549 2:0.052288 3:0.045752 5:0.069506359 7:0.017097079 +-1 1:0.778802 3:0.018433 7:0.013600091 +-1 1:0.735849 3:0.037736 7:0.011792451 +-1 1:0.7 2:0.036364 3:0.072727 7:0.015410201 8:0.023809524 +-1 1:0.727273 2:0.022727 3:0.022727 5:0.086681675 7:0.011917957 8:0.023809524 +-1 1:0.785714 7:0.0108885 +-1 1:0.742268 2:0.010309 3:0.082474 4:0.014760148 5:0.022184784 7:0.021121445 +-1 1:0.79661 7:0.012815213 +-1 1:0.662162 2:0.040541 3:0.040541 6:0.046155046 7:0.010711933 8:0.047619048 +-1 1:0.801282 7:0.015478421 +-1 1:0.653846 3:0.115385 4:0.014760148 7:0.01477486 +-1 1:0.655738 2:0.04918 3:0.147541 4:0.036900369 5:0.055320323 7:0.026939226 8:0.023809524 +-1 1:0.826087 7:0.015906683 8:0.023809524 +-1 1:0.743243 3:0.027027 7:0.012579652 +-1 1:0.765957 2:0.021277 6:0.021054021 7:0.018487287 8:0.047619048 +-1 1:0.765957 3:0.085106 4:0.0073800738 7:0.021600933 +-1 1:0.58371 2:0.117647 3:0.108597 5:0.035215362 6:0.066141066 7:0.01752014 +-1 1:0.709677 2:0.048387 5:0.049043579 6:0.01973702 7:0.01494886 +-1 1:0.588235 2:0.137255 3:0.098039 5:0.056908145 6:0.13740614 7:0.01566236 +-1 1:0.744792 2:0.046875 3:0.026042 5:0.12245613 7:0.015466207 +-1 1:0.707094 2:0.043478 3:0.002288 5:0.042215198 7:0.012320701 +-1 1:0.75 2:0.035714 7:0.011541811 +-1 1:0.7 7:0.0093495915 +-1 1:0.65625 3:0.03125 7:0.014481707 +-1 1:0.666667 3:0.1 7:0.025609756 +-1 1:0.733333 3:0.053333 7:0.012439024 +-1 1:0.770992 3:0.030534 7:0.015034445 +-1 1:0.73516 2:0.050228 3:0.013699 5:0.068142173 6:0.016452016 7:0.015229982 8:0.11904762 +-1 1:0.714286 3:0.122449 7:0.01941264 +-1 1:0.813953 7:0.015598415 +-1 1:0.706667 2:0.033333 3:0.046667 5:0.023220968 7:0.01304878 +-1 1:0.810345 3:0.034483 7:0.024390244 +-1 1:0.707317 2:0.02439 3:0.073171 4:0.0036900369 7:0.014425939 8:0.023809524 +-1 1:0.792 3:0.024 7:0.015853659 +-1 1:0.735043 2:0.025641 3:0.034188 5:0.055014685 7:0.014123409 +-1 1:0.684211 2:0.105263 3:0.039474 4:0.025830258 6:0.073320073 7:0.019696726 8:0.047619048 +-1 1:0.798851 3:0.014368 7:0.017066165 +-1 1:0.7875 7:0.014329268 8:0.023809524 +-1 1:0.816667 7:0.018394311 8:0.023809524 +-1 1:0.639456 2:0.027211 3:0.108844 4:0.0036900369 6:0.016761017 7:0.014849841 +-1 1:0.78 7:0.011463415 +-1 1:0.88961 3:0.058442 4:0.062730627 7:0.11508157 +-1 1:0.755906 3:0.07874 7:0.018964854 8:0.023809524 +-1 1:0.684932 2:0.123288 3:0.013699 6:0.11111111 7:0.015786835 +-1 1:0.762411 3:0.035461 4:0.0073800738 7:0.014660091 8:0.071428571 +-1 1:0.701031 2:0.051546 3:0.113402 5:0.063356343 6:0.025497025 7:0.022190091 +-1 1:0.685714 3:0.085714 4:0.0073800738 7:0.01811847 +-1 1:1 7:0.12804878 +-1 1:0.989899 7:0.1583518 +-1 1:0.923077 3:0.076923 7:0.042682927 +-1 1:0.640625 2:0.296875 3:0.03125 5:0.010048753 6:0.060648061 7:0.070693598 +-1 1:0.666667 2:0.070175 3:0.035088 5:0.09165387 7:0.026101841 +-1 1:0.779661 2:0.033898 3:0.033898 5:0.085198217 7:0.018085988 +-1 1:0.746835 2:0.044304 3:0.025316 6:0.048387048 7:0.01435628 +-1 1:0.742972 2:0.028112 3:0.032129 5:0.031905536 6:0.0085590086 7:0.017166226 +-1 1:0.791139 3:0.044304 4:0.014760148 7:0.021032726 +-1 1:0.945946 7:0.065589982 +-1 1:0.809524 7:0.015679445 8:0.023809524 +-1 1:0.766667 2:0.1 4:0.018450185 5:0.063177434 6:0.025425025 7:0.023983738 +-1 1:0.821622 7:0.028543177 +-1 1:0.714286 3:0.061224 7:0.014683921 +-1 1:0.762857 2:0.04 3:0.051429 6:0.018354018 7:0.025627177 +-1 1:0.766571 2:0.011527 3:0.060519 4:0.0036900369 5:0.026113339 7:0.020067476 +-1 1:0.8 3:0.05 7:0.016158537 +-1 1:0.779141 2:0.01227 5:0.040075738 7:0.013915909 +-1 1:0.734767 2:0.021505 3:0.046595 5:0.05647578 7:0.014424335 +-1 1:0.730159 2:0.039683 3:0.039683 5:0.058235057 6:0.015624016 7:0.018583043 8:0.047619048 +-1 1:0.585034 2:0.176871 3:0.013605 5:0.49383508 7:0.013149165 +-1 1:0.606742 2:0.191011 3:0.05618 6:0.12828913 7:0.020827622 +-1 1:0.796875 7:0.019435976 8:0.071428571 +-1 1:0.752577 2:0.030928 3:0.010309 4:0.0036900369 5:0.059875062 6:0.012048012 7:0.0156525 +-1 1:0.846154 7:0.012195122 +-1 1:0.814815 7:0.019271305 +-1 1:0.690476 2:0.095238 3:0.071429 5:0.14713074 6:0.01973702 7:0.022067366 +-1 1:0.666667 2:0.133333 4:0.0036900369 6:0.05000105 7:0.024390244 +-1 1:0.433333 2:0.266667 3:0.1 5:0.46591028 6:0.093750094 7:0.013008128 +-1 1:0.764103 2:0.025641 3:0.028205 4:0.0036900369 5:0.06341598 7:0.016541591 8:0.023809524 +-1 1:0.758621 7:0.0092514695 8:0.047619048 +-1 1:0.857143 7:0.01633275 +-1 1:0.772727 3:0.090909 4:0.0036900369 7:0.01773836 +-1 1:0.714894 2:0.046809 3:0.051064 5:0.035610454 6:0.019107019 7:0.016294756 +-1 1:0.797101 7:0.013609049 8:0.047619048 +-1 1:0.736842 2:0.023392 3:0.040936 5:0.038927735 7:0.01365711 8:0.023809524 +-1 1:0.787356 7:0.013176335 +-1 1:0.692308 2:0.100592 3:0.047337 5:0.013962399 6:0.061797062 7:0.019266848 +-1 1:0.698276 2:0.034483 3:0.077586 5:0.077922562 7:0.015086207 8:0.023809524 +-1 1:0.759259 7:0.01129178 8:0.023809524 +-1 1:0.772727 3:0.045455 7:0.011917957 +-1 1:0.681159 2:0.043478 3:0.028986 5:0.050027582 6:0.04026904 7:0.013167195 8:0.023809524 +-1 1:0.742647 3:0.044118 4:0.025830258 7:0.013069402 +-1 1:0.62069 2:0.137931 3:0.058621 5:0.036676457 6:0.092250092 7:0.017094195 +-1 1:0.690909 2:0.018182 3:0.190909 4:0.066420664 5:0.019240231 7:0.042960091 +-1 1:0.842105 7:0.013157896 +-1 1:0.791045 2:0.044776 3:0.029851 5:0.028021708 6:0.011277011 7:0.024208226 +-1 1:0.8 7:0.012840744 8:0.023809524 +-1 1:0.78 3:0.04 7:0.013292683 +-1 1:0.641026 2:0.051282 3:0.076923 5:0.17539845 7:0.013289555 +-1 1:0.619048 2:0.126984 3:0.058201 4:0.0073800738 5:0.14879311 6:0.065868066 7:0.016163378 8:0.023809524 +-1 1:0.745614 2:0.008772 3:0.070175 7:0.01636714 +-1 1:0.791667 3:0.125 7:0.038617884 +-1 1:0.57 2:0.13 3:0.08 4:0.0073800738 5:0.039971374 6:0.064344064 7:0.022743902 +-1 1:0.725806 3:0.048387 7:0.019374506 8:0.071428571 +-1 1:0.88 2:0.04 5:0.063714162 7:0.028536585 +-1 1:0.852941 7:0.017306311 +-1 1:0.810811 3:0.108108 4:0.011070111 7:0.035926171 +-1 1:0.727273 3:0.066116 7:0.01637775 +-1 1:0.712329 2:0.041096 3:0.054795 6:0.035502036 7:0.014116268 +-1 1:0.75 2:0.053571 5:0.07958493 6:0.021351021 7:0.015298348 +-1 1:0.823529 7:0.012195122 +-1 1:0.729412 3:0.058824 7:0.016786226 +-1 1:0.781609 7:0.01198486 +-1 1:0.572755 2:0.182663 3:0.080495 4:0.022140221 5:0.054925231 6:0.12000012 7:0.017934 +-1 1:0.639344 2:0.147541 3:0.016393 6:0.14724015 7:0.016293482 +-1 1:0.8 3:0.016667 7:0.014837396 +-1 1:0.516129 2:0.354839 3:0.064516 4:0.0036900369 5:0.14244182 6:0.15286515 7:0.030881195 +-1 1:0.75 3:0.107143 7:0.021123695 +-1 1:0.823529 3:0.058824 4:0.0036900369 7:0.021700146 +-1 1:0.8125 3:0.0625 7:0.016768293 +-1 1:0.774648 3:0.028169 7:0.013139817 +-1 1:0.666667 2:0.087719 3:0.070175 5:0.19114249 7:0.016688061 +-1 1:0.789809 7:0.015069134 +-1 1:0.690909 3:0.036364 7:0.02450111 +-1 1:0.758065 2:0.048387 3:0.016129 5:0.14335873 7:0.01534225 +-1 1:0.709677 3:0.064516 7:0.044059793 +-1 1:0.869565 7:0.018292683 +-1 1:0.724138 3:0.034483 7:0.020395293 +-1 1:0.746988 3:0.072289 7:0.01652953 +-1 1:0.72093 3:0.069767 7:0.011911512 +-1 1:0.7 2:0.1 6:0.06976807 7:0.013109756 +-1 1:0.765432 2:0.024691 6:0.018405018 7:0.012270402 +-1 1:0.75 2:0.016667 5:0.063714162 7:0.011890244 8:0.047619048 +-1 1:0.866667 7:0.01422764 +-1 1:0.888889 3:0.111111 7:0.057926829 +-1 1:0.683673 2:0.040816 3:0.142857 4:0.0073800738 5:0.058085966 7:0.023954701 +-1 1:0.676768 2:0.050505 3:0.060606 5:0.13960163 7:0.016444939 8:0.11904762 +-1 1:0.684211 3:0.105263 7:0.012676506 +-1 1:0.8 7:0.010731707 +-1 1:0.740741 2:0.037037 3:0.018519 7:0.011969287 8:0.023809524 +-1 1:0.75 3:0.0625 7:0.028010671 +-1 1:0.708333 3:0.041667 7:0.016768293 +-1 1:0.743802 2:0.033058 3:0.041322 5:0.060441608 7:0.018645433 +-1 1:0.717391 2:0.043478 3:0.043478 7:0.012857902 +-1 1:1 7:0.048780488 +-1 1:0.820895 2:0.014925 5:0.035923546 7:0.018884238 8:0.047619048 +-1 1:0.782857 2:0.017143 3:0.017143 5:0.048514305 7:0.01606272 +-1 1:0.65625 2:0.1875 3:0.03125 5:0.20012524 6:0.02013302 7:0.028391768 +-1 1:0.769231 2:0.076923 3:0.076923 7:0.0272045 +-1 1:0.788618 3:0.081301 7:0.0269185 +-1 1:0.653846 3:0.153846 4:0.0036900369 7:0.034474671 +-1 1:0.714286 3:0.122449 7:0.018541561 8:0.023809524 +-1 1:0.5 2:0.388889 3:0.055556 5:0.073807642 6:0.14851515 7:0.034214091 +-1 1:0.823529 7:0.014347201 +-1 1:0.721854 2:0.033113 3:0.039735 6:0.028572029 7:0.012720079 +-1 1:0.714286 7:0.01480836 8:0.023809524 +-1 1:0.72 3:0.12 7:0.016585366 +-1 1:0.805195 3:0.051948 7:0.021301866 +-1 1:0.692308 7:0.020168854 +-1 1:0.675 3:0.1 4:0.0036900369 7:0.013414634 +-1 1:0.655844 2:0.006494 3:0.136364 7:0.015600256 +-1 1:0.590308 2:0.22467 3:0.052863 5:0.06545853 6:0.10692011 7:0.026001933 +-1 1:0.697143 2:0.045714 3:0.051429 5:0.084519852 7:0.015365854 +-1 1:0.659341 2:0.035714 3:0.112637 4:0.0036900369 5:0.0076931105 6:0.0092880093 7:0.016232244 8:0.023809524 +-1 1:0.843137 7:0.017455762 +-1 1:0.781609 3:0.022989 7:0.01794225 +-1 1:0.676056 2:0.119718 3:0.028169 6:0.1031941 7:0.017476811 +-1 1:0.8 3:0.044444 7:0.018563689 +-1 1:0.853659 7:0.016805476 +-1 1:0.707424 2:0.056769 3:0.008734 5:0.1482042 7:0.013393335 +-1 1:0.791045 3:0.01194 7:0.015089189 8:0.047619048 +-1 1:0.79661 7:0.012505171 +-1 1:0.831776 7:0.016697061 +-1 1:0.85 7:0.017378049 8:0.023809524 +-1 1:0.766667 3:0.066667 4:0.0036900369 7:0.01382114 +-1 1:0.84 7:0.014390244 +-1 1:0.737179 3:0.051282 4:0.011070111 7:0.014618512 8:0.071428571 +-1 1:0.666667 3:0.166667 7:0.018229165 +-1 1:0.827586 7:0.013036165 8:0.047619048 +-1 1:0.722222 7:0.017953927 +-1 1:0.714286 2:0.004608 3:0.0553 7:0.012644713 +-1 1:0.789474 7:0.011232348 +-1 1:0.745763 3:0.084746 4:0.033210332 7:0.018137659 +-1 1:0.732057 2:0.023923 3:0.052632 4:0.0036900369 5:0.027060069 6:0.0054450054 7:0.01607539 8:0.047619048 +-1 1:0.785714 3:0.035714 7:0.018183799 8:0.047619048 +-1 1:0.725806 2:0.048387 3:0.032258 6:0.041097041 7:0.014358774 8:0.023809524 +-1 1:0.702247 2:0.039326 3:0.044944 5:0.063535253 6:0.017046017 7:0.012058098 +-1 1:0.731959 2:0.046392 3:0.005155 5:0.10649591 6:0.0071430071 7:0.013200902 8:0.11904762 +-1 1:0.714286 3:0.071429 7:0.023954701 +-1 1:0.705882 3:0.117647 7:0.054878049 +-1 1:1 7:0.17378049 +-1 1:0.846154 2:0.051282 6:0.027396027 7:0.034240152 +-1 1:1 7:0.057926829 +-1 1:0.75 3:0.016667 7:0.01382114 8:0.023809524 +-1 1:0.752066 2:0.041322 3:0.016529 6:0.036810037 7:0.01642814 8:0.047619048 +-1 1:0.624114 2:0.099291 3:0.106383 4:0.011070111 5:0.10962682 6:0.044118044 7:0.017644006 +-1 1:0.831081 4:0.0036900369 7:0.019446274 8:0.023809524 +-1 1:0.67658 2:0.081784 3:0.04461 4:0.011070111 5:0.048961579 6:0.059112059 7:0.013804518 +-1 1:0.769231 3:0.038462 7:0.011491555 8:0.023809524 +-1 1:0.804878 2:0.012195 3:0.02439 6:0.0066090066 7:0.033759665 +-1 1:0.814815 7:0.014679317 +-1 1:0.8125 3:0.125 7:0.026676829 +-1 1:0.637931 2:0.051724 3:0.103448 4:0.0036900369 6:0.033897034 7:0.018608073 +-1 1:0.823848 2:0.00813 5:0.0057474692 6:0.0011580012 7:0.042848171 8:0.047619048 +-1 1:0.875 7:0.015243902 +-1 1:0.846154 7:0.018136335 +-1 1:0.666667 3:0.166667 4:0.0073800738 7:0.013550134 +-1 1:0.675676 2:0.027027 3:0.081081 6:0.044118044 7:0.011206329 +-1 1:0.740741 2:0.049383 3:0.049383 6:0.037815038 7:0.017916293 +-1 1:0.669565 2:0.078261 3:0.06087 6:0.062499062 7:0.015270415 +-1 1:0.692308 2:0.115385 6:0.17307617 7:0.012195122 +-1 1:0.668317 2:0.089109 3:0.09901 4:0.033210332 6:0.055488055 7:0.024480805 +-1 1:0.767857 7:0.011215159 8:0.071428571 +-1 1:0.769231 7:0.010084427 +-1 1:0.763889 3:0.083333 7:0.019139567 8:0.023809524 +-1 1:0.75 3:0.125 7:0.049288616 +-1 1:0.9 7:0.020121951 +-1 1:0.694915 2:0.008475 3:0.084746 4:0.0073800738 5:0.025531883 7:0.015088878 +-1 1:0.652632 2:0.126316 3:0.052632 4:0.0073800738 6:0.10546811 7:0.016431323 +-1 1:0.746377 2:0.07971 3:0.036232 4:0.0036900369 5:0.065108166 6:0.039300039 7:0.020236835 +-1 1:0.671053 2:0.085526 3:0.052632 4:0.0073800738 5:0.018636411 6:0.06000006 7:0.016046213 +-1 1:0.571429 2:0.122449 3:0.102041 4:0.0073800738 5:0.12706305 6:0.051135051 7:0.021901445 +-1 1:0.645161 2:0.032258 3:0.064516 7:0.010818256 +-1 1:0.68 7:0.0092682927 8:0.071428571 +-1 1:0.705882 2:0.047059 6:0.061224061 7:0.010545195 +-1 1:0.666667 2:0.133333 3:0.133333 5:0.13078288 7:0.023170732 +-1 1:0.666667 3:0.148148 4:0.011070111 7:0.012195122 +-1 1:0.810811 7:0.01252472 +-1 1:0.790323 3:0.032258 7:0.01681747 +-1 1:0.674419 3:0.162791 4:0.0073800738 7:0.01715825 +-1 1:0.735043 3:0.08547 4:0.0073800738 7:0.017615177 +-1 1:0.658228 2:0.037975 3:0.139241 4:0.022140221 5:0.065972895 7:0.017443652 +-1 1:0.829268 7:0.018813207 8:0.023809524 +-1 1:0.75 3:0.153846 7:0.056050652 +-1 1:0.818182 7:0.015243902 8:0.047619048 +-1 1:0.833333 7:0.013211384 8:0.023809524 +-1 1:0.763158 2:0.026316 3:0.026316 5:0.076849105 7:0.015564829 8:0.047619048 +-1 1:0.70922 2:0.028369 3:0.070922 6:0.022332022 7:0.01742778 +-1 1:0.75 3:0.0625 7:0.012195122 +-1 1:0.708861 3:0.088608 7:0.013352884 +-1 1:0.641509 2:0.132075 3:0.075472 4:0.0036900369 5:0.039650828 6:0.063831064 7:0.021629085 +-1 1:0.721311 3:0.114754 4:0.0036900369 7:0.017692921 8:0.023809524 +-1 1:0.75 3:0.083333 7:0.014481707 8:0.023809524 +-1 1:0.766423 3:0.034063 7:0.014138628 8:0.095238095 +-1 1:0.571429 2:0.186335 3:0.062112 5:0.060732336 6:0.12831013 7:0.018595671 +-1 1:0.702381 2:0.047619 3:0.107143 4:0.0036900369 5:0.067560717 7:0.024027293 +-1 1:0.52439 2:0.207317 3:0.060976 4:0.0073800738 5:0.69750123 7:0.012715646 +-1 1:0.787879 3:0.090909 4:0.0073800738 7:0.022357726 +-1 1:0.904762 7:0.021777006 +-1 1:0.833333 3:0.055556 7:0.018631439 +-1 1:0.723404 2:0.106383 3:0.06383 4:0.022140221 6:0.060915061 7:0.02555786 +-1 1:0.590909 2:0.136364 3:0.136364 5:0.37272822 7:0.016629713 +-1 1:0.725806 3:0.048387 7:0.011408341 8:0.047619048 +-1 1:0.794872 7:0.012273293 8:0.071428571 +-1 1:0.738462 2:0.030769 3:0.015385 4:0.0036900369 5:0.12220267 7:0.011444652 +-1 1:0.758621 3:0.051724 7:0.015454165 8:0.047619048 +-1 1:0.885714 7:0.029094079 +-1 1:0.813953 7:0.013542256 8:0.023809524 +-1 1:0.571429 2:0.142857 3:0.102041 5:0.017704591 6:0.028503029 7:0.05238925 +-1 1:0.774194 2:0.064516 3:0.016129 5:0.076454013 6:0.030768031 7:0.019177811 8:0.023809524 +-1 1:0.826087 7:0.012460232 +-1 1:0.709677 3:0.112903 7:0.016424073 +-1 1:0.720472 2:0.023622 3:0.066929 4:0.0073800738 5:0.035051362 7:0.015315921 8:0.023809524 +-1 1:0.821429 3:0.071429 7:0.023301396 +-1 1:0.866667 7:0.017682927 +-1 1:0.634146 2:0.146341 3:0.121951 4:0.011070111 5:0.039233373 6:0.063159063 7:0.028256988 +-1 1:0.479167 2:0.25 3:0.104167 5:0.2420348 6:0.077922078 7:0.019563006 +-1 1:0.894737 4:0.0036900369 7:0.01861361 +-1 1:0.555556 2:0.222222 3:0.074074 5:0.099391708 6:0.15999916 7:0.016937671 +-1 1:0.615385 3:0.115385 4:0.0073800738 7:0.017120073 +-1 1:0.763158 3:0.078947 7:0.020699616 +-1 1:0.75 2:0.032895 3:0.026316 5:0.096812428 7:0.015444482 +-1 1:0.764706 7:0.01040172 +-1 1:0.653061 3:0.102041 4:0.0073800738 7:0.016674963 +-1 1:0.75 3:0.056818 4:0.0036900369 7:0.022519402 +-1 1:0.688525 2:0.016393 3:0.04918 7:0.013694524 8:0.023809524 +-1 1:0.916667 4:0.092250923 7:0.095782518 +-1 1:0.653846 2:0.076923 3:0.096154 4:0.022140221 5:0.016787679 6:0.060810061 7:0.017354598 +-1 1:0.695652 2:0.021739 3:0.043478 7:0.010074232 +-1 1:0.72 2:0.013333 3:0.08 7:0.015528457 +-1 1:0.615702 2:0.061983 3:0.107438 5:0.029542439 6:0.01981502 7:0.019073774 +-1 1:0.748201 3:0.028777 7:0.013905951 8:0.095238095 +-1 1:0.797753 3:0.067416 4:0.011070111 7:0.025554945 +-1 1:0.846154 7:0.016416512 +-1 1:0.970588 7:0.084469159 +-1 1:0.762712 3:0.033898 4:0.0036900369 7:0.012401817 +-1 1:0.706806 2:0.031414 3:0.052356 5:0.048514305 6:0.013014013 7:0.014717152 8:0.071428571 +-1 1:0.721519 2:0.025316 3:0.075949 4:0.033210332 5:0.016564042 6:0.013332013 7:0.01736647 +-1 1:0.7 3:0.1 4:0.0036900369 7:0.013109756 8:0.023809524 +-1 1:0.756098 2:0.04878 3:0.02439 6:0.028845029 7:0.015466982 +-1 1:0.702703 3:0.108108 4:0.0073800738 7:0.018292683 +-1 1:0.875 7:0.016006098 +-1 1:0.723404 3:0.06383 4:0.0036900369 7:0.022703683 8:0.047619048 +-1 1:0.710526 3:0.171053 4:0.018450185 7:0.027037866 +-1 1:0.833333 3:0.083333 7:0.023882116 +-1 1:0.72 3:0.16 4:0.0036900369 7:0.020731707 +-1 1:0.761905 3:0.095238 7:0.018292683 +-1 1:0.821429 7:0.015625 +-1 1:0.857143 7:0.013501744 8:0.023809524 +-1 1:0.8 7:0.010670732 8:0.023809524 +-1 1:0.738095 7:0.010162604 8:0.047619048 +-1 1:0.792683 7:0.012566927 8:0.047619048 +-1 1:0.833333 7:0.01422764 +-1 1:0.628571 2:0.114286 3:0.028571 5:0.067769445 6:0.054546055 7:0.019163762 +-1 1:0.846154 7:0.012664165 8:0.023809524 +-1 1:0.8 7:0.011382116 8:0.095238095 +-1 1:0.677419 3:0.096774 7:0.011998427 +-1 1:0.742268 2:0.041237 3:0.030928 5:0.032270809 6:0.025974026 7:0.014520994 +-1 1:0.714894 2:0.029787 3:0.07234 5:0.047783758 7:0.01619097 +-1 1:0.67033 3:0.043956 4:0.011070111 7:0.014272311 +-1 1:0.774436 3:0.030075 7:0.014120665 8:0.047619048 +-1 1:0.743119 2:0.018349 3:0.055046 5:0.054217047 7:0.015383756 +-1 1:0.833333 7:0.011686994 +-1 1:0.68254 2:0.063492 3:0.079365 4:0.0036900369 5:0.1461691 7:0.01480836 +-1 1:0.722892 7:0.012195122 8:0.023809524 +-1 1:0.769634 2:0.041885 3:0.015707 5:0.058883604 6:0.0094800095 7:0.020208146 +-1 1:0.772727 3:0.022727 7:0.011779378 8:0.023809524 +-1 1:0.761494 2:0.011494 3:0.037356 5:0.0076111103 7:0.017153768 8:0.023809524 +-1 1:0.60274 3:0.027397 7:0.011025726 +-1 1:0.723077 3:0.123077 4:0.0036900369 7:0.020262665 +-1 1:0.916667 4:0.014760148 7:0.021341463 +-1 1:0.75 3:0.014286 4:0.0036900369 7:0.015418116 8:0.023809524 +-1 1:0.641791 2:0.074627 3:0.104478 4:0.0036900369 5:0.087188586 6:0.035088035 7:0.015562433 +-1 1:0.803279 7:0.01339464 8:0.023809524 +-1 1:0.778689 3:0.016393 7:0.013594561 8:0.023809524 +-1 1:0.763158 2:0.052632 6:0.033708034 7:0.014281128 +-1 1:0.827586 7:0.013246427 8:0.023809524 +-1 1:0.833333 7:0.01117886 +-1 1:0.77193 3:0.070175 7:0.01647411 +-1 1:0.655172 3:0.103448 7:0.014507988 +-1 1:0.769231 2:0.153846 6:0.058824059 7:0.023921201 +-1 1:0.725 3:0.075 7:0.014405488 8:0.047619048 +-1 1:0.809524 7:0.012775841 +-1 1:0.737374 3:0.030303 7:0.014627988 8:0.023809524 +-1 1:0.823529 7:0.013271165 +-1 1:0.658228 2:0.037975 3:0.151899 4:0.036900369 6:0.024489024 7:0.018910159 +-1 1:0.786611 2:0.004184 3:0.041841 5:0.0070072906 6:0.0028200028 7:0.027145628 +-1 1:0.7 2:0.069231 3:0.038462 4:0.0036900369 6:0.068628069 7:0.01435272 +-1 1:0.744186 7:0.010068067 8:0.023809524 +-1 1:0.724638 2:0.028986 3:0.014493 5:0.10764391 7:0.012239305 8:0.14285714 +-1 1:0.758621 3:0.034483 7:0.011774598 8:0.023809524 +-1 1:0.714286 3:0.120879 4:0.014760148 7:0.020034841 8:0.023809524 +-1 1:0.767857 3:0.053571 7:0.015570555 +-1 1:0.76 2:0.04 4:0.0036900369 6:0.037266037 7:0.013089433 +-1 1:0.783505 3:0.010309 7:0.013829518 +-1 1:0.666667 2:0.090909 3:0.030303 6:0.095238095 7:0.011640799 +-1 1:0.8 7:0.014430896 8:0.023809524 +-1 1:0.769231 7:0.011022512 8:0.047619048 +-1 1:0.666667 2:0.125 3:0.083333 6:0.074073074 7:0.020579268 +-1 1:0.777778 7:0.010388439 +-1 1:0.735294 3:0.088235 4:0.0036900369 7:0.014705884 +-1 1:0.659794 2:0.113402 3:0.041237 6:0.095238095 7:0.015841085 +-1 1:0.677215 2:0.044304 3:0.063291 5:0.021990965 6:0.0088500089 7:0.013082744 +-1 1:0.587302 2:0.111111 3:0.111111 4:0.029520295 5:0.18330774 6:0.0081960082 7:0.017711963 8:0.023809524 +-1 1:0.745614 3:0.052632 7:0.014548567 8:0.023809524 +-1 1:0.731707 2:0.04878 3:0.073171 4:0.0073800738 6:0.025209025 7:0.017697799 8:0.023809524 +-1 1:0.731183 2:0.010753 3:0.032258 7:0.011801732 8:0.023809524 +-1 1:0.716216 2:0.040541 3:0.054054 6:0.03000003 7:0.016479896 +-1 1:0.731481 3:0.083333 7:0.01682475 +-1 1:0.730769 2:0.012821 3:0.076923 6:0.013953014 7:0.016807378 +-1 1:0.74359 3:0.051282 4:0.0073800738 7:0.01422764 8:0.047619048 +-1 1:0.694805 2:0.019481 3:0.071429 6:0.0076140076 7:0.015600256 8:0.047619048 +-1 1:0.705882 2:0.094118 3:0.023529 6:0.094170094 7:0.015997128 +-1 1:0.791667 7:0.01257622 +-1 1:0.84 7:0.013902439 +-1 1:0.769231 7:0.011960598 +-1 1:0.625 2:0.166667 6:0.20930121 7:0.010924799 +-1 1:0.730769 3:0.070513 4:0.0036900369 7:0.015009384 8:0.023809524 +-1 1:0.814516 3:0.008065 7:0.01721086 +-1 1:0.747826 2:0.021739 3:0.013043 5:0.013880399 6:0.011172011 7:0.014236482 8:0.047619048 +-1 1:0.666667 2:0.111111 3:0.111111 5:0.076849105 6:0.061857062 7:0.021906049 +-1 1:0.731959 2:0.030928 3:0.041237 6:0.037344037 7:0.01514961 +-1 1:0.857143 7:0.013501744 +-1 1:0.619718 2:0.140845 3:0.028169 5:0.17137298 6:0.051723052 7:0.014943317 +-1 1:0.585366 2:0.219512 3:0.02439 5:0.076066375 6:0.18367218 7:0.014574659 +-1 1:0.657895 3:0.078947 7:0.013478817 8:0.023809524 +-1 1:0.8125 3:0.125 7:0.032012195 +-1 1:0.62201 2:0.090909 3:0.08134 4:0.0036900369 5:0.12976906 6:0.029013029 7:0.015083439 +-1 1:0.780488 2:0.04878 4:0.0036900369 5:0.070997272 7:0.015615707 +-1 1:0.689922 2:0.03876 3:0.077519 4:0.0036900369 6:0.026088026 7:0.016307433 +-1 1:0.825 7:0.01554878 +-1 1:0.631579 2:0.115789 3:0.052632 6:0.096000096 7:0.016046213 8:0.023809524 +-1 1:0.710526 3:0.131579 4:0.025830258 7:0.023801884 +-1 1:0.555556 2:0.333333 6:0.17910318 7:0.022696476 +-1 1:0.708333 3:0.194444 4:0.0073800738 7:0.032096884 +-1 1:0.923077 3:0.076923 4:0.0036900369 7:0.042682927 +-1 1:0.785714 3:0.202381 4:0.040590406 7:0.15287456 +-1 1:0.692308 7:0.011960598 +-1 1:0.717391 7:0.010737012 +-1 1:0.795455 3:0.015152 7:0.014735774 8:0.023809524 +-1 1:0.8 7:0.010365854 +-1 1:0.692308 2:0.019231 3:0.076923 4:0.044280443 5:0.039032099 7:0.022396811 +-1 1:0.492754 2:0.115942 3:0.086957 4:0.011070111 5:0.22819913 7:0.01732061 +-1 1:0.787356 2:0.005747 3:0.028736 5:0.017056043 7:0.015313988 8:0.023809524 +-1 1:0.728814 2:0.016949 3:0.067797 4:0.0073800738 6:0.022557023 7:0.013745348 8:0.023809524 +-1 1:0.846154 7:0.014071293 +-1 1:0.75 3:0.0625 7:0.014481707 +-1 1:0.487179 2:0.076923 3:0.153846 5:0.15213275 7:0.015322073 +-1 1:0.823529 3:0.058824 7:0.019368726 +-1 1:0.76259 3:0.043165 7:0.015485171 +-1 1:0.75 3:0.166667 7:0.021341463 +-1 1:0.730769 3:0.115385 7:0.01594747 +-1 1:0.714286 2:0.047619 3:0.047619 6:0.076923077 7:0.011324043 +-1 1:0.846154 7:0.012195122 +-1 1:0.692308 3:0.102564 7:0.01235147 +-1 1:0.756098 3:0.073171 7:0.015913146 +-1 1:0.714286 2:0.015873 3:0.079365 5:0.051764495 7:0.01393728 +-1 1:0.761905 3:0.142857 4:0.0036900369 7:0.023228805 +-1 1:0.74359 2:0.012821 3:0.012821 7:0.015087555 8:0.047619048 +-1 1:0.740741 2:0.055556 6:0.047244047 7:0.014340561 8:0.023809524 +-1 1:0.75 3:0.083333 7:0.01117886 +-1 1:0.730769 2:0.019231 3:0.096154 4:0.0036900369 5:0.019776959 7:0.022103659 +-1 1:0.75 3:0.055556 7:0.013380756 +-1 1:0.75 3:0.090909 4:0.0073800738 7:0.017461195 +-1 1:0.691176 2:0.029412 3:0.102941 4:0.011070111 6:0.015423015 7:0.017440817 +-1 1:0.630435 2:0.021739 3:0.152174 4:0.0036900369 5:0.050370492 7:0.019618238 +-1 1:0.7375 3:0.025 7:0.012118902 +-1 1:0.754098 7:0.010995604 8:0.023809524 +-1 1:0.7 3:0.133333 4:0.0036900369 7:0.015447152 +-1 1:0.75 3:0.083333 4:0.0036900369 7:0.014058268 +-1 1:0.797101 3:0.050725 4:0.014760148 7:0.023373982 +-1 1:0.802198 2:0.010989 3:0.010989 5:0.027611707 7:0.018091665 8:0.047619048 +-1 1:0.846154 7:0.012195122 +-1 1:0.779412 3:0.014706 7:0.012195122 +-1 1:0.709459 2:0.054054 3:0.074324 4:0.014760148 5:0.047381212 6:0.019068019 7:0.019446274 +-1 1:0.866667 7:0.015040652 +-1 1:0.824176 7:0.016416512 +-1 1:0.836735 7:0.01630164 8:0.023809524 +-1 1:0.714286 2:0.028571 3:0.028571 7:0.012195122 8:0.047619048 +-1 1:0.801471 7:0.013629841 +-1 1:0.669421 2:0.049587 3:0.049587 5:0.071675637 7:0.015722634 8:0.047619048 +-1 1:0.627451 2:0.117647 3:0.137255 4:0.018450185 5:0.062909069 6:0.025317025 7:0.028335726 +-1 1:0.814815 3:0.074074 7:0.021454378 +-1 1:0.756757 3:0.054054 7:0.012854317 +-1 1:0.828571 4:0.025830258 7:0.017247384 +-1 1:0.657143 2:0.057143 3:0.114286 4:0.011070111 5:0.17336335 6:0.034884035 7:0.014982579 +-1 1:0.736842 2:0.026316 3:0.078947 7:0.056322207 +-1 1:0.695035 2:0.085106 3:0.049645 5:0.031994991 6:0.045063045 7:0.020152226 8:0.023809524 +-1 1:0.75 7:0.012195122 +-1 1:0.814815 7:0.012872628 +-1 1:0.705882 2:0.029412 3:0.117647 4:0.036900369 6:0.015999016 7:0.022417506 +-1 1:0.820513 2:0.025641 4:0.036900369 5:0.054410866 7:0.021419634 +-1 1:0.795181 7:0.015721421 8:0.047619048 +-1 1:0.666667 2:0.08642 3:0.037037 6:0.030612031 7:0.014754591 +-1 1:0.84 3:0.04 7:0.02097561 +-1 1:0.746835 3:0.050633 7:0.014047543 8:0.023809524 +-1 1:0.565217 2:0.108696 3:0.086957 5:0.19617432 6:0.026316026 7:0.015111348 +-1 1:0.7 2:0.05 3:0.1 7:0.01554878 +-1 1:0.688889 2:0.088889 3:0.022222 5:0.08471367 6:0.1022731 7:0.011924122 +-1 1:0.864865 7:0.021753463 +-1 1:0.75 2:0.03125 6:0.051723052 7:0.011051829 +-1 1:0.619048 2:0.095238 3:0.095238 4:0.011070111 5:0.074545644 6:0.06000006 7:0.014518 8:0.023809524 +-1 1:0.775 2:0.05 3:0.075 4:0.0036900369 5:0.0463003 7:0.024542683 +-1 1:0.779661 3:0.00565 7:0.012367372 +-1 1:0.699029 2:0.029126 3:0.097087 6:0.016485016 7:0.021548665 +-1 1:0.6 2:0.033333 3:0.233333 4:0.011070111 5:0.086681675 7:0.017479677 +-1 1:0.846154 7:0.015634774 +-1 1:0.708333 2:0.069444 3:0.069444 6:0.060606061 7:0.016768293 +-1 1:0.772727 2:0.011364 3:0.068182 4:0.018450185 5:0.027507343 7:0.018777713 +-1 1:0.803738 2:0.009346 6:0.011406011 7:0.014987463 +-1 1:0.702703 2:0.081081 3:0.013514 6:0.080538081 7:0.012277524 +-1 1:0.75 2:0.083333 6:0.053571054 7:0.01422764 +-1 1:0.648438 2:0.148438 3:0.015625 5:0.04809685 6:0.12580513 7:0.01476753 +-1 1:0.768293 2:0.02439 3:0.085366 4:0.018450185 5:0.020425507 7:0.027141585 +-1 1:0.676471 2:0.088235 3:0.058824 4:0.0036900369 6:0.077922078 7:0.013809183 +-1 1:0.709677 2:0.064516 3:0.032258 5:0.11295156 7:0.012981902 +-1 1:0.71875 2:0.0625 3:0.015625 5:0.02720916 6:0.032847033 7:0.026105183 +-1 1:0.758621 3:0.034483 7:0.011879732 +-1 1:0.761905 3:0.047619 7:0.012485482 +-1 1:0.62963 3:0.111111 7:0.012420957 +-1 1:0.775362 2:0.007246 3:0.014493 4:0.0036900369 7:0.015420646 +-1 1:0.719298 2:0.035088 3:0.052632 5:0.029467893 6:0.017787018 7:0.018043073 8:0.071428571 +-1 1:0.505882 2:0.2 3:0.105882 4:0.0036900369 5:0.10856082 6:0.11650512 7:0.014777616 +-1 1:0.794872 2:0.008547 7:0.014383988 8:0.023809524 +-1 1:0.755814 2:0.023256 6:0.015228015 7:0.013967671 +-1 1:0.677419 2:0.096774 6:0.11764812 7:0.01003147 +-1 1:0.785714 3:0.214286 4:0.0036900369 7:0.045731707 +-1 1:0.648352 2:0.087912 3:0.054945 4:0.011070111 6:0.078603079 7:0.015344415 +-1 1:0.72973 3:0.108108 7:0.014831902 +-1 1:0.759494 3:0.037975 7:0.021225689 8:0.023809524 +-1 1:0.769231 3:0.051282 7:0.015165732 8:0.023809524 +-1 1:0.817391 7:0.015429482 8:0.023809524 +-1 1:0.681818 7:0.011640799 8:0.047619048 +-1 1:0.636364 3:0.113636 7:0.014273835 8:0.023809524 +-1 1:0.789474 2:0.030075 3:0.007519 6:0.015504016 7:0.01774253 8:0.023809524 +-1 1:0.819672 7:0.015493805 8:0.047619048 +-1 1:0.815789 7:0.022785622 8:0.071428571 +-1 1:0.740741 3:0.111111 7:0.033197835 8:0.023809524 +-1 1:0.777778 7:0.010162604 8:0.023809524 +-1 1:0.689655 2:0.068966 3:0.057471 5:0.10212008 6:0.027396027 7:0.01534903 8:0.047619048 +-1 1:0.833333 7:0.01422764 8:0.023809524 +-1 1:0.779661 3:0.050847 4:0.0073800738 7:0.01839603 8:0.023809524 +-1 1:0.555556 2:0.277778 5:0.13078288 6:0.15789616 7:0.019308945 +-1 1:0.675676 3:0.135135 7:0.014337506 8:0.023809524 +-1 1:0.783784 7:0.01252472 8:0.023809524 +-1 1:0.636364 2:0.181818 6:0.18181818 7:0.013719512 +-1 1:0.8125 7:0.01549797 +-1 1:0.757396 2:0.017751 3:0.047337 4:0.0036900369 6:0.01049101 7:0.020637896 8:0.023809524 +-1 1:0.666667 3:0.2 7:0.015040652 +-1 1:0.660377 2:0.056604 3:0.113208 4:0.0036900369 5:0.10725627 7:0.01599172 +-1 1:0.866667 7:0.015040652 +-1 1:0.781022 7:0.014108957 +-1 1:0.78022 2:0.032967 6:0.028170028 7:0.014272311 +-1 1:0.752809 2:0.011236 3:0.067416 7:0.017127982 +-1 1:0.8 7:0.012682927 8:0.023809524 +-1 1:0.833333 3:0.083333 7:0.018292683 +-1 1:0.795181 3:0.024096 7:0.015354098 +-1 1:0.741071 3:0.026786 7:0.012630665 8:0.047619048 +-1 1:0.710526 3:0.026316 4:0.0036900369 7:0.017008988 +-1 1:0.481481 2:0.111111 3:0.074074 5:0.15861077 6:0.063831064 7:0.010614274 +-1 1:0.717391 3:0.130435 4:0.0073800738 7:0.017895018 +-1 1:0.727273 3:0.090909 4:0.0036900369 7:0.012749445 8:0.023809524 +-1 1:0.769231 7:0.011022512 8:0.047619048 +-1 1:0.75 3:0.083333 7:0.013719512 +-1 1:0.808333 7:0.021341463 8:0.071428571 +-1 1:0.764706 3:0.117647 7:0.018651366 8:0.023809524 +-1 1:0.764706 3:0.047059 4:0.0036900369 7:0.014203732 +-1 1:0.736111 2:0.037037 3:0.050926 5:0.038376098 7:0.02193428 +-1 1:0.60274 2:0.123288 3:0.061644 5:0.16565533 6:0.066666067 7:0.013155695 8:0.023809524 +-1 1:0.776 7:0.011512195 8:0.047619048 +-1 1:0.745455 2:0.009091 3:0.036364 4:0.0036900369 7:0.016629713 8:0.047619048 +-1 1:0.714286 3:0.071429 7:0.020905921 +-1 1:0.8 7:0.012664165 8:0.023809524 +-1 1:0.727273 3:0.068182 7:0.017253323 +-1 1:0.82243 7:0.017266927 8:0.023809524 +-1 1:0.610169 2:0.118644 3:0.033898 6:0.10619411 7:0.011678378 +-1 1:0.789474 7:0.011071884 8:0.023809524 +-1 1:0.772727 2:0.045455 5:0.15530094 7:0.013303768 +-1 1:0.666667 2:0.125 3:0.083333 6:0.02000102 7:0.076219512 +-1 1:0.684211 2:0.052632 3:0.052632 7:0.0105905 +-1 1:0.673469 2:0.061224 3:0.071429 4:0.018450185 5:0.031719172 6:0.025533026 7:0.014621701 +-1 1:0.728571 2:0.014286 3:0.042857 6:0.016575017 7:0.015766549 8:0.023809524 +-1 1:0.804598 7:0.013316512 8:0.023809524 +-1 1:0.721804 2:0.030075 3:0.037594 5:0.061269065 7:0.016733909 +-1 1:0.730769 7:0.010787994 +-1 1:0.764706 7:0.031563848 +-1 1:0.724138 2:0.068966 6:0.05000105 7:0.01261564 +-1 1:0.8 7:0.016463415 +-1 1:0.857143 7:0.013066201 +-1 1:0.833333 7:0.011686994 8:0.023809524 +-1 1:0.833333 7:0.015879067 8:0.023809524 +-1 1:0.777778 3:0.074074 4:0.0036900369 7:0.016034329 +-1 1:0.777778 7:0.011517616 8:0.071428571 +-1 1:0.714286 2:0.038462 3:0.06044 5:0.092794418 7:0.016148488 8:0.023809524 +-1 1:0.739726 2:0.013699 3:0.082192 7:0.02079853 +-1 1:0.79798 7:0.012872628 +-1 1:0.71134 3:0.092784 4:0.0073800738 7:0.018858433 +-1 1:0.767296 3:0.031447 7:0.01495628 +-1 1:0.807692 7:0.011960598 +-1 1:0.813953 7:0.029707884 8:0.023809524 +-1 1:0.8 7:0.010670732 +-1 1:0.756757 3:0.108108 7:0.021588659 8:0.023809524 +-1 1:0.784884 3:0.02907 7:0.016147902 8:0.023809524 +-1 1:0.65873 2:0.111111 3:0.02381 5:0.029937531 6:0.10843511 7:0.012049939 +-1 1:0.75841 2:0.024465 3:0.030581 5:0.045621934 7:0.015234579 8:0.023809524 +-1 1:0.568182 2:0.045455 3:0.181818 4:0.0073800738 5:0.068388174 7:0.015105323 +-1 1:0.666667 2:0.111111 3:0.037037 6:0.056604057 7:0.011969287 +-1 1:0.769231 2:0.010989 3:0.010989 7:0.013334226 8:0.023809524 +-1 1:0.77551 3:0.081633 4:0.014760148 7:0.019039323 8:0.023809524 +-1 1:0.75 3:0.25 4:0.011070111 7:0.039634146 +-1 1:0.75 2:0.038462 3:0.038462 6:0.018519019 7:0.01899625 +-1 1:0.798165 2:0.009174 3:0.045872 7:0.020865963 +-1 1:0.742857 2:0.142857 6:0.1034491 7:0.025261323 +-1 1:0.850932 2:0.006211 3:0.018634 5:0.0075216555 6:0.003027003 7:0.037532195 +-1 1:0.954545 2:0.045455 5:0.029467893 7:0.070121951 +-1 1:0.925926 3:0.018519 7:0.10433604 +-1 1:0.988235 4:0.084870849 7:0.14361549 +-1 1:0.987952 7:0.15302674 +-1 1:0.769231 2:0.038462 3:0.076923 5:0.029117529 7:0.030018762 +-1 1:0.857143 7:0.01480836 +-1 1:0.76 2:0.06 3:0.06 6:0.028707029 7:0.025487805 +-1 1:0.767327 2:0.012376 3:0.027228 5:0.015028402 7:0.014972232 +-1 1:0.826087 7:0.014183457 +-1 1:0.757353 2:0.029412 3:0.007353 6:0.028845029 7:0.013988524 +-1 1:0.758621 3:0.034483 7:0.011774598 8:0.023809524 +-1 1:0.754098 3:0.081967 4:0.0073800738 7:0.016193524 +-1 1:0.72 2:0.08 3:0.04 5:0.23295514 7:0.015609756 +-1 1:0.766667 3:0.047619 4:0.014760148 7:0.015389079 8:0.071428571 +-1 1:0.652174 2:0.043478 3:0.173913 4:0.0073800738 7:0.02492047 +-1 1:0.741935 3:0.051613 4:0.011070111 7:0.013650671 +-1 1:0.8 7:0.010569104 +-1 1:0.663043 2:0.086957 3:0.086957 6:0.055557056 7:0.017895018 +-1 1:0.823529 7:0.011836439 +-1 1:0.836735 3:0.020408 7:0.018790445 +-1 1:0.861111 7:0.019817073 +-1 1:0.77551 3:0.040816 4:0.0073800738 7:0.015306122 +-1 1:0.635135 2:0.148649 3:0.040541 4:0.0073800738 5:0.03516318 6:0.11320811 7:0.017468689 +-1 1:0.650307 2:0.08589 3:0.08589 5:0.014305309 6:0.057582058 7:0.01948975 +-1 1:0.827586 2:0.034483 5:0.093182055 7:0.01682086 +-1 1:0.733333 3:0.133333 4:0.0036900369 7:0.015040652 +-1 1:0.78534 2:0.013089 3:0.015707 5:0.030183531 7:0.015770652 +-1 1:0.785714 2:0.071429 5:0.248483 7:0.013066201 +-1 1:0.806452 2:0.032258 5:0.08874659 7:0.016522421 +-1 1:0.73913 2:0.006211 3:0.055901 5:0.018636411 7:0.01514922 8:0.023809524 +-1 1:0.757895 3:0.042105 7:0.015725287 8:0.047619048 +-1 1:0.742857 3:0.057143 4:0.0036900369 7:0.01480836 8:0.023809524 +-1 1:0.777778 3:0.055556 4:0.011070111 7:0.023750378 +-1 1:0.851852 2:0.12963 6:0.014574015 7:0.13945348 +-1 1:0.767677 2:0.030303 3:0.020202 5:0.087360041 7:0.015767433 +-1 1:0.952381 7:0.032229963 +-1 1:0.684211 2:0.045113 3:0.067669 4:0.014760148 5:0.11433065 7:0.014945902 8:0.023809524 +-1 1:0.747059 2:0.023529 3:0.023529 5:0.044816841 7:0.017898134 8:0.095238095 +-1 1:0.297872 2:0.12766 3:0.085106 4:0.0073800738 5:0.49697345 7:0.011676183 8:0.047619048 +-1 1:0.571429 2:0.214286 5:0.97233611 7:0.010017421 +-1 1:0.75 3:0.075 7:0.014481707 +-1 1:0.807692 7:0.012664165 8:0.047619048 +-1 1:0.568807 2:0.137615 3:0.082569 4:0.018450185 5:0.040515558 6:0.065217065 7:0.020586262 +-1 1:0.771429 3:0.085714 4:0.0073800738 7:0.033449476 8:0.023809524 +-1 1:0.765625 2:0.007812 3:0.039062 7:0.017482854 8:0.023809524 +-1 1:0.8 7:0.010162604 8:0.023809524 +-1 1:0.745763 3:0.059322 7:0.02139314 8:0.023809524 +-1 1:0.709677 2:0.016129 3:0.064516 5:0.060121062 6:0.024195024 7:0.012195122 +-1 1:0.8 7:0.013871951 8:0.023809524 +-1 1:0.756757 3:0.027027 7:0.020270268 +-1 1:0.758929 3:0.071429 7:0.017748256 +-1 1:0.833333 7:0.01117886 +-1 1:0.622807 2:0.131579 3:0.105263 5:0.15494312 6:0.0069270069 7:0.023160037 +-1 1:0.807692 3:0.076923 4:0.0036900369 7:0.023217634 +-1 1:0.780105 3:0.04712 7:0.016792238 +-1 1:0.732283 2:0.007874 3:0.031496 5:0.028782073 7:0.012435183 8:0.023809524 +-1 1:0.6875 2:0.125 5:0.25705575 6:0.1034491 7:0.011051829 +-1 1:0.789474 3:0.017544 7:0.014174152 +-1 1:0.8 7:0.011707317 +-1 1:0.769231 3:0.021978 7:0.012865183 8:0.047619048 +-1 1:0.777778 7:0.0094850976 8:0.023809524 +-1 1:0.761905 2:0.047619 5:0.18636411 7:0.011614402 8:0.023809524 +-1 1:0.75 2:0.05 5:0.19617432 6:0.078948079 7:0.011585366 8:0.023809524 +-1 1:0.793103 3:0.068966 7:0.0294365 +-1 1:0.714286 3:0.071429 4:0.0073800738 7:0.019599305 8:0.047619048 +-1 1:0.727273 2:0.022727 3:0.022727 4:0.0036900369 6:0.015543016 7:0.013373061 8:0.047619048 +-1 1:0.761468 3:0.073394 7:0.021313494 8:0.023809524 +-1 1:0.684564 2:0.067114 3:0.053691 6:0.052941053 7:0.013913896 8:0.023809524 +-1 1:0.764706 2:0.014706 3:0.044118 4:0.011070111 5:0.033731904 7:0.019817073 8:0.023809524 +-1 1:0.710784 2:0.04902 3:0.044118 5:0.04141756 6:0.022221022 7:0.016140604 +-1 1:0.798077 4:0.0073800738 7:0.012781427 8:0.023809524 +-1 1:0.8125 2:0.03125 3:0.03125 7:0.033536585 +-1 1:0.76259 3:0.028777 7:0.012546061 8:0.047619048 +-1 1:0.674419 2:0.093023 3:0.023256 5:0.086681675 7:0.012195122 +-1 1:0.803922 7:0.01351028 +-1 1:0.77027 2:0.027027 3:0.040541 5:0.033128084 7:0.018539878 +-1 1:0.75 3:0.083333 7:0.022357726 +-1 1:0.695652 2:0.130435 3:0.043478 5:0.30635278 7:0.019353128 +-1 1:0.828571 3:0.028571 7:0.021254354 +-1 1:0.692308 2:0.042735 3:0.051282 6:0.035088035 7:0.01782364 +-1 1:0.778626 7:0.012241671 8:0.071428571 +-1 1:0.609195 2:0.034483 3:0.011494 4:0.0036900369 6:0.021276021 7:0.019764506 8:0.047619048 +-1 1:0.79661 3:0.016949 7:0.015192226 +-1 1:0.72807 2:0.04386 3:0.017544 6:0.044445044 7:0.014441591 8:0.047619048 +-1 1:0.741573 2:0.022472 3:0.033708 5:0.079726567 7:0.012811732 8:0.023809524 +-1 1:0.774194 2:0.016129 3:0.016129 5:0.055633414 7:0.013178598 +-1 1:0.770833 7:0.010543701 +-1 1:0.818182 7:0.013442348 +-1 1:0.672043 2:0.069892 3:0.139785 4:0.0073800738 6:0.03033003 7:0.035667457 +-1 1:0.78 3:0.01 7:0.012560976 8:0.047619048 +-1 1:0.72 3:0.04 7:0.011219512 8:0.023809524 +-1 1:0.574074 2:0.12963 3:0.12963 4:0.011070111 5:0.070997272 6:0.028572029 7:0.023712738 8:0.023809524 +-1 1:0.761538 3:0.046154 7:0.01665103 8:0.023809524 +-1 1:0.695652 3:0.043478 7:0.011930012 8:0.071428571 +-1 1:0.755102 2:0.010204 3:0.040816 7:0.017483823 8:0.047619048 +-1 1:0.732535 2:0.00998 3:0.085828 4:0.011070111 6:0.0068220068 7:0.021408402 8:0.047619048 +-1 1:0.764151 3:0.018868 7:0.013805799 +-1 1:0.773585 2:0.028302 3:0.028302 5:0.025882248 7:0.016566957 +-1 1:0.705128 2:0.025641 3:0.064103 5:0.090356775 7:0.012898689 8:0.023809524 +-1 1:0.738318 3:0.056075 7:0.015386372 +-1 1:0.691176 3:0.088235 7:0.014078195 +-1 1:0.793548 2:0.006452 3:0.064516 4:0.0036900369 7:0.025019671 +-1 1:0.716418 2:0.044776 3:0.089552 4:0.0073800738 6:0.027522028 7:0.019839823 +-1 1:0.760417 3:0.020833 7:0.013084348 +-1 1:0.795322 3:0.02924 7:0.016581085 8:0.047619048 +-1 1:0.761905 3:0.02381 7:0.012485482 +-1 1:0.612903 2:0.032258 3:0.225806 5:0.072376366 7:0.02025964 +-1 1:0.690476 2:0.035714 3:0.107143 5:0.052316133 7:0.020688152 +-1 1:0.712159 2:0.062035 3:0.059553 4:0.0036900369 5:0.022087874 6:0.033333033 7:0.020426073 +-1 1:0.739837 2:0.03252 3:0.02439 5:0.022728967 6:0.018294018 7:0.016260165 8:0.047619048 +-1 1:0.753165 2:0.044304 3:0.018987 5:0.016206223 6:0.026088026 7:0.01775239 8:0.023809524 +-1 1:0.755319 2:0.039007 3:0.035461 6:0.024975025 7:0.020779274 +-1 1:0.770992 2:0.022901 3:0.030534 5:0.052495043 7:0.019828707 8:0.023809524 +-1 1:0.789474 3:0.105263 7:0.02342747 +-1 1:0.758065 3:0.032258 7:0.013571988 +-1 1:0.742857 2:0.042857 3:0.028571 5:0.077654198 7:0.016724738 +-1 1:0.808511 3:0.042553 7:0.019330567 +-1 1:0.735294 2:0.058824 5:0.055215959 6:0.044445044 7:0.012105451 +-1 1:0.781609 3:0.011494 7:0.012335299 +-1 1:0.80303 3:0.015152 7:0.015613451 8:0.071428571 +-1 1:0.626506 2:0.024096 3:0.180723 5:0.066561806 7:0.016456067 +-1 1:0.735294 2:0.029412 3:0.051471 5:0.083759486 7:0.015961262 +-1 1:0.69697 2:0.060606 5:0.096812428 6:0.038961039 7:0.01422764 +-1 1:0.677419 3:0.080645 7:0.012096774 8:0.047619048 +-1 1:0.77686 2:0.008264 3:0.016529 5:0.02258733 7:0.016629713 +-1 1:0.75 3:0.058594 4:0.0073800738 7:0.019769439 8:0.023809524 +-1 1:0.75 2:0.0625 5:0.25705575 7:0.011051829 8:0.023809524 +-1 1:0.538462 2:0.076923 3:0.230769 5:0.21298436 6:0.085713086 7:0.016416512 +-1 1:0.733333 2:0.033333 3:0.133333 5:0.036184456 7:0.041869921 +-1 1:0.729167 3:0.041667 7:0.011623476 8:0.047619048 +-1 1:0.763975 2:0.012422 3:0.037267 4:0.0036900369 7:0.016474774 +-1 1:0.717949 2:0.051282 3:0.059829 5:0.070661816 6:0.0071100071 7:0.021992915 +-1 1:0.87069 2:0.017241 4:0.19188192 5:0.0073054731 6:0.0029400029 7:0.053616482 8:0.023809524 +-1 1:0.862069 7:0.01682086 +-1 1:0.705521 2:0.006135 3:0.04908 4:0.0036900369 5:0.020425507 7:0.013654049 +-1 1:0.714286 4:0.0036900369 7:0.01480836 +-1 1:0.65812 2:0.08547 3:0.025641 5:0.050541947 6:0.061017061 7:0.015374195 +-1 1:0.646341 2:0.134146 3:0.02439 4:0.0036900369 6:0.13259713 7:0.01345925 +-1 1:0.851852 7:0.016034329 +-1 1:0.728814 2:0.016949 3:0.101695 4:0.025830258 7:0.019946256 +-1 1:0.85 7:0.019715445 +-1 1:0.62 2:0.03 3:0.025 6:0.027675028 7:0.01652439 +-1 1:0.705882 7:0.01649928 +-1 1:0.829787 7:0.019200829 8:0.023809524 +-1 1:0.806452 7:0.013276945 8:0.023809524 +-1 1:0.516129 2:0.193548 3:0.096774 4:0.0036900369 5:0.15530094 6:0.093750094 7:0.018882768 +-1 1:0.769231 3:0.076923 7:0.03142589 +-1 1:0.625 2:0.0875 3:0.1125 4:0.0073800738 5:0.17176062 6:0.013824014 7:0.016539634 +-1 1:0.852941 7:0.020086085 8:0.023809524 +-1 1:0.647059 2:0.058824 3:0.176471 4:0.011070111 5:0.031584989 7:0.028216165 +-1 1:0.771429 3:0.028571 7:0.013414634 +-1 1:0.632911 2:0.164557 3:0.050633 6:0.092307092 7:0.02759339 +-1 1:0.853659 7:0.021861988 +-1 1:0.916667 7:0.018292683 +-1 1:0.723485 2:0.030303 3:0.041667 5:0.057169055 6:0.0046020046 7:0.015059128 +-1 1:0.744361 2:0.06015 5:0.1224934 6:0.021126021 7:0.01953053 +-1 1:0.944444 7:0.041666665 +-1 1:0.72 3:0.12 7:0.014634146 +-1 1:0.866667 7:0.015040652 +-1 1:0.73913 3:0.130435 7:0.023329799 +-1 1:0.46 2:0.2 3:0.14 5:0.20998763 6:0.084507085 7:0.017317073 +-1 1:0.719298 3:0.105263 7:0.014441591 +-1 1:0.770213 3:0.06383 4:0.0036900369 7:0.021120915 8:0.047619048 +-1 1:0.80597 3:0.014925 4:0.011070111 7:0.015471421 +-1 1:0.72956 2:0.069182 3:0.044025 5:0.042438835 6:0.034155034 7:0.020210159 +-1 1:0.731602 3:0.051948 7:0.013673317 8:0.023809524 +-1 1:0.647059 2:0.117647 3:0.058824 6:0.1034491 7:0.015602585 +-1 1:0.833333 3:0.041667 4:0.0036900369 7:0.021087396 +-1 1:0.982323 7:0.1736419 +-1 1:0.809524 2:0.095238 5:0.21298436 7:0.020325201 +-1 1:0.8 7:0.022560976 +-1 1:0.75 2:0.022727 3:0.045455 7:0.013719512 +-1 1:0.761905 2:0.015873 3:0.063492 5:0.037459186 7:0.019260549 +-1 1:0.766067 2:0.015424 3:0.028278 5:0.027432797 7:0.017038683 8:0.11904762 +-1 1:0.68 2:0.071111 3:0.053333 5:0.068268901 6:0.043956044 7:0.01479675 +-1 1:0.642857 2:0.014286 3:0.085714 4:0.0073800738 5:0.03499918 7:0.018554006 8:0.047619048 +-1 1:0.787879 7:0.014504805 8:0.047619048 +-1 1:0.851852 3:0.037037 7:0.019647695 +-1 1:0.644737 3:0.118421 4:0.025830258 7:0.015965982 +-1 1:0.762295 2:0.02459 3:0.02459 5:0.020037869 6:0.0080640081 7:0.018592561 +-1 1:0.797753 7:0.013976433 8:0.023809524 +-1 1:0.765625 2:0.0625 3:0.046875 5:0.10962682 7:0.025914634 +-1 1:0.7 2:0.03 3:0.07 5:0.092794418 7:0.014695122 +-1 1:0.73494 2:0.060241 3:0.024096 5:0.17416844 7:0.015721421 +-1 1:0.785714 3:0.02381 7:0.015127756 8:0.047619048 +-1 1:0.697479 2:0.016807 3:0.033613 7:0.01393728 +-1 1:0.633005 2:0.049261 3:0.165025 5:0.033128084 7:0.02027514 +-1 1:0.7625 2:0.0125 3:0.0625 7:0.017835366 +-1 1:0.8 2:0.04 3:0.04 4:0.011070111 7:0.02 +-1 1:0.842105 3:0.052632 7:0.01861361 +-1 1:0.631579 2:0.157895 3:0.157895 5:0.081918209 6:0.032967033 7:0.02920411 +-1 1:0.636364 2:0.036364 3:0.072727 7:0.018403549 +-1 1:0.753247 2:0.025974 3:0.064935 5:0.029818258 7:0.019797274 +-1 1:0.732394 2:0.028169 3:0.014085 6:0.017856018 7:0.01442803 +-1 1:0.637795 2:0.173228 3:0.110236 5:0.049274671 6:0.031161031 7:0.050845018 +-1 1:0.518519 2:0.037037 3:0.037037 7:0.026874433 +-1 1:0.789474 7:0.0105905 +-1 1:0.777778 3:0.148148 4:0.033210332 7:0.031842817 +-1 1:0.746667 3:0.093333 4:0.011070111 7:0.019186994 +-1 1:0.788462 3:0.038462 4:0.018450185 7:0.016064726 8:0.023809524 +-1 1:0.738095 3:0.071429 7:0.013792104 +-1 1:0.8 7:0.013747226 8:0.047619048 +-1 1:0.829016 2:0.010363 3:0.015544 5:0.021990965 7:0.021420445 +-1 1:0.755952 3:0.035714 4:0.0036900369 7:0.01549797 8:0.047619048 +-1 1:0.8 7:0.012195122 +-1 1:0.633333 2:0.144444 3:0.033333 6:0.12558013 7:0.014566396 +-1 1:0.613636 2:0.113636 3:0.068182 5:0.16383642 6:0.065934066 7:0.012610866 8:0.023809524 +-1 1:0.770732 2:0.004878 3:0.009756 5:0.015691858 7:0.014128494 8:0.023809524 +-1 1:0.71875 2:0.046875 3:0.03125 6:0.043479043 7:0.013147866 8:0.023809524 +-1 1:0.777778 7:0.0098238476 +-1 1:0.768328 2:0.017595 3:0.029326 5:0.04269229 7:0.01561047 +-1 1:0.534247 2:0.287671 5:0.021238054 6:0.17094017 7:0.029318409 +-1 1:0.798742 3:0.012579 7:0.016426341 +-1 1:0.751412 2:0.00565 3:0.056497 5:0.012001849 7:0.02139314 8:0.095238095 +-1 1:0.775194 2:0.023256 5:0.068813084 7:0.015362073 +-1 1:0.733333 2:0.044444 3:0.022222 7:0.01382114 +-1 1:0.772727 3:0.030303 7:0.013396159 +-1 1:0.693548 2:0.080645 3:0.032258 5:0.10212008 6:0.041097041 7:0.014358774 +-1 1:0.677184 2:0.053398 3:0.038835 5:0.024540426 6:0.027159027 7:0.017981884 8:0.047619048 +-1 1:0.73428 2:0.022312 3:0.034483 5:0.027149524 6:0.0043710044 7:0.016981646 8:0.023809524 +-1 1:0.80756 2:0.003436 3:0.010309 7:0.019361329 +-1 1:0.796748 2:0.01626 3:0.020325 5:0.039919193 7:0.018515762 +-1 1:0.709677 3:0.064516 7:0.011605037 8:0.023809524 +-1 1:0.779221 2:0.064935 3:0.025974 5:0.016034768 6:0.012903013 7:0.036822933 +-1 1:0.675889 2:0.166008 3:0.011858 5:0.020775871 6:0.066900067 7:0.034584982 8:0.023809524 +-1 1:0.857143 7:0.022299652 +-1 1:0.666667 2:0.030303 3:0.136364 5:0.044906296 6:0.018072018 7:0.015336293 +-1 1:0.791667 7:0.014524049 8:0.023809524 +-1 1:0.671233 2:0.054795 3:0.082192 6:0.034749035 7:0.021633811 +-1 1:0.76875 7:0.0125 8:0.071428571 +-1 1:0.758621 3:0.068966 7:0.015278945 +-1 1:0.739583 2:0.020833 3:0.0625 5:0.055633414 7:0.01702236 8:0.023809524 +-1 1:0.727273 3:0.128788 4:0.0036900369 7:0.020971915 +-1 1:0.768293 3:0.060976 7:0.017325994 +-1 1:0.76 3:0.08 7:0.017073171 8:0.023809524 +-1 1:0.636364 2:0.060606 3:0.054545 5:0.094359877 7:0.017516628 8:0.047619048 +-1 1:0.683742 2:0.140312 3:0.026726 4:0.0036900369 5:0.03790646 6:0.07966208 7:0.024037159 +-1 1:0.8 7:0.010365854 +-1 1:0.6 7:0.022022957 +-1 1:0.705882 2:0.058824 3:0.058824 5:0.20707289 7:0.012912482 +-1 1:0.753086 2:0.012346 3:0.055556 7:0.018104488 8:0.023809524 +-1 1:0.777778 3:0.111111 4:0.0073800738 7:0.026874433 +-1 1:0.75 7:0.020121951 +-1 1:0.80315 7:0.013731518 8:0.071428571 +-1 1:0.453901 2:0.255319 3:0.099291 5:0.30899915 6:0.26424926 7:0.016692616 +-1 1:0.75 7:0.018038616 +-1 1:0.75 7:0.012195122 8:0.023809524 +-1 1:0.827586 7:0.021993274 +-1 1:0.777778 7:0.011894006 8:0.047619048 +-1 1:0.795918 3:0.061224 7:0.01941264 +-1 1:0.830508 7:0.017259195 +-1 1:0.8 7:0.012195122 +-1 1:0.788462 7:0.019934335 +-1 1:0.782051 2:0.012821 3:0.025641 5:0.03516318 7:0.01657286 +-1 1:0.697674 2:0.023256 3:0.034884 5:0.03499918 7:0.015102098 +-1 1:0.875 7:0.015243902 +-1 1:0.805556 7:0.011856366 +-1 1:0.690583 2:0.004484 3:0.089686 5:0.010212753 7:0.019960628 8:0.023809524 +-1 1:0.6 3:0.08 7:0.01195122 +-1 1:0.706897 2:0.013793 3:0.031034 5:0.048961579 7:0.012804878 8:0.095238095 +-1 1:0.809524 3:0.047619 7:0.014518 +-1 1:0.731343 3:0.029851 7:0.011285037 8:0.023809524 +-1 1:0.754717 3:0.066038 7:0.015416476 +-1 1:0.5625 2:0.25 3:0.0625 5:0.16941989 6:0.13636514 7:0.016768293 +-1 1:0.769231 2:0.076923 3:0.076923 7:0.0272045 +-1 1:0.695122 2:0.02439 3:0.097561 4:0.0073800738 5:0.033731904 7:0.016433671 8:0.023809524 +-1 1:0.875 3:0.0625 7:0.026676829 +-1 1:0.76494 3:0.011952 4:0.0036900369 7:0.013847049 8:0.071428571 +-1 1:0.717391 2:0.065217 5:0.14713074 6:0.01973702 7:0.020148463 +-1 1:0.670213 2:0.095745 3:0.095745 4:0.0073800738 6:0.045282045 7:0.034379866 +-1 1:0.713235 2:0.058824 3:0.066176 5:0.13177434 7:0.017754665 +-1 1:0.8 3:0.08 7:0.025853659 +-1 1:0.633333 3:0.1 7:0.014634146 8:0.023809524 +-1 1:0.857143 7:0.015679445 +-1 1:0.734694 3:0.102041 7:0.016177201 +-1 1:0.663043 2:0.054348 3:0.125 5:0.0050243764 6:0.01011601 7:0.049145018 +-1 1:0.804878 3:0.04878 7:0.016210591 +-1 1:0.757143 2:0.004082 3:0.053061 6:0.0021630022 7:0.017259829 8:0.071428571 +-1 1:0.844444 7:0.016395665 8:0.023809524 +-1 1:0.772277 3:0.029703 7:0.013402561 +-1 1:0.707317 3:0.036585 7:0.013236171 8:0.023809524 +-1 1:0.764706 3:0.058824 7:0.011836439 +-1 1:0.75 2:0.025 3:0.025 5:0.085682764 7:0.013262195 8:0.023809524 +-1 1:0.787879 3:0.030303 7:0.018662232 8:0.023809524 +-1 1:0.733333 3:0.022222 7:0.01382114 8:0.047619048 +-1 1:0.678571 2:0.071429 3:0.071429 5:0.25269483 7:0.012848433 +-1 1:0.866667 7:0.01422764 +-1 1:0.780952 3:0.019048 7:0.01422764 +-1 1:0.72 2:0.08 3:0.08 5:0.096812428 6:0.038961039 7:0.018780488 +-1 1:0.675978 2:0.039106 3:0.128492 4:0.044280443 5:0.035752091 7:0.028409866 8:0.023809524 +-1 1:0.77551 3:0.081633 7:0.020283726 +-1 1:0.725806 2:0.032258 3:0.032258 5:0.085682764 7:0.017112512 +-1 1:0.72043 3:0.075269 7:0.014162079 +-1 1:0.742038 7:0.013088396 8:0.047619048 +-1 1:0.826667 3:0.013333 7:0.018699189 8:0.047619048 +-1 1:0.766423 3:0.051095 7:0.015310665 +-1 1:0.819149 7:0.015179037 8:0.023809524 +-1 1:0.731707 3:0.01626 7:0.01437636 8:0.023809524 +-1 1:0.827586 7:0.013666945 +-1 1:0.802632 7:0.012676506 8:0.047619048 +-1 1:0.833333 7:0.01422764 +-1 1:0.8 7:0.048780488 +-1 1:0.699029 2:0.067961 3:0.009709 5:0.016206223 6:0.052173052 7:0.013615915 8:0.023809524 +-1 1:0.725 2:0.05 5:0.15213275 7:0.014939024 8:0.047619048 +-1 1:0.731707 3:0.073171 7:0.014574659 8:0.023809524 +-1 1:0.987013 7:0.21777004 +-1 1:0.923077 7:0.092495305 +-1 1:0.916667 7:0.066692073 +-1 1:0.708333 3:0.058333 7:0.029674799 8:0.023809524 +-1 1:0.784091 3:0.022727 7:0.014273835 +-1 1:0.657895 2:0.078947 3:0.052632 5:0.29043728 7:0.012355585 8:0.023809524 +-1 1:0.756757 2:0.009009 3:0.045045 5:0.025442428 7:0.016095366 +-1 1:0.695652 7:0.009809122 +-1 1:0.776081 2:0.02799 3:0.040712 5:0.0570796 7:0.02026314 +-1 1:0.820895 7:0.015744451 8:0.023809524 +-1 1:0.708333 3:0.145833 4:0.0036900369 7:0.023755079 +-1 1:0.633027 2:0.119266 3:0.055046 4:0.011070111 5:0.13553889 6:0.065454065 7:0.015383756 +-1 1:0.759259 2:0.012346 3:0.049383 4:0.014760148 6:0.0071610072 7:0.015770854 8:0.023809524 +-1 1:0.739583 3:0.0625 4:0.011070111 7:0.015053354 8:0.071428571 +-1 1:0.735294 3:0.029412 7:0.010043043 +-1 1:0.758621 3:0.057471 4:0.0036900369 7:0.014578079 +-1 1:0.728 2:0.008 3:0.072 4:0.011070111 5:0.024682063 7:0.014731707 +-1 1:0.756757 3:0.040541 7:0.013815646 8:0.047619048 +-1 1:0.8 7:0.013414634 8:0.023809524 +-1 1:0.757143 3:0.014286 7:0.012020909 8:0.047619048 +-1 1:0.653846 3:0.153846 7:0.012898689 +-1 1:0.825688 7:0.015607518 +-1 1:0.795597 3:0.009434 7:0.01455361 +-1 1:0.783333 3:0.016667 7:0.015243902 8:0.047619048 +-1 1:0.622222 2:0.111111 3:0.088889 4:0.0036900369 6:0.086331086 7:0.018834689 +-1 1:0.809524 3:0.02381 7:0.018583043 +-1 1:0.745098 3:0.045752 7:0.013191457 +-1 1:0.833333 7:0.014566396 +-1 1:0.687075 2:0.034014 3:0.142857 4:0.040590406 5:0.03259881 6:0.0043740044 7:0.028455287 +-1 1:0.655172 2:0.206897 6:0.13584914 7:0.027859543 +-1 1:0.35 2:0.266667 3:0.133333 4:0.0036900369 5:0.66558824 6:0.08035808 7:0.011382116 8:0.047619048 +-1 1:0.794118 7:0.015184122 8:0.023809524 +-1 1:0.8125 7:0.013528963 +-1 1:0.690909 3:0.109091 7:0.017294902 8:0.023809524 +-1 1:0.5 2:0.1875 3:0.125 5:0.14335873 6:0.086538087 7:0.013211384 +-1 1:0.740741 7:0.016486 +-1 1:0.79 3:0.03 7:0.016646341 +-1 1:0.826087 7:0.012725348 +-1 1:0.701613 3:0.064516 7:0.012981902 +-1 1:0.745763 3:0.067797 7:0.017362549 +-1 1:0.779661 7:0.011368335 +-1 1:0.756881 3:0.055046 7:0.015607518 +-1 1:0.928571 2:0.035714 3:0.035714 5:0.018360592 7:0.088414634 +-1 1:0.951807 3:0.036145 4:0.0073800738 7:0.15302674 +-1 1:0.637363 2:0.137363 3:0.027473 5:0.033500813 6:0.12809113 7:0.014908872 +-1 1:0.833333 7:0.015243902 +-1 1:0.764706 2:0.014706 3:0.014706 7:0.013898854 8:0.047619048 +-1 1:0.775 2:0.05 3:0.025 4:0.0036900369 5:0.14199454 7:0.016006098 +-1 1:0.857143 7:0.01480836 +-1 1:0.756098 2:0.012195 3:0.04878 5:0.032129173 7:0.017251634 +-1 1:0.785047 2:0.009346 3:0.11215 4:0.011070111 5:0.0045472843 6:0.0018300018 7:0.093400957 +-1 1:0.684211 2:0.017544 3:0.093567 5:0.057936875 7:0.013764085 8:0.047619048 +-1 1:0.8 7:0.01097561 +-1 1:0.77451 2:0.009804 3:0.04902 5:0.025442428 6:0.01023901 7:0.017515543 8:0.023809524 +-1 1:0.763158 3:0.052632 7:0.013478817 +-1 1:0.783333 3:0.033333 7:0.01402439 +-1 1:0.527778 2:0.25 3:0.013889 5:0.06999836 6:0.18309918 7:0.018038616 +-1 1:0.563218 2:0.172414 3:0.068966 5:0.027455161 6:0.060774061 7:0.038057189 +-1 1:0.769231 3:0.025641 7:0.015348134 +-1 1:0.64 2:0.04 3:0.16 5:0.12023467 7:0.015121951 +-1 1:0.767647 3:0.055882 4:0.0036900369 7:0.018794835 +-1 1:0.5 2:0.111111 3:0.111111 5:0.13553889 7:0.018631439 +-1 1:0.761194 2:0.007463 3:0.037313 5:0.021610782 7:0.015698945 +-1 1:0.755814 2:0.023256 3:0.081395 4:0.011070111 5:0.016564042 7:0.031905841 +-1 1:0.794118 3:0.008824 7:0.015530848 +-1 1:0.75 2:0.03125 3:0.010417 5:0.052867771 7:0.017911585 +-1 1:0.857143 7:0.018466896 +-1 1:0.731707 3:0.073171 7:0.017102915 8:0.023809524 +-1 1:0.825397 3:0.015873 7:0.01838947 8:0.023809524 +-1 1:0.73 2:0.025 6:0.023436023 7:0.011707317 +-1 1:0.78125 3:0.0625 7:0.014481707 +-1 1:0.754717 2:0.048218 3:0.027254 5:0.01455131 6:0.021963022 7:0.026192671 +-1 1:0.775974 3:0.019481 7:0.013917488 +-1 1:0.819672 7:0.015493805 8:0.023809524 +-1 1:0.792453 7:0.014381037 8:0.071428571 +-1 1:0.785714 7:0.011106274 +-1 1:0.806452 7:0.01347364 +-1 1:0.8 7:0.012527713 +-1 1:0.777778 3:0.004274 7:0.011934543 8:0.095238095 +-1 1:0.785714 2:0.010582 3:0.007937 5:0.014998584 6:0.006036006 7:0.016034329 +-1 1:0.811765 7:0.015208037 8:0.023809524 +-1 1:0.84 4:0.011070111 7:0.018780488 8:0.023809524 +-1 1:0.711538 3:0.076923 7:0.01477486 8:0.071428571 +-1 1:0.76 7:0.012682927 +-1 1:0.731629 2:0.022364 3:0.025559 5:0.058853786 7:0.014805579 8:0.11904762 +-1 1:0.731629 2:0.022364 3:0.025559 5:0.059554515 7:0.01463025 8:0.095238095 +-1 1:0.708333 2:0.0625 3:0.041667 5:0.13805108 7:0.013719512 +-1 1:0.758883 2:0.015228 3:0.035533 4:0.011070111 5:0.044153385 7:0.015677232 8:0.047619048 +-1 1:0.757143 2:0.042857 3:0.014286 5:0.092600599 7:0.01402439 +-1 1:0.578947 2:0.105263 3:0.157895 5:0.3549789 7:0.013478817 +-1 1:0.746556 2:0.033058 3:0.033058 4:0.0036900369 5:0.057124327 6:0.0057480057 7:0.017536787 8:0.023809524 +-1 1:0.789062 3:0.023438 7:0.016577744 8:0.095238095 +-1 1:0.699346 2:0.065359 3:0.058824 6:0.052500053 7:0.015941335 +-1 1:0.837838 2:0.027027 5:0.069021812 7:0.017798287 +-1 1:0.767196 3:0.010582 7:0.012517744 8:0.023809524 +-1 1:0.790323 3:0.032258 7:0.014752165 8:0.023809524 +-1 1:0.663366 2:0.059406 3:0.108911 4:0.033210332 5:0.17202898 7:0.015696689 +-1 1:0.916667 7:0.019308945 +-1 1:0.629032 2:0.048387 3:0.096774 4:0.0073800738 5:0.042595381 7:0.01721086 8:0.023809524 +-1 1:0.771429 3:0.085714 7:0.017770037 +-1 1:0.705882 3:0.058824 7:0.010043043 8:0.023809524 +-1 1:0.555556 2:0.055556 3:0.222222 4:0.022140221 5:0.13553889 7:0.018631439 +-1 1:0.738292 2:0.041322 3:0.019284 5:0.10096462 6:0.0033870034 7:0.01488275 8:0.095238095 +-1 1:0.635802 2:0.049383 3:0.08642 5:0.026217703 7:0.032106293 +-1 1:0.535714 2:0.214286 3:0.071429 5:0.61102828 7:0.01328397 +-1 1:0.483871 2:0.129032 3:0.096774 5:0.24046934 7:0.012195122 +-1 1:0.80814 2:0.005814 3:0.005814 5:0.015184948 6:0.0061110061 7:0.017406409 +-1 1:0.678571 3:0.178571 4:0.0073800738 7:0.01785714 +-1 1:0.833333 7:0.01117886 +-1 1:0.78866 7:0.013656652 +-1 1:0.759259 2:0.009259 3:0.009259 7:0.012590335 8:0.071428571 +-1 1:0.780822 7:0.011443366 +-1 1:0.658537 2:0.073171 3:0.073171 4:0.0073800738 6:0.064515065 7:0.013831055 8:0.023809524 +-1 1:0.824324 7:0.015079104 +-1 1:0.792793 3:0.018018 7:0.014282573 8:0.023809524 +-1 1:0.806452 3:0.016129 7:0.020603854 8:0.023809524 +-1 1:0.644068 2:0.084746 3:0.050847 5:0.20012524 7:0.015398927 8:0.047619048 +-1 1:0.709677 2:0.032258 5:0.095574971 7:0.01534225 +-1 1:0.733333 3:0.066667 7:0.01382114 +-1 1:0.722222 3:0.111111 7:0.01541328 +-1 1:0.802326 7:0.013825866 +-1 1:0.769912 2:0.035398 3:0.035398 5:0.062640705 6:0.025209025 7:0.019263976 +-1 1:0.591837 2:0.163265 3:0.020408 6:0.14285714 7:0.010452963 +-1 1:0.75 2:0.041667 3:0.020833 5:0.063714162 7:0.014862805 +-1 1:0.786667 3:0.08 7:0.027317073 +-1 1:0.663866 2:0.10084 3:0.067227 5:0.039867011 6:0.054546055 7:0.023954701 +-1 1:0.622222 2:0.022222 3:0.155556 4:0.0036900369 7:0.013414634 +-1 1:0.583333 2:0.125 3:0.125 7:0.013973579 +-1 1:0.666667 3:0.133333 4:0.0036900369 7:0.011788616 +-1 1:0.833333 7:0.013211384 +-1 1:0.776471 3:0.011765 7:0.013271165 8:0.047619048 +-1 1:0.72973 3:0.027027 7:0.012359921 8:0.047619048 +-1 1:0.612903 2:0.177419 3:0.048387 5:0.34056178 7:0.019374506 +-1 1:0.725714 2:0.005714 3:0.068571 4:0.011070111 7:0.015818817 +-1 1:0.765799 3:0.018587 7:0.013305829 8:0.095238095 +-1 1:0.69697 3:0.121212 7:0.015336293 8:0.023809524 +-1 1:0.758065 3:0.016129 7:0.011605037 8:0.023809524 +-1 1:0.744186 2:0.046512 3:0.046512 5:0.11647757 7:0.018150878 +-1 1:0.692308 3:0.104895 4:0.0073800738 7:0.016501793 +-1 1:0.754386 2:0.023392 3:0.035088 5:0.055215959 7:0.014441591 +-1 1:0.789474 3:0.052632 7:0.02000428 +-1 1:0.631579 2:0.052632 3:0.175439 5:0.09165387 7:0.026101841 +-1 1:0.747368 3:0.063158 7:0.018164311 8:0.047619048 +-1 1:0.681818 2:0.045455 3:0.045455 5:0.20147451 7:0.010254988 +-1 1:0.714286 3:0.053571 4:0.0036900369 7:0.011541811 8:0.047619048 +-1 1:0.726708 2:0.012422 3:0.080745 4:0.011070111 6:0.0068640069 7:0.016550524 8:0.023809524 +-1 1:0.488372 2:0.302326 3:0.046512 5:0.22936949 6:0.18461418 7:0.018434488 +-1 1:0.772152 3:0.022152 7:0.013893177 +-1 1:0.67354 2:0.072165 3:0.058419 6:0.051252051 7:0.018397451 +-1 1:0.757895 7:0.010718872 8:0.047619048 +-1 1:0.802469 3:0.012346 7:0.019346579 +-1 1:0.696721 2:0.065574 3:0.065574 5:0.067978173 6:0.018237018 7:0.016443421 +-1 1:0.604478 2:0.074627 3:0.11194 4:0.025830258 5:0.19114249 7:0.014197305 +-1 1:0.734628 2:0.019417 3:0.042071 4:0.025830258 5:0.049170307 7:0.014957768 +-1 1:0.662338 2:0.077922 3:0.012987 5:0.050713402 6:0.061224061 7:0.011640799 +-1 1:0.727273 3:0.090909 4:0.0036900369 7:0.01518847 +-1 1:0.8 7:0.013747226 +-1 1:0.763975 3:0.018634 7:0.013520677 8:0.071428571 +-1 1:0.58209 2:0.238806 3:0.074627 4:0.10332103 5:0.022154965 6:0.044577045 7:0.061248634 +-1 1:0.773946 2:0.015326 3:0.038314 6:0.010989011 7:0.019133726 +-1 1:0.730769 3:0.038462 7:0.012312384 +-1 1:0.722222 3:0.166667 7:0.021341463 +-1 1:0.774648 3:0.014085 7:0.011937482 8:0.11904762 +-1 1:0.691892 2:0.108108 3:0.010811 6:0.08030708 7:0.01723797 +-1 1:0.66 3:0.12 4:0.0073800738 7:0.011463415 +-1 1:0.648352 2:0.131868 3:0.065934 5:0.18636411 6:0.0083340083 7:0.02412222 +-1 1:0.692308 3:0.153846 7:0.01665103 +-1 1:0.790909 7:0.014135256 8:0.047619048 +-1 1:0.758621 3:0.068966 4:0.0036900369 7:0.015979817 +-1 1:0.783784 2:0.013514 3:0.027027 5:0.0394421 7:0.0155735 +-1 1:0.755102 7:0.012070683 8:0.047619048 +-1 1:0.697674 2:0.093023 3:0.069767 5:0.039233373 6:0.015789016 7:0.026942713 +-1 1:0.73913 2:0.057971 3:0.039855 4:0.011070111 5:0.02609843 6:0.028005028 7:0.018933366 +-1 1:0.809524 7:0.011614402 +-1 1:0.72093 2:0.011628 3:0.093023 7:0.015598415 +-1 1:0.790698 7:0.016307433 8:0.023809524 +-1 1:0.786667 3:0.053333 7:0.016260165 +-1 1:0.777778 7:0.01111111 8:0.023809524 +-1 1:0.685484 2:0.084677 3:0.048387 5:0.046531391 6:0.044943045 7:0.01969414 +-1 1:0.777778 3:0.051282 7:0.017302482 8:0.071428571 +-1 1:0.771812 3:0.020134 7:0.014077591 8:0.071428571 +-1 1:0.829787 2:0.010638 3:0.074468 4:0.011070111 7:0.1031396 +-1 1:0.5625 2:0.21875 3:0.0625 5:0.081918209 6:0.13186813 7:0.017339939 +-1 1:0.75 2:0.055556 3:0.027778 6:0.032967033 7:0.01541328 +-1 1:0.7125 2:0.04375 3:0.04375 5:0.10296244 6:0.0082860083 7:0.013795732 +-1 1:0.672598 2:0.078292 3:0.05694 5:0.025211337 6:0.047352047 7:0.019247463 8:0.023809524 +-1 1:0.769231 7:0.010787994 8:0.023809524 +-1 1:0.755196 2:0.016166 3:0.036952 4:0.0036900369 5:0.013656762 6:0.0054960055 7:0.015377683 +-1 1:0.852941 7:0.015602585 +-1 1:0.715 2:0.015 3:0.035 4:0.0073800738 5:0.036184456 7:0.012560976 8:0.071428571 +-1 1:0.810127 2:0.012658 3:0.025316 5:0.027611707 7:0.020839768 +-1 1:0.6 2:0.181818 3:0.054545 5:0.053247954 6:0.17142917 7:0.015521067 +-1 1:0.730924 2:0.028112 3:0.044177 5:0.02456279 6:0.0049410049 7:0.014864335 +-1 1:0.679487 2:0.038462 3:0.076923 5:0.073807642 7:0.015791122 +-1 1:0.666667 2:0.033755 3:0.113924 4:0.011070111 5:0.012218031 6:0.01967102 7:0.015694146 +-1 1:0.720524 2:0.030568 3:0.039301 4:0.0036900369 5:0.05296468 6:0.010656011 7:0.014990945 +-1 1:0.85 3:0.05 4:0.040590406 7:0.029369921 +-1 1:0.656716 2:0.067164 3:0.059701 4:0.0036900369 6:0.060693061 7:0.015744451 +-1 1:0.822086 7:0.017731555 8:0.023809524 +-1 1:0.698413 2:0.031746 3:0.047619 4:0.0073800738 7:0.012001549 +-1 1:0.683616 2:0.107345 3:0.016949 5:0.051764495 6:0.09027909 7:0.014882183 +-1 1:0.781457 7:0.013002744 8:0.023809524 +-1 1:0.810219 7:0.015488695 +-1 1:0.654762 2:0.035714 3:0.035714 5:0.10212008 7:0.015897213 8:0.095238095 +-1 1:0.720588 2:0.009804 3:0.078431 4:0.011070111 5:0.028782073 7:0.015483024 +-1 1:0.782609 2:0.043478 6:0.027522028 7:0.014448567 +-1 1:0.773852 2:0.003534 3:0.031802 4:0.0073800738 7:0.016030335 +-1 1:0.717949 3:0.115385 4:0.0036900369 7:0.020051591 8:0.023809524 +-1 1:0.809524 3:0.047619 7:0.014518 +-1 1:0.64 2:0.08 3:0.133333 4:0.0036900369 5:0.1125192 6:0.011322011 7:0.021544713 +-1 1:0.665706 2:0.069164 3:0.097983 4:0.025830258 5:0.027134615 6:0.03002703 7:0.019311872 +-1 1:0.770833 3:0.034722 4:0.0036900369 7:0.019986451 8:0.071428571 +-1 1:0.779661 3:0.016949 7:0.014158744 8:0.047619048 +-1 1:0.761006 2:0.012579 6:0.0093450093 7:0.012310171 8:0.11904762 +-1 1:0.791262 7:0.013467915 8:0.023809524 +-1 1:0.772 3:0.032 7:0.014463415 8:0.047619048 +-1 1:0.724868 3:0.074074 4:0.0036900369 7:0.015098726 8:0.047619048 +-1 1:0.786667 7:0.013577238 +-1 1:0.684932 2:0.068493 3:0.068493 5:0.075298555 7:0.016538591 +-1 1:0.775623 2:0.01385 3:0.036011 4:0.0073800738 5:0.014051854 6:0.0028290028 7:0.017921085 8:0.023809524 +-1 1:0.775281 7:0.014593037 +-1 1:0.784314 7:0.011657104 +-1 1:0.797872 3:0.042553 7:0.020692787 +-1 1:0.68932 3:0.165049 4:0.022140221 7:0.025337439 +-1 1:0.763636 7:0.010753878 8:0.047619048 +-1 1:0.701342 2:0.07047 3:0.04698 4:0.0036900369 5:0.038323916 6:0.05013005 7:0.015919134 +-1 1:0.678161 2:0.034483 3:0.08046 4:0.018450185 6:0.033150033 7:0.012685732 8:0.023809524 +-1 1:0.757778 2:0.026667 3:0.017778 6:0.025164025 7:0.014539293 8:0.023809524 +-1 1:0.648936 2:0.042553 3:0.106383 4:0.0036900369 6:0.028125028 7:0.020757652 +-1 1:0.759494 3:0.037975 7:0.01288978 8:0.023809524 +-1 1:0.708791 2:0.054945 3:0.038462 5:0.0642658 6:0.012930013 7:0.015545433 8:0.023809524 +-1 1:0.806452 7:0.013571988 +-1 1:0.746032 3:0.063492 7:0.013840494 8:0.047619048 +-1 1:0.727979 3:0.090674 4:0.092250923 7:0.021767976 +-1 1:0.790698 3:0.046512 7:0.014747591 +-1 1:0.887097 7:0.062549171 +-1 1:0.571429 2:0.166667 3:0.119048 5:0.18330774 6:0.073770074 7:0.017711963 +-1 1:0.707317 3:0.02439 7:0.014128494 +-1 1:0.695652 3:0.072464 7:0.012813713 8:0.023809524 +-1 1:0.952381 7:0.033101043 +-1 1:0.971429 4:0.077490775 7:0.08275261 +-1 1:0.9 4:0.070110701 7:0.041585366 +-1 1:0.775 3:0.025 7:0.013338415 +-1 1:0.9 7:0.028506098 +-1 1:0.720721 2:0.018018 3:0.063063 4:0.011070111 7:0.017633488 +-1 1:0.663265 2:0.040816 3:0.061224 4:0.011070111 6:0.037191037 7:0.015057244 +-1 1:0.658228 3:0.177215 7:0.020762579 +-1 1:0.73913 3:0.095652 4:0.029520295 7:0.017815482 +-1 1:0.74359 2:0.051282 3:0.025641 4:0.0036900369 6:0.044118044 7:0.01594747 8:0.023809524 +-1 1:0.869565 7:0.016171793 +-1 1:0.759382 2:0.00883 3:0.006623 6:0.0094350094 7:0.01284122 8:0.047619048 +-1 1:0.827586 7:0.01633025 +-1 1:0.75 2:0.05 7:0.025 8:0.023809524 +-1 1:0.806452 7:0.012588512 8:0.023809524 +-1 1:0.753086 3:0.049383 4:0.025830258 7:0.020475762 8:0.023809524 +-1 1:0.631579 2:0.052632 3:0.157895 5:0.16941989 7:0.014120665 +-1 1:0.626168 2:0.121495 3:0.084112 4:0.025830258 5:0.022117693 6:0.08011808 7:0.01920447 +-1 1:0.658088 2:0.066176 3:0.088235 4:0.018450185 5:0.052569588 6:0.033849034 7:0.015894012 +-1 1:0.69697 2:0.121212 6:0.12328812 7:0.013488543 +-1 1:0.690141 3:0.15493 7:0.021727927 +-1 1:0.717391 2:0.032609 3:0.086957 4:0.0073800738 5:0.080442205 7:0.018425238 +-1 1:0.796875 7:0.012004573 +-1 1:0.512315 2:0.20197 3:0.108374 4:0.029520295 5:0.32088918 6:0.034767035 7:0.018142494 8:0.023809524 +-1 1:0.764706 3:0.176471 4:0.0073800738 7:0.02618364 +-1 1:0.62963 2:0.08642 3:0.074074 5:0.043340838 6:0.052326052 7:0.012947909 +-1 1:0.719626 3:0.093458 4:0.025830258 7:0.014987463 +-1 1:0.666667 2:0.066667 3:0.111111 4:0.011070111 6:0.041097041 7:0.019783195 +-1 1:0.903226 7:0.023800159 +-1 1:0.64 2:0.1 3:0.04 5:0.28130544 7:0.012926829 8:0.023809524 +-1 1:0.55102 2:0.102041 3:0.122449 5:0.1183263 6:0.047619048 7:0.015679445 +-1 1:0.678571 2:0.053571 3:0.178571 4:0.0036900369 6:0.01036201 7:0.063044427 +-1 1:0.568182 2:0.113636 3:0.159091 5:0.12852415 6:0.051723052 7:0.01607539 +-1 1:0.717277 2:0.031414 3:0.068063 5:0.072942913 7:0.016313372 +-1 1:0.724638 2:0.009662 3:0.067633 5:0.024928063 7:0.017615177 +-1 1:0.633333 2:0.166667 3:0.083333 4:0.011070111 6:0.071430071 7:0.029878049 +-1 1:0.875 3:0.025 4:0.0073800738 7:0.054306402 +-1 1:0.789474 3:0.052632 7:0.016046213 8:0.023809524 +-1 1:0.833333 7:0.016034329 8:0.023809524 +-1 1:0.586777 2:0.173554 3:0.041322 6:0.13548314 7:0.015621854 +-1 1:0.763158 2:0.017544 3:0.026316 6:0.011451011 7:0.014013695 +-1 1:0.630435 2:0.065217 3:0.130435 4:0.011070111 6:0.053571054 7:0.014846238 +-1 1:0.708571 3:0.12 4:0.033210332 7:0.020313591 8:0.023809524 +-1 1:0.747059 3:0.064706 7:0.014849354 +-1 1:0.80531 7:0.016026335 8:0.047619048 +-1 1:0.770833 3:0.041667 7:0.015434451 8:0.047619048 +-1 1:0.731343 3:0.014925 7:0.010101927 8:0.047619048 +-1 1:0.545455 2:0.236364 3:0.054545 4:0.0073800738 5:0.094359877 6:0.17088617 7:0.017516628 +-1 1:0.772727 2:0.045455 5:0.15213275 6:0.061224061 7:0.013580933 +-1 1:0.789062 3:0.023438 7:0.015458268 +-1 1:0.724638 2:0.043478 3:0.072464 6:0.031251031 7:0.016967128 +-1 1:0.796748 7:0.015070396 8:0.047619048 +-1 1:0.760417 3:0.020833 7:0.013338415 8:0.023809524 +-1 1:0.763359 2:0.022901 3:0.007634 6:0.017856018 7:0.015639543 +-1 1:0.622951 2:0.04918 3:0.114754 6:0.037974038 7:0.015793683 +-1 1:0.710938 2:0.023438 3:0.03125 6:0.02020202 7:0.014148244 +-1 1:0.765957 3:0.042553 7:0.015762841 8:0.095238095 +-1 1:0.804878 7:0.015020823 8:0.047619048 +-1 1:0.72093 3:0.139535 4:0.018450185 7:0.023397616 +-1 1:0.666667 2:0.055556 3:0.055556 7:0.010162604 +-1 1:0.803922 7:0.013868963 8:0.023809524 +-1 1:0.692308 2:0.076923 3:0.025641 5:0.17539845 6:0.070587071 7:0.013289555 +-1 1:0.653846 3:0.115385 7:0.014305817 +-1 1:0.777778 7:0.010388439 +-1 1:0.703125 3:0.0625 4:0.0073800738 7:0.011528201 +-1 1:0.8 7:0.011890244 +-1 1:0.698925 3:0.075269 4:0.014760148 7:0.020587463 +-1 1:0.744444 2:0.005556 3:0.083333 7:0.018936317 8:0.023809524 +-1 1:0.727273 2:0.019481 3:0.045455 4:0.014760148 7:0.012670256 8:0.047619048 +-1 1:0.673469 2:0.061224 3:0.081633 5:0.03080226 6:0.024792025 7:0.015057244 +-1 1:0.617647 2:0.107843 3:0.019608 6:0.087867088 7:0.014287421 +-1 1:0.698113 2:0.056604 3:0.056604 4:0.0036900369 5:0.017577863 6:0.038916039 7:0.016260165 8:0.023809524 +-1 1:0.848485 3:0.030303 7:0.031042128 +-1 1:0.797468 3:0.012658 7:0.015514049 8:0.071428571 +-1 1:0.701493 3:0.119403 4:0.0036900369 7:0.016108482 8:0.047619048 +-1 1:0.770833 7:0.011517616 8:0.11904762 +-1 1:0.802817 7:0.014943317 +-1 1:0.610778 2:0.095808 3:0.08982 5:0.10935846 6:0.036675037 7:0.014933549 8:0.023809524 +-1 1:0.77551 3:0.040816 7:0.018043805 8:0.023809524 +-1 1:0.730435 2:0.026087 3:0.043478 6:0.022557023 7:0.014103927 8:0.023809524 +-1 1:0.781818 2:0.030303 3:0.030303 5:0.027156978 6:0.010929011 7:0.02028825 +-1 1:0.642857 2:0.142857 3:0.035714 6:0.095238095 7:0.013719512 +-1 1:0.746667 3:0.026667 7:0.011626018 8:0.023809524 +-1 1:0.712042 3:0.094241 4:0.0073800738 7:0.015451409 8:0.047619048 +-1 1:0.668639 2:0.071006 3:0.094675 5:0.029698985 6:0.041832042 7:0.01811228 +-1 1:0.777778 7:0.01084011 +-1 1:0.714286 7:0.010017421 +-1 1:0.777778 3:0.074074 7:0.015356817 +-1 1:0.642105 2:0.063158 3:0.105263 4:0.014760148 5:0.055014685 6:0.022140022 7:0.017394098 8:0.047619048 +-1 1:0.723077 2:0.010256 3:0.05641 4:0.011070111 7:0.016885555 8:0.047619048 +-1 1:0.826923 3:0.057692 4:0.0036900369 7:0.026149159 +-1 1:0.731707 2:0.073171 3:0.02439 6:0.042552043 7:0.020969659 +-1 1:0.84375 7:0.021150915 +-1 1:0.721212 3:0.060606 7:0.012786402 8:0.047619048 +-1 1:0.722222 3:0.111111 4:0.011070111 7:0.015074524 +-1 1:0.73913 2:0.021739 3:0.086957 4:0.0073800738 6:0.022389022 7:0.017762457 +-1 1:0.802326 3:0.034884 4:0.033210332 7:0.017938171 8:0.023809524 +-1 1:0.705263 2:0.010526 3:0.063158 4:0.0036900369 7:0.012965341 +-1 1:0.694915 2:0.050847 3:0.016949 6:0.04026904 7:0.015398927 8:0.023809524 +-1 1:0.684211 2:0.078947 3:0.052632 4:0.0036900369 6:0.070587071 7:0.01363928 +-1 1:0.623188 2:0.057971 3:0.115942 4:0.0073800738 6:0.06040206 7:0.013167195 +-1 1:0.9 4:0.022140221 7:0.027286585 +-1 1:0.631579 2:0.070175 3:0.105263 5:0.044637932 6:0.035928036 7:0.017864787 +-1 1:0.684211 2:0.105263 3:0.052632 5:0.16941989 6:0.068181068 7:0.014120665 +-1 1:0.816901 3:0.070423 7:0.026709037 +-1 1:0.727273 3:0.136364 7:0.01773836 +-1 1:0.763636 3:0.054545 4:0.0073800738 7:0.014301549 8:0.023809524 +-1 1:0.695652 2:0.043478 3:0.065217 5:0.076066375 7:0.012990457 +-1 1:0.705882 2:0.035294 3:0.070588 6:0.014814015 7:0.029053085 +-1 1:0.75 2:0.043478 3:0.076087 4:0.0073800738 6:0.020691021 7:0.02883086 +-1 1:0.69 2:0.04 3:0.08 6:0.02020202 7:0.018109756 8:0.023809524 +-1 1:0.782609 7:0.013586957 +-1 1:0.669811 2:0.056604 3:0.075472 5:0.058585422 6:0.023577024 7:0.014639896 8:0.023809524 +-1 1:0.678571 2:0.035714 6:0.065217065 7:0.010017421 8:0.023809524 +-1 1:0.764706 7:0.012613579 +-1 1:0.761905 3:0.047619 7:0.011614402 +-1 1:0.659341 2:0.054945 3:0.10989 4:0.011070111 5:0.031719172 6:0.038298038 7:0.015746445 +-1 1:0.735632 3:0.08046 4:0.0073800738 7:0.014297732 +-1 1:0.651376 2:0.100917 3:0.059633 5:0.026433885 6:0.07978808 7:0.015775341 8:0.023809524 +-1 1:0.836735 7:0.015057244 +-1 1:0.736364 3:0.118182 4:0.0036900369 7:0.021341463 +-1 1:0.784091 3:0.045455 7:0.024320951 +-1 1:0.793103 2:0.068966 4:0.011070111 5:0.16205478 7:0.019343988 +-1 1:0.65625 2:0.0625 3:0.083333 4:0.0073800738 6:0.054744055 7:0.017403457 +-1 1:0.777778 7:0.010433604 8:0.023809524 +-1 1:0.764706 3:0.058824 7:0.012195122 +-1 1:0.71831 2:0.035211 3:0.070423 4:0.0073800738 5:0.016564042 6:0.026667027 7:0.019323256 +-1 1:0.77305 2:0.007092 3:0.049645 4:0.0036900369 5:0.016638588 7:0.019373811 +-1 1:0.795918 7:0.01474614 8:0.023809524 +-1 1:0.699248 2:0.06015 3:0.045113 5:0.091184232 6:0.018348018 7:0.01499175 +-1 1:0.6875 2:0.0625 3:0.125 5:0.078466745 7:0.018102134 +-1 1:0.85 7:0.015243902 +-1 1:0.796296 3:0.037037 7:0.020551037 +-1 1:0.784314 3:0.058824 7:0.015901482 +-1 1:0.773585 3:0.037736 4:0.0036900369 7:0.01633686 8:0.023809524 +-1 1:0.730769 7:0.017120073 8:0.023809524 +-1 1:0.751825 2:0.010949 3:0.029197 4:0.0036900369 7:0.014843335 8:0.095238095 +-1 1:0.753247 3:0.038961 7:0.012511878 8:0.071428571 +-1 1:0.727273 3:0.090909 4:0.0036900369 7:0.013580933 8:0.023809524 +-1 1:0.655172 3:0.172414 4:0.0073800738 7:0.017872165 +-1 1:0.636364 2:0.09596 3:0.070707 4:0.014760148 6:0.083094083 7:0.016121579 +-1 1:0.753425 3:0.054795 7:0.014032744 +-1 1:0.708861 2:0.075949 3:0.031646 4:0.0036900369 5:0.017794045 6:0.042960043 7:0.016170116 +-1 1:0.778524 3:0.040268 7:0.016532982 +-1 1:0.707182 2:0.016575 3:0.066298 4:0.033210332 6:0.014493014 7:0.013946909 8:0.023809524 +-1 1:0.808 7:0.013560976 8:0.047619048 +-1 1:0.725806 2:0.048387 3:0.016129 6:0.046875047 7:0.012588512 8:0.023809524 +-1 1:0.689076 2:0.02521 3:0.151261 4:0.04797048 6:0.011649012 7:0.026388604 +-1 1:0.702479 2:0.049587 3:0.082645 5:0.066561806 6:0.017856018 7:0.016932073 +-1 1:0.76 3:0.04 7:0.011219512 +-1 1:0.466667 2:0.266667 3:0.133333 5:0.21298436 6:0.17142917 7:0.01422764 +-1 1:0.760563 3:0.070423 4:0.0073800738 7:0.019580902 8:0.023809524 +-1 1:0.763158 2:0.078947 5:0.24046934 7:0.014922976 +-1 1:0.657143 2:0.114286 3:0.051429 5:0.081918209 6:0.079122079 7:0.015853659 +-1 1:0.54386 2:0.122807 3:0.175439 4:0.0073800738 5:0.17336335 6:0.034884035 7:0.018399659 +-1 1:0.722222 3:0.166667 4:0.0073800738 7:0.017953927 +-1 1:0.785714 3:0.142857 4:0.0036900369 7:0.023954701 +-1 1:0.715328 2:0.036496 3:0.043796 5:0.046881756 7:0.014153463 +-1 1:0.606061 2:0.090909 3:0.060606 5:0.22819913 7:0.018107909 +-1 1:0.625 2:0.0625 3:0.125 7:0.012957317 +-1 1:0.795396 2:0.005115 3:0.005115 7:0.01501778 +-1 1:0.714286 2:0.020408 3:0.061224 4:0.0073800738 5:0.072376366 7:0.012817323 8:0.047619048 +-1 1:0.762452 2:0.019157 3:0.030651 5:0.032270809 7:0.016190073 +-1 1:0.819444 7:0.018970189 8:0.023809524 +-1 1:0.700637 2:0.025478 3:0.044586 4:0.014760148 5:0.06160452 7:0.015664646 8:0.023809524 +-1 1:0.791667 3:0.083333 7:0.017784555 +-1 1:0.775281 2:0.033708 3:0.022472 6:0.024390024 7:0.016853933 +-1 1:0.763819 2:0.015075 3:0.005025 5:0.04809685 7:0.014248073 8:0.023809524 +-1 1:0.661972 2:0.028169 3:0.169014 4:0.018450185 6:0.011493011 7:0.022414976 +-1 1:0.736842 3:0.031579 7:0.0105905 +-1 1:0.8 7:0.01097561 +-1 1:0.813559 3:0.016949 7:0.017207524 +-1 1:0.815789 3:0.026316 7:0.016688061 +-1 1:0.732824 2:0.022901 3:0.053435 4:0.0036900369 5:0.069454177 7:0.014987896 +-1 1:0.657143 2:0.085714 3:0.085714 6:0.073170073 7:0.014285713 +-1 1:0.752941 2:0.023529 3:0.070588 5:0.014305309 6:0.023034023 7:0.018687232 +-1 1:0.736264 2:0.028571 3:0.037363 5:0.051540858 6:0.0025920026 7:0.015505226 +-1 1:0.818182 7:0.013858091 8:0.023809524 +-1 1:0.736842 3:0.078947 4:0.011070111 7:0.020913567 8:0.023809524 +-1 1:0.619048 2:0.119048 5:0.3467267 7:0.012485482 +-1 1:0.790541 3:0.02027 7:0.015037902 +-1 1:0.817073 7:0.015987506 8:0.023809524 +-1 1:0.658537 3:0.146341 7:0.013682329 +-1 1:0.698113 2:0.056604 3:0.037736 5:0.071675637 7:0.011965024 +-1 1:0.677419 2:0.010753 3:0.075269 7:0.014096512 8:0.023809524 +-1 1:0.711864 2:0.033898 3:0.084746 7:0.033898305 +-1 1:0.732143 3:0.083333 4:0.018450185 7:0.018510451 +-1 1:0.7125 2:0.05 3:0.025 5:0.045733753 6:0.055215055 7:0.01242378 +-1 1:0.728395 3:0.074074 4:0.011070111 7:0.017464616 +-1 1:0.4 2:0.325 3:0.1 5:0.33579085 6:0.18918919 7:0.016920732 +-1 1:0.709677 3:0.064516 7:0.011211646 8:0.071428571 +-1 1:0.691489 2:0.074468 3:0.106383 4:0.0073800738 6:0.033936034 7:0.028671506 +-1 1:0.803922 2:0.058824 3:0.019608 4:0.014760148 6:0.033708034 7:0.021281683 +-1 1:0.706767 3:0.067669 4:0.0036900369 7:0.014487439 +-1 1:1 7:0.10060976 +-1 1:0.775 2:0.0125 3:0.0125 4:0.0036900369 5:0.043847748 7:0.012957317 +-1 1:0.825397 3:0.015873 7:0.020518774 +-1 1:0.786885 3:0.016393 7:0.013294683 +-1 1:0.619048 2:0.111111 3:0.087302 5:0.039971374 6:0.064344064 7:0.018050713 +-1 1:0.61194 2:0.074627 3:0.164179 5:0.10898573 7:0.03112486 +-1 1:0.901961 2:0.019608 3:0.019608 7:0.050215207 +-1 1:0.666667 3:0.133333 7:0.011788616 +-1 1:0.786802 2:0.030457 3:0.015228 5:0.073807642 7:0.018756963 +-1 1:0.685393 3:0.05618 7:0.023910659 +-1 1:0.761905 3:0.047619 7:0.017131244 8:0.047619048 +-1 1:0.726562 2:0.007812 3:0.054688 7:0.012719134 +-1 1:0.731707 3:0.097561 7:0.021713268 8:0.023809524 +-1 1:0.746988 2:0.036145 3:0.024096 5:0.035498636 7:0.015427561 8:0.023809524 +-1 1:0.612903 3:0.129032 7:0.01455547 +-1 1:0.693878 3:0.020408 7:0.015430561 +-1 1:0.70068 2:0.047619 3:0.027211 4:0.0073800738 5:0.024518062 6:0.039474039 7:0.012609921 8:0.047619048 +-1 1:0.764706 2:0.009804 3:0.029412 4:0.014760148 7:0.014825445 +-1 1:0.727273 2:0.027273 3:0.054545 5:0.026717159 7:0.015465634 +-1 1:0.648456 3:0.009501 4:0.0036900369 7:0.023550201 8:0.023809524 +-1 1:0.612188 2:0.146814 3:0.080332 4:0.014760148 5:0.042155562 6:0.036537037 7:0.038831835 +-1 1:0.739362 2:0.026596 3:0.047872 4:0.029520295 6:0.017856018 7:0.016346652 +-1 1:0.779661 7:0.010644896 +-1 1:0.9 7:0.021341463 +-1 1:0.652174 2:0.086957 3:0.086957 5:0.040962832 6:0.049452049 7:0.016083421 +-1 1:0.735294 3:0.058824 4:0.0073800738 7:0.01201578 +-1 1:0.926471 3:0.029412 4:0.0036900369 7:0.12688307 +-1 1:0.78125 3:0.052083 7:0.016514226 +-1 1:0.813953 7:0.014180372 +-1 1:0.709677 3:0.096774 4:0.0073800738 7:0.013965384 8:0.023809524 +-1 1:0.791209 3:0.065934 4:0.055350554 7:0.02747253 +-1 1:0.779528 4:0.0073800738 7:0.014691762 8:0.023809524 +-1 1:0.75 2:0.027778 3:0.166667 4:0.055350554 5:0.022520239 7:0.056063689 +-1 1:0.733656 2:0.041162 3:0.021792 5:0.064198709 6:0.0057420057 7:0.015428451 8:0.023809524 +-1 1:0.782609 2:0.043478 5:0.13553889 7:0.014581122 +-1 1:0.710526 3:0.131579 7:0.015404366 +-1 1:0.730159 3:0.087302 4:0.0036900369 7:0.016550524 8:0.023809524 +-1 1:0.62 2:0.08 3:0.08 5:0.25269483 7:0.014390244 +-1 1:0.666667 2:0.064516 3:0.080645 5:0.040291921 6:0.032433032 7:0.018194335 8:0.023809524 +-1 1:0.771084 3:0.012048 7:0.015794884 8:0.023809524 +-1 1:0.789474 3:0.210526 4:0.025830258 7:0.11890244 +-1 1:0.777778 3:0.074074 7:0.014905146 +-1 1:0.837209 7:0.015314805 +-1 1:0.740816 2:0.016327 3:0.057143 5:0.017794045 6:0.0047730048 7:0.01564211 8:0.023809524 +-1 1:0.666667 2:0.069767 3:0.100775 6:0.014967015 7:0.066316884 +-1 1:0.810811 7:0.015120305 8:0.023809524 +-1 1:0.743719 2:0.015075 3:0.040201 4:0.0036900369 5:0.015117857 7:0.015106018 +-1 1:0.75 2:0.050505 3:0.017677 5:0.027328433 6:0.032997033 7:0.016799085 +-1 1:0.75 2:0.039474 3:0.052632 5:0.066561806 7:0.017971756 +-1 1:0.675676 2:0.054054 3:0.162162 4:0.018450185 5:0.059636515 7:0.030899799 +-1 1:0.753425 2:0.054795 3:0.027397 6:0.045000045 7:0.016705646 +-1 1:0.707317 2:0.03252 3:0.089431 5:0.062118885 7:0.017846518 +-1 1:0.647059 2:0.058824 3:0.058824 7:0.008967 +-1 1:0.818182 7:0.01465878 +-1 1:0.764706 2:0.023529 3:0.011765 5:0.037272822 7:0.014347201 8:0.047619048 +-1 1:0.863636 7:0.016352549 +-1 1:0.790541 3:0.040541 4:0.022140221 7:0.018004287 8:0.023809524 +-1 1:0.707692 2:0.061538 3:0.092308 4:0.014760148 6:0.042705043 7:0.026360226 8:0.023809524 +-1 1:0.75 7:0.013211384 +-1 1:0.616883 2:0.181818 3:0.051948 5:0.078951292 6:0.029127029 7:0.044860628 +-1 1:0.72973 2:0.054054 3:0.027027 4:0.0036900369 5:0.1172603 7:0.018333884 +-1 1:0.764706 3:0.058824 7:0.012195122 +-1 1:0.642857 2:0.142857 3:0.071429 5:0.48093868 7:0.013501744 +-1 1:0.6 2:0.2 5:0.21298436 6:0.17142917 7:0.01422764 +-1 1:0.746528 2:0.013889 3:0.045139 5:0.009720752 6:0.0039120039 7:0.016238988 +-1 1:0.758278 2:0.003311 3:0.049669 5:0.0089082045 7:0.01689953 +-1 1:0.688889 2:0.044444 3:0.111111 4:0.0036900369 5:0.059636515 7:0.016937671 +-1 1:0.705357 2:0.017857 3:0.035714 7:0.017693817 +-1 1:0.776119 3:0.037313 4:0.0036900369 7:0.018338189 +-1 1:0.636905 2:0.107143 3:0.02381 6:0.10655711 7:0.01328397 +-1 1:0.665254 2:0.09322 3:0.029661 5:0.052219224 6:0.068301068 7:0.014753 +-1 1:0.67037 2:0.085185 3:0.033333 5:0.057966693 6:0.060654061 7:0.014521226 +-1 1:0.67037 2:0.085185 3:0.033333 5:0.058510876 6:0.061224061 7:0.014385726 +-1 1:0.67037 2:0.085185 3:0.033333 5:0.057698329 6:0.06037206 7:0.014588982 +-1 1:0.685606 2:0.087121 3:0.037879 5:0.03645282 6:0.047676048 7:0.018893201 +-1 1:0.666667 2:0.087121 3:0.037879 5:0.057698329 6:0.06037206 7:0.014920549 +-1 1:0.701923 3:0.144231 7:0.019113506 +-1 1:0.777778 3:0.02963 7:0.017660341 8:0.023809524 +-1 1:0.761111 3:0.033333 4:0.018450185 7:0.013516262 8:0.023809524 +-1 1:0.65 2:0.025 3:0.1 5:0.065972895 7:0.01722561 +-1 1:0.716418 2:0.074627 3:0.059701 5:0.058928332 6:0.023715024 7:0.023025116 8:0.023809524 +-1 1:0.75 3:0.09375 4:0.0073800738 7:0.018483232 8:0.023809524 +-1 1:0.731544 3:0.060403 7:0.016860372 +-1 1:0.7 3:0.066667 7:0.0099593476 8:0.023809524 +-1 1:0.715909 3:0.017045 7:0.013234482 8:0.095238095 +-1 1:0.681818 3:0.181818 7:0.018292683 +-1 1:0.746154 2:0.046154 3:0.023077 5:0.13351125 7:0.015712945 8:0.023809524 +-1 1:0.794872 7:0.01665103 +-1 1:0.817308 7:0.017940902 8:0.047619048 +-1 1:0.587209 2:0.145349 3:0.063953 5:0.047276848 6:0.10782311 7:0.016768293 8:0.023809524 +-1 1:0.892857 7:0.022430311 +-1 1:0.741497 3:0.054422 4:0.0073800738 7:0.014061726 +-1 1:0.637931 2:0.086207 3:0.12069 5:0.085682764 6:0.034482034 7:0.018292683 +-1 1:0.545455 2:0.121212 3:0.151515 5:0.20069924 7:0.024020695 +-1 1:0.755102 3:0.020408 7:0.020034841 8:0.023809524 +-1 1:0.803279 7:0.018992402 +-1 1:0.688679 3:0.103774 7:0.013403128 8:0.023809524 +-1 1:0.545455 2:0.212121 3:0.045455 5:0.040515558 6:0.097827098 7:0.016999262 +-1 1:0.68 2:0.04 3:0.04 5:0.05605087 7:0.016219512 +-1 1:0.701493 3:0.171642 7:0.029759738 +-1 1:0.756098 2:0.04878 3:0.04878 5:0.13553889 7:0.016359311 +-1 1:0.788793 3:0.025862 7:0.017004835 8:0.095238095 +-1 1:0.75 3:0.152778 4:0.029520295 7:0.040311652 +-1 1:0.97 7:0.17204268 +-1 1:0.747368 3:0.042105 7:0.01598203 +-1 1:0.806452 7:0.016915817 +-1 1:0.769231 3:0.032967 7:0.013066201 +-1 1:0.939394 7:0.17045455 +-1 1:0.758621 2:0.060345 3:0.008621 5:0.023593696 6:0.047469047 7:0.016610598 8:0.047619048 +-1 1:0.913043 7:0.026511134 +-1 1:0.722222 2:0.055556 3:0.074074 5:0.0463003 7:0.018179768 +-1 1:0.866667 4:0.0073800738 7:0.048780488 +-1 1:0.607143 2:0.089286 3:0.071429 6:0.098361098 7:0.01328397 +-1 1:0.761905 7:0.011324043 +-1 1:0.882353 7:0.020803445 +-1 1:0.857143 3:0.142857 7:0.045731707 +-1 1:0.666667 2:0.041667 3:0.0625 5:0.046881756 6:0.018867019 7:0.020198171 +-1 1:0.794643 7:0.012902872 +-1 1:0.72549 2:0.019608 3:0.098039 4:0.022140221 5:0.044906296 7:0.019846963 +-1 1:0.903226 4:0.025830258 7:0.024980329 +-1 1:0.854545 3:0.054545 7:0.040576494 8:0.023809524 +-1 1:0.787879 2:0.121212 3:0.060606 4:0.077490775 6:0.022902023 7:0.072616409 +-1 1:0.672956 2:0.025157 3:0.100629 5:0.060121062 7:0.014265994 +-1 1:0.794118 3:0.073529 4:0.014760148 7:0.022865854 +-1 1:0.591549 2:0.15493 3:0.084507 5:0.045830662 6:0.043032043 7:0.04191 +-1 1:0.823529 3:0.019608 7:0.02020564 +-1 1:0.804878 3:0.012195 7:0.016061866 8:0.023809524 +-1 1:0.738854 3:0.038217 7:0.012466988 +-1 1:0.827957 2:0.010753 3:0.010753 5:0.019262594 7:0.02537372 +-1 1:0.65 2:0.066667 3:0.15 6:0.023346023 7:0.026117884 +-1 1:0.846154 7:0.01899625 +-1 1:0.9375 3:0.0625 7:0.051829268 +-1 1:0.673469 3:0.040816 7:0.019163762 +-1 1:0.793651 3:0.063492 4:0.011070111 7:0.021583433 8:0.023809524 +-1 1:0.590909 2:0.113636 3:0.113636 5:0.1249385 7:0.024805988 +-1 1:0.822222 2:0.022222 3:0.022222 5:0.04937158 7:0.020460707 +-1 1:0.658537 3:0.097561 7:0.013236171 8:0.023809524 +-1 1:0.73913 2:0.086957 3:0.065217 6:0.013698014 7:0.087089079 +-1 1:0.869565 7:0.017497348 +-1 1:0.8 7:0.011707317 8:0.023809524 +-1 1:0.861702 3:0.042553 7:0.048261549 8:0.023809524 +-1 1:0.715356 2:0.018727 3:0.05618 5:0.046471755 7:0.018315518 +-1 1:0.76087 3:0.086957 7:0.018425238 +-1 1:0.694444 3:0.111111 7:0.012872628 +-1 1:0.748322 2:0.033557 3:0.04698 4:0.011070111 5:0.070475452 7:0.019479457 +-1 1:0.668874 2:0.019868 3:0.192053 4:0.036900369 5:0.018942048 7:0.031780006 +-1 1:0.727273 2:0.038961 3:0.090909 4:0.018450185 5:0.03132408 6:0.025209025 7:0.018847006 +-1 1:0.656716 2:0.044776 3:0.104478 4:0.011070111 5:0.082372937 6:0.016575017 7:0.016472518 +-1 1:0.770642 3:0.027523 7:0.017397628 8:0.023809524 +-1 1:0.678899 2:0.073394 3:0.082569 5:0.052741043 6:0.014151014 7:0.023718951 +-1 1:0.666667 3:0.166667 7:0.01702236 +-1 1:0.767442 3:0.116279 7:0.020845152 +-1 1:0.772894 2:0.025641 3:0.025641 6:0.01958102 7:0.017108909 +-1 1:0.846154 7:0.019043152 +-1 1:0.871795 3:0.051282 7:0.058630396 +-1 1:0.5 2:0.055556 3:0.166667 5:0.14335873 7:0.017615177 +-1 1:0.766497 3:0.071066 4:0.029520295 7:0.019066488 +-1 1:0.712766 3:0.148936 4:0.036900369 7:0.022833421 +-1 1:0.768293 3:0.04878 7:0.015690067 8:0.023809524 +-1 1:0.758621 2:0.051724 3:0.017241 5:0.13636635 6:0.018294018 7:0.017241378 +-1 1:0.65 2:0.125 3:0.033333 5:0.11398774 6:0.073395073 7:0.016615854 8:0.047619048 +-1 1:0.6875 2:0.0625 3:0.104167 4:0.0073800738 5:0.12706305 7:0.022357726 8:0.047619048 +-1 1:0.682692 2:0.038462 3:0.125 5:0.042595381 6:0.0085710086 7:0.02052064 +-1 1:0.833333 2:0.055556 3:0.055556 5:0.092034052 7:0.027439024 +-1 1:0.719251 2:0.053476 3:0.066845 4:0.0036900369 5:0.024622426 6:0.027249027 7:0.019743707 8:0.047619048 +-1 1:0.668639 2:0.059172 3:0.076923 4:0.014760148 5:0.077169651 6:0.012423012 7:0.017426756 +-1 1:0.788136 3:0.004237 7:0.013176933 8:0.023809524 +-1 1:0.709677 2:0.048387 3:0.048387 5:0.04920758 6:0.01980302 7:0.014899683 +-1 1:0.723684 2:0.013158 3:0.131579 5:0.021484055 7:0.027840183 +-1 1:0.368421 2:0.157895 3:0.210526 5:0.63896054 7:0.011232348 +-1 1:0.714286 3:0.142857 7:0.013501744 +-1 1:0.785425 2:0.016194 3:0.064777 5:0.027507343 7:0.026760146 8:0.023809524 +-1 1:0.75 2:0.032609 6:0.025209025 7:0.015774128 8:0.023809524 +-1 1:0.779221 3:0.025974 7:0.014095659 8:0.047619048 +-1 1:0.693878 3:0.061224 7:0.011448482 8:0.023809524 +-1 1:0.6875 2:0.015625 3:0.078125 7:0.013528963 8:0.023809524 +-1 1:0.848485 7:0.016814488 +-1 1:0.628571 2:0.114286 6:0.078948079 7:0.013240421 +-1 1:0.853659 7:0.017400354 +-1 1:0.706897 3:0.068966 7:0.015559293 +-1 1:0.664557 2:0.075949 3:0.082278 5:0.036273911 6:0.036495036 7:0.015861378 +-1 1:0.6875 7:0.019054878 8:0.023809524 +-1 1:0.8 7:0.013414634 +-1 1:0.666667 2:0.121212 5:0.45179133 7:0.012195122 8:0.023809524 +-1 1:0.88172 2:0.064516 4:0.04797048 6:0.016650017 7:0.070875951 +-1 1:0.642857 2:0.02381 3:0.142857 5:0.065391439 7:0.016550524 +-1 1:0.704545 3:0.181818 7:0.024251665 +-1 1:0.766551 3:0.031359 7:0.015594457 +-1 1:0.7375 3:0.125 4:0.018450185 7:0.026219512 +-1 1:0.777778 2:0.007407 3:0.051852 4:0.0073800738 5:0.018591684 7:0.018112012 +-1 1:0.688312 2:0.051948 3:0.064935 4:0.0073800738 6:0.049452049 7:0.014412415 +-1 1:0.734375 2:0.015625 3:0.078125 5:0.0463003 6:0.018633019 7:0.015339177 +-1 1:0.754717 3:0.113208 7:0.021053841 +-1 1:0.717949 3:0.102564 4:0.0073800738 7:0.022983116 +-1 1:0.705882 2:0.039216 3:0.078431 4:0.0036900369 5:0.025613883 6:0.030927031 7:0.017395982 +-1 1:0.552239 2:0.19403 3:0.134328 5:0.064824892 6:0.06956407 7:0.03139789 +-1 1:0.74026 3:0.064935 4:0.0036900369 7:0.014254037 +-1 1:0.678571 2:0.178571 3:0.071429 4:0.011070111 6:0.044445044 7:0.029398957 +-1 1:0.681818 3:0.181818 4:0.014760148 7:0.023651146 +-1 1:0.695652 2:0.043478 3:0.086957 7:0.012990457 +-1 1:0.828571 3:0.085714 4:0.073800738 7:0.043263646 +-1 1:0.625 2:0.0625 3:0.125 4:0.0036900369 5:0.23295514 7:0.012195122 +-1 1:0.615385 2:0.092308 3:0.092308 5:0.049043579 6:0.059211059 7:0.014258915 +-1 1:0.741935 3:0.032258 7:0.031667976 +-1 1:0.65 2:0.114286 3:0.042857 5:0.078265472 6:0.062991063 7:0.016594079 8:0.023809524 +-1 1:0.633333 2:0.153333 3:0.068889 4:0.040590406 5:0.024398789 6:0.081834082 7:0.024837396 +-1 1:0.726708 2:0.031056 3:0.043478 5:0.093413147 7:0.015111348 8:0.023809524 +-1 1:0.818182 2:0.045455 3:0.045455 7:0.029656317 +-1 1:0.64 3:0.16 7:0.026585366 +-1 1:0.780488 3:0.04878 7:0.017400354 8:0.023809524 +-1 1:0.820513 7:0.01297686 +-1 1:0.780749 3:0.074866 7:0.027324896 +-1 1:0.777778 2:0.027778 3:0.027778 5:0.08874659 7:0.01422764 +-1 1:0.75 3:0.032258 4:0.011070111 7:0.015047207 8:0.095238095 +-1 1:0.75 3:0.03125 7:0.023818598 +-1 1:0.538462 2:0.230769 3:0.076923 5:0.86014492 7:0.012195122 +-1 1:0.725806 3:0.048387 7:0.013965384 8:0.023809524 +-1 1:0.738462 2:0.076923 3:0.030769 5:0.14267291 6:0.014355014 7:0.019606006 +-1 1:0.714286 3:0.079365 7:0.015776226 8:0.047619048 +-1 1:0.585366 2:0.292683 3:0.121951 4:0.014760148 5:0.0086547493 6:0.038328038 7:0.12804878 +-1 1:0.788079 7:0.013164268 8:0.023809524 +-1 1:0.759777 3:0.03352 4:0.0036900369 7:0.013796159 +-1 1:0.823529 2:0.058824 5:0.14335873 7:0.018651366 +-1 1:0.747475 2:0.020202 3:0.030303 7:0.012995811 +-1 1:0.792079 2:0.029703 5:0.030056804 6:0.024195024 7:0.014972232 +-1 1:0.770992 7:0.013172591 8:0.071428571 +-1 1:0.716981 2:0.028302 3:0.113208 6:0.006048006 7:0.028531982 +-1 1:0.578125 2:0.375 3:0.015625 5:0.0066643806 6:0.061716062 7:0.10651677 +-1 1:0.645 2:0.05 3:0.045 5:0.088396225 6:0.0059280059 7:0.015426829 +-1 1:0.752941 7:0.012625537 +-1 1:0.734783 2:0.06087 3:0.030435 6:0.047388047 7:0.021818665 +-1 1:0.740741 3:0.148148 4:0.0036900369 7:0.026874433 +-1 1:0.811111 7:0.018360433 8:0.023809524 +-1 1:0.807692 7:0.013133207 8:0.023809524 +-1 1:0.942308 7:0.050656665 +-1 1:0.72 3:0.08 7:0.024634146 +-1 1:0.736264 2:0.032967 3:0.054945 4:0.0073800738 6:0.021939022 7:0.018326189 +-1 1:0.744125 2:0.015666 3:0.031332 5:0.042476108 7:0.016764311 +-1 1:0.861111 7:0.018631439 +-1 1:0.636364 2:0.136364 3:0.136364 5:0.16383642 7:0.025221732 +-1 1:0.894737 7:0.021181 +-1 1:0.764706 3:0.044118 7:0.019817073 +-1 1:0.803571 3:0.035714 7:0.028527872 +-1 1:0.71 2:0.02 3:0.05 4:0.0073800738 5:0.064541619 7:0.014085366 +-1 1:0.765432 2:0.049383 3:0.074074 5:0.031860808 7:0.035230354 +-1 1:0.722222 2:0.031746 3:0.039683 5:0.04450375 7:0.016211768 +-1 1:0.76779 2:0.014981 3:0.018727 4:0.0036900369 5:0.01386549 7:0.024550104 8:0.023809524 +-1 1:0.585746 2:0.104677 3:0.115813 4:0.044280443 5:0.16648279 6:0.027294027 7:0.016418598 +-1 1:0.814815 7:0.012195122 8:0.023809524 +-1 1:0.726115 2:0.031847 3:0.070064 5:0.033582813 6:0.0067560068 7:0.017244061 +-1 1:0.636364 2:0.090909 3:0.109091 4:0.0036900369 5:0.092600599 6:0.037266037 7:0.017849226 +-1 1:0.721951 2:0.004878 3:0.053659 7:0.013444378 8:0.047619048 +-1 1:0.634328 2:0.067164 3:0.08209 4:0.011070111 5:0.043594293 6:0.035088035 7:0.015562433 +-1 1:0.728261 7:0.012592787 +-1 1:0.772182 3:0.023981 7:0.014856409 8:0.023809524 +-1 1:0.771429 3:0.042857 7:0.016724738 8:0.047619048 +-1 1:0.686869 3:0.141414 4:0.0036900369 7:0.020756341 +-1 1:0.701299 2:0.038961 3:0.084416 5:0.031517898 6:0.0063420063 7:0.018728226 +-1 1:0.773006 2:0.01227 3:0.02454 5:0.018002773 7:0.015487055 8:0.071428571 +-1 1:0.648936 3:0.12766 4:0.025830258 7:0.011935652 +-1 1:0.763158 3:0.078947 7:0.020539152 8:0.023809524 +-1 1:0.809524 7:0.011324043 +-1 1:0.675 3:0.15 4:0.014760148 7:0.014939024 +-1 1:0.825688 2:0.009174 3:0.036697 6:0.0050580051 7:0.03317297 +-1 1:0.73913 2:0.028986 3:0.043478 5:0.085198217 7:0.015464829 +-1 1:0.740741 2:0.037037 3:0.024691 5:0.079301656 7:0.014152366 8:0.023809524 +-1 1:0.6875 7:0.018292683 +-1 1:0.781818 2:0.014545 3:0.029091 5:0.037653005 7:0.017560976 8:0.047619048 +-1 1:0.628205 2:0.076923 3:0.128205 4:0.0036900369 5:0.066561806 6:0.026787027 7:0.017510945 8:0.047619048 +-1 1:0.737557 3:0.117647 7:0.027259683 +-1 1:0.8 7:0.012347561 8:0.023809524 +-1 1:0.679487 2:0.012821 3:0.141026 4:0.014760148 5:0.024764063 7:0.023530329 +-1 1:0.751634 3:0.03268 7:0.012832774 8:0.023809524 +-1 1:0.82963 7:0.017163506 8:0.047619048 +-1 1:0.714286 3:0.028571 7:0.017073171 +-1 1:0.73913 3:0.130435 7:0.024655354 +-1 1:0.56 2:0.06 3:0.16 5:0.22589567 7:0.012073171 +-1 1:0.711864 2:0.050847 3:0.084746 4:0.0073800738 5:0.08634622 7:0.026767262 +-1 1:0.684211 2:0.105263 3:0.052632 5:0.26156576 7:0.018292683 +-1 1:0.782609 3:0.086957 7:0.022534463 +-1 1:0.774194 7:0.010818256 +-1 1:0.8 7:0.013414634 8:0.023809524 +-1 1:0.663636 2:0.063636 3:0.063636 4:0.0036900369 5:0.026717159 6:0.043011043 7:0.015465634 +-1 1:0.806667 7:0.013577238 +-1 1:0.735294 7:0.01201578 8:0.023809524 +-1 1:0.734694 2:0.016327 3:0.053061 4:0.011070111 5:0.042118289 7:0.017620707 +-1 1:0.791878 3:0.010152 7:0.014887951 8:0.023809524 +-1 1:0.823529 7:0.014705884 +-1 1:0.794872 7:0.012195122 +-1 1:0.630769 2:0.184615 3:0.061538 4:0.011070111 5:0.19326704 6:0.044445044 7:0.025328329 +-1 1:0.766667 3:0.077778 4:0.025830258 7:0.023983738 +-1 1:0.722581 3:0.103226 4:0.014760148 7:0.02407553 +-1 1:0.59596 2:0.166667 3:0.025253 5:0.028618073 6:0.12092112 7:0.016044591 8:0.023809524 +-1 1:0.748387 2:0.012903 3:0.051613 5:0.018591684 7:0.015774982 +-1 1:0.984802 7:0.17514271 +-1 1:0.65625 2:0.1875 3:0.125 4:0.0036900369 6:0.043353043 7:0.065929878 +-1 1:0.693878 2:0.142857 3:0.061224 5:0.064541619 6:0.038961039 7:0.028745646 +-1 1:1 7:0.06402439 +-1 1:0.833333 7:0.044207317 +-1 1:0.982456 2:0.004386 5:0.0011405484 7:0.17450257 +-1 1:0.745098 3:0.117647 4:0.011070111 7:0.018890482 +-1 1:0.752941 2:0.011765 3:0.047059 7:0.016857963 +-1 1:0.690647 2:0.007194 3:0.043165 5:0.024764063 7:0.013204073 +-1 1:0.778846 3:0.009615 7:0.012546902 +-1 1:0.75 3:0.05 7:0.01097561 +-1 1:0.882353 7:0.01649928 +-1 1:0.792553 2:0.005319 3:0.010638 7:0.015535805 +-1 1:0.794872 2:0.025641 3:0.025641 7:0.018605378 +-1 1:0.842105 7:0.01283697 +-1 1:0.607143 2:0.071429 3:0.142857 4:0.0036900369 7:0.012630665 +-1 1:0.848485 3:0.060606 7:0.034183299 +-1 1:0.804124 7:0.014018104 8:0.047619048 +-1 1:0.779661 2:0.016949 3:0.033898 5:0.047783758 7:0.016122366 +-1 1:0.553846 2:0.169231 3:0.046154 5:0.29377693 6:0.02955603 7:0.019043152 +-1 1:0.684211 7:0.015725287 8:0.023809524 +-1 1:0.631579 3:0.131579 7:0.016527598 +-1 1:0.846154 7:0.01594747 +-1 1:0.765517 3:0.02069 7:0.012888982 +-1 1:0.813953 7:0.013825866 +-1 1:0.740741 2:0.037037 3:0.037037 5:0.11927303 7:0.014114726 +-1 1:0.793103 7:0.012405384 8:0.023809524 +-1 1:0.767442 2:0.011628 6:0.012783013 7:0.012478732 8:0.095238095 +-1 1:0.833333 7:0.011686994 +-1 1:0.761194 3:0.037313 7:0.012786677 +-1 1:0.870968 3:0.016129 7:0.03147128 +-1 1:0.782609 3:0.086957 7:0.02492047 +-1 1:0.689189 2:0.013514 3:0.081081 7:0.015079104 8:0.023809524 +-1 1:0.78481 3:0.012658 7:0.013044152 8:0.071428571 +-1 1:0.674419 2:0.054264 3:0.023256 5:0.12508014 7:0.014085835 +-1 1:0.806452 3:0.032258 7:0.01534225 +-1 1:0.851852 7:0.018970189 +-1 1:0.793814 7:0.013420921 8:0.11904762 +-1 1:0.62069 2:0.034483 3:0.206897 5:0.086681675 7:0.018082421 +-1 1:0.847826 3:0.032609 7:0.026908799 +-1 1:0.875 7:0.030233738 +-1 1:0.783784 3:0.006757 7:0.01273072 +-1 1:0.658462 2:0.116923 3:0.033846 5:0.055215959 6:0.066666067 7:0.020262665 8:0.023809524 +-1 1:0.661538 3:0.184615 4:0.011070111 7:0.02382739 +-1 1:0.72093 3:0.023256 7:0.010068067 8:0.023809524 +-1 1:0.698795 2:0.036145 3:0.048193 6:0.029412029 7:0.014986774 8:0.047619048 +-1 1:0.708333 3:0.083333 7:0.010670732 +-1 1:0.761905 2:0.047619 5:0.18181683 7:0.011904762 +-1 1:0.795918 3:0.040816 7:0.018790445 +-1 1:0.576923 2:0.115385 3:0.192308 4:0.011070111 5:0.078466745 6:0.031578032 7:0.022279549 +-1 1:0.732394 2:0.028169 3:0.056338 4:0.0073800738 5:0.036542275 7:0.017519756 +-1 1:0.748936 2:0.017021 3:0.021277 7:0.016165024 8:0.023809524 +-1 1:0.846154 3:0.038462 7:0.027439024 8:0.023809524 +-1 1:0.666667 2:0.08 3:0.12 5:0.043512293 6:0.0058380058 7:0.041788616 +-1 1:0.748792 3:0.067633 4:0.0073800738 7:0.016967128 +-1 1:0.641026 2:0.051282 3:0.153846 4:0.014760148 5:0.13805108 7:0.016885555 +-1 1:0.692308 2:0.076923 3:0.076923 7:0.013133207 +-1 1:0.617647 2:0.147059 6:0.14516115 7:0.011119079 8:0.023809524 +-1 1:0.763158 2:0.052632 3:0.013158 6:0.044334044 7:0.016286909 +-1 1:0.75 3:0.166667 4:0.0036900369 7:0.024390244 +-1 1:0.8125 7:0.01257622 8:0.047619048 +-1 1:0.760479 2:0.035928 3:0.035928 5:0.076536013 7:0.017781512 +-1 1:0.73913 7:0.022534463 +-1 1:0.684211 7:0.013157896 +-1 1:0.777778 3:0.022222 7:0.014453476 +-1 1:0.615385 2:0.123077 3:0.046154 6:0.13138813 7:0.01285178 +-1 1:0.884615 7:0.022514073 +-1 1:0.857143 7:0.01480836 +-1 1:0.729167 3:0.083333 4:0.0073800738 7:0.024326726 +-1 1:0.863636 7:0.018015518 +-1 1:0.8125 7:0.013910061 8:0.023809524 +-1 1:0.842105 3:0.105263 7:0.049743262 +-1 1:0.755102 2:0.020408 3:0.030612 5:0.059166878 7:0.015679445 8:0.023809524 +-1 1:0.696 3:0.136 7:0.019707317 +-1 1:0.753623 2:0.014493 3:0.057971 5:0.04073174 7:0.016171793 +-1 1:0.638889 2:0.069444 3:0.097222 5:0.072726731 6:0.014634015 7:0.01736111 8:0.023809524 +-1 1:0.723404 3:0.021277 7:0.014919567 +-1 1:0.833333 7:0.014905146 8:0.023809524 +-1 1:0.731707 3:0.073171 4:0.0073800738 7:0.014128494 8:0.023809524 +-1 1:0.703125 2:0.015625 3:0.140625 4:0.0036900369 7:0.023151677 +-1 1:0.785714 2:0.035714 3:0.035714 5:0.083759486 7:0.01938153 +-1 1:0.72 3:0.106667 4:0.0036900369 7:0.01617886 +-1 1:0.757812 3:0.070312 7:0.018149768 +-1 1:0.75 2:0.055556 3:0.027778 7:0.018462061 8:0.023809524 +-1 1:0.721739 3:0.034783 4:0.0036900369 7:0.015058323 8:0.023809524 +-1 1:0.8 3:0.1 7:0.023373982 +-1 1:0.643939 2:0.128788 6:0.13186813 7:0.012610866 8:0.023809524 +-1 1:0.722222 2:0.011111 3:0.1 7:0.018699189 8:0.047619048 +-1 1:0.736462 2:0.032491 3:0.046931 4:0.0036900369 5:0.06144052 6:0.0082410082 7:0.01602536 +-1 1:0.8 2:0.018182 5:0.053247954 7:0.015521067 +-1 1:0.738372 3:0.093023 7:0.016591037 8:0.023809524 +-1 1:0.785124 3:0.024793 7:0.01577303 +-1 1:0.795455 3:0.05303 7:0.023697341 +-1 1:0.761905 7:0.011396634 8:0.023809524 +-1 1:0.873016 7:0.040940768 +-1 1:0.928571 7:0.023954701 +-1 1:0.962963 7:0.044715445 +-1 1:0.743842 2:0.014778 3:0.049261 4:0.0036900369 5:0.013477852 7:0.016610598 +-1 1:0.875 3:0.09375 7:0.051067073 +-1 1:0.741935 2:0.145161 3:0.032258 5:0.027253888 6:0.027423027 7:0.05379622 +-1 1:0.755556 2:0.111111 3:0.022222 6:0.04013404 7:0.040514902 +-1 1:0.670455 3:0.034091 7:0.01517461 +-1 1:0.837209 7:0.015598415 +-1 1:0.804124 2:0.005155 3:0.030928 6:0.0021450021 7:0.021970079 +-1 1:0.837838 7:0.017139091 8:0.023809524 +-1 1:0.6639 2:0.053942 3:0.087137 4:0.0073800738 5:0.066203987 6:0.0053280053 7:0.014244512 +-1 1:0.8 7:0.015156793 +-1 1:0.532895 2:0.217105 3:0.032895 5:0.60261208 6:0.017964018 7:0.013398585 +-1 1:0.794118 3:0.029412 7:0.01416786 +-1 1:0.770781 2:0.037783 3:0.012594 6:0.031914032 7:0.017325061 8:0.047619048 +-1 1:0.778226 3:0.020161 7:0.015932335 8:0.047619048 +-1 1:0.663551 3:0.102804 4:0.0036900369 7:0.013733762 8:0.023809524 +-1 1:0.747619 3:0.028571 7:0.013269451 8:0.095238095 +-1 1:0.774648 2:0.014085 3:0.014085 7:0.018206799 8:0.023809524 +-1 1:0.709877 2:0.055556 3:0.037037 6:0.030981031 7:0.021868415 8:0.023809524 +-1 1:0.789855 7:0.012813713 8:0.023809524 +-1 1:0.712329 3:0.068493 7:0.014116268 +-1 1:0.757812 2:0.023438 3:0.028646 6:0.01959002 7:0.01702236 8:0.023809524 +-1 1:0.711864 3:0.101695 7:0.013745348 +-1 1:0.829268 7:0.014723378 +-1 1:0.823529 3:0.117647 4:0.0036900369 7:0.027259683 +-1 1:0.777778 2:0.037037 5:0.12852415 7:0.013098463 +-1 1:0.8 2:0.066667 5:0.20147451 7:0.015040652 +-1 1:0.62963 2:0.111111 3:0.111111 5:0.18181683 7:0.018518518 +-1 1:0.815789 7:0.012997433 +-1 1:0.766667 7:0.02215447 +-1 1:0.770833 3:0.0625 4:0.0073800738 7:0.017276421 8:0.023809524 +-1 1:0.690583 2:0.071749 3:0.03139 4:0.014760148 6:0.070866071 7:0.013890409 8:0.023809524 +-1 1:0.734177 2:0.037975 3:0.037975 6:0.024096024 7:0.019218896 +-1 1:0.734177 2:0.037975 3:0.037975 6:0.025317025 7:0.018292683 +-1 1:0.695652 2:0.026087 3:0.086957 5:0.044906296 7:0.01760339 +-1 1:0.743056 2:0.055556 3:0.006944 6:0.042615043 7:0.014905146 8:0.023809524 +-1 1:0.714286 3:0.142857 7:0.01843786 +-1 1:0.694444 2:0.083333 3:0.064815 4:0.0073800738 6:0.05965806 7:0.01987353 8:0.023809524 +-1 1:0.751055 2:0.004219 3:0.046414 4:0.0036900369 7:0.014716476 8:0.047619048 +-1 1:0.717391 3:0.043478 7:0.013255567 +-1 1:0.684211 2:0.035088 3:0.087719 5:0.057787783 7:0.013799744 +-1 1:0.833333 2:0.041667 5:0.095574971 7:0.019817073 +-1 1:0.780822 3:0.027397 7:0.014283329 +-1 1:0.711462 2:0.019763 3:0.079051 4:0.011070111 5:0.011278756 6:0.0045390045 7:0.01593078 +-1 1:0.795455 7:0.01302661 +-1 1:0.791667 7:0.012639738 +-1 1:0.98913 7:0.15416224 +-1 1:0.8125 3:0.0625 7:0.019626524 +-1 1:0.758621 3:0.034483 7:0.016400335 +-1 1:0.727273 2:0.136364 5:0.32410955 7:0.019124171 +-1 1:0.794118 3:0.029412 7:0.013091823 +-1 1:0.568627 2:0.235294 3:0.039216 5:0.050370492 6:0.18243318 7:0.017694884 +-1 1:0.73913 2:0.086957 3:0.130435 5:0.047478121 7:0.041622482 +-1 1:0.722689 2:0.028011 3:0.039216 5:0.0080882024 6:0.01952402 7:0.015747762 +-1 1:0.804124 3:0.020619 7:0.015966811 8:0.023809524 +-1 1:0.789474 7:0.0105905 8:0.023809524 +-1 1:0.825 7:0.01402439 +-1 1:0.740741 3:0.111111 7:0.016937671 +-1 1:0.666667 2:0.074074 3:0.046296 4:0.0036900369 5:0.11295156 6:0.034092034 7:0.014905146 +-1 1:0.73913 2:0.028986 3:0.057971 5:0.044108658 7:0.014934604 +-1 1:0.793103 7:0.011143817 +-1 1:0.761194 7:0.013742262 8:0.023809524 +-1 1:0.781132 3:0.015094 7:0.014173951 8:0.047619048 +-1 1:0.809524 3:0.059524 7:0.025116146 +-1 1:0.738636 7:0.01306125 8:0.047619048 +-1 1:0.604651 2:0.093023 3:0.069767 5:0.12220267 7:0.017300055 +-1 1:0.770492 3:0.032787 7:0.015393841 +-1 1:0.714286 2:0.031746 3:0.142857 4:0.022140221 5:0.060605609 7:0.023809524 +-1 1:0.776536 7:0.012297317 8:0.095238095 +-1 1:0.714286 3:0.142857 7:0.01480836 +-1 1:0.741214 3:0.060703 4:0.0036900369 7:0.016091329 +-1 1:0.745098 3:0.098039 7:0.019607841 +-1 1:0.478261 2:0.304348 3:0.043478 5:0.10353645 6:0.14583315 7:0.019088018 +-1 1:0.777778 7:0.015356817 8:0.023809524 +-1 1:0.529412 2:0.117647 3:0.117647 5:0.092034052 7:0.029053085 +-1 1:0.7625 2:0.0125 3:0.025 5:0.042356835 7:0.013414634 +-1 1:0.777778 3:0.055556 7:0.01682475 +-1 1:0.762346 2:0.024691 3:0.030864 5:0.041052286 6:0.0033030033 7:0.017088226 +-1 1:0.666667 2:0.011494 3:0.126437 4:0.014760148 7:0.017872165 +-1 1:0.753968 2:0.039683 3:0.039683 4:0.011070111 5:0.020537325 6:0.016530017 7:0.01756678 +-1 1:0.726644 2:0.020761 3:0.051903 5:0.019799323 6:0.011952012 7:0.015887415 8:0.023809524 +-1 1:0.8 7:0.01097561 +-1 1:0.888889 3:0.055556 7:0.029471543 +-1 1:0.744186 2:0.023256 3:0.116279 7:0.032331256 +-1 1:0.813953 3:0.046512 4:0.0036900369 7:0.030204195 +-1 1:0.673913 2:0.130435 3:0.021739 5:0.047478121 6:0.028662029 7:0.041622482 +-1 1:0.84 3:0.04 7:0.018780488 +-1 1:0.634146 3:0.073171 7:0.033016061 +-1 1:0.794872 2:0.025641 3:0.076923 5:0.048723033 7:0.023921201 +-1 1:0.444444 2:0.111111 3:0.148148 5:0.21298436 7:0.015808488 +-1 1:0.77551 3:0.102041 4:0.0073800738 7:0.023394726 8:0.047619048 +-1 1:0.809524 3:0.015873 7:0.016066591 +-1 1:0.866667 7:0.048780488 +-1 1:0.789474 7:0.010269579 +-1 1:0.75 3:0.098485 4:0.011070111 7:0.024113079 +-1 1:1 7:0.082317073 +-1 1:0.776119 3:0.089552 4:0.0036900369 7:0.030442299 +-1 1:0.740385 3:0.057692 7:0.014071293 8:0.023809524 +-1 1:0.693878 2:0.020408 3:0.129252 7:0.020532604 +-1 1:0.666667 2:0.039216 3:0.078431 4:0.0073800738 6:0.017964018 7:0.019966524 +-1 1:0.742857 2:0.057143 3:0.028571 5:0.089812592 7:0.014459927 +-1 1:0.807692 7:0.01325047 8:0.023809524 +-1 1:0.823529 3:0.058824 7:0.01649928 +-1 1:0.744444 2:0.011111 3:0.055556 5:0.034194087 7:0.014769646 8:0.023809524 +-1 1:0.720721 2:0.036036 3:0.054054 6:0.023256023 7:0.014172707 +-1 1:0.746377 2:0.036232 3:0.028986 5:0.04073174 6:0.016392016 7:0.016171793 +-1 1:0.808511 3:0.021277 7:0.016346652 +-1 1:0.782991 2:0.017595 3:0.026393 5:0.020440416 6:0.0054840055 7:0.019562262 +-1 1:0.783133 3:0.048193 4:0.0073800738 7:0.017558037 8:0.023809524 +-1 1:0.802326 2:0.011628 5:0.033128084 7:0.015952921 +-1 1:0.684211 2:0.036437 3:0.089069 4:0.014760148 6:0.03015003 7:0.014737829 +-1 1:0.694915 2:0.016949 3:0.084746 5:0.053628137 7:0.014365439 +-1 1:0.835526 3:0.006579 7:0.019335689 8:0.047619048 +-1 1:0.679389 2:0.076336 3:0.053435 4:0.0036900369 6:0.071856072 7:0.015546451 +-1 1:0.686207 2:0.034483 3:0.1 5:0.02900571 6:0.015564016 7:0.016211104 +-1 1:0.723404 3:0.053191 7:0.013622213 +-1 1:0.958333 4:0.044280443 7:0.044207317 +-1 1:0.758621 3:0.006897 7:0.01299411 8:0.023809524 +-1 1:0.655172 2:0.034483 3:0.103448 7:0.01198486 +-1 1:0.752427 3:0.033981 7:0.012935116 +-1 1:0.726115 2:0.012739 3:0.076433 5:0.019672596 7:0.014719591 +-1 1:0.783784 2:0.013514 7:0.022742256 8:0.023809524 +-1 1:0.728814 3:0.118644 4:0.0073800738 7:0.017259195 +-1 1:0.784615 7:0.01360225 8:0.023809524 +-1 1:0.784615 7:0.013742963 8:0.023809524 +-1 1:0.782051 3:0.025641 7:0.01414947 8:0.023809524 +-1 1:0.727273 3:0.068182 7:0.013165189 8:0.023809524 +-1 1:0.8 7:0.011585366 +-1 1:0.74026 2:0.038961 3:0.103896 5:0.017600227 6:0.0070830071 7:0.067073171 +-1 1:0.829787 7:0.015438506 +-1 1:0.72973 2:0.036036 3:0.063063 5:0.049043579 7:0.016699628 +-1 1:0.875 3:0.041667 7:0.024390244 +-1 1:0.763359 2:0.002545 3:0.040712 4:0.0036900369 7:0.015608512 8:0.047619048 +-1 1:0.802632 2:0.013158 3:0.026316 5:0.033731904 7:0.017731067 +-1 1:0.642857 7:0.010452963 +-1 1:0.842105 7:0.01636714 +-1 1:0.804348 3:0.043478 7:0.018557793 +-1 1:0.709677 2:0.048387 3:0.064516 5:0.093182055 7:0.01573564 +-1 1:0.877551 2:0.020408 5:0.030675533 7:0.030238927 +-1 1:0.790816 3:0.035714 7:0.020097061 +-1 1:0.70297 2:0.029703 3:0.138614 4:0.0036900369 5:0.035670091 6:0.0071760072 7:0.025235451 +-1 1:0.791304 3:0.034783 4:0.0036900369 7:0.016383878 +-1 1:0.788462 3:0.028846 7:0.01477486 +-1 1:0.752212 2:0.00885 3:0.053097 4:0.011070111 7:0.015055043 8:0.023809524 +-1 1:0.751131 2:0.004525 3:0.045249 5:0.014588583 7:0.014098884 +-1 1:0.864865 7:0.017798287 +-1 1:0.740741 2:0.037037 3:0.074074 7:0.021002707 +-1 1:0.781818 2:0.036364 3:0.054545 5:0.069021812 7:0.023946787 +-1 1:0.859649 2:0.017544 5:0.03516318 7:0.022678646 +-1 1:0.733333 3:0.116667 7:0.019004067 +-1 1:0.716667 2:0.041667 3:0.066667 5:0.0750451 7:0.015142274 +-1 1:0.742424 3:0.045455 7:0.019955652 8:0.023809524 +-1 1:0.723684 2:0.105263 3:0.065789 5:0.04398193 6:0.035397035 7:0.027198329 +-1 1:0.64 2:0.08 3:0.04 5:0.23295514 7:0.015609756 +-1 1:0.769231 3:0.059829 4:0.0036900369 7:0.017510945 +-1 1:0.72 3:0.16 4:0.0073800738 7:0.025609756 +-1 1:0.604396 2:0.021978 3:0.208791 5:0.05647578 7:0.017689628 +-1 1:0.702703 3:0.094595 4:0.0073800738 7:0.016150299 +-1 1:0.615385 2:0.153846 3:0.102564 5:0.10649591 6:0.042858043 7:0.021888683 +-1 1:0.727273 3:0.181818 7:0.024020695 +-1 1:0.578571 2:0.164286 3:0.042857 5:0.078675473 6:0.087072087 7:0.01650697 +-1 1:0.805825 3:0.019417 7:0.016220695 8:0.023809524 +-1 1:0.8 3:0.01 7:0.015731707 8:0.071428571 +-1 1:0.755556 3:0.133333 7:0.029674799 8:0.047619048 +-1 1:0.692308 2:0.038462 3:0.192308 4:0.014760148 5:0.051414131 7:0.034005628 +-1 1:0.740947 2:0.030641 3:0.050139 5:0.026068612 7:0.019430671 8:0.047619048 +-1 1:0.642857 3:0.178571 7:0.014699476 +-1 1:0.755245 2:0.013986 3:0.048951 5:0.014819674 7:0.021448067 +-1 1:0.804348 3:0.01087 7:0.017895018 8:0.023809524 +-1 1:0.635593 2:0.076271 3:0.09322 5:0.10842664 6:0.021819022 7:0.014210415 +-1 1:0.673729 2:0.063559 3:0.088983 5:0.027007887 6:0.025362025 7:0.02139314 +-1 1:0.701754 2:0.087719 3:0.008772 5:0.05734051 6:0.069231069 7:0.01390672 8:0.023809524 +-1 1:0.639535 2:0.093023 3:0.069767 4:0.018450185 6:0.087378087 7:0.014605787 +-1 1:0.681818 2:0.045455 3:0.136364 5:0.087702951 7:0.023558756 +-1 1:0.842105 7:0.013157896 +-1 1:0.712329 3:0.013699 7:0.014951555 8:0.023809524 +-1 1:0.875 7:0.017530488 +-1 1:0.791667 3:0.041667 7:0.014481707 +-1 1:0.823529 7:0.013629841 +-1 1:0.65625 2:0.114583 3:0.041667 5:0.13855799 6:0.078066078 7:0.017085872 +-1 1:0.705202 2:0.017341 3:0.109827 4:0.0036900369 5:0.020149688 7:0.026082055 +-1 1:0.773256 2:0.005814 3:0.011628 5:0.017100771 7:0.01545661 +-1 1:0.752101 2:0.004202 3:0.031513 4:0.0036900369 5:0.012605668 7:0.015154232 +-1 1:0.805755 2:0.007194 3:0.007194 5:0.021059145 7:0.015529043 +-1 1:0.782609 7:0.015906683 +-1 1:0.792208 2:0.004329 3:0.012987 5:0.012344759 7:0.015943409 +-1 1:0.555556 2:0.166667 3:0.166667 5:0.39234864 7:0.019308945 +-1 1:0.711538 2:0.051282 3:0.044872 5:0.019314776 6:0.046632047 7:0.015087555 +-1 1:1 7:0.06097561 +-1 1:0.55814 2:0.232558 5:0.85685 7:0.012336927 +-1 1:0.730435 3:0.078261 4:0.025830258 7:0.017656415 8:0.071428571 +-1 1:0.790698 3:0.046512 7:0.015598415 +-1 1:0.723404 7:0.010508561 8:0.023809524 +-1 1:0.730769 2:0.038462 3:0.076923 4:0.0036900369 6:0.041097041 7:0.017120073 +-1 1:0.775362 3:0.057971 7:0.026555317 +-1 1:0.777778 2:0.037037 5:0.13311616 7:0.012646793 +-1 1:0.775974 2:0.00974 3:0.035714 5:0.016049677 7:0.018391671 +-1 1:0.793478 3:0.032609 7:0.016900848 +-1 1:0.706422 2:0.045872 3:0.018349 5:0.071332727 7:0.011691652 8:0.023809524 +-1 1:0.842105 7:0.013799744 +-1 1:0.741379 2:0.034483 3:0.051724 5:0.043087382 7:0.018187555 +-1 1:0.693182 2:0.034091 3:0.079545 4:0.022140221 6:0.026550027 7:0.015659646 +-1 1:0.820513 7:0.013133207 +-1 1:0.675 2:0.083333 3:0.066667 4:0.011070111 5:0.056617417 6:0.045570046 7:0.02007114 8:0.023809524 +-1 1:0.746032 7:0.011517616 8:0.047619048 +-1 1:0.763975 2:0.015528 3:0.031056 5:0.043952112 7:0.016058171 +-1 1:0.761905 2:0.031746 3:0.047619 4:0.0036900369 6:0.016485016 7:0.017615177 +-1 1:0.810811 2:0.027027 4:0.0036900369 5:0.071675637 7:0.017139091 +-1 1:0.65 2:0.133333 3:0.05 6:0.10876211 7:0.016819104 +-1 1:0.808219 7:0.016037421 8:0.047619048 +-1 1:0.73224 3:0.120219 4:0.011070111 7:0.025523122 +-1 1:0.759259 3:0.027778 7:0.014001805 +-1 1:0.8 3:0.05 7:0.020020323 +-1 1:0.782609 7:0.011399787 +-1 1:0.78 2:0.01 3:0.06 4:0.0036900369 5:0.020820598 7:0.021829268 +-1 1:0.758065 3:0.056452 7:0.016768293 +-1 1:0.673797 2:0.106952 3:0.053476 4:0.0036900369 6:0.06997207 7:0.022368591 +-1 1:0.8125 3:0.125 7:0.024390244 +-1 1:0.798701 7:0.014095659 +-1 1:0.76 7:0.013170732 8:0.047619048 +-1 1:0.6 2:0.175 3:0.0375 5:0.033500813 6:0.12809113 7:0.016958841 +-1 1:0.784173 2:0.007194 3:0.014388 5:0.023370059 7:0.013993683 8:0.023809524 +-1 1:0.886364 7:0.023558756 +-1 1:0.744681 3:0.06383 7:0.013297872 +-1 1:0.724739 3:0.101045 4:0.025830258 7:0.018271439 8:0.023809524 +-1 1:0.848485 7:0.021433854 8:0.023809524 +-1 1:0.714286 2:0.071429 3:0.071429 7:0.014372823 8:0.023809524 +-1 1:0.761905 3:0.047619 7:0.013646921 +-1 1:0.806452 7:0.012981902 +-1 1:0.764706 3:0.039216 7:0.014705884 8:0.047619048 +-1 1:0.772727 3:0.045455 7:0.01302661 +-1 1:0.763889 3:0.069444 4:0.0036900369 7:0.019478317 8:0.023809524 +-1 1:0.842105 7:0.013157896 +-1 1:0.671875 2:0.078125 3:0.0625 4:0.0036900369 5:0.1277936 6:0.017142017 7:0.016673018 +-1 1:0.714286 3:0.142857 7:0.019272646 8:0.023809524 +-1 1:0.779874 3:0.037736 7:0.015761622 8:0.023809524 +-1 1:0.727273 3:0.136364 7:0.018569848 +-1 1:0.735849 3:0.075472 7:0.013230555 8:0.023809524 +-1 1:0.842105 7:0.013799744 +-1 1:0.623853 2:0.073394 3:0.137615 4:0.029520295 5:0.067612899 6:0.02040902 7:0.024669951 +-1 1:0.816327 7:0.013439524 +-1 1:0.828571 3:0.014286 7:0.019599305 +-1 1:0.755556 2:0.02963 3:0.022222 5:0.067158171 7:0.015040652 8:0.023809524 +-1 1:0.819277 7:0.016896854 +-1 1:0.668342 2:0.065327 3:0.080402 4:0.025830258 5:0.02781298 6:0.05037305 7:0.016423579 +-1 1:0.770115 3:0.051724 4:0.025830258 7:0.019659378 8:0.047619048 +-1 1:0.75 7:0.021341463 +-1 1:0.863636 7:0.016629713 +-1 1:0.75 2:0.027778 3:0.041667 7:0.01583672 +-1 1:0.818182 3:0.090909 7:0.027346634 +-1 1:0.714286 3:0.214286 7:0.022212543 +-1 1:0.827586 7:0.013456689 8:0.023809524 +-1 1:0.764706 3:0.058824 7:0.017635104 +-1 1:0.647959 2:0.122449 3:0.045918 5:0.02583752 6:0.072789073 7:0.01795047 8:0.023809524 +-1 1:0.774648 3:0.014085 7:0.012882171 +-1 1:0.720721 2:0.036036 3:0.09009 5:0.051525949 7:0.023840915 8:0.023809524 +-1 1:0.794118 7:0.011657104 +-1 1:0.765957 7:0.011546445 8:0.023809524 +-1 1:0.723404 3:0.12766 4:0.0036900369 7:0.022963152 +-1 1:0.802632 3:0.026316 7:0.021020537 +-1 1:0.785714 3:0.071429 4:0.0036900369 7:0.014372823 +-1 1:0.758842 2:0.025723 3:0.025723 5:0.04192447 6:0.0067500068 7:0.017430006 +-1 1:0.758065 3:0.048387 7:0.01455547 8:0.023809524 +-1 1:0.792208 2:0.015584 3:0.038961 5:0.0048529214 6:0.0058590059 7:0.02432689 +-1 1:0.742424 2:0.022727 3:0.022727 5:0.027007887 7:0.012749445 +-1 1:0.768293 2:0.012195 3:0.036585 4:0.0036900369 5:0.037272822 7:0.014872098 +-1 1:0.777778 7:0.012787939 8:0.047619048 +-1 1:0.703704 2:0.055556 3:0.111111 5:0.033128084 6:0.013332013 7:0.025406506 +-1 1:0.736842 2:0.035088 3:0.017544 5:0.12634741 6:0.025425025 7:0.012623018 +-1 1:0.736842 2:0.026316 3:0.078947 5:0.076066375 7:0.015725287 +-1 1:0.8125 3:0.0625 7:0.02038872 +-1 1:0.816327 3:0.040816 7:0.018790445 +-1 1:0.709677 3:0.112903 7:0.01799764 +-1 1:0.768293 3:0.036585 4:0.0073800738 7:0.013979774 8:0.023809524 +-1 1:0.722222 2:0.111111 6:0.075000075 7:0.013550134 8:0.023809524 +-1 1:0.795699 7:0.014358774 8:0.023809524 +-1 1:0.565217 2:0.282609 3:0.021739 5:0.041879743 6:0.15168615 7:0.023594909 +-1 1:0.786667 3:0.053333 7:0.020731707 8:0.023809524 +-1 1:0.641026 2:0.076923 3:0.128205 5:0.029937531 6:0.024096024 7:0.019465293 +-1 1:0.847826 7:0.017497348 +-1 1:0.829787 3:0.06383 4:0.04797048 7:0.033731189 +-1 1:0.66129 2:0.032258 3:0.080645 5:0.10006262 7:0.014653817 +-1 1:0.789474 3:0.105263 4:0.0036900369 7:0.022785622 +-1 1:0.8 3:0.085714 7:0.023867598 +-1 1:0.647059 3:0.176471 7:0.011477762 +-1 1:0.785714 3:0.057143 7:0.019947738 +-1 1:0.75 2:0.034091 3:0.056818 5:0.027104796 6:0.010908011 7:0.019054878 +-1 1:0.790323 3:0.048387 4:0.0073800738 7:0.016424073 +-1 1:0.902748 2:0.006342 3:0.002114 6:0.0022020022 7:0.035141549 +-1 1:0.611111 2:0.166667 3:0.055556 5:0.62121122 7:0.012195122 +-1 1:0.808511 7:0.012584329 +-1 1:0.777778 7:0.010936896 +-1 1:0.785714 3:0.035714 7:0.01491725 +-1 1:0.823529 7:0.012195122 +-1 1:0.653543 2:0.074803 3:0.106299 4:0.011070111 6:0.03038103 7:0.037929707 +-1 1:0.770492 3:0.065574 7:0.017892841 8:0.023809524 +-1 1:0.674033 2:0.038674 3:0.116022 4:0.011070111 5:0.033277176 6:0.0089280089 7:0.022638457 8:0.023809524 +-1 1:0.794118 3:0.029412 4:0.022140221 7:0.022178384 +-1 1:0.774194 7:0.011644372 8:0.047619048 +-1 1:0.857143 7:0.015679445 +-1 1:0.692308 2:0.025641 3:0.064103 7:0.013914945 8:0.023809524 +-1 1:0.762295 2:0.045082 3:0.008197 5:0.11363738 7:0.016393439 +-1 1:0.833333 7:0.01549797 +-1 1:0.75 3:0.03125 7:0.010480183 8:0.023809524 +-1 1:0.762712 2:0.025424 3:0.008475 5:0.05647578 7:0.013642 +-1 1:0.667832 2:0.090909 3:0.045455 5:0.027440252 6:0.066258066 7:0.017375915 +-1 1:0.649351 2:0.051948 3:0.077922 4:0.0073800738 6:0.048129048 7:0.01480836 +-1 1:0.871795 7:0.046591622 +-1 1:0.704545 3:0.068182 7:0.013373061 +-1 1:0.756579 2:0.019737 3:0.039474 5:0.039546464 7:0.015123555 +-1 1:0.785185 3:0.037037 7:0.0163505 +-1 1:0.66129 2:0.016129 3:0.193548 4:0.014760148 5:0.027007887 7:0.027143982 +-1 1:0.812155 2:0.005525 3:0.005525 5:0.016310587 7:0.0153955 +-1 1:0.777778 3:0.074074 4:0.0036900369 7:0.016486 +-1 1:0.809524 7:0.01480836 +-1 1:0.794118 7:0.01201578 +-1 1:0.762376 3:0.029703 7:0.011893262 +-1 1:0.814815 7:0.01422764 +-1 1:0.625 2:0.017857 3:0.196429 4:0.033210332 5:0.044369567 7:0.018292683 +-1 1:0.85 7:0.015853659 8:0.023809524 +-1 1:0.65625 2:0.046875 3:0.09375 4:0.014760148 6:0.031413031 7:0.018197409 8:0.023809524 +-1 1:0.75 7:0.012588512 8:0.023809524 +-1 1:0.833333 7:0.014481707 +-1 1:0.79703 7:0.015938177 8:0.071428571 +-1 1:0.754098 2:0.038251 3:0.021858 4:0.0036900369 5:0.056691962 6:0.011406011 7:0.017526323 +-1 1:0.686747 2:0.048193 6:0.055557056 7:0.011901262 +-1 1:0.75 3:0.073529 7:0.015243902 +-1 1:0.794118 7:0.01201578 8:0.023809524 +-1 1:0.77451 3:0.019608 7:0.012553805 +-1 1:0.826087 7:0.012990457 +-1 1:0.680272 2:0.088435 3:0.027211 5:0.14474528 6:0.038835039 7:0.012817323 +-1 1:0.804124 2:0.010309 5:0.030056804 7:0.01558964 +-1 1:0.731343 3:0.044776 7:0.017200579 8:0.023809524 +-1 1:0.792929 4:0.0036900369 7:0.013211384 +-1 1:0.653846 2:0.051282 3:0.102564 4:0.0036900369 5:0.061351065 7:0.01899625 +-1 1:0.774648 3:0.028169 7:0.01442803 8:0.023809524 +-1 1:0.745098 2:0.019608 3:0.019608 5:0.048409941 7:0.018412244 +-1 1:0.810345 2:0.017241 3:0.017241 5:0.049043579 7:0.015979817 +-1 1:0.771429 2:0.028571 3:0.028571 5:0.092034052 7:0.0141115 8:0.023809524 +-1 1:0.760563 3:0.028169 7:0.011679835 +-1 1:0.692308 3:0.153846 4:0.011070111 7:0.01899625 +-1 1:0.793814 7:0.013766659 8:0.023809524 +-1 1:0.742574 2:0.059406 3:0.019802 5:0.087702951 6:0.023529024 7:0.015394829 8:0.023809524 +-1 1:0.787234 3:0.042553 7:0.014789829 +-1 1:0.770115 3:0.045977 7:0.015909726 8:0.047619048 +-1 1:0.790698 3:0.011628 7:0.013045945 +-1 1:0.715909 3:0.136364 4:0.022140221 7:0.022242238 +-1 1:0.756345 3:0.035533 7:0.014299866 +-1 1:0.7891 2:0.014218 3:0.007109 6:0.010656011 7:0.016269799 +-1 1:0.675676 3:0.027027 7:0.013019116 +-1 1:0.79096 3:0.045198 4:0.025830258 7:0.022633317 8:0.023809524 +-1 1:0.8125 7:0.010670732 +-1 1:0.765217 3:0.017391 7:0.012566274 8:0.095238095 +-1 1:0.715026 7:0.013522055 8:0.071428571 +-1 1:0.727273 2:0.077922 3:0.012987 5:0.11468847 6:0.030768031 7:0.015441878 +-1 1:0.638889 2:0.034722 3:0.111111 4:0.04797048 5:0.015498039 6:0.018711019 7:0.020367549 +-1 1:0.738095 2:0.02381 3:0.071429 4:0.0036900369 5:0.076066375 7:0.01422764 +-1 1:0.842105 7:0.013157896 +-1 1:0.882353 7:0.01649928 +-1 1:0.7 7:0.018597561 8:0.023809524 +-1 1:0.75 3:0.1 4:0.0036900369 7:0.017682927 8:0.023809524 +-1 1:0.741722 2:0.019868 3:0.046358 5:0.057936875 7:0.01558714 +-1 1:0.762452 7:0.012895994 +-1 1:0.73913 3:0.031056 7:0.013444933 +-1 1:0.642857 2:0.026786 3:0.116071 5:0.058928332 7:0.013773957 8:0.047619048 +-1 1:0.733607 2:0.04918 3:0.02459 5:0.10499754 6:0.015846016 7:0.014194323 +-1 1:0.646552 3:0.086207 4:0.033210332 7:0.01682086 +-1 1:0.761905 3:0.047619 4:0.0036900369 7:0.015098726 +-1 1:0.709091 2:0.027273 3:0.063636 6:0.021819022 7:0.015243902 +-1 1:0.875 7:0.020121951 +-1 1:0.776119 2:0.014925 3:0.059701 4:0.011070111 5:0.034514633 7:0.019657811 +-1 1:0.744681 2:0.037234 3:0.026596 6:0.031056031 7:0.015665543 +-1 1:0.681818 3:0.136364 7:0.02716186 +-1 1:0.809524 7:0.016453738 +-1 1:0.75 2:0.025 3:0.05 5:0.068388174 7:0.016615854 8:0.023809524 +-1 1:0.743434 2:0.014141 3:0.044444 5:0.039233373 7:0.016383348 +-1 1:0.753623 2:0.019324 3:0.038647 6:0.017307017 7:0.015317543 8:0.071428571 +-1 1:0.77193 2:0.026316 3:0.026316 5:0.070773635 7:0.016902012 +-1 1:0.772152 3:0.050633 7:0.016440262 +-1 1:0.75 2:0.031818 3:0.054545 5:0.032889538 6:0.013236013 7:0.018847006 +-1 1:0.755725 2:0.038168 3:0.038168 5:0.096812428 7:0.017920311 +-1 1:0.780723 2:0.00241 3:0.00241 4:0.011070111 5:0.0090722049 7:0.012077579 +-1 1:0.560606 2:0.136364 3:0.151515 4:0.0073800738 5:0.15861077 6:0.047871048 7:0.017368811 +-1 1:0.731034 2:0.068966 3:0.034483 5:0.081321843 6:0.010908011 7:0.023128677 +-1 1:0.555556 2:0.166667 5:0.27107778 7:0.018631439 +-1 1:0.724138 3:0.068966 4:0.0036900369 7:0.010933555 +-1 1:0.807229 3:0.060241 7:0.04327064 +-1 1:0.56962 2:0.202532 3:0.025316 5:0.032554083 6:0.15720616 7:0.017675207 +-1 1:0.743902 3:0.036585 4:0.0036900369 7:0.014425939 +-1 1:0.804348 7:0.013123012 8:0.023809524 +-1 1:0.643939 2:0.106061 3:0.037879 5:0.010294753 6:0.045579046 7:0.033444195 +-1 1:0.627907 2:0.186047 3:0.162791 6:0.022902023 7:0.11145774 +-1 1:0.754237 2:0.025424 3:0.033898 7:0.016742457 +-1 1:0.790323 3:0.016129 7:0.01380147 +-1 1:0.792553 3:0.005319 7:0.01521147 +-1 1:0.8 7:0.012638579 +-1 1:0.7 2:0.1 3:0.05 5:0.12424523 6:0.05000105 7:0.018292683 +-1 1:0.753846 3:0.046154 4:0.0073800738 7:0.019230768 +-1 1:0.711538 2:0.019231 3:0.019231 5:0.063177434 7:0.013836774 +-1 1:0.75 2:0.05 3:0.0375 5:0.087360041 7:0.019512195 +-1 1:0.72549 2:0.039216 3:0.078431 4:0.0073800738 5:0.079301656 7:0.022477287 +-1 1:0.769231 2:0.008547 3:0.076923 5:0.020313688 7:0.019126537 +-1 1:0.75 3:0.025 7:0.016768293 +-1 1:0.775 3:0.0625 7:0.020884146 +-1 1:0.72093 2:0.007752 3:0.069767 4:0.029520295 5:0.019113503 7:0.018434488 8:0.047619048 +-1 1:0.805825 2:0.009709 3:0.009709 6:0.011904012 7:0.014918305 +-1 1:0.681159 3:0.043478 7:0.014050902 +-1 1:0.769231 3:0.038462 7:0.01477486 +-1 1:0.659091 2:0.204545 6:0.17518218 7:0.018985585 +-1 1:0.716981 3:0.113208 4:0.014760148 7:0.024792915 +-1 1:0.73913 3:0.130435 4:0.018450185 7:0.03043478 +-1 1:0.788235 2:0.011765 3:0.005882 5:0.038130097 7:0.01402439 8:0.023809524 +-1 1:0.796296 7:0.01388889 8:0.047619048 +-1 1:0.785276 3:0.027607 7:0.017469701 +-1 1:0.723926 2:0.03681 3:0.018405 5:0.057638692 6:0.015465015 7:0.014514439 +-1 1:0.72973 2:0.027027 3:0.054054 4:0.0036900369 5:0.093182055 7:0.013183915 +-1 1:0.813187 7:0.014205305 +-1 1:0.786325 2:0.008547 3:0.034188 7:0.016520744 +-1 1:0.811765 3:0.023529 7:0.017144909 +-1 1:0.74375 2:0.025 6:0.03000003 7:0.011432927 8:0.095238095 +-1 1:0.794118 7:0.01201578 +-1 1:0.806452 7:0.012785207 +-1 1:0.767196 2:0.031746 3:0.026455 4:0.0073800738 6:0.027273027 7:0.017744226 +-1 1:0.714286 2:0.064935 3:0.022727 5:0.044958478 6:0.032568033 7:0.016411939 +-1 1:0.659794 2:0.134021 3:0.030928 4:0.0036900369 5:0.030675533 6:0.098766099 7:0.015275335 +-1 1:0.785714 7:0.0095818841 8:0.023809524 +-1 1:0.75 3:0.166667 7:0.023882116 +-1 1:0.774892 3:0.056277 7:0.016920073 +-1 1:0.655914 3:0.129032 7:0.02025964 +-1 1:0.688047 2:0.040816 3:0.072886 5:0.0082298391 6:0.02980203 7:0.016106091 +-1 1:0.677419 2:0.032258 3:0.032258 7:0.015145555 +-1 1:0.57 2:0.21 3:0.02 5:0.10401354 6:0.18139518 7:0.013109756 +-1 1:0.851852 3:0.037037 7:0.02168022 +-1 1:0.784553 7:0.014302 8:0.023809524 +-1 1:0.740741 3:0.055556 7:0.013098463 +-1 1:0.810345 7:0.016084945 +-1 1:0.765766 3:0.027027 7:0.012799384 +-1 1:0.777108 3:0.054217 4:0.0036900369 7:0.016676463 +-1 1:0.75 2:0.045455 3:0.022727 5:0.13252725 7:0.015590354 +-1 1:0.791667 2:0.041667 3:0.020833 5:0.089812592 7:0.021087396 +-1 1:0.736318 2:0.052239 3:0.017413 5:0.074172916 6:0.017910018 7:0.015243902 8:0.023809524 +-1 1:0.785714 7:0.0095818841 +-1 1:0.794521 7:0.013197463 +-1 1:0.677419 2:0.064516 3:0.016129 5:0.046591028 6:0.037500038 7:0.01573564 +-1 1:0.765625 3:0.03125 7:0.019435976 +-1 1:0.787356 3:0.022989 7:0.016172555 +-1 1:0.763158 3:0.039474 7:0.012516049 +-1 1:0.774194 2:0.021505 3:0.032258 5:0.063989981 7:0.015276683 +-1 1:0.818182 7:0.014729171 +-1 1:0.730769 7:0.010084427 8:0.047619048 +-1 1:0.783951 3:0.024691 7:0.014302921 8:0.023809524 +-1 1:0.704819 2:0.006024 3:0.042169 4:0.0073800738 5:0.022453148 7:0.012195122 8:0.095238095 +-1 1:0.611111 2:0.055556 3:0.074074 5:0.12220267 6:0.024591025 7:0.01377597 +-1 1:0.712329 2:0.027397 3:0.041096 5:0.10573554 7:0.011777482 +-1 1:0.591304 2:0.173913 3:0.052174 5:0.14109254 6:0.094638095 7:0.016808061 +-1 1:0.69697 3:0.151515 4:0.014760148 7:0.018292683 +-1 1:0.785088 2:0.004386 3:0.035088 7:0.019308945 +-1 1:0.681373 2:0.058824 3:0.068627 5:0.013910217 7:0.016021043 8:0.023809524 +-1 1:0.774892 3:0.025974 7:0.016233768 8:0.023809524 +-1 1:0.666667 3:0.076923 4:0.0073800738 7:0.015322073 +-1 1:0.738938 2:0.017699 3:0.035398 4:0.011070111 6:0.010581011 7:0.015297866 +-1 1:0.747475 2:0.010101 3:0.080808 7:0.018354274 +-1 1:0.688889 7:0.012330622 +-1 1:0.738462 2:0.030769 3:0.061538 5:0.039867011 7:0.017542213 +-1 1:0.8 7:0.01197339 +-1 1:0.77193 7:0.011767226 +-1 1:0.78481 7:0.01142328 +-1 1:0.65236 2:0.030043 3:0.158798 4:0.029520295 5:0.027142069 6:0.0072810073 7:0.021563909 +-1 1:0.857143 3:0.035714 4:0.018450185 7:0.024608012 +-1 1:0.779221 7:0.011878366 +-1 1:0.805031 3:0.025157 4:0.0036900369 7:0.019941707 +-1 1:0.744898 2:0.040816 3:0.020408 5:0.094762423 7:0.014683921 +-1 1:0.796163 2:0.002398 3:0.007194 5:0.0072607458 7:0.015017256 8:0.023809524 +-1 1:0.777778 7:0.010614274 +-1 1:0.759036 7:0.012562445 8:0.071428571 +-1 1:0.76 2:0.05 5:0.12688414 7:0.014329268 +-1 1:0.680851 3:0.148936 4:0.0036900369 7:0.016865591 +-1 1:0.681818 2:0.075758 3:0.090909 5:0.070102724 6:0.0094050094 7:0.029471543 +-1 1:0.780702 2:0.04386 3:0.017544 5:0.10994737 7:0.01813222 +-1 1:0.755906 2:0.028871 3:0.026247 4:0.0073800738 5:0.0077974744 6:0.025104025 7:0.015299915 +-1 1:0.72973 2:0.036036 3:0.072072 4:0.014760148 6:0.024930025 7:0.019830805 +-1 1:0.781155 2:0.009119 3:0.015198 5:0.019359504 7:0.014270884 8:0.047619048 +-1 1:0.826816 7:0.016844939 +-1 1:0.766169 2:0.014925 3:0.034826 5:0.031808626 7:0.021326293 +-1 1:0.702381 2:0.047619 3:0.059524 5:0.036542275 6:0.014706015 7:0.01480836 +-1 1:0.670051 2:0.086294 3:0.040609 4:0.0036900369 5:0.096394973 6:0.038793039 7:0.014361768 +-1 1:0.8 7:0.012652439 +-1 1:0.631579 2:0.114035 3:0.114035 4:0.0073800738 5:0.15090275 6:0.0060720061 7:0.026422762 +-1 1:0.621622 2:0.108108 3:0.135135 5:0.19446722 7:0.018951878 +-1 1:0.65 2:0.1 3:0.06 4:0.014760148 5:0.062640705 6:0.088236088 7:0.014512195 +-1 1:0.586207 2:0.103448 3:0.137931 5:0.32410955 7:0.014507988 +-1 1:0.411765 2:0.176471 3:0.176471 5:0.25705575 7:0.020803445 +-1 1:0.742188 2:0.023438 3:0.0625 5:0.063714162 7:0.016720659 +-1 1:0.632653 2:0.142857 3:0.040816 5:0.43125401 7:0.015057244 +-1 1:0.745098 3:0.04902 7:0.014586323 +-1 1:0.6375 2:0.0875 3:0.05 5:0.21818019 7:0.015625 +-1 1:0.858065 3:0.012903 7:0.023721482 +-1 1:0.643243 2:0.048649 3:0.081081 4:0.0073800738 5:0.079987476 6:0.012876013 7:0.015359262 8:0.071428571 +-1 1:0.76555 2:0.004785 5:0.017018771 7:0.012778622 8:0.047619048 +-1 1:0.714286 2:0.02381 3:0.071429 7:0.012485482 8:0.023809524 +-1 1:0.833333 7:0.011686994 +-1 1:0.674699 2:0.048193 3:0.096386 5:0.10548954 7:0.015574494 +-1 1:0.730769 7:0.016416512 +-1 1:0.755814 3:0.081395 4:0.011070111 7:0.017938171 +-1 1:0.782609 7:0.011797457 +-1 1:0.567568 2:0.162162 3:0.081081 5:0.28671746 6:0.076923077 7:0.012854317 +-1 1:0.876712 3:0.013699 4:0.13284133 7:0.082776476 +-1 1:0.785714 3:0.035714 7:0.014155055 +-1 1:0.710526 2:0.052632 3:0.026316 5:0.16031041 7:0.014922976 +-1 1:0.727273 2:0.019139 3:0.076555 5:0.025315701 7:0.017184037 +-1 1:0.794118 3:0.009804 7:0.022537067 8:0.071428571 +-1 1:0.769231 3:0.025641 7:0.012038774 +-1 1:0.774648 7:0.011250427 8:0.023809524 +-1 1:0.775 7:0.011737805 8:0.023809524 +-1 1:0.741667 3:0.016667 7:0.011941055 +-1 1:0.75 3:0.035714 4:0.0036900369 7:0.015516116 8:0.047619048 +-1 1:0.75 3:0.035714 4:0.0036900369 7:0.015352787 8:0.047619048 +-1 1:0.815789 7:0.012997433 +-1 1:0.77907 7:0.015704762 8:0.023809524 +-1 1:0.75 3:0.066667 7:0.028353659 +-1 1:0.778689 2:0.040984 5:0.02258733 6:0.027273027 7:0.016493402 8:0.023809524 +-1 1:0.813793 3:0.024138 7:0.018566024 +-1 1:0.745342 2:0.006211 3:0.043478 4:0.0036900369 7:0.014732616 8:0.023809524 +-1 1:0.777778 2:0.009259 3:0.046296 4:0.0073800738 5:0.023370059 7:0.01801039 8:0.047619048 +-1 1:0.776119 3:0.037313 7:0.014925372 8:0.023809524 +-1 1:0.684211 7:0.015083439 +-1 1:0.785714 7:0.012195122 8:0.023809524 +-1 1:0.705128 3:0.153846 4:0.014760148 7:0.025641024 8:0.023809524 +-1 1:0.645161 2:0.032258 3:0.096774 5:0.10353645 7:0.014162079 +-1 1:0.790323 4:0.0036900369 7:0.012195122 8:0.023809524 +-1 1:0.798165 2:0.009174 3:0.009174 5:0.023370059 7:0.017845152 +-1 1:0.862069 7:0.015979817 +-1 1:0.781818 3:0.054545 7:0.01607539 +-1 1:0.828571 2:0.028571 5:0.067769445 7:0.019163762 +-1 1:0.83871 2:0.016129 5:0.039867011 7:0.01839103 +-1 1:0.732673 2:0.029703 3:0.049505 5:0.088396225 7:0.015274091 +-1 1:0.75641 3:0.012821 7:0.014618512 +-1 1:0.642857 2:0.059524 3:0.166667 6:0.027777028 7:0.031358884 +-1 1:0.717949 3:0.179487 4:0.0036900369 7:0.028611628 +-1 1:0.811111 3:0.022222 7:0.028794037 +-1 1:0.783784 2:0.005405 3:0.021622 5:0.014506582 7:0.016941329 +-1 1:0.646409 2:0.038674 3:0.055249 4:0.014760148 5:0.072234729 7:0.017383104 8:0.047619048 +-1 1:0.719512 3:0.042683 7:0.01970553 8:0.047619048 +-1 1:0.7225 2:0.01 3:0.04 4:0.025830258 5:0.02524861 7:0.018003049 8:0.071428571 +-1 1:0.857143 7:0.016986061 +-1 1:0.888889 7:0.022527098 +-1 1:0.712644 2:0.045977 3:0.045977 5:0.034194087 6:0.027522028 7:0.015278945 +-1 1:0.818182 7:0.011640799 +-1 1:0.752688 2:0.010753 5:0.041879743 7:0.011670598 +-1 1:0.761905 3:0.011905 7:0.015098726 +-1 1:0.788462 3:0.019231 7:0.013836774 8:0.047619048 +-1 1:0.787234 3:0.042553 7:0.014141152 +-1 1:0.722222 7:0.017953927 +-1 1:0.736842 2:0.010526 3:0.094737 4:0.022140221 5:0.023295514 7:0.020539152 +-1 1:0.727273 2:0.045455 3:0.106061 6:0.007959008 7:0.034830006 +-1 1:0.723077 2:0.061538 5:0.11739448 6:0.023622024 7:0.011913695 +-1 1:0.576271 2:0.186441 3:0.033898 5:0.065972895 6:0.18584119 7:0.011678378 +-1 1:0.699301 2:0.062937 3:0.041958 4:0.0036900369 5:0.04372102 6:0.026394026 7:0.014540335 +-1 1:0.742424 2:0.015152 3:0.045455 4:0.014760148 5:0.049043579 7:0.014042866 +-1 1:0.777778 3:0.037037 7:0.012195122 +-1 1:0.729167 3:0.104167 4:0.0036900369 7:0.017911585 +-1 1:0.792208 7:0.014887549 8:0.071428571 +-1 1:0.64527 2:0.091216 3:0.108108 4:0.025830258 6:0.055323055 7:0.024575646 +-1 1:0.752809 2:0.022472 3:0.05618 5:0.027708616 7:0.018429707 +-1 1:0.722222 2:0.013889 3:0.083333 7:0.015582659 +-1 1:0.767241 3:0.034483 7:0.014507988 +-1 1:0.792531 3:0.012448 7:0.014016799 8:0.047619048 +-1 1:0.753731 3:0.052239 4:0.0036900369 7:0.015926463 +-1 1:0.818182 3:0.022727 7:0.017461195 +-1 1:0.8 3:0.028571 7:0.016027878 +-1 1:0.665072 2:0.033493 3:0.110048 6:0.02034002 7:0.017213213 +-1 1:0.755556 3:0.066667 4:0.0036900369 7:0.015176152 +-1 1:0.643312 2:0.025478 3:0.11465 5:0.066710897 7:0.017360573 +-1 1:0.787234 3:0.021277 7:0.014270884 +-1 1:0.764706 3:0.098039 7:0.024988043 +-1 1:0.746269 2:0.014925 5:0.051056312 7:0.013287226 8:0.047619048 +-1 1:0.785714 2:0.071429 5:0.248483 7:0.013066201 +-1 1:0.8 2:0.006061 3:0.018182 5:0.015214766 7:0.018107909 8:0.023809524 +-1 1:0.75 3:0.125 4:0.0036900369 7:0.015625 +-1 1:0.802083 2:0.020833 3:0.010417 5:0.051585586 7:0.018356201 +-1 1:0.79661 3:0.016949 7:0.014882183 +-1 1:0.786885 2:0.016393 3:0.065574 5:0.028670255 7:0.025989604 +-1 1:0.732026 2:0.013072 3:0.058824 5:0.020880235 7:0.01422764 +-1 1:0.769231 2:0.025641 3:0.025641 5:0.085682764 7:0.01360225 +-1 1:0.577982 2:0.192661 3:0.018349 5:0.069021812 6:0.19444519 7:0.012083238 +-1 1:0.681818 2:0.011364 3:0.159091 5:0.022386057 7:0.023073726 +-1 1:0.772472 3:0.033708 7:0.014370378 8:0.023809524 +-1 1:0.642857 2:0.071429 7:0.021341463 +-1 1:0.708333 2:0.020833 3:0.0625 7:0.012957317 +-1 1:0.78125 7:0.015434451 +-1 1:0.733333 2:0.009524 3:0.066667 5:0.028558436 7:0.015156793 +-1 1:0.833333 7:0.014735774 +-1 1:0.846154 7:0.012195122 +-1 1:0.693878 2:0.020408 3:0.102041 5:0.069021812 7:0.013439524 +-1 1:0.753086 2:0.012346 3:0.049383 5:0.036363365 7:0.015432098 +-1 1:0.735484 2:0.012903 3:0.064516 5:0.0069401995 7:0.042250195 8:0.047619048 +-1 1:0.789474 7:0.016768293 +-1 1:0.857143 7:0.021123695 +-1 1:0.727273 2:0.033058 3:0.057851 5:0.076327285 7:0.014765171 +-1 1:0.75 7:0.015243902 8:0.023809524 +-1 1:0.732143 2:0.053571 6:0.051282051 7:0.012739549 +-1 1:0.764706 7:0.0095050244 +-1 1:0.746154 3:0.053846 7:0.01435272 8:0.023809524 +-1 1:0.676471 2:0.014706 3:0.117647 5:0.043847748 7:0.015243902 +-1 1:0.731959 2:0.030928 3:0.041237 5:0.097654794 7:0.014395274 +-1 1:0.773438 3:0.046875 4:0.0036900369 7:0.015910823 +-1 1:0.727273 3:0.030303 7:0.01127125 +-1 1:0.741259 2:0.041958 3:0.062937 5:0.076849105 7:0.020680537 +-1 1:0.724806 2:0.007752 3:0.062016 5:0.026113339 7:0.013494988 +-1 1:0.754098 3:0.098361 4:0.0073800738 7:0.021591366 +-1 1:0.741176 2:0.023529 3:0.023529 5:0.079726567 7:0.013414634 +-1 1:0.846154 7:0.012195122 +-1 1:0.75 7:0.016877177 +-1 1:0.833333 7:0.014634146 +-1 1:0.704918 3:0.114754 4:0.0073800738 7:0.022291085 +-1 1:0.73913 3:0.086957 4:0.011070111 7:0.014713677 +-1 1:0.780488 7:0.014128494 +-1 1:0.833333 7:0.011686994 +-1 1:0.686567 2:0.014925 3:0.104478 4:0.0073800738 7:0.01356025 8:0.023809524 +-1 1:0.911765 3:0.029412 7:0.057568146 +-1 1:0.746667 3:0.073333 4:0.011070111 7:0.017926829 8:0.047619048 +-1 1:0.864865 7:0.017633488 +-1 1:0.85 7:0.01402439 +-1 1:0.807692 3:0.076923 7:0.082317073 +-1 1:0.788462 3:0.019231 7:0.01325047 8:0.023809524 +-1 1:0.8 7:0.011788616 8:0.023809524 +-1 1:0.756098 2:0.00813 3:0.01626 5:0.028021708 7:0.013186598 +-1 1:0.75 3:0.03125 4:0.0036900369 7:0.013199835 8:0.095238095 +-1 1:0.62 2:0.1 3:0.12 5:0.15530094 7:0.023414634 +-1 1:0.728814 3:0.135593 4:0.025830258 7:0.031211244 +-1 1:0.555556 2:0.055556 3:0.166667 5:0.15213275 7:0.016598915 +-1 1:0.757576 7:0.0097930549 8:0.023809524 +-1 1:0.710145 2:0.028986 3:0.057971 7:0.015111348 +-1 1:0.64 3:0.16 7:0.012926829 +-1 1:0.972222 7:0.070121951 +-1 1:0.393939 2:0.212121 3:0.121212 5:0.38228497 7:0.014412415 +-1 1:0.778626 2:0.003817 3:0.038168 4:0.022140221 5:0.0086100219 7:0.020154537 8:0.047619048 +-1 1:0.769231 7:0.0093808659 +-1 1:0.758065 2:0.008065 3:0.032258 7:0.013522817 8:0.047619048 +-1 1:0.75 2:0.104167 5:0.098519524 6:0.026433026 7:0.028836384 +-1 1:0.574627 2:0.141791 3:0.089552 5:0.04176047 6:0.092436092 7:0.016244994 +-1 1:0.713287 2:0.041958 3:0.053613 5:0.018561865 6:0.0074700075 7:0.017127183 8:0.023809524 +-1 1:0.8 2:0.009091 3:0.027273 4:0.0036900369 5:0.022117693 7:0.018680707 +-1 1:0.814286 3:0.028571 7:0.019337982 +-1 1:0.715054 2:0.043011 3:0.053763 4:0.011070111 5:0.050564311 6:0.014535015 7:0.016915817 8:0.023809524 +-1 1:0.641196 2:0.136213 3:0.033223 5:0.1093361 6:0.087999088 7:0.015193256 +-1 1:0.846154 3:0.076923 4:0.0036900369 7:0.023921201 +-1 1:0.545455 2:0.204545 3:0.068182 4:0.011070111 5:0.74545644 7:0.012472287 +-1 1:0.809524 7:0.014663183 +-1 1:0.811321 7:0.01599172 +-1 1:0.766551 2:0.027875 3:0.017422 5:0.076849105 7:0.016486787 +-1 1:0.666667 2:0.076923 3:0.102564 4:0.0036900369 5:0.05734051 6:0.069231069 7:0.020325201 8:0.023809524 +-1 1:0.863636 7:0.018569848 +-1 1:0.916667 7:0.018292683 +-1 1:0.69697 3:0.090909 4:0.0073800738 7:0.024575018 +-1 1:0.732394 3:0.056338 7:0.01597389 +-1 1:0.899083 3:0.036697 4:0.11439114 7:0.12709778 +-1 1:0.766355 3:0.046729 7:0.016184183 8:0.023809524 +-1 1:0.821429 3:0.035714 7:0.01633275 +-1 1:0.779528 7:0.01214711 +-1 1:0.827586 3:0.103448 7:0.044365012 +-1 1:0.695652 3:0.130435 4:0.0073800738 7:0.012460232 +-1 1:0.988024 7:0.17142545 +-1 1:0.945455 7:0.17073171 +-1 1:0.774194 7:0.011605037 8:0.023809524 +-1 1:0.731343 3:0.119403 4:0.0073800738 7:0.020658902 8:0.023809524 +-1 1:0.658537 2:0.02439 3:0.170732 7:0.021118384 +-1 1:0.735294 2:0.051471 3:0.022059 5:0.11027537 6:0.017751018 7:0.015154232 +-1 1:0.682927 2:0.02439 3:0.02439 5:0.035841546 7:0.03093397 8:0.023809524 +-1 1:0.711111 2:0.022222 3:0.022222 5:0.024279516 7:0.041598915 8:0.023809524 +-1 1:0.780488 3:0.02439 7:0.013756695 +-1 1:0.482143 2:0.267857 3:0.017857 5:0.024682063 6:0.099339099 7:0.032883274 +-1 1:0.7 2:0.028571 3:0.114286 4:0.0036900369 5:0.015498039 7:0.041898951 +-1 1:0.896552 7:0.022287634 +-1 1:0.73913 3:0.130435 7:0.018292683 +-1 1:0.76 7:0.01804878 +-1 1:0.84 7:0.01597561 +-1 1:0.865854 3:0.060976 7:0.051457463 +-1 1:0.742857 7:0.026306622 +-1 1:0.645833 2:0.104167 3:0.125 6:0.052449052 7:0.036331299 +-1 1:0.730769 3:0.076923 4:0.0036900369 7:0.013133207 8:0.023809524 +-1 1:0.666667 2:0.074074 3:0.037037 5:0.06160452 6:0.024792025 7:0.02732611 +-1 1:0.666667 2:0.111111 6:0.071430071 7:0.01422764 +-1 1:0.666667 3:0.047619 7:0.017131244 +-1 1:0.666667 3:0.047619 7:0.016260165 +-1 1:0.857143 2:0.02381 3:0.02381 5:0.042841382 7:0.025261323 +-1 1:0.75 3:0.166667 4:0.0036900369 7:0.019308945 +-1 1:0.807692 7:0.01242964 +-1 1:0.875 7:0.01867378 +-1 1:0.796296 3:0.024691 7:0.016034329 +-1 1:0.740741 3:0.111111 7:0.017389341 +-1 1:0.672566 2:0.044248 3:0.061947 5:0.025352974 6:0.02040902 7:0.015864451 8:0.023809524 +-1 1:0.766667 7:0.011991872 8:0.071428571 +-1 1:0.772727 7:0.01657428 8:0.071428571 +-1 1:0.780303 7:0.012241317 8:0.023809524 +-1 1:0.625 3:0.125 7:0.0091463415 +-1 1:0.918919 2:0.027027 3:0.054054 4:0.0036900369 5:0.010600391 7:0.11585366 +-1 1:0.78125 3:0.015625 7:0.01324314 8:0.023809524 +-1 1:0.692308 3:0.057692 7:0.014305817 8:0.071428571 +-1 1:0.738462 3:0.015385 7:0.013039402 8:0.095238095 +-1 1:0.752688 7:0.011408341 8:0.11904762 +-1 1:0.633333 3:0.133333 4:0.011070111 7:0.010569104 +-1 1:0.727273 3:0.024793 7:0.013303768 8:0.047619048 +-1 1:0.80597 7:0.013651256 +-1 1:0.798246 3:0.008772 7:0.015939238 8:0.047619048 +-1 1:0.75 2:0.043478 3:0.043478 4:0.0073800738 5:0.10962682 7:0.018027573 +-1 1:0.775862 7:0.015664421 +-1 1:0.756757 2:0.027027 3:0.054054 7:0.019281476 +-1 1:0.837838 7:0.019528677 +-1 1:0.8 3:0.066667 7:0.020731707 +-1 1:0.789474 7:0.012195122 +-1 1:0.759399 3:0.015038 7:0.012607738 8:0.071428571 +-1 1:0.84375 7:0.016196646 +-1 1:0.628571 2:0.028571 3:0.057143 7:0.01010453 8:0.023809524 +-1 1:0.733333 3:0.044444 4:0.011070111 7:0.012782293 8:0.071428571 +-1 1:0.753247 2:0.025974 3:0.012987 7:0.013620524 8:0.023809524 +-1 1:0.644444 2:0.044444 3:0.044444 7:0.013414634 8:0.023809524 +-1 1:0.72973 2:0.013514 3:0.040541 7:0.012854317 8:0.023809524 +-1 1:0.625 2:0.125 3:0.125 5:0.33884723 7:0.016768293 +-1 1:0.725 3:0.1 4:0.033210332 7:0.022294207 +-1 1:0.746835 2:0.018987 3:0.037975 4:0.0036900369 6:0.015708016 7:0.014742207 8:0.071428571 +-1 1:0.690789 2:0.039474 3:0.078947 5:0.038033188 6:0.015306015 7:0.015725287 +-1 1:0.55914 2:0.107527 3:0.150538 4:0.022140221 5:0.093569693 6:0.037656038 7:0.015670073 +-1 1:0.730539 2:0.017964 3:0.065868 5:0.033500813 7:0.016247994 +-1 1:0.775862 3:0.008621 7:0.014797098 8:0.023809524 +-1 1:0.741935 3:0.064516 7:0.012588512 +-1 1:0.767442 3:0.023256 7:0.013471354 8:0.071428571 +-1 1:0.758621 7:0.010513037 +-1 1:0.736842 7:0.013960207 +-1 1:0.831325 7:0.026777841 +-1 1:0.511111 2:0.244444 3:0.044444 5:0.54356447 6:0.031251031 7:0.013008128 +-1 1:0.727273 3:0.090909 7:0.014135256 +-1 1:0.7 3:0.071429 7:0.011846689 8:0.023809524 +-1 1:0.780952 3:0.019048 7:0.01480836 +-1 1:0.795455 7:0.013303768 +-1 1:0.757009 3:0.056075 4:0.0073800738 7:0.016070207 8:0.047619048 +-1 1:0.75 3:0.125 4:0.018450185 7:0.038436409 8:0.023809524 +-1 1:0.732143 7:0.010452963 +-1 1:0.73913 3:0.086957 7:0.019353128 8:0.023809524 +-1 1:0.705882 3:0.117647 7:0.01721664 +-1 1:0.660714 2:0.071429 3:0.071429 4:0.0073800738 5:0.05605087 6:0.022557023 7:0.014481707 +-1 1:0.75 3:0.019231 7:0.010905256 +-1 1:0.571429 2:0.142857 3:0.142857 5:0.45179133 7:0.014372823 +-1 1:0.662791 2:0.023256 3:0.081395 5:0.069342358 7:0.015243902 +-1 1:0.846154 7:0.012664165 +-1 1:0.714286 3:0.178571 4:0.011070111 7:0.024608012 +-1 1:0.741935 3:0.075269 7:0.01573564 +-1 1:0.768 2:0.004 3:0.052 7:0.019926829 +-1 1:0.711864 2:0.033898 3:0.084746 5:0.066166714 6:0.0088770089 7:0.017465896 +-1 1:0.659864 2:0.054422 3:0.097506 4:0.095940959 5:0.031741535 6:0.025551026 7:0.019481774 +-1 1:0.777778 2:0.004274 3:0.017094 7:0.014357933 8:0.095238095 +-1 1:0.72381 2:0.009524 3:0.114286 4:0.0073800738 5:0.018874957 7:0.022938445 +-1 1:0.853659 7:0.031677573 8:0.023809524 +-1 1:0.814815 7:0.014679317 8:0.023809524 +-1 1:0.708502 2:0.02834 3:0.064777 4:0.0073800738 5:0.021894056 6:0.013215013 7:0.016811494 8:0.047619048 +-1 1:0.755102 7:0.011821805 +-1 1:0.793103 7:0.012195122 8:0.023809524 +-1 1:0.768293 3:0.018293 7:0.013570793 8:0.071428571 +-1 1:0.75 7:0.013109756 +-1 1:0.75 3:0.09375 7:0.023151677 8:0.023809524 +-1 1:0.805556 3:0.055556 7:0.018800811 +-1 1:0.832117 3:0.153285 4:0.070110701 7:0.16823927 +-1 1:0.780488 3:0.02439 7:0.014277213 +-1 1:0.814815 3:0.037037 7:0.016937671 +-1 1:0.754658 2:0.015528 3:0.040373 4:0.0036900369 5:0.027074978 7:0.015641567 +-1 1:0.759494 7:0.012581043 +-1 1:0.709677 2:0.019355 3:0.064516 5:0.02070878 7:0.014162079 +-1 1:0.754717 3:0.113208 7:0.028531982 +-1 1:0.735294 3:0.088235 7:0.014347201 8:0.023809524 +-1 1:0.75 3:0.09375 7:0.018483232 +-1 1:0.80198 7:0.013523305 +-1 1:0.74 2:0.01 3:0.03 7:0.01195122 +-1 1:0.846154 7:0.020286116 +-1 1:0.682119 2:0.059603 3:0.019868 6:0.066456066 7:0.012760457 8:0.047619048 +-1 1:0.733728 2:0.029586 3:0.023669 5:0.016422405 7:0.016380433 +-1 1:0.740741 3:0.104938 7:0.024202049 8:0.023809524 +-1 1:0.725086 2:0.051546 3:0.017182 5:0.010384208 6:0.045960046 7:0.015044841 8:0.023809524 +-1 1:0.772908 2:0.003984 3:0.035857 5:0.009720752 7:0.018632787 8:0.095238095 +-1 1:0.73399 2:0.039409 3:0.014778 6:0.034248034 7:0.013156311 8:0.023809524 +-1 1:0.733333 2:0.016667 3:0.066667 5:0.052129769 7:0.014532518 +-1 1:0.731092 3:0.084034 7:0.017575323 8:0.047619048 +-1 1:0.585859 2:0.070707 3:0.191919 4:0.0073800738 5:0.14522237 7:0.018970189 +-1 1:0.875 7:0.033536585 +-1 1:0.789474 7:0.010911427 +-1 1:0.807692 7:0.01242964 8:0.023809524 +-1 1:0.7625 3:0.0375 4:0.0036900369 7:0.014176829 8:0.023809524 +-1 1:0.733333 7:0.0091463415 8:0.023809524 +-1 1:0.715596 2:0.045872 3:0.055046 5:0.023668242 6:0.028572029 7:0.01762139 +-1 1:0.75 2:0.005814 3:0.063953 5:0.016944225 7:0.015598415 +-1 1:0.814815 7:0.014905146 +-1 1:0.793249 3:0.012658 7:0.015514049 8:0.023809524 +-1 1:0.647887 2:0.028169 3:0.126761 4:0.014760148 6:0.016950017 7:0.015200963 +-1 1:0.734513 3:0.070796 4:0.0036900369 7:0.015540689 +-1 1:0.494737 2:0.157895 3:0.147368 5:0.13647071 7:0.02804878 +-1 1:0.738095 3:0.047619 7:0.014953543 8:0.023809524 +-1 1:0.618644 2:0.09322 3:0.084746 4:0.0036900369 6:0.091836092 7:0.015192226 +-1 1:0.758621 7:0.011704512 8:0.11904762 +-1 1:0.727273 3:0.136364 4:0.014760148 7:0.019955652 +-1 1:0.804124 7:0.013138043 +-1 1:0.681818 3:0.136364 4:0.0073800738 7:0.017184037 8:0.023809524 +-1 1:0.833333 7:0.01388889 +-1 1:0.666667 3:0.16 7:0.01617886 +-1 1:0.866667 7:0.018699189 +-1 1:0.5625 2:0.0625 6:0.061224061 7:0.01867378 +-1 1:0.821429 7:0.01480836 +-1 1:0.769231 7:0.025093811 8:0.023809524 +-1 1:0.818182 7:0.015705841 +-1 1:0.810811 7:0.014831902 +-1 1:0.765432 3:0.037037 7:0.013550134 +-1 1:0.754098 3:0.016393 7:0.014494201 8:0.047619048 +-1 1:0.723684 3:0.078947 4:0.014760148 7:0.018051988 8:0.023809524 +-1 1:0.678571 3:0.107143 7:0.036803134 +-1 1:0.728814 2:0.025424 3:0.067797 4:0.011070111 5:0.010570572 6:0.012765013 7:0.018215171 8:0.047619048 +-1 1:0.827586 7:0.014507988 8:0.023809524 +-1 1:0.878049 7:0.032718622 +-1 1:0.791667 7:0.012195122 +-1 1:0.68 3:0.12 4:0.0073800738 7:0.011707317 +-1 1:0.72 2:0.08 6:0.05000105 7:0.014634146 +-1 1:0.765957 3:0.042553 7:0.013622213 +-1 1:0.714286 2:0.02381 3:0.071429 5:0.068388174 7:0.015824622 8:0.023809524 +-1 1:0.675325 2:0.051948 3:0.103896 4:0.0036900369 7:0.017817549 8:0.023809524 +-1 1:0.714286 3:0.081633 4:0.0073800738 7:0.019785963 +-1 1:0.722222 2:0.038889 3:0.061111 6:0.023811024 7:0.021341463 8:0.071428571 +-1 1:0.777778 2:0.055556 6:0.068181068 7:0.014905146 +-1 1:0.754386 7:0.013692768 8:0.047619048 +-1 1:0.837838 7:0.016479896 +-1 1:0.839286 7:0.01644164 +-1 1:0.76087 3:0.021739 7:0.010869567 +-1 1:0.730769 2:0.038462 3:0.053846 5:0.033500813 6:0.013482013 7:0.020872421 +-1 1:0.724138 7:0.017031116 +-1 1:0.833333 7:0.011686994 +-1 1:0.75 2:0.020833 3:0.034722 6:0.015957016 7:0.015921409 8:0.047619048 +-1 1:0.764706 7:0.012195122 8:0.023809524 +-1 1:0.75 3:0.076087 4:0.0073800738 7:0.017828738 +-1 1:0.75 2:0.015625 3:0.0625 5:0.044637932 7:0.015910823 +-1 1:0.642857 3:0.071429 7:0.011324043 +-1 1:0.679245 3:0.09434 4:0.0036900369 7:0.021398988 8:0.023809524 +-1 1:0.777778 3:0.018519 7:0.013098463 8:0.047619048 +-1 1:0.666667 3:0.083333 7:0.010162604 8:0.023809524 +-1 1:0.833333 7:0.011686994 +-1 1:0.659574 3:0.12766 4:0.0036900369 7:0.01453036 8:0.023809524 +-1 1:0.810976 3:0.018293 7:0.017660622 8:0.023809524 +-1 1:0.819444 3:0.013889 7:0.018377372 8:0.023809524 +-1 1:0.685393 2:0.044944 3:0.089888 5:0.068075082 6:0.013698014 7:0.01500411 +-1 1:0.653846 2:0.038462 3:0.115385 4:0.0036900369 7:0.015009384 8:0.023809524 +-1 1:0.678571 2:0.071429 7:0.023083622 8:0.071428571 +-1 1:0.72043 2:0.075269 3:0.043011 4:0.0036900369 5:0.053054135 6:0.042705043 7:0.018423811 8:0.023809524 +-1 1:0.757042 2:0.038732 3:0.038732 5:0.030772442 6:0.018576019 7:0.020804707 8:0.023809524 +-1 1:0.704918 3:0.098361 4:0.011070111 7:0.015193921 8:0.023809524 +-1 1:0.786667 7:0.012682927 8:0.047619048 +-1 1:0.770492 7:0.010995604 8:0.023809524 +-1 1:0.75 2:0.016667 3:0.033333 7:0.014278457 8:0.071428571 +-1 1:0.768421 3:0.063158 7:0.017265726 +-1 1:0.809524 4:0.0036900369 7:0.011904762 +-1 1:0.710526 2:0.105263 4:0.018450185 6:0.1011241 7:0.014281128 +-1 1:0.763158 3:0.026316 7:0.011874195 8:0.023809524 +-1 1:0.857143 7:0.018002323 +-1 1:0.765125 7:0.012086622 8:0.047619048 +-1 1:0.605263 2:0.157895 3:0.052632 6:0.12244812 7:0.015725287 +-1 1:0.695652 3:0.086957 7:0.014713677 +-1 1:0.771739 2:0.01087 3:0.065217 4:0.0036900369 5:0.021357327 7:0.023130963 +-1 1:0.833333 3:0.083333 7:0.018292683 +-1 1:0.66129 2:0.072581 3:0.032258 6:0.072288072 7:0.016325726 +-1 1:0.693548 3:0.193548 4:0.011070111 7:0.040912665 +-1 1:0.734694 2:0.027211 3:0.068027 4:0.0073800738 5:0.029177165 6:0.0058710059 7:0.021196287 +-1 1:0.653846 2:0.019231 3:0.128205 4:0.011070111 5:0.034432633 7:0.01692464 8:0.023809524 +-1 1:0.75 7:0.017505902 8:0.047619048 +-1 1:0.746667 2:0.006667 3:0.033333 5:0.020768417 7:0.014593494 8:0.047619048 +-1 1:0.745763 3:0.056497 7:0.015261128 +-1 1:0.842105 3:0.052632 7:0.064666238 +-1 1:0.842105 3:0.052632 7:0.072368421 +-1 1:0.93617 7:0.14634146 +-1 1:0.666667 2:0.125 3:0.125 4:0.0073800738 5:0.19278995 7:0.029471543 +-1 1:0.676617 2:0.074627 3:0.042289 5:0.095925335 6:0.03033003 7:0.016502854 +-1 1:0.666667 2:0.012821 3:0.128205 4:0.0036900369 7:0.020403378 +-1 1:0.751479 2:0.005917 3:0.071006 6:0.0051720052 7:0.020926543 +-1 1:0.851064 7:0.017125067 +-1 1:0.78481 3:0.012658 7:0.012966963 +-1 1:0.605263 2:0.026316 3:0.210526 5:0.078466745 7:0.015243902 +-1 1:0.781915 7:0.01384925 8:0.047619048 +-1 1:0.8 7:0.012195122 +-1 1:0.78125 3:0.09375 4:0.0036900369 7:0.019626524 +-1 1:0.75 3:0.096154 7:0.018409945 +-1 1:0.809524 7:0.014663183 +-1 1:0.75 3:0.166667 4:0.014760148 7:0.029471543 +-1 1:0.695652 2:0.054348 3:0.076087 4:0.011070111 5:0.11927303 6:0.012000012 7:0.016569457 +-1 1:0.794521 7:0.012571 8:0.047619048 +-1 1:0.716049 2:0.012346 3:0.111111 5:0.032270809 7:0.017389341 +-1 1:0.773585 2:0.018868 3:0.056604 5:0.042595381 7:0.020133457 8:0.023809524 +-1 1:0.607843 2:0.294118 3:0.019608 6:0.13592114 7:0.036944049 +-1 1:0.73913 2:0.01087 3:0.032609 5:0.042356835 7:0.011664896 8:0.023809524 +-1 1:0.68 2:0.01 3:0.1 4:0.025830258 5:0.035670091 7:0.012743902 8:0.047619048 +-1 1:0.758621 3:0.206897 7:0.046047098 +-1 1:0.849057 7:0.025770823 8:0.023809524 +-1 1:0.76699 2:0.067961 3:0.029126 5:0.10558645 6:0.0084990085 7:0.02089747 +-1 1:0.623932 2:0.068376 3:0.08547 5:0.080330386 7:0.02418178 +-1 1:0.712575 2:0.047904 3:0.023952 5:0.13773053 7:0.015809841 8:0.047619048 +-1 1:0.842697 3:0.033708 7:0.030145244 +-1 1:0.661765 2:0.117647 6:0.077721078 7:0.017306311 +-1 1:0.954545 7:0.041851439 +-1 1:0.684211 3:0.105263 7:0.015404366 +-1 1:0.731707 2:0.121951 6:0.081081081 7:0.022010707 +-1 1:0.692308 2:0.025641 3:0.128205 7:0.01594747 +-1 1:0.654822 2:0.040609 3:0.071066 4:0.0073800738 5:0.013656762 6:0.0054960055 7:0.016899841 +-1 1:0.875 3:0.0625 7:0.024390244 +-1 1:0.765432 2:0.024691 3:0.061728 4:0.0036900369 5:0.031189898 7:0.017991567 +-1 1:0.663934 2:0.098361 3:0.057377 4:0.0073800738 6:0.050943051 7:0.026489402 +-1 1:1 7:0.11890244 +-1 1:0.840909 2:0.034091 3:0.045455 4:0.018450185 5:0.027611707 7:0.056125274 +-1 1:0.672727 2:0.054545 3:0.018182 6:0.047619048 7:0.013968957 +-1 1:0.805556 3:0.055556 7:0.017953927 +-1 1:0.709677 3:0.058065 4:0.0036900369 7:0.014712823 8:0.023809524 +-1 1:1 7:0.039634146 +-1 1:0.875 7:0.016006098 +-1 1:0.706215 2:0.00565 3:0.033898 4:0.0036900369 5:0.018822775 7:0.013642 +-1 1:0.809524 3:0.02381 7:0.018292683 +-1 1:0.669145 2:0.01487 3:0.144981 5:0.034000268 7:0.019879409 +-1 1:0.748148 2:0.022222 3:0.059259 6:0.014052014 7:0.01928636 8:0.023809524 +-1 1:0.713287 2:0.048951 3:0.048951 5:0.018181683 6:0.036585037 7:0.017482518 +-1 1:0.75 3:0.057692 7:0.020286116 8:0.047619048 +-1 1:0.807692 3:0.038462 7:0.01719825 +-1 1:0.814815 7:0.01388889 +-1 1:0.578947 2:0.052632 3:0.105263 5:0.10499754 7:0.022785622 +-1 1:0.818182 7:0.013580933 +-1 1:0.7875 7:0.021493902 8:0.023809524 +-1 1:0.821429 7:0.013066201 8:0.023809524 +-1 1:0.464789 2:0.43662 3:0.014085 5:0.0051958314 6:0.056445056 7:0.12323943 +-1 1:0.760736 2:0.047035 3:0.051125 5:0.078921474 7:0.025911518 +-1 1:0.793103 7:0.011143817 +-1 1:0.777778 3:0.074074 7:0.019308945 +-1 1:0.869565 7:0.022534463 +-1 1:0.7125 3:0.075 7:0.013109756 +-1 1:0.75 3:0.083333 7:0.015243902 8:0.023809524 +-1 1:0.647727 3:0.136364 7:0.014343128 +-1 1:0.75 2:0.0625 5:0.25705575 7:0.011051829 +-1 1:0.717949 3:0.051282 7:0.011257037 8:0.047619048 +-1 1:0.740741 2:0.037037 3:0.074074 5:0.10353645 7:0.016260165 +-1 1:0.851852 7:0.015582659 +-1 1:0.782609 3:0.043478 7:0.016967128 +-1 1:0.731707 3:0.097561 7:0.016805476 8:0.023809524 +-1 1:0.733333 3:0.133333 7:0.016260165 +-1 1:0.769231 3:0.064103 7:0.017979988 8:0.023809524 +-1 1:0.77193 3:0.052632 7:0.015618317 +-1 1:0.804348 4:0.0036900369 7:0.011930012 8:0.023809524 +-1 1:0.774194 2:0.006452 3:0.032258 5:0.019724777 7:0.014870183 8:0.095238095 +-1 1:0.664234 2:0.007299 3:0.145985 5:0.015430948 7:0.021497244 +-1 1:0.766667 3:0.033333 4:0.0036900369 7:0.015447152 8:0.071428571 +-1 1:0.8 7:0.011737805 +-1 1:0.739726 3:0.068493 7:0.013448043 +-1 1:0.722222 2:0.055556 3:0.055556 5:0.19114249 7:0.013211384 +-1 1:0.8 2:0.018182 3:0.054545 4:0.0073800738 5:0.03842828 7:0.021507762 +-1 1:0.8 7:0.012560976 +-1 1:0.776025 2:0.006309 3:0.022082 5:0.016959134 7:0.01690775 +-1 1:0.778761 3:0.017699 7:0.013598098 +-1 1:0.785714 2:0.035714 3:0.035714 5:0.096812428 7:0.016768293 +-1 1:0.925926 3:0.037037 7:0.06368564 +-1 1:0.85 7:0.014939024 +-1 1:0.78 7:0.01097561 8:0.023809524 +-1 1:0.765625 3:0.03125 7:0.018387957 +-1 1:0.755102 3:0.040816 7:0.01319064 8:0.023809524 +-1 1:0.823009 3:0.017699 7:0.017861 +-1 1:0.785714 3:0.010989 7:0.01360225 8:0.023809524 +-1 1:0.632353 2:0.132353 3:0.073529 4:0.011070111 5:0.36661548 7:0.01640961 +-1 1:0.847619 3:0.019048 7:0.022473866 +-1 1:0.743902 7:0.0099643049 +-1 1:0.742222 2:0.044444 3:0.008889 5:0.13232597 6:0.0059160059 7:0.013739835 +-1 1:0.783505 7:0.011786524 8:0.023809524 +-1 1:0.788321 2:0.021898 3:0.021898 5:0.018822775 7:0.017625067 +-1 1:0.764706 3:0.037815 7:0.01457778 8:0.071428571 +-1 1:0.774725 3:0.065934 4:0.0073800738 7:0.019833823 +-1 1:0.82774 3:0.004474 7:0.017692476 +-1 1:0.771784 3:0.010373 4:0.0036900369 7:0.014143305 8:0.047619048 +-1 1:0.800905 3:0.004525 7:0.014540335 8:0.071428571 +-1 1:0.601594 2:0.215139 3:0.023904 5:0.01334367 6:0.087708088 7:0.040715189 8:0.023809524 +-1 1:0.641667 2:0.054167 3:0.1125 4:0.022140221 5:0.035386817 6:0.014241014 7:0.016056909 +-1 1:0.730216 2:0.02518 3:0.014388 5:0.040366466 7:0.012151256 8:0.023809524 +-1 1:0.732394 2:0.042254 3:0.042254 6:0.03030303 7:0.017004463 8:0.047619048 +-1 1:0.717391 3:0.032609 7:0.012128841 8:0.071428571 +-1 1:0.773585 3:0.018868 7:0.013499 8:0.095238095 +-1 1:0.743478 2:0.002174 3:0.043478 4:0.0036900369 7:0.015005305 8:0.047619048 +-1 1:0.633027 2:0.110092 3:0.100917 4:0.029520295 5:0.021543691 6:0.086706087 7:0.019355561 +-1 1:0.75 2:0.064286 3:0.028571 6:0.055944056 7:0.018684671 +-1 1:0.791667 7:0.01388889 8:0.023809524 +-1 1:0.659341 2:0.076923 3:0.076923 4:0.0073800738 5:0.18952485 7:0.015813457 +-1 1:0.777778 3:0.037037 7:0.014829872 +-1 1:0.724138 2:0.011494 3:0.103448 5:0.029579712 7:0.017661902 +-1 1:0.643836 2:0.027397 3:0.150685 4:0.0073800738 5:0.040291921 7:0.015452726 +-1 1:0.75 2:0.02551 3:0.035714 4:0.0036900369 5:0.067769445 7:0.017110506 +-1 1:0.702811 2:0.076305 3:0.016064 6:0.072789073 7:0.014129689 8:0.047619048 +-1 1:0.753731 3:0.052239 7:0.015607933 +-1 1:0.641026 2:0.076923 3:0.076923 5:0.093182055 7:0.012507817 +-1 1:0.723577 3:0.097561 4:0.011070111 7:0.01893714 8:0.047619048 +-1 1:0.772727 3:0.025974 7:0.014768768 8:0.095238095 +-1 1:0.764045 3:0.033708 7:0.014867085 8:0.047619048 +-1 1:0.833333 7:0.017073171 8:0.023809524 +-1 1:0.645695 2:0.119205 3:0.05298 5:0.087084222 6:0.073599074 7:0.017283152 +-1 1:0.785 3:0.02 4:0.0036900369 7:0.015213415 8:0.095238095 +-1 1:0.795455 3:0.022727 7:0.013580933 8:0.023809524 +-1 1:0.645833 3:0.166667 7:0.013846543 +-1 1:0.818965 3:0.008621 7:0.016742012 +-1 1:0.76 7:0.011707317 +-1 1:0.778524 2:0.013423 3:0.040268 5:0.032911902 7:0.01853822 8:0.023809524 +-1 1:0.596899 2:0.139535 3:0.077519 5:0.073628733 6:0.066666067 7:0.019143506 +-1 1:0.810127 7:0.014665018 8:0.047619048 +-1 1:0.813187 7:0.01360225 +-1 1:0.736842 3:0.105263 7:0.020432177 +-1 1:0.807339 3:0.009174 7:0.015495634 +-1 1:0.75 3:0.1 7:0.01402439 +-1 1:0.647059 3:0.117647 7:0.011477762 +-1 1:0.782609 3:0.012422 7:0.014921982 8:0.11904762 +-1 1:0.710059 2:0.047337 3:0.04142 6:0.043689044 7:0.014865061 8:0.023809524 +-1 1:0.606061 2:0.151515 3:0.090909 5:0.065972895 6:0.07964708 7:0.020879524 +-1 1:0.653563 2:0.130221 3:0.034398 5:0.040135375 6:0.064602065 7:0.022262841 +-1 1:0.757576 2:0.015152 3:0.030303 5:0.054813412 7:0.012564671 +-1 1:0.823529 7:0.01699247 +-1 1:0.694915 2:0.101695 3:0.028249 6:0.093168093 7:0.01663911 +-1 1:0.709677 3:0.053763 7:0.019931811 8:0.023809524 +-1 1:0.65 3:0.025 7:0.014430896 +-1 1:0.714286 2:0.071429 3:0.089286 4:0.0036900369 6:0.03999904 7:0.024499128 +-1 1:0.738372 3:0.075581 4:0.036900369 7:0.01744186 8:0.047619048 +-1 1:0.764706 2:0.029412 3:0.117647 4:0.036900369 7:0.031922524 +-1 1:0.755556 3:0.044444 7:0.013143628 +-1 1:0.75419 2:0.005587 3:0.027933 5:0.016824952 7:0.01509061 +-1 1:0.714286 3:0.107143 7:0.015461671 +-1 1:0.625 2:0.15 3:0.05 5:0.33131066 6:0.033333033 7:0.013719512 8:0.023809524 +-1 1:0.717172 2:0.080808 3:0.020202 5:0.12424523 6:0.037500038 7:0.014781963 +-1 1:0.666667 2:0.021505 3:0.107527 4:0.022140221 5:0.059636515 7:0.016391293 +-1 1:0.822581 2:0.016129 3:0.016129 5:0.037459186 7:0.019571201 +-1 1:0.616438 2:0.150685 3:0.082192 4:0.0073800738 5:0.11468847 6:0.057693058 7:0.021717341 +-1 1:0.679245 2:0.037736 3:0.056604 4:0.0073800738 6:0.025209025 7:0.01369075 +-1 1:0.769231 7:0.010318951 +-1 1:0.784615 3:0.092308 7:0.030769232 +-1 1:0.518519 2:0.240741 3:0.055556 5:0.13232597 6:0.12426012 7:0.01908311 +-1 1:0.857143 7:0.017131244 +-1 1:0.673077 2:0.00641 3:0.147436 4:0.025830258 5:0.013380943 7:0.021771421 +-1 1:0.623853 2:0.036697 3:0.183486 4:0.025830258 5:0.031391171 7:0.026571939 +-1 1:0.565217 2:0.173913 3:0.101449 4:0.0036900369 5:0.11647757 6:0.093750094 7:0.016967128 +-1 1:0.704545 3:0.113636 4:0.0036900369 7:0.014966738 8:0.023809524 +-1 1:0.745536 2:0.008929 3:0.040179 5:0.026910978 7:0.015080573 8:0.071428571 +-1 1:0.75 3:0.083333 7:0.016006098 +-1 1:0.801724 2:0.008621 3:0.008621 7:0.017241378 8:0.023809524 +-1 1:0.723684 3:0.131579 4:0.014760148 7:0.020619384 +-1 1:0.643478 2:0.095652 3:0.043478 6:0.091524092 7:0.015641567 +-1 1:0.764045 2:0.005618 3:0.044944 5:0.016564042 7:0.015415183 +-1 1:0.677165 2:0.031496 3:0.086614 4:0.0036900369 6:0.025938026 7:0.016660262 +-1 1:0.617647 2:0.058824 3:0.102941 5:0.17749318 7:0.011298421 +-1 1:0.76087 2:0.007246 3:0.057971 7:0.016878756 +-1 1:0.757282 3:0.058252 7:0.019003079 8:0.023809524 +-1 1:0.77512 2:0.019139 3:0.014354 6:0.017646018 7:0.014879213 8:0.071428571 +-1 1:0.807692 7:0.011726079 8:0.023809524 +-1 1:0.746667 2:0.033333 3:0.013333 5:0.022058056 7:0.013739835 +-1 1:0.741935 3:0.064516 7:0.013375293 +-1 1:0.689655 2:0.034483 3:0.068966 5:0.13553889 7:0.011564341 +-1 1:0.746412 2:0.038278 3:0.057416 4:0.0036900369 5:0.028118617 6:0.011316011 7:0.027074335 +-1 1:0.72 2:0.04 3:0.12 5:0.077654198 7:0.023414634 +-1 1:0.73494 2:0.012048 3:0.072289 7:0.015574494 +-1 1:0.767196 7:0.012485482 8:0.023809524 +-1 1:0.631068 2:0.145631 3:0.019417 5:0.057564147 6:0.1042471 7:0.015332701 +-1 1:0.777778 3:0.166667 7:0.037601628 +-1 1:0.714286 3:0.095238 7:0.016405341 8:0.023809524 +-1 1:0.833333 7:0.015243902 +-1 1:0.721311 2:0.008197 3:0.02459 7:0.011995201 +-1 1:0.759184 3:0.097959 7:0.024315579 +-1 1:0.654545 2:0.045455 3:0.109091 4:0.0073800738 5:0.11210174 7:0.014745012 8:0.023809524 +-1 1:0.581081 2:0.148649 3:0.162162 4:0.0036900369 5:0.078265472 7:0.031394201 +-1 1:0.789062 2:0.007812 3:0.054688 5:0.015863313 7:0.022389482 +-1 1:0.725806 3:0.080645 7:0.013965384 +-1 1:0.772727 3:0.090909 7:0.021202884 +-1 1:0.719008 3:0.07438 7:0.014765171 8:0.023809524 +-1 1:0.84375 7:0.016958841 +-1 1:0.857143 7:0.013501744 +-1 1:0.789116 3:0.020408 7:0.014663183 +-1 1:0.795455 3:0.022727 7:0.01302661 +-1 1:0.708333 3:0.097222 7:0.017699866 +-1 1:0.674074 2:0.081481 3:0.037037 6:0.076434076 7:0.014182476 +-1 1:0.736559 2:0.021505 3:0.075269 4:0.011070111 6:0.014730015 7:0.020030159 +-1 1:0.649123 2:0.017544 3:0.087719 4:0.0036900369 7:0.012302098 +-1 1:0.875 4:0.025830258 7:0.020579268 +-1 1:0.846154 7:0.012195122 +-1 1:0.647059 3:0.058824 7:0.01649928 +-1 1:0.6875 7:0.016768293 +-1 1:0.682927 3:0.170732 4:0.0073800738 7:0.020374774 +-1 1:0.620155 2:0.147287 3:0.03876 5:0.098407705 6:0.10891211 7:0.014322177 +-1 1:0.811594 7:0.014316012 8:0.023809524 +-1 1:0.741259 3:0.027972 4:0.036900369 7:0.017908921 8:0.071428571 +-1 1:0.710526 3:0.052632 7:0.016527598 +-1 1:0.725806 3:0.032258 7:0.01455547 8:0.047619048 +-1 1:0.747706 2:0.022936 3:0.027523 5:0.071817274 7:0.014516671 8:0.023809524 +-1 1:0.820513 3:0.179487 7:0.12195122 +-1 1:0.785714 7:0.015156793 +-1 1:0.666667 3:0.148148 7:0.01377597 +-1 1:0.705882 2:0.058824 3:0.029412 4:0.0036900369 6:0.030612031 7:0.017575323 +-1 1:0.719101 2:0.02809 3:0.044944 5:0.078056744 7:0.013085774 +-1 1:0.724638 2:0.028986 3:0.043478 5:0.039032099 7:0.016878756 +-1 1:0.712121 3:0.106061 7:0.015428677 +-1 1:0.726027 2:0.013699 3:0.031963 7:0.012055909 8:0.095238095 +-1 1:0.833333 7:0.011686994 +-1 1:0.74359 2:0.064103 6:0.066666067 7:0.014071293 +-1 1:0.800614 3:0.033742 7:0.020050878 8:0.047619048 +-1 1:0.755556 3:0.088889 7:0.017208671 +-1 1:0.78 2:0.02 3:0.05 5:0.04141756 7:0.02195122 +-1 1:0.734375 7:0.013910061 +-1 1:0.65625 2:0.078125 3:0.078125 5:0.14909129 6:0.02000102 7:0.014291159 +-1 1:0.733333 2:0.033333 3:0.133333 4:0.0036900369 7:0.033333335 +-1 1:0.8 3:0.008163 7:0.016102537 +-1 1:0.692308 2:0.082051 3:0.046154 4:0.0073800738 5:0.039934102 6:0.064287064 7:0.017510945 +-1 1:0.746835 2:0.012658 3:0.012658 7:0.011191726 +-1 1:0.704797 2:0.02583 3:0.0369 4:0.0036900369 5:0.037146095 7:0.013545134 8:0.095238095 +-1 1:0.714286 3:0.035714 7:0.011977354 +-1 1:0.705882 2:0.039216 7:0.013151604 +-1 1:0.80226 2:0.00565 3:0.00565 5:0.016549133 7:0.0155195 +-1 1:0.727273 2:0.045455 3:0.045455 5:0.1461691 7:0.014135256 +-1 1:0.778116 3:0.036474 4:0.014760148 7:0.017495738 8:0.023809524 +-1 1:0.795789 2:0.033684 3:0.027368 5:0.035893728 6:0.0048150048 7:0.023992299 +-1 1:0.789474 7:0.010911427 +-1 1:0.740741 3:0.074074 7:0.012420957 8:0.023809524 +-1 1:0.702564 2:0.035897 3:0.025641 4:0.018450185 5:0.05605087 6:0.015039015 7:0.012476549 8:0.095238095 +-1 1:0.733333 3:0.066667 7:0.014532518 8:0.047619048 +-1 1:0.709677 3:0.064516 7:0.014358774 8:0.023809524 +-1 1:0.717949 2:0.051282 3:0.076923 5:0.13431634 7:0.017354598 +-1 1:0.892857 7:0.023301396 +-1 1:0.612426 2:0.174556 3:0.050296 5:0.037086458 6:0.12238812 7:0.018130323 +-1 1:0.828125 3:0.015625 7:0.016387195 +-1 1:0.75 3:0.038043 7:0.013321848 8:0.047619048 +-1 1:0.785714 7:0.0108885 +-1 1:0.776632 2:0.006873 3:0.065292 4:0.077490775 5:0.012687669 7:0.024620738 +-1 1:0.75641 2:0.016026 3:0.041667 5:0.025703338 7:0.017002811 +-1 1:0.782805 3:0.031674 7:0.015671561 +-1 1:0.766667 2:0.016667 3:0.033333 5:0.054813412 7:0.01382114 +-1 1:0.735294 3:0.044118 7:0.012464134 8:0.023809524 +-1 1:0.757396 2:0.017751 3:0.04142 5:0.046784846 7:0.017246354 8:0.095238095 +-1 1:0.737991 3:0.09607 4:0.0036900369 7:0.017680262 +-1 1:0.774648 3:0.042254 7:0.013912744 +-1 1:0.738636 3:0.051136 4:0.0036900369 7:0.016317902 +-1 1:0.721519 2:0.012658 3:0.088608 5:0.034194087 7:0.016826183 +-1 1:0.75 3:0.090909 7:0.01759978 +-1 1:0.549296 2:0.28169 3:0.070423 5:0.026717159 6:0.096774097 7:0.047921677 +-1 1:0.787234 3:0.021277 7:0.015568238 +-1 1:0.709924 3:0.061069 4:0.011070111 7:0.012707128 8:0.071428571 +-1 1:0.777778 3:0.020833 7:0.014820463 8:0.023809524 +-1 1:0.776471 3:0.011765 7:0.012625537 +-1 1:0.8 2:0.022222 3:0.022222 5:0.059636515 7:0.016937671 +-1 1:0.770492 3:0.016393 7:0.015393841 +-1 1:0.745283 3:0.028302 7:0.013920848 8:0.047619048 +-1 1:0.709677 3:0.096774 7:0.013178598 +-1 1:0.714286 3:0.122449 7:0.016052762 8:0.023809524 +-1 1:0.692308 3:0.115385 4:0.011070111 7:0.013133207 +-1 1:0.758621 3:0.068966 7:0.013666945 +-1 1:0.830986 3:0.042254 7:0.027567848 +-1 1:0.815789 3:0.026316 7:0.019897305 +-1 1:0.787879 3:0.020202 4:0.0036900369 7:0.013488543 8:0.023809524 +-1 1:0.795918 2:0.020408 3:0.040816 5:0.04937158 7:0.018790445 +-1 1:0.514286 2:0.257143 3:0.057143 5:0.14065272 6:0.16981217 7:0.018466896 +-1 1:0.671329 2:0.055944 3:0.048951 5:0.023153877 6:0.027951028 7:0.013730171 +-1 1:0.631579 2:0.105263 3:0.092105 6:0.088671089 7:0.016286909 +-1 1:0.742857 2:0.057143 3:0.028571 4:0.0036900369 6:0.054216054 7:0.014459927 +-1 1:0.741935 3:0.064516 4:0.011070111 7:0.015145555 8:0.047619048 +-1 1:0.744681 3:0.092199 7:0.018595396 8:0.023809524 +-1 1:0.776471 3:0.029412 7:0.017754665 +-1 1:0.755556 2:0.008889 3:0.053333 5:0.024085698 7:0.016775067 +-1 1:0.657534 2:0.068493 3:0.123288 5:0.12071922 7:0.020631476 +-1 1:0.77551 7:0.012817323 +-1 1:0.666667 2:0.049383 3:0.074074 5:0.068179446 7:0.02469136 8:0.071428571 +-1 1:0.62 2:0.04 3:0.18 4:0.0036900369 5:0.068179446 7:0.02 +-1 1:0.773723 3:0.036496 7:0.014910098 8:0.071428571 +-1 1:0.762238 2:0.020979 3:0.020979 6:0.016215016 7:0.015776909 +-1 1:0.768229 3:0.018229 7:0.014989835 +-1 1:0.684478 2:0.050891 3:0.071247 4:0.0036900369 5:0.060359608 6:0.021255021 7:0.015329238 8:0.023809524 +-1 1:0.75 3:0.05 7:0.014329268 +-1 1:0.806452 3:0.021505 7:0.016325726 +-1 1:0.683761 3:0.102564 7:0.015791122 8:0.023809524 +-1 1:0.770492 7:0.01089564 +-1 1:0.710914 2:0.103245 3:0.020649 5:0.078951292 6:0.034422034 7:0.020379165 +-1 1:0.686275 3:0.156863 4:0.011070111 7:0.019368726 +-1 1:0.755102 7:0.014559482 8:0.047619048 +-1 1:0.759615 2:0.019231 3:0.028846 5:0.026344431 6:0.010602011 7:0.016592402 +-1 1:0.770161 2:0.032258 3:0.030242 5:0.067724718 6:0.0019470019 7:0.018944238 +-1 1:0.75 2:0.017857 5:0.048409941 7:0.016768293 +-1 1:0.768908 3:0.021008 7:0.013476122 +-1 1:0.781513 3:0.016807 7:0.013988524 8:0.047619048 +-1 1:0.784483 3:0.034483 4:0.025830258 7:0.016032378 +-1 1:0.83871 7:0.019472854 +-1 1:0.606383 2:0.06383 3:0.095745 6:0.047619048 7:0.016346652 +-1 1:0.61039 2:0.051948 3:0.064935 5:0.11647757 7:0.015204305 8:0.023809524 +-1 1:0.765957 3:0.06383 7:0.015438506 +-1 1:0.748344 2:0.013245 3:0.013245 5:0.022728967 7:0.01324503 8:0.023809524 +-1 1:0.772727 3:0.060606 7:0.018754622 +-1 1:0.717391 3:0.065217 7:0.010471896 +-1 1:0.659091 2:0.045455 3:0.136364 4:0.011070111 5:0.12528886 7:0.016491128 +-1 1:0.653846 2:0.038462 3:0.076923 5:0.14909129 7:0.011726079 8:0.023809524 +-1 1:0.594286 2:0.194286 3:0.028571 4:0.0036900369 5:0.12742832 6:0.12820513 7:0.016306622 8:0.023809524 +-1 1:0.777778 7:0.012872628 8:0.047619048 +-1 1:0.780051 2:0.012788 3:0.02046 5:0.03089917 7:0.01504897 +-1 1:0.825758 7:0.015567256 8:0.023809524 +-1 1:0.588235 2:0.098039 3:0.078431 5:0.05647578 6:0.045456045 7:0.015781921 +-1 1:0.692308 7:0.020168854 +-1 1:0.777778 3:0.166667 7:0.031504067 +-1 1:0.720588 2:0.014706 3:0.044118 7:0.013271165 8:0.023809524 +-1 1:0.650746 2:0.020896 3:0.032836 5:0.024279516 7:0.022351659 +-1 1:0.755102 3:0.05102 7:0.016052762 +-1 1:0.833333 7:0.012195122 +-1 1:0.75 3:0.075 4:0.0073800738 7:0.026676829 +-1 1:0.728682 2:0.015504 3:0.100775 4:0.022140221 5:0.013574762 7:0.025950085 +-1 1:0.774359 2:0.010256 3:0.030769 5:0.027402979 7:0.017010634 8:0.023809524 +-1 1:0.758242 3:0.021978 7:0.012731171 8:0.095238095 +-1 1:0.787234 2:0.014184 3:0.021277 5:0.042595381 7:0.015135793 +-1 1:0.657895 2:0.131579 3:0.052632 5:0.31857081 7:0.018774067 +-1 1:0.73183 2:0.032581 3:0.055138 5:0.074172916 6:0.014925015 7:0.01843022 +-1 1:0.707317 2:0.02439 3:0.02439 7:0.011302799 8:0.047619048 +-1 1:0.644444 2:0.022222 3:0.055556 5:0.022728967 7:0.02222222 +-1 1:0.703704 2:0.018519 3:0.111111 4:0.0073800738 7:0.023035232 +-1 1:0.709677 2:0.003584 3:0.078853 4:0.0036900369 7:0.014424335 8:0.023809524 +-1 1:0.663551 2:0.009346 3:0.121495 5:0.028558436 7:0.014873488 +-1 1:0.716667 3:0.083333 7:0.017479677 8:0.023809524 +-1 1:0.734375 3:0.0625 7:0.01324314 8:0.047619048 +-1 1:0.696429 2:0.071429 3:0.071429 5:0.1339138 7:0.018183799 +-1 1:0.725806 2:0.016129 3:0.129032 4:0.025830258 5:0.026717159 7:0.027439024 8:0.023809524 +-1 1:0.615385 7:0.019699811 +-1 1:0.35 2:0.325 3:0.05 5:0.41414578 6:0.16666817 7:0.013719512 +-1 1:0.840909 7:0.015659646 +-1 1:0.726141 2:0.016598 3:0.041494 6:0.015900016 7:0.014320415 8:0.047619048 +-1 1:0.823529 3:0.078431 4:0.0036900369 7:0.026303201 +-1 1:0.863636 3:0.045455 4:0.0036900369 7:0.021895787 +-1 1:0.716763 2:0.069364 3:0.040462 6:0.056841057 7:0.01674186 +-1 1:0.765432 2:0.037037 3:0.049383 5:0.014760038 7:0.038015659 +-1 1:1 7:0.10670732 +-1 1:0.883117 3:0.025974 7:0.074516945 +-1 1:0.94898 7:0.12885763 +-1 1:1 7:0.13719512 +-1 1:0.724551 2:0.056886 3:0.035928 5:0.011375665 6:0.0071940072 7:0.083759305 +-1 1:0.721557 2:0.05988 3:0.035928 5:0.012993306 6:0.0078420078 7:0.083814079 +-1 1:0.939394 7:0.058388768 +-1 1:0.826389 3:0.006944 7:0.022400067 +-1 1:0.638655 2:0.084034 3:0.134454 4:0.025830258 5:0.032837356 6:0.0044040044 7:0.034894445 +-1 1:0.826087 2:0.043478 5:0.022453148 7:0.044008482 +-1 1:0.894737 7:0.027599488 +-1 1:0.846154 7:0.018895738 +-1 1:0.807692 3:0.038462 7:0.019934335 8:0.047619048 +-1 1:0.75 2:0.039062 3:0.054688 5:0.051175585 6:0.0068640069 7:0.020817451 +-1 1:0.77193 2:0.017544 3:0.105263 4:0.0073800738 6:0.01003201 7:0.031985451 +-1 1:0.733333 2:0.011111 3:0.1 4:0.0036900369 7:0.018631439 +-1 1:0.673077 2:0.096154 3:0.096154 6:0.059406059 7:0.023686677 +-1 1:0.782609 3:0.086957 7:0.017762457 8:0.023809524 +-1 1:0.703704 2:0.074074 3:0.018519 6:0.081819082 7:0.012420957 +-1 1:0.735294 3:0.088235 7:0.014526543 8:0.023809524 +-1 1:0.703704 2:0.022222 3:0.096296 4:0.011070111 5:0.04372102 7:0.015401988 +-1 1:0.714286 3:0.107143 4:0.0036900369 7:0.013501744 +-1 1:0.783333 3:0.016667 7:0.012398372 +-1 1:0.743243 3:0.054054 4:0.011070111 7:0.01384311 8:0.023809524 +-1 1:0.663636 3:0.154545 4:0.011070111 7:0.016740579 +-1 1:0.717262 2:0.014881 3:0.077381 4:0.011070111 5:0.035878819 7:0.015080573 +-1 1:0.75 3:0.06 4:0.033210332 7:0.019146341 8:0.023809524 +-1 1:0.742857 3:0.1 7:0.025958189 8:0.023809524 +-1 1:0.925926 3:0.037037 7:0.11404697 +-1 1:0.742268 2:0.010309 3:0.020619 5:0.031584989 7:0.014835305 8:0.023809524 +-1 1:0.833333 7:0.013414634 +-1 1:0.752941 3:0.070588 4:0.011070111 7:0.016068866 +-1 1:0.744444 3:0.011111 7:0.013211384 +-1 1:0.632911 3:0.050633 7:0.013584439 +-1 1:0.708861 2:0.012658 3:0.126582 4:0.0036900369 5:0.023817333 7:0.024158689 +-1 1:0.597938 2:0.164948 3:0.14433 5:0.12634741 7:0.033379433 +-1 1:0.654867 2:0.00885 3:0.079646 7:0.014839195 8:0.047619048 +-1 1:0.597403 2:0.103896 3:0.12987 4:0.0073800738 5:0.066263623 6:0.03999904 7:0.017817549 +-1 1:0.75 3:0.083333 7:0.01422764 +-1 1:0.730769 3:0.096154 7:0.014892122 +-1 1:0.716667 3:0.15 7:0.026626018 8:0.023809524 +-1 1:0.742268 2:0.048969 3:0.025773 4:0.0036900369 6:0.033519034 7:0.016878299 +-1 1:0.690141 2:0.035211 3:0.042254 4:0.0073800738 5:0.04809685 6:0.019356019 7:0.013311579 8:0.095238095 +-1 1:0.763636 3:0.072727 7:0.015853659 +-1 1:0.78125 3:0.023438 7:0.013576598 8:0.023809524 +-1 1:0.753247 2:0.025974 3:0.012987 5:0.096186245 7:0.012274311 8:0.023809524 +-1 1:0.785714 7:0.010017421 8:0.023809524 +-1 1:0.722892 2:0.048193 3:0.072289 5:0.030183531 7:0.018145756 +-1 1:0.725 3:0.060714 7:0.013087982 8:0.071428571 +-1 1:0.784314 7:0.013988524 +-1 1:0.6 3:0.1 7:0.016463415 +-1 1:0.625 2:0.125 3:0.046875 5:0.054410866 6:0.087591088 7:0.013052591 +-1 1:0.8 3:0.075 7:0.029573171 8:0.023809524 +-1 1:0.701754 3:0.105263 4:0.0073800738 7:0.015832262 8:0.023809524 +-1 1:0.85 7:0.016768293 8:0.023809524 +-1 1:0.672727 3:0.054545 4:0.0073800738 7:0.014634146 +-1 1:0.707965 2:0.035398 3:0.079646 5:0.099063707 7:0.016242177 +-1 1:0.707317 3:0.109756 4:0.011070111 7:0.016284951 +-1 1:0.66 2:0.08 3:0.06 4:0.0073800738 5:0.065108166 6:0.039300039 7:0.013963415 +-1 1:0.737705 2:0.065574 3:0.016393 5:0.04141756 6:0.033333033 7:0.017992805 8:0.023809524 +-1 1:0.75 3:0.026316 4:0.0036900369 7:0.012355585 +-1 1:0.706667 2:0.08 3:0.04 6:0.077319077 7:0.01577236 +-1 1:0.759494 3:0.063291 7:0.0182155 +-1 1:0.606061 4:0.0036900369 7:0.015151512 +-1 1:0.695187 2:0.069519 3:0.064171 4:0.0073800738 5:0.090908413 6:0.036585037 7:0.018716579 8:0.023809524 +-1 1:0.830769 7:0.015478421 +-1 1:0.833333 7:0.017911585 +-1 1:0.746575 2:0.006849 3:0.047945 4:0.0036900369 7:0.014199799 +-1 1:0.630435 2:0.070652 3:0.092391 5:0.036363365 6:0.029268029 7:0.013586957 +-1 1:0.7 2:0.00625 3:0.06875 7:0.013071646 8:0.047619048 +-1 1:0.906977 7:0.039563244 +-1 1:0.948276 7:0.17987805 +-1 1:0.774775 3:0.036036 4:0.0073800738 7:0.014612171 8:0.023809524 +-1 1:0.786517 3:0.033708 7:0.01562072 +-1 1:0.745283 2:0.028302 3:0.028302 6:0.023904024 7:0.014438561 +-1 1:0.714286 3:0.085714 4:0.0036900369 7:0.012891988 8:0.023809524 +-1 1:0.555556 2:0.333333 5:0.030056804 6:0.14516115 7:0.033604335 +-1 1:0.75 3:0.083333 7:0.01388889 +-1 1:0.72973 2:0.018018 3:0.063063 4:0.0073800738 5:0.028454072 7:0.014392439 +-1 1:0.647059 3:0.176471 7:0.011836439 +-1 1:0.707692 3:0.107692 4:0.014760148 7:0.020168854 8:0.047619048 +-1 1:0.669856 2:0.07177 3:0.100478 5:0.054149956 6:0.021792022 7:0.024098494 +-1 1:0.755319 3:0.031915 7:0.013881683 8:0.023809524 +-1 1:0.689189 3:0.081081 4:0.0036900369 7:0.012030323 +-1 1:0.732558 2:0.034884 3:0.046512 5:0.074918373 7:0.01410947 8:0.023809524 +-1 1:0.743363 3:0.044248 7:0.012572848 8:0.071428571 +-1 1:0.82 3:0.02 7:0.016585366 +-1 1:0.733333 3:0.133333 7:0.017479677 +-1 1:0.783019 7:0.012252646 +-1 1:0.636364 3:0.136364 7:0.015798226 +-1 1:0.632653 2:0.071429 3:0.122449 4:0.0036900369 6:0.029220029 7:0.019163762 +-1 1:0.746479 2:0.021127 3:0.042254 6:0.017094017 7:0.01507214 8:0.071428571 +-1 1:0.73913 2:0.086957 6:0.061224061 7:0.012990457 +-1 1:0.784946 3:0.032258 7:0.015473378 +-1 1:0.7 3:0.15 7:0.021112805 +-1 1:0.739645 3:0.047337 4:0.0036900369 7:0.015370183 8:0.023809524 +-1 1:0.818182 3:0.045455 4:0.0036900369 7:0.021341463 8:0.023809524 +-1 1:0.702381 2:0.020833 3:0.095238 5:0.025211337 6:0.0067650068 7:0.016096835 +-1 1:0.75 3:0.052083 7:0.01410061 8:0.023809524 +-1 1:0.75641 2:0.051282 5:0.037459186 6:0.045225045 7:0.015556598 8:0.023809524 +-1 1:0.763158 2:0.026316 3:0.026316 7:0.014922976 8:0.047619048 +-1 1:0.77381 7:0.011832171 8:0.095238095 +-1 1:0.756098 3:0.04878 7:0.013236171 8:0.047619048 +-1 1:0.75 3:0.118421 4:0.018450185 7:0.028642494 +-1 1:0.611111 3:0.055556 7:0.02201897 +-1 1:0.632653 2:0.142857 3:0.030612 5:0.17108971 6:0.059016059 7:0.018977104 +-1 1:0.78125 3:0.015625 7:0.013052591 +-1 1:0.688073 2:0.009174 3:0.137615 4:0.0036900369 7:0.022376372 +-1 1:0.777778 3:0.037037 7:0.026874433 +-1 1:0.614035 2:0.115789 3:0.101754 4:0.018450185 5:0.074992918 6:0.06036306 7:0.021266579 +-1 1:0.794872 2:0.012821 3:0.051282 5:0.026247521 6:0.010563011 7:0.022201378 +-1 1:0.776471 3:0.023529 7:0.014347201 8:0.023809524 +-1 1:0.7875 2:0.0125 3:0.025 5:0.037086458 7:0.015320122 8:0.023809524 +-1 1:0.784884 2:0.011628 3:0.052326 4:0.0036900369 5:0.023258241 7:0.022724049 +-1 1:0.69697 2:0.030303 3:0.121212 5:0.085682764 7:0.01607539 +-1 1:0.740741 2:0.055556 3:0.055556 6:0.035295035 7:0.019196024 +-1 1:0.756667 3:0.086667 4:0.0073800738 7:0.022276421 +-1 1:0.447368 2:0.210526 3:0.157895 4:0.0073800738 5:0.56109761 7:0.014922976 +-1 1:0.785714 3:0.071429 7:0.019744482 8:0.023809524 +-1 1:0.730769 3:0.134615 4:0.0073800738 7:0.021224201 +-1 1:0.823529 3:0.011765 7:0.017144909 +-1 1:0.717391 3:0.108696 4:0.011070111 7:0.014050902 +-1 1:0.792208 3:0.038961 7:0.017104848 +-1 1:0.76 7:0.012317073 8:0.023809524 +-1 1:0.693182 2:0.049242 3:0.079545 4:0.011070111 5:0.098474796 6:0.0079260079 7:0.017484293 +-1 1:0.833333 3:0.083333 7:0.021341463 +-1 1:0.689655 3:0.137931 7:0.013666945 +-1 1:0.477273 2:0.227273 3:0.136364 5:0.41745561 6:0.048000048 7:0.017322616 +-1 1:0.823529 7:0.012912482 8:0.023809524 +-1 1:0.762887 7:0.01030928 +-1 1:0.534884 2:0.186047 3:0.116279 4:0.014760148 5:0.12964233 6:0.1043491 7:0.016307433 +-1 1:0.620253 2:0.101266 3:0.088608 6:0.046512047 7:0.029870329 +-1 1:0.795455 3:0.045455 4:0.0036900369 7:0.021341463 +-1 1:0.736842 2:0.026316 3:0.052632 7:0.01588575 +-1 1:0.678571 2:0.107143 3:0.071429 6:0.067416067 7:0.01938153 +-1 1:0.69697 3:0.090909 4:0.0036900369 7:0.017245628 8:0.047619048 +-1 1:0.64 2:0.06 3:0.12 4:0.0036900369 6:0.042255042 7:0.017317073 +-1 1:0.689655 2:0.206897 6:0.16666817 7:0.022708159 +-1 1:0.760331 7:0.010431366 +-1 1:0.803109 7:0.015322884 8:0.023809524 +-1 1:0.803109 7:0.015702012 8:0.047619048 +-1 1:0.684211 7:0.013157896 +-1 1:0.772727 7:0.0094235061 +-1 1:0.747826 2:0.008696 3:0.017391 5:0.029698985 7:0.013308591 8:0.023809524 +-1 1:0.788462 7:0.012546902 8:0.047619048 +-1 1:0.771084 3:0.024096 4:0.0036900369 7:0.013076695 +-1 1:0.761905 7:0.01393728 8:0.095238095 +-1 1:0.735714 3:0.071429 4:0.011070111 7:0.017900695 8:0.023809524 +-1 1:0.585366 2:0.121951 3:0.109756 4:0.0073800738 5:0.10258226 6:0.055047055 7:0.016210591 +-1 1:0.602041 2:0.153061 3:0.071429 5:0.08804586 6:0.094488094 7:0.015803884 +-1 1:0.744186 3:0.031008 7:0.014747591 8:0.023809524 +-1 1:0.816327 7:0.015306122 8:0.047619048 +-1 1:0.580645 2:0.129032 3:0.096774 5:0.081918209 6:0.065934066 7:0.017899293 +-1 1:0.828571 7:0.016550524 8:0.023809524 +-1 1:0.857143 7:0.019163762 8:0.047619048 +-1 1:0.740741 3:0.111111 4:0.0036900369 7:0.015582659 +-1 1:0.700935 2:0.037383 3:0.11215 4:0.011070111 5:0.021923874 6:0.017646018 7:0.019375427 +-1 1:0.742857 3:0.085714 7:0.014459927 8:0.023809524 +-1 1:0.623529 2:0.117647 3:0.082353 5:0.033426267 6:0.080718081 7:0.015997128 +-1 1:0.68932 2:0.038835 3:0.097087 4:0.025830258 6:0.031470031 7:0.016931091 +-1 1:0.797297 3:0.013514 7:0.014914305 8:0.023809524 +-1 1:0.765432 3:0.098765 7:0.027250829 8:0.023809524 +-1 1:0.611111 3:0.111111 7:0.017953927 +-1 1:0.741935 2:0.032258 3:0.096774 4:0.0036900369 5:0.070997272 7:0.02065303 +-1 1:0.722222 7:0.010162604 8:0.047619048 +-1 1:0.815789 7:0.014521823 8:0.023809524 +-1 1:0.745833 2:0.029167 3:0.020833 4:0.0036900369 5:0.036967185 6:0.0099180099 7:0.015370933 8:0.047619048 +-1 1:0.840909 2:0.068182 4:0.0036900369 5:0.056259598 6:0.011322011 7:0.036723945 +-1 1:0.789474 3:0.052632 7:0.016206677 8:0.023809524 +-1 1:0.804878 4:0.0036900369 7:0.016954195 +-1 1:0.808511 3:0.021277 7:0.015568238 +-1 1:0.72093 3:0.046512 7:0.013329555 +-1 1:0.741573 3:0.078652 7:0.01705947 +-1 1:0.938776 3:0.061224 4:0.0073800738 7:0.15243902 +-1 1:0.642857 3:0.095238 4:0.0036900369 7:0.012775841 +-1 1:0.774648 7:0.010906902 8:0.047619048 +-1 1:0.742268 3:0.113402 4:0.036900369 7:0.04016847 +-1 1:0.724638 3:0.043478 7:0.024478616 +-1 1:0.640625 2:0.101562 3:0.054688 5:0.021424418 6:0.051723052 7:0.016577744 +-1 1:0.6875 2:0.125 3:0.0625 6:0.065217065 7:0.017530488 +-1 1:0.675 2:0.0625 3:0.1 4:0.014760148 5:0.017704591 6:0.014253014 7:0.032088415 8:0.023809524 +-1 1:0.782313 2:0.020408 3:0.013605 5:0.020649143 6:0.0083100083 7:0.01497428 +-1 1:0.5 2:0.166667 3:0.222222 4:0.0036900369 5:0.19879087 6:0.03999904 7:0.025406506 +-1 1:0.632075 2:0.132075 3:0.028302 5:0.033128084 6:0.08000108 7:0.012942939 +-1 1:0.622222 2:0.088889 3:0.066667 5:0.094359877 6:0.037974038 7:0.01070461 +-1 1:0.762162 3:0.037838 7:0.01361239 +-1 1:0.671171 2:0.004505 3:0.126126 4:0.011070111 7:0.015518567 +-1 1:0.711111 2:0.07037 3:0.025926 5:0.035051362 6:0.047022047 7:0.014408311 +-1 1:0.70202 3:0.121212 7:0.021864994 +-1 1:0.814815 3:0.074074 7:0.02168022 +-1 1:0.784946 2:0.032258 3:0.043011 6:0.020784021 7:0.02838972 +-1 1:0.625 3:0.15625 4:0.0073800738 7:0.014195884 +-1 1:0.783784 3:0.027027 4:0.0036900369 7:0.01384311 +-1 1:0.730769 3:0.102564 7:0.019230768 8:0.023809524 +-1 1:0.863636 7:0.020509976 +-1 1:0.814189 3:0.010135 7:0.016109098 8:0.023809524 +-1 1:0.765432 3:0.024691 7:0.012797348 8:0.023809524 +-1 1:0.752688 3:0.021505 7:0.012260689 +-1 1:0.6 2:0.2 3:0.028571 5:0.28308708 6:0.11392511 7:0.013763067 +-1 1:0.678571 2:0.057143 3:0.057143 6:0.042018042 7:0.01554878 8:0.047619048 +-1 1:0.744526 2:0.043796 6:0.039216039 7:0.013619372 +-1 1:0.724138 2:0.025862 3:0.068966 4:0.0036900369 5:0.024928063 7:0.015716988 +-1 1:0.744526 2:0.058394 3:0.014599 5:0.14909129 7:0.015577707 +-1 1:0.747917 3:0.04375 7:0.015078762 +-1 1:0.754098 3:0.04918 7:0.014394244 +-1 1:0.761905 3:0.035714 7:0.014009872 +-1 1:0.763926 2:0.02122 3:0.03183 5:0.052979589 7:0.015931293 +-1 1:0.78125 3:0.023438 7:0.015100988 +-1 1:0.792683 2:0.012195 3:0.02439 5:0.016101859 7:0.034428909 8:0.023809524 +-1 1:0.8 7:0.01195122 +-1 1:0.722772 2:0.024752 3:0.054455 5:0.047582485 7:0.014187396 8:0.047619048 +-1 1:0.785185 3:0.02963 7:0.015176152 +-1 1:0.77907 3:0.011628 7:0.011982415 8:0.095238095 +-1 1:0.75 7:0.01146922 8:0.023809524 +-1 1:0.738095 7:0.013646921 +-1 1:0.804878 7:0.012046402 8:0.047619048 +-1 1:0.771429 3:0.057143 7:0.0141115 8:0.023809524 +-1 1:0.82 7:0.01402439 8:0.023809524 +-1 1:0.772727 7:0.010670732 +-1 1:0.677419 2:0.053763 3:0.064516 4:0.014760148 5:0.057787783 6:0.023256023 7:0.016915817 8:0.047619048 +-1 1:0.752266 2:0.018127 3:0.02719 5:0.018822775 7:0.014589933 8:0.11904762 +-1 1:0.783784 7:0.010876732 +-1 1:0.777778 2:0.027778 3:0.027778 5:0.079301656 7:0.015921409 +-1 1:0.818182 7:0.012749445 8:0.047619048 +-1 1:0.775 7:0.01089939 8:0.047619048 +-1 1:0.654321 2:0.082305 3:0.098765 5:0.036870276 6:0.017805018 7:0.025368866 +-1 1:0.815 7:0.014573171 8:0.047619048 +-1 1:0.809524 7:0.012049939 8:0.047619048 +-1 1:0.823529 7:0.014108079 8:0.023809524 +-1 1:0.782609 3:0.043478 7:0.015575293 8:0.023809524 +-1 1:0.884615 7:0.020168854 +-1 1:0.714286 3:0.076923 7:0.013669256 8:0.071428571 +-1 1:0.736842 3:0.052632 7:0.013478817 8:0.047619048 +-1 1:0.818182 3:0.015152 7:0.015336293 8:0.047619048 +-1 1:0.727273 2:0.030303 3:0.030303 5:0.071675637 7:0.019216555 8:0.047619048 +-1 1:0.740426 3:0.051064 4:0.0036900369 7:0.013284896 8:0.023809524 +-1 1:0.682927 3:0.170732 7:0.025133848 +-1 1:0.704225 2:0.014085 3:0.112676 4:0.011070111 5:0.030183531 7:0.02121264 +-1 1:0.869565 7:0.019883354 +-1 1:0.666667 2:0.027778 3:0.027778 7:0.025237128 +-1 1:0.747475 4:0.011070111 7:0.013242177 8:0.023809524 +-1 1:0.670732 2:0.036585 3:0.134146 4:0.011070111 5:0.03106317 6:0.012501013 7:0.017846518 +-1 1:0.705882 3:0.161765 4:0.014760148 7:0.029860116 8:0.023809524 +-1 1:0.523077 2:0.2 3:0.123077 4:0.0073800738 5:0.35965292 7:0.021388366 +-1 1:0.75 3:0.014706 7:0.011477762 +-1 1:0.686567 2:0.044776 3:0.119403 5:0.10649591 7:0.019111756 +-1 1:0.809524 3:0.047619 4:0.0036900369 7:0.01480836 +-1 1:0.741935 3:0.080645 7:0.014752165 +-1 1:0.793478 7:0.013719512 +-1 1:0.7 2:0.075 3:0.075 5:0.18792957 7:0.018140244 +-1 1:0.722222 2:0.027778 3:0.027778 7:0.010162604 +-1 1:0.781818 3:0.054545 7:0.016740579 +-1 1:0.666667 3:0.166667 4:0.0073800738 7:0.01549797 +-1 1:0.8 2:0.066667 3:0.133333 4:0.0036900369 5:0.062118885 7:0.048780488 +-1 1:0.757576 3:0.090909 7:0.019955652 +-1 1:0.690265 3:0.132743 7:0.018400604 +-1 1:0.75974 3:0.019481 7:0.013066201 8:0.071428571 +-1 1:0.756757 3:0.027027 7:0.015875634 +-1 1:0.771429 3:0.057143 7:0.016724738 +-1 1:0.8 7:0.012195122 +-1 1:0.666667 3:0.166667 7:0.01549797 +-1 1:0.790323 7:0.013621165 8:0.095238095 +-1 1:0.723077 2:0.015385 3:0.107692 4:0.0036900369 7:0.018386494 8:0.023809524 +-1 1:0.692308 2:0.115385 3:0.057692 4:0.0073800738 5:0.044369567 6:0.071430071 7:0.019699811 +-1 1:0.75 2:0.0125 3:0.1 5:0.024279516 7:0.02339939 +-1 1:0.702703 2:0.108108 3:0.027027 5:0.078466745 6:0.063159063 7:0.015655902 +-1 1:0.75 3:0.0625 7:0.011814024 +-1 1:0.78866 7:0.012823738 8:0.023809524 +-1 1:0.792453 7:0.012080073 8:0.023809524 +-1 1:0.7 3:0.1 7:0.017987805 +-1 1:0.947368 4:0.036900369 7:0.040436457 +-1 1:0.788462 3:0.019231 7:0.015869293 8:0.047619048 +-1 1:0.751295 2:0.020725 3:0.041451 5:0.044369567 7:0.015923165 8:0.023809524 +-1 1:0.690909 2:0.054545 3:0.063636 5:0.13855799 7:0.014911311 +-1 1:0.741935 2:0.032258 3:0.021505 5:0.11237756 6:0.015075015 7:0.01304747 +-1 1:0.787879 7:0.01293422 8:0.071428571 +-1 1:0.763889 3:0.034722 7:0.013719512 +-1 1:0.663043 2:0.065217 3:0.076087 5:0.032837356 6:0.026433026 7:0.015045067 8:0.023809524 +-1 1:0.756757 2:0.027027 5:0.10282081 7:0.011947921 8:0.047619048 +-1 1:0.683168 3:0.108911 4:0.0073800738 7:0.01756822 8:0.023809524 +-1 1:0.8 2:0.028571 3:0.028571 7:0.020209061 +-1 1:0.75 2:0.01087 7:0.011333512 8:0.047619048 +-1 1:0.967742 7:0.075531073 +-1 1:0.892857 7:0.021994774 +-1 1:0.524752 2:0.19802 3:0.09901 4:0.011070111 5:0.065533076 6:0.079122079 7:0.027469213 +-1 1:0.753086 2:0.037037 3:0.037037 6:0.02985003 7:0.015130988 +-1 1:0.757576 3:0.060606 7:0.015428677 +-1 1:0.730942 2:0.035874 3:0.03139 5:0.055379959 7:0.018402055 +-1 1:0.666667 2:0.05 3:0.116667 4:0.0036900369 5:0.0394421 7:0.019207317 +-1 1:0.75 3:0.068182 4:0.018450185 7:0.023096823 8:0.023809524 +-1 1:0.8 3:0.025 7:0.015320122 +-1 1:0.767123 3:0.068493 4:0.0036900369 7:0.016622116 +-1 1:0.742718 2:0.019417 3:0.024272 5:0.032554083 7:0.013556713 8:0.047619048 +-1 1:0.696629 2:0.022472 3:0.078652 4:0.011070111 5:0.074545644 7:0.013702384 +-1 1:0.754098 2:0.021858 3:0.054645 5:0.051861405 7:0.019159 +-1 1:0.740458 3:0.10687 4:0.0036900369 7:0.026857195 +-1 1:0.722008 2:0.073359 3:0.034749 5:0.060851609 6:0.032652033 7:0.01730389 +-1 1:0.819672 7:0.013494604 +-1 1:0.687316 2:0.050147 3:0.056047 5:0.054813412 6:0.0031500032 7:0.01712353 8:0.047619048 +-1 1:0.836735 3:0.061224 7:0.030238927 +-1 1:0.757576 2:0.006061 3:0.012121 5:0.019620414 7:0.014042866 +-1 1:0.826087 3:0.043478 7:0.016967128 +-1 1:0.603774 2:0.135849 3:0.083019 5:0.040403739 6:0.1016251 7:0.016981134 +-1 1:0.78125 7:0.010480183 8:0.023809524 +-1 1:0.673077 2:0.076923 3:0.081731 5:0.061708884 6:0.034767035 7:0.017706378 +-1 1:0.69863 2:0.027397 3:0.013699 6:0.02040902 7:0.012278652 +-1 1:0.791667 7:0.010670732 +-1 1:0.745679 2:0.02963 3:0.032099 4:0.0036900369 5:0.021141145 6:0.01984802 7:0.015928939 8:0.023809524 +-1 1:0.752475 2:0.009901 3:0.019802 5:0.032412446 7:0.013885537 8:0.023809524 +-1 1:0.735219 2:0.020566 3:0.033419 6:0.012606013 7:0.014922567 +-1 1:0.702703 2:0.067568 3:0.067568 4:0.0073800738 6:0.051282051 7:0.019281476 8:0.023809524 +-1 1:0.5 2:0.115385 3:0.076923 4:0.0036900369 5:0.31060934 7:0.016885555 +-1 1:0.764706 2:0.016807 3:0.008403 6:0.0094950095 7:0.016191841 8:0.047619048 +-1 1:0.726444 2:0.079027 3:0.009119 5:0.14566219 6:0.017241017 7:0.01612425 +-1 1:0.769063 2:0.006536 3:0.043573 5:0.011450211 7:0.017296348 +-1 1:0.751269 2:0.005076 3:0.06599 5:0.012277668 7:0.018787915 8:0.023809524 +-1 1:0.791667 3:0.041667 7:0.016133128 +-1 1:0.913043 3:0.043478 7:0.044538707 +-1 1:0.809524 2:0.047619 3:0.047619 5:0.093182055 7:0.023228805 +-1 1:0.792793 3:0.036036 7:0.018347616 8:0.047619048 +-1 1:0.761905 3:0.095238 4:0.0036900369 7:0.01480836 +-1 1:0.782609 3:0.065217 7:0.020767055 8:0.023809524 +-1 1:0.742857 7:0.010452963 8:0.071428571 +-1 1:0.789474 3:0.032895 7:0.020258341 8:0.023809524 +-1 1:0.6875 3:0.125 7:0.013910061 +-1 1:0.740741 2:0.012346 3:0.061728 5:0.041648651 7:0.01347486 8:0.023809524 +-1 1:0.708571 3:0.125714 4:0.0036900369 7:0.020905921 8:0.047619048 +-1 1:0.71875 2:0.020833 3:0.03125 5:0.03483518 7:0.013592482 8:0.023809524 +-1 1:0.714286 3:0.116883 4:0.014760148 7:0.017896738 +-1 1:0.76 3:0.04 7:0.010731707 8:0.023809524 +-1 1:0.792308 3:0.015385 7:0.016135085 +-1 1:0.782609 3:0.032609 7:0.015575293 8:0.023809524 +-1 1:0.647059 2:0.029412 3:0.073529 7:0.01273314 +-1 1:0.8125 3:0.0625 7:0.016768293 +-1 1:0.744 2:0.024 3:0.048 4:0.0036900369 5:0.021797146 7:0.016682927 +-1 1:0.785714 3:0.107143 4:0.0073800738 7:0.021559232 +-1 1:0.767677 7:0.012102732 8:0.023809524 +-1 1:0.778689 2:0.004098 3:0.069672 4:0.0036900369 7:0.023290683 +-1 1:0.88664 7:0.096227909 8:0.047619048 +-1 1:0.748718 2:0.005128 3:0.051282 4:0.0036900369 5:0.014282945 7:0.016322701 8:0.071428571 +-1 1:0.756098 2:0.04878 6:0.032967033 7:0.01353361 8:0.023809524 +-1 1:0.737864 3:0.038835 7:0.011484726 8:0.071428571 +-1 1:0.705426 2:0.03876 3:0.089147 4:0.04797048 5:0.06204434 7:0.019876159 +-1 1:0.78125 3:0.052083 7:0.018102134 +-1 1:0.675325 2:0.155844 3:0.025974 5:0.026433885 6:0.11702112 7:0.022331329 +-1 1:0.740741 2:0.012346 3:0.074074 5:0.02781298 7:0.020174646 8:0.023809524 +-1 1:0.761905 2:0.095238 5:0.25705575 7:0.016840884 +-1 1:0.631579 2:0.087719 3:0.087719 5:0.050370492 6:0.060810061 7:0.015832262 8:0.023809524 +-1 1:0.795918 7:0.013066201 +-1 1:0.670588 3:0.176471 4:0.022140221 7:0.024175037 +-1 1:0.741497 2:0.020408 3:0.027211 4:0.0073800738 6:0.018810019 7:0.013232122 8:0.071428571 +-1 1:0.823529 7:0.014705884 +-1 1:0.762376 3:0.039604 4:0.011070111 7:0.015757061 8:0.023809524 +-1 1:0.650685 2:0.130137 3:0.047945 5:0.019463868 6:0.10966211 7:0.015995659 +-1 1:0.746988 3:0.012048 7:0.013737878 8:0.047619048 +-1 1:0.606061 3:0.090909 7:0.012010348 8:0.023809524 +-1 1:0.764706 7:0.01422764 +-1 1:0.777778 7:0.012533878 8:0.023809524 +-1 1:0.76 3:0.026667 7:0.012357726 8:0.047619048 +-1 1:0.711111 3:0.111111 4:0.011070111 7:0.021544713 +-1 1:0.75 2:0.083333 3:0.083333 5:0.17749318 7:0.021341463 +-1 1:0.721854 2:0.019868 3:0.046358 5:0.042968109 7:0.014012274 8:0.023809524 +-1 1:0.777778 2:0.022222 5:0.054015774 7:0.018699189 +-1 1:0.726708 2:0.018634 3:0.037267 6:0.013245013 7:0.017156494 8:0.023809524 +-1 1:0.691667 3:0.1 4:0.018450185 7:0.017276421 +-1 1:0.767045 3:0.011364 7:0.013234482 8:0.023809524 +-1 1:0.717949 3:0.076923 7:0.012195122 +-1 1:0.755906 2:0.031496 3:0.047244 5:0.074545644 7:0.019204915 +-1 1:0.688889 2:0.044444 3:0.066667 5:0.15861077 7:0.012737128 8:0.023809524 +-1 1:0.785714 7:0.0091463415 +-1 1:0.761755 2:0.009404 3:0.040752 5:0.026881159 7:0.015903354 8:0.047619048 +-1 1:0.75 3:0.032609 7:0.015243902 +-1 1:0.743243 3:0.054054 7:0.01466711 +-1 1:0.72619 2:0.047619 3:0.059524 4:0.0036900369 5:0.079868203 7:0.020325201 8:0.023809524 +-1 1:0.642105 2:0.094737 3:0.115789 5:0.086182219 6:0.0086700087 7:0.022207957 +-1 1:0.693878 2:0.061224 6:0.061857062 7:0.012070683 8:0.023809524 +-1 1:0.785714 7:0.010235189 +-1 1:0.739394 3:0.036364 7:0.014190689 8:0.071428571 +-1 1:0.636364 2:0.136364 3:0.060606 6:0.0999991 7:0.016629713 +-1 1:0.752174 2:0.008696 3:0.06087 5:0.023481878 7:0.016834573 8:0.023809524 +-1 1:0.808511 3:0.042553 7:0.017903476 8:0.023809524 +-1 1:0.765957 2:0.012766 3:0.017021 5:0.04133556 7:0.014037366 8:0.023809524 +-1 1:0.757062 2:0.00565 3:0.045198 7:0.016225713 +-1 1:0.734513 3:0.070796 4:0.0036900369 7:0.017267427 8:0.023809524 +-1 1:0.761905 3:0.047619 7:0.015316494 8:0.023809524 +-1 1:0.758621 3:0.060345 7:0.020868378 8:0.047619048 +-1 1:0.531532 2:0.207207 3:0.054054 5:0.61654466 7:0.014612171 +-1 1:0.76 7:0.0097560976 8:0.047619048 +-1 1:0.705882 3:0.156863 7:0.018651366 +-1 1:0.666667 7:0.016666665 +-1 1:0.701493 3:0.059701 7:0.014652348 8:0.071428571 +-1 1:0.795455 7:0.017461195 8:0.023809524 +-1 1:0.804878 7:0.014723378 +-1 1:0.730159 3:0.084656 7:0.019196024 +-1 1:0.724026 2:0.038961 3:0.035714 5:0.046069208 6:0.0037080037 7:0.016015994 +-1 1:0.736111 2:0.020833 3:0.090278 4:0.0036900369 6:0.012396012 7:0.020494579 +-1 1:0.733945 2:0.009174 3:0.027523 5:0.035841546 7:0.011635713 8:0.023809524 +-1 1:0.756 3:0.068 4:0.0036900369 7:0.017731707 8:0.023809524 +-1 1:0.785714 7:0.01146922 8:0.023809524 +-1 1:0.818182 7:0.012749445 +-1 1:0.829787 7:0.017773744 8:0.023809524 +-1 1:0.761905 2:0.02381 3:0.047619 4:0.0036900369 5:0.063714162 7:0.016986061 8:0.047619048 +-1 1:0.743119 2:0.027523 3:0.036697 5:0.093182055 7:0.013425823 +-1 1:0.787879 3:0.004329 7:0.014122055 8:0.071428571 +-1 1:0.643411 2:0.03876 3:0.116279 5:0.030869351 6:0.018633019 7:0.022830402 8:0.023809524 +-1 1:0.684211 3:0.039474 7:0.0099486524 8:0.047619048 +-1 1:0.783333 3:0.016667 7:0.016209348 8:0.023809524 +-1 1:0.784314 3:0.039216 7:0.015423244 +-1 1:0.755814 7:0.01623653 +-1 1:0.729469 3:0.007246 7:0.013402854 8:0.095238095 +-1 1:0.734234 2:0.040541 3:0.018018 5:0.093375874 7:0.013156451 +-1 1:0.740741 3:0.037037 7:0.012119841 +-1 1:0.75 2:0.008929 3:0.044643 7:0.013991726 +-1 1:0.745098 3:0.039216 7:0.013570061 +-1 1:0.742857 3:0.038095 4:0.0073800738 7:0.013879213 8:0.023809524 +-1 1:0.659751 2:0.103734 3:0.053942 4:0.0073800738 5:0.010853846 6:0.082968083 7:0.017381841 8:0.023809524 +-1 1:0.770492 3:0.016393 7:0.012395043 8:0.023809524 +-1 1:0.768116 3:0.043478 7:0.014846238 +-1 1:0.686047 3:0.116279 4:0.0036900369 7:0.015811116 8:0.023809524 +-1 1:0.764706 2:0.029412 6:0.041667042 7:0.012912482 8:0.023809524 +-1 1:0.863636 7:0.026746122 +-1 1:0.634615 2:0.096154 3:0.096154 5:0.027611707 6:0.033333033 7:0.031660409 +-1 1:0.755102 3:0.020408 7:0.015928323 +-1 1:0.731034 2:0.02069 3:0.027586 4:0.0036900369 5:0.053054135 7:0.011816652 +-1 1:0.833333 7:0.01549797 8:0.023809524 +-1 1:0.787879 7:0.011640799 +-1 1:0.643836 2:0.109589 3:0.041096 5:0.096812428 6:0.077922078 7:0.012863348 8:0.023809524 +-1 1:0.762712 3:0.016949 7:0.013745348 +-1 1:0.748299 2:0.020408 3:0.013605 4:0.0036900369 6:0.018927019 7:0.013149165 8:0.095238095 +-1 1:0.70529 2:0.050378 3:0.037783 5:0.068313628 6:0.01030801 7:0.013408488 8:0.023809524 +-1 1:0.7 3:0.033333 7:0.014634146 +-1 1:0.690632 2:0.076253 3:0.043573 5:0.066129441 6:0.036291036 7:0.016472713 +-1 1:0.79661 3:0.033898 7:0.01741422 +-1 1:0.758333 7:0.014684957 +-1 1:0.827957 7:0.015932335 +-1 1:0.828947 7:0.017169445 +-1 1:0.763359 3:0.038168 4:0.0036900369 7:0.013731146 +-1 1:0.666667 2:0.040404 3:0.121212 4:0.022140221 6:0.028662029 7:0.019339738 +-1 1:0.357143 2:0.321429 3:0.071429 5:0.58466894 6:0.41176541 7:0.011106274 8:0.023809524 +-1 1:0.703008 2:0.052632 3:0.037594 5:0.066755624 6:0.031344031 7:0.015358518 +-1 1:0.747312 3:0.032258 7:0.012080384 8:0.071428571 +-1 1:0.607843 2:0.137255 3:0.058824 5:0.02823789 6:0.045456045 7:0.031563848 +-1 1:0.782609 7:0.010869567 +-1 1:0.696078 3:0.098039 4:0.0036900369 7:0.014646104 8:0.047619048 +-1 1:0.765957 2:0.021277 3:0.042553 5:0.0642658 7:0.015049299 +-1 1:0.672377 2:0.117773 3:0.021413 4:0.0073800738 5:0.036482638 6:0.090537091 7:0.016007732 +-1 1:0.805085 3:0.016949 7:0.016949152 8:0.023809524 +-1 1:0.727669 2:0.034858 3:0.041394 4:0.0073800738 5:0.015729131 6:0.018987019 7:0.018890482 8:0.023809524 +-1 1:0.717391 3:0.130435 7:0.021606573 +-1 1:0.806452 2:0.021505 3:0.010753 5:0.024764063 7:0.019735116 +-1 1:0.73913 2:0.065217 3:0.043478 5:0.054410866 6:0.021897022 7:0.018160128 +-1 1:0.709091 2:0.018182 3:0.018182 5:0.060121062 7:0.013747226 +-1 1:0.666667 2:0.066667 3:0.066667 7:0.0097560976 +-1 1:0.622642 2:0.169811 6:0.16981217 7:0.012195122 +-1 1:0.625 2:0.125 3:0.068182 5:0.035670091 6:0.1004791 7:0.014481707 +-1 1:0.753219 2:0.055794 3:0.021459 5:0.015348948 6:0.030885031 7:0.019064689 8:0.023809524 +-1 1:0.645161 2:0.064516 3:0.112903 4:0.0073800738 5:0.12908324 7:0.022718329 +-1 1:0.708661 2:0.015748 3:0.086614 5:0.048566487 7:0.014739774 +-1 1:0.72 3:0.06 7:0.014634146 8:0.023809524 +-1 1:0.717172 3:0.121212 4:0.0036900369 7:0.018415866 +-1 1:0.75 2:0.05 5:0.21925365 7:0.010365854 +-1 1:0.734848 2:0.060606 3:0.030303 6:0.036216036 7:0.022958244 +-1 1:0.646465 2:0.111111 3:0.060606 4:0.011070111 6:0.083046083 7:0.017799951 +-1 1:0.625 2:0.083333 3:0.125 4:0.0073800738 5:0.26623231 7:0.01422764 +-1 1:0.811881 7:0.015032604 +-1 1:0.770335 3:0.038278 7:0.014208189 +-1 1:0.692308 2:0.065934 3:0.054945 6:0.051948052 7:0.015478421 +-1 1:0.767338 2:0.01566 3:0.033557 5:0.035699909 7:0.017092268 +-1 1:0.725 2:0.021429 3:0.071429 4:0.025830258 5:0.030891715 6:0.0082860083 7:0.015766549 +-1 1:0.857143 7:0.013501744 +-1 1:0.857143 7:0.015969805 +-1 1:0.857143 7:0.015969805 +-1 1:0.761905 2:0.017857 3:0.047619 5:0.016564042 6:0.0066660067 7:0.01633275 +-1 1:0.714286 7:0.012115933 +-1 1:0.478261 2:0.231884 3:0.057971 5:0.76912469 6:0.047619048 7:0.011134677 +-1 1:0.726316 3:0.063158 4:0.0036900369 7:0.019062902 +-1 1:0.821429 7:0.01241289 +-1 1:0.750769 2:0.027692 3:0.046154 4:0.0036900369 5:0.046784846 6:0.0062760063 7:0.017936213 +-1 1:0.706731 2:0.048077 3:0.0625 4:0.014760148 5:0.04809685 6:0.024195024 7:0.018175421 8:0.047619048 +-1 1:0.833333 7:0.01117886 +-1 1:0.694444 2:0.027778 3:0.138889 4:0.0073800738 5:0.070326361 7:0.017953927 +-1 1:0.777778 3:0.079365 7:0.017711963 +-1 1:0.666667 2:0.047619 3:0.047619 5:0.094359877 7:0.022938445 +-1 1:0.804688 7:0.016911207 8:0.023809524 +-1 1:0.818182 3:0.037879 7:0.021711012 +-1 1:0.594937 2:0.037975 3:0.177215 4:0.018450185 5:0.11468847 7:0.015050939 +-1 1:0.481132 2:0.273585 3:0.084906 4:0.0073800738 5:0.31915227 6:0.1009171 7:0.018810402 +-1 1:0.775 3:0.025 7:0.0125 +-1 1:0.666667 2:0.020833 3:0.0625 5:0.072376366 7:0.013084348 +-1 1:0.75 3:0.1 7:0.015243902 +-1 1:0.623188 2:0.115942 3:0.072464 4:0.0036900369 5:0.1277936 6:0.068571069 7:0.015464829 +-1 1:0.73494 2:0.024096 3:0.084337 5:0.021797146 7:0.02512489 +-1 1:0.703911 2:0.050279 3:0.061453 5:0.031450807 6:0.012657013 7:0.016146616 +-1 1:0.745763 3:0.025424 4:0.0036900369 7:0.014778835 +-1 1:0.787879 3:0.075758 7:0.024667409 +-1 1:0.766667 3:0.066667 4:0.0036900369 7:0.015040652 +-1 1:0.794393 2:0.009346 3:0.018692 5:0.023519151 7:0.018064738 +-1 1:0.741176 2:0.035294 3:0.047059 4:0.0073800738 5:0.061105065 6:0.012294012 7:0.017503585 +-1 1:0.790123 3:0.024691 7:0.014905146 +-1 1:0.634146 2:0.04878 3:0.146341 4:0.014760148 5:0.14761528 7:0.015020823 +-1 1:0.71875 2:0.0625 3:0.0625 5:0.17336335 7:0.016387195 +-1 1:0.8125 7:0.012195122 8:0.023809524 +-1 1:0.588235 2:0.058824 3:0.235294 4:0.011070111 5:0.14335873 7:0.018651366 +-1 1:0.790323 3:0.048387 7:0.023996854 +-1 1:0.783333 2:0.05 3:0.016667 5:0.12563923 7:0.018089433 +-1 1:0.74 3:0.08 4:0.0073800738 7:0.015365854 +-1 1:0.803419 2:0.008547 3:0.008547 5:0.027104796 7:0.014331872 +-1 1:0.682848 2:0.042071 3:0.071197 4:0.033210332 5:0.074866191 6:0.012912013 7:0.013754043 8:0.047619048 +-1 1:0.753425 2:0.013699 3:0.041096 4:0.0073800738 7:0.01520214 +-1 1:0.664474 2:0.039474 3:0.092105 4:0.033210332 5:0.017436226 6:0.028071028 7:0.01714939 +-1 1:0.715909 2:0.034091 3:0.056818 4:0.0036900369 5:0.105989 7:0.014620287 8:0.023809524 +-1 1:0.707692 2:0.015385 3:0.061538 4:0.011070111 5:0.049699581 7:0.014071293 +-1 1:0.75 2:0.018939 3:0.026515 5:0.063386161 7:0.013580933 8:0.11904762 +-1 1:0.7 3:0.1 7:0.012804878 +-1 1:0.5 2:0.22 3:0.04 5:1 7:0.01 +-1 1:0.801282 2:0.003205 3:0.016026 5:0.0080136568 7:0.018175421 8:0.023809524 +-1 1:0.709302 2:0.040698 3:0.081395 5:0.074694736 7:0.017690018 +-1 1:0.735537 2:0.033058 3:0.033058 6:0.027027027 7:0.01678089 +-1 1:0.776 3:0.064 7:0.018878049 +-1 1:0.660714 3:0.133929 4:0.040590406 7:0.019925957 +-1 1:0.734513 2:0.035398 3:0.053097 5:0.021424418 6:0.0086220086 7:0.018778329 8:0.023809524 +-1 1:0.774194 2:0.016129 3:0.016129 5:0.042841382 7:0.017112512 +-1 1:0.588235 2:0.117647 3:0.176471 4:0.0073800738 5:0.081918209 6:0.016485016 7:0.032639884 +-1 1:0.785714 7:0.01241289 +-1 1:0.814815 7:0.013098463 +-1 1:0.697479 2:0.05042 3:0.067227 4:0.0036900369 5:0.065779077 6:0.026472026 7:0.017421604 +-1 1:0.77305 2:0.014184 3:0.049645 5:0.016906952 7:0.019071098 +-1 1:0.8 3:0.044444 7:0.017886177 +-1 1:0.746479 3:0.098592 7:0.021040878 8:0.023809524 +-1 1:0.786325 2:0.034188 3:0.017094 6:0.024861025 7:0.018865957 +-1 1:0.571429 2:0.142857 3:0.071429 5:0.035110998 6:0.023547024 7:0.046239835 +-1 1:0.571429 2:0.142857 3:0.071429 5:0.023295514 6:0.023436023 7:0.04645761 +-1 1:0.802158 3:0.017986 7:0.015463238 +-1 1:0.818182 7:0.017304543 +-1 1:0.75 3:0.026786 7:0.012467335 8:0.047619048 +-1 1:0.696429 2:0.071429 3:0.071429 4:0.0036900369 5:0.042356835 6:0.034092034 7:0.019163762 +-1 1:0.731844 2:0.027933 3:0.03352 5:0.053918865 7:0.01883772 +-1 1:0.703704 3:0.074074 4:0.0036900369 7:0.023035232 +-1 1:0.571429 3:0.071429 7:0.013066201 +-1 1:0.733333 3:0.133333 7:0.019105689 +-1 1:0.779874 3:0.031447 4:0.0073800738 7:0.015416476 8:0.023809524 +-1 1:0.714286 2:0.047619 3:0.047619 5:0.17749318 7:0.012195122 +-1 1:0.793103 7:0.011143817 +-1 1:0.698276 3:0.112069 4:0.0073800738 7:0.017083683 8:0.023809524 +-1 1:0.827586 7:0.015138774 +-1 1:0.833333 7:0.013211384 +-1 1:0.509804 2:0.235294 3:0.058824 5:0.17609172 6:0.14173214 7:0.015184122 +-1 1:0.771429 7:0.011149823 8:0.023809524 +-1 1:0.764706 3:0.117647 7:0.020444762 +-1 1:0.737705 2:0.040984 3:0.057377 4:0.0036900369 5:0.070490361 6:0.0070920071 7:0.021141543 +-1 1:0.790123 3:0.024691 7:0.017690457 +-1 1:0.784394 2:0.016427 3:0.024641 5:0.037839369 7:0.017265988 +-1 1:0.8 2:0.05 3:0.05 5:0.11125937 7:0.020426829 +-1 1:0.772727 3:0.068182 7:0.01607539 +-1 1:0.741935 3:0.096774 4:0.0036900369 7:0.01494886 +-1 1:0.647059 2:0.117647 3:0.058824 5:0.4385073 7:0.012195122 +-1 1:0.674419 2:0.081395 3:0.069767 5:0.1758159 7:0.015031195 +-1 1:0.648649 2:0.054054 3:0.108108 6:0.018948019 7:0.019569878 +-1 1:0.75 2:0.026786 3:0.080357 5:0.019314776 7:0.021014811 +-1 1:0.657609 2:0.108696 3:0.070652 4:0.011070111 5:0.019799323 6:0.047808048 7:0.024953604 +-1 1:0.894737 7:0.018292683 +-1 1:0.743468 2:0.042755 3:0.028504 5:0.052174496 6:0.015747016 7:0.016554659 8:0.023809524 +-1 1:0.714286 2:0.035714 3:0.071429 4:0.0036900369 6:0.026667027 7:0.01633275 +-1 1:0.6125 2:0.1 3:0.1625 5:0.079301656 6:0.010638011 7:0.021493902 +-1 1:0.615385 2:0.153846 3:0.115385 6:0.068181068 7:0.020637896 +-1 1:0.703125 2:0.015625 3:0.078125 7:0.014958079 +-1 1:0.685714 3:0.133333 7:0.015795585 +-1 1:0.740625 2:0.009375 3:0.0625 5:0.0087069313 6:0.007008007 7:0.016310976 +-1 1:0.771739 2:0.032609 3:0.043478 5:0.045040478 7:0.021937963 +-1 1:0.848485 7:0.015890616 8:0.023809524 +-1 1:0.672727 2:0.072727 3:0.109091 4:0.011070111 5:0.11959358 7:0.020731707 +-1 1:0.776786 3:0.026786 7:0.013556183 +-1 1:0.814815 3:0.037037 7:0.017389341 8:0.023809524 +-1 1:0.691358 2:0.006173 3:0.141975 4:0.036900369 5:0.010168026 7:0.027589585 8:0.023809524 +-1 1:0.709906 2:0.035377 3:0.058962 4:0.022140221 6:0.034332034 7:0.01633686 +-1 1:0.789474 3:0.105263 4:0.0036900369 7:0.019576378 +-1 1:0.753425 2:0.054795 3:0.041096 5:0.026717159 6:0.010752011 7:0.023304378 +-1 1:0.764706 2:0.058824 5:0.22589567 7:0.011836439 +-1 1:0.6875 2:0.0625 3:0.0625 5:0.23295514 7:0.012195122 +-1 1:0.806452 3:0.032258 7:0.01839103 8:0.023809524 +-1 1:0.77193 7:0.011446299 8:0.023809524 +-1 1:0.75 2:0.03125 6:0.052632053 7:0.01086128 +-1 1:0.848485 3:0.030303 4:0.0036900369 7:0.020509976 +-1 1:0.788462 7:0.011608817 8:0.047619048 +-1 1:0.727273 7:0.018015518 +-1 1:0.769231 3:0.038462 4:0.0036900369 7:0.014188555 8:0.047619048 +-1 1:0.791667 7:0.012068091 +-1 1:0.757576 2:0.030303 3:0.030303 5:0.10212008 7:0.013488543 +-1 1:0.654206 3:0.149533 4:0.0073800738 7:0.020914067 +-1 1:0.711111 2:0.066667 3:0.066667 5:0.18482102 7:0.016395665 +-1 1:0.759036 2:0.012048 3:0.042169 5:0.018681138 7:0.014656189 +-1 1:0.728155 3:0.097087 7:0.024212646 +-1 1:0.798122 7:0.012996677 +-1 1:0.745098 3:0.029412 7:0.014287421 +-1 1:0.764045 3:0.089888 4:0.011070111 7:0.021649768 +-1 1:0.711111 3:0.155556 7:0.020731707 +-1 1:0.684211 2:0.105263 3:0.078947 6:0.064749065 7:0.022304238 +-1 1:0.846154 7:0.012195122 +-1 1:0.747748 2:0.022523 3:0.031532 5:0.053725046 7:0.015243902 8:0.047619048 +-1 1:0.709199 2:0.041543 3:0.121662 4:0.011070111 5:0.0052554679 6:0.021156021 7:0.025656799 +-1 1:0.821429 7:0.012848433 +-1 1:0.709016 2:0.02459 3:0.07377 5:0.036967185 7:0.015118951 +-1 1:0.75 2:0.022727 3:0.022727 5:0.027507343 7:0.012518476 +-1 1:0.692308 2:0.153846 5:0.55218941 7:0.012664165 +-1 1:0.774775 7:0.014941768 +-1 1:0.591837 2:0.204082 5:0.677687 7:0.012319561 +-1 1:0.77665 2:0.005076 3:0.030457 4:0.014760148 5:0.014998584 7:0.015383189 +-1 1:0.809524 3:0.02381 7:0.015824622 +-1 1:0.78125 2:0.010417 3:0.020833 5:0.030675533 7:0.015434451 +-1 1:0.821429 7:0.014046165 +-1 1:0.763158 2:0.026316 5:0.108039 7:0.011071884 +-1 1:0.625 2:0.125 3:0.1875 5:0.17749318 7:0.032012195 +-1 1:0.611111 2:0.111111 3:0.166667 5:0.26156576 7:0.019308945 +-1 1:0.776119 3:0.011194 7:0.013105207 8:0.023809524 +-1 1:0.680851 2:0.06383 3:0.12766 4:0.011070111 5:0.10258226 7:0.028282305 +-1 1:0.623932 2:0.076923 3:0.094017 4:0.0073800738 5:0.040113011 6:0.0053820054 7:0.058109238 +-1 1:0.732143 2:0.075 3:0.017857 5:0.051324676 6:0.025818026 7:0.025304878 +-1 1:0.708333 2:0.041667 3:0.020833 5:0.05869724 7:0.016133128 +-1 1:0.704225 2:0.028169 3:0.028169 5:0.032986448 7:0.01940914 +-1 1:0.566667 2:0.155556 3:0.055556 5:0.013776035 6:0.055452055 7:0.036653116 +-1 1:0.759036 3:0.012048 7:0.014692921 +-1 1:0.676301 2:0.057803 3:0.080925 4:0.011070111 5:0.089812592 7:0.017552518 8:0.047619048 +-1 1:0.666667 7:0.015040652 +-1 1:0.738739 3:0.027027 7:0.011535927 8:0.095238095 +-1 1:0.762195 3:0.030488 7:0.01338489 8:0.023809524 +-1 1:0.842105 7:0.033483098 8:0.023809524 +-1 1:0.707224 2:0.04943 3:0.04943 5:0.04398193 6:0.022125022 7:0.015719189 +-1 1:0.735714 3:0.05 4:0.018450185 7:0.01393728 8:0.071428571 +-1 1:0.738318 2:0.018692 3:0.018692 7:0.013676774 +-1 1:0.719745 2:0.044586 3:0.015924 5:0.069021812 6:0.0046290046 7:0.0125835 +-1 1:0.825581 7:0.015952921 +-1 1:0.782609 7:0.011664896 8:0.047619048 +-1 1:0.788462 3:0.019231 7:0.015009384 8:0.047619048 +-1 1:0.801887 7:0.015013805 8:0.023809524 +-1 1:0.862745 3:0.019608 7:0.028574848 +-1 1:0.866667 3:0.133333 7:0.048780488 +-1 1:0.644886 2:0.133523 3:0.03125 5:0.15118602 6:0.035100035 7:0.022207591 +-1 1:0.794118 7:0.020444762 8:0.023809524 +-1 1:0.794118 7:0.019368726 +-1 1:0.790698 3:0.093023 4:0.0036900369 7:0.025382872 +-1 1:0.782051 3:0.012821 4:0.0073800738 7:0.014102561 8:0.023809524 +-1 1:0.587413 2:0.160839 3:0.045455 5:0.059010332 6:0.12664813 7:0.016160671 8:0.023809524 +-1 1:0.694268 2:0.012739 3:0.10828 6:0.0072120072 7:0.016156598 8:0.023809524 +-1 1:0.774194 7:0.010228165 8:0.047619048 +-1 1:0.692308 2:0.025641 3:0.128205 5:0.073807642 7:0.015791122 +-1 1:0.788889 3:0.044444 4:0.0036900369 7:0.017750677 +-1 1:0.716216 3:0.135135 4:0.033210332 7:0.02809822 +-1 1:0.692308 3:0.163462 4:0.022140221 7:0.027732177 +-1 1:0.642857 2:0.059524 3:0.059524 5:0.033933177 6:0.0045510046 7:0.047836817 +-1 1:0.72 3:0.08 4:0.011070111 7:0.017926829 +-1 1:0.590909 2:0.045455 3:0.181818 5:0.13934072 7:0.014828159 +-1 1:0.688889 2:0.033333 3:0.066667 5:0.12288104 7:0.012330622 +-1 1:0.811594 2:0.028986 5:0.055633414 6:0.011193011 7:0.02368328 +-1 1:0.508361 2:0.244147 3:0.016722 5:0.56490689 6:0.066864067 7:0.01372461 +-1 1:0.785714 2:0.035714 3:0.071429 4:0.0036900369 5:0.073807642 7:0.021994774 +-1 1:0.8 3:0.028571 7:0.016898957 +-1 1:0.663793 2:0.103448 3:0.030172 4:0.0036900369 5:0.039032099 6:0.083769084 7:0.015059927 +-1 1:0.578947 2:0.150376 3:0.067669 5:0.050027582 6:0.11073911 7:0.013662207 +-1 1:0.5 2:0.090909 3:0.272727 5:0.27107778 7:0.015243902 +-1 1:0.688889 2:0.011111 3:0.144444 5:0.025971702 6:0.01045201 7:0.019444445 +-1 1:0.736842 3:0.022556 4:0.0036900369 7:0.014120665 8:0.047619048 +-1 1:0.690323 2:0.025806 3:0.090323 5:0.029065347 7:0.020180957 8:0.023809524 +-1 1:0.806452 2:0.043011 3:0.043011 4:0.084870849 7:0.060778915 +-1 1:0.795918 3:0.040816 7:0.018666 +-1 1:1 7:0.097560976 +-1 1:0.976744 3:0.007752 7:0.17432407 +-1 1:0.638889 2:0.027778 3:0.055556 6:0.041667042 7:0.012195122 +-1 1:0.75 3:0.03125 4:0.014760148 7:0.019626524 +-1 1:0.803922 3:0.039216 7:0.032281201 +-1 1:0.728395 3:0.049383 7:0.029960854 +-1 1:0.631579 3:0.052632 7:0.013157896 +-1 1:0.707317 3:0.097561 7:0.016433671 +-1 1:0.687831 2:0.037037 3:0.095238 5:0.064713074 7:0.018583043 +-1 1:0.728814 3:0.050847 7:0.019842909 8:0.047619048 +-1 1:0.790393 2:0.008734 3:0.030568 7:0.018319311 +-1 1:0.685315 2:0.006993 3:0.020979 7:0.017098756 8:0.071428571 +-1 1:0.715151 3:0.030303 7:0.014634146 +-1 1:0.666667 2:0.083333 3:0.083333 5:0.17749318 7:0.021341463 +-1 1:0.727273 2:0.068182 3:0.045455 5:0.15749258 7:0.019678494 +-1 1:0.792812 7:0.013922549 +-1 1:0.68593 2:0.067839 3:0.045226 4:0.0073800738 5:0.052442861 6:0.03015003 7:0.015243902 +-1 1:0.768617 3:0.029255 7:0.014627659 8:0.023809524 +-1 1:0.767442 3:0.139535 7:0.059982988 +-1 1:0.697674 3:0.023256 4:0.0036900369 7:0.011060695 8:0.023809524 +-1 1:0.630435 3:0.065217 7:0.014581122 +-1 1:0.676596 2:0.06383 3:0.055319 4:0.0036900369 5:0.036721184 6:0.024630025 7:0.015801762 8:0.023809524 +-1 1:0.763636 3:0.054545 7:0.016518848 +-1 1:0.789272 3:0.003831 7:0.013994018 8:0.095238095 +-1 1:0.745763 3:0.016949 4:0.0036900369 7:0.014158744 8:0.023809524 +-1 1:0.686047 3:0.069767 7:0.014960293 +-1 1:0.466667 2:0.2 7:0.013008128 +-1 1:0.669643 3:0.116071 7:0.02580575 +-1 1:0.75 3:0.05 7:0.039634146 +-1 1:0.710145 3:0.101449 7:0.015288085 8:0.023809524 +-1 1:0.75 7:0.013211384 +-1 1:0.733333 3:0.088889 7:0.017073171 8:0.047619048 +-1 1:0.764286 3:0.064286 7:0.020209061 8:0.023809524 +-1 1:0.722772 3:0.069307 7:0.016421152 +-1 1:0.73913 3:0.043478 7:0.017762457 +-1 1:0.609091 2:0.081818 3:0.127273 4:0.0073800738 5:0.011271301 6:0.0068040068 7:0.07333703 +-1 1:0.704918 3:0.147541 4:0.014760148 7:0.024890043 +-1 1:0.9 2:0.025 5:0.010555663 7:0.10762195 +-1 1:0.705882 3:0.058824 7:0.020444762 8:0.047619048 +-1 1:0.671141 2:0.060403 3:0.053691 5:0.071675637 6:0.014424014 7:0.017024061 +-1 1:0.710059 2:0.047337 3:0.047337 5:0.03842828 6:0.01030801 7:0.020998701 +-1 1:0.686275 2:0.078431 3:0.044118 5:0.08077766 6:0.027864028 7:0.019308945 +-1 1:0.71134 2:0.041237 3:0.041237 4:0.011070111 5:0.042513381 6:0.011406011 7:0.016532561 +-1 1:0.668874 2:0.059603 3:0.059603 5:0.070661816 6:0.014217014 7:0.017040866 +-1 1:0.664835 2:0.049451 3:0.082418 5:0.041492106 6:0.011133011 7:0.018058165 +-1 1:0.67027 2:0.054054 3:0.07027 5:0.052495043 6:0.010563011 7:0.018721159 +-1 1:0.672619 2:0.047619 3:0.071429 5:0.048723033 6:0.013071013 7:0.016659409 +-1 1:0.732955 2:0.034091 3:0.032197 5:0.044809387 6:0.0067620068 7:0.015370933 +-1 1:0.671533 2:0.047445 3:0.087591 5:0.06580144 6:0.0075660076 7:0.017647323 +-1 1:0.659574 3:0.12766 7:0.014660091 +-1 1:0.689655 2:0.022989 3:0.057471 6:0.014634015 7:0.014367817 8:0.047619048 +-1 1:0.603053 2:0.110687 3:0.087786 5:0.035036453 6:0.056403056 7:0.019805439 +-1 1:0.5625 7:0.024390244 +-1 1:0.517857 2:0.142857 3:0.080357 4:0.0073800738 5:0.20531361 6:0.0063570064 7:0.025696866 +-1 1:0.333333 2:0.083333 5:0.20707289 7:0.018292683 +-1 1:0.590909 3:0.090909 7:0.011917957 +-1 1:0.762887 7:0.017601207 8:0.095238095 +-1 1:0.754098 7:0.01319472 +-1 1:0.651163 3:0.116279 7:0.030062396 +-1 1:0.684211 7:0.019736841 8:0.023809524 +-1 1:0.765625 2:0.023438 3:0.019531 4:0.0036900369 5:0.051414131 7:0.017268482 +-1 1:0.69697 3:0.030303 7:0.015705841 +-1 1:0.595376 2:0.034682 3:0.040462 5:0.05869724 7:0.017904976 8:0.047619048 diff --git a/data/c_rbf.sf b/data/c_rbf.sf new file mode 100644 index 0000000..7d48c41 --- /dev/null +++ b/data/c_rbf.sf @@ -0,0 +1,9 @@ +8 +1 +1 +1 +0.0369004 +7.45456 +3 +0.00609756 +0.238095 diff --git a/parameterresult.h b/parameterresult.h new file mode 100644 index 0000000..3238a6c --- /dev/null +++ b/parameterresult.h @@ -0,0 +1,70 @@ +// Copyright 2008 Rarefied Technologies, Inc. +// Distributed under the GPL v2 please see +// LICENSE file for more information. + +#pragma once + +#include +#include + + +class ParameterResult +{ +public: + ParameterResult() { bRefined = false; fError=0; nLevel=0; }; + + float fError; + float fStdDev; + float fWrong; // percent of predictions that would yield the wrong class + float fParam1; + float fParam2; + bool bRefined; // indicates if a refinement search has been spawned from this result + int nLevel; // which level of refinement this result is from + +private: + + friend class boost::serialization::access; + + template + void serialize(Archive & ar, const unsigned int version) + { + ar & fWrong; + ar & fError; + ar & fStdDev; + ar & fParam1; + ar & fParam2; + ar & bRefined; + ar & nLevel; + } + friend std::ostream& operator<<(std::ostream &os, const ParameterResult &pr) + { + os << pr.fWrong << '\t'; + os << pr.fError << '\t'; + os << pr.fStdDev << '\t'; + os << pr.fParam1 << '\t'; + os << pr.fParam2 << '\t'; + os << pr.bRefined << '\t'; + os << pr.nLevel; + + return os; + } +}; + + +class lessthan +{ +public: + bool operator()(const ParameterResult* left, const ParameterResult* right) const + { + bool bRet = (left->fWrong < right->fWrong); + if(!bRet && (left->fWrong == right->fWrong )) + { + bRet = left->fError < right->fError; + + } + + return bRet; + } + +}; + diff --git a/parametersearch.cpp b/parametersearch.cpp new file mode 100644 index 0000000..66298ac --- /dev/null +++ b/parametersearch.cpp @@ -0,0 +1,217 @@ +// Copyright 2008 Rarefied Technologies, Inc. +// Distributed under the GPL v2 please see +// LICENSE file for more information. + +#include "parametersearch.h" +#include "parameterresult.h" +#include "../thirdparty/libsvm/svm.h" +#include +#include +#include + +#define REFINED_RANGE 1.33 + +CParameterSearch::CParameterSearch(svm_problem* pProb, svm_parameter* pSvmParam, string strFilename) +{ + if(!pProb || !pSvmParam) + return; + + m_pOA = NULL; + m_pofs = NULL; + m_strFilename = strFilename; + + ResetSerialization(); + + m_pProblem = pProb; + m_pSvmParam = pSvmParam; + + m_rangeParameters.fParam1Min = -15; + //m_rangeParameters.fParam1Max = -1; + m_rangeParameters.fParam1Max = 3; + m_rangeParameters.fParam1Step = 4; + m_rangeParameters.bParam1UseLog = true; + m_rangeParameters.fParam1RefinementFactor = 2; + m_rangeParameters.fParam2Min = -13; + //m_rangeParameters.fParam2Max = -1; + m_rangeParameters.fParam2Max = -5; + m_rangeParameters.fParam2Step = 4; + m_rangeParameters.bParam2UseLog = true; + m_rangeParameters.fParam2RefinementFactor = 2; + + ParameterResult* pResult = new ParameterResult; + + const RangeParameters tempRP = m_rangeParameters; + *m_pOA << tempRP; + m_pofs->flush(); + + SearchRange( pResult, m_rangeParameters); + + // semi-infinite, breakable loop + while( pResult = GetNextResult()) + { + RangeParameters Params; + GetRefinedParameters(pResult->nLevel, pResult->fParam1, pResult->fParam2, Params); + if(!SearchRange( pResult, Params)) + break; + } +} + +CParameterSearch::~CParameterSearch() +{ + +} + +ParameterResult* CParameterSearch::GetNextResult() +{ + ParameterResult* pResult = NULL; + ResultsSet::iterator it = m_searchResults.begin(); + while(it != m_searchResults.end()) + { + pResult = *it; + if(!pResult->bRefined) + return pResult; + ++it; + } + return NULL; +} + +bool CParameterSearch::SearchRange(ParameterResult* pResult, RangeParameters& Params) +{ + if(!m_pProblem || !m_pSvmParam || !pResult) + return false; + + float fParam1 = 0; + float fParam2 = 0; + + double* target = new double[m_pProblem->l]; +/* for(int i=0; il; i++) + { + target[i] = 0; + }*/ + + for(fParam1=Params.fParam1Min; fParam1<=Params.fParam1Max; fParam1+=Params.fParam1Step) + { + if(Params.bParam1UseLog) + m_pSvmParam->p = ::pow(2,fParam1); + else + m_pSvmParam->p = fParam1; + + for(fParam2=Params.fParam2Min; fParam2<=Params.fParam2Max; fParam2+=Params.fParam2Step) + { + if(Params.bParam2UseLog) + m_pSvmParam->C = ::pow(2,fParam2); + else + m_pSvmParam->C = fParam2; + + int nFolds = 2; + svm_cross_validation(m_pProblem, m_pSvmParam, nFolds, target); + float fError = 0; + float fWrong = 0; + for(int i=0; il; i++) + { + fError += abs(m_pProblem->y[i] - target[i]); + if( m_pProblem->y[i] >= 0.5 && target[i] < 0.5) + fWrong++; + else if( m_pProblem->y[i] < 0.5 && target[i] >= 0.5) + fWrong++; + } + fError = (float)fError/m_pProblem->l; + fWrong = (float) fWrong/m_pProblem->l; + + float fStdDev = 0; + for(int i=0; il; i++) + { + fStdDev += pow(fError - abs(m_pProblem->y[i] - target[i]), 2) ; + } + fStdDev = pow(fStdDev, (float)0.5) / m_pProblem->l; + + std::cout << "\n****************" << std::endl; + std::cout << "C = 2^" << fParam2 << ", epsilon = 2^" << fParam1 << std::endl; + std::cout << "Avg Error: " << fError << " Std Dev: " << fStdDev << std::endl; + std::cout << "Percent wrong: " << fWrong << std::endl; + + ParameterResult* pNewResult = new ParameterResult; + pNewResult->fError = fError; + pNewResult->fStdDev = fStdDev; + pNewResult->fWrong = fWrong; + pNewResult->fParam1 = fParam1; + pNewResult->fParam2 = fParam2; + pNewResult->nLevel = pResult->nLevel + 1; + m_searchResults.insert(pNewResult); + + const ParameterResult* pConstResult = pNewResult; + + *m_pOA << *pConstResult; + m_pofs->flush(); + + //SaveTextResults(); + } + } + pResult->bRefined = true; + + SerializeData(); + + return true; +} + + +// nLevel is desired level, not current level +bool CParameterSearch::GetRefinedParameters(int nLevel, float fParam1, float fParam2, RangeParameters& paramsOut) +{ + paramsOut.bParam1UseLog = m_rangeParameters.bParam1UseLog; + float fParam1StepPrev = m_rangeParameters.fParam1Step / pow(m_rangeParameters.fParam1RefinementFactor, nLevel-1); + paramsOut.fParam1Min = max( m_rangeParameters.fParam1Min, fParam1 - (float)REFINED_RANGE * fParam1StepPrev ); + paramsOut.fParam1Max = min( m_rangeParameters.fParam1Max, fParam1 + (float)REFINED_RANGE * fParam1StepPrev ); + paramsOut.fParam1Step = m_rangeParameters.fParam1Step / pow(m_rangeParameters.fParam1RefinementFactor, nLevel); + + paramsOut.bParam2UseLog = m_rangeParameters.bParam2UseLog; + float fParam2StepPrev = m_rangeParameters.fParam2Step / pow(m_rangeParameters.fParam2RefinementFactor, nLevel-1); + paramsOut.fParam2Min = max( m_rangeParameters.fParam2Min, fParam2 - (float)REFINED_RANGE * fParam2StepPrev ); + paramsOut.fParam2Max = min( m_rangeParameters.fParam2Max, fParam2 + (float)REFINED_RANGE * fParam2StepPrev ); + paramsOut.fParam2Step = m_rangeParameters.fParam2Step / pow(m_rangeParameters.fParam2RefinementFactor, nLevel); + + return true; +} + +void CParameterSearch::ResetSerialization() +{ + delete m_pOA; + delete m_pofs; + + m_pofs = new std::ofstream(m_strFilename.c_str()); + m_pOA = new boost::archive::text_oarchive(*m_pofs); +} + +void CParameterSearch::SerializeData() +{ + ResetSerialization(); + + const CParameterSearch* pSearch = this; + + *m_pOA << *pSearch; + + m_pofs->flush(); +} + +void CParameterSearch::SaveTextResults() +{ + std::ofstream ofs("SearchResults.txt"); + ofs << *this; +} + +std::ostream & operator<<(std::ostream &os, const CParameterSearch &ps) +{ + os << ps.m_rangeParameters << std::endl << std::endl; + ResultsSet::iterator it = ps.m_searchResults.begin(); + while(it != ps.m_searchResults.end()) + { + const ParameterResult* pResult = *it; + + os << *pResult << '\n'; + + ++it; + } + + return os; +} + diff --git a/parametersearch.h b/parametersearch.h new file mode 100644 index 0000000..8edb3a6 --- /dev/null +++ b/parametersearch.h @@ -0,0 +1,119 @@ +#include +#include "../thirdparty/boost/archive/text_oarchive.hpp" +#include "../thirdparty/boost/archive/text_iarchive.hpp" +#include "../thirdparty/boost/serialization/set.hpp" +#include +#include "parameterresult.h" +#include + +struct svm_problem; +struct svm_parameter; + +using namespace std; + + +typedef multiset ResultsSet; + +struct RangeParameters +{ + float fParam1Min; + float fParam1Max; + float fParam1Step; + bool bParam1UseLog; + + float fParam2Min; + float fParam2Max; + float fParam2Step; + bool bParam2UseLog; + + // members below could be moved to a derived class + float fParam1RefinementFactor; + float fParam2RefinementFactor; + int nLevels; // alternatively have a minimum refined step for each param + + template + void serialize(Archive & ar, const unsigned int version) + { + ar & fParam1Min; + ar & fParam1Max; + ar & fParam1Step; + ar & bParam1UseLog; + ar & fParam2Min; + ar & fParam2Max; + ar & fParam2Step; + ar & bParam2UseLog; + ar & fParam1RefinementFactor; + ar & fParam2RefinementFactor; + } + +// friend ostream& operator<<(ostream &os, const RangeParameters &rp); + friend ostream& operator<<(ostream &os, const RangeParameters &rp) + { + os << rp.fParam1Min << endl; + os << rp.fParam1Max << endl; + os << rp.fParam1Step << endl; + os << rp.bParam1UseLog << endl; + os << rp.fParam2Min << endl; + os << rp.fParam2Max << endl; + os << rp.fParam2Step << endl; + os << rp.bParam2UseLog << endl; + os << rp.fParam1RefinementFactor << endl; + os << rp.fParam2RefinementFactor << endl; + return os; + /* return os << rp.fParam1Min + << rp.fParam1Max + << rp.fParam1Step + << rp.bParam1UseLog + << rp.fParam2Min + << rp.fParam2Max + << rp.fParam2Step + << rp.bParam2UseLog + << rp.fParam1RefinementFactor + << rp.fParam2RefinementFactor;*/ + } +}; + + +/*class SearchParameters : class RangeParameters +{ +public: + float fRefinementFactor; +};*/ + +class CParameterSearch +{ +public: + + CParameterSearch(svm_problem* pProb, svm_parameter* pSvmParam, std::string); + ~CParameterSearch(); + + bool SearchRange(ParameterResult* pResult, RangeParameters&); + bool GetRefinedParameters(int nLevel, float fParam1, float fParam2, RangeParameters& paramsOut); + ParameterResult* GetNextResult(); + + svm_problem* m_pProblem; + svm_parameter* m_pSvmParam; + ResultsSet m_searchResults; + RangeParameters m_rangeParameters; + + +private: + friend class boost::serialization::access; + friend std::ostream & operator<<(std::ostream &os, const CParameterSearch &ps); + + template + void serialize(Archive & ar, const unsigned int version) + { + ar.register_type(static_cast(NULL)); + ar & m_rangeParameters; + ar & m_searchResults; + } + + void ResetSerialization(); + void SerializeData(); + void SaveTextResults(); + + std::ofstream* m_pofs; + boost::archive::text_oarchive* m_pOA; + std::string m_strFilename; +}; diff --git a/stupidfilter.cpp b/stupidfilter.cpp new file mode 100644 index 0000000..c577d0e --- /dev/null +++ b/stupidfilter.cpp @@ -0,0 +1,1996 @@ +// Copyright 2008 Rarefied Technologies, Inc. +// Distributed under the GPL v2 please see +// LICENSE file for more information. + +#line 2 "fclassify.cpp" + +#line 4 "fclassify.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 34 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + * Given that the standard has decreed that size_t exists since 1989, + * I guess we can afford to depend on it. Manoj. + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 12 +#define YY_END_OF_BUFFER 13 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_acclist[123] = + { 0, + 13, 1, 5, 11, 12, 1, 10, 11, 12, 10, + 12, 1, 5, 10, 11, 12, 1, 10, 11, 12, + 1, 4, 5, 11, 12, 1, 4, 5, 11, 12, + 1, 4, 5, 11, 12, 1, 5, 11, 12, 1, + 4, 5, 11, 12, 1, 3, 5, 11, 12, 1, + 3, 5, 11, 12, 1, 2, 5, 11, 12, 1, + 2, 5, 11, 12, 1, 2, 5, 11, 12, 1, + 2, 5, 11, 12, 5, 9, 5, 8, 5, 5, + 8, 5, 8, 5, 5, 5, 5, 5, 5, 8, + 5, 8, 5, 8, 5, 5, 5, 5, 8, 5, + + 8, 5, 8, 5, 8, 5, 7, 6, 5, 5, + 8, 5, 5, 8, 5, 8, 5, 5, 5, 5, + 5, 8 + } ; + +static yyconst flex_int16_t yy_accept[201] = + { 0, + 1, 1, 1, 2, 6, 10, 12, 17, 21, 26, + 31, 36, 40, 45, 50, 55, 60, 65, 70, 75, + 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 79, 80, 82, 84, 85, 86, 87, + 88, 89, 91, 93, 95, 96, 97, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 100, 102, 104, 106, 107, + + 108, 109, 110, 112, 113, 115, 117, 118, 119, 120, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123 + + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 7, 9, 7, 1, 10, 1, + 1, 11, 1, 1, 1, 12, 1, 7, 7, 7, + 7, 7, 13, 7, 14, 14, 14, 14, 15, 14, + 14, 14, 14, 14, 14, 16, 14, 14, 17, 14, + 14, 18, 14, 14, 19, 14, 14, 14, 14, 14, + 7, 7, 7, 1, 7, 7, 20, 21, 22, 23, + + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 29, 36, 37, 38, 39, 40, 41, 29, + 42, 43, 7, 7, 7, 7, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[44] = + { 0, + 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[203] = + { 0, + 0, 0, 421, 0, 422, 422, 0, 39, 76, 0, + 411, 39, 41, 110, 129, 135, 83, 149, 156, 0, + 422, 382, 400, 47, 389, 14, 67, 376, 18, 153, + 391, 51, 76, 93, 409, 378, 68, 73, 28, 150, + 154, 174, 121, 403, 171, 189, 395, 383, 389, 377, + 146, 147, 401, 400, 180, 201, 219, 366, 389, 383, + 365, 364, 183, 378, 356, 360, 359, 191, 359, 168, + 177, 362, 197, 389, 381, 369, 354, 385, 384, 364, + 347, 381, 358, 353, 363, 350, 349, 356, 341, 156, + 198, 340, 346, 356, 0, 225, 369, 368, 238, 422, + + 422, 252, 246, 261, 266, 271, 276, 280, 242, 284, + 337, 367, 328, 346, 203, 349, 363, 340, 361, 341, + 247, 359, 358, 357, 356, 355, 323, 316, 337, 104, + 247, 351, 350, 349, 323, 347, 346, 345, 318, 324, + 337, 310, 321, 339, 338, 337, 336, 309, 334, 288, + 314, 309, 313, 303, 302, 300, 327, 307, 325, 287, + 318, 296, 293, 320, 296, 318, 280, 311, 315, 264, + 314, 313, 309, 280, 307, 287, 305, 262, 304, 298, + 301, 274, 299, 298, 297, 295, 261, 292, 270, 290, + 289, 245, 228, 184, 203, 165, 185, 103, 422, 68, + + 67, 315 + } ; + +static yyconst flex_int16_t yy_def[203] = + { 0, + 199, 1, 199, 200, 199, 199, 200, 199, 200, 200, + 200, 9, 9, 201, 201, 200, 200, 200, 200, 200, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 200, 200, 9, 9, 200, 200, 200, 200, + 9, 9, 200, 200, 202, 15, 202, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 200, 200, 200, 200, 202, 199, + + 199, 200, 202, 202, 202, 202, 202, 202, 202, 202, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 202, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 0, 199, + + 199, 199 + } ; + +static yyconst flex_int16_t yy_nxt[466] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, + 4, 4, 13, 14, 14, 14, 15, 14, 14, 16, + 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, + 17, 17, 17, 19, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 21, 52, 72, 52, 65, 53, 22, + 53, 54, 66, 54, 88, 89, 73, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 56, 20, 33, + 34, 35, 21, 36, 37, 38, 39, 40, 60, 41, + 42, 43, 78, 61, 44, 45, 67, 62, 46, 63, + 68, 85, 47, 79, 69, 48, 55, 55, 55, 55, + + 55, 55, 49, 80, 82, 70, 86, 21, 21, 50, + 20, 87, 83, 20, 81, 20, 20, 20, 20, 20, + 20, 20, 20, 55, 55, 55, 55, 55, 55, 20, + 95, 163, 20, 95, 20, 20, 20, 20, 20, 20, + 20, 20, 55, 55, 57, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 21, 53, 97, 21, 54, 98, + 21, 51, 55, 55, 55, 55, 55, 55, 51, 55, + 55, 55, 55, 55, 55, 74, 96, 91, 21, 144, + 53, 100, 100, 54, 100, 90, 51, 21, 75, 21, + 198, 76, 92, 93, 96, 21, 126, 94, 53, 124, + + 127, 54, 101, 101, 125, 101, 102, 21, 102, 102, + 116, 197, 128, 102, 20, 20, 20, 20, 20, 20, + 100, 100, 122, 100, 103, 117, 130, 104, 105, 131, + 145, 106, 21, 146, 95, 107, 154, 95, 108, 100, + 100, 155, 100, 100, 100, 109, 100, 100, 100, 21, + 100, 21, 110, 101, 101, 150, 101, 102, 150, 102, + 102, 150, 100, 100, 102, 100, 21, 100, 100, 150, + 100, 150, 100, 100, 164, 100, 150, 100, 100, 165, + 100, 100, 100, 159, 100, 100, 100, 187, 100, 100, + 100, 150, 100, 21, 21, 196, 21, 195, 192, 21, + + 188, 21, 21, 21, 194, 21, 150, 193, 21, 191, + 190, 21, 189, 21, 150, 99, 99, 21, 21, 21, + 186, 185, 21, 184, 21, 183, 182, 181, 180, 21, + 179, 21, 178, 177, 176, 175, 174, 173, 21, 172, + 21, 21, 21, 21, 171, 170, 169, 168, 167, 21, + 21, 21, 166, 21, 21, 21, 162, 161, 160, 21, + 21, 21, 21, 21, 158, 21, 157, 21, 156, 153, + 152, 21, 151, 95, 95, 149, 148, 147, 143, 142, + 141, 140, 139, 138, 137, 21, 136, 135, 21, 21, + 134, 133, 132, 21, 129, 123, 121, 120, 119, 118, + + 115, 114, 113, 112, 111, 95, 95, 95, 95, 95, + 95, 95, 84, 21, 77, 71, 64, 59, 58, 51, + 199, 3, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199 + } ; + +static yyconst flex_int16_t yy_chk[466] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 8, 12, 29, 13, 26, 12, 8, + 13, 12, 26, 13, 39, 39, 29, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 201, 200, 8, + 8, 8, 37, 8, 8, 8, 8, 8, 24, 8, + 8, 9, 32, 24, 9, 9, 27, 24, 9, 24, + 27, 37, 9, 32, 27, 9, 17, 17, 17, 17, + + 17, 17, 9, 33, 34, 27, 38, 198, 130, 9, + 14, 38, 34, 14, 33, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, + 43, 130, 15, 43, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, + 16, 16, 16, 16, 40, 51, 52, 30, 51, 52, + 90, 16, 18, 18, 18, 18, 18, 18, 18, 19, + 19, 19, 19, 19, 19, 30, 45, 41, 42, 90, + 45, 55, 55, 45, 55, 40, 19, 63, 30, 197, + 196, 30, 41, 42, 46, 68, 71, 42, 46, 70, + + 71, 46, 56, 56, 70, 56, 56, 195, 56, 56, + 63, 194, 71, 56, 56, 56, 56, 56, 56, 56, + 57, 57, 68, 57, 57, 63, 73, 57, 57, 73, + 91, 57, 193, 91, 96, 57, 115, 96, 57, 99, + 99, 115, 99, 109, 109, 57, 109, 103, 103, 192, + 103, 121, 57, 102, 102, 103, 102, 102, 103, 102, + 102, 109, 104, 104, 102, 104, 178, 105, 105, 104, + 105, 105, 106, 106, 131, 106, 106, 107, 107, 131, + 107, 108, 108, 121, 108, 110, 110, 170, 110, 150, + 150, 107, 150, 191, 190, 189, 188, 187, 178, 186, + + 170, 185, 184, 183, 182, 181, 108, 180, 179, 177, + 176, 175, 174, 173, 110, 202, 202, 172, 171, 169, + 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, + 158, 157, 156, 155, 154, 153, 152, 151, 149, 148, + 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, + 137, 136, 135, 134, 133, 132, 129, 128, 127, 126, + 125, 124, 123, 122, 120, 119, 118, 117, 116, 114, + 113, 112, 111, 98, 97, 94, 93, 92, 89, 88, + 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, + 77, 76, 75, 74, 72, 69, 67, 66, 65, 64, + + 62, 61, 60, 59, 58, 54, 53, 50, 49, 48, + 47, 44, 36, 35, 31, 28, 25, 23, 22, 11, + 3, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199 + } ; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ +{ \ +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ +yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ +++(yy_lp); \ +goto find_rule; \ +} + +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "fclassify.flex" +float misspell = 0, word_length = 0, num_total = 0, num_lowers = 0, num_caps = 0, num_punct = 0, word_count = 0, initial_cap = 0, intercap = 0, repeat_emphasis = 0; +#line 649 "fclassify.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 4 "fclassify.flex" + +#line 804 "fclassify.cpp" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! (yy_state_buf) ) + (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ); + if ( ! (yy_state_buf) ) + YY_FATAL_ERROR( "out of dynamic memory in yylex()" ); + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 200 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 422 ); + +yy_find_action: + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[(yy_lp)]; + { + (yy_full_match) = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +YY_RULE_SETUP +#line 5 "fclassify.flex" +++num_total; REJECT; + YY_BREAK +case 2: +YY_RULE_SETUP +#line 6 "fclassify.flex" +++num_lowers; REJECT; + YY_BREAK +case 3: +YY_RULE_SETUP +#line 7 "fclassify.flex" +++num_caps; REJECT; + YY_BREAK +case 4: +YY_RULE_SETUP +#line 8 "fclassify.flex" +++num_punct; REJECT; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 9 "fclassify.flex" +++word_count; REJECT; + YY_BREAK +case 6: +/* rule 6 can match eol */ +YY_RULE_SETUP +#line 10 "fclassify.flex" +++initial_cap; REJECT; + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 11 "fclassify.flex" +++intercap; REJECT; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 12 "fclassify.flex" +++repeat_emphasis; REJECT; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 13 "fclassify.flex" +++misspell; REJECT; + YY_BREAK +case 10: +/* rule 10 can match eol */ +YY_RULE_SETUP +#line 14 "fclassify.flex" +; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 15 "fclassify.flex" +; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 16 "fclassify.flex" +ECHO; + YY_BREAK +#line 959 "fclassify.cpp" + case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 200 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 200 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 199); + if ( ! yy_is_jam ) + *(yy_state_ptr)++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + + (yy_state_buf) = 0; + (yy_state_ptr) = 0; + (yy_full_match) = 0; + (yy_lp) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + yyfree ( (yy_state_buf) ); + (yy_state_buf) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 16 "fclassify.flex" + + + +#include "SVMUtil.h" +#include "../thirdparty/libsvm/svm.h" +#include +#include + +main(int argc, char** argv) +{ + if ( argc < 2 ) + { + printf( "usage: %s [model filename] \n", argv[0] ); + } + else + { + yylex(); + num_lowers = num_lowers / num_total; + num_caps = num_caps / num_total; + num_punct = num_punct / num_total; + initial_cap = initial_cap / word_count; + intercap = intercap / word_count; + word_length = word_count / num_total; + + + + // Model/scale factor filename (no extension) + std::string strFilename = argv[1]; + + SVMUtil svmutil; + + if(svmutil.Load(strFilename.c_str())) + { + const int num_attributes = 8; + + svm_node* node = new svm_node[num_attributes+1]; + + for(int i=0; i // for using pairs with boost::cref +#include + +namespace boost { + + template + tuple< T const&, T const& > + minmax(T const& a, T const& b) { + return (b + tuple< T const&, T const& > + minmax(T const& a, T const& b, BinaryPredicate comp) { + return comp(b,a) ? make_tuple(cref(b),cref(a)) : make_tuple(cref(a),cref(b)); + } + +} // namespace boost + +#endif // BOOST_ALGORITHM_MINMAX_HPP diff --git a/thirdparty/boost/algorithm/minmax_element.hpp b/thirdparty/boost/algorithm/minmax_element.hpp new file mode 100644 index 0000000..996ede0 --- /dev/null +++ b/thirdparty/boost/algorithm/minmax_element.hpp @@ -0,0 +1,551 @@ +// (C) Copyright Herve Bronnimann 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) + +/* + Revision history: + 1 July 2004 + Split the code into two headers to lessen dependence on + Boost.tuple. (Herve) + 26 June 2004 + Added the code for the boost minmax library. (Herve) +*/ + +#ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP +#define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP + +/* PROPOSED STANDARD EXTENSIONS: + * + * minmax_element(first, last) + * Effect: std::make_pair( std::min_element(first, last), + * std::max_element(first, last) ); + * + * minmax_element(first, last, comp) + * Effect: std::make_pair( std::min_element(first, last, comp), + * std::max_element(first, last, comp) ); + */ + +#include // for std::pair and std::make_pair + +namespace boost { + + namespace detail { // for obtaining a uniform version of minmax_element + // that compiles with VC++ 6.0 -- avoid the iterator_traits by + // having comparison object over iterator, not over dereferenced value + + template + struct less_over_iter { + bool operator()(Iterator const& it1, + Iterator const& it2) const { return *it1 < *it2; } + }; + + template + struct binary_pred_over_iter { + explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {} + bool operator()(Iterator const& it1, + Iterator const& it2) const { return m_p(*it1, *it2); } + private: + BinaryPredicate m_p; + }; + + // common base for the two minmax_element overloads + + template + std::pair + basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp) + { + if (first == last) + return std::make_pair(last,last); + + ForwardIter min_result = first; + ForwardIter max_result = first; + + // if only one element + ForwardIter second = first; ++second; + if (second == last) + return std::make_pair(min_result, max_result); + + // treat first pair separately (only one comparison for first two elements) + ForwardIter potential_min_result = last; + if (comp(first, second)) + max_result = second; + else { + min_result = second; + potential_min_result = first; + } + + // then each element by pairs, with at most 3 comparisons per pair + first = ++second; if (first != last) ++second; + while (second != last) { + if (comp(first, second)) { + if (comp(first, min_result)) { + min_result = first; + potential_min_result = last; + } + if (comp(max_result, second)) + max_result = second; + } else { + if (comp(second, min_result)) { + min_result = second; + potential_min_result = first; + } + if (comp(max_result, first)) + max_result = first; + } + first = ++second; + if (first != last) ++second; + } + + // if odd number of elements, treat last element + if (first != last) { // odd number of elements + if (comp(first, min_result)) + min_result = first, potential_min_result = last; + else if (comp(max_result, first)) + max_result = first; + } + + // resolve min_result being incorrect with one extra comparison + // (in which case potential_min_result is necessarily the correct result) + if (potential_min_result != last + && !comp(min_result, potential_min_result)) + min_result = potential_min_result; + + return std::make_pair(min_result,max_result); + } + + } // namespace detail + + template + std::pair + minmax_element(ForwardIter first, ForwardIter last) + { + return detail::basic_minmax_element(first, last, + detail::less_over_iter() ); + } + + template + std::pair + minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp) + { + return detail::basic_minmax_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + +} + +/* PROPOSED BOOST EXTENSIONS + * In the description below, [rfirst,rlast) denotes the reversed range + * of [first,last). Even though the iterator type of first and last may + * be only a Forward Iterator, it is possible to explain the semantics + * by assuming that it is a Bidirectional Iterator. In the sequel, + * reverse(ForwardIterator&) returns the reverse_iterator adaptor. + * This is not how the functions would be implemented! + * + * first_min_element(first, last) + * Effect: std::min_element(first, last); + * + * first_min_element(first, last, comp) + * Effect: std::min_element(first, last, comp); + * + * last_min_element(first, last) + * Effect: reverse( std::min_element(reverse(last), reverse(first)) ); + * + * last_min_element(first, last, comp) + * Effect: reverse( std::min_element(reverse(last), reverse(first), comp) ); + * + * first_max_element(first, last) + * Effect: std::max_element(first, last); + * + * first_max_element(first, last, comp) + * Effect: max_element(first, last); + * + * last_max_element(first, last) + * Effect: reverse( std::max_element(reverse(last), reverse(first)) ); + * + * last_max_element(first, last, comp) + * Effect: reverse( std::max_element(reverse(last), reverse(first), comp) ); + * + * first_min_first_max_element(first, last) + * Effect: std::make_pair( first_min_element(first, last), + * first_max_element(first, last) ); + * + * first_min_first_max_element(first, last, comp) + * Effect: std::make_pair( first_min_element(first, last, comp), + * first_max_element(first, last, comp) ); + * + * first_min_last_max_element(first, last) + * Effect: std::make_pair( first_min_element(first, last), + * last_max_element(first, last) ); + * + * first_min_last_max_element(first, last, comp) + * Effect: std::make_pair( first_min_element(first, last, comp), + * last_max_element(first, last, comp) ); + * + * last_min_first_max_element(first, last) + * Effect: std::make_pair( last_min_element(first, last), + * first_max_element(first, last) ); + * + * last_min_first_max_element(first, last, comp) + * Effect: std::make_pair( last_min_element(first, last, comp), + * first_max_element(first, last, comp) ); + * + * last_min_last_max_element(first, last) + * Effect: std::make_pair( last_min_element(first, last), + * last_max_element(first, last) ); + * + * last_min_last_max_element(first, last, comp) + * Effect: std::make_pair( last_min_element(first, last, comp), + * last_max_element(first, last, comp) ); + */ + +namespace boost { + + // Min_element and max_element variants + + namespace detail { // common base for the overloads + + template + ForwardIter + basic_first_min_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return last; + ForwardIter min_result = first; + while (++first != last) + if (comp(first, min_result)) + min_result = first; + return min_result; + } + + template + ForwardIter + basic_last_min_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return last; + ForwardIter min_result = first; + while (++first != last) + if (!comp(min_result, first)) + min_result = first; + return min_result; + } + + template + ForwardIter + basic_first_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return last; + ForwardIter max_result = first; + while (++first != last) + if (comp(max_result, first)) + max_result = first; + return max_result; + } + + template + ForwardIter + basic_last_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return last; + ForwardIter max_result = first; + while (++first != last) + if (!comp(first, max_result)) + max_result = first; + return max_result; + } + + } // namespace detail + + template + ForwardIter + first_min_element(ForwardIter first, ForwardIter last) + { + return detail::basic_first_min_element(first, last, + detail::less_over_iter() ); + } + + template + ForwardIter + first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp) + { + return detail::basic_first_min_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + template + ForwardIter + last_min_element(ForwardIter first, ForwardIter last) + { + return detail::basic_last_min_element(first, last, + detail::less_over_iter() ); + } + + template + ForwardIter + last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp) + { + return detail::basic_last_min_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + template + ForwardIter + first_max_element(ForwardIter first, ForwardIter last) + { + return detail::basic_first_max_element(first, last, + detail::less_over_iter() ); + } + + template + ForwardIter + first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp) + { + return detail::basic_first_max_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + template + ForwardIter + last_max_element(ForwardIter first, ForwardIter last) + { + return detail::basic_last_max_element(first, last, + detail::less_over_iter() ); + } + + template + ForwardIter + last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp) + { + return detail::basic_last_max_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + + // Minmax_element variants -- comments removed + + namespace detail { + + template + std::pair + basic_first_min_last_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) + return std::make_pair(last,last); + + ForwardIter min_result = first; + ForwardIter max_result = first; + + ForwardIter second = ++first; + if (second == last) + return std::make_pair(min_result, max_result); + + if (comp(second, min_result)) + min_result = second; + else + max_result = second; + + first = ++second; if (first != last) ++second; + while (second != last) { + if (!comp(second, first)) { + if (comp(first, min_result)) + min_result = first; + if (!comp(second, max_result)) + max_result = second; + } else { + if (comp(second, min_result)) + min_result = second; + if (!comp(first, max_result)) + max_result = first; + } + first = ++second; if (first != last) ++second; + } + + if (first != last) { + if (comp(first, min_result)) + min_result = first; + else if (!comp(first, max_result)) + max_result = first; + } + + return std::make_pair(min_result, max_result); + } + + template + std::pair + basic_last_min_first_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return std::make_pair(last,last); + + ForwardIter min_result = first; + ForwardIter max_result = first; + + ForwardIter second = ++first; + if (second == last) + return std::make_pair(min_result, max_result); + + if (comp(max_result, second)) + max_result = second; + else + min_result = second; + + first = ++second; if (first != last) ++second; + while (second != last) { + if (comp(first, second)) { + if (!comp(min_result, first)) + min_result = first; + if (comp(max_result, second)) + max_result = second; + } else { + if (!comp(min_result, second)) + min_result = second; + if (comp(max_result, first)) + max_result = first; + } + first = ++second; if (first != last) ++second; + } + + if (first != last) { + if (!comp(min_result, first)) + min_result = first; + else if (comp(max_result, first)) + max_result = first; + } + + return std::make_pair(min_result, max_result); + } + + template + std::pair + basic_last_min_last_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + if (first == last) return std::make_pair(last,last); + + ForwardIter min_result = first; + ForwardIter max_result = first; + + ForwardIter second = first; ++second; + if (second == last) + return std::make_pair(min_result,max_result); + + ForwardIter potential_max_result = last; + if (comp(first, second)) + max_result = second; + else { + min_result = second; + potential_max_result = second; + } + + first = ++second; if (first != last) ++second; + while (second != last) { + if (comp(first, second)) { + if (!comp(min_result, first)) + min_result = first; + if (!comp(second, max_result)) { + max_result = second; + potential_max_result = last; + } + } else { + if (!comp(min_result, second)) + min_result = second; + if (!comp(first, max_result)) { + max_result = first; + potential_max_result = second; + } + } + first = ++second; + if (first != last) ++second; + } + + if (first != last) { + if (!comp(min_result, first)) + min_result = first; + if (!comp(first, max_result)) { + max_result = first; + potential_max_result = last; + } + } + + if (potential_max_result != last + && !comp(potential_max_result, max_result)) + max_result = potential_max_result; + + return std::make_pair(min_result,max_result); + } + + } // namespace detail + + template + inline std::pair + first_min_first_max_element(ForwardIter first, ForwardIter last) + { + return minmax_element(first, last); + } + + template + inline std::pair + first_min_first_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + return minmax_element(first, last, comp); + } + + template + std::pair + first_min_last_max_element(ForwardIter first, ForwardIter last) + { + return detail::basic_first_min_last_max_element(first, last, + detail::less_over_iter() ); + } + + template + inline std::pair + first_min_last_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + return detail::basic_first_min_last_max_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + template + std::pair + last_min_first_max_element(ForwardIter first, ForwardIter last) + { + return detail::basic_last_min_first_max_element(first, last, + detail::less_over_iter() ); + } + + template + inline std::pair + last_min_first_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + return detail::basic_last_min_first_max_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + + template + std::pair + last_min_last_max_element(ForwardIter first, ForwardIter last) + { + return detail::basic_last_min_last_max_element(first, last, + detail::less_over_iter() ); + } + + template + inline std::pair + last_min_last_max_element(ForwardIter first, ForwardIter last, + BinaryPredicate comp) + { + return detail::basic_last_min_last_max_element(first, last, + detail::binary_pred_over_iter(comp) ); + } + +} // namespace boost + +#endif // BOOST_ALGORITHM_MINMAX_ELEMENT_HPP diff --git a/thirdparty/boost/algorithm/string.hpp b/thirdparty/boost/algorithm/string.hpp new file mode 100644 index 0000000..0c88658 --- /dev/null +++ b/thirdparty/boost/algorithm/string.hpp @@ -0,0 +1,30 @@ +// Boost string_algo library string_algo.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ALGO_HPP +#define BOOST_STRING_ALGO_HPP + +/*! \file + Cumulative include for string_algo library +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif // BOOST_STRING_ALGO_HPP diff --git a/thirdparty/boost/algorithm/string/case_conv.hpp b/thirdparty/boost/algorithm/string/case_conv.hpp new file mode 100644 index 0000000..d246bbb --- /dev/null +++ b/thirdparty/boost/algorithm/string/case_conv.hpp @@ -0,0 +1,176 @@ +// Boost string_algo library case_conv.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CASE_CONV_HPP +#define BOOST_STRING_CASE_CONV_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*! \file + Defines sequence case-conversion algorithms. + Algorithms convert each element in the input sequence to the + desired case using provided locales. +*/ + +namespace boost { + namespace algorithm { + +// to_lower -----------------------------------------------// + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The result is a copy of the input converted to lower case. + It is returned as a sequence or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param Loc A locale used for conversion + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + + */ + template + inline OutputIteratorT + to_lower_copy( + OutputIteratorT Output, + const RangeT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Output, + as_literal(Input), + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + + //! Convert to lower case + /*! + \overload + */ + template + inline SequenceT to_lower_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Input, + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The input sequence is modified in-place. + + \param Input A range + \param Loc a locale used for conversion + */ + template + inline void to_lower( + WritableRangeT& Input, + const std::locale& Loc=std::locale()) + { + ::boost::algorithm::detail::transform_range( + as_literal(Input), + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + +// to_upper -----------------------------------------------// + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The result is a copy of the input converted to upper case. + It is returned as a sequence or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param Loc A locale used for conversion + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT + to_upper_copy( + OutputIteratorT Output, + const RangeT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Output, + as_literal(Input), + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + //! Convert to upper case + /*! + \overload + */ + template + inline SequenceT to_upper_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Input, + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The input sequence is modified in-place. + + \param Input An input range + \param Loc a locale used for conversion + */ + template + inline void to_upper( + WritableRangeT& Input, + const std::locale& Loc=std::locale()) + { + ::boost::algorithm::detail::transform_range( + as_literal(Input), + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::to_lower; + using algorithm::to_lower_copy; + using algorithm::to_upper; + using algorithm::to_upper_copy; + +} // namespace boost + +#endif // BOOST_STRING_CASE_CONV_HPP diff --git a/thirdparty/boost/algorithm/string/classification.hpp b/thirdparty/boost/algorithm/string/classification.hpp new file mode 100644 index 0000000..409ed54 --- /dev/null +++ b/thirdparty/boost/algorithm/string/classification.hpp @@ -0,0 +1,312 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_HPP +#define BOOST_STRING_CLASSIFICATION_HPP + +#include +#include +#include +#include +#include +#include + + +/*! \file + Classification predicates are included in the library to give + some more convenience when using algorithms like \c trim() and \c all(). + They wrap functionality of STL classification functions ( e.g. \c std::isspace() ) + into generic functors. +*/ + +namespace boost { + namespace algorithm { + +// classification functor generator -------------------------------------// + + //! is_classified predicate + /*! + Construct the \c is_classified predicate. This predicate holds if the input is + of specified \c std::ctype category. + + \param Type A \c std::ctype category + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(Type, Loc); + } + + //! is_space predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::space category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_space(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::space, Loc); + } + + //! is_alnum predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alnum category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alnum(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alnum, Loc); + } + + //! is_alpha predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alpha category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alpha(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alpha, Loc); + } + + //! is_cntrl predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::cntrl category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_cntrl(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::cntrl, Loc); + } + + //! is_digit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::digit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_digit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::digit, Loc); + } + + //! is_graph predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::graph category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_graph(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::graph, Loc); + } + + //! is_lower predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::lower category. + + \param Loc A locale used for classification + \return An instance of \c is_classified predicate + */ + inline detail::is_classifiedF + is_lower(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::lower, Loc); + } + + //! is_print predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::print category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_print(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::print, Loc); + } + + //! is_punct predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::punct category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_punct(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::punct, Loc); + } + + //! is_upper predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::upper category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_upper(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::upper, Loc); + } + + //! is_xdigit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::xdigit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_xdigit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::xdigit, Loc); + } + + //! is_any_of predicate + /*! + Construct the \c is_any_of predicate. The predicate holds if the input + is included in the specified set of characters. + + \param Set A set of characters to be recognized + \return An instance of the \c is_any_of predicate + */ + template + inline detail::is_any_ofF< + BOOST_STRING_TYPENAME range_value::type> + is_any_of( const RangeT& Set ) + { + return detail::is_any_ofF< + BOOST_STRING_TYPENAME range_value::type>(as_literal(Set)); + } + + //! is_from_range predicate + /*! + Construct the \c is_from_range predicate. The predicate holds if the input + is included in the specified range. (i.e. From <= Ch <= To ) + + \param From The start of the range + \param To The end of the range + \return An instance of the \c is_from_range predicate + */ + template + inline detail::is_from_rangeF is_from_range(CharT From, CharT To) + { + return detail::is_from_rangeF(From,To); + } + + // predicate combinators ---------------------------------------------------// + + //! predicate 'and' composition predicate + /*! + Construct the \c class_and predicate. This predicate can be used + to logically combine two classification predicates. \c class_and holds, + if both predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_and predicate + */ + template + inline detail::pred_andF + operator&&( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_andF( + *static_cast(&Pred1), + *static_cast(&Pred2) ); + } + + //! predicate 'or' composition predicate + /*! + Construct the \c class_or predicate. This predicate can be used + to logically combine two classification predicates. \c class_or holds, + if one of the predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_or predicate + */ + template + inline detail::pred_orF + operator||( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_orF( + *static_cast(&Pred1), + *static_cast(&Pred2)); + } + + //! predicate negation operator + /*! + Construct the \c class_not predicate. This predicate represents a negation. + \c class_or holds if of the predicates return false. + + \param Pred The predicate to be negated + \return An instance of the \c class_not predicate + */ + template + inline detail::pred_notF + operator!( const predicate_facade& Pred ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_notF(*static_cast(&Pred)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_classified; + using algorithm::is_space; + using algorithm::is_alnum; + using algorithm::is_alpha; + using algorithm::is_cntrl; + using algorithm::is_digit; + using algorithm::is_graph; + using algorithm::is_lower; + using algorithm::is_upper; + using algorithm::is_print; + using algorithm::is_punct; + using algorithm::is_xdigit; + using algorithm::is_any_of; + using algorithm::is_from_range; + +} // namespace boost + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/thirdparty/boost/algorithm/string/compare.hpp b/thirdparty/boost/algorithm/string/compare.hpp new file mode 100644 index 0000000..f610b36 --- /dev/null +++ b/thirdparty/boost/algorithm/string/compare.hpp @@ -0,0 +1,199 @@ +// Boost string_algo library compare.hpp header file -------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_COMPARE_HPP +#define BOOST_STRING_COMPARE_HPP + +#include +#include + +/*! \file + Defines element comparison predicates. Many algorithms in this library can + take an additional argument with a predicate used to compare elements. + This makes it possible, for instance, to have case insensitive versions + of the algorithms. +*/ + +namespace boost { + namespace algorithm { + + // is_equal functor -----------------------------------------------// + + //! is_equal functor + /*! + Standard STL equal_to only handle comparison between arguments + of the same type. This is a less restrictive version which wraps operator ==. + */ + struct is_equal + { + //! Function operator + /*! + Compare two operands for equality + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1==Arg2; + } + }; + + //! case insensitive version of is_equal + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_iequal + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_iequal( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)==std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)==std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_less functor -----------------------------------------------// + + //! is_less functor + /*! + Convenient version of standard std::less. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_less + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1 + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)(Arg1,m_Loc)(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_not_greater functor -----------------------------------------------// + + //! is_not_greater functor + /*! + Convenient version of standard std::not_greater_to. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_not_greater + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1<=Arg2; + } + }; + + + //! case insensitive version of is_not_greater + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_not_igreater + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_not_igreater( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)<=std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)<=std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_equal; + using algorithm::is_iequal; + using algorithm::is_less; + using algorithm::is_iless; + using algorithm::is_not_greater; + using algorithm::is_not_igreater; + +} // namespace boost + + +#endif // BOOST_STRING_COMPARE_HPP diff --git a/thirdparty/boost/algorithm/string/concept.hpp b/thirdparty/boost/algorithm/string/concept.hpp new file mode 100644 index 0000000..cb08b96 --- /dev/null +++ b/thirdparty/boost/algorithm/string/concept.hpp @@ -0,0 +1,83 @@ +// Boost string_algo library concept.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONCEPT_HPP +#define BOOST_STRING_CONCEPT_HPP + +#include +#include +#include +#include + +/*! \file + Defines concepts used in string_algo library +*/ + +namespace boost { + namespace algorithm { + + //! Finder concept + /*! + Defines the Finder concept. Finder is a functor which selects + an arbitrary part of a string. Search is performed on + the range specified by starting and ending iterators. + + Result of the find operation must be convertible to iterator_range. + */ + template + struct FinderConcept + { + private: + typedef iterator_range range; + public: + void constraints() + { + // Operation + r=(*pF)(i,i); + } + private: + range r; + IteratorT i; + FinderT* pF; + }; // Finder_concept + + + //! Formatter concept + /*! + Defines the Formatter concept. Formatter is a functor, which + takes a result from a finder operation and transforms it + in a specific way. + + Result must be a container supported by container_traits, + or a reference to it. + */ + template + struct FormatterConcept + { + public: + void constraints() + { + // Operation + begin((*pFo)( (*pF)(i,i) )); + end((*pFo)( (*pF)(i,i) )); + } + private: + IteratorT i; + FinderT* pF; + FormatterT *pFo; + }; // FormatterConcept; + + } // namespace algorithm +} // namespace boost + + + + +#endif // BOOST_STRING_CONCEPT_HPP diff --git a/thirdparty/boost/algorithm/string/config.hpp b/thirdparty/boost/algorithm/string/config.hpp new file mode 100644 index 0000000..d10c6f5 --- /dev/null +++ b/thirdparty/boost/algorithm/string/config.hpp @@ -0,0 +1,28 @@ +// Boost string_algo library config.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONFIG_HPP +#define BOOST_STRING_CONFIG_HPP + +#include +#include + +#ifdef BOOST_STRING_DEDUCED_TYPENAME +# error "macro already defined!" +#endif + +#define BOOST_STRING_TYPENAME BOOST_DEDUCED_TYPENAME + +// Metrowerks workaround +#if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x +#pragma parse_func_templ off +#endif + +#endif // BOOST_STRING_CONFIG_HPP diff --git a/thirdparty/boost/algorithm/string/constants.hpp b/thirdparty/boost/algorithm/string/constants.hpp new file mode 100644 index 0000000..9022d43 --- /dev/null +++ b/thirdparty/boost/algorithm/string/constants.hpp @@ -0,0 +1,36 @@ +// Boost string_algo library constants.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONSTANTS_HPP +#define BOOST_STRING_CONSTANTS_HPP + +namespace boost { + namespace algorithm { + + //! Token compression mode + /*! + Specifies token compression mode for the token_finder. + */ + enum token_compress_mode_type + { + token_compress_on, //!< Compress adjacent tokens + token_compress_off //!< Do not compress adjacent tokens + }; + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::token_compress_on; + using algorithm::token_compress_off; + +} // namespace boost + +#endif // BOOST_STRING_CONSTANTS_HPP + diff --git a/thirdparty/boost/algorithm/string/detail/case_conv.hpp b/thirdparty/boost/algorithm/string/detail/case_conv.hpp new file mode 100644 index 0000000..84937c9 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/case_conv.hpp @@ -0,0 +1,112 @@ +// Boost string_algo library string_funct.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CASE_CONV_DETAIL_HPP +#define BOOST_STRING_CASE_CONV_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// case conversion functors -----------------------------------------------// + + // a tolower functor + template + struct to_lowerF : public std::unary_function + { + // Constructor + to_lowerF( const std::locale& Loc ) : m_Loc( Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::tolower( Ch); + #else + return std::tolower( Ch, m_Loc ); + #endif + } + private: + const std::locale& m_Loc; + }; + + // a toupper functor + template + struct to_upperF : public std::unary_function + { + // Constructor + to_upperF( const std::locale& Loc ) : m_Loc( Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper( Ch); + #else + return std::toupper( Ch, m_Loc ); + #endif + } + private: + const std::locale& m_Loc; + }; + +// algorithm implementation ------------------------------------------------------------------------- + + // Transform a range + template + OutputIteratorT transform_range_copy( + OutputIteratorT Output, + const RangeT& Input, + FunctorT Functor) + { + return std::transform( + begin(Input), + end(Input), + Output, + Functor); + } + + // Transform a range (in-place) + template + void transform_range( + const RangeT& Input, + FunctorT Functor) + { + std::transform( + begin(Input), + end(Input), + begin(Input), + Functor); + } + + template + inline SequenceT transform_range_copy( + const RangeT& Input, + FunctorT Functor) + { + return SequenceT( + make_transform_iterator( + begin(Input), + Functor), + make_transform_iterator( + end(Input), + Functor)); + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CASE_CONV_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/classification.hpp b/thirdparty/boost/algorithm/string/detail/classification.hpp new file mode 100644 index 0000000..e6b20ba --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/classification.hpp @@ -0,0 +1,198 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP +#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// classification functors -----------------------------------------------// + + // is_classified functor + struct is_classifiedF : + public predicate_facade + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor from a locale + is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : + m_Type(Type), m_Locale(Loc) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL) + template<> + bool operator()( char const Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + #endif + + private: + const std::ctype_base::mask m_Type; + const std::locale m_Locale; + }; + + // is_any_of functor + /* + returns true if the value is from the specified set + */ + template + struct is_any_ofF : + public predicate_facade > + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + template + is_any_ofF( const RangeT& Range ) : + m_Set( begin(Range), end(Range) ) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return m_Set.find(Ch)!=m_Set.end(); + } + + private: + // set cannot operate on const value-type + typedef typename remove_const::type set_value_type; + std::set m_Set; + }; + + // is_from_range functor + /* + returns true if the value is from the specified range. + (i.e. x>=From && x>=To) + */ + template + struct is_from_rangeF : + public predicate_facade< is_from_rangeF > + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return ( m_From <= Ch ) && ( Ch <= m_To ); + } + + private: + CharT m_From; + CharT m_To; + }; + + // class_and composition predicate + template + struct pred_andF : + public predicate_facade< pred_andF > + { + public: + + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_andF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) && m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_or composition predicate + template + struct pred_orF : + public predicate_facade< pred_orF > + { + public: + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_orF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) || m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_not composition predicate + template< typename PredT > + struct pred_notF : + public predicate_facade< pred_notF > + { + public: + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_notF( PredT Pred ) : m_Pred(Pred) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return !m_Pred(Ch); + } + + private: + PredT m_Pred; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/find_format.hpp b/thirdparty/boost/algorithm/string/detail/find_format.hpp new file mode 100644 index 0000000..fc812c5 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/find_format.hpp @@ -0,0 +1,193 @@ +// Boost string_algo library find_format.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_copy (iterator variant) implementation -------------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult ) + { + return find_format_copy_impl2( + Output, + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename OutputIteratorT, + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_const_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + std::copy( begin(Input), end(Input), Output ); + return Output; + } + + // Copy the beginning of the sequence + std::copy( begin(Input), begin(M), Output ); + // Format find result + // Copy formated result + std::copy( begin(M.format_result()), end(M.format_result()), Output ); + // Copy the rest of the sequence + std::copy( M.end(), end(Input), Output ); + + return Output; + } + +// find_format_copy implementation --------------------------------------------------// + + template< + typename InputT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_copy_impl( + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult) + { + return find_format_copy_impl2( + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_copy_impl2( + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_const_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + return InputT( Input ); + } + + InputT Output; + // Copy the beginning of the sequence + insert( Output, end(Output), begin(Input), M.begin() ); + // Copy formated result + insert( Output, end(Output), M.format_result() ); + // Copy the rest of the sequence + insert( Output, end(Output), M.end(), end(Input) ); + + return Output; + } + +// replace implementation ----------------------------------------------------// + + template< + typename InputT, + typename FormatterT, + typename FindResultT > + inline void find_format_impl( + InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult) + { + find_format_impl2( + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_impl2( + InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Search not found - return original sequence + return; + } + + // Replace match + replace( Input, M.begin(), M.end(), M.format_result() ); + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/find_format_all.hpp b/thirdparty/boost/algorithm/string/detail/find_format_all.hpp new file mode 100644 index 0000000..da5bf40 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/find_format_all.hpp @@ -0,0 +1,263 @@ +// Boost string_algo library find_format_all.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_all_copy (iterator variant) implementation ---------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_all_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult ) + { + return find_format_all_copy_impl2( + Output, + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_all_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=begin(Input); + + // Iterate through all matches + while( M ) + { + // Copy the beginning of the sequence + std::copy( LastMatch, M.begin(), Output ); + // Copy formated result + std::copy( begin(M.format_result()), end(M.format_result()), Output ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, end(Input) ); + } + + // Copy the rest of the sequence + std::copy( LastMatch, end(Input), Output ); + + return Output; + } + +// find_format_all_copy implementation ----------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_all_copy_impl( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult) + { + return find_format_all_copy_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_all_copy_impl2( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=begin(Input); + + // Output temporary + InputT Output; + + // Iterate through all matches + while( M ) + { + // Copy the beginning of the sequence + insert( Output, end(Output), LastMatch, M.begin() ); + // Copy formated result + insert( Output, end(Output), M.format_result() ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, end(Input) ); + } + + // Copy the rest of the sequence + insert( Output, end(Output), LastMatch, end(Input) ); + + return Output; + } + +// find_format_all implementation ------------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline void find_format_all_impl( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult) + { + find_format_all_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_all_impl2( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult, + FormatResultT FormatResult) + { + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Instantiate replacement storage + std::deque< + BOOST_STRING_TYPENAME range_value::type> Storage; + + // Initialize replacement iterators + input_iterator_type InsertIt=begin(Input); + input_iterator_type SearchIt=begin(Input); + + while( M ) + { + // process the segment + InsertIt=process_segment( + Storage, + Input, + InsertIt, + SearchIt, + M.begin() ); + + // Adjust search iterator + SearchIt=M.end(); + + // Copy formated replace to the storage + copy_to_storage( Storage, M.format_result() ); + + // Find range for a next match + M=Finder( SearchIt, end(Input) ); + } + + // process the last segment + InsertIt=process_segment( + Storage, + Input, + InsertIt, + SearchIt, + end(Input) ); + + if ( Storage.empty() ) + { + // Truncate input + erase( Input, InsertIt, end(Input) ); + } + else + { + // Copy remaining data to the end of input + insert( Input, end(Input), Storage.begin(), Storage.end() ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/find_format_store.hpp b/thirdparty/boost/algorithm/string/detail/find_format_store.hpp new file mode 100644 index 0000000..fe763c8 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/find_format_store.hpp @@ -0,0 +1,71 @@ +// Boost string_algo library find_format_store.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// temporary format and find result storage --------------------------------// + + template< + typename ForwardIteratorT, + typename FormatterT, + typename FormatResultT > + class find_format_store : + public iterator_range + { + public: + // typedefs + typedef iterator_range base_type; + typedef FormatterT formatter_type; + typedef FormatResultT format_result_type; + + public: + // Construction + find_format_store( + const base_type& FindResult, + const format_result_type& FormatResult, + const formatter_type& Formatter ) : + base_type(FindResult), + m_FormatResult(FormatResult), + m_Formatter(Formatter) {} + + // Assignment + template< typename FindResultT > + find_format_store& operator=( FindResultT FindResult ) + { + iterator_range::operator=(FindResult); + m_FormatResult=m_Formatter(FindResult); + + return *this; + } + + // Retrieve format result + const format_result_type& format_result() + { + return m_FormatResult; + } + + private: + format_result_type m_FormatResult; + const formatter_type& m_Formatter; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/find_iterator.hpp b/thirdparty/boost/algorithm/string/detail/find_iterator.hpp new file mode 100644 index 0000000..e2d27f0 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/find_iterator.hpp @@ -0,0 +1,87 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP +#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_iterator base -----------------------------------------------// + + // Find iterator base + template + class find_iterator_base + { + protected: + // typedefs + typedef IteratorT input_iterator_type; + typedef iterator_range match_type; + typedef function2< + match_type, + input_iterator_type, + input_iterator_type> finder_type; + + protected: + // Protected construction/destruction + + // Default constructor + find_iterator_base() {}; + // Copy construction + find_iterator_base( const find_iterator_base& Other ) : + m_Finder(Other.m_Finder) {} + + // Constructor + template + find_iterator_base( FinderT Finder, int ) : + m_Finder(Finder) {} + + // Destructor + ~find_iterator_base() {} + + // Find operation + match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const + { + if (!m_Finder.empty()) + { + return m_Finder(Begin,End); + } + else + { + return match_type(End,End); + } + } + + // Check + bool is_null() const + { + return m_Finder.empty(); + } + + private: + // Finder + finder_type m_Finder; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/finder.hpp b/thirdparty/boost/algorithm/string/detail/finder.hpp new file mode 100644 index 0000000..c489d96 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/finder.hpp @@ -0,0 +1,646 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_DETAIL_HPP +#define BOOST_STRING_FINDER_DETAIL_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + + +// find first functor -----------------------------------------------// + + // find a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, functor returns + */ + template + struct first_finderF + { + typedef SearchIteratorT search_iterator_type; + + // Construction + template< typename SearchT > + first_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(begin(Search), end(Search)), m_Comp(Comp) {} + first_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=Begin; + OuterIt!=End; + ++OuterIt) + { + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + input_iterator_type InnerIt=OuterIt; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if ( SubstrIt==m_Search.end() ) + return result_type( OuterIt, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find last functor -----------------------------------------------// + + // find the last match a subseqeunce in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct last_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + + // Construction + template< typename SearchT > + last_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(begin(Search), end(Search)), m_Comp(Comp) {} + last_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + if( boost::empty(m_Search) ) + return result_type( End, End ); + + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // forward iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M=first_finder( Begin, End ); + result_type Last=M; + + while( M ) + { + Last=M; + M=first_finder( end(M), End ); + } + + return Last; + } + + // bidirectional iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::bidirectional_iterator_tag ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=End; + OuterIt!=Begin; ) + { + input_iterator_type OuterIt2=--OuterIt; + + input_iterator_type InnerIt=OuterIt2; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if( SubstrIt==m_Search.end() ) + return result_type( OuterIt2, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find n-th functor -----------------------------------------------// + + // find the n-th match of a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct nth_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + typedef last_finderF< + search_iterator_type, + PredicateT> last_finder_type; + + // Construction + template< typename SearchT > + nth_finderF( + const SearchT& Search, + int Nth, + PredicateT Comp) : + m_Search(begin(Search), end(Search)), + m_Nth(Nth), + m_Comp(Comp) {} + nth_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + int Nth, + PredicateT Comp) : + m_Search(SearchBegin, SearchEnd), + m_Nth(Nth), + m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_Nth>=0) + { + return find_forward(Begin, End, m_Nth); + } + else + { + return find_backward(Begin, End, -m_Nth); + } + + } + + private: + // Implementation helpers + template< typename ForwardIteratorT > + iterator_range + find_forward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( Begin, Begin ); + + for( unsigned int n=0; n<=N; ++n ) + { + // find next match + M=first_finder( end(M), End ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + template< typename ForwardIteratorT > + iterator_range + find_backward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + last_finder_type last_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( End, End ); + + for( unsigned int n=1; n<=N; ++n ) + { + // find next match + M=last_finder( Begin, begin(M) ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + + private: + iterator_range m_Search; + int m_Nth; + PredicateT m_Comp; + }; + +// find head/tail implementation helpers ---------------------------// + + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin; + for( + unsigned int Index=0; + Index + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type(Begin,Begin+N); + } + + // Find head implementation + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return find_head_impl( Begin, End, N, category() ); + } + + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + unsigned int Index=0; + input_iterator_type It=Begin; + input_iterator_type It2=Begin; + + // Advance It2 by N increments + for( Index=0; Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::bidirectional_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=End; + for( + unsigned int Index=0; + Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type( End-N, End ); + } + + // Operation + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return find_tail_impl( Begin, End, N, category() ); + } + + + +// find head functor -----------------------------------------------// + + + // find a head in the sequence ( functor ) + /* + This functor find a head of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct head_finderF + { + // Construction + head_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return find_head_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + find_tail_impl( Begin, End, -m_N ); + + return make_iterator_range(Begin, Res.begin()); + } + } + + private: + int m_N; + }; + +// find tail functor -----------------------------------------------// + + + // find a tail in the sequence ( functor ) + /* + This functor find a tail of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct tail_finderF + { + // Construction + tail_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return find_tail_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + find_head_impl( Begin, End, -m_N ); + + return make_iterator_range(Res.end(), End); + } + } + + private: + int m_N; + }; + +// find token functor -----------------------------------------------// + + // find a token in a sequence ( functor ) + /* + This find functor finds a token specified be a predicate + in a sequence. It is equivalent of std::find algorithm, + with an exception that it return range instead of a single + iterator. + + If bCompress is set to true, adjacent matching tokens are + concatenated into one match. + */ + template< typename PredicateT > + struct token_finderF + { + // Construction + token_finderF( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) : + m_Pred(Pred), m_eCompress(eCompress) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + ForwardIteratorT It=std::find_if( Begin, End, m_Pred ); + + if( It==End ) + { + return result_type( End, End ); + } + else + { + ForwardIteratorT It2=It; + + if( m_eCompress==token_compress_on ) + { + // Find first non-matching character + while( It2!=End && m_Pred(*It2) ) ++It2; + } + else + { + // Advance by one position + ++It2; + } + + return result_type( It, It2 ); + } + } + + private: + PredicateT m_Pred; + token_compress_mode_type m_eCompress; + }; + +// find range functor -----------------------------------------------// + + // find a range in the sequence ( functor ) + /* + This functor actually does not perform any find operation. + It always returns given iterator range as a result. + */ + template + struct range_finderF + { + typedef ForwardIterator1T input_iterator_type; + typedef iterator_range result_type; + + // Construction + range_finderF( + input_iterator_type Begin, + input_iterator_type End ) : m_Range(Begin, End) {} + + range_finderF(const iterator_range& Range) : + m_Range(Range) {} + + // Operation + template< typename ForwardIterator2T > + iterator_range + operator()( + ForwardIterator2T, + ForwardIterator2T ) const + { +#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) + return iterator_range(this->m_Range); +#elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + return iterator_range(m_Range.begin(), m_Range.end()); +#else + return m_Range; +#endif + } + + private: + iterator_range m_Range; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FINDER_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/finder_regex.hpp b/thirdparty/boost/algorithm/string/detail/finder_regex.hpp new file mode 100644 index 0000000..fdf0da0 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/finder_regex.hpp @@ -0,0 +1,122 @@ +// Boost string_algo library find_regex.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_REGEX_DETAIL_HPP +#define BOOST_STRING_FINDER_REGEX_DETAIL_HPP + +#include +#include + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// regex find functor -----------------------------------------------// + + // regex search result + template + struct regex_search_result : + public iterator_range + { + typedef regex_search_result type; + typedef iterator_range base_type; + typedef BOOST_STRING_TYPENAME base_type::value_type value_type; + typedef BOOST_STRING_TYPENAME base_type::difference_type difference_type; + typedef BOOST_STRING_TYPENAME base_type::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME base_type::iterator iterator; + typedef boost::match_results match_results_type; + + // Construction + + // Construction from the match result + regex_search_result( const match_results_type& MatchResults ) : + base_type( MatchResults[0].first, MatchResults[0].second ), + m_MatchResults( MatchResults ) {} + + // Construction of empty match. End iterator has to be specified + regex_search_result( IteratorT End ) : + base_type( End, End ) {} + + regex_search_result( const regex_search_result& Other ) : + base_type( Other.begin(), Other.end() ), + m_MatchResults( Other.m_MatchResults ) {} + + // Assignment + regex_search_result& operator=( const regex_search_result& Other ) + { + base_type::operator=( Other ); + m_MatchResults=Other.m_MatchResults; + return *this; + } + + // Match result retrival + const match_results_type& match_results() const + { + return m_MatchResults; + } + + private: + // Saved matchresult + match_results_type m_MatchResults; + }; + + // find_regex + /* + Regex based search functor + */ + template + struct find_regexF + { + typedef RegExT regex_type; + typedef const RegExT& regex_reference_type; + + // Construction + find_regexF( regex_reference_type Rx, match_flag_type MatchFlags = match_default ) : + m_Rx(Rx), m_MatchFlags(MatchFlags) {} + + // Operation + template< typename ForwardIteratorT > + regex_search_result + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef regex_search_result result_type; + + // instantiate match result + match_results result; + // search for a match + if ( regex_search( Begin, End, result, m_Rx, m_MatchFlags ) ) + { + // construct a result + return result_type( result ); + } + else + { + // empty result + return result_type( End ); + } + } + + private: + regex_reference_type m_Rx; // Regexp + match_flag_type m_MatchFlags; // match flags + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/formatter.hpp b/thirdparty/boost/algorithm/string/detail/formatter.hpp new file mode 100644 index 0000000..31456be --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/formatter.hpp @@ -0,0 +1,94 @@ +// Boost string_algo library formatter.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FORMATTER_DETAIL_HPP +#define BOOST_STRING_FORMATTER_DETAIL_HPP + + +#include +#include +#include +#include + +#include + +// generic replace functors -----------------------------------------------// + +namespace boost { + namespace algorithm { + namespace detail { + +// const format functor ----------------------------------------------------// + + // constant format functor + template + struct const_formatF + { + private: + typedef BOOST_STRING_TYPENAME + range_const_iterator::type format_iterator; + typedef iterator_range result_type; + + public: + // Construction + const_formatF(const RangeT& Format) : + m_Format(begin(Format), end(Format)) {} + + // Operation +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template + result_type& operator()(const Range2T&) + { + return m_Format; + } +#endif + + template + const result_type& operator()(const Range2T&) const + { + return m_Format; + } + + private: + result_type m_Format; + }; + +// identity format functor ----------------------------------------------------// + + // identity format functor + template + struct identity_formatF + { + // Operation + template< typename Range2T > + const RangeT& operator()(const Range2T& Replace) const + { + return RangeT(begin(Replace), end(Replace)); + } + }; + +// empty format functor ( used by erase ) ------------------------------------// + + // empty format functor + template< typename CharT > + struct empty_formatF + { + template< typename ReplaceT > + empty_container operator()(const ReplaceT&) const + { + return empty_container(); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FORMATTER_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/formatter_regex.hpp b/thirdparty/boost/algorithm/string/detail/formatter_regex.hpp new file mode 100644 index 0000000..20ebc96 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/formatter_regex.hpp @@ -0,0 +1,61 @@ +// Boost string_algo library formatter_regex.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP +#define BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// regex format functor -----------------------------------------// + + // regex format functor + template + struct regex_formatF + { + private: + typedef StringT result_type; + typedef BOOST_STRING_TYPENAME StringT::value_type char_type; + + public: + // Construction + regex_formatF( const StringT& Fmt, match_flag_type Flags=format_default ) : + m_Fmt(Fmt), m_Flags( Flags ) {} + + template + result_type operator()( + const regex_search_result& Replace ) const + { + if ( Replace.empty() ) + { + return result_type(); + } + else + { + return Replace.match_results().format( m_Fmt, m_Flags ); + } + } + private: + const StringT& m_Fmt; + match_flag_type m_Flags; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FORMATTER_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/predicate.hpp b/thirdparty/boost/algorithm/string/detail/predicate.hpp new file mode 100644 index 0000000..ef7eb87 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/predicate.hpp @@ -0,0 +1,77 @@ +// Boost string_algo library predicate.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_DETAIL_HPP +#define BOOST_STRING_PREDICATE_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// ends_with predicate implementation ----------------------------------// + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::bidirectional_iterator_tag) + { + ForwardIterator1T it=End; + ForwardIterator2T pit=SubEnd; + for(;it!=Begin && pit!=SubBegin;) + { + if( !(Comp(*(--it),*(--pit))) ) + return false; + } + + return pit==SubBegin; + } + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::forward_iterator_tag) + { + if ( SubBegin==SubEnd ) + { + // empty subsequence check + return true; + } + + iterator_range Result + =last_finder( + make_iterator_range(SubBegin, SubEnd), + Comp)(Begin, End); + + return !Result.empty() && Result.end()==End; + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/replace_storage.hpp b/thirdparty/boost/algorithm/string/detail/replace_storage.hpp new file mode 100644 index 0000000..11b047e --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/replace_storage.hpp @@ -0,0 +1,159 @@ +// Boost string_algo library replace_storage.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP +#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// storage handling routines -----------------------------------------------// + + template< typename StorageT, typename OutputIteratorT > + inline OutputIteratorT move_from_storage( + StorageT& Storage, + OutputIteratorT DestBegin, + OutputIteratorT DestEnd ) + { + OutputIteratorT OutputIt=DestBegin; + + while( !Storage.empty() && OutputIt!=DestEnd ) + { + *OutputIt=Storage.front(); + Storage.pop_front(); + ++OutputIt; + } + + return OutputIt; + } + + template< typename StorageT, typename WhatT > + inline void copy_to_storage( + StorageT& Storage, + const WhatT& What ) + { + Storage.insert( Storage.end(), begin(What), end(What) ); + } + + +// process segment routine -----------------------------------------------// + + template< bool HasStableIterators > + struct process_segment_helper + { + // Optimized version of process_segment for generic sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& /*Input*/, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + // Copy data from the storage until the beginning of the segment + ForwardIteratorT It=move_from_storage( Storage, InsertIt, SegmentBegin ); + + // 3 cases are possible : + // a) Storage is empty, It==SegmentBegin + // b) Storage is empty, It!=SegmentBegin + // c) Storage is not empty + + if( Storage.empty() ) + { + if( It==SegmentBegin ) + { + // Case a) everything is grand, just return end of segment + return SegmentEnd; + } + else + { + // Case b) move the segment backwards + return std::copy( SegmentBegin, SegmentEnd, It ); + } + } + else + { + // Case c) -> shift the segment to the left and keep the overlap in the storage + while( It!=SegmentEnd ) + { + // Store value into storage + Storage.push_back( *It ); + // Get the top from the storage and put it here + *It=Storage.front(); + Storage.pop_front(); + + // Advance + ++It; + } + + return It; + } + } + }; + + template<> + struct process_segment_helper< true > + { + // Optimized version of process_segment for list-like sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + + { + // Call replace to do the job + replace( Input, InsertIt, SegmentBegin, Storage ); + // Empty the storage + Storage.clear(); + // Iterators were not changed, simply return the end of segment + return SegmentEnd; + } + }; + + // Process one segment in the replace_all algorithm + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + inline ForwardIteratorT process_segment( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + return + process_segment_helper< + has_stable_iterators::value>()( + Storage, Input, InsertIt, SegmentBegin, SegmentEnd ); + } + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/sequence.hpp b/thirdparty/boost/algorithm/string/detail/sequence.hpp new file mode 100644 index 0000000..4eca9e4 --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/sequence.hpp @@ -0,0 +1,200 @@ +// Boost string_algo library sequence.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP +#define BOOST_STRING_DETAIL_SEQUENCE_HPP + +#include +#include +#include +#include +#include + +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// insert helpers -------------------------------------------------// + + template< typename InputT, typename ForwardIteratorT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.insert( At, Begin, End ); + } + + template< typename InputT, typename InsertT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + const InsertT& Insert ) + { + insert( Input, At, begin(Insert), end(Insert) ); + } + +// erase helper ---------------------------------------------------// + + // Erase a range in the sequence + /* + Returns the iterator pointing just after the erase subrange + */ + template< typename InputT > + inline typename InputT::iterator erase( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To ) + { + return Input.erase( From, To ); + } + +// replace helper implementation ----------------------------------// + + // Optimized version of replace for generic sequence containers + // Assumption: insert and erase are expensive + template< bool HasConstTimeOperations > + struct replace_const_time_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + // Copy data to the container ( as much as possible ) + ForwardIteratorT InsertIt=Begin; + BOOST_STRING_TYPENAME InputT::iterator InputIt=From; + for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ ) + { + *InputIt=*InsertIt; + } + + if ( InsertIt!=End ) + { + // Replace sequence is longer, insert it + Input.insert( InputIt, InsertIt, End ); + } + else + { + if ( InputIt!=To ) + { + // Replace sequence is shorter, erase the rest + Input.erase( InputIt, To ); + } + } + } + }; + + template<> + struct replace_const_time_helper< true > + { + // Const-time erase and insert methods -> use them + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To ); + if ( Begin!=End ) + { + if(!Input.empty()) + { + Input.insert( At, Begin, End ); + } + else + { + Input.insert( Input.begin(), Begin, End ); + } + } + } + }; + + // No native replace method + template< bool HasNative > + struct replace_native_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_const_time_helper< + boost::mpl::and_< + has_const_time_insert, + has_const_time_erase >::value >()( + Input, From, To, Begin, End ); + } + }; + + // Container has native replace method + template<> + struct replace_native_helper< true > + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.replace( From, To, Begin, End ); + } + }; + +// replace helper -------------------------------------------------// + + template< typename InputT, typename ForwardIteratorT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_native_helper< has_native_replace::value >()( + Input, From, To, Begin, End ); + } + + template< typename InputT, typename InsertT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + const InsertT& Insert ) + { + if(From!=To) + { + replace( Input, From, To, begin(Insert), end(Insert) ); + } + else + { + insert( Input, From, begin(Insert), end(Insert) ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_DETAIL_SEQUENCE_HPP diff --git a/thirdparty/boost/algorithm/string/detail/trim.hpp b/thirdparty/boost/algorithm/string/detail/trim.hpp new file mode 100644 index 0000000..1d7f03a --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/trim.hpp @@ -0,0 +1,95 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_DETAIL_HPP +#define BOOST_STRING_TRIM_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// trim iterator helper -----------------------------------------------// + + // Search for first non matching character from the beginning of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_begin( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + ForwardIteratorT It=InBegin; + for(; It!=InEnd; ++It ) + { + if (!IsSpace(*It)) + return It; + } + + return It; + } + + // Search for first non matching character from the end of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return trim_end_iter_select( InBegin, InEnd, IsSpace, category() ); + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::forward_iterator_tag ) + { + ForwardIteratorT TrimIt=InBegin; + + for( ForwardIteratorT It=InBegin; It!=InEnd; ++It ) + { + if ( !IsSpace(*It) ) + { + TrimIt=It; + ++TrimIt; + } + } + + return TrimIt; + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::bidirectional_iterator_tag ) + { + for( ForwardIteratorT It=InEnd; It!=InBegin; ) + { + if ( !IsSpace(*(--It)) ) + return ++It; + } + + return InBegin; + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_TRIM_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/detail/util.hpp b/thirdparty/boost/algorithm/string/detail/util.hpp new file mode 100644 index 0000000..8e03a5d --- /dev/null +++ b/thirdparty/boost/algorithm/string/detail/util.hpp @@ -0,0 +1,106 @@ +// Boost string_algo library util.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_UTIL_DETAIL_HPP +#define BOOST_STRING_UTIL_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// empty container -----------------------------------------------// + + // empty_container + /* + This class represents always empty container, + containing elements of type CharT. + + It is supposed to be used in a const version only + */ + template< typename CharT > + struct empty_container + { + typedef empty_container type; + typedef CharT value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type& reference; + typedef const value_type& const_reference; + typedef const value_type* iterator; + typedef const value_type* const_iterator; + + + // Operations + const_iterator begin() const + { + return reinterpret_cast(0); + } + + const_iterator end() const + { + return reinterpret_cast(0); + } + + bool empty() const + { + return false; + } + + size_type size() const + { + return 0; + } + }; + +// bounded copy algorithm -----------------------------------------------// + + // Bounded version of the std::copy algorithm + template + inline OutputIteratorT bounded_copy( + InputIteratorT First, + InputIteratorT Last, + OutputIteratorT DestFirst, + OutputIteratorT DestLast ) + { + InputIteratorT InputIt=First; + OutputIteratorT OutputIt=DestFirst; + for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ ) + { + *OutputIt=*InputIt; + } + + return OutputIt; + } + +// iterator range utilities -----------------------------------------// + + // copy range functor + template< + typename SeqT, + typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > + struct copy_iterator_rangeF : + public std::unary_function< iterator_range, SeqT > + { + SeqT operator()( const iterator_range& Range ) const + { + return copy_range(Range); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_UTIL_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/erase.hpp b/thirdparty/boost/algorithm/string/erase.hpp new file mode 100644 index 0000000..569ee65 --- /dev/null +++ b/thirdparty/boost/algorithm/string/erase.hpp @@ -0,0 +1,844 @@ +// Boost string_algo library erase.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ERASE_HPP +#define BOOST_STRING_ERASE_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines various erase algorithms. Each algorithm removes + part(s) of the input according to a searching criteria. +*/ + +namespace boost { + namespace algorithm { + +// erase_range -------------------------------------------------------// + + //! Erase range algorithm + /*! + Remove the given range from the input. The result is a modified copy of + the input. It is returned as a sequence or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param SearchRange A range in the input to be removed + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT erase_range_copy( + OutputIteratorT Output, + const RangeT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange ) + { + return find_format_copy( + Output, + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + \overload + */ + template + inline SequenceT erase_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange ) + { + return find_format_copy( + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + Remove the given range from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param SearchRange A range in the input to be removed + */ + template + inline void erase_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_iterator::type>& SearchRange ) + { + find_format( + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + +// erase_first --------------------------------------------------------// + + //! Erase first algorithm + /*! + Remove the first occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return find_format_copy( + Output, + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + \overload + */ + template + inline SequenceT erase_first_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return find_format_copy( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + Remove the first occurrence of the substring from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + */ + template + inline void erase_first( + SequenceT& Input, + const RangeT& Search ) + { + find_format( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + +// erase_first ( case insensitive ) ------------------------------------// + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_first_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first occurrence of the substring from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_first( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_last --------------------------------------------------------// + + //! Erase last algorithm + /*! + Remove the last occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return find_format_copy( + Output, + Input, + last_finder(Search), + empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + \overload + */ + template + inline SequenceT erase_last_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return find_format_copy( + Input, + last_finder(Search), + empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + Remove the last occurrence of the substring from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + */ + template + inline void erase_last( + SequenceT& Input, + const RangeT& Search ) + { + find_format( + Input, + last_finder(Search), + empty_formatter(Input) ); + } + +// erase_last ( case insensitive ) ------------------------------------// + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_last_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last occurrence of the substring from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_last( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_nth --------------------------------------------------------------------// + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + \overload + */ + template + inline SequenceT erase_nth_copy( + const SequenceT& Input, + const RangeT& Search, + int Nth ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + */ + template + inline void erase_nth( + SequenceT& Input, + const RangeT& Search, + int Nth ) + { + find_format( + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + +// erase_nth ( case insensitive ) ---------------------------------------------// + + //! Erase nth algorithm ( case insensitive ) + /*! + Remove the Nth occurrence of the substring in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + \overload + */ + template + inline SequenceT ierase_nth_copy( + const SequenceT& Input, + const RangeT& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_nth( + SequenceT& Input, + const RangeT& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + +// erase_all --------------------------------------------------------// + + //! Erase all algorithm + /*! + Remove all the occurrences of the string from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Search A substring to be searched for. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + \overload + */ + template + inline SequenceT erase_all_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return find_format_all_copy( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + Remove all the occurrences of the string from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + */ + template + inline void erase_all( + SequenceT& Input, + const RangeT& Search ) + { + find_format_all( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + +// erase_all ( case insensitive ) ------------------------------------// + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the string from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_all_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the string from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_all( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + find_format_all( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_head --------------------------------------------------------------------// + + //! Erase head algorithm + /*! + Remove the head from the input. The head is a prefix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The result is a modified copy of the input. + It is returned as a sequence or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT> + inline OutputIteratorT erase_head_copy( + OutputIteratorT Output, + const RangeT& Input, + int N ) + { + return find_format_copy( + Output, + Input, + head_finder(N), + empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + \overload + */ + template + inline SequenceT erase_head_copy( + const SequenceT& Input, + int N ) + { + return find_format_copy( + Input, + head_finder(N), + empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + Remove the head from the input. The head is a prefix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the head + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + */ + template + inline void erase_head( + SequenceT& Input, + int N ) + { + find_format( + Input, + head_finder(N), + empty_formatter( Input ) ); + } + +// erase_tail --------------------------------------------------------------------// + + //! Erase tail algorithm + /*! + Remove the tail from the input. The tail is a suffix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT> + inline OutputIteratorT erase_tail_copy( + OutputIteratorT Output, + const RangeT& Input, + int N ) + { + return find_format_copy( + Output, + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + \overload + */ + template + inline SequenceT erase_tail_copy( + const SequenceT& Input, + int N ) + { + return find_format_copy( + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + Remove the tail from the input. The tail is a suffix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the head + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + */ + template + inline void erase_tail( + SequenceT& Input, + int N ) + { + find_format( + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + } // namespace algorithm + + // pull names into the boost namespace + using algorithm::erase_range_copy; + using algorithm::erase_range; + using algorithm::erase_first_copy; + using algorithm::erase_first; + using algorithm::ierase_first_copy; + using algorithm::ierase_first; + using algorithm::erase_last_copy; + using algorithm::erase_last; + using algorithm::ierase_last_copy; + using algorithm::ierase_last; + using algorithm::erase_nth_copy; + using algorithm::erase_nth; + using algorithm::ierase_nth_copy; + using algorithm::ierase_nth; + using algorithm::erase_all_copy; + using algorithm::erase_all; + using algorithm::ierase_all_copy; + using algorithm::ierase_all; + using algorithm::erase_head_copy; + using algorithm::erase_head; + using algorithm::erase_tail_copy; + using algorithm::erase_tail; + +} // namespace boost + + +#endif // BOOST_ERASE_HPP diff --git a/thirdparty/boost/algorithm/string/find.hpp b/thirdparty/boost/algorithm/string/find.hpp new file mode 100644 index 0000000..e0df8ec --- /dev/null +++ b/thirdparty/boost/algorithm/string/find.hpp @@ -0,0 +1,334 @@ +// Boost string_algo library find.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_HPP +#define BOOST_STRING_FIND_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines a set of find algorithms. The algorithms are searching + for a substring of the input. The result is given as an \c iterator_range + delimiting the substring. +*/ + +namespace boost { + namespace algorithm { + +// Generic find -----------------------------------------------// + + //! Generic find algorithm + /*! + Search the input using the given finder. + + \param Input A string which will be searched. + \param Finder Finder object used for searching. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find( + RangeT& Input, + const FinderT& Finder) + { + iterator_range::type> lit_input(as_literal(Input)); + + return Finder(begin(lit_input),end(lit_input)); + } + +// find_first -----------------------------------------------// + + //! Find first algorithm + /*! + Search for the first occurrence of the substring in the input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_first( + Range1T& Input, + const Range2T& Search) + { + return find(Input, first_finder(Search)); + } + + //! Find first algorithm ( case insensitive ) + /*! + Search for the first occurence of the substring in the input. + Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_first( + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale()) + { + return find(Input, first_finder(Search,is_iequal(Loc))); + } + +// find_last -----------------------------------------------// + + //! Find last algorithm + /*! + Search for the last occurrence of the substring in the input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_last( + Range1T& Input, + const Range2T& Search) + { + return find(Input, last_finder(Search)); + } + + //! Find last algorithm ( case insensitive ) + /*! + Search for the last match a string in the input. + Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_last( + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale()) + { + return find(Input, last_finder(Search, is_iequal(Loc))); + } + +// find_nth ----------------------------------------------------------------------// + + //! Find n-th algorithm + /*! + Search for the n-th (zero-indexed) occurrence of the substring in the + input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Nth An index (zero-indexed) of the match to be found. + For negative N, the matches are counted from the end of string. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_nth( + Range1T& Input, + const Range2T& Search, + int Nth) + { + return find(Input, nth_finder(Search,Nth)); + } + + //! Find n-th algorithm ( case insensitive ). + /*! + Search for the n-th (zero-indexed) occurrence of the substring in the + input. Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Nth An index (zero-indexed) of the match to be found. + For negative N, the matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_nth( + Range1T& Input, + const Range2T& Search, + int Nth, + const std::locale& Loc=std::locale()) + { + return find(Input, nth_finder(Search,Nth,is_iequal(Loc))); + } + +// find_head ----------------------------------------------------------------------// + + //! Find head algorithm + /*! + Get the head of the input. Head is a prefix of the string of the + given size. If the input is shorter then required, whole input if considered + to be the head. + + \param Input An input string + \param N Length of the head + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_head( + RangeT& Input, + int N) + { + return find(Input, head_finder(N)); + } + +// find_tail ----------------------------------------------------------------------// + + //! Find tail algorithm + /*! + Get the head of the input. Head is a suffix of the string of the + given size. If the input is shorter then required, whole input if considered + to be the tail. + + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_tail( + RangeT& Input, + int N) + { + return find(Input, tail_finder(N)); + } + +// find_token --------------------------------------------------------------------// + + //! Find token algorithm + /*! + Look for a given token in the string. Token is a character that matches the + given predicate. + If the "token compress mode" is enabled, adjacent tokens are considered to be one match. + + \param Input A input string. + \param Pred An unary predicate to identify a token + \param eCompress Enable/Disable compressing of adjacent tokens + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_token( + RangeT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off) + { + return find(Input, token_finder(Pred, eCompress)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find; + using algorithm::find_first; + using algorithm::ifind_first; + using algorithm::find_last; + using algorithm::ifind_last; + using algorithm::find_nth; + using algorithm::ifind_nth; + using algorithm::find_head; + using algorithm::find_tail; + using algorithm::find_token; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_HPP diff --git a/thirdparty/boost/algorithm/string/find_format.hpp b/thirdparty/boost/algorithm/string/find_format.hpp new file mode 100644 index 0000000..541dc45 --- /dev/null +++ b/thirdparty/boost/algorithm/string/find_format.hpp @@ -0,0 +1,269 @@ +// Boost string_algo library find_format.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_HPP +#define BOOST_STRING_FIND_FORMAT_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines generic replace algorithms. Each algorithm replaces + part(s) of the input. The part to be replaced is looked up using a Finder object. + Result of finding is then used by a Formatter object to generate the replacement. +*/ + +namespace boost { + namespace algorithm { + +// generic replace -----------------------------------------------------------------// + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_copy( + OutputIteratorT Output, + const RangeT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + iterator_range::type> lit_input(as_literal(Input)); + + return detail::find_format_copy_impl( + Output, + lit_input, + Formatter, + Finder( begin(lit_input), end(lit_input) ) ); + } + + //! Generic replace algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline SequenceT find_format_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + return detail::find_format_copy_impl( + Input, + Formatter, + Finder(begin(Input), end(Input))); + } + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline void find_format( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + detail::find_format_impl( + Input, + Formatter, + Finder(begin(Input), end(Input))); + } + + +// find_format_all generic ----------------------------------------------------------------// + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_all_copy( + OutputIteratorT Output, + const RangeT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + iterator_range::type> lit_input(as_literal(Input)); + + return detail::find_format_all_copy_impl( + Output, + lit_input, + Finder, + Formatter, + Finder(begin(lit_input), end(lit_input))); + } + + //! Generic replace all algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline SequenceT find_format_all_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + return detail::find_format_all_copy_impl( + Input, + Finder, + Formatter, + Finder( begin(Input), end(Input) ) ); + } + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings.The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline void find_format_all( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> >(); + + detail::find_format_all_impl( + Input, + Finder, + Formatter, + Finder(begin(Input), end(Input))); + + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::find_format_copy; + using algorithm::find_format; + using algorithm::find_format_all_copy; + using algorithm::find_format_all; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_FORMAT_HPP diff --git a/thirdparty/boost/algorithm/string/find_iterator.hpp b/thirdparty/boost/algorithm/string/find_iterator.hpp new file mode 100644 index 0000000..a66ba90 --- /dev/null +++ b/thirdparty/boost/algorithm/string/find_iterator.hpp @@ -0,0 +1,387 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_HPP +#define BOOST_STRING_FIND_ITERATOR_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/*! \file + Defines find iterator classes. Find iterator repeatly applies a Finder + to the specified input string to search for matches. Dereferencing + the iterator yields the current match or a range between the last and the current + match depending on the iterator used. +*/ + +namespace boost { + namespace algorithm { + +// find_iterator -----------------------------------------------// + + //! find_iterator + /*! + Find iterator encapsulates a Finder and allows + for incremental searching in a string. + Each increment moves the iterator to the next match. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class find_iterator : + public iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + // base type + typedef iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag> facade_type; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + find_iterator() {} + + //! Copy constructor + /*! + Construct a copy of the find_iterator + */ + find_iterator( const find_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_End(Other.m_End) {} + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_End(End) + { + increment(); + } + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0) + { + iterator_range::type> lit_col(as_literal(Col)); + m_Match=make_iterator_range(begin(lit_col), begin(lit_col)); + m_End=end(lit_col); + + increment(); + } + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + m_Match=this->do_find(m_Match.end(),m_End); + } + + // comparison + bool equal( const find_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return + this->is_null() || + ( + m_Match.begin() == m_End && + m_Match.end() == m_End + ); + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_End; + }; + + //! find iterator construction helper + /*! + * Construct a find iterator to iterate through the specified string + */ + template + inline find_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_find_iterator( + RangeT& Collection, + FinderT Finder) + { + return find_iterator::type>( + Collection, Finder); + } + +// split iterator -----------------------------------------------// + + //! split_iterator + /*! + Split iterator encapsulates a Finder and allows + for incremental searching in a string. + Unlike the find iterator, split iterator iterates + through gaps between matches. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class split_iterator : + public iterator_facade< + split_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + // base type + typedef iterator_facade< + find_iterator, + iterator_range, + forward_traversal_tag> facade_type; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + split_iterator() {} + //! Copy constructor + /*! + Construct a copy of the split_iterator + */ + split_iterator( const split_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_Next(Other.m_Next), + m_End(Other.m_End), + m_bEof(false) + {} + + //! Constructor + /*! + Construct new split_iterator for a given finder + and a range. + */ + template + split_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_Next(Begin), + m_End(End), + m_bEof(false) + { + increment(); + } + //! Constructor + /*! + Construct new split_iterator for a given finder + and a collection. + */ + template + split_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_bEof(false) + { + iterator_range::type> lit_col(as_literal(Col)); + m_Match=make_iterator_range(begin(lit_col), begin(lit_col)); + m_Next=begin(lit_col); + m_End=end(lit_col); + + increment(); + } + + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + match_type FindMatch=this->do_find( m_Next, m_End ); + + if(FindMatch.begin()==m_End && FindMatch.end()==m_End) + { + if(m_Match.end()==m_End) + { + // Mark iterator as eof + m_bEof=true; + } + } + + m_Match=match_type( m_Next, FindMatch.begin() ); + m_Next=FindMatch.end(); + } + + // comparison + bool equal( const split_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_Next==Other.m_Next && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return this->is_null() || m_bEof; + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_Next; + input_iterator_type m_End; + bool m_bEof; + }; + + //! split iterator construction helper + /*! + * Construct a split iterator to iterate through the specified collection + */ + template + inline split_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_split_iterator( + RangeT& Collection, + FinderT Finder) + { + return split_iterator::type>( + Collection, Finder); + } + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_iterator; + using algorithm::make_find_iterator; + using algorithm::split_iterator; + using algorithm::make_split_iterator; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_HPP diff --git a/thirdparty/boost/algorithm/string/finder.hpp b/thirdparty/boost/algorithm/string/finder.hpp new file mode 100644 index 0000000..6c60648 --- /dev/null +++ b/thirdparty/boost/algorithm/string/finder.hpp @@ -0,0 +1,270 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_HPP +#define BOOST_STRING_FINDER_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines Finder generators. Finder object is a functor which is able to + find a substring matching a specific criteria in the input. + Finders are used as a pluggable components for replace, find + and split facilities. This header contains generator functions + for finders provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// Finder generators ------------------------------------------// + + //! "First" finder + /*! + Construct the \c first_finder. The finder searches for the first + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c first_finder object + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + first_finder( const RangeT& Search ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( as_literal(Search), is_equal() ) ; + } + + //! "First" finder + /*! + \overload + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + first_finder( + const RangeT& Search, PredicateT Comp ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( as_literal(Search), Comp ); + } + + //! "Last" finder + /*! + Construct the \c last_finder. The finder searches for the last + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c last_finder object + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + last_finder( const RangeT& Search ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( as_literal(Search), is_equal() ); + } + //! "Last" finder + /*! + \overload + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + last_finder( const RangeT& Search, PredicateT Comp ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( as_literal(Search), Comp ) ; + } + + //! "Nth" finder + /*! + Construct the \c nth_finder. The finder searches for the n-th (zero-indexed) + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Nth An index of the match to be find + \param Comp An element comparison predicate + \return An instance of the \c nth_finder object + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + nth_finder( + const RangeT& Search, + int Nth) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( as_literal(Search), Nth, is_equal() ) ; + } + //! "Nth" finder + /*! + \overload + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + nth_finder( + const RangeT& Search, + int Nth, + PredicateT Comp ) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( as_literal(Search), Nth, Comp ); + } + + //! "Head" finder + /*! + Construct the \c head_finder. The finder returns a head of a given + input. The head is a prefix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c head_finder object + */ + inline detail::head_finderF + head_finder( int N ) + { + return detail::head_finderF(N); + } + + //! "Tail" finder + /*! + Construct the \c tail_finder. The finder returns a tail of a given + input. The tail is a suffix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c tail_finder object + */ + inline detail::tail_finderF + tail_finder( int N ) + { + return detail::tail_finderF(N); + } + + //! "Token" finder + /*! + Construct the \c token_finder. The finder searches for a token + specified by a predicate. It is similar to std::find_if + algorithm, with an exception that it return a range of + instead of a single iterator. + + If "compress token mode" is enabled, adjacent matching tokens are + concatenated into one match. Thus the finder can be used to + search for continuous segments of characters satisfying the + given predicate. + + The result is given as an \c iterator_range delimiting the match. + + \param Pred An element selection predicate + \param eCompress Compress flag + \return An instance of the \c token_finder object + */ + template< typename PredicateT > + inline detail::token_finderF + token_finder( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return detail::token_finderF( Pred, eCompress ); + } + + //! "Range" finder + /*! + Construct the \c range_finder. The finder does not perform + any operation. It simply returns the given range for + any input. + + \param Begin Beginning of the range + \param End End of the range + \param Range The range. + \return An instance of the \c range_finger object + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + return detail::range_finderF( Begin, End ); + } + + //! "Range" finder + /*! + \overload + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( iterator_range Range ) + { + return detail::range_finderF( Range ); + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::first_finder; + using algorithm::last_finder; + using algorithm::nth_finder; + using algorithm::head_finder; + using algorithm::tail_finder; + using algorithm::token_finder; + using algorithm::range_finder; + +} // namespace boost + + +#endif // BOOST_STRING_FINDER_HPP diff --git a/thirdparty/boost/algorithm/string/formatter.hpp b/thirdparty/boost/algorithm/string/formatter.hpp new file mode 100644 index 0000000..38eda1d --- /dev/null +++ b/thirdparty/boost/algorithm/string/formatter.hpp @@ -0,0 +1,103 @@ +// Boost string_algo library formatter.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FORMATTER_HPP +#define BOOST_STRING_FORMATTER_HPP + +#include +#include +#include +#include + +#include + +/*! \file + Defines Formatter generators. Formatter is a functor which formats + a string according to given parameters. A Formatter works + in conjunction with a Finder. A Finder can provide additional information + for a specific Formatter. An example of such a cooperation is regex_finder + and regex_formatter. + + Formatters are used as pluggable components for replace facilities. + This header contains generator functions for the Formatters provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// generic formatters ---------------------------------------------------------------// + + //! Constant formatter + /*! + Construct the \c const_formatter. Const formatter always returns + the same value, regardless of the parameter. + + \param Format A predefined value used as a result for formating + \return An instance of the \c const_formatter object. + */ + template + inline detail::const_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> > + const_formatter(const RangeT& Format) + { + return detail::const_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> >(as_literal(Format)); + } + + //! Identity formatter + /*! + Construct the \c identity_formatter. Identity formatter always returns + the parameter. + + \return An instance of the \c identity_formatter object. + */ + template + inline detail::identity_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> > + identity_formatter() + { + return detail::identity_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> >(); + } + + //! Empty formatter + /*! + Construct the \c empty_formatter. Empty formatter always returns an empty + sequence. + + \param Input container used to select a correct value_type for the + resulting empty_container<>. + \return An instance of the \c empty_formatter object. + */ + template + inline detail::empty_formatF< + BOOST_STRING_TYPENAME range_value::type> + empty_formatter(const RangeT&) + { + return detail::empty_formatF< + BOOST_STRING_TYPENAME range_value::type>(); + } + + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::const_formatter; + using algorithm::identity_formatter; + using algorithm::empty_formatter; + +} // namespace boost + + +#endif // BOOST_FORMATTER_HPP diff --git a/thirdparty/boost/algorithm/string/iter_find.hpp b/thirdparty/boost/algorithm/string/iter_find.hpp new file mode 100644 index 0000000..cc74e27 --- /dev/null +++ b/thirdparty/boost/algorithm/string/iter_find.hpp @@ -0,0 +1,190 @@ +// Boost string_algo library iter_find.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ITER_FIND_HPP +#define BOOST_STRING_ITER_FIND_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines generic split algorithms. Split algorithms can be + used to divide a sequence into several part according + to a given criteria. Result is given as a 'container + of containers' where elements are copies or references + to extracted parts. + + There are two algorithms provided. One iterates over matching + substrings, the other one over the gaps between these matches. +*/ + +namespace boost { + namespace algorithm { + +// iterate find ---------------------------------------------------// + + //! Iter find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + In each iteration new match is found and added to the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A Finder object used for searching + \return A reference the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_find( + SequenceSequenceT& Result, + RangeT& Input, + FinderT Finder ) + { + function_requires< + FinderConcept::type> >(); + + iterator_range::type> lit_input(as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef find_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + make_transform_iterator( + find_iterator_type( begin(lit_input), InputEnd, Finder ), + copy_range_type()); + + transform_iter_type itEnd= + make_transform_iterator( + find_iterator_type(), + copy_range_type()); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + +// iterate split ---------------------------------------------------// + + //! Split find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + Each match is used as a separator of segments. These segments are then + returned in the result. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A finder object used for searching + \return A reference the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_split( + SequenceSequenceT& Result, + RangeT& Input, + FinderT Finder ) + { + function_requires< + FinderConcept::type> >(); + + iterator_range::type> lit_input(as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef split_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + make_transform_iterator( + find_iterator_type( begin(lit_input), InputEnd, Finder ), + copy_range_type() ); + + transform_iter_type itEnd= + make_transform_iterator( + find_iterator_type(), + copy_range_type() ); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::iter_find; + using algorithm::iter_split; + +} // namespace boost + + +#endif // BOOST_STRING_ITER_FIND_HPP diff --git a/thirdparty/boost/algorithm/string/join.hpp b/thirdparty/boost/algorithm/string/join.hpp new file mode 100644 index 0000000..c04a23c --- /dev/null +++ b/thirdparty/boost/algorithm/string/join.hpp @@ -0,0 +1,145 @@ +// Boost string_algo library join.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_JOIN_HPP +#define BOOST_STRING_JOIN_HPP + +#include +#include +#include +#include + +/*! \file + Defines join algorithm. + + Join algorithm is a counterpart to split algorithms. + It joins strings from a 'list' by adding user defined separator. + Additionally there is a version that allows simple filtering + by providing a predicate. +*/ + +namespace boost { + namespace algorithm { + +// join --------------------------------------------------------------// + + //! Join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T> + inline typename range_value::type + join( + const SequenceSequenceT& Input, + const Range1T& Separator) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=begin(Input); + InputIteratorT itEnd=end(Input); + + // Construct container to hold the result + ResultT Result; + + // Append first element + if(itBegin!=itEnd) + { + detail::insert(Result, end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + // Add separator + detail::insert(Result, end(Result), as_literal(Separator)); + // Add element + detail::insert(Result, end(Result), *itBegin); + } + + return Result; + } + +// join_if ----------------------------------------------------------// + + //! Conditional join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. Only segments that + satisfy the predicate will be added to the result. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \param Pred A segment selection predicate + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename PredicateT> + inline typename range_value::type + join_if( + const SequenceSequenceT& Input, + const Range1T& Separator, + PredicateT Pred) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=begin(Input); + InputIteratorT itEnd=end(Input); + + // Construct container to hold the result + ResultT Result; + + // Roll to the first element that will be added + while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin; + // Add this element + if(itBegin!=itEnd) + { + detail::insert(Result, end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + if(Pred(*itBegin)) + { + // Add separator + detail::insert(Result, end(Result), as_literal(Separator)); + // Add element + detail::insert(Result, end(Result), *itBegin); + } + } + + return Result; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::join; + using algorithm::join_if; + +} // namespace boost + + +#endif // BOOST_STRING_JOIN_HPP + diff --git a/thirdparty/boost/algorithm/string/predicate.hpp b/thirdparty/boost/algorithm/string/predicate.hpp new file mode 100644 index 0000000..3afda1f --- /dev/null +++ b/thirdparty/boost/algorithm/string/predicate.hpp @@ -0,0 +1,475 @@ +// Boost string_algo library predicate.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_HPP +#define BOOST_STRING_PREDICATE_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file boost/algorithm/string/predicate.hpp + Defines string-related predicates. + The predicates determine whether a substring is contained in the input string + under various conditions: a string starts with the substring, ends with the + substring, simply contains the substring or if both strings are equal. + Additionaly the algorithm \c all() checks all elements of a container to satisfy a + condition. + + All predicates provide the strong exception guarantee. +*/ + +namespace boost { + namespace algorithm { + +// starts_with predicate -----------------------------------------------// + + //! 'Starts with' predicate + /*! + This predicate holds when the test string is a prefix of the Input. + In other words, if the input starts with the test. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool starts_with( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(as_literal(Input)); + iterator_range::type> lit_test(as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator2T; + + Iterator1T InputEnd=end(lit_input); + Iterator2T TestEnd=end(lit_test); + + Iterator1T it=begin(lit_input); + Iterator2T pit=begin(lit_test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return pit==TestEnd; + } + + //! 'Starts with' predicate + /*! + \overload + */ + template + inline bool starts_with( + const Range1T& Input, + const Range2T& Test) + { + return starts_with(Input, Test, is_equal()); + } + + //! 'Starts with' predicate ( case insensitive ) + /*! + This predicate holds when the test string is a prefix of the Input. + In other words, if the input starts with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool istarts_with( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return starts_with(Input, Test, is_iequal(Loc)); + } + + +// ends_with predicate -----------------------------------------------// + + //! 'Ends with' predicate + /*! + This predicate holds when the test string is a suffix of the Input. + In other words, if the input ends with the test. + When the optional predicate is specified, it is used for character-wise + comparison. + + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool ends_with( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(as_literal(Input)); + iterator_range::type> lit_test(as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return detail:: + ends_with_iter_select( + begin(lit_input), + end(lit_input), + begin(lit_test), + end(lit_test), + Comp, + category()); + } + + + //! 'Ends with' predicate + /*! + \overload + */ + template + inline bool ends_with( + const Range1T& Input, + const Range2T& Test) + { + return ends_with(Input, Test, is_equal()); + } + + //! 'Ends with' predicate ( case insensitive ) + /*! + This predicate holds when the test container is a suffix of the Input. + In other words, if the input ends with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool iends_with( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return ends_with(Input, Test, is_iequal(Loc)); + } + +// contains predicate -----------------------------------------------// + + //! 'Contains' predicate + /*! + This predicate holds when the test container is contained in the Input. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool contains( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(as_literal(Input)); + iterator_range::type> lit_test(as_literal(Test)); + + if (empty(lit_test)) + { + // Empty range is contained always + return true; + } + + // Use the temporary variable to make VACPP happy + bool bResult=(first_finder(lit_test,Comp)(begin(lit_input), end(lit_input))); + return bResult; + } + + //! 'Contains' predicate + /*! + \overload + */ + template + inline bool contains( + const Range1T& Input, + const Range2T& Test) + { + return contains(Input, Test, is_equal()); + } + + //! 'Contains' predicate ( case insensitive ) + /*! + This predicate holds when the test container is contained in the Input. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool icontains( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return contains(Input, Test, is_iequal(Loc)); + } + +// equals predicate -----------------------------------------------// + + //! 'Equals' predicate + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This is a two-way version of \c std::equal algorithm + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool equals( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(as_literal(Input)); + iterator_range::type> lit_test(as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator2T; + + Iterator1T InputEnd=end(lit_input); + Iterator2T TestEnd=end(lit_test); + + Iterator1T it=begin(lit_input); + Iterator2T pit=begin(lit_test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return (pit==TestEnd) && (it==InputEnd); + } + + //! 'Equals' predicate + /*! + \overload + */ + template + inline bool equals( + const Range1T& Input, + const Range2T& Test) + { + return equals(Input, Test, is_equal()); + } + + //! 'Equals' predicate ( case insensitive ) + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This is a two-way version of \c std::equal algorithm + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool iequals( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return equals(Input, Test, is_iequal(Loc)); + } + +// lexicographical_compare predicate -----------------------------// + + //! Lexicographical compare predicate + /*! + This predicate is an overload of std::lexicographical_compare + for range arguments + + It check whether the first argument is lexicographically less + then the second one. + + If the optional predicate is specified, it is used for character-wise + comparison + + \param Arg1 First argument + \param Arg2 Second argument + \param Pred Comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool lexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2, + PredicateT Pred) + { + iterator_range::type> lit_arg1(as_literal(Arg1)); + iterator_range::type> lit_arg2(as_literal(Arg2)); + + return std::lexicographical_compare( + begin(lit_arg1), + end(lit_arg1), + begin(lit_arg2), + end(lit_arg2), + Pred); + } + + //! Lexicographical compare predicate + /*! + \overload + */ + template + inline bool lexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2) + { + return lexicographical_compare(Arg1, Arg2, is_less()); + } + + //! Lexicographical compare predicate (case-insensitive) + /*! + This predicate is an overload of std::lexicographical_compare + for range arguments. + It check whether the first argument is lexicographically less + then the second one. + Elements are compared case insensitively + + + \param Arg1 First argument + \param Arg2 Second argument + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool ilexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2, + const std::locale& Loc=std::locale()) + { + return lexicographical_compare(Arg1, Arg2, is_iless(Loc)); + } + + +// all predicate -----------------------------------------------// + + //! 'All' predicate + /*! + This predicate holds it all its elements satisfy a given + condition, represented by the predicate. + + \param Input An input sequence + \param Pred A predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool all( + const RangeT& Input, + PredicateT Pred) + { + iterator_range::type> lit_input(as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + + Iterator1T InputEnd=end(lit_input); + for( Iterator1T It=begin(lit_input); It!=InputEnd; ++It) + { + if (!Pred(*It)) + return false; + } + + return true; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::starts_with; + using algorithm::istarts_with; + using algorithm::ends_with; + using algorithm::iends_with; + using algorithm::contains; + using algorithm::icontains; + using algorithm::equals; + using algorithm::iequals; + using algorithm::all; + using algorithm::lexicographical_compare; + using algorithm::ilexicographical_compare; + +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/thirdparty/boost/algorithm/string/predicate_facade.hpp b/thirdparty/boost/algorithm/string/predicate_facade.hpp new file mode 100644 index 0000000..c9d4881 --- /dev/null +++ b/thirdparty/boost/algorithm/string/predicate_facade.hpp @@ -0,0 +1,42 @@ +// Boost string_algo library predicate_facade.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_FACADE_HPP +#define BOOST_STRING_PREDICATE_FACADE_HPP + +#include + +/* + \file boost/algorith/string/predicate_facade.hpp + This file containes predicate_facade definition. This template class is used + to identify classification predicates, so they can be combined using + composition operators. +*/ + +namespace boost { + namespace algorithm { + +// predicate facade ------------------------------------------------------// + + //! Predicate facade + /*! + This class allows to recognize classification + predicates, so that they can be combined using + composition operators. + Every classification predicate must be derived from this class. + */ + template + struct predicate_facade {}; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string/regex.hpp b/thirdparty/boost/algorithm/string/regex.hpp new file mode 100644 index 0000000..2393a72 --- /dev/null +++ b/thirdparty/boost/algorithm/string/regex.hpp @@ -0,0 +1,646 @@ +// Boost string_algo library regex.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REGEX_HPP +#define BOOST_STRING_REGEX_HPP + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*! \file + Defines regex variants of the algorithms. +*/ + +namespace boost { + namespace algorithm { + +// find_regex -----------------------------------------------// + + //! Find regex algorithm + /*! + Search for a substring matching the given regex in the input. + + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template< + typename RangeT, + typename CharT, + typename RegexTraitsT> + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type > + find_regex( + RangeT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + iterator_range::type> lit_input(as_literal(Input)); + + return regex_finder(Rx,Flags)( + begin(lit_input), end(lit_input) ); + } + +// replace_regex --------------------------------------------------------------------// + + //! Replace regex algorithm + /*! + Search for a substring matching given regex and format it with + the specified format. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline OutputIteratorT replace_regex_copy( + OutputIteratorT Output, + const RangeT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_copy( + Output, + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace regex algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline SequenceT replace_regex_copy( + const SequenceT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_copy( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace regex algorithm + /*! + Search for a substring matching given regex and format it with + the specified format. The input string is modified in-place. + + \param Input An input string + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline void replace_regex( + SequenceT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + find_format( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + +// replace_all_regex --------------------------------------------------------------------// + + //! Replace all regex algorithm + /*! + Format all substrings, matching given regex, with the specified format. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline OutputIteratorT replace_all_regex_copy( + OutputIteratorT Output, + const RangeT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_all_copy( + Output, + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace all regex algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline SequenceT replace_all_regex_copy( + const SequenceT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_all_copy( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace all regex algorithm + /*! + Format all substrings, matching given regex, with the specified format. + The input string is modified in-place. + + \param Input An input string + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline void replace_all_regex( + SequenceT& Input, + const basic_regex& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + find_format_all( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + +// erase_regex --------------------------------------------------------------------// + + //! Erase regex algorithm + /*! + Remove a substring matching given regex from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Rx A regular expression + \param Flags Regex options + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename CharT, + typename RegexTraitsT > + inline OutputIteratorT erase_regex_copy( + OutputIteratorT Output, + const RangeT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return find_format_copy( + Output, + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase regex algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT > + inline SequenceT erase_regex_copy( + const SequenceT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return find_format_copy( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase regex algorithm + /*! + Remove a substring matching given regex from the input. + The input string is modified in-place. + + \param Input An input string + \param Rx A regular expression + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT > + inline void erase_regex( + SequenceT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + find_format( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + +// erase_all_regex --------------------------------------------------------------------// + + //! Erase all regex algorithm + /*! + Erase all substrings, matching given regex, from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Rx A regular expression + \param Flags Regex options + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename CharT, + typename RegexTraitsT > + inline OutputIteratorT erase_all_regex_copy( + OutputIteratorT Output, + const RangeT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return find_format_all_copy( + Output, + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase all regex algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT > + inline SequenceT erase_all_regex_copy( + const SequenceT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return find_format_all_copy( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase all regex algorithm + /*! + Erase all substrings, matching given regex, from the input. + The input string is modified in-place. + + \param Input An input string + \param Rx A regular expression + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT> + inline void erase_all_regex( + SequenceT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + find_format_all( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + +// find_all_regex ------------------------------------------------------------------// + + //! Find all regex algorithm + /*! + This algorithm finds all substrings matching the give regex + in the input. + + Each part is copied and added as a new element to the output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings. + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return A reference to the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename CharT, + typename RegexTraitsT > + inline SequenceSequenceT& find_all_regex( + SequenceSequenceT& Result, + const RangeT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return iter_find( + Result, + Input, + regex_finder(Rx,Flags) ); + } + +// split_regex ------------------------------------------------------------------// + + //! Split regex algorithm + /*! + Tokenize expression. This function is equivalent to C strtok. Input + sequence is split into tokens, separated by separators. Separator + is an every match of the given regex. + Each part is copied and added as a new element to the output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings. + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return A reference to the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename CharT, + typename RegexTraitsT > + inline SequenceSequenceT& split_regex( + SequenceSequenceT& Result, + const RangeT& Input, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + return iter_split( + Result, + Input, + regex_finder(Rx,Flags) ); + } + +// join_if ------------------------------------------------------------------// + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Conditional join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. Only segments that + match the given regular expression will be added to the result + + This is a specialization of join_if algorithm. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \param Rx A regular expression + \param Flags Regex options + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< + typename SequenceSequenceT, + typename Range1T, + typename CharT, + typename RegexTraitsT > + inline typename range_value::type + join_if( + const SequenceSequenceT& Input, + const Range1T& Separator, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=begin(Input); + InputIteratorT itEnd=end(Input); + + // Construct container to hold the result + ResultT Result; + + + // Roll to the first element that will be added + while( + itBegin!=itEnd && + !regex_match(begin(*itBegin), end(*itBegin), Rx, Flags)) ++itBegin; + + // Add this element + if(itBegin!=itEnd) + { + detail::insert(Result, end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + if(regex_match(begin(*itBegin), end(*itBegin), Rx, Flags)) + { + // Add separator + detail::insert(Result, end(Result), as_literal(Separator)); + // Add element + detail::insert(Result, end(Result), *itBegin); + } + } + + return Result; + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Conditional join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. Only segments that + match the given regular expression will be added to the result + + This is a specialization of join_if algorithm. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \param Rx A regular expression + \param Flags Regex options + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< + typename SequenceSequenceT, + typename Range1T, + typename CharT, + typename RegexTraitsT > + inline typename range_value::type + join_if_regex( + const SequenceSequenceT& Input, + const Range1T& Separator, + const basic_regex& Rx, + match_flag_type Flags=match_default ) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=begin(Input); + InputIteratorT itEnd=end(Input); + + // Construct container to hold the result + ResultT Result; + + + // Roll to the first element that will be added + while( + itBegin!=itEnd && + !regex_match(begin(*itBegin), end(*itBegin), Rx, Flags)) ++itBegin; + + // Add this element + if(itBegin!=itEnd) + { + detail::insert(Result, end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + if(regex_match(begin(*itBegin), end(*itBegin), Rx, Flags)) + { + // Add separator + detail::insert(Result, end(Result), as_literal(Separator)); + // Add element + detail::insert(Result, end(Result), *itBegin); + } + } + + return Result; + } + + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + } // namespace algorithm + + // pull names into the boost namespace + using algorithm::find_regex; + using algorithm::replace_regex; + using algorithm::replace_regex_copy; + using algorithm::replace_all_regex; + using algorithm::replace_all_regex_copy; + using algorithm::erase_regex; + using algorithm::erase_regex_copy; + using algorithm::erase_all_regex; + using algorithm::erase_all_regex_copy; + using algorithm::find_all_regex; + using algorithm::split_regex; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + using algorithm::join_if; +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + using algorithm::join_if_regex; +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +} // namespace boost + + +#endif // BOOST_STRING_REGEX_HPP diff --git a/thirdparty/boost/algorithm/string/regex_find_format.hpp b/thirdparty/boost/algorithm/string/regex_find_format.hpp new file mode 100644 index 0000000..9f861ac --- /dev/null +++ b/thirdparty/boost/algorithm/string/regex_find_format.hpp @@ -0,0 +1,90 @@ +// Boost string_algo library regex_find_format.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REGEX_FIND_FORMAT_HPP +#define BOOST_STRING_REGEX_FIND_FORMAT_HPP + +#include +#include +#include +#include + +/*! \file + Defines the \c regex_finder and \c regex_formatter generators. These two functors + are designed to work together. \c regex_formatter uses additional information + about a match contained in the regex_finder search result. +*/ + +namespace boost { + namespace algorithm { + +// regex_finder -----------------------------------------------// + + //! "Regex" finder + /*! + Construct the \c regex_finder. Finder uses the regex engine to search + for a match. + Result is given in \c regex_search_result. This is an extension + of the iterator_range. In addition it containes match results + from the \c regex_search algorithm. + + \param Rx A regular expression + \param MatchFlags Regex search options + \return An instance of the \c regex_finder object + */ + template< + typename CharT, + typename RegexTraitsT> + inline detail::find_regexF< basic_regex > + regex_finder( + const basic_regex& Rx, + match_flag_type MatchFlags=match_default ) + { + return detail:: + find_regexF< + basic_regex >( Rx, MatchFlags ); + } + +// regex_formater ---------------------------------------------// + + //! Regex formatter + /*! + Construct the \c regex_formatter. Regex formatter uses the regex engine to + format a match found by the \c regex_finder. + This formatted it designed to closely cooperate with \c regex_finder. + + \param Format Regex format definition + \param Flags Format flags + \return An instance of the \c regex_formatter functor + */ + template< + typename CharT, + typename TraitsT, typename AllocT > + inline detail::regex_formatF< std::basic_string< CharT, TraitsT, AllocT > > + regex_formatter( + const std::basic_string& Format, + match_flag_type Flags=format_default ) + { + return + detail::regex_formatF< std::basic_string >( + Format, + Flags ); + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::regex_finder; + using algorithm::regex_formatter; + +} // namespace boost + + +#endif // BOOST_STRING_REGEX_FIND_FORMAT_HPP diff --git a/thirdparty/boost/algorithm/string/replace.hpp b/thirdparty/boost/algorithm/string/replace.hpp new file mode 100644 index 0000000..c56198b --- /dev/null +++ b/thirdparty/boost/algorithm/string/replace.hpp @@ -0,0 +1,928 @@ +// Boost string_algo library replace.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REPLACE_HPP +#define BOOST_STRING_REPLACE_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*! \file + Defines various replace algorithms. Each algorithm replaces + part(s) of the input according to set of searching and replace criteria. +*/ + +namespace boost { + namespace algorithm { + +// replace_range --------------------------------------------------------------------// + + //! Replace range algorithm + /*! + Replace the given range in the input string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param SearchRange A range in the input to be substituted + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_range_copy( + OutputIteratorT Output, + const Range1T& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange, + const Range2T& Format) + { + return find_format_copy( + Output, + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + + //! Replace range algorithm + /*! + \overload + */ + template + inline SequenceT replace_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange, + const RangeT& Format) + { + return find_format_copy( + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + + //! Replace range algorithm + /*! + Replace the given range in the input string. + The input sequence is modified in-place. + + \param Input An input string + \param SearchRange A range in the input to be substituted + \param Format A substitute string + */ + template + inline void replace_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_iterator::type>& SearchRange, + const RangeT& Format) + { + find_format( + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + +// replace_first --------------------------------------------------------------------// + + //! Replace first algorithm + /*! + Replace the first match of the search substring in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format) + { + return find_format_copy( + Output, + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + \overload + */ + template + inline SequenceT replace_first_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return find_format_copy( + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + replace the first match of the search substring in the input + with the format string. The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + */ + template + inline void replace_first( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + find_format( + Input, + first_finder(Search), + const_formatter(Format) ); + } + +// replace_first ( case insensitive ) ---------------------------------------------// + + //! Replace first algorithm ( case insensitive ) + /*! + Replace the first match of the search substring in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_first_copy( + const SequenceT& Input, + const Range2T& Search, + const Range1T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + Replace the first match of the search substring in the input + with the format string. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_first( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_last --------------------------------------------------------------------// + + //! Replace last algorithm + /*! + Replace the last match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format ) + { + return find_format_copy( + Output, + Input, + last_finder(Search), + const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + \overload + */ + template + inline SequenceT replace_last_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return find_format_copy( + Input, + last_finder(Search), + const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + Replace the last match of the search string in the input + with the format string. Input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + */ + template + inline void replace_last( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + find_format( + Input, + last_finder(Search), + const_formatter(Format) ); + } + +// replace_last ( case insensitive ) -----------------------------------------------// + + //! Replace last algorithm ( case insensitive ) + /*! + Replace the last match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_last_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + Replace the last match of the search string in the input + with the format string.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return A reference to the modified input + */ + template + inline void ireplace_last( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_nth --------------------------------------------------------------------// + + //! Replace nth algorithm + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const Range3T& Format ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + \overload + */ + template + inline SequenceT replace_nth_copy( + const SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. Input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + */ + template + inline void replace_nth( + SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format ) + { + find_format( + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + +// replace_nth ( case insensitive ) -----------------------------------------------// + + //! Replace nth algorithm ( case insensitive ) + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth, is_iequal(Loc) ), + const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_nth_copy( + const SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_nth( + SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_all --------------------------------------------------------------------// + + //! Replace all algorithm + /*! + Replace all occurrences of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + \overload + */ + template + inline SequenceT replace_all_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return find_format_all_copy( + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + Replace all occurrences of the search string in the input + with the format string. The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return A reference to the modified input + */ + template + inline void replace_all( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + find_format_all( + Input, + first_finder(Search), + const_formatter(Format) ); + } + +// replace_all ( case insensitive ) -----------------------------------------------// + + //! Replace all algorithm ( case insensitive ) + /*! + Replace all occurrences of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_all_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + Replace all occurrences of the search string in the input + with the format string.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_all( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format_all( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_head --------------------------------------------------------------------// + + //! Replace head algorithm + /*! + Replace the head of the input with the given format string. + The head is a prefix of a string of given size. + If the sequence is shorter then required, whole string if + considered to be the head. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_head_copy( + OutputIteratorT Output, + const Range1T& Input, + int N, + const Range2T& Format ) + { + return find_format_copy( + Output, + Input, + head_finder(N), + const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + \overload + */ + template + inline SequenceT replace_head_copy( + const SequenceT& Input, + int N, + const RangeT& Format ) + { + return find_format_copy( + Input, + head_finder(N), + const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + Replace the head of the input with the given format string. + The head is a prefix of a string of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + */ + template + inline void replace_head( + SequenceT& Input, + int N, + const RangeT& Format ) + { + find_format( + Input, + head_finder(N), + const_formatter(Format) ); + } + +// replace_tail --------------------------------------------------------------------// + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format string. + The tail is a suffix of a string of given size. + If the sequence is shorter then required, whole string is + considered to be the tail. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_tail_copy( + OutputIteratorT Output, + const Range1T& Input, + int N, + const Range2T& Format ) + { + return find_format_copy( + Output, + Input, + tail_finder(N), + const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + \overload + */ + template + inline SequenceT replace_tail_copy( + const SequenceT& Input, + int N, + const RangeT& Format ) + { + return find_format_copy( + Input, + tail_finder(N), + const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format sequence. + The tail is a suffix of a string of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + */ + template + inline void replace_tail( + SequenceT& Input, + int N, + const RangeT& Format ) + { + find_format( + Input, + tail_finder(N), + const_formatter(Format) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::replace_range_copy; + using algorithm::replace_range; + using algorithm::replace_first_copy; + using algorithm::replace_first; + using algorithm::ireplace_first_copy; + using algorithm::ireplace_first; + using algorithm::replace_last_copy; + using algorithm::replace_last; + using algorithm::ireplace_last_copy; + using algorithm::ireplace_last; + using algorithm::replace_nth_copy; + using algorithm::replace_nth; + using algorithm::ireplace_nth_copy; + using algorithm::ireplace_nth; + using algorithm::replace_all_copy; + using algorithm::replace_all; + using algorithm::ireplace_all_copy; + using algorithm::ireplace_all; + using algorithm::replace_head_copy; + using algorithm::replace_head; + using algorithm::replace_tail_copy; + using algorithm::replace_tail; + +} // namespace boost + +#endif // BOOST_REPLACE_HPP diff --git a/thirdparty/boost/algorithm/string/sequence_traits.hpp b/thirdparty/boost/algorithm/string/sequence_traits.hpp new file mode 100644 index 0000000..f9f4a9c --- /dev/null +++ b/thirdparty/boost/algorithm/string/sequence_traits.hpp @@ -0,0 +1,193 @@ +// Boost string_algo library sequence_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP +#define BOOST_STRING_SEQUENCE_TRAITS_HPP + +#include +#include +#include + +/*! \file + Traits defined in this header are used by various algorithms to achieve + better performance for specific containers. + Traits provide fail-safe defaults. If a container supports some of these + features, it is possible to specialize the specific trait for this container. + For lacking compilers, it is possible of define an override for a specific tester + function. + + Due to a language restriction, it is not currently possible to define specializations for + stl containers without including the corresponding header. To decrease the overhead + needed by this inclusion, user can selectively include a specialization + header for a specific container. They are located in boost/algorithm/string/stl + directory. Alternatively she can include boost/algorithm/string/std_collection_traits.hpp + header which contains specializations for all stl containers. +*/ + +namespace boost { + namespace algorithm { + +// sequence traits -----------------------------------------------// + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + //! Native replace tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the container has basic_string like native replace + method. + */ + no_type has_native_replace_tester(...); + + //! Stable iterators tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the sequence's insert/replace/erase methods do not invalidate + existing iterators. + */ + no_type has_stable_iterators_tester(...); + + //! const time insert tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the sequence's insert method is working in constant time + */ + no_type has_const_time_insert_tester(...); + + //! const time erase tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the sequence's erase method is working in constant time + */ + no_type has_const_time_erase_tester(...); + +#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + //! Native replace trait + /*! + This trait specifies that the sequence has \c std::string like replace method + */ + template< typename T > + class has_native_replace + { + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_native_replace_tester(t))==sizeof(yes_type) ) ); +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + + typedef mpl::bool_::value> type; + }; + + + //! Stable iterators trait + /*! + This trait specifies that the sequence has stable iterators. It means + that operations like insert/erase/replace do not invalidate iterators. + */ + template< typename T > + class has_stable_iterators + { +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_stable_iterators_tester(t))==sizeof(yes_type) ) ); +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + typedef mpl::bool_::value> type; + }; + + + //! Const time insert trait + /*! + This trait specifies that the sequence's insert method has + constant time complexity. + */ + template< typename T > + class has_const_time_insert + { +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_const_time_insert_tester(t))==sizeof(yes_type) ) ); +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + typedef mpl::bool_::value> type; + }; + + + //! Const time erase trait + /*! + This trait specifies that the sequence's erase method has + constant time complexity. + */ + template< typename T > + class has_const_time_erase + { +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_const_time_erase_tester(t))==sizeof(yes_type) ) ); +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + typedef mpl::bool_::value> type; + }; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_SEQUENCE_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/split.hpp b/thirdparty/boost/algorithm/string/split.hpp new file mode 100644 index 0000000..297716e --- /dev/null +++ b/thirdparty/boost/algorithm/string/split.hpp @@ -0,0 +1,163 @@ +// Boost string_algo library split.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_SPLIT_HPP +#define BOOST_STRING_SPLIT_HPP + +#include + +#include +#include +#include + +/*! \file + Defines basic split algorithms. + Split algorithms can be used to divide a string + into several parts according to given criteria. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> +*/ + +namespace boost { + namespace algorithm { + +// find_all ------------------------------------------------------------// + + //! Find all algorithm + /*! + This algorithm finds all occurrences of the search string + in the input. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& find_all( + SequenceSequenceT& Result, + Range1T& Input, + const Range2T& Search) + { + return iter_find( + Result, + Input, + first_finder(Search) ); + } + + //! Find all algorithm ( case insensitive ) + /*! + This algorithm finds all occurrences of the search string + in the input. + Each part is copied and added as a new element to the + output container. Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + Searching is case insensitive. + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& ifind_all( + SequenceSequenceT& Result, + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return iter_find( + Result, + Input, + first_finder(Search, is_iequal(Loc) ) ); + } + + +// tokenize -------------------------------------------------------------// + + //! Split algorithm + /*! + Tokenize expression. This function is equivalent to C strtok. Input + sequence is split into tokens, separated by separators. Separators + are given by means of the predicate. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Pred A predicate to identify separators. This predicate is + supposed to return true if a given element is a separator. + \param eCompress If eCompress argument is set to token_compress_on, adjacent + separators are merged together. Otherwise, every two separators + delimit a token. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename RangeT, typename PredicateT > + inline SequenceSequenceT& split( + SequenceSequenceT& Result, + RangeT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return iter_split( + Result, + Input, + token_finder( Pred, eCompress ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_all; + using algorithm::ifind_all; + using algorithm::split; + +} // namespace boost + + +#endif // BOOST_STRING_SPLIT_HPP + diff --git a/thirdparty/boost/algorithm/string/std/list_traits.hpp b/thirdparty/boost/algorithm/string/std/list_traits.hpp new file mode 100644 index 0000000..3f25f63 --- /dev/null +++ b/thirdparty/boost/algorithm/string/std/list_traits.hpp @@ -0,0 +1,85 @@ +// Boost string_algo library list_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_LIST_TRAITS_HPP +#define BOOST_STRING_STD_LIST_TRAITS_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + +// std::list<> traits -----------------------------------------------// + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const ::std::list* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const ::std::list* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const ::std::list* ); + + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // stable iterators trait + template + class has_stable_iterators< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time insert trait + template + class has_const_time_insert< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time erase trait + template + class has_const_time_erase< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; +#endif + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/std/rope_traits.hpp b/thirdparty/boost/algorithm/string/std/rope_traits.hpp new file mode 100644 index 0000000..e9ae03a --- /dev/null +++ b/thirdparty/boost/algorithm/string/std/rope_traits.hpp @@ -0,0 +1,101 @@ +// Boost string_algo library string_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_ROPE_TRAITS_HPP +#define BOOST_STRING_STD_ROPE_TRAITS_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + +// SGI's std::rope<> traits -----------------------------------------------// + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // native replace tester + template + yes_type has_native_replace_tester( const std::rope* ); + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const std::rope* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const std::rope* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const std::rope* ); + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // native replace trait + template + class has_native_replace< std::rope > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_ type; + }; + + // stable iterators trait + template + class has_stable_iterators< std::rope > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_ type; + }; + + // const time insert trait + template + class has_const_time_insert< std::rope > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_ type; + }; + + // const time erase trait + template + class has_const_time_erase< std::rope > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_ type; + }; +#endif + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_ROPE_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/std/slist_traits.hpp b/thirdparty/boost/algorithm/string/std/slist_traits.hpp new file mode 100644 index 0000000..c3cfe64 --- /dev/null +++ b/thirdparty/boost/algorithm/string/std/slist_traits.hpp @@ -0,0 +1,85 @@ +// Boost string_algo library slist_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_SLIST_TRAITS_HPP +#define BOOST_STRING_STD_SLIST_TRAITS_HPP + +#include +#include +#include BOOST_SLIST_HEADER +#include + +namespace boost { + namespace algorithm { + +// SGI's std::slist<> traits -----------------------------------------------// + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist* ); + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // stable iterators trait + template + class has_stable_iterators< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time insert trait + template + class has_const_time_insert< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time erase trait + template + class has_const_time_erase< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; +#endif + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/std/string_traits.hpp b/thirdparty/boost/algorithm/string/std/string_traits.hpp new file mode 100644 index 0000000..e67a49a --- /dev/null +++ b/thirdparty/boost/algorithm/string/std/string_traits.hpp @@ -0,0 +1,52 @@ +// Boost string_algo library string_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_STRING_TRAITS_HPP +#define BOOST_STRING_STD_STRING_TRAITS_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + +// std::basic_string<> traits -----------------------------------------------// + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // native replace tester + template + yes_type has_native_replace_tester( const std::basic_string* ); + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // native replace trait + template + class has_native_replace< std::basic_string > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true } ; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + typedef mpl::bool_::value> type; + }; + + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_LIST_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/std_containers_traits.hpp b/thirdparty/boost/algorithm/string/std_containers_traits.hpp new file mode 100644 index 0000000..28dddc7 --- /dev/null +++ b/thirdparty/boost/algorithm/string/std_containers_traits.hpp @@ -0,0 +1,26 @@ +// Boost string_algo library std_containers_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_CONTAINERS_TRAITS_HPP +#define BOOST_STRING_STD_CONTAINERS_TRAITS_HPP + +/*!\file + This file includes sequence traits for stl containers. +*/ + +#include +#include +#include + +#ifdef BOOST_HAS_SLIST +# include +#endif + +#endif // BOOST_STRING_STD_CONTAINERS_TRAITS_HPP diff --git a/thirdparty/boost/algorithm/string/trim.hpp b/thirdparty/boost/algorithm/string/trim.hpp new file mode 100644 index 0000000..ddcb9f3 --- /dev/null +++ b/thirdparty/boost/algorithm/string/trim.hpp @@ -0,0 +1,398 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_HPP +#define BOOST_STRING_TRIM_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines trim algorithms. + Trim algorithms are used to remove trailing and leading spaces from a + sequence (string). Space is recognized using given locales. + + Parametric (\c _if) variants use a predicate (functor) to select which characters + are to be trimmed.. + Functions take a selection predicate as a parameter, which is used to determine + whether a character is a space. Common predicates are provided in classification.hpp header. + +*/ + +namespace boost { + namespace algorithm { + + // left trim -----------------------------------------------// + + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace An unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_left_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(as_literal(Input)); + + std::copy( + ::boost::algorithm::detail::trim_begin( + begin(lit_range), + end(lit_range), + IsSpace ), + end(lit_range), + Output); + + return Output; + } + + //! Left trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + ::boost::algorithm::detail::trim_begin( + begin(Input), + end(Input), + IsSpace ), + end(Input)); + } + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The result is a trimmed copy of the input. + + \param Input An input sequence + \param Loc a locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + trim_left_copy_if( + Input, + is_space(Loc)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. The supplied predicate is + used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_left_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + begin(Input), + ::boost::algorithm::detail::trim_begin( + begin(Input), + end(Input), + IsSpace)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. + The Input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_left_if( + Input, + is_space(Loc)); + } + + // right trim -----------------------------------------------// + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace An unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_right_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace ) + { + iterator_range::type> lit_range(as_literal(Input)); + + std::copy( + begin(lit_range), + ::boost::algorithm::detail::trim_end( + begin(lit_range), + end(lit_range), + IsSpace ), + Output ); + + return Output; + } + + //! Right trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + begin(Input), + ::boost::algorithm::detail::trim_end( + begin(Input), + end(Input), + IsSpace) + ); + } + + //! Right trim + /*! + Remove all trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + trim_right_copy_if( + Input, + is_space(Loc)); + } + + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_right_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + ::boost::algorithm::detail::trim_end( + begin(Input), + end(Input), + IsSpace ), + end(Input) + ); + } + + + //! Right trim + /*! + Remove all trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_right_if( + Input, + is_space(Loc) ); + } + + // both side trim -----------------------------------------------// + + //! Trim - parametric + /*! + Remove all trailing and leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace An unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(as_literal(Input)); + + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + begin(lit_range), + end(lit_range), + IsSpace); + + std::copy( + detail::trim_begin( + begin(lit_range), TrimEnd, IsSpace), + TrimEnd, + Output + ); + + return Output; + } + + //! Trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + begin(Input), + end(Input), + IsSpace); + + return SequenceT( + detail::trim_begin( + begin(Input), + TrimEnd, + IsSpace), + TrimEnd + ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() ) + { + return + trim_copy_if( + Input, + is_space(Loc) ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_if(SequenceT& Input, PredicateT IsSpace) + { + trim_right_if( Input, IsSpace ); + trim_left_if( Input, IsSpace ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_if( + Input, + is_space( Loc ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::trim_left; + using algorithm::trim_left_if; + using algorithm::trim_left_copy; + using algorithm::trim_left_copy_if; + using algorithm::trim_right; + using algorithm::trim_right_if; + using algorithm::trim_right_copy; + using algorithm::trim_right_copy_if; + using algorithm::trim; + using algorithm::trim_if; + using algorithm::trim_copy; + using algorithm::trim_copy_if; + +} // namespace boost + +#endif // BOOST_STRING_TRIM_HPP diff --git a/thirdparty/boost/algorithm/string/yes_no_type.hpp b/thirdparty/boost/algorithm/string/yes_no_type.hpp new file mode 100644 index 0000000..4109763 --- /dev/null +++ b/thirdparty/boost/algorithm/string/yes_no_type.hpp @@ -0,0 +1,33 @@ +// Boost string_algo library yes_no_type.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_YES_NO_TYPE_DETAIL_HPP +#define BOOST_STRING_YES_NO_TYPE_DETAIL_HPP + +namespace boost { + namespace algorithm { + + // taken from boost mailing-list + // when yes_no_type will become officially + // a part of boost distribution, this header + // will be deprecated + template struct size_descriptor + { + typedef char (& type)[I]; + }; + + typedef size_descriptor<1>::type yes_type; + typedef size_descriptor<2>::type no_type; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_YES_NO_TYPE_DETAIL_HPP diff --git a/thirdparty/boost/algorithm/string_regex.hpp b/thirdparty/boost/algorithm/string_regex.hpp new file mode 100644 index 0000000..a77d04f --- /dev/null +++ b/thirdparty/boost/algorithm/string_regex.hpp @@ -0,0 +1,23 @@ +// Boost string_algo library string_regex.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ALGO_REGEX_HPP +#define BOOST_STRING_ALGO_REGEX_HPP + +/*! \file + Cumulative include for string_algo library. + In addtion to string.hpp contains also regex-related stuff. +*/ + +#include +#include +#include + +#endif // BOOST_STRING_ALGO_REGEX_HPP diff --git a/thirdparty/boost/aligned_storage.hpp b/thirdparty/boost/aligned_storage.hpp new file mode 100644 index 0000000..1120cf8 --- /dev/null +++ b/thirdparty/boost/aligned_storage.hpp @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------------- +// boost aligned_storage.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman, Itay Maman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ALIGNED_STORAGE_HPP +#define BOOST_ALIGNED_STORAGE_HPP + +#include // for std::size_t + +#include "boost/config.hpp" +#include "boost/detail/workaround.hpp" +#include "boost/type_traits/alignment_of.hpp" +#include "boost/type_traits/type_with_alignment.hpp" +#include "boost/type_traits/is_pod.hpp" + +#include "boost/mpl/eval_if.hpp" +#include "boost/mpl/identity.hpp" + +#include "boost/type_traits/detail/bool_trait_def.hpp" + +namespace boost { + +namespace detail { namespace aligned_storage { + +BOOST_STATIC_CONSTANT( + std::size_t + , alignment_of_max_align = ::boost::alignment_of::value + ); + +// +// To be TR1 conforming this must be a POD type: +// +template < + std::size_t size_ + , std::size_t alignment_ +> +struct aligned_storage_imp +{ + union data_t + { + char buf[size_]; + + typename mpl::eval_if_c< + alignment_ == std::size_t(-1) + , mpl::identity + , type_with_alignment + >::type align_; + } data_; +}; + +}} // namespace detail::aligned_storage + +template < + std::size_t size_ + , std::size_t alignment_ = std::size_t(-1) +> +class aligned_storage +{ +private: // representation + + detail::aligned_storage::aligned_storage_imp data_; + +public: // constants + + typedef detail::aligned_storage::aligned_storage_imp type; + + BOOST_STATIC_CONSTANT( + std::size_t + , size = size_ + ); + BOOST_STATIC_CONSTANT( + std::size_t + , alignment = ( + alignment_ == std::size_t(-1) + ? ::boost::detail::aligned_storage::alignment_of_max_align + : alignment_ + ) + ); + +#if defined(__GNUC__) &&\ + (__GNUC__ > 3) ||\ + (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 ||\ + (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ >=3))) + +private: // noncopyable + + aligned_storage(const aligned_storage&); + aligned_storage& operator=(const aligned_storage&); + +#else // gcc less than 3.2.3 + +public: // _should_ be noncopyable, but GCC compiler emits error + + aligned_storage(const aligned_storage&); + aligned_storage& operator=(const aligned_storage&); + +#endif // gcc < 3.2.3 workaround + +public: // structors + + aligned_storage() + { + } + + ~aligned_storage() + { + } + +public: // accessors + + void* address() + { + return this; + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + const void* address() const + { + return this; + } + +#else // MSVC6 + + const void* address() const; + +#endif // MSVC6 workaround + +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +// MSVC6 seems not to like inline functions with const void* returns, so we +// declare the following here: + +template +const void* aligned_storage::address() const +{ + return const_cast< aligned_storage* >(this)->address(); +} + +#endif // MSVC6 workaround + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +// +// Make sure that is_pod recognises aligned_storage<>::type +// as a POD (Note that aligned_storage<> itself is not a POD): +// +template +struct is_pod > + BOOST_TT_AUX_BOOL_C_BASE(true) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(true) +}; +#endif + + +} // namespace boost + +#include "boost/type_traits/detail/bool_trait_undef.hpp" + +#endif // BOOST_ALIGNED_STORAGE_HPP diff --git a/thirdparty/boost/any.hpp b/thirdparty/boost/any.hpp new file mode 100644 index 0000000..53047b1 --- /dev/null +++ b/thirdparty/boost/any.hpp @@ -0,0 +1,235 @@ +// See http://www.boost.org/libs/any for Documentation. + +#ifndef BOOST_ANY_INCLUDED +#define BOOST_ANY_INCLUDED + +// what: variant type boost::any +// who: contributed by Kevlin Henney, +// with features contributed and bugs found by +// Ed Brey, Mark Rodgers, Peter Dimov, and James Curran +// when: July 2001 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 + +#include +#include + +#include "boost/config.hpp" +#include +#include +#include +#include + +namespace boost +{ + class any + { + public: // structors + + any() + : content(0) + { + } + + template + any(const ValueType & value) + : content(new holder(value)) + { + } + + any(const any & other) + : content(other.content ? other.content->clone() : 0) + { + } + + ~any() + { + delete content; + } + + public: // modifiers + + any & swap(any & rhs) + { + std::swap(content, rhs.content); + return *this; + } + + template + any & operator=(const ValueType & rhs) + { + any(rhs).swap(*this); + return *this; + } + + any & operator=(const any & rhs) + { + any(rhs).swap(*this); + return *this; + } + + public: // queries + + bool empty() const + { + return !content; + } + + const std::type_info & type() const + { + return content ? content->type() : typeid(void); + } + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + private: // types +#else + public: // types (public so any_cast can be non-friend) +#endif + + class placeholder + { + public: // structors + + virtual ~placeholder() + { + } + + public: // queries + + virtual const std::type_info & type() const = 0; + + virtual placeholder * clone() const = 0; + + }; + + template + class holder : public placeholder + { + public: // structors + + holder(const ValueType & value) + : held(value) + { + } + + public: // queries + + virtual const std::type_info & type() const + { + return typeid(ValueType); + } + + virtual placeholder * clone() const + { + return new holder(held); + } + + public: // representation + + ValueType held; + + }; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + + private: // representation + + template + friend ValueType * any_cast(any *); + + template + friend ValueType * unsafe_any_cast(any *); + +#else + + public: // representation (public so any_cast can be non-friend) + +#endif + + placeholder * content; + + }; + + class bad_any_cast : public std::bad_cast + { + public: + virtual const char * what() const throw() + { + return "boost::bad_any_cast: " + "failed conversion using boost::any_cast"; + } + }; + + template + ValueType * any_cast(any * operand) + { + return operand && operand->type() == typeid(ValueType) + ? &static_cast *>(operand->content)->held + : 0; + } + + template + inline const ValueType * any_cast(const any * operand) + { + return any_cast(const_cast(operand)); + } + + template + ValueType any_cast(any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // If 'nonref' is still reference type, it means the user has not + // specialized 'remove_reference'. + + // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro + // to generate specialization of remove_reference for your class + // See type traits library documentation for details + BOOST_STATIC_ASSERT(!is_reference::value); +#endif + + nonref * result = any_cast(&operand); + if(!result) + boost::throw_exception(bad_any_cast()); + return *result; + } + + template + inline ValueType any_cast(const any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // The comment in the above version of 'any_cast' explains when this + // assert is fired and what to do. + BOOST_STATIC_ASSERT(!is_reference::value); +#endif + + return any_cast(const_cast(operand)); + } + + // Note: The "unsafe" versions of any_cast are not part of the + // public interface and may be removed at any time. They are + // required where we know what type is stored in the any and can't + // use typeid() comparison, e.g., when our types may travel across + // different shared libraries. + template + inline ValueType * unsafe_any_cast(any * operand) + { + return &static_cast *>(operand->content)->held; + } + + template + inline const ValueType * unsafe_any_cast(const any * operand) + { + return unsafe_any_cast(const_cast(operand)); + } +} + +// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#endif diff --git a/thirdparty/boost/archive/add_facet.hpp b/thirdparty/boost/archive/add_facet.hpp new file mode 100644 index 0000000..e50543f --- /dev/null +++ b/thirdparty/boost/archive/add_facet.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_ARCHIVE_ADD_FACET_HPP +#define BOOST_ARCHIVE_ADD_FACET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// add_facet.hpp + +// (C) Copyright 2003 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +// does STLport uses native STL for locales? +#if (defined(__SGI_STL_PORT)&& defined(_STLP_NO_OWN_IOSTREAMS)) +// and this native STL lib is old Dinkumware (has not defined _CPPLIB_VER) +# if (defined(_YVALS) && !defined(__IBMCPP__)) || !defined(_CPPLIB_VER) +# define BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT +# endif +#endif + +namespace boost { +namespace archive { + +template +inline std::locale * +add_facet(const std::locale &l, Facet * f){ + return + #if defined BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT + // std namespace used for native locale + new std::locale(std::_Addfac(l, f)); + #elif BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) // old Dinkumwar + // std namespace used for native locale + new std::locale(std::_Addfac(l, f)); + #else + // standard compatible + new std::locale(l, f); + #endif +} + +} // namespace archive +} // namespace boost + +#undef BOOST_ARCHIVE_OLD_DINKUMWARE_BENEATH_STLPORT + +#endif // BOOST_ARCHIVE_ADD_FACET_HPP diff --git a/thirdparty/boost/archive/archive_exception.hpp b/thirdparty/boost/archive/archive_exception.hpp new file mode 100644 index 0000000..8433f0b --- /dev/null +++ b/thirdparty/boost/archive/archive_exception.hpp @@ -0,0 +1,115 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive/archive_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by archives +// +class archive_exception : + public virtual std::exception +{ +public: + typedef enum { + no_exception, // initialized without code + other_exception, // any excepton not listed below + unregistered_class, // attempt to serialize a pointer of an + // an unregistered class + invalid_signature, // first line of archive does not contain + // expected string + unsupported_version,// archive created with library version + // subsequent to this one + pointer_conflict, // an attempt has been made to directly + // serialization::detail an object + // after having already serialzed the same + // object through a pointer. Were this permited, + // it the archive load would result in the + // creation of an extra copy of the obect. + incompatible_native_format, // attempt to read native binary format + // on incompatible platform + array_size_too_short,// array being loaded doesn't fit in array allocated + stream_error, // i/o error on stream + invalid_class_name, // class name greater than the maximum permitted. + // most likely a corrupted archive or an attempt + // to insert virus via buffer overrun method. + unregistered_cast // base - derived relationship not registered with + // void_cast_register + } exception_code; + exception_code code; + archive_exception(exception_code c) : + code(c) + {} + virtual const char *what( ) const throw( ) + { + const char *msg = "programming error"; + switch(code){ + case no_exception: + msg = "uninitialized exception"; + break; + case unregistered_class: + msg = "unregistered class"; + break; + case invalid_signature: + msg = "invalid signature"; + break; + case unsupported_version: + msg = "unsupported version"; + break; + case pointer_conflict: + msg = "pointer conflict"; + break; + case incompatible_native_format: + msg = "incompatible native format"; + break; + case array_size_too_short: + msg = "array size too short"; + break; + case stream_error: + msg = "stream error"; + break; + case invalid_class_name: + msg = "class name too long"; + break; + case unregistered_cast: + msg = "unregistered void cast"; + break; + case other_exception: + // if get here - it indicates a derived exception + // was sliced by passing by value in catch + msg = "unknown derived exception"; + break; + default: + assert(false); + break; + } + return msg; + } +protected: + archive_exception() : + code(no_exception) + {} +}; + +}// namespace archive +}// namespace boost + +#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/thirdparty/boost/archive/array/iarchive.hpp b/thirdparty/boost/archive/array/iarchive.hpp new file mode 100644 index 0000000..f196b6b --- /dev/null +++ b/thirdparty/boost/archive/array/iarchive.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP +#define BOOST_ARCHIVE_ARRAY_IARCHIVE_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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) + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace archive { namespace array { + + // To conveniently array-optimize an input archive X: + // + // * Derive it from iarchive, where Impl is an + // archive implementation base class from + // Boost.Serialization + // + // * add a member function template that implements the + // procedure for serializing arrays of T (for appropriate T) + // + // template + // load_array(serialization::array &, unsigned int) + // + // * add a unary MPL lambda expression member called + // use_array_optimization whose result is convertible to + // mpl::true_ iff array elements of type T can be serialized + // with the load_array member function, and to mpl::false_ if + // the unoptimized procedure must be used. + +template +class iarchive + : public archive::detail::common_iarchive +{ + typedef archive::detail::common_iarchive Base; +public: + iarchive(unsigned int flags) + : archive::detail::common_iarchive(flags) + {} + + + // save_override for std::vector and serialization::array dispatches to + // save_optimized with an additional argument. + // + // If that argument is of type mpl::true_, an optimized serialization is provided + // If it is false, we just forward to the default serialization in the base class + + //the default version dispatches to the base class + template + void load_optimized(T &t, unsigned int version, mpl::false_) + { + Base::load_override(t, version); + } + + // the optimized implementation for vector uses serialization::array +// template +// void load_optimized( +// std::vector &t, unsigned int version, mpl::true_) +// { +// t.clear(); +// // retrieve number of elements +// serialization::collection_size_type count; +// *this->This() >> BOOST_SERIALIZATION_NVP(count); +// t.resize(count); +// if (!t.empty()) +// * this->This() >> serialization::make_array(serialization::detail::get_data(t),t.size()); +// } + + // the optimized implementation for serialization::array uses save_array + template + void load_optimized( + serialization::array &t, unsigned int version, mpl::true_) + { + this->This()->load_array(t,version); + } + + + // to load a vector: + // if the value type is trivially constructable or an optimized array save exists, + // then we can use the optimized version + +// template +// void load_override(std::vector &x, unsigned int version) +// { +// typedef typename mpl::and_< +// mpl::not_ >, +// mpl::apply1< +// BOOST_DEDUCED_TYPENAME Archive::use_array_optimization +// , ValueType> +// >::type use_optimized; +// load_optimized(x,version, use_optimized() ); +// } + + + // dispatch loading of arrays to the optimized version where supported + template + void load_override(serialization::array const& x, unsigned int version) + { + typedef typename mpl::apply1< + BOOST_DEDUCED_TYPENAME Archive::use_array_optimization + , ValueType + >::type use_optimized; + load_optimized(const_cast&>(x),version,use_optimized()); + } + + // Load everything else in the usual way, forwarding on to the base class + template + void load_override(T & x, unsigned BOOST_PFTO int version) + { + Base::load_override(x, static_cast(version)); + } +}; + + +} } } // end namespace boost::archive::array + + + +#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP + diff --git a/thirdparty/boost/archive/array/oarchive.hpp b/thirdparty/boost/archive/array/oarchive.hpp new file mode 100644 index 0000000..f72d639 --- /dev/null +++ b/thirdparty/boost/archive/array/oarchive.hpp @@ -0,0 +1,130 @@ +#ifndef BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP +#define BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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) + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace archive { namespace array { + + // To conveniently array-optimize an output archive X: + // + // * Derive it from oarchive, where Impl is an + // archive implementation base class from + // Boost.Serialization + // + // * add a member function template that implements the + // procedure for serializing arrays of T (for appropriate T) + // + // template + // save_array(serialization::array const &, unsigned int) + // + // * add a unary MPL lambda expression member called + // use_array_optimization whose result is convertible to + // mpl::true_ iff array elements of type T can be serialized + // with the load_array member function, and to mpl::false_ if + // the unoptimized procedure must be used. + +template +class oarchive + : public archive::detail::common_oarchive +{ + typedef archive::detail::common_oarchive Base; +public: + + oarchive(unsigned int flags) + : archive::detail::common_oarchive(flags) + {} + + // save_override for std::vector and serialization::array dispatches to + // save_optimized with an additional argument. + // + // If that argument is of type mpl::true_, an optimized serialization is provided + // If it is false, we just forward to the default serialization in the base class + + //the default version dispatches to the base class + template + void save_optimized(T const &t, unsigned int version, mpl::false_) + { + Base::save_override(t, version); + } + + + // the optimized implementation for vector uses serialization::array +// template +// void save_optimized( +// const std::vector &t, unsigned int, mpl::true_) +// { +// const serialization::collection_size_type count(t.size()); +// * this->This() << BOOST_SERIALIZATION_NVP(count); +// if (!t.empty()) +// * this->This() << serialization::make_array(serialization::detail::get_data(t),t.size()); +// } + + // the optimized implementation for serialization::array uses save_array + template + void save_optimized( + const serialization::array &t, unsigned int version, mpl::true_) + { + this->This()->save_array(t,version); + } + + + // to save a vector: + // if the value type is trivially constructable or an optimized array save exists, + // then we can use the optimized version + +// template +// void save_override(std::vector const &x, unsigned int version) +// { +// typedef BOOST_DEDUCED_TYPENAME remove_const::type value_type; +// typedef typename mpl::and_< +// mpl::not_ >, +// mpl::apply1< +// BOOST_DEDUCED_TYPENAME Archive::use_array_optimization +// , value_type> +// >::type use_optimized; +// save_optimized(x,version,use_optimized() ); +// } + + + + // dispatch saving of arrays to the optimized version where supported + template + void save_override(serialization::array const& x, unsigned int version) + { + typedef typename mpl::apply1< + BOOST_DEDUCED_TYPENAME Archive::use_array_optimization + , BOOST_DEDUCED_TYPENAME remove_const::type + >::type use_optimized; + save_optimized(x,version,use_optimized()); + } + + // Load everything else in the usual way, forwarding on to the + // Base class + template + void save_override(T const& x, unsigned BOOST_PFTO int version) + { + Base::save_override(x, static_cast(version)); + } +}; + +} } } // end namespace boost::archive::array + + +#endif // BOOST_ARCHIVE_ARRAY_OARCHIVE_HPP + diff --git a/thirdparty/boost/archive/basic_archive.hpp b/thirdparty/boost/archive/basic_archive.hpp new file mode 100644 index 0000000..9a602d4 --- /dev/null +++ b/thirdparty/boost/archive/basic_archive.hpp @@ -0,0 +1,120 @@ +#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace archive { + +BOOST_STRONG_TYPEDEF(unsigned int, version_type) +BOOST_STRONG_TYPEDEF(int, class_id_type) +BOOST_STRONG_TYPEDEF(int, class_id_optional_type) +BOOST_STRONG_TYPEDEF(int, class_id_reference_type) +BOOST_STRONG_TYPEDEF(unsigned int, object_id_type) +BOOST_STRONG_TYPEDEF(unsigned int, object_reference_type) + +struct tracking_type { + typedef bool value_type; + bool t; + explicit tracking_type(const bool t_ = false) + : t(t_) + {}; + tracking_type(const tracking_type & t_) + : t(t_.t) + {} + operator bool () const { + return t; + }; + operator bool & () { + return t; + }; + tracking_type & operator=(const bool t_){ + t = t_; + return *this; + } + bool operator==(const tracking_type & rhs) const { + return t == rhs.t; + } + bool operator==(const bool & rhs) const { + return t == rhs; + } + tracking_type & operator=(const tracking_type & rhs){ + t = rhs.t; + return *this; + } +}; + +struct class_name_type : private boost::noncopyable { + char *t; + operator const char * & () const { + return const_cast(t); + } + operator char * () { + return t; + } + explicit class_name_type(const char *key_) + : t(const_cast(key_)){} + explicit class_name_type(char *key_) + : t(key_){} + class_name_type & operator=(const class_name_type & rhs){ + t = rhs.t; + return *this; + } +}; + +enum archive_flags { + no_header = 1, // suppress archive header info + no_codecvt = 2, // suppress alteration of codecvt facet + no_xml_tag_checking = 4, // suppress checking of xml tags + no_tracking = 8 // suppress ALL tracking +// no_object_creation = 16 // don't create any new objects +}; + +#define NULL_POINTER_TAG class_id_type(-1) + +BOOST_ARCHIVE_DECL(const char *) +ARCHIVE_SIGNATURE(); + +BOOST_ARCHIVE_DECL(unsigned char) +ARCHIVE_VERSION(); + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#include + +// set implementation level to primitive for all types +// used internally by the serialization library + +BOOST_CLASS_IMPLEMENTATION(boost::archive::version_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_optional_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_name_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type) + +#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_binary_iarchive.hpp b/thirdparty/boost/archive/basic_binary_iarchive.hpp new file mode 100644 index 0000000..b4babcc --- /dev/null +++ b/thirdparty/boost/archive/basic_binary_iarchive.hpp @@ -0,0 +1,125 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +//#include + +#include +#include +#include + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_iarchive - read serialized objects from a input binary stream +template +class basic_binary_iarchive : + public array::iarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; +#else + friend class detail::interface_iarchive; +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering. If we get here pass to base class + // note extra nonsense to sneak it pass the borland compiers + typedef array::iarchive array_iarchive; + template + void load_override(T & t, BOOST_PFTO int){ + this->array_iarchive::load_override(t, 0); + } + // binary files don't include the optional information + void load_override(class_id_optional_type & /* t */, int){} + + // the following have been overridden to provide specific sizes + // for these pseudo prmitive types. + void load_override(version_type & t, int){ + // upto 255 versions + unsigned char x=0; + * this->This() >> x; + t = version_type(x); + } + void load_override(class_id_type & t, int){ + // upto 32K classes + int_least16_t x=0; + * this->This() >> x; + t = class_id_type(x); + } + void load_override(class_id_reference_type & t, int){ + // upto 32K classes + int_least16_t x=0; + * this->This() >> x; + t = class_id_reference_type(x); + } + void load_override(object_id_type & t, int){ + // upto 2G objects + uint_least32_t x=0; + * this->This() >> x; + t = object_id_type(x); + } + void load_override(object_reference_type & t, int){ + // upto 2G objects + uint_least32_t x=0; + * this->This() >> x; + t = object_reference_type(x); + } + void load_override(tracking_type & t, int){ + char x=0; + * this->This() >> x; + t = (0 != x); + } + void load_override(serialization::collection_size_type & t, int){ + unsigned int x=0; + * this->This() >> x; + t = serialization::collection_size_type(x); + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(class_name_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + + basic_binary_iarchive(unsigned int flags) : + array_iarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_binary_iprimitive.hpp b/thirdparty/boost/archive/basic_binary_iprimitive.hpp new file mode 100644 index 0000000..c670c67 --- /dev/null +++ b/thirdparty/boost/archive/basic_binary_iprimitive.hpp @@ -0,0 +1,192 @@ +#ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include // std::memcpy +#include // std::size_t +#include // basic_streambuf +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +//#include +//#include + +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////////// +// class binary_iarchive - read serialized objects from a input binary stream +template +class basic_binary_iprimitive +{ +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class load_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + boost::scoped_ptr archive_locale; + basic_streambuf_locale_saver locale_saver; + + // main template for serilization of primitive types + template + void load(T & t){ + load_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean + void load(bool & t){ + load_binary(& t, sizeof(t)); + int i = t; + assert(0 == i || 1 == i); + (void)i; // warning suppression for release builds. + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load(std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load(char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load(wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_binary_iprimitive(); +public: + // we provide an optimized load for all fundamental types + //typedef serialization::is_bitwise_serializable + // use_array_optimization; + struct use_array_optimization { + template + struct apply : public serialization::is_bitwise_serializable {}; + }; + + // the optimized load_array dispatches to load_binary + template + void load_array(serialization::array& a, unsigned int) + { + load_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void + load_binary(void *address, std::size_t count); +}; + +template +inline void +basic_binary_iprimitive::load_binary( + void *address, + std::size_t count +){ +#if 0 + assert( + static_cast((std::numeric_limits::max)()) >= count + ); + //if(is.fail()) + // boost::throw_exception(archive_exception(archive_exception::stream_error)); + // note: an optimizer should eliminate the following for char files + std::size_t s = count / sizeof(BOOST_DEDUCED_TYPENAME IStream::char_type); + is.read( + static_cast(address), + s + ); + // note: an optimizer should eliminate the following for char files + s = count % sizeof(BOOST_DEDUCED_TYPENAME IStream::char_type); + if(0 < s){ + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + BOOST_DEDUCED_TYPENAME IStream::char_type t; + is.read(& t, 1); + std::memcpy(address, &t, s); + } +#endif + // note: an optimizer should eliminate the following for char files + std::streamsize s = count / sizeof(Elem); + std::streamsize scount = m_sb.sgetn( + static_cast(address), + s + ); + if(scount != static_cast(s)) + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + // note: an optimizer should eliminate the following for char files + s = count % sizeof(Elem); + if(0 < s){ +// if(is.fail()) +// boost::throw_exception(archive_exception(archive_exception::stream_error)); + Elem t; + scount = m_sb.sgetn(& t, 1); + if(scount != 1) + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + std::memcpy(address, &t, s); + } +} + +} // namespace archive +} // namespace boost + +#include // pop pragams + +#endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP diff --git a/thirdparty/boost/archive/basic_binary_oarchive.hpp b/thirdparty/boost/archive/basic_binary_oarchive.hpp new file mode 100644 index 0000000..1696715 --- /dev/null +++ b/thirdparty/boost/archive/basic_binary_oarchive.hpp @@ -0,0 +1,127 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// class basic_binary_oarchive - write serialized objects to a binary output stream +// note: this archive has no pretensions to portability. Archive format +// may vary across machine architectures and compilers. About the only +// guarentee is that an archive created with this code will be readable +// by a program built with the same tools for the same machne. This class +// does have the virtue of buiding the smalles archive in the minimum amount +// of time. So under some circumstances it may be he right choice. +template +class basic_binary_oarchive : + public array::oarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; +#else + friend class detail::interface_oarchive; +#endif + // any datatype not specifed below will be handled by base class + typedef array::oarchive array_oarchive; + template + void save_override(const T & t, BOOST_PFTO int){ + this->array_oarchive::save_override(t, 0); + } + template + void save_override(T & t, BOOST_PFTO int){ + this->save_override(const_cast(t), 0); + } + // binary files don't include the optional information + void save_override(const class_id_optional_type & /* t */, int){} + + void save_override(const version_type & t, int){ + // upto 255 versions + // note:t.t resolves borland ambguity + const unsigned char x = t.t; + * this->This() << x; + } + void save_override(const class_id_type & t, int){ + // upto 32K classes + const int_least16_t x = t.t; + * this->This() << x; + } + void save_override(const class_id_reference_type & t, int){ + // upto 32K classes + const int_least16_t x = t.t; + * this->This() << x; + } + void save_override(const object_id_type & t, int){ + // upto 2G objects + const uint_least32_t x = t.t; + * this->This() << x; + } + void save_override(const object_reference_type & t, int){ + // upto 2G objects + uint_least32_t x = t.t; + * this->This() << x; + } + void save_override(const tracking_type & t, int){ + const char x = t.t; + * this->This() << x; + } + + // explicitly convert to char * to avoid compile ambiguities + void save_override(const class_name_type & t, int){ + const std::string s(t); + * this->This() << s; + } + + void save_override(const serialization::collection_size_type & t, int){ + // for backward compatibility, 64 bit integer or variable length integer would be preferred + unsigned int x = t.t; + * this->This() << x; + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + + basic_binary_oarchive(unsigned int flags) : + array_oarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_binary_oprimitive.hpp b/thirdparty/boost/archive/basic_binary_oprimitive.hpp new file mode 100644 index 0000000..5c39f0f --- /dev/null +++ b/thirdparty/boost/archive/basic_binary_oprimitive.hpp @@ -0,0 +1,173 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include +#include +#include // size_t +#include // basic_streambuf +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +//#include +//#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_oprimitive - binary output of prmitives + +template +class basic_binary_oprimitive +{ +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class save_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + boost::scoped_ptr archive_locale; + basic_streambuf_locale_saver locale_saver; + + // default saving of primitives. + template + void save(const T & t) + { + save_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + void save(const bool t){ + int i = t; + assert(0 == i || 1 == i); + save_binary(& t, sizeof(t)); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save(const char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save(const wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_binary_oprimitive(); +public: + + // we provide an optimized save for all fundamental types + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + // workaround without using mpl lambdas + struct use_array_optimization { + template + struct apply : public serialization::is_bitwise_serializable {}; + }; + + + // the optimized save_array dispatches to save_binary + template + void save_array(serialization::array const& a, unsigned int) + { + save_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void save_binary(const void *address, std::size_t count); +}; + +template +inline void +basic_binary_oprimitive::save_binary( + const void *address, + std::size_t count +){ + //assert( + // static_cast((std::numeric_limits::max)()) >= count + //); + // note: if the following assertions fail + // a likely cause is that the output stream is set to "text" + // mode where by cr characters recieve special treatment. + // be sure that the output stream is opened with ios::binary + //if(os.fail()) + // boost::throw_exception(archive_exception(archive_exception::stream_error)); + // figure number of elements to output - round up + count = ( count + sizeof(Elem) - 1) + / sizeof(Elem); + std::streamsize scount = m_sb.sputn( + static_cast(address), + count + ); + if(count != static_cast(scount)) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + //os.write( + // static_cast(address), + // count + //); + //assert(os.good()); +} + +} //namespace boost +} //namespace archive + +#include // pop pragams + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP diff --git a/thirdparty/boost/archive/basic_streambuf_locale_saver.hpp b/thirdparty/boost/archive/basic_streambuf_locale_saver.hpp new file mode 100644 index 0000000..bf8788f --- /dev/null +++ b/thirdparty/boost/archive/basic_streambuf_locale_saver.hpp @@ -0,0 +1,61 @@ +#ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP +#define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_streambuf_local_saver.hpp + +// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note derived from boost/io/ios_state.hpp +// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_NO_STD_LOCALE +#include // for std::locale +#endif +#include // for std::basic_streambuf + +namespace boost{ +namespace archive{ + +#ifndef BOOST_NO_STD_LOCALE +template < typename Ch, class Tr > +class basic_streambuf_locale_saver +{ +public: + typedef ::std::basic_streambuf state_type; + typedef ::std::locale aspect_type; + explicit basic_streambuf_locale_saver( state_type &s ) + : s_save_( s ), a_save_( s.getloc() ) + {} + basic_streambuf_locale_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.pubimbue(a) ) + {} + ~basic_streambuf_locale_saver() + { this->restore(); } + void restore() + { s_save_.pubimbue( a_save_ ); } +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +} // archive +} // boost + +#endif // BOOST_NO_STD_LOCALE +#endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP diff --git a/thirdparty/boost/archive/basic_text_iarchive.hpp b/thirdparty/boost/archive/basic_text_iarchive.hpp new file mode 100644 index 0000000..ad3dc67 --- /dev/null +++ b/thirdparty/boost/archive/basic_text_iarchive.hpp @@ -0,0 +1,94 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include + +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - read serialized objects from a input text stream +template +class basic_text_iarchive : + public detail::common_iarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; +#else + friend class detail::interface_iarchive; +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override(T & t, BOOST_PFTO int) + { + this->detail_common_iarchive::load_override(t, 0); + } +#if 0 + // Borland compilers has a problem with strong type. Try to fix this here + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + void load_override(version_type & t, int){ + unsigned int x; + * this->This() >> x; + t.t = version_type(x); + } + #endif +#endif + // text file don't include the optional information + void load_override(class_id_optional_type & /*t*/, int){} + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(class_name_type & t, int); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(void); + + basic_text_iarchive(unsigned int flags) : + detail::common_iarchive(flags) + {} + ~basic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_text_iprimitive.hpp b/thirdparty/boost/archive/basic_text_iprimitive.hpp new file mode 100644 index 0000000..34f4e77 --- /dev/null +++ b/thirdparty/boost/archive/basic_text_iprimitive.hpp @@ -0,0 +1,130 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include +#include +#include +#include + +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - load serialized objects from a input text stream +template +class basic_text_iprimitive +{ +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +protected: +#else +public: +#endif + IStream &is; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + boost::scoped_ptr archive_locale; + io::basic_ios_locale_saver< + BOOST_DEDUCED_TYPENAME IStream::char_type, BOOST_DEDUCED_TYPENAME IStream::traits_type + > locale_saver; + template + void load(T & t) + { + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + is >> t; + } + void load(unsigned char & t) + { + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + unsigned short int i; + is >> i; + t = static_cast(i); + } + void load(signed char & t) + { + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + signed short int i; + is >> i; + t = static_cast(i); + } + void load(char & t) + { + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + short int i; + is >> i; + t = static_cast(i); + } + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void load(wchar_t & t) + { + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + unsigned i; + is >> i; + t = static_cast(i); + } + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_text_iprimitive(IStream &is, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_text_iprimitive(); +public: + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_binary(void *address, std::size_t count); +}; + +} // namespace archive +} // namespace boost + +#include // pop pragams + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP diff --git a/thirdparty/boost/archive/basic_text_oarchive.hpp b/thirdparty/boost/archive/basic_text_oarchive.hpp new file mode 100644 index 0000000..fa4b24d --- /dev/null +++ b/thirdparty/boost/archive/basic_text_oarchive.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include +#include + +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - read serialized objects from a input text stream +template +class basic_text_oarchive : + public detail::common_oarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ +|| BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x560)) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; +#else + friend class detail::interface_oarchive; +#endif + enum { + none, + eol, + space + } delimiter; + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + newtoken(); + + void newline(){ + delimiter = eol; + } + + // default processing - kick back to base class. Note the + // extra stuff to get it passed borland compilers + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override(T & t, BOOST_PFTO int){ + this->detail_common_oarchive::save_override(t, 0); + } + + // start new objects on a new line + void save_override(const object_id_type & t, int){ + this->This()->newline(); + // note extra .t to funciton with Borland 5.51 compiler + // and invoke prmitive to underlying value + this->This()->save(t.t); + } + + void save_override(const object_reference_type & t, int){ + this->This()->newline(); + // note extra .t to funciton with Borland 5.51 compiler + // and invoke prmitive to underlying value + this->This()->save(t.t); + } + + // note the following four overrides are necessary for some borland + // compilers(5.51) which don't handle BOOST_STRONG_TYPE properly. + void save_override(const version_type & t, int){ + // note:t.t resolves borland ambguity + const unsigned int x = t.t; + * this->This() << x; + } + void save_override(const class_id_type & t, int){ + // note:t.t resolves borland ambguity + const int x = t.t; + * this->This() << x; + } + void save_override(const class_id_reference_type & t, int){ + // note:t.t resolves borland ambguity + const int x = t.t; + * this->This() << x; + } + + // text file don't include the optional information + void save_override(const class_id_optional_type & /* t */, int){} + + void save_override(const class_name_type & t, int){ + const std::string s(t); + * this->This() << s; + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + + basic_text_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + delimiter(none) + {} + ~basic_text_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_text_oprimitive.hpp b/thirdparty/boost/archive/basic_text_oprimitive.hpp new file mode 100644 index 0000000..682ae8a --- /dev/null +++ b/thirdparty/boost/archive/basic_text_oprimitive.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include // size_t +#include // isnan +#include + +#include +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +class save_access; + +///////////////////////////////////////////////////////////////////////// +// class basic_text_oprimitive - output of prmitives to stream +template +class basic_text_oprimitive +{ +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +protected: +#else +public: +#endif + OStream &os; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + boost::scoped_ptr archive_locale; + io::basic_ios_locale_saver< + BOOST_DEDUCED_TYPENAME OStream::char_type, BOOST_DEDUCED_TYPENAME OStream::traits_type + > locale_saver; + + // default saving of primitives. + template + void save(const T &t){ + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << t; + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + void save(const bool t){ + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + int i = t; + assert(0 == i || 1 == i); + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << t; + } + void save(const signed char t) + { + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << static_cast(t); + } + void save(const unsigned char t) + { + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << static_cast(t); + } + void save(const char t) + { + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << static_cast(t); + } + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void save(const wchar_t t) + { + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << static_cast(t); + } + #endif + void save(const float t) + { + // must be a user mistake - can't serialize un-initialized data + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << std::setprecision(std::numeric_limits::digits10 + 2); + os << t; + } + void save(const double t) + { + // must be a user mistake - can't serialize un-initialized data + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os << std::setprecision(std::numeric_limits::digits10 + 2); + os << t; + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_text_oprimitive(OStream & os, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_text_oprimitive(); +public: + // unformatted append of one character + void put(int c){ + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + os.put(c); + } + // unformatted append of null terminated string + void put(const char * s){ + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + while('\0' != *s) + os.put(*s++); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_binary(const void *address, std::size_t count); +}; + +} //namespace boost +} //namespace archive + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP diff --git a/thirdparty/boost/archive/basic_xml_archive.hpp b/thirdparty/boost/archive/basic_xml_archive.hpp new file mode 100644 index 0000000..b4f85f0 --- /dev/null +++ b/thirdparty/boost/archive/basic_xml_archive.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_archive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml archives +// +class xml_archive_exception : + public virtual archive_exception +{ +public: + typedef enum { + xml_archive_parsing_error, // see save_register + xml_archive_tag_mismatch, + xml_archive_tag_name_error + } exception_code; + xml_archive_exception(exception_code c) + {} + virtual const char *what( ) const throw( ) + { + const char *msg; + switch(code){ + case xml_archive_parsing_error: + msg = "unrecognized XML syntax"; + break; + case xml_archive_tag_mismatch: + msg = "XML start/end tag mismatch"; + break; + case xml_archive_tag_name_error: + msg = "Invalid XML tag name"; + break; + default: + msg = archive_exception::what(); + break; + } + return msg; + } +}; + +// constant strings used in xml i/o + +extern +BOOST_ARCHIVE_DECL(const char *) +OBJECT_ID(); + +extern +BOOST_ARCHIVE_DECL(const char *) +OBJECT_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL(const char *) +CLASS_ID(); + +extern +BOOST_ARCHIVE_DECL(const char *) +CLASS_ID_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL(const char *) +CLASS_NAME(); + +extern +BOOST_ARCHIVE_DECL(const char *) +TRACKING(); + +extern +BOOST_ARCHIVE_DECL(const char *) +VERSION(); + +extern +BOOST_ARCHIVE_DECL(const char *) +SIGNATURE(); + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + diff --git a/thirdparty/boost/archive/basic_xml_iarchive.hpp b/thirdparty/boost/archive/basic_xml_iarchive.hpp new file mode 100644 index 0000000..385facf --- /dev/null +++ b/thirdparty/boost/archive/basic_xml_iarchive.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include + +#include +#include + +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class xml_iarchive - read serialized objects from a input text stream +template +class basic_xml_iarchive : + public detail::common_iarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; +#else + friend class detail::interface_oarchive; +#endif + unsigned int depth; + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_end(const char *name); + + // Anything not an attribute and not a name-value pair is an + // should be trapped here. + template + void load_override(T & t, BOOST_PFTO int) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper)); + this->detail_common_iarchive::load_override(t, 0); + } + + // Anything not an attribute - see below - should be a name value + // pair and be processed here + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + boost::serialization::nvp & t, + int + ){ + load_start(t.name()); + this->detail_common_iarchive::load_override(t.value(), 0); + load_end(t.name()); + } + + // specific overrides for attributes - handle as + // primitives. These are not name-value pairs + // so they have to be intercepted here and passed on to load. + // although the class_id is included in the xml text file in order + // to make the file self describing, it isn't used when loading + // an xml archive. So we can skip it here. Note: we MUST override + // it otherwise it will be loaded as a normal primitive w/o tag and + // leaving the archive in an undetermined state + void load_override(class_id_optional_type & /* t */, int){} + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(object_id_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(version_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(class_id_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + load_override(tracking_type & t, int); + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation + // handle this. + // void load_override(class_name_type & t, int); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_xml_iarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_xml_iarchive(); +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/basic_xml_oarchive.hpp b/thirdparty/boost/archive/basic_xml_oarchive.hpp new file mode 100644 index 0000000..90773db --- /dev/null +++ b/thirdparty/boost/archive/basic_xml_oarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include + +#include + +#include // must be the last header + + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// class basic_xml_oarchive - write serialized objects to a xml output stream +template +class basic_xml_oarchive : + public detail::common_oarchive +{ +protected: +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +public: +#elif defined(BOOST_MSVC) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + friend class save_access; +#else + friend class detail::interface_oarchive; + friend class save_access; +#endif + // special stuff for xml output + unsigned int depth; + bool indent_next; + bool pending_preamble; + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + indent(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + write_attribute( + const char *attribute_name, + int t, + const char *conjunction = "=\"" + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + write_attribute( + const char *attribute_name, + const char *key + ); + // helpers used below + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_end(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + end_preamble(); + + // Anything not an attribute and not a name-value pair is an + // error and should be trapped here. + template + void save_override(T & t, BOOST_PFTO int) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper)); + this->detail_common_oarchive::save_override(t, 0); + } + + // special treatment for name-value pairs. + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + ::boost::serialization::nvp & t, + int + ){ + save_start(t.name()); + this->detail_common_oarchive::save_override(t.const_value(), 0); + save_end(t.name()); + } + + // specific overrides for attributes - not name value pairs so we + // want to trap them before the above "fall through" + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const object_id_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const object_reference_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const version_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const class_id_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const class_id_optional_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const class_id_reference_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const class_name_type & t, int); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) + save_override(const tracking_type & t, int); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + basic_xml_oarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~basic_xml_oarchive(); +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/binary_iarchive.hpp b/thirdparty/boost/archive/binary_iarchive.hpp new file mode 100644 index 0000000..a0eae5c --- /dev/null +++ b/thirdparty/boost/archive/binary_iarchive.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost { +namespace archive { + +// do not derive from the classes below. If you want to extend this functionality +// via inhertance, derived from text_iarchive_impl instead. This will +// preserve correct static polymorphism. + +// same as binary_iarchive below - without the shared_ptr_helper +class naked_binary_iarchive : + public binary_iarchive_impl< + boost::archive::naked_binary_iarchive, + std::istream::char_type, + std::istream::traits_type + > +{ +public: + naked_binary_iarchive(std::istream & is, unsigned int flags = 0) : + binary_iarchive_impl< + naked_binary_iarchive, std::istream::char_type, std::istream::traits_type + >(is, flags) + {} + naked_binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + naked_binary_iarchive, std::istream::char_type, std::istream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_iarchive_impl instead. This will +// preserve correct static polymorphism. +class binary_iarchive : + public binary_iarchive_impl< + boost::archive::binary_iarchive, + std::istream::char_type, + std::istream::traits_type + >, + public detail::shared_ptr_helper +{ +public: + binary_iarchive(std::istream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(is, flags) + {} + binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive) + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/binary_iarchive_impl.hpp b/thirdparty/boost/archive/binary_iarchive_impl.hpp new file mode 100644 index 0000000..57c70d3 --- /dev/null +++ b/thirdparty/boost/archive/binary_iarchive_impl.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive_impl.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +template +class binary_iarchive_impl : + public basic_binary_iprimitive, + public basic_binary_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class basic_binary_iarchive; + friend class load_access; +protected: +#endif + // note: the following should not needed - but one compiler (vc 7.1) + // fails to compile one test (test_shared_ptr) without it !!! + // make this protected so it can be called from a derived archive + template + void load_override(T & t, BOOST_PFTO int){ + basic_binary_iarchive::load_override(t, 0); + } + void init(unsigned int flags){ + if(0 != (flags & no_header)) + return; + #if ! defined(__MWERKS__) + this->basic_binary_iarchive::init(); + this->basic_binary_iprimitive::init(); + #else + basic_binary_iarchive::init(); + basic_binary_iprimitive::init(); + #endif + } + binary_iarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_iprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } + binary_iarchive_impl( + std::basic_istream & is, + unsigned int flags + ) : + basic_binary_iprimitive( + * is.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP diff --git a/thirdparty/boost/archive/binary_oarchive.hpp b/thirdparty/boost/archive/binary_oarchive.hpp new file mode 100644 index 0000000..45953e3 --- /dev/null +++ b/thirdparty/boost/archive/binary_oarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class binary_oarchive : + public binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + > +{ +public: + binary_oarchive(std::ostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(os, flags) + {} + binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(bsb, flags) + {} +}; + +typedef binary_oarchive naked_binary_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive) + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/binary_oarchive_impl.hpp b/thirdparty/boost/archive/binary_oarchive_impl.hpp new file mode 100644 index 0000000..7a5b0aa --- /dev/null +++ b/thirdparty/boost/archive/binary_oarchive_impl.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive_impl.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +template +class binary_oarchive_impl : + public basic_binary_oprimitive, + public basic_binary_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class basic_binary_oarchive; + friend class save_access; +protected: +#endif + // note: the following should not needed - but one compiler (vc 7.1) + // fails to compile one test (test_shared_ptr) without it !!! + // make this protected so it can be called from a derived archive + template + void save_override(T & t, BOOST_PFTO int){ + basic_binary_oarchive::save_override(t, 0); + } + void init(unsigned int flags) { + if(0 != (flags & no_header)) + return; + #if ! defined(__MWERKS__) + this->basic_binary_oarchive::init(); + this->basic_binary_oprimitive::init(); + #else + basic_binary_oarchive::init(); + basic_binary_oprimitive::init(); + #endif + } + binary_oarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_oprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } + binary_oarchive_impl( + std::basic_ostream & os, + unsigned int flags + ) : + basic_binary_oprimitive( + * os.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP diff --git a/thirdparty/boost/archive/binary_wiarchive.hpp b/thirdparty/boost/archive/binary_wiarchive.hpp new file mode 100644 index 0000000..780621b --- /dev/null +++ b/thirdparty/boost/archive/binary_wiarchive.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include // wistream +#include + +namespace boost { +namespace archive { + +// same as binary_wiarchive below - without the shared_ptr_helper +class naked_binary_wiarchive : + public binary_iarchive_impl< + boost::archive::naked_binary_wiarchive, + std::wistream::char_type, + std::wistream::traits_type + > +{ +public: + naked_binary_wiarchive(std::wistream & is, unsigned int flags = 0) : + binary_iarchive_impl< + naked_binary_wiarchive, + std::wistream::char_type, + std::wistream::traits_type + >(is, flags) + {} + naked_binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + naked_binary_wiarchive, + std::wistream::char_type, + std::wistream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class binary_wiarchive : + public binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + > +{ +public: + binary_wiarchive(std::wistream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(is, flags) + {} + binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP diff --git a/thirdparty/boost/archive/binary_woarchive.hpp b/thirdparty/boost/archive/binary_woarchive.hpp new file mode 100644 index 0000000..e39382a --- /dev/null +++ b/thirdparty/boost/archive/binary_woarchive.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class binary_woarchive : + public binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + > +{ +public: + binary_woarchive(std::wostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(os, flags) + {} + binary_woarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(bsb, flags) + {} +}; + +typedef binary_woarchive naked_binary_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP diff --git a/thirdparty/boost/archive/codecvt_null.hpp b/thirdparty/boost/archive/codecvt_null.hpp new file mode 100644 index 0000000..fda2c7b --- /dev/null +++ b/thirdparty/boost/archive/codecvt_null.hpp @@ -0,0 +1,93 @@ +#ifndef BOOST_ARCHIVE_CODECVT_NULL_HPP +#define BOOST_ARCHIVE_CODECVT_NULL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// codecvt_null.hpp: + +// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include + +namespace std{ + #if defined(__LIBCOMO__) + using ::mbstate_t; + #elif defined(__QNXNTO__) + //using std::mbstate_t; + #elif defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB == 1 + using ::mbstate_t; + #elif defined(__SGI_STL_PORT) + #elif defined(BOOST_NO_STDC_NAMESPACE) + using ::codecvt; + using ::mbstate_t; + #elif defined(BOOST_RWSTD_VER) + using ::mbstate_t; + #endif +} // namespace std + +namespace boost { +namespace archive { + +template +class codecvt_null; + +template<> +class codecvt_null : public std::codecvt +{ + virtual bool do_always_noconv() const throw() { + return true; + } +public: + explicit codecvt_null(std::size_t no_locale_manage = 0) : + std::codecvt(no_locale_manage) + {} +}; + +template<> +class codecvt_null : public std::codecvt +{ + virtual BOOST_ARCHIVE_DECL(std::codecvt_base::result) + do_out( + std::mbstate_t & state, + const wchar_t * first1, + const wchar_t * last1, + const wchar_t * & next1, + char * first2, + char * last2, + char * & next2 + ) const; + virtual BOOST_ARCHIVE_DECL(std::codecvt_base::result) + do_in( + std::mbstate_t & state, + const char * first1, + const char * last1, + const char * & next1, + wchar_t * first2, + wchar_t * last2, + wchar_t * & next2 + ) const; + virtual int do_encoding( ) const throw( ){ + return sizeof(wchar_t) / sizeof(char); + } + virtual int do_max_length( ) const throw( ){ + return do_encoding(); + } +}; + +} // namespace archive +} // namespace boost + +#endif //BOOST_ARCHIVE_CODECVT_NULL_HPP diff --git a/thirdparty/boost/archive/detail/abi_prefix.hpp b/thirdparty/boost/archive/detail/abi_prefix.hpp new file mode 100644 index 0000000..093a109 --- /dev/null +++ b/thirdparty/boost/archive/detail/abi_prefix.hpp @@ -0,0 +1,20 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_prefix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/thirdparty/boost/archive/detail/abi_suffix.hpp b/thirdparty/boost/archive/detail/abi_suffix.hpp new file mode 100644 index 0000000..61061ca --- /dev/null +++ b/thirdparty/boost/archive/detail/abi_suffix.hpp @@ -0,0 +1,19 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_suffix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/thirdparty/boost/archive/detail/archive_pointer_iserializer.hpp b/thirdparty/boost/archive/detail/archive_pointer_iserializer.hpp new file mode 100644 index 0000000..38fa5bc --- /dev/null +++ b/thirdparty/boost/archive/detail/archive_pointer_iserializer.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_POINTER_ISERIALIZER_POINTER_HPP +#define BOOST_ARCHIVE_ARCHIVE_POINTER_ISERIALIZER_POINTER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_pointer_iserializer.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +template +class archive_pointer_iserializer : + public basic_pointer_iserializer { +protected: + explicit BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + archive_pointer_iserializer( + const boost::serialization::extended_type_info & eti + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~archive_pointer_iserializer(); +public: + virtual const basic_iserializer & get_basic_serializer() const + // mscvc 6.0 requires template functions to be implemented. For this + // reason we can't make abstract. + #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || defined(__MWERKS__) + { + assert(false); + return *static_cast(NULL); + } + #else + = 0; + #endif + virtual void load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version + ) const + #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || defined(__MWERKS__) + { + assert(false); + } + #else + = 0; + #endif + // return the type_extended load pointer corresponding to a given + // type_info. returns NULL if there is no such instance. This + // would indicate that the no object of the specified type was loaded + // any where in the code. + static + BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *) + find( + const boost::serialization::extended_type_info & eti + ); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_ARCHIVE_POINTER_ISERIALIZER_POINTER_HPP diff --git a/thirdparty/boost/archive/detail/archive_pointer_oserializer.hpp b/thirdparty/boost/archive/detail/archive_pointer_oserializer.hpp new file mode 100644 index 0000000..d87c3b5 --- /dev/null +++ b/thirdparty/boost/archive/detail/archive_pointer_oserializer.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_POINTER_OSERIALIZER_POINTER_HPP +#define BOOST_ARCHIVE_ARCHIVE_POINTER_OSERIALIZER_POINTER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +template +class archive_pointer_oserializer : + public basic_pointer_oserializer { +protected: + explicit BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + archive_pointer_oserializer( + const boost::serialization::extended_type_info & eti + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~archive_pointer_oserializer(); +public: + // return the type_extended save pointer corresponding to a give + // type_info. returns NULL, if there is no such instance. This + // would indicate that the no object of the specified type was saved + // any where in the code. + static + BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *) + find( + const boost::serialization::extended_type_info & eti + ); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_ARCHIVE_POINTER_OSERIALIZER_POINTER_HPP diff --git a/thirdparty/boost/archive/detail/auto_link_archive.hpp b/thirdparty/boost/archive/detail/auto_link_archive.hpp new file mode 100644 index 0000000..54c32ee --- /dev/null +++ b/thirdparty/boost/archive/detail/auto_link_archive.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_archive.hpp +// +// © Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_ARCHIVE_SOURCE) \ +&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_serialization +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/auto_link_warchive.hpp b/thirdparty/boost/archive/detail/auto_link_warchive.hpp new file mode 100644 index 0000000..6e72241 --- /dev/null +++ b/thirdparty/boost/archive/detail/auto_link_warchive.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_warchive.hpp +// +// © Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_wserialization +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/basic_archive_impl.hpp b/thirdparty/boost/archive/detail/basic_archive_impl.hpp new file mode 100644 index 0000000..dd01cff --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_archive_impl.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive_impl.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// can't use this - much as I'd like to as borland doesn't support it +// #include + +#include + +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +////////////////////////////////////////////////////////////////////// +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_archive_impl +{ +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_DETAIL_BASIC_ARCHIVE_IMPL_HPP + + + diff --git a/thirdparty/boost/archive/detail/basic_config.hpp b/thirdparty/boost/archive/detail/basic_config.hpp new file mode 100644 index 0000000..f6094de --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_config.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// basic_config.hpp ---------------------------------------------// + +// © Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include + +#ifdef BOOST_HAS_DECLSPEC // defined in config system +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_ARCHIVE_DYN_LINK +// if they want just this one to be dynamically linked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ARCHIVE_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_ARCHIVE_SOURCE +# define BOOST_ARCHIVE_DECL __declspec(dllexport) +#else +# define BOOST_ARCHIVE_DECL __declspec(dllimport) +#endif // BOOST_ARCHIVE_SOURCE +#endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_ARCHIVE_DECL isn't defined yet define it now: +#ifndef BOOST_ARCHIVE_DECL +#define BOOST_ARCHIVE_DECL +#endif + +#endif // BOOST_ARCHIVE_DETAIL_BASIC_CONFIG_HPP diff --git a/thirdparty/boost/archive/detail/basic_iarchive.hpp b/thirdparty/boost/archive/detail/basic_iarchive.hpp new file mode 100644 index 0000000..f0294a9 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_iarchive.hpp @@ -0,0 +1,108 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// can't use this - much as I'd like to as borland doesn't support it +// #include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +template +class shared_ptr; + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_iarchive_impl; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer; +////////////////////////////////////////////////////////////////////// +// class basic_iarchive - read serialized objects from a input stream +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive +{ + friend class basic_iarchive_impl; + // hide implementation of this class to minimize header conclusion + // in client code. I couldn't used scoped pointer with borland + // boost::scoped_ptr pimpl; + basic_iarchive_impl * pimpl; + + virtual void vload(version_type &t) = 0; + virtual void vload(object_id_type &t) = 0; + virtual void vload(class_id_type &t) = 0; + virtual void vload(class_id_optional_type &t) = 0; + virtual void vload(class_name_type &t) = 0; + virtual void vload(tracking_type &t) = 0; +protected: + basic_iarchive(unsigned int flags); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_iarchive(); +public: + // note: NOT part of the public API. + void next_object_pointer(void *t); + void register_basic_serializer( + const basic_iserializer & bis + ); + void load_object( + void *t, + const basic_iserializer & bis + ); + const basic_pointer_iserializer * + load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & eti + ) + ); + // real public API starts here + void + set_library_version(unsigned int archive_library_version); + unsigned int + get_library_version() const; + unsigned int + get_flags() const; + void + reset_object_address(const void * new_address, const void * old_address); + void + delete_created_pointers(); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +// required by smart_cast for compilers not implementing +// partial template specialization +BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION( + boost::archive::detail::basic_iarchive +) + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/basic_iserializer.hpp b/thirdparty/boost/archive/detail/basic_iserializer.hpp new file mode 100644 index 0000000..22d9ad3 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_iserializer.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iserializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL +#include + +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer; + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer : + public basic_serializer +{ +private: + basic_pointer_iserializer *bpis; +protected: + explicit basic_iserializer( + const boost::serialization::extended_type_info & type_ + ); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_iserializer(); +public: + bool serialized_as_pointer() const { + return bpis != NULL; + } + void set_bpis(basic_pointer_iserializer *bpis_){ + bpis = bpis_; + } + const basic_pointer_iserializer * get_bpis_ptr() const { + return bpis; + } + virtual void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0 ; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int) const = 0 ; + // returns class version + virtual unsigned int version() const = 0 ; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; + virtual void destroy(/*const*/ void *address) const = 0 ; +}; + +} // namespae detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/basic_oarchive.hpp b/thirdparty/boost/archive/detail/basic_oarchive.hpp new file mode 100644 index 0000000..acbc6d8 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_oarchive.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_BASIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +// can't use this - much as I'd like to as borland doesn't support it +// #include + +#include +#include + +#include // must be the last header + +namespace boost { +template +class shared_ptr; + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive_impl; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer; +////////////////////////////////////////////////////////////////////// +// class basic_oarchive - write serialized objects to an output stream +class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive +{ + friend class basic_oarchive_impl; + // hide implementation of this class to minimize header conclusion + // in client code. note: borland can't use scoped_ptr + //boost::scoped_ptr pimpl; + basic_oarchive_impl * pimpl; + + // overload these to bracket object attributes. Used to implement + // xml archives + virtual void vsave(const version_type t) = 0; + virtual void vsave(const object_id_type t) = 0; + virtual void vsave(const object_reference_type t) = 0; + virtual void vsave(const class_id_type t) = 0; + virtual void vsave(const class_id_optional_type t) = 0; + virtual void vsave(const class_id_reference_type t) = 0; + virtual void vsave(const class_name_type & t) = 0; + virtual void vsave(const tracking_type t) = 0; +protected: + basic_oarchive(unsigned int flags = 0); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_oarchive(); +public: + // note: NOT part of the public interface + void register_basic_serializer( + const basic_oserializer & bos + ); + void save_object( + const void *x, + const basic_oserializer & bos + ); + void save_pointer( + const void * t, + const basic_pointer_oserializer * bpos_ptr + ); + void save_null_pointer(){ + vsave(NULL_POINTER_TAG); + } + // real public interface starts here + void end_preamble(); // default implementation does nothing + unsigned int get_library_version() const; + unsigned int get_flags() const; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +// required by smart_cast for compilers not implementing +// partial template specialization +BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION( + boost::archive::detail::basic_oarchive +) + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_BASIC_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/basic_oserializer.hpp b/thirdparty/boost/archive/detail/basic_oserializer.hpp new file mode 100644 index 0000000..b59bb07 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_oserializer.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP +#define BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oserializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include + +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer; + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer : + public basic_serializer +{ +private: + basic_pointer_oserializer *bpos; +protected: + explicit basic_oserializer( + const boost::serialization::extended_type_info & type_ + ); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_oserializer(); +public: + bool serialized_as_pointer() const { + return bpos != NULL; + } + void set_bpos(basic_pointer_oserializer *bpos_){ + bpos = bpos_; + } + const basic_pointer_oserializer * get_bpos() const { + return bpos; + } + virtual void save_object_data( + basic_oarchive & ar, const void * x + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int flags) const = 0; + // returns class version + virtual unsigned int version() const = 0; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/basic_pointer_iserializer.hpp b/thirdparty/boost/archive/detail/basic_pointer_iserializer.hpp new file mode 100644 index 0000000..983436d --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_pointer_iserializer.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iarchive; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer; + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer + : public basic_serializer { +protected: + explicit basic_pointer_iserializer( + const boost::serialization::extended_type_info & type_ + ); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_pointer_iserializer(); +public: + virtual const basic_iserializer & get_basic_serializer() const = 0; + virtual void load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_ISERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/basic_pointer_oserializer.hpp b/thirdparty/boost/archive/detail/basic_pointer_oserializer.hpp new file mode 100644 index 0000000..d40d3a7 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_pointer_oserializer.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oarchive; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer; + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer : + public basic_serializer { +protected: + explicit basic_pointer_oserializer( + const boost::serialization::extended_type_info & type_ + ); + // account for bogus gcc warning + #if defined(__GNUC__) + virtual + #endif + ~basic_pointer_oserializer(); +public: + virtual const basic_oserializer & get_basic_serializer() const = 0; + virtual void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_ARCHIVE_POINTER_OSERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/basic_serializer.hpp b/thirdparty/boost/archive/detail/basic_serializer.hpp new file mode 100644 index 0000000..df27678 --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_serializer.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_ARCHIVE_BASIC_SERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_SERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +class basic_serializer : private boost::noncopyable +{ + const boost::serialization::extended_type_info & m_eti; +protected: + explicit basic_serializer( + const boost::serialization::extended_type_info & eti + ) : + m_eti(eti) + {} +public: + const boost::serialization::extended_type_info & get_eti() const { + return m_eti; + } + bool operator<(const basic_serializer & rhs) const { + return & m_eti < & rhs.get_eti(); + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BASIC_SERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/basic_serializer_map.hpp b/thirdparty/boost/archive/detail/basic_serializer_map.hpp new file mode 100644 index 0000000..03e4a2a --- /dev/null +++ b/thirdparty/boost/archive/detail/basic_serializer_map.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_TYPEINFO_EXTENDED_MAP_HPP +#define BOOST_TYPEINFO_EXTENDED_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer_map.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} + +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer; + +struct BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) type_info_pointer_compare +{ + bool operator()( + const basic_serializer * lhs, const basic_serializer * rhs + ) const ; +}; + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_serializer_map : public + boost::noncopyable +{ + typedef std::set map_type; + map_type m_map; + bool & m_deleted; +public: + bool insert(const basic_serializer * bs); + const basic_serializer * tfind( + const boost::serialization::extended_type_info & type_ + ) const; + void erase(basic_serializer * bs); + basic_serializer_map(bool & deleted); + ~basic_serializer_map(); +private: + // cw 8.3 requires this + basic_serializer_map& operator=(basic_serializer_map const&); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_TYPEINFO_EXTENDED_MAP_HPP diff --git a/thirdparty/boost/archive/detail/common_iarchive.hpp b/thirdparty/boost/archive/detail/common_iarchive.hpp new file mode 100644 index 0000000..2d3d1f9 --- /dev/null +++ b/thirdparty/boost/archive/detail/common_iarchive.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template +class common_iarchive : + public basic_iarchive, + public interface_iarchive +{ + friend class interface_iarchive; +private: + virtual void vload(version_type & t){ + * this->This() >> t; + } + virtual void vload(object_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_optional_type & t){ + * this->This() >> t; + } + virtual void vload(tracking_type & t){ + * this->This() >> t; + } + virtual void vload(class_name_type &s){ + * this->This() >> s; + } +protected: + // default processing - invoke serialization library + template + void load_override(T & t, BOOST_PFTO int){ + archive::load(* this->This(), t); + } + // default implementations of functions which emit start/end tags for + // archive types that require them. + void load_start(const char *name){} + void load_end(const char *name){} + // default archive initialization + common_iarchive(unsigned int flags = 0) : + basic_iarchive(flags), + interface_iarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + diff --git a/thirdparty/boost/archive/detail/common_oarchive.hpp b/thirdparty/boost/archive/detail/common_oarchive.hpp new file mode 100644 index 0000000..8de0130 --- /dev/null +++ b/thirdparty/boost/archive/detail/common_oarchive.hpp @@ -0,0 +1,78 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template +class common_oarchive : + public basic_oarchive, + public interface_oarchive +{ + friend class interface_oarchive; +private: + virtual void vsave(const version_type t){ + * this->This() << t; + } + virtual void vsave(const object_id_type t){ + * this->This() << t; + } + virtual void vsave(const object_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_optional_type t){ + * this->This() << t; + } + virtual void vsave(const class_name_type & t){ + * this->This() << t; + } + virtual void vsave(const tracking_type t){ + * this->This() << t; + } +protected: + // default processing - invoke serialization library + template + void save_override(T & t, BOOST_PFTO int){ + archive::save(* this->This(), t); + } + void save_start(const char *name){} + void save_end(const char *name){} + common_oarchive(unsigned int flags = 0) : + basic_oarchive(flags), + interface_oarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/decl.hpp b/thirdparty/boost/archive/detail/decl.hpp new file mode 100644 index 0000000..a46bad1 --- /dev/null +++ b/thirdparty/boost/archive/detail/decl.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP +#define BOOST_ARCHIVE_DETAIL_DECL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 +// decl.hpp +// +// © Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include +#include + +#if defined(BOOST_HAS_DECLSPEC) + #if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) + #if defined(BOOST_ARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_DECL(T) T __export + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export + #else + #define BOOST_ARCHIVE_DECL(T) __declspec(dllexport) T + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T + #endif + #else + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_DECL(T) T __import + #else + #define BOOST_ARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #if defined(BOOST_WARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_WARCHIVE_DECL(T) T __export + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export + #else + #define BOOST_WARCHIVE_DECL(T) __declspec(dllexport) T + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T + #endif + #else + #if defined(__BORLANDC__) + #define BOOST_WARCHIVE_DECL(T) T __import + #else + #define BOOST_WARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #if !defined(BOOST_WARCHIVE_SOURCE) && !defined(BOOST_ARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __import + #else + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #endif +#endif // BOOST_HAS_DECLSPEC + +#if ! defined(BOOST_ARCHIVE_DECL) + #define BOOST_ARCHIVE_DECL(T) T +#endif +#if ! defined(BOOST_WARCHIVE_DECL) + #define BOOST_WARCHIVE_DECL(T) T +#endif +#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T +#endif + +#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP diff --git a/thirdparty/boost/archive/detail/dynamically_initialized.hpp b/thirdparty/boost/archive/detail/dynamically_initialized.hpp new file mode 100644 index 0000000..902eae5 --- /dev/null +++ b/thirdparty/boost/archive/detail/dynamically_initialized.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP +# define BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP + +# include + +namespace boost { namespace archive { namespace detail { + +// +// Provides a dynamically-initialized (singleton) instance of T in a +// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or +// http://lists.boost.org/Archives/boost/2006/05/105286.php for +// details. +// +template +struct dynamically_initialized +{ +protected: + static T& instance; +private: + static T& get_instance(); +#if defined(__GNUC__) + // Workaround "warning: all member functions in class ` + // boost::archive::detail::dynamically_initialized' are private" + public: + void work_around_gcc_warning(); +#endif +}; + +template +T& dynamically_initialized::instance + = dynamically_initialized::get_instance(); + +template +T& dynamically_initialized::get_instance() +{ + static T instance_; + return instance_; +} + +}}} // namespace boost::archive::detail + +#endif // BOOST_ARCHIVE_DETAIL_DYNAMICALLY_INITIALIZED_DWA2006524_HPP diff --git a/thirdparty/boost/archive/detail/interface_iarchive.hpp b/thirdparty/boost/archive/detail/interface_iarchive.hpp new file mode 100644 index 0000000..4601c9d --- /dev/null +++ b/thirdparty/boost/archive/detail/interface_iarchive.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer; + +template +class interface_iarchive +{ +protected: + interface_iarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_iserializer * + register_type(T * = NULL){ + const basic_pointer_iserializer & bpis = + pointer_iserializer::get_instance(); + this->This()->register_basic_serializer(bpis.get_basic_serializer()); + return & bpis; + } + template + Archive & operator>>(T & t){ + this->This()->load_override(t, 0); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + return *(this->This()) >> t; + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/interface_oarchive.hpp b/thirdparty/boost/archive/detail/interface_oarchive.hpp new file mode 100644 index 0000000..2c31053 --- /dev/null +++ b/thirdparty/boost/archive/detail/interface_oarchive.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include +#include +#include // must be the last header + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + +class BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer; + +template +class interface_oarchive +{ +protected: + interface_oarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_oserializer * + register_type(const T * = NULL){ + const basic_pointer_oserializer & bpos = + pointer_oserializer::get_instance(); + this->This()->register_basic_serializer(bpos.get_basic_serializer()); + return & bpos; + } + + template + Archive & operator<<(T & t){ + this->This()->save_override(t, 0); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + return * this->This() << const_cast(t); + #else + return * this->This() << t; + #endif + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/detail/iserializer.hpp b/thirdparty/boost/archive/detail/iserializer.hpp new file mode 100644 index 0000000..842486f --- /dev/null +++ b/thirdparty/boost/archive/detail/iserializer.hpp @@ -0,0 +1,597 @@ +#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// iserializer.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // for placement new +#include // for auto_ptr +#include // size_t + +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include + #endif +// the following is need only for dynamic cast of polymorphic pointers +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class load_access { +public: + template + static void load_primitive(Archive &ar, T &t){ + ar.load(t); + } +}; + +namespace detail { + +template +class iserializer : public basic_iserializer +{ +private: + virtual void destroy(/*const*/ void *address) const { + boost::serialization::access::destroy(static_cast(address)); + } + // private constructor to inhibit any existence other than the + // static one + explicit iserializer() : + basic_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) + {} +public: + virtual BOOST_DLLEXPORT void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const BOOST_USED ; + virtual bool class_info() const { + return boost::serialization::implementation_level::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { +// if(0 != (flags & no_tracking)) +// return false; + return boost::serialization::tracking_level::value + == boost::serialization::track_always + || boost::serialization::tracking_level::value + == boost::serialization::track_selectively + && serialized_as_pointer(); + } + virtual unsigned int version() const { + return ::boost::serialization::version::value; + } + virtual bool is_polymorphic() const { + typedef BOOST_DEDUCED_TYPENAME + boost::serialization::type_info_implementation< + T + >::type::is_polymorphic::type typex; + return typex::value; + } + static iserializer & get_instance(){ + static iserializer instance; + return instance; + } + virtual ~iserializer(){}; +}; + +template +BOOST_DLLEXPORT void iserializer::load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version +) const { + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + boost::smart_cast_reference(ar), + * static_cast(x), + file_version + ); +} + +template +class pointer_iserializer + : public archive_pointer_iserializer + , public dynamically_initialized > +{ +private: + virtual const basic_iserializer & get_basic_serializer() const { + return iserializer::get_instance(); + } + virtual BOOST_DLLEXPORT void load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version + ) const BOOST_USED; +#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) ) +public: +#endif + // private constructor to inhibit any existence other than the + // static one. Note GCC doesn't permit constructor to be private + BOOST_DLLEXPORT pointer_iserializer() BOOST_USED; + friend struct dynamically_initialized >; +public: + // at least one compiler (CW) seems to require that serialize_adl + // be explicitly instantiated. Still under investigation. + #if !defined(__BORLANDC__) + void (* const m)(Archive &, T &, const unsigned); + boost::serialization::extended_type_info * (* e)(); + #endif + BOOST_DLLEXPORT static const pointer_iserializer & get_instance() BOOST_USED; +}; + +// note trick to be sure that operator new is using class specific +// version if such exists. Due to Peter Dimov. +// note: the following fails if T has no default constructor. +// otherwise it would have been ideal +//struct heap_allocator : public T +//{ +// T * invoke(){ +// return ::new(sizeof(T)); +// } +//} + +// note: this should really be a member of the load_ptr function +// below but some compilers still complain about this. +template +struct heap_allocator +{ + #if 0 + // note: this fails on msvc 7.0 and gcc 3.2 + template struct test; + typedef char* yes; + typedef int* no; + template + yes has_op_new(U*, test* = 0); + no has_op_new(...); + + template + T * new_operator(U); + + T * new_operator(yes){ + return (T::operator new)(sizeof(T)); + } + T * new_operator(no){ + return static_cast(operator new(sizeof(T))); + } + static T * invoke(){ + return new_operator(has_op_new(static_cast(NULL))); + } + #else + // while this doesn't handle operator new overload for class T + static T * invoke(){ + return static_cast(operator new(sizeof(T))); + } + #endif +}; + +// due to Martin Ecker +template +class auto_ptr_with_deleter +{ +public: + explicit auto_ptr_with_deleter(T* p) : + m_p(p) + {} + ~auto_ptr_with_deleter(){ + if (m_p) + boost::serialization::access::destroy(m_p); + } + T* get() const { + return m_p; + } + + T* release() { + T* p = m_p; + m_p = NULL; + return p; + } +private: + T* m_p; +}; + +template +BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( + basic_iarchive & ar, + void * & x, + const unsigned int file_version +) const +{ + Archive & ar_impl = boost::smart_cast_reference(ar); + + auto_ptr_with_deleter ap(heap_allocator::invoke()); + if(NULL == ap.get()) + boost::throw_exception(std::bad_alloc()) ; + + T * t = ap.get(); + x = t; + + // catch exception during load_construct_data so that we don't + // automatically delete the t which is most likely not fully + // constructed + BOOST_TRY { + // this addresses an obscure situtation that occurs when + // load_constructor de-serializes something through a pointer. + ar.next_object_pointer(t); + boost::serialization::load_construct_data_adl( + ar_impl, + t, + file_version + ); + } + BOOST_CATCH(...){ + ap.release(); + BOOST_RETHROW; + } + BOOST_CATCH_END + + ar_impl >> boost::serialization::make_nvp(NULL, * t); + ap.release(); +} + +template +#if !defined(__BORLANDC__) +BOOST_DLLEXPORT pointer_iserializer::pointer_iserializer() : + archive_pointer_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ), + m(boost::serialization::serialize_adl), + e(boost::serialization::type_info_implementation::type::get_instance) +#else +BOOST_DLLEXPORT pointer_iserializer::pointer_iserializer() : + archive_pointer_iserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) +#endif +{ + iserializer & bis = iserializer::get_instance(); + bis.set_bpis(this); +} + +template +BOOST_DLLEXPORT const pointer_iserializer & +pointer_iserializer::get_instance() { + // note: comeau complains without full qualification + return dynamically_initialized >::instance; +} + +template +struct load_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_primitive { + static void invoke(Archive & ar, T & t){ + load_access::load_primitive(ar, t); + } + }; + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_only { + static void invoke(Archive & ar, T & t){ + // short cut to user's serializer + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, t, boost::serialization::version::value + ); + } + }; + + // note this save class information including version + // and serialization level to the archive + struct load_standard { + static void invoke(Archive &ar, T &t){ + //BOOST_STATIC_ASSERT(! boost::is_const::value); + // borland - for some reason T is const here - even though + // its not called that way - so fix it her + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type typex; + void * x = & const_cast(t); + ar.load_object(x, iserializer::get_instance()); + } + }; + + struct load_conditional { + static void invoke(Archive &ar, T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + load_standard::invoke(ar, t); + //else + // load_only::invoke(ar, t); + } + }; + + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level, + mpl::int_ + >, + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >, + // do standard load + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level, + mpl::int_ + >, + // do a fast load + mpl::identity, + // else + // do a fast load only tracking is turned off + mpl::identity + > > >::type typex; + + static void invoke(Archive & ar, T &t){ + BOOST_STATIC_ASSERT(( + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >::value + )); + typex::invoke(ar, t); + } +}; + +template +struct load_pointer_type { + template + struct abstract + { + static const basic_pointer_iserializer * register_type(Archive & /* ar */){ + #if ! defined(__BORLANDC__) + typedef BOOST_DEDUCED_TYPENAME + boost::serialization::type_info_implementation::type::is_polymorphic typex; + // it has? to be polymorphic + BOOST_STATIC_ASSERT(typex::value); + #endif + return static_cast(NULL); + } + }; + + template + struct non_abstract + { + static const basic_pointer_iserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_iserializer * register_type(Archive &ar, T & /*t*/){ + // there should never be any need to load an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef BOOST_DEDUCED_TYPENAME + mpl::eval_if< + serialization::is_abstract, + mpl::identity >, + mpl::identity > + >::type typex; + return typex::register_type(ar); + } + + template + static T * pointer_tweak( + const boost::serialization::extended_type_info & eti, + void * t, + T & + ) { + // tweak the pointer back to the base class + return static_cast( + boost::serialization::void_upcast( + eti, + * boost::serialization::type_info_implementation::type::get_instance(), + t + ) + ); + } + + static void invoke(Archive & ar, Tptr & t){ + const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); + const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( + * reinterpret_cast(&t), + bpis_ptr, + archive_pointer_iserializer::find + ); + // if the pointer isn't that of the base class + if(newbpis_ptr != bpis_ptr){ + t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); + } + } +}; + +template +struct load_enum_type { + static void invoke(Archive &ar, T &t){ + // convert integers to correct enum to load + int i; + ar >> boost::serialization::make_nvp(NULL, i); + t = static_cast(i); + } +}; + +template +struct load_array_type { + static void invoke(Archive &ar, T &t){ + typedef typename remove_all_extents::type value_type; + + // convert integers to correct enum to load + int current_count = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + int count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(count > current_count) + boost::throw_exception(archive::archive_exception( + boost::archive::archive_exception::array_size_too_short + )); + ar >> serialization::make_array(static_cast(&t[0]),count); + } +}; + +#if 0 +// note bogus arguments to workaround msvc 6 silent runtime failure +template +BOOST_DLLEXPORT +inline const basic_pointer_iserializer & +instantiate_pointer_iserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +) BOOST_USED; + +template +BOOST_DLLEXPORT +inline const basic_pointer_iserializer & +instantiate_pointer_iserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +){ + return pointer_iserializer::instance; +} +#endif + +} // detail + +template +inline void load(Archive &ar, T &t){ + // if this assertion trips. It means we're trying to load a + // const object with a compiler that doesn't have correct + // funtion template ordering. On other compilers, this is + // handled below. + BOOST_STATIC_ASSERT(! boost::is_const::value); + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity > + ,//else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +// BORLAND +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) +// borland has a couple of problems +// a) if function is partiall specialized - see below +// const paramters are transformed to non-const ones +// b) implementation of base_object can't be made to work +// correctly which results in all base_object s being const. +// So, strip off the const for borland. This breaks the trap +// for loading const objects - but I see no alternative +template +inline void load(Archive &ar, const T & t){ + load(ar, const_cast(t)); +} +#endif + +// let wrappers through. +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +template +inline void load_wrapper(Archive &ar, const T&t, mpl::true_){ + boost::archive::load(ar, const_cast(t)); +} + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) +template +inline void load(Archive &ar, const T&t){ + load_wrapper(ar,t,serialization::is_wrapper()); +} +#endif +#endif + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/oserializer.hpp b/thirdparty/boost/archive/detail/oserializer.hpp new file mode 100644 index 0000000..1814dd4 --- /dev/null +++ b/thirdparty/boost/archive/detail/oserializer.hpp @@ -0,0 +1,572 @@ +#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP +#define BOOST_ARCHIVE_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// oserializer.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include + #endif +// the following is need only for dynamic cast of polymorphic pointers +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class save_access { +public: + template + static void end_preamble(Archive & ar){ + ar.end_preamble(); + } + template + static void save_primitive(Archive & ar, const T & t){ + ar.end_preamble(); + ar.save(t); + } +}; + +namespace detail { + +template +class oserializer : public basic_oserializer +{ +private: + // private constructor to inhibit any existence other than the + // static one + explicit BOOST_DLLEXPORT oserializer() : + basic_oserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) + {} +public: + virtual BOOST_DLLEXPORT void save_object_data( + basic_oarchive & ar, + const void *x + ) const BOOST_USED ; + virtual bool class_info() const { + return boost::serialization::implementation_level::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { +// if(0 != (flags & no_tracking)) +// return false; + return boost::serialization::tracking_level::value == boost::serialization::track_always + || boost::serialization::tracking_level::value == boost::serialization::track_selectively + && serialized_as_pointer(); + } + virtual unsigned int version() const { + return ::boost::serialization::version::value; + } + virtual bool is_polymorphic() const { + typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation< + T + >::type::is_polymorphic::type typex; + return typex::value; + } + static oserializer & get_instance(){ + static oserializer instance; + return instance; + } + virtual ~oserializer(){} +}; + +template +BOOST_DLLEXPORT void oserializer::save_object_data( + basic_oarchive & ar, + const void *x +) const { + // make sure call is routed through the highest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + boost::smart_cast_reference(ar), + * static_cast(const_cast(x)), + version() + ); +} + +template +class pointer_oserializer + : public archive_pointer_oserializer + , public dynamically_initialized > +{ +private: + virtual const basic_oserializer & get_basic_serializer() const { + return oserializer::get_instance(); + } + virtual BOOST_DLLEXPORT void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const BOOST_USED ; +#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) ) +public: +#endif + // private constructor to inhibit any existence other than the + // static one. Note GCC doesn't permit constructor to be private + explicit BOOST_DLLEXPORT pointer_oserializer() BOOST_USED; + friend struct dynamically_initialized >; +public: + #if !defined(__BORLANDC__) + // at least one compiler (CW) seems to require that serialize_adl + // be explicitly instantiated. Still under investigation. + void (* const m)(Archive &, T &, const unsigned); + boost::serialization::extended_type_info * (* e)(); + #endif + BOOST_DLLEXPORT static const pointer_oserializer & get_instance() BOOST_USED; +}; + +template +BOOST_DLLEXPORT void pointer_oserializer::save_object_ptr( + basic_oarchive & ar, + const void * x +) const { + assert(NULL != x); + // make sure call is routed through the highest interface that might + // be specialized by the user. + T * t = static_cast(const_cast(x)); + const unsigned int file_version = boost::serialization::version::value; + Archive & ar_impl = boost::smart_cast_reference(ar); + boost::serialization::save_construct_data_adl( + ar_impl, + t, + file_version + ); + ar_impl << boost::serialization::make_nvp(NULL, * t); +} + +template +#if !defined(__BORLANDC__) +BOOST_DLLEXPORT pointer_oserializer::pointer_oserializer() : + archive_pointer_oserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ), + m(boost::serialization::serialize_adl), + e(boost::serialization::type_info_implementation::type::get_instance) +#else +BOOST_DLLEXPORT pointer_oserializer::pointer_oserializer() : + archive_pointer_oserializer( + * boost::serialization::type_info_implementation::type::get_instance() + ) +#endif +{ + // make sure appropriate member function is instantiated + oserializer & bos = oserializer::get_instance(); + bos.set_bpos(this); +} + +template +BOOST_DLLEXPORT const pointer_oserializer & +pointer_oserializer::get_instance() { + // note: comeau complains without full qualification + return dynamically_initialized >::instance; +} + +template +struct save_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct save_primitive { + static void invoke(Archive & ar, const T & t){ + save_access::save_primitive(ar, t); + } + }; + // same as above but passes through serialization + struct save_only { + static void invoke(Archive & ar, const T & t){ + // make sure call is routed through the highest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast(t), + ::boost::serialization::version::value + ); + } + }; + // adds class information to the archive. This includes + // serialization level and class version + struct save_standard { + static void invoke(Archive &ar, const T & t){ + ar.save_object(& t, oserializer::get_instance()); + } + }; + + // adds class information to the archive. This includes + // serialization level and class version + struct save_conditional { + static void invoke(Archive &ar, const T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + save_standard::invoke(ar, t); + //else + // save_only::invoke(ar, t); + } + }; + + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level, + mpl::int_ + >, + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >, + // do standard save + mpl::identity, + // else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level, + mpl::int_ + >, + // do a fast save + mpl::identity, + // else + // do a fast save only tracking is turned off + mpl::identity + > > >::type typex; + + static void invoke(Archive & ar, const T & t){ + // check that we're not trying to serialize something that + // has been marked not to be serialized. If this your program + // traps here, you've tried to serialize a class whose trait + // has been marked "non-serializable". Either reset the trait + // (see level.hpp) or change program not to serialize items of this class + BOOST_STATIC_ASSERT(( + mpl::greater_equal< + boost::serialization::implementation_level, + mpl::int_ + >::value + )); + typex::invoke(ar, t); + }; +}; + +template +struct save_pointer_type { + template + struct abstract + { + static const basic_pointer_oserializer * register_type(Archive & /* ar */){ + // it has? to be polymorphic + BOOST_STATIC_ASSERT( + boost::serialization::type_info_implementation::type::is_polymorphic::value + ); + return static_cast(NULL); + } + }; + + template + struct non_abstract + { + static const basic_pointer_oserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){ + // there should never be any need to save an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + serialization::is_abstract, + mpl::identity >, + mpl::identity > + >::type typex; + return typex::register_type(ar); + } + + template + struct non_polymorphic + { + static void save( + Archive &ar, + const T & t, + const basic_pointer_oserializer * bpos_ptr + ){ + // save the requested pointer type + ar.save_pointer(& t, bpos_ptr); + } + }; + + template + struct polymorphic + { + static void save( + Archive &ar, + const T & t, + const basic_pointer_oserializer * bpos_ptr + ){ + const boost::serialization::extended_type_info * this_type + = boost::serialization::type_info_implementation::type::get_instance(); + // retrieve the true type of the object pointed to + // if this assertion fails its an error in this library + assert(NULL != this_type); + const boost::serialization::extended_type_info * true_type + = boost::serialization::type_info_implementation::type::get_derived_extended_type_info(t); + // note:if this exception is thrown, be sure that derived pointer + // is either regsitered or exported. + if(NULL == true_type){ + boost::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + } + + // if its not a pointer to a more derived type + const void *vp = static_cast(&t); + if(*this_type == *true_type){ + ar.save_pointer(vp, bpos_ptr); + return; + } + // convert pointer to more derived type. if this is thrown + // it means that the base/derived relationship hasn't be registered + vp = serialization::void_downcast(*true_type, *this_type, &t); + if(NULL == vp){ + boost::throw_exception( + archive_exception(archive_exception::unregistered_cast) + ); + } + + // sice true_type is valid, and this only gets made if the + // pointer oserializer object has been created, this should never + // fail + bpos_ptr = archive_pointer_oserializer::find(* true_type); + assert(NULL != bpos_ptr); + if(NULL == bpos_ptr) + boost::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + ar.save_pointer(vp, bpos_ptr); + } + }; + + template + static void save( + Archive & ar, + const T &t, + const basic_pointer_oserializer * bpos_ptr + ){ + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + BOOST_DEDUCED_TYPENAME boost::serialization:: + type_info_implementation::type::is_polymorphic, + mpl::identity >, + mpl::identity > + >::type typey; + typey::save(ar, const_cast(t), bpos_ptr); + } + + template + static void const_check(T & t){ + BOOST_STATIC_ASSERT(! boost::is_const::value); + } + + static void invoke(Archive &ar, const TPtr t){ + #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // if your program traps here, its because you tried to do + // something like ar << t where t is a pointer to a const value + // void f3(A const* a, text_oarchive& oa) + // { + // oa << a; + // } + // with a compiler which doesn't support remove_const + // const_check(* t); + #else + // otherwise remove the const + #endif + const basic_pointer_oserializer * bpos_ptr = register_type(ar, * t); + if(NULL == t){ + basic_oarchive & boa = boost::smart_cast_reference(ar); + boa.save_null_pointer(); + save_access::end_preamble(ar); + return; + } + save(ar, * t, bpos_ptr); + }; +}; + +template +struct save_enum_type +{ + static void invoke(Archive &ar, const T &t){ + // convert enum to integers on save + const int i = static_cast(t); + ar << boost::serialization::make_nvp(NULL, i); + } +}; + +template +struct save_array_type +{ + static void invoke(Archive &ar, const T &t){ + typedef typename remove_all_extents::type value_type; + + save_access::end_preamble(ar); + // consider alignment + int count = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + ar << BOOST_SERIALIZATION_NVP(count); + ar << serialization::make_array(static_cast(&t[0]),count); + } +}; + + +#if 0 +// note bogus arguments to workaround msvc 6 silent runtime failure +// declaration to satisfy gcc +template +BOOST_DLLEXPORT const basic_pointer_oserializer & +instantiate_pointer_oserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +) BOOST_USED ; +// definition +template +BOOST_DLLEXPORT const basic_pointer_oserializer & +instantiate_pointer_oserializer( + Archive * /* ar = NULL */, + T * /* t = NULL */ +){ + return pointer_oserializer::instance; +} +#endif + +} // detail + +template +inline void save(Archive & ar, const T &t){ + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity >, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity >, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if, + mpl::identity >, + //else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template +struct check_tracking { + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + // if its never tracked. + BOOST_DEDUCED_TYPENAME mpl::equal_to< + serialization::tracking_level, + mpl::int_ + >, + // it better not be a pointer + mpl::not_ >, + //else + // otherwise if it might be tracked. So there shouldn't + // be any problem making a const + is_const + >::type typex; + BOOST_STATIC_CONSTANT(bool, value = typex::value); +}; + +template +inline void save(Archive & ar, T &t){ + // if your program traps here, it indicates that your doing one of the following: + // a) serializing an object of a type marked "track_never" through a pointer. + // b) saving an non-const object of a type not markd "track_never) + // Either of these conditions may be an indicator of an error usage of the + // serialization library and should be double checked. See documentation on + // object tracking. Also, see the "rationale" section of the documenation + // for motivation for this checking. + BOOST_STATIC_ASSERT(check_tracking::value); + save(ar, const_cast(t)); +} +#endif + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_OSERIALIZER_HPP diff --git a/thirdparty/boost/archive/detail/polymorphic_iarchive_dispatch.hpp b/thirdparty/boost/archive/detail/polymorphic_iarchive_dispatch.hpp new file mode 100644 index 0000000..d3b9032 --- /dev/null +++ b/thirdparty/boost/archive/detail/polymorphic_iarchive_dispatch.hpp @@ -0,0 +1,197 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive_dispatch.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include // must be the last header + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_iserializer; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_iserializer; + +template +class polymorphic_iarchive_dispatch : + public polymorphic_iarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation, + private boost::noncopyable +{ +private: + // these are used by the serialization library. + virtual void load_object( + void *t, + const basic_iserializer & bis + ){ + ArchiveImplementation::load_object(t, bis); + } + virtual const basic_pointer_iserializer * load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ){ + return ArchiveImplementation::load_pointer(t, bpis_ptr, finder); + } + virtual void set_library_version(unsigned int archive_library_version){ + ArchiveImplementation::set_library_version(archive_library_version); + } + virtual unsigned int get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void delete_created_pointers(){ + ArchiveImplementation::delete_created_pointers(); + } + virtual void reset_object_address( + const void * new_address, + const void * old_address + ){ + ArchiveImplementation::reset_object_address(new_address, old_address); + } + virtual void load_binary(void * t, std::size_t size){ + ArchiveImplementation::load_binary(t, size); + } + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t){ + ArchiveImplementation::load(t); + } + virtual void load(char & t){ + ArchiveImplementation::load(t); + } + virtual void load(signed char & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned char & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t){ + ArchiveImplementation::load(t); + } + #endif + #endif + virtual void load(short & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned short & t){ + ArchiveImplementation::load(t); + } + virtual void load(int & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned int & t){ + ArchiveImplementation::load(t); + } + virtual void load(long & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned long & t){ + ArchiveImplementation::load(t); + } + #if !defined(BOOST_NO_INTRINSIC_INT64_T) + virtual void load(boost::int64_t & t){ + ArchiveImplementation::load(t); + } + virtual void load(boost::uint64_t & t){ + ArchiveImplementation::load(t); + } + #endif + virtual void load(float & t){ + ArchiveImplementation::load(t); + } + virtual void load(double & t){ + ArchiveImplementation::load(t); + } + virtual void load(std::string & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t){ + ArchiveImplementation::load(t); + } + #endif + // used for xml and other tagged formats default does nothing + virtual void load_start(const char * name){ + ArchiveImplementation::load_start(name); + } + virtual void load_end(const char * name){ + ArchiveImplementation::load_end(name); + } + + virtual void register_basic_serializer(const basic_iserializer & bis){ + ArchiveImplementation::register_basic_serializer(bis); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the >> operator + template + polymorphic_iarchive & operator>>(T & t){ + return polymorphic_iarchive::operator>>(t); + } + + // the & operator + template + polymorphic_iarchive & operator&(T & t){ + return polymorphic_iarchive::operator&(t); + } + + // all current archives take a stream as constructor argument + template + polymorphic_iarchive_dispatch( + std::basic_istream<_Elem, _Tr> & is, + unsigned int flags = 0 + ) : + ArchiveImplementation(is, flags) + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP diff --git a/thirdparty/boost/archive/detail/polymorphic_oarchive_dispatch.hpp b/thirdparty/boost/archive/detail/polymorphic_oarchive_dispatch.hpp new file mode 100644 index 0000000..c6605c0 --- /dev/null +++ b/thirdparty/boost/archive/detail/polymorphic_oarchive_dispatch.hpp @@ -0,0 +1,185 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive_dispatch.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include // must be the last header + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_oserializer; +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) basic_pointer_oserializer; + +template +class polymorphic_oarchive_dispatch : + public polymorphic_oarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation, + private boost::noncopyable +{ +private: + // these are used by the serialization library. + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ){ + ArchiveImplementation::save_object(x, bos); + } + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ){ + ArchiveImplementation::save_pointer(t, bpos_ptr); + } + virtual void save_null_pointer(){ + ArchiveImplementation::save_null_pointer(); + } + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t){ + ArchiveImplementation::save(t); + } + virtual void save(const char t){ + ArchiveImplementation::save(t); + } + virtual void save(const signed char t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned char t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t){ + ArchiveImplementation::save(t); + } + #endif + #endif + virtual void save(const short t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned short t){ + ArchiveImplementation::save(t); + } + virtual void save(const int t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned int t){ + ArchiveImplementation::save(t); + } + virtual void save(const long t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned long t){ + ArchiveImplementation::save(t); + } + #if !defined(BOOST_NO_INTRINSIC_INT64_T) + virtual void save(const boost::int64_t t){ + ArchiveImplementation::save(t); + } + virtual void save(const boost::uint64_t t){ + ArchiveImplementation::save(t); + } + #endif + virtual void save(const float t){ + ArchiveImplementation::save(t); + } + virtual void save(const double t){ + ArchiveImplementation::save(t); + } + virtual void save(const std::string & t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t){ + ArchiveImplementation::save(t); + } + #endif + virtual unsigned int get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void save_binary(const void * t, std::size_t size){ + ArchiveImplementation::save_binary(t, size); + } + // used for xml and other tagged formats default does nothing + virtual void save_start(const char * name){ + ArchiveImplementation::save_start(name); + } + virtual void save_end(const char * name){ + ArchiveImplementation::save_end(name); + } + virtual void end_preamble(){ + ArchiveImplementation::end_preamble(); + } + virtual void register_basic_serializer(const detail::basic_oserializer & bos){ + ArchiveImplementation::register_basic_serializer(bos); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the << operator + template + polymorphic_oarchive & operator<<(T & t){ + return polymorphic_oarchive::operator<<(t); + } + // the & operator + template + polymorphic_oarchive & operator&(T & t){ + return polymorphic_oarchive::operator&(t); + } + // all current archives take a stream as constructor argument + template + polymorphic_oarchive_dispatch( + std::basic_ostream<_Elem, _Tr> & os, + unsigned int flags = 0 + ) : + ArchiveImplementation(os, flags) + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP diff --git a/thirdparty/boost/archive/detail/register_archive.hpp b/thirdparty/boost/archive/detail/register_archive.hpp new file mode 100644 index 0000000..d416f90 --- /dev/null +++ b/thirdparty/boost/archive/detail/register_archive.hpp @@ -0,0 +1,47 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP +# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP + +# include + +namespace boost { namespace archive { namespace detail { + +template +struct ptr_serialization_support; + +// We could've just used ptr_serialization_support, above, but using +// it with only a forward declaration causes vc6/7 to complain about a +// missing instantiate member, even if it has one. This is just a +// friendly layer of indirection. +template +struct _ptr_serialization_support + : ptr_serialization_support +{ + typedef int type; +}; + +// This function gets called, but its only purpose is to participate +// in overload resolution with the functions declared by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. +template +void instantiate_ptr_serialization(Serializable*, int) {} + +// The function declaration generated by this macro never actually +// gets called, but its return type gets instantiated, and that's +// enough to cause registration of serialization functions between +// Archive and any exported Serializable type. See also: +// boost/serialization/export.hpp +# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ +namespace boost { namespace archive { namespace detail { \ + \ +template \ +typename _ptr_serialization_support::type \ +instantiate_ptr_serialization( Serializable*, Archive* ); \ + \ +}}} + +}}} // namespace boost::archive::detail + +#endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP diff --git a/thirdparty/boost/archive/detail/utf8_codecvt_facet.hpp b/thirdparty/boost/archive/detail/utf8_codecvt_facet.hpp new file mode 100644 index 0000000..bcd52c3 --- /dev/null +++ b/thirdparty/boost/archive/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,21 @@ +// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP +#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP + +#define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { +#define BOOST_UTF8_DECL +#define BOOST_UTF8_END_NAMESPACE }}} + +#include + +#undef BOOST_UTF8_END_NAMESPACE +#undef BOOST_UTF8_DECL +#undef BOOST_UTF8_BEGIN_NAMESPACE + +#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP diff --git a/thirdparty/boost/archive/dinkumware.hpp b/thirdparty/boost/archive/dinkumware.hpp new file mode 100644 index 0000000..59afd69 --- /dev/null +++ b/thirdparty/boost/archive/dinkumware.hpp @@ -0,0 +1,224 @@ +#ifndef BOOST_ARCHIVE_DINKUMWARE_HPP +#define BOOST_ARCHIVE_DINKUMWARE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dinkumware.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// this file adds a couple of things that are missing from the dinkumware +// implementation of the standard library. + +#include +#include + +#include +#include + +namespace std { + +// define i/o operators for 64 bit integers +template +basic_ostream & +operator<<(basic_ostream & os, boost::uint64_t t){ + // octal rendering of 64 bit number would be 22 octets + eos + CharType d[23]; + unsigned int radix; + + if(os.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(os.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + unsigned int i = 0; + do{ + unsigned int j = t % radix; + d[i++] = j + ((j < 10) ? '0' : ('a' - 10)); + t /= radix; + } + while(t > 0); + d[i--] = '\0'; + + // reverse digits + unsigned int j = 0; + while(j < i){ + CharType k = d[i]; + d[i] = d[j]; + d[j] = k; + --i;++j; + } + os << d; + return os; + +} + +template +basic_ostream & +operator<<(basic_ostream &os, boost::int64_t t){ + if(0 <= t){ + os << static_cast(t); + } + else{ + os.put('-'); + os << -t; + } + return os; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::int64_t & t){ + CharType d; + do{ + d = is.get(); + } + while(::isspace(d)); + bool negative = (d == '-'); + if(negative) + d = is.get(); + unsigned int radix; + if(is.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(is.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + t = 0; + do{ + if('0' <= d && d <= '9') + t = t * radix + (d - '0'); + else + if('a' <= d && d <= 'f') + t = t * radix + (d - 'a' + 10); + else + break; + d = is.get(); + } + while(!is.fail()); + // restore the delimiter + is.putback(d); + is.clear(); + if(negative) + t = -t; + return is; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::uint64_t & t){ + boost::int64_t it; + is >> it; + t = it; + return is; +} + +//#endif + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +} // namespace std + +#endif //BOOST_ARCHIVE_DINKUMWARE_HPP diff --git a/thirdparty/boost/archive/impl/archive_pointer_iserializer.ipp b/thirdparty/boost/archive/impl/archive_pointer_iserializer.ipp new file mode 100644 index 0000000..59567ca --- /dev/null +++ b/thirdparty/boost/archive/impl/archive_pointer_iserializer.ipp @@ -0,0 +1,65 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// pointer_iserializer.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // msvc 6.0 needs this for warning suppression + +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +template +basic_serializer_map * +iserializer_map(){ + static bool deleted = false; + static basic_serializer_map map(deleted); + return deleted ? NULL : & map; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_pointer_iserializer::archive_pointer_iserializer( + const boost::serialization::extended_type_info & eti +) : + basic_pointer_iserializer(eti) +{ + basic_serializer_map *mp = iserializer_map(); + assert(NULL != mp); + mp->insert(this); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_iserializer *) +archive_pointer_iserializer::find( + const boost::serialization::extended_type_info & eti +){ + basic_serializer_map *mp = iserializer_map(); + assert(NULL != mp); + return static_cast(mp->tfind(eti)); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_pointer_iserializer::~archive_pointer_iserializer(){ + // note: we need to check that the map still exists as we can't depend + // on static variables being constructed in a specific sequence + basic_serializer_map *mp = iserializer_map(); + if(NULL == mp) + return; + mp->erase(this); +} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/archive_pointer_oserializer.ipp b/thirdparty/boost/archive/impl/archive_pointer_oserializer.ipp new file mode 100644 index 0000000..c617dac --- /dev/null +++ b/thirdparty/boost/archive/impl/archive_pointer_oserializer.ipp @@ -0,0 +1,63 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_pointer_oserializer.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // msvc 6.0 needs this for warning suppression + +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +template +basic_serializer_map * +oserializer_map(){ + static bool deleted = false; + static basic_serializer_map map(deleted); + return deleted ? NULL : & map; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_pointer_oserializer::archive_pointer_oserializer( + const boost::serialization::extended_type_info & eti +) : + basic_pointer_oserializer(eti) +{ + basic_serializer_map *mp = oserializer_map(); + assert(NULL != mp); + mp->insert(this); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(const basic_pointer_oserializer *) +archive_pointer_oserializer::find( + const boost::serialization::extended_type_info & eti +){ + basic_serializer_map *mp = oserializer_map(); + assert(NULL != mp); + return static_cast(mp->tfind(eti)); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_pointer_oserializer::~archive_pointer_oserializer(){ + // note: we need to check that the map still exists as we can't depend + // on static variables being constructed in a specific sequence + basic_serializer_map *mp = oserializer_map(); + if(NULL == mp) + return; + mp->erase(this); +} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_binary_iarchive.ipp b/thirdparty/boost/archive/impl/basic_binary_iarchive.ipp new file mode 100644 index 0000000..80c3ba1 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_binary_iarchive.ipp @@ -0,0 +1,80 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +#include +//#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_archive +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iarchive::load_override(class_name_type & t, int){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn, 0); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iarchive::init(){ + // read signature in an archive version independent manner + std::string file_signature; + * this->This() >> file_signature; + if(file_signature != ARCHIVE_SIGNATURE()) + boost::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + version_type input_library_version; + * this->This() >> input_library_version; + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + #if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + detail:: + #endif + basic_iarchive::set_library_version(input_library_version); + #endif + + // extra little .t is to get around borland quirk + if(ARCHIVE_VERSION() < input_library_version.t) + boost::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_binary_iprimitive.ipp b/thirdparty/boost/archive/impl/basic_binary_iprimitive.ipp new file mode 100644 index 0000000..e24637a --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_binary_iprimitive.ipp @@ -0,0 +1,190 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // size_t +#include // memcpy + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + using ::memcpy; +} // namespace std +#endif + +#include // fixup for RogueWave + +#include +#include + +#include +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_iprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iprimitive::init() +{ + // Detect attempts to pass native binary archives across + // incompatible platforms. This is not fool proof but its + // better than nothing. + unsigned char size; + this->This()->load(size); + if(sizeof(int) != size) + boost::throw_exception( + archive_exception(archive_exception::incompatible_native_format) + ); + this->This()->load(size); + if(sizeof(long) != size) + boost::throw_exception( + archive_exception(archive_exception::incompatible_native_format) + ); + this->This()->load(size); + if(sizeof(float) != size) + boost::throw_exception( + archive_exception(archive_exception::incompatible_native_format) + ); + this->This()->load(size); + if(sizeof(double) != size) + boost::throw_exception( + archive_exception(archive_exception::incompatible_native_format) + ); + + // for checking endian + int i; + this->This()->load(i); + if(1 != i) + boost::throw_exception( + archive_exception(archive_exception::incompatible_native_format) + ); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iprimitive::load(wchar_t * ws) +{ + std::size_t l; + this->This()->load(l); + load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); + ws[l / sizeof(wchar_t)] = L'\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iprimitive::load(std::string & s) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(l); + // note breaking a rule here - could be a problem on some platform + load_binary(const_cast(s.data()), l); +} + +#ifndef BOOST_NO_CWCHAR +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iprimitive::load(char * s) +{ + std::size_t l; + this->This()->load(l); + load_binary(s, l); + s[l] = '\0'; +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_iprimitive::load(std::wstring & ws) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(l); + // note breaking a rule here - is could be a problem on some platform + load_binary(const_cast(ws.data()), l * sizeof(wchar_t) / sizeof(char)); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_binary_iprimitive::basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : + m_sb(sb), + archive_locale(NULL), + locale_saver(m_sb) +{ + if(! no_codecvt){ + archive_locale.reset( + boost::archive::add_facet( + std::locale::classic(), + new codecvt_null + ) + ); + m_sb.pubimbue(* archive_locale); + } +} + +// some libraries including stl and libcomo fail if the +// buffer isn't flushed before the code_cvt facet is changed. +// I think this is a bug. We explicity invoke sync to when +// we're done with the streambuf to work around this problem. +// Note that sync is a protected member of stream buff so we +// have to invoke it through a contrived derived class. +namespace detail { +// note: use "using" to get past msvc bug +using namespace std; +template +class input_streambuf_access : public std::basic_streambuf { + public: + virtual int sync(){ +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + return this->basic_streambuf::sync(); +#else + return this->basic_streambuf::sync(); +#endif + } +}; +} // detail + +// scoped_ptr requires that archive_locale be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_binary_iprimitive::~basic_binary_iprimitive(){ + // push back unread characters + int result = static_cast &>( + m_sb + ).sync(); + if(0 != result){ + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + } +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_binary_oarchive.ipp b/thirdparty/boost/archive/impl/basic_binary_oarchive.ipp new file mode 100644 index 0000000..3d47d38 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_binary_oarchive.ipp @@ -0,0 +1,46 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_oarchive + +template +#if !defined(__BORLANDC__) +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +#else +void +#endif +basic_binary_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const version_type v(ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_binary_oprimitive.ipp b/thirdparty/boost/archive/impl/basic_binary_oprimitive.ipp new file mode 100644 index 0000000..324eb9a --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_binary_oprimitive.ipp @@ -0,0 +1,160 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_oprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_oprimitive::init() +{ + // record native sizes of fundamental types + // this is to permit detection of attempts to pass + // native binary archives accross incompatible machines. + // This is not foolproof but its better than nothing. + this->This()->save(static_cast(sizeof(int))); + this->This()->save(static_cast(sizeof(long))); + this->This()->save(static_cast(sizeof(float))); + this->This()->save(static_cast(sizeof(double))); + // for checking endianness + this->This()->save(int(1)); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_oprimitive::save(const char * s) +{ + std::size_t l = std::strlen(s); + this->This()->save(l); + save_binary(s, l); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_oprimitive::save(const std::string &s) +{ + std::size_t l = static_cast(s.size()); + this->This()->save(l); + save_binary(s.data(), l); +} + +#ifndef BOOST_NO_CWCHAR +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_oprimitive::save(const wchar_t * ws) +{ + std::size_t l = std::wcslen(ws); + this->This()->save(l); + save_binary(ws, l * sizeof(wchar_t) / sizeof(char)); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_binary_oprimitive::save(const std::wstring &ws) +{ + std::size_t l = ws.size(); + this->This()->save(l); + save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); +} +#endif +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_binary_oprimitive::basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : + m_sb(sb), + archive_locale(NULL), + locale_saver(m_sb) +{ + if(! no_codecvt){ + archive_locale.reset( + add_facet( + std::locale::classic(), + new codecvt_null + ) + ); + m_sb.pubimbue(* archive_locale); + } +} + +// some libraries including stl and libcomo fail if the +// buffer isn't flushed before the code_cvt facet is changed. +// I think this is a bug. We explicity invoke sync to when +// we're done with the streambuf to work around this problem. +// Note that sync is a protected member of stream buff so we +// have to invoke it through a contrived derived class. +namespace detail { +// note: use "using" to get past msvc bug +using namespace std; +template +class output_streambuf_access : public std::basic_streambuf { + public: + virtual int sync(){ +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + return this->basic_streambuf::sync(); +#else + return this->basic_streambuf::sync(); +#endif + } +}; +} // detail + +// scoped_ptr requires that g be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_binary_oprimitive::~basic_binary_oprimitive(){ + // flush buffer + int result = static_cast &>( + m_sb + ).sync(); + if(0 != result){ + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + } +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_text_iarchive.ipp b/thirdparty/boost/archive/impl/basic_text_iarchive.ipp new file mode 100644 index 0000000..c11b617 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_text_iarchive.ipp @@ -0,0 +1,80 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +#include +//#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of text_text_archive +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_iarchive::load_override(class_name_type & t, int){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn, 0); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_iarchive::init(void){ + // read signature in an archive version independent manner + std::string file_signature; + * this->This() >> file_signature; + if(file_signature != ARCHIVE_SIGNATURE()) + boost::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + version_type input_library_version; + * this->This() >> input_library_version; + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + #if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + detail:: + #endif + basic_iarchive::set_library_version(input_library_version.t); + #endif + + // extra little .t is to get around borland quirk + if(ARCHIVE_VERSION() < input_library_version.t) + boost::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_text_iprimitive.ipp b/thirdparty/boost/archive/impl/basic_text_iprimitive.ipp new file mode 100644 index 0000000..99b1ecf --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_text_iprimitive.ipp @@ -0,0 +1,123 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +// translate base64 text into binary and copy into buffer +// until buffer is full. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_iprimitive::load_binary( + void *address, + std::size_t count +){ + typedef BOOST_DEDUCED_TYPENAME IStream::char_type CharType; + + if(0 == count) + return; + + assert( + static_cast((std::numeric_limits::max)()) + > (count + sizeof(CharType) - 1)/sizeof(CharType) + ); + + if(is.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + // convert from base64 to binary + typedef BOOST_DEDUCED_TYPENAME + iterators::transform_width< + iterators::binary_from_base64< + iterators::remove_whitespace< + iterators::istream_iterator + > + ,CharType + > + ,8 + ,6 + ,CharType + > + binary; + + binary ti_begin = binary( + BOOST_MAKE_PFTO_WRAPPER( + iterators::istream_iterator(is) + ) + ); + + char * caddr = static_cast(address); + std::size_t padding = 2 - count % 3; + + // take care that we don't increment anymore than necessary + while(--count > 0){ + *caddr++ = static_cast(*ti_begin); + ++ti_begin; + } + *caddr++ = static_cast(*ti_begin); + + if(padding > 1) + ++ti_begin; + if(padding > 2) + ++ti_begin; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_text_iprimitive::basic_text_iprimitive( + IStream &is_, + bool no_codecvt +) : + is(is_), + flags_saver(is_), + precision_saver(is_), + archive_locale(NULL), + locale_saver(is_) +{ + if(! no_codecvt){ + archive_locale.reset( + add_facet( + std::locale::classic(), + new codecvt_null + ) + ); + is.imbue(* archive_locale); + } + is >> std::noboolalpha; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_text_iprimitive::~basic_text_iprimitive(){ + is.sync(); +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_text_oarchive.ipp b/thirdparty/boost/archive/impl/basic_text_oarchive.ipp new file mode 100644 index 0000000..dffadb6 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_text_oarchive.ipp @@ -0,0 +1,62 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of basic_text_oarchive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_oarchive::newtoken() +{ + switch(delimiter){ + default: + assert(false); + break; + case eol: + this->This()->put('\n'); + delimiter = space; + break; + case space: + this->This()->put(' '); + break; + case none: + delimiter = space; + break; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const version_type v(ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_text_oprimitive.ipp b/thirdparty/boost/archive/impl/basic_text_oprimitive.ipp new file mode 100644 index 0000000..3b2cf06 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_text_oprimitive.ipp @@ -0,0 +1,103 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +// translate to base64 and copy in to buffer. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_text_oprimitive::save_binary( + const void *address, + std::size_t count +){ + typedef BOOST_DEDUCED_TYPENAME OStream::char_type CharType; + + if(0 == count) + return; + + if(os.fail()) + boost::throw_exception(archive_exception(archive_exception::stream_error)); + + os.put('\n'); + + typedef + boost::archive::iterators::insert_linebreaks< + boost::archive::iterators::base64_from_binary< + boost::archive::iterators::transform_width< + const char *, + 6, + 8 + > + > + ,72 + ,const char // cwpro8 needs this + > + base64_text; + + boost::archive::iterators::ostream_iterator oi(os); + std::copy( + base64_text(BOOST_MAKE_PFTO_WRAPPER(static_cast(address))), + base64_text( + BOOST_MAKE_PFTO_WRAPPER(static_cast(address) + count) + ), + oi + ); + std::size_t padding = 2 - count % 3; + if(padding > 1) + *oi = '='; + if(padding > 2) + *oi = '='; + +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_text_oprimitive::basic_text_oprimitive( + OStream & os_, + bool no_codecvt +) : + os(os_), + flags_saver(os_), + precision_saver(os_), + archive_locale(NULL), + locale_saver(os_) +{ + if(! no_codecvt){ + archive_locale.reset( + add_facet( + std::locale::classic(), + new codecvt_null + ) + ); + os.imbue(* archive_locale); + } + os << std::noboolalpha; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_text_oprimitive::~basic_text_oprimitive(){ + os << std::endl; +} + +} //namespace boost +} //namespace archive diff --git a/thirdparty/boost/archive/impl/basic_xml_grammar.hpp b/thirdparty/boost/archive/impl/basic_xml_grammar.hpp new file mode 100644 index 0000000..efd4ac3 --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_xml_grammar.hpp @@ -0,0 +1,191 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP +#define BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_grammar.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// this module is derived from simplexml.cpp - an example shipped as part of +// the spirit parser. This example contains the following notice: +/*============================================================================= + simplexml.cpp + + Spirit V1.3 + URL: http://spirit.sourceforge.net/ + + Copyright (c) 2001, Daniel C. Nuffer + + This software is provided 'as-is', without any express or implied + warranty. In no event will the copyright holder be held liable for + any damages arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product documentation + would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +=============================================================================*/ +#include + +#include +#include + +// supress noise +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +//#define BOOST_SPIRIT_DEBUG +//#include +#include +#include + +// the following hack is to evade a bogus error generated by using the +// word "arg" when bind.hpp has been included +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +#define arg xarg +#endif + +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +#undef arg +#endif + +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// XML grammar parsing + +template +class basic_xml_grammar : public boost::spirit::grammar > +{ +public: + // The following is not necessary according to DR45, but at least + // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. + struct return_values; + friend struct return_values; + +private: + typedef BOOST_DEDUCED_TYPENAME std::basic_istream IStream; + typedef BOOST_DEDUCED_TYPENAME std::basic_string StringType; + typedef BOOST_DEDUCED_TYPENAME boost::spirit::chset chset_t; + typedef BOOST_DEDUCED_TYPENAME boost::spirit::chlit chlit_t; + typedef BOOST_DEDUCED_TYPENAME boost::spirit::scanner< + BOOST_DEDUCED_TYPENAME std::basic_string::iterator + > scanner_t; + typedef BOOST_DEDUCED_TYPENAME boost::spirit::rule rule_t; + // Start grammar definition + rule_t + Reference, + Eq, + STag, + ETag, + LetterOrUnderscoreOrColon, + AttValue, + CharRef1, + CharRef2, + CharRef, + AmpRef, + LTRef, + GTRef, + AposRef, + QuoteRef, + CharData, + CharDataChars, + content, + AmpName, + LTName, + GTName, + ClassNameChar, + ClassName, + Name, + XMLDecl, + XMLDeclChars, + DocTypeDecl, + DocTypeDeclChars, + ClassIDAttribute, + ObjectIDAttribute, + ClassNameAttribute, + TrackingAttribute, + VersionAttribute, + UnusedAttribute, + Attribute, + SignatureAttribute, + SerializationWrapper, + NameHead, + NameTail, + AttributeList, + S; + + // XML Character classes + chset_t + BaseChar, + Ideographic, + Char, + Letter, + Digit, + CombiningChar, + Extender, + Sch, + NameChar; + + void init_chset(); + + bool my_parse( + IStream & is, + const rule_t &rule_, + const CharType delimiter = L'>' + ); +public: + struct return_values { + StringType object_name; + StringType contents; + class_id_type class_id; + object_id_type object_id; + version_type version; + tracking_type tracking_level; + StringType class_name; + return_values() : + version(0), + tracking_level(false) + {} + } rv; + bool parse_start_tag(IStream & is) ; + bool parse_end_tag(IStream & is); + bool parse_string(IStream & is, StringType & s); + void init(IStream & is); + void windup(IStream & is); + basic_xml_grammar(); +}; + + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP diff --git a/thirdparty/boost/archive/impl/basic_xml_iarchive.ipp b/thirdparty/boost/archive/impl/basic_xml_iarchive.ipp new file mode 100644 index 0000000..323db1e --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_xml_iarchive.ipp @@ -0,0 +1,111 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include + +#include +#include +//#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of xml_text_archive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_start(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_start_tag(this->This()->get_is()); + if(true != result){ + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + } + // don't check start tag at highest level + ++depth; + return; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_end(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_end_tag(this->This()->get_is()); + if(true != result){ + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + } + + // don't check start tag at highest level + if(0 == --depth) + return; + + if(0 == (this->get_flags() & no_xml_tag_checking)){ + // double check that the tag matches what is expected - useful for debug + if(0 != name[this->This()->gimpl->rv.object_name.size()] + || ! std::equal( + this->This()->gimpl->rv.object_name.begin(), + this->This()->gimpl->rv.object_name.end(), + name + ) + ){ + boost::throw_exception( + archive_exception(archive_exception::stream_error) + ); + } + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_override(object_id_type & t, int){ + t = this->This()->gimpl->rv.object_id; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_override(version_type & t, int){ + t = this->This()->gimpl->rv.version; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_override(class_id_type & t, int){ + t = this->This()->gimpl->rv.class_id; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_iarchive::load_override(tracking_type & t, int){ + t = this->This()->gimpl->rv.tracking_level; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_xml_iarchive::basic_xml_iarchive(unsigned int flags) : + detail::common_iarchive(flags), + depth(0) +{} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_xml_iarchive::~basic_xml_iarchive(){} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/basic_xml_oarchive.ipp b/thirdparty/boost/archive/impl/basic_xml_oarchive.ipp new file mode 100644 index 0000000..1221f6b --- /dev/null +++ b/thirdparty/boost/archive/impl/basic_xml_oarchive.ipp @@ -0,0 +1,269 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include +#include + +namespace boost { +namespace archive { + +namespace detail { +template +struct XML_name { + void operator()(CharType t) const{ + const unsigned char lookup_table[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. + 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + if((unsigned)t > 127) + return; + if(0 == lookup_table[(unsigned)t]) + boost::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_tag_name_error + ) + ); + } +}; + +} // namespace detail + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions common to both types of xml output + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::write_attribute( + const char *attribute_name, + int t, + const char *conjunction +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put(conjunction); + this->This()->save(t); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::write_attribute( + const char *attribute_name, + const char *key +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put("=\""); + this->This()->put(key); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::indent(){ + int i; + for(i = depth; i-- > 0;) + this->This()->put('\t'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_start(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + if(depth > 0){ + this->This()->put('\n'); + indent(); + } + ++depth; + this->This()->put('<'); + this->This()->save(name); + pending_preamble = true; + indent_next = false; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_end(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + --depth; + if(indent_next){ + this->This()->put('\n'); + indent(); + } + indent_next = true; + this->This()->put("This()->save(name); + this->This()->put('>'); + if(0 == depth) + this->This()->put('\n'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::end_preamble(){ + if(pending_preamble){ + this->This()->put('>'); + pending_preamble = false; + } +} +#if 0 +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const object_id_type & t, int) +{ + int i = t.t; // extra .t is for borland + write_attribute(OBJECT_ID(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override( + const object_reference_type & t, + int +){ + int i = t.t; // extra .t is for borland + write_attribute(OBJECT_REFERENCE(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const version_type & t, int) +{ + int i = t.t; // extra .t is for borland + write_attribute(VERSION(), i); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const object_id_type & t, int) +{ + write_attribute(OBJECT_ID(), t, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override( + const object_reference_type & t, + int +){ + write_attribute(OBJECT_REFERENCE(), t, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const version_type & t, int) +{ + write_attribute(VERSION(), t); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const class_id_type & t, int) +{ + write_attribute(CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override( + const class_id_reference_type & t, + int +){ + write_attribute(CLASS_ID_REFERENCE(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override( + const class_id_optional_type & t, + int +){ + write_attribute(CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const class_name_type & t, int) +{ + const char * key = t; + if(NULL == key) + return; + write_attribute(CLASS_NAME(), key); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::save_override(const tracking_type & t, int) +{ + write_attribute(TRACKING(), t.t); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) +basic_xml_oarchive::init(){ + // xml header + this->This()->put("\n"); + this->This()->put("\n"); + // xml document wrapper - outer root + this->This()->put("This()->put(">\n"); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + depth(0), + indent_next(false), + pending_preamble(false) +{ +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_xml_oarchive::~basic_xml_oarchive(){ + if(0 == (this->get_flags() & no_header)){ + BOOST_TRY{ + this->This()->put(""); + } + BOOST_CATCH(...){} + BOOST_CATCH_END + } +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/text_iarchive_impl.ipp b/thirdparty/boost/archive/impl/text_iarchive_impl.ipp new file mode 100644 index 0000000..7f3205c --- /dev/null +++ b/thirdparty/boost/archive/impl/text_iarchive_impl.ipp @@ -0,0 +1,127 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_iprimitive overrides for the combination +// of template parameters used to implement a text_iprimitive + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // RogueWave + +#include + +namespace boost { +namespace archive { + +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = '\0'; +} + +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(size); + is.read(const_cast(s.data()), size); +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::load(wchar_t *ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + is.read((char *)ws, size * sizeof(wchar_t)/sizeof(char)); + ws[size] = L'\0'; +} +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // skip separating space + is.get(); + is.read((char *)ws.data(), size * sizeof(wchar_t)/sizeof(char)); +} + +#endif // BOOST_NO_STD_WSTRING +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::load_override(class_name_type & t, int){ + basic_text_iarchive::load_override(t, 0); +} + +template +BOOST_ARCHIVE_DECL(void) +text_iarchive_impl::init(){ + basic_text_iarchive::init(); +} + +template +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +text_iarchive_impl::text_iarchive_impl( + std::istream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_iarchive::init(); + #endif +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/text_oarchive_impl.ipp b/thirdparty/boost/archive/impl/text_oarchive_impl.ipp new file mode 100644 index 0000000..d66c737 --- /dev/null +++ b/thirdparty/boost/archive/impl/text_oarchive_impl.ipp @@ -0,0 +1,124 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_oprimitive overrides for the combination +// of template parameters used to create a text_oprimitive + +template +BOOST_ARCHIVE_DECL(void) +text_oarchive_impl::save(const char * s) +{ + const std::size_t len = std::ostream::traits_type::length(s); + *this->This() << len; + this->This()->newtoken(); + os << s; +} + +template +BOOST_ARCHIVE_DECL(void) +text_oarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + *this->This() << size; + this->This()->newtoken(); + os << s; +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL(void) +text_oarchive_impl::save(const wchar_t * ws) +{ + const std::size_t l = std::wcslen(ws); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)ws, l * sizeof(wchar_t)/sizeof(char)); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL(void) +text_oarchive_impl::save(const std::wstring &ws) +{ + const std::size_t l = ws.size(); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)(ws.data()), l * sizeof(wchar_t)/sizeof(char)); +} +#endif +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +text_oarchive_impl::text_oarchive_impl( + std::ostream & os, + unsigned int flags +) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_oarchive::init(); + #endif +} + +template +BOOST_ARCHIVE_DECL(void) +text_oarchive_impl::save_binary(const void *address, std::size_t count){ + put('\n'); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->delimiter = this->eol; +} + +} // namespace archive +} // namespace boost + diff --git a/thirdparty/boost/archive/impl/text_wiarchive_impl.ipp b/thirdparty/boost/archive/impl/text_wiarchive_impl.ipp new file mode 100644 index 0000000..3cf6005 --- /dev/null +++ b/thirdparty/boost/archive/impl/text_wiarchive_impl.ipp @@ -0,0 +1,118 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_text_wiarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // fixup for RogueWave + +#ifndef BOOST_NO_STD_WSTREAMBUF +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of wiprimtives functions +// +template +BOOST_WARCHIVE_DECL(void) +text_wiarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + while(size-- > 0){ + *s++ = is.narrow(is.get(), '\0'); + } + *s = '\0'; +} + +template +BOOST_WARCHIVE_DECL(void) +text_wiarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(size); + while(size-- > 0){ + int x = is.narrow(is.get(), '\0'); + s += x; + } +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL(void) +text_wiarchive_impl::load(wchar_t *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = L'\0'; +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL(void) +text_wiarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland complains about resize + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // note breaking a rule here - is this a problem on some platform + is.read(const_cast(ws.data()), size); +} +#endif + +template +BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) +text_wiarchive_impl::text_wiarchive_impl( + std::wistream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + basic_text_iarchive::init(); +} + +} // archive +} // boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/thirdparty/boost/archive/impl/text_woarchive_impl.ipp b/thirdparty/boost/archive/impl/text_woarchive_impl.ipp new file mode 100644 index 0000000..0d0a9ff --- /dev/null +++ b/thirdparty/boost/archive/impl/text_woarchive_impl.ipp @@ -0,0 +1,85 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; + using ::size_t; +} // namespace std +#endif + +#include + +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of woarchive functions +// +template +BOOST_WARCHIVE_DECL(void) +text_woarchive_impl::save(const char *s) +{ + // note: superfluous local variable fixes borland warning + const std::size_t size = std::strlen(s); + * this->This() << size; + this->This()->newtoken(); + while(*s != '\0') + os.put(os.widen(*s++)); +} + +template +BOOST_WARCHIVE_DECL(void) +text_woarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + * this->This() << size; + this->This()->newtoken(); + const char * cptr = s.data(); + for(std::size_t i = size; i-- > 0;) + os.put(os.widen(*cptr++)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL(void) +text_woarchive_impl::save(const wchar_t *ws) +{ + const std::size_t size = std::wostream::traits_type::length(ws); + * this->This() << size; + this->This()->newtoken(); + os.write(ws, size); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL(void) +text_woarchive_impl::save(const std::wstring &ws) +{ + const std::size_t size = ws.length(); + * this->This() << size; + this->This()->newtoken(); + os.write(ws.data(), size); +} +#endif + +} // namespace archive +} // namespace boost + +#endif + diff --git a/thirdparty/boost/archive/impl/xml_iarchive_impl.ipp b/thirdparty/boost/archive/impl/xml_iarchive_impl.ipp new file mode 100644 index 0000000..4555f89 --- /dev/null +++ b/thirdparty/boost/archive/impl/xml_iarchive_impl.ipp @@ -0,0 +1,199 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive_impl.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include +#include // memcpy +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include // mbtowc +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbtowc; + } // namespace std +#endif +#endif // BOOST_NO_CWCHAR + +#include // RogueWave and Dinkumware +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include + +#include +#include +#include +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::load(std::wstring &ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(0); + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + int resultx = std::mbtowc(&wc, start, end - start); + if(0 < resultx){ + start += resultx; + ws += wc; + continue; + } + boost::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + } +} +#endif // BOOST_NO_STD_WSTRING + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::load(wchar_t * ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + int result = std::mbtowc(&wc, start, end - start); + if(0 < result){ + start += result; + *ws++ = wc; + continue; + } + boost::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + } + *ws = L'\0'; +} +#endif + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::load(std::string &s){ + bool result = gimpl->parse_string(is, s); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} + +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::load(char * s){ + std::string tstring; + bool result = gimpl->parse_string(is, tstring); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(s, tstring.data(), tstring.size()); + s[tstring.size()] = 0; +} + +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::load_override(class_name_type & t, int){ + const std::string & s = gimpl->rv.class_name; + if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::throw_exception(archive_exception::invalid_class_name); + char * tptr = t; + std::memcpy(tptr, s.data(), s.size()); + tptr[s.size()] = '\0'; +} + +template +BOOST_ARCHIVE_DECL(void) +xml_iarchive_impl::init(){ + gimpl->init(is); + this->set_library_version(gimpl->rv.version); +} + +template +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_iarchive_impl::xml_iarchive_impl( + std::istream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + 0 != (flags & no_codecvt) + ), + basic_xml_iarchive(flags), + gimpl(new xml_grammar()) +{ + if(0 == (flags & no_header)){ + BOOST_TRY{ + init(); + } + BOOST_CATCH(...){ + delete gimpl; + #ifndef BOOST_NO_EXCEPTIONS + throw; // re-throw + #endif + } + BOOST_CATCH_END + } +} + +template +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_iarchive_impl::~xml_iarchive_impl(){ + if(0 == (this->get_flags() & no_header)){ + BOOST_TRY{ + gimpl->windup(is); + } + BOOST_CATCH(...){} + BOOST_CATCH_END + } + delete gimpl; +} +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/xml_oarchive_impl.ipp b/thirdparty/boost/archive/impl/xml_oarchive_impl.ipp new file mode 100644 index 0000000..20b2189 --- /dev/null +++ b/thirdparty/boost/archive/impl/xml_oarchive_impl.ipp @@ -0,0 +1,117 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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) + +#include +#include +#include +#include + +#include // strlen +#include // msvc 6.0 needs this to suppress warnings +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include +#include +#endif + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives +#ifndef BOOST_NO_CWCHAR +// copy chars to output escaping to xml and translating wide chars to mb chars +template +void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){ + typedef boost::archive::iterators::mb_from_wchar< + boost::archive::iterators::xml_escape + > translator; + std::copy( + translator(BOOST_MAKE_PFTO_WRAPPER(begin)), + translator(BOOST_MAKE_PFTO_WRAPPER(end)), + boost::archive::iterators::ostream_iterator(os) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL(void) +xml_oarchive_impl::save(const std::wstring & ws){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it +// save_iterator(os, ws.data(), ws.data() + std::wcslen(ws.data())); + save_iterator(os, ws.data(), ws.data() + ws.size()); +} +#endif + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL(void) +xml_oarchive_impl::save(const wchar_t * ws){ + save_iterator(os, ws, ws + std::wcslen(ws)); +} +#endif + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL(void) +xml_oarchive_impl::save(const std::string & s){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s.data())), + xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s.data()+ s.size())), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL(void) +xml_oarchive_impl::save(const char * s){ + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s)), + xml_escape_translator(BOOST_MAKE_PFTO_WRAPPER(s + std::strlen(s))), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_oarchive_impl::xml_oarchive_impl( + std::ostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + 0 != (flags & no_codecvt) + ), + basic_xml_oarchive(flags) +{ + if(0 == (flags & no_header)) + this->init(); +} + +} // namespace archive +} // namespace boost diff --git a/thirdparty/boost/archive/impl/xml_wiarchive_impl.ipp b/thirdparty/boost/archive/impl/xml_wiarchive_impl.ipp new file mode 100644 index 0000000..bc31761 --- /dev/null +++ b/thirdparty/boost/archive/impl/xml_wiarchive_impl.ipp @@ -0,0 +1,202 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiprimitive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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 for updates, documentation, and revision history. + +#include // for BOOST_DEDUCED_TYPENAME + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} //std +#endif + +#include // msvc 6.0 needs this to suppress warnings +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include + +#include // Dinkumware and RogueWave +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +namespace { // anonymous + +void copy_to_ptr(char * s, const std::wstring & ws){ + std::copy( + iterators::mb_from_wchar( + BOOST_MAKE_PFTO_WRAPPER(ws.begin()) + ), + iterators::mb_from_wchar( + BOOST_MAKE_PFTO_WRAPPER(ws.end()) + ), + s + ); + s[ws.size()] = 0; +} + +} // anonymous + +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::load(std::string & s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(ws.size()); + std::copy( + iterators::mb_from_wchar( + BOOST_MAKE_PFTO_WRAPPER(ws.begin()) + ), + iterators::mb_from_wchar( + BOOST_MAKE_PFTO_WRAPPER(ws.end()) + ), + std::back_inserter(s) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::load(std::wstring & ws){ + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::load(char * s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + copy_to_ptr(s, ws); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::load(wchar_t * ws){ + std::wstring twstring; + bool result = gimpl->parse_string(is, twstring); + if(! result) + boost::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(ws, twstring.c_str(), twstring.size()); + ws[twstring.size()] = L'\0'; +} +#endif + +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::load_override(class_name_type & t, int){ + const std::wstring & ws = gimpl->rv.class_name; + if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::throw_exception(archive_exception::invalid_class_name); + copy_to_ptr(t, ws); +} + +template +BOOST_WARCHIVE_DECL(void) +xml_wiarchive_impl::init(){ + gimpl->init(is); + this->set_library_version(gimpl->rv.version); +} + +template +BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_wiarchive_impl::xml_wiarchive_impl( + std::wistream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + true // don't change the codecvt - use the one below + ), + basic_xml_iarchive(flags), + gimpl(new xml_wgrammar()) +{ + if(0 == (flags & no_codecvt)){ + archive_locale.reset( + add_facet( + std::locale::classic(), + new detail::utf8_codecvt_facet + ) + ); + is.imbue(* archive_locale); + } + if(0 == (flags & no_header)){ + BOOST_TRY{ + this->init(); + } + BOOST_CATCH(...){ + delete gimpl; + #ifndef BOOST_NO_EXCEPTIONS + throw; // re-throw + #endif + } + BOOST_CATCH_END + } +} + +template +BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_wiarchive_impl::~xml_wiarchive_impl(){ + if(0 == (this->get_flags() & no_header)){ + BOOST_TRY{ + gimpl->windup(is); + } + BOOST_CATCH(...){} + BOOST_CATCH_END + } + delete gimpl; +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/thirdparty/boost/archive/impl/xml_woarchive_impl.ipp b/thirdparty/boost/archive/impl/xml_woarchive_impl.ipp new file mode 100644 index 0000000..9190de4 --- /dev/null +++ b/thirdparty/boost/archive/impl/xml_woarchive_impl.ipp @@ -0,0 +1,159 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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) + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include +#include +#include + +#include // msvc 6.0 needs this to suppress warnings + // for BOOST_DEDUCED_TYPENAME +#include // strlen +#include // mbtowc +#include // wcslen + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; + #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) + using ::mbtowc; + using ::wcslen; + #endif +} // namespace std +#endif + +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +// copy chars to output escaping to xml and widening characters as we go +template +void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ + typedef iterators::wchar_from_mb< + iterators::xml_escape + > xmbtows; + std::copy( + xmbtows(BOOST_MAKE_PFTO_WRAPPER(begin)), + xmbtows(BOOST_MAKE_PFTO_WRAPPER(end)), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_WARCHIVE_DECL(void) +xml_woarchive_impl::save(const std::string & s){ + // note: we don't use s.begin() and s.end() because dinkumware + // doesn't have string::value_type defined. So use a wrapper + // around these values to implement the definitions. + const char * begin = s.data(); + const char * end = begin + s.size(); + save_iterator(os, begin, end); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL(void) +xml_woarchive_impl::save(const std::wstring & ws){ +#if 0 + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.begin())), + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.end())), + boost::archive::iterators::ostream_iterator(os) + ); +#endif + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.data())), + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws.data() + ws.size())), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif //BOOST_NO_STD_WSTRING + +template +BOOST_WARCHIVE_DECL(void) +xml_woarchive_impl::save(const char * s){ + save_iterator(os, s, s + std::strlen(s)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL(void) +xml_woarchive_impl::save(const wchar_t * ws){ + os << ws; + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws)), + xmbtows(BOOST_MAKE_PFTO_WRAPPER(ws + std::wcslen(ws))), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_woarchive_impl::xml_woarchive_impl( + std::wostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + true // don't change the codecvt - use the one below + ), + basic_xml_oarchive(flags) +{ + // Standard behavior is that imbue can be called + // a) before output is invoked or + // b) after flush has been called. This prevents one-to-many + // transforms (such as one to many transforms from getting + // mixed up. Unfortunately, STLPort doesn't respect b) above + // so the restoration of the original archive locale done by + // the locale_saver doesn't get processed, + // before the current one is destroyed. + // so the codecvt doesn't get replaced with the orginal + // so closing the stream invokes codecvt::do_unshift + // so it crashes because the corresponding locale that contained + // the codecvt isn't around any more. + // we can hack around this by using a static codecvt that never + // gets destroyed. + if(0 == (flags & no_codecvt)){ + detail::utf8_codecvt_facet *pfacet; + #if defined(__SGI_STL_PORT) + static detail::utf8_codecvt_facet facet(static_cast(1)); + pfacet = & facet; + #else + pfacet = new detail::utf8_codecvt_facet; + #endif + archive_locale.reset(add_facet(std::locale::classic(), pfacet)); + os.imbue(* archive_locale); + } + if(0 == (flags & no_header)) + this->init(); +} + +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_STD_WSTREAMBUF diff --git a/thirdparty/boost/archive/iterators/base64_exception.hpp b/thirdparty/boost/archive/iterators/base64_exception.hpp new file mode 100644 index 0000000..48a67c4 --- /dev/null +++ b/thirdparty/boost/archive/iterators/base64_exception.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by base64s +// +class base64_exception : public std::exception +{ +public: + typedef enum { + invalid_code, // attempt to encode a value > 6 bits + invalid_character, // decode a value not in base64 char set + other_exception + } exception_code; + exception_code code; + + base64_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_code: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_character: + msg = "attempt to decode a value not in base64 char set"; + break; + default: + assert(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_ARCHIVE_EXCEPTION_HPP diff --git a/thirdparty/boost/archive/iterators/base64_from_binary.hpp b/thirdparty/boost/archive/iterators/base64_from_binary.hpp new file mode 100644 index 0000000..347c520 --- /dev/null +++ b/thirdparty/boost/archive/iterators/base64_from_binary.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_from_binary.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert binary integers to base64 characters + +namespace detail { + +template +struct from_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + const char * lookup_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + assert(t < 64); + return lookup_table[t]; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +//template +template< + class Base, + class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value::type +> +class base64_from_binary : + public transform_iterator< + detail::from_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + BOOST_DEDUCED_TYPENAME detail::from_6_bit, + Base + > super_t; + +public: + // make composible buy using templated constructor + template + base64_from_binary(BOOST_PFTO_WRAPPER(T) start) : + super_t( + Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start))), + detail::from_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + base64_from_binary(const base64_from_binary & rhs) : + super_t( + Base(rhs.base_reference()), + detail::from_6_bit() + ) + {} +// base64_from_binary(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP diff --git a/thirdparty/boost/archive/iterators/binary_from_base64.hpp b/thirdparty/boost/archive/iterators/binary_from_base64.hpp new file mode 100644 index 0000000..db49439 --- /dev/null +++ b/thirdparty/boost/archive/iterators/binary_from_base64.hpp @@ -0,0 +1,120 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP +#define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_from_base64.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include +#include +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 characters to binary data + +namespace detail { + +template +struct to_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + const char lookup_table[] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 + }; + // metrowerks trips this assertion - how come? + #if ! defined(__MWERKS__) + BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); + #endif + signed char value = -1; + if((unsigned)t <= 127) + value = lookup_table[(unsigned)t]; + if(-1 == value) + boost::throw_exception( + dataflow_exception(dataflow_exception::invalid_base64_character) + ); + return value; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +template< + class Base, + class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value::type +> +class binary_from_base64 : public + transform_iterator< + detail::to_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + detail::to_6_bit, + Base + > super_t; +public: + // make composible buy using templated constructor + template + binary_from_base64(BOOST_PFTO_WRAPPER(T) start) : + super_t( + Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start))), + detail::to_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + binary_from_base64(const binary_from_base64 & rhs) : + super_t( + Base(rhs.base_reference()), + detail::to_6_bit() + ) + {} +// binary_from_base64(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP diff --git a/thirdparty/boost/archive/iterators/dataflow.hpp b/thirdparty/boost/archive/iterators/dataflow.hpp new file mode 100644 index 0000000..6a88a23 --- /dev/null +++ b/thirdparty/boost/archive/iterators/dataflow.hpp @@ -0,0 +1,104 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// poor man's tri-state +struct tri_state { + enum state_enum { + is_false = false, + is_true = true, + is_indeterminant, + } m_state; + // convert to bool + operator bool (){ + assert(is_indeterminant != m_state); + return is_true == m_state ? true : false; + } + // assign from bool + tri_state & operator=(bool rhs) { + m_state = rhs ? is_true : is_false; + } + tri_state(bool rhs) : + m_state(rhs ? is_true : is_false) + {} + tri_state(state_enum state) : + m_state(state) + {} + bool operator==(const tri_state & rhs) const { + return m_state == rhs.m_state; + } + bool operator!=(const tri_state & rhs) const { + return m_state != rhs.m_state; + } +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implement functions common to dataflow iterators +template +class dataflow { + bool m_eoi; +protected: + // test for iterator equality + tri_state equal(const Derived & rhs) const { + if(m_eoi && rhs.m_eoi) + return true; + if(m_eoi || rhs.m_eoi) + return false; + return tri_state(tri_state::is_indeterminant); + } + void eoi(bool tf){ + m_eoi = tf; + } + bool eoi() const { + return m_eoi; + } +public: + dataflow(bool tf) : + m_eoi(tf) + {} + dataflow() : // used for iterator end + m_eoi(true) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP diff --git a/thirdparty/boost/archive/iterators/dataflow_exception.hpp b/thirdparty/boost/archive/iterators/dataflow_exception.hpp new file mode 100644 index 0000000..7492f51 --- /dev/null +++ b/thirdparty/boost/archive/iterators/dataflow_exception.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by dataflows +// +class dataflow_exception : public std::exception +{ +public: + typedef enum { + invalid_6_bitcode, + invalid_base64_character, + invalid_xml_escape_sequence, + comparison_not_permitted, + invalid_conversion, + other_exception + } exception_code; + exception_code code; + + dataflow_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_6_bitcode: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_base64_character: + msg = "attempt to decode a value not in base64 char set"; + break; + case invalid_xml_escape_sequence: + msg = "invalid xml escape_sequence"; + break; + case comparison_not_permitted: + msg = "cannot invoke iterator comparison now"; + break; + case invalid_conversion: + msg = "invalid multbyte/wide char conversion"; + break; + default: + assert(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP diff --git a/thirdparty/boost/archive/iterators/escape.hpp b/thirdparty/boost/archive/iterators/escape.hpp new file mode 100644 index 0000000..3f01943 --- /dev/null +++ b/thirdparty/boost/archive/iterators/escape.hpp @@ -0,0 +1,114 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// escape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into text + +template +class escape : + public boost::iterator_adaptor< + Derived, + Base, + BOOST_DEDUCED_TYPENAME boost::iterator_value::type, + single_pass_traversal_tag, + BOOST_DEDUCED_TYPENAME boost::iterator_value::type + > +{ + typedef BOOST_DEDUCED_TYPENAME boost::iterator_value::type base_value_type; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference::type reference_type; + friend class boost::iterator_core_access; + + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + Derived, + Base, + base_value_type, + single_pass_traversal_tag, + base_value_type + > super_t; + + typedef escape this_t; + + void dereference_impl() { + m_current_value = static_cast(this)->fill(m_bnext, m_bend); + m_full = true; + } + + //Access the value referred to + reference_type dereference() const { + if(!m_full) + const_cast(this)->dereference_impl(); + return m_current_value; + } + + bool equal(const this_t & rhs) const { + if(m_full){ + if(! rhs.m_full) + const_cast(& rhs)->dereference_impl(); + } + else{ + if(rhs.m_full) + const_cast(this)->dereference_impl(); + } + if(m_bnext != rhs.m_bnext) + return false; + if(this->base_reference() != rhs.base_reference()) + return false; + return true; + } + + void increment(){ + if(++m_bnext < m_bend){ + m_current_value = *m_bnext; + return; + } + ++(this->base_reference()); + m_bnext = NULL; + m_bend = NULL; + m_full = false; + } + + // buffer to handle pending characters + const base_value_type *m_bnext; + const base_value_type *m_bend; + bool m_full; + BOOST_DEDUCED_TYPENAME boost::iterator_value::type m_current_value; +public: + escape(Base base) : + super_t(base), + m_bnext(NULL), + m_bend(NULL), + m_full(false) + { + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP diff --git a/thirdparty/boost/archive/iterators/head_iterator.hpp b/thirdparty/boost/archive/iterators/head_iterator.hpp new file mode 100644 index 0000000..08e08a3 --- /dev/null +++ b/thirdparty/boost/archive/iterators/head_iterator.hpp @@ -0,0 +1,81 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_HEAD_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_HEAD_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// head_iterator.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +template +class head_iterator + : public boost::iterator_adaptor< + head_iterator, + Base, + use_default, + single_pass_traversal_tag + > +{ +private: + friend class iterator_core_access; + typedef boost::iterator_adaptor< + head_iterator, + Base, + use_default, + single_pass_traversal_tag + > super_t; + + typedef head_iterator this_t; + typedef BOOST_DEDUCED_TYPENAME super_t::value_type value_type; + typedef BOOST_DEDUCED_TYPENAME super_t::reference reference_type; + + reference_type dereference_impl(){ + if(! m_end){ + while(! m_predicate(* base_reference())) + ++ base_reference(); + m_end = true; + } + return * base_reference(); + } + + reference_type dereference() const { + return const_cast(this)->dereference_impl(); + } + + void increment(){ + ++base_reference(); + } + Predicate m_predicate; + bool m_end; +public: + template + head_iterator(Predicate f, T start) : + super_t(Base(start)), + m_predicate(f), + m_end(false) + {} + +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_HEAD_ITERATOR_HPP diff --git a/thirdparty/boost/archive/iterators/insert_linebreaks.hpp b/thirdparty/boost/archive/iterators/insert_linebreaks.hpp new file mode 100644 index 0000000..13b890c --- /dev/null +++ b/thirdparty/boost/archive/iterators/insert_linebreaks.hpp @@ -0,0 +1,101 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP +#define BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_from_base64.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::memcpy; } +#endif + +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert line break every N characters +template< + class Base, + int N, + class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value::type +> +class insert_linebreaks : + public iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ +private: + friend class boost::iterator_core_access; + typedef iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + bool equal(const insert_linebreaks & rhs) const { + return +// m_count == rhs.m_count +// && base_reference() == rhs.base_reference() + this->base_reference() == rhs.base_reference() + ; + } + + void increment() { + if(m_count == N){ + m_count = 0; + return; + } + ++m_count; + ++(this->base_reference()); + } + CharType dereference() const { + if(m_count == N) + return '\n'; + return * (this->base_reference()); + } + unsigned int m_count; +public: + // make composible buy using templated constructor + template + insert_linebreaks(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))), + m_count(0) + {} + // intel 7.1 doesn't like default copy constructor + insert_linebreaks(const insert_linebreaks & rhs) : + super_t(rhs.base_reference()), + m_count(rhs.m_count) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP diff --git a/thirdparty/boost/archive/iterators/istream_iterator.hpp b/thirdparty/boost/archive/iterators/istream_iterator.hpp new file mode 100644 index 0000000..17fb91f --- /dev/null +++ b/thirdparty/boost/archive/iterators/istream_iterator.hpp @@ -0,0 +1,94 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// istream_iterator.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: this is a custom version of the standard istream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class istream_iterator : + public boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > +{ + friend class boost::iterator_core_access; + typedef istream_iterator this_t ; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > super_t; + typedef BOOST_DEDUCED_TYPENAME std::basic_istream istream_type; + + //Access the value referred to + Elem dereference() const { + return m_current_value; + } + + bool equal(const this_t & rhs) const { + // note: only works for comparison against end of stream + return m_istream == rhs.m_istream; + } + + void increment(){ + if(NULL != m_istream){ + m_current_value = m_istream->get(); + if(! m_istream->good()){ + const_cast(this)->m_istream = NULL; + } + } + } + + istream_type *m_istream; + Elem m_current_value; +public: + istream_iterator(istream_type & is) : + m_istream(& is) + { + increment(); + } + + istream_iterator() : + m_istream(NULL) + {} + + istream_iterator(const istream_iterator & rhs) : + m_istream(rhs.m_istream), + m_current_value(rhs.m_current_value) + {} + +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP diff --git a/thirdparty/boost/archive/iterators/mb_from_wchar.hpp b/thirdparty/boost/archive/iterators/mb_from_wchar.hpp new file mode 100644 index 0000000..5464900 --- /dev/null +++ b/thirdparty/boost/archive/iterators/mb_from_wchar.hpp @@ -0,0 +1,136 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP +#define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// mb_from_wchar.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // size_t +#include // for wctomb() + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + using ::wctomb; +} // namespace std +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate wide strings and to char +// strings of the currently selected locale +template // the input iterator +class mb_from_wchar + : public boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > +{ + friend class boost::iterator_core_access; + + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > super_t; + + typedef mb_from_wchar this_t; + + char dereference_impl() { + if(! m_full){ + fill(); + m_full = true; + } + return m_buffer[m_bnext]; + } + char dereference() const { + return (const_cast(this))->dereference_impl(); + } + + // test for iterator equality + bool equal(const mb_from_wchar & rhs) const { + // once the value is filled, the base_reference has been incremented + // so don't permit comparison anymore. + return + 0 == m_bend + && 0 == m_bnext + && this->base_reference() == rhs.base_reference() + ; + } + + void fill(){ + wchar_t value = * this->base_reference(); + #if (defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 3) \ + || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION >= 8)))) + m_bend = std::wcrtomb(m_buffer, value, 0); + #else + m_bend = std::wctomb(m_buffer, value); + #endif + assert(-1 != m_bend); + assert((std::size_t)m_bend <= sizeof(m_buffer)); + assert(m_bend > 0); + m_bnext = 0; + } + + void increment(){ + if(++m_bnext < m_bend) + return; + m_bend = + m_bnext = 0; + ++(this->base_reference()); + m_full = false; + } + + // buffer to handle pending characters + int m_bend; + int m_bnext; + char m_buffer[9]; + bool m_full; + +public: + // make composible buy using templated constructor + template + mb_from_wchar(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))), + m_bend(0), + m_bnext(0), + m_full(false) + {} + // intel 7.1 doesn't like default copy constructor + mb_from_wchar(const mb_from_wchar & rhs) : + super_t(rhs.base_reference()), + m_bend(rhs.m_bend), + m_bnext(rhs.m_bnext), + m_full(rhs.m_full) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP diff --git a/thirdparty/boost/archive/iterators/ostream_iterator.hpp b/thirdparty/boost/archive/iterators/ostream_iterator.hpp new file mode 100644 index 0000000..791529f --- /dev/null +++ b/thirdparty/boost/archive/iterators/ostream_iterator.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// ostream_iterator.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: this is a custom version of the standard ostream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class ostream_iterator : + public boost::iterator_facade< + ostream_iterator, + Elem, + std::output_iterator_tag, + ostream_iterator & + > +{ + friend class boost::iterator_core_access; + typedef ostream_iterator this_t ; + typedef Elem char_type; + typedef std::basic_ostream ostream_type; + + //emulate the behavior of std::ostream + ostream_iterator & dereference() const { + return const_cast(*this); + } + bool equal(const this_t & rhs) const { + return m_ostream == rhs.m_ostream; + } + void increment(){} +protected: + ostream_type *m_ostream; + void put_val(char_type e){ + if(NULL != m_ostream){ + m_ostream->put(e); + if(! m_ostream->good()) + m_ostream = NULL; + } + } +public: + this_t & operator=(char_type c){ + put_val(c); + return *this; + } + ostream_iterator(ostream_type & os) : + m_ostream (& os) + {} + ostream_iterator() : + m_ostream (NULL) + {} + ostream_iterator(const ostream_iterator & rhs) : + m_ostream (rhs.m_ostream) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP diff --git a/thirdparty/boost/archive/iterators/remove_whitespace.hpp b/thirdparty/boost/archive/iterators/remove_whitespace.hpp new file mode 100644 index 0000000..31099c0 --- /dev/null +++ b/thirdparty/boost/archive/iterators/remove_whitespace.hpp @@ -0,0 +1,169 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP +#define BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_from_base64.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME + +#include + +#include +#include + +//#include +//#if ! BOOST_WORKAROUND(BOOST_MSVC, <=1300) + +// here is the default standard implementation of the functor used +// by the filter iterator to remove spaces. Unfortunately usage +// of this implementation in combination with spirit trips a bug +// VC 6.5. The only way I can find to work around it is to +// implement a special non-standard version for this platform + +#ifndef BOOST_NO_CWCTYPE +#include // iswspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::iswspace; } +#endif +#endif + +#include // isspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::isspace; } +#endif + +#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// this is required for the RW STL on Linux and Tru64. +#undef isspace +#undef iswspace +#endif + +//#endif // BOOST_WORKAROUND + +namespace { // anonymous + +template +struct remove_whitespace_predicate; + +template<> +struct remove_whitespace_predicate +{ + bool operator()(unsigned char t){ + return ! std::isspace(t); + } +}; + +#ifndef BOOST_NO_CWCHAR +template<> +struct remove_whitespace_predicate +{ + bool operator()(wchar_t t){ + return ! std::iswspace(t); + } +}; +#endif + +} // namespace anonymous + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 file data (including whitespace and padding) to binary + +namespace boost { +namespace archive { +namespace iterators { + +// custom version of filter iterator which doesn't look ahead further than +// necessary + +template +class filter_iterator + : public boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > +{ + friend class boost::iterator_core_access; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > super_t; + typedef filter_iterator this_t; + typedef BOOST_DEDUCED_TYPENAME super_t::reference reference_type; + + reference_type dereference_impl(){ + if(! m_full){ + while(! m_predicate(* this->base_reference())) + ++(this->base_reference()); + m_full = true; + } + return * this->base_reference(); + } + + reference_type dereference() const { + return const_cast(this)->dereference_impl(); + } + + Predicate m_predicate; + bool m_full; +public: + // note: this function is public only because comeau compiler complained + // I don't know if this is because the compiler is wrong or what + void increment(){ + m_full = false; + ++(this->base_reference()); + } + filter_iterator(Base start) : + super_t(start), + m_full(false) + {} + filter_iterator(){} +}; + +template +class remove_whitespace : + public filter_iterator< + remove_whitespace_predicate, + Base + > +{ + friend class boost::iterator_core_access; + typedef filter_iterator< + remove_whitespace_predicate, + Base + > super_t; +public: +// remove_whitespace(){} // why is this needed? + // make composible buy using templated constructor + template + remove_whitespace(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))) + {} + // intel 7.1 doesn't like default copy constructor + remove_whitespace(const remove_whitespace & rhs) : + super_t(rhs.base_reference()) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP diff --git a/thirdparty/boost/archive/iterators/transform_width.hpp b/thirdparty/boost/archive/iterators/transform_width.hpp new file mode 100644 index 0000000..8353d56 --- /dev/null +++ b/thirdparty/boost/archive/iterators/transform_width.hpp @@ -0,0 +1,168 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP +#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// transform_width.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// iterator which takes elements of x bits and returns elements of y bits. +// used to change streams of 8 bit characters into streams of 6 bit characters. +// and vice-versa for implementing base64 encodeing/decoding. Be very careful +// when using and end iterator. end is only reliable detected when the input +// stream length is some common multiple of x and y. E.G. Base64 6 bit +// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters +// or 3 8 bit characters + +#include // for BOOST_DEDUCED_TYPENAME & PTFO +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template< + class Base, + int BitsOut, + int BitsIn, + class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value::type // output character +> +class transform_width : + public boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ + friend class boost::iterator_core_access; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + typedef transform_width this_t; + typedef BOOST_DEDUCED_TYPENAME iterator_value::type base_value_type; + + CharType fill(); + + CharType dereference_impl(){ + if(! m_full){ + m_current_value = fill(); + m_full = true; + } + return m_current_value; + } + + CharType dereference() const { + return const_cast(this)->dereference_impl(); + } + + // test for iterator equality + bool equal(const this_t & rhs) const { + return + this->base_reference() == rhs.base_reference(); + ; + } + + void increment(){ + m_displacement += BitsOut; + + while(m_displacement >= BitsIn){ + m_displacement -= BitsIn; + if(0 == m_displacement) + m_bufferfull = false; + if(! m_bufferfull){ + // note: suspect that this is not invoked for borland + ++(this->base_reference()); + } + } + m_full = false; + } + + CharType m_current_value; + // number of bits left in current input character buffer + unsigned int m_displacement; + base_value_type m_buffer; + // flag to current output character is ready - just used to save time + bool m_full; + // flag to indicate that m_buffer has data + bool m_bufferfull; + +public: + // make composible buy using templated constructor + template + transform_width(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))), + m_displacement(0), + m_full(false), + m_bufferfull(false) + {} + // intel 7.1 doesn't like default copy constructor + transform_width(const transform_width & rhs) : + super_t(rhs.base_reference()), + m_current_value(rhs.m_current_value), + m_displacement(rhs.m_displacement), + m_buffer(rhs.m_buffer), + m_full(rhs.m_full), + m_bufferfull(rhs.m_bufferfull) + {} +}; + +template +CharType transform_width::fill(){ + CharType retval = 0; + unsigned int missing_bits = BitsOut; + for(;;){ + unsigned int bcount; + if(! m_bufferfull){ + m_buffer = * this->base_reference(); + m_bufferfull = true; + bcount = BitsIn; + } + else + bcount = BitsIn - m_displacement; + unsigned int i = (std::min)(bcount, missing_bits); + // shift interesting bits to least significant position + unsigned int j = m_buffer >> (bcount - i); + // strip off uninteresting bits + // (note presumption of two's complement arithmetic) + j &= ~(-(1 << i)); + // append then interesting bits to the output value + retval <<= i; + retval |= j; + missing_bits -= i; + if(0 == missing_bits) + break; + // note: suspect that this is not invoked for borland 5.51 + ++(this->base_reference()); + m_bufferfull = false; + } + return retval; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP diff --git a/thirdparty/boost/archive/iterators/unescape.hpp b/thirdparty/boost/archive/iterators/unescape.hpp new file mode 100644 index 0000000..49f5263 --- /dev/null +++ b/thirdparty/boost/archive/iterators/unescape.hpp @@ -0,0 +1,94 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unescape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include +//#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class unescape + : public boost::iterator_adaptor< + unescape, + Base, + BOOST_DEDUCED_TYPENAME pointee::type, + single_pass_traversal_tag, + BOOST_DEDUCED_TYPENAME pointee::type + > +{ + friend class boost::iterator_core_access; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + unescape, + Base, + BOOST_DEDUCED_TYPENAME pointee::type, + single_pass_traversal_tag, + BOOST_DEDUCED_TYPENAME pointee::type + > super_t; + + typedef unescape this_t; + typedef BOOST_DEDUCED_TYPENAME super_t::reference reference_type; +public: + // gcc 3.4.1 - linux required that this be public + typedef BOOST_DEDUCED_TYPENAME super_t::value_type value_type; +private: + + reference_type dereference_impl() { + if(! m_full){ + m_current_value = static_cast(this)->drain(); + m_full = true; + } + return m_current_value; + } + + reference_type dereference() const { + return const_cast(this)->dereference_impl(); + } + + // value_type is const char - can't be const fix later + value_type m_current_value; + bool m_full; + + void increment(){ + ++(this->base_reference()); + dereference_impl(); + m_full = false; + }; + +public: + + unescape(Base base) : + super_t(base), + m_full(false) + {} + +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP diff --git a/thirdparty/boost/archive/iterators/wchar_from_mb.hpp b/thirdparty/boost/archive/iterators/wchar_from_mb.hpp new file mode 100644 index 0000000..f2fd547 --- /dev/null +++ b/thirdparty/boost/archive/iterators/wchar_from_mb.hpp @@ -0,0 +1,129 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP +#define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wchar_from_mb.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t +#include // mblen + +#include // for BOOST_DEDUCED_TYPENAME +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mblen; + using ::mbtowc; +} // namespace std +#endif + +#include +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class wchar_from_mb + : public boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > +{ + friend class boost::iterator_core_access; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > super_t; + + typedef wchar_from_mb this_t; + + wchar_t drain(); + + wchar_t dereference_impl() { + if(! m_full){ + m_current_value = drain(); + m_full = true; + } + return m_current_value; + } + + wchar_t dereference() const { + return const_cast(this)->dereference_impl(); + } + + void increment(){ + dereference_impl(); + m_full = false; + ++(this->base_reference()); + }; + + wchar_t m_current_value; + bool m_full; + +public: + // make composible buy using templated constructor + template + wchar_from_mb(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))), + m_full(false) + {} + // intel 7.1 doesn't like default copy constructor + wchar_from_mb(const wchar_from_mb & rhs) : + super_t(rhs.base_reference()), + m_full(rhs.m_full) + {} +}; + +template +wchar_t wchar_from_mb::drain(){ + char buffer[9]; + char * bptr = buffer; + char val; + for(std::size_t i = 0; i++ < (unsigned)MB_CUR_MAX;){ + val = * this->base_reference(); + *bptr++ = val; + int result = std::mblen(buffer, i); + if(-1 != result) + break; + ++(this->base_reference()); + } + wchar_t retval; + int result = std::mbtowc(& retval, buffer, MB_CUR_MAX); + if(0 >= result) + boost::throw_exception(iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + )); + return retval; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP diff --git a/thirdparty/boost/archive/iterators/xml_escape.hpp b/thirdparty/boost/archive/iterators/xml_escape.hpp new file mode 100644 index 0000000..5c16820 --- /dev/null +++ b/thirdparty/boost/archive/iterators/xml_escape.hpp @@ -0,0 +1,125 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_escape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into xml text + +template +class xml_escape + : public escape, Base> +{ + friend class boost::iterator_core_access; + + typedef escape, Base> super_t; + +public: + char fill(const char * & bstart, const char * & bend); + wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend); + + template + xml_escape(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))) + {} + // intel 7.1 doesn't like default copy constructor + xml_escape(const xml_escape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +char xml_escape::fill( + const char * & bstart, + const char * & bend +){ + char current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = "<"; + bend = bstart + 4; + break; + case '>': + bstart = ">"; + bend = bstart + 4; + break; + case '&': + bstart = "&"; + bend = bstart + 5; + break; + case '"': + bstart = """; + bend = bstart + 6; + break; + case '\'': + bstart = "'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +template +wchar_t xml_escape::fill( + const wchar_t * & bstart, + const wchar_t * & bend +){ + wchar_t current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = L"<"; + bend = bstart + 4; + break; + case '>': + bstart = L">"; + bend = bstart + 4; + break; + case '&': + bstart = L"&"; + bend = bstart + 5; + break; + case '"': + bstart = L"""; + bend = bstart + 6; + break; + case '\'': + bstart = L"'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP diff --git a/thirdparty/boost/archive/iterators/xml_unescape.hpp b/thirdparty/boost/archive/iterators/xml_unescape.hpp new file mode 100644 index 0000000..2f40ab0 --- /dev/null +++ b/thirdparty/boost/archive/iterators/xml_unescape.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // for BOOST_DEDUCED_TYPENAME +#include +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// replace &??? xml escape sequences with the corresponding characters +template +class xml_unescape + : public unescape, Base> +{ + friend class boost::iterator_core_access; + typedef xml_unescape this_t; + typedef unescape super_t; + typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference reference_type; + + reference_type dereference() const { + return unescape, Base>::dereference(); + } +public: + void drain_residue(const char *literal); + int drain(); + + template + xml_unescape(BOOST_PFTO_WRAPPER(T) start) : + super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast(start)))) + {} + // intel 7.1 doesn't like default copy constructor + xml_unescape(const xml_unescape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +void xml_unescape::drain_residue(const char * literal){ + do{ + if(* literal != * ++(this->base_reference())) + boost::throw_exception( + dataflow_exception( + dataflow_exception::invalid_xml_escape_sequence + ) + ); + } + while('\0' != * ++literal); +} + +// note key constraint on this function is that can't "look ahead" any +// more than necessary into base iterator. Doing so would alter the base +// iterator refenence which would make subsequent iterator comparisons +// incorrect and thereby break the composiblity of iterators. +template +int xml_unescape::drain(){ + int retval = * this->base_reference(); + if('&' != retval){ + return retval; + } + retval = * ++(this->base_reference()); + switch(retval){ + case 'l': // < + drain_residue("t;"); + retval = '<'; + break; + case 'g': // > + drain_residue("t;"); + retval = '>'; + break; + case 'a': + retval = * ++(this->base_reference()); + switch(retval){ + case 'p': // ' + drain_residue("os;"); + retval = '\''; + break; + case 'm': // & + drain_residue("p;"); + retval = '&'; + break; + } + break; + case 'q': + drain_residue("uot;"); + retval = '"'; + break; + } + return retval; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP diff --git a/thirdparty/boost/archive/iterators/xml_unescape_exception.hpp b/thirdparty/boost/archive/iterators/xml_unescape_exception.hpp new file mode 100644 index 0000000..ebc3468 --- /dev/null +++ b/thirdparty/boost/archive/iterators/xml_unescape_exception.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml_unescapes +// +class xml_unescape_exception : public std::exception +{ +public: + xml_unescape_exception() + {} + + virtual const char *what( ) const throw( ) + { + return "xml contained un-recognized escape code"; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP diff --git a/thirdparty/boost/archive/polymorphic_binary_iarchive.hpp b/thirdparty/boost/archive/polymorphic_binary_iarchive.hpp new file mode 100644 index 0000000..8e850da --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_binary_iarchive.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +class polymorphic_binary_iarchive : + public detail::polymorphic_iarchive_dispatch +{ +public: + polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_dispatch(is, flags) + {} + ~polymorphic_binary_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_binary_oarchive.hpp b/thirdparty/boost/archive/polymorphic_binary_oarchive.hpp new file mode 100644 index 0000000..f9e4178 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_binary_oarchive.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_dispatch< + binary_oarchive_impl< + naked_binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > + > polymorphic_binary_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_iarchive.hpp b/thirdparty/boost/archive/polymorphic_iarchive.hpp new file mode 100644 index 0000000..3eb9a63 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_iarchive.hpp @@ -0,0 +1,177 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // std::size_t +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +#include +#include +#include +#include +#include + +// determine if its necessary to handle (u)int64_t specifically +// i.e. that its not a synonym for (unsigned) long +// if there is no 64 bit int or if its the same as a long +// we shouldn't define separate functions for int64 data types. +#if defined(BOOST_NO_INT64_T) \ + || (ULONG_MAX != 0xffffffff && ULONG_MAX == 18446744073709551615u) // 2**64 - 1 +# define BOOST_NO_INTRINSIC_INT64_T +#endif + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_iarchive; + class basic_iserializer; +} + +class polymorphic_iarchive; + +class polymorphic_iarchive_impl : + public detail::interface_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class load_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t) = 0; + + virtual void load(char & t) = 0; + virtual void load(signed char & t) = 0; + virtual void load(unsigned char & t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t) = 0; + #endif + #endif + virtual void load(short & t) = 0; + virtual void load(unsigned short & t) = 0; + virtual void load(int & t) = 0; + virtual void load(unsigned int & t) = 0; + virtual void load(long & t) = 0; + virtual void load(unsigned long & t) = 0; + + #if !defined(BOOST_NO_INTRINSIC_INT64_T) + virtual void load(boost::int64_t & t) = 0; + virtual void load(boost::uint64_t & t) = 0; + #endif + virtual void load(float & t) = 0; + virtual void load(double & t) = 0; + + // string types are treated as primitives + virtual void load(std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t) = 0; + #endif + + // used for xml and other tagged formats + virtual void load_start(const char * name) = 0; + virtual void load_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void load_override(T & t, BOOST_PFTO int) + { + archive::load(* this->This(), t); + } + // special treatment for name-value pairs. + template + void load_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + boost::serialization::nvp & t, + int + ){ + load_start(t.name()); + archive::load(* this->This(), t.value()); + load_end(t.name()); + } +protected: + virtual ~polymorphic_iarchive_impl(){} +public: + // utility function implemented by all legal archives + virtual void set_library_version(unsigned int archive_library_version) = 0; + virtual unsigned int get_library_version() const = 0; + virtual unsigned int get_flags() const = 0; + virtual void delete_created_pointers() = 0; + virtual void reset_object_address( + const void * new_address, + const void * old_address + ) = 0; + + virtual void load_binary(void * t, std::size_t size) = 0; + + // these are used by the serialization library implementation. + virtual void load_object( + void *t, + const detail::basic_iserializer & bis + ) = 0; + virtual const detail::basic_pointer_iserializer * load_pointer( + void * & t, + const detail::basic_pointer_iserializer * bpis_ptr, + const detail::basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ) = 0; +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class polymorphic_iarchive : + public polymorphic_iarchive_impl, + public detail::shared_ptr_helper +{}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_iarchive) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/polymorphic_oarchive.hpp b/thirdparty/boost/archive/polymorphic_oarchive.hpp new file mode 100644 index 0000000..d15b63e --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_oarchive.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include + +// determine if its necessary to handle (u)int64_t specifically +// i.e. that its not a synonym for (unsigned) long +// if there is no 64 bit int or if its the same as a long +// we shouldn't define separate functions for int64 data types. +#if defined(BOOST_NO_INT64_T) \ + || (ULONG_MAX != 0xffffffff && ULONG_MAX == 18446744073709551615u) // 2**64 - 1 +# define BOOST_NO_INTRINSIC_INT64_T +#endif + +namespace boost { +template +class shared_ptr; +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_oarchive; + class basic_oserializer; +} + +class polymorphic_oarchive; + +class polymorphic_oarchive_impl : + public detail::interface_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class save_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t) = 0; + + virtual void save(const char t) = 0; + virtual void save(const signed char t) = 0; + virtual void save(const unsigned char t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t) = 0; + #endif + #endif + virtual void save(const short t) = 0; + virtual void save(const unsigned short t) = 0; + virtual void save(const int t) = 0; + virtual void save(const unsigned int t) = 0; + virtual void save(const long t) = 0; + virtual void save(const unsigned long t) = 0; + #if !defined(BOOST_NO_INTRINSIC_INT64_T) + virtual void save(const boost::int64_t t) = 0; + virtual void save(const boost::uint64_t t) = 0; + #endif + virtual void save(const float t) = 0; + virtual void save(const double t) = 0; + + // string types are treated as primitives + virtual void save(const std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t) = 0; + #endif + + virtual void save_null_pointer() = 0; + // used for xml and other tagged formats + virtual void save_start(const char * name) = 0; + virtual void save_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0; + + virtual void end_preamble() = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void save_override(T & t, BOOST_PFTO int) + { + archive::save(* this->This(), t); + } + // special treatment for name-value pairs. + template + void save_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + ::boost::serialization::nvp & t, int + ){ + save_start(t.name()); + archive::save(* this->This(), t.const_value()); + save_end(t.name()); + } +protected: + virtual ~polymorphic_oarchive_impl(){} +public: + // utility functions implemented by all legal archives + virtual unsigned int get_flags() const = 0; + virtual unsigned int get_library_version() const = 0; + virtual void save_binary(const void * t, std::size_t size) = 0; + + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ) = 0; + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ) = 0; +}; + +// note: preserve naming symmetry +class polymorphic_oarchive : + public polymorphic_oarchive_impl +{}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_oarchive) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/polymorphic_text_iarchive.hpp b/thirdparty/boost/archive/polymorphic_text_iarchive.hpp new file mode 100644 index 0000000..b363f5e --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_text_iarchive.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +class polymorphic_text_iarchive : + public detail::polymorphic_iarchive_dispatch +{ +public: + polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_dispatch(is, flags) + {} + ~polymorphic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_text_oarchive.hpp b/thirdparty/boost/archive/polymorphic_text_oarchive.hpp new file mode 100644 index 0000000..9ab3c29 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_text_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_dispatch< + text_oarchive_impl +> polymorphic_text_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_text_wiarchive.hpp b/thirdparty/boost/archive/polymorphic_text_wiarchive.hpp new file mode 100644 index 0000000..fb5c221 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_text_wiarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_iarchive_dispatch< + text_wiarchive_impl +> polymorphic_text_wiarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_text_woarchive.hpp b/thirdparty/boost/archive/polymorphic_text_woarchive.hpp new file mode 100644 index 0000000..fed199b --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_text_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_dispatch< + text_woarchive_impl +> polymorphic_text_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_xml_iarchive.hpp b/thirdparty/boost/archive/polymorphic_xml_iarchive.hpp new file mode 100644 index 0000000..c6d9082 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_xml_iarchive.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +class polymorphic_xml_iarchive : + public detail::polymorphic_iarchive_dispatch +{ +public: + polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_dispatch(is, flags) + {} + ~polymorphic_xml_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_xml_oarchive.hpp b/thirdparty/boost/archive/polymorphic_xml_oarchive.hpp new file mode 100644 index 0000000..7f83ae2 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_xml_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_dispatch< + xml_oarchive_impl +> polymorphic_xml_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_xml_wiarchive.hpp b/thirdparty/boost/archive/polymorphic_xml_wiarchive.hpp new file mode 100644 index 0000000..4d8f134 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_xml_wiarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_iarchive_dispatch< + xml_wiarchive_impl +> polymorphic_xml_wiarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + diff --git a/thirdparty/boost/archive/polymorphic_xml_woarchive.hpp b/thirdparty/boost/archive/polymorphic_xml_woarchive.hpp new file mode 100644 index 0000000..a165da0 --- /dev/null +++ b/thirdparty/boost/archive/polymorphic_xml_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_dispatch< + xml_woarchive_impl +> polymorphic_xml_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + diff --git a/thirdparty/boost/archive/shared_ptr_helper.hpp b/thirdparty/boost/archive/shared_ptr_helper.hpp new file mode 100644 index 0000000..b1becd4 --- /dev/null +++ b/thirdparty/boost/archive/shared_ptr_helper.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP +#define BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr.hpp: serialization for boost shared pointer + +// (C) Copyright 2004 Robert Ramey and Martin Ecker +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include + +#include + +namespace boost_132 { + template class shared_ptr; +} +namespace boost { + template class shared_ptr; + namespace serialization { + class extended_type_info; + template + inline void load( + Archive & ar, + boost::shared_ptr &t, + const unsigned int file_version + ); + } + +namespace archive{ +namespace detail { + +struct null_deleter { + void operator()(void const *) const {} +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// a common class for holding various types of shared pointers + +class shared_ptr_helper { + typedef std::map > collection_type; + typedef collection_type::const_iterator iterator_type; + // list of shared_pointers create accessable by raw pointer. This + // is used to "match up" shared pointers loaded at different + // points in the archive. Note, we delay construction until + // it is actually used since this is by default included as + // a "mix-in" even if shared_ptr isn't used. + collection_type * m_pointers; + +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + template + friend inline void boost::serialization::load( + Archive & ar, + boost::shared_ptr &t, + const unsigned int file_version + ); +#endif + + // list of loaded pointers. This is used to be sure that the pointers + // stay around long enough to be "matched" with other pointers loaded + // by the same archive. These are created with a "null_deleter" so that + // when this list is destroyed - the underlaying raw pointers are not + // destroyed. This has to be done because the pointers are also held by + // new system which is disjoint from this set. This is implemented + // by a change in load_construct_data below. It makes this file suitable + // only for loading pointers into a 1.33 or later boost system. + std::list > * m_pointers_132; + + // return a void pointer to the most derived type + template + void * object_identifier(T * t) const { + const boost::serialization::extended_type_info * true_type + = boost::serialization::type_info_implementation::type + ::get_derived_extended_type_info(*t); + // note:if this exception is thrown, be sure that derived pointer + // is either registered or exported. + if(NULL == true_type) + boost::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unregistered_class + ) + ); + const boost::serialization::extended_type_info * this_type + = boost::serialization::type_info_implementation::type::get_instance(); + void * vp = void_downcast(*true_type, *this_type, t); + return vp; + } + template + void reset(shared_ptr & s, T * r){ + if(NULL == r){ + s.reset(); + return; + } + // get pointer to the most derived object. This is effectively + // the object identifer + void * od = object_identifier(r); + + if(NULL == m_pointers) + m_pointers = new collection_type; + + iterator_type it = m_pointers->find(od); + + if(it == m_pointers->end()){ + s.reset(r); + m_pointers->insert(collection_type::value_type(od,s)); + } + else{ + s = static_pointer_cast((*it).second); + } + } + void append(const boost_132::shared_ptr & t){ + if(NULL == m_pointers_132) + m_pointers_132 = new std::list >; + m_pointers_132->push_back(t); + } +public: + shared_ptr_helper() : + m_pointers(NULL), + m_pointers_132(NULL) + {} + ~shared_ptr_helper(){ + if(NULL != m_pointers) + delete m_pointers; + if(NULL != m_pointers_132) + delete m_pointers_132; + } +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#endif // BOOST_ARCHIVE_SHARED_PTR_HELPER_HPP diff --git a/thirdparty/boost/archive/text_iarchive.hpp b/thirdparty/boost/archive/text_iarchive.hpp new file mode 100644 index 0000000..a71173d --- /dev/null +++ b/thirdparty/boost/archive/text_iarchive.hpp @@ -0,0 +1,123 @@ +#ifndef BOOST_ARCHIVE_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class text_iarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class basic_text_iarchive; + friend class load_access; +protected: +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + BOOST_ARCHIVE_DECL(void) + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL(void) + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL(void) + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL(void) + load(std::wstring &ws); + #endif + // note: the following should not needed - but one compiler (vc 7.1) + // fails to compile one test (test_shared_ptr) without it !!! + // make this protected so it can be called from a derived archive + template + void load_override(T & t, BOOST_PFTO int){ + basic_text_iarchive::load_override(t, 0); + } + BOOST_ARCHIVE_DECL(void) + load_override(class_name_type & t, int); + BOOST_ARCHIVE_DECL(void) + init(); + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + text_iarchive_impl(std::istream & is, unsigned int flags); + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + ~text_iarchive_impl(){}; +}; + +// do not derive from the classes below. If you want to extend this functionality +// via inhertance, derived from text_iarchive_impl instead. This will +// preserve correct static polymorphism. + +// same as text_iarchive below - without the shared_ptr_helper +class naked_text_iarchive : + public text_iarchive_impl +{ +public: + naked_text_iarchive(std::istream & is, unsigned int flags = 0) : + text_iarchive_impl(is, flags) + {} + ~naked_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class text_iarchive : + public text_iarchive_impl, + public detail::shared_ptr_helper +{ +public: + text_iarchive(std::istream & is, unsigned int flags = 0) : + text_iarchive_impl(is, flags) + {} + ~text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_iarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_TEXT_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/text_oarchive.hpp b/thirdparty/boost/archive/text_oarchive.hpp new file mode 100644 index 0000000..c54bc5a --- /dev/null +++ b/thirdparty/boost/archive/text_oarchive.hpp @@ -0,0 +1,101 @@ +#ifndef BOOST_ARCHIVE_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // std::size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class text_oarchive_impl : + /* protected ? */ public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; +protected: +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + BOOST_ARCHIVE_DECL(void) + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL(void) + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL(void) + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL(void) + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + text_oarchive_impl(std::ostream & os, unsigned int flags); + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + ~text_oarchive_impl(){}; +public: + BOOST_ARCHIVE_DECL(void) + save_binary(const void *address, std::size_t count); +}; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class text_oarchive : + public text_oarchive_impl +{ +public: + + text_oarchive(std::ostream & os, unsigned int flags = 0) : + text_oarchive_impl(os, flags) + {} + ~text_oarchive(){} +}; + +typedef text_oarchive naked_text_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_TEXT_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/text_wiarchive.hpp b/thirdparty/boost/archive/text_wiarchive.hpp new file mode 100644 index 0000000..a1f1383 --- /dev/null +++ b/thirdparty/boost/archive/text_wiarchive.hpp @@ -0,0 +1,122 @@ +#ifndef BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class text_wiarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class basic_text_iarchive; + friend class load_access; +protected: +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + BOOST_WARCHIVE_DECL(void) + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL(void) + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL(void) + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL(void) + load(std::wstring &ws); + #endif + // note: the following should not needed - but one compiler (vc 7.1) + // fails to compile one test (test_shared_ptr) without it !!! + template + void load_override(T & t, BOOST_PFTO int){ + basic_text_iarchive::load_override(t, 0); + } + BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) + text_wiarchive_impl(std::wistream & is, unsigned int flags); + ~text_wiarchive_impl(){}; +}; + +// do not derive from the classes below. If you want to extend this functionality +// via inhertance, derived from text_iarchive_impl instead. This will +// preserve correct static polymorphism. + +// same as text_wiarchive below - without the shared_ptr_helper +class naked_text_wiarchive : + public text_wiarchive_impl +{ +public: + naked_text_wiarchive(std::wistream & is, unsigned int flags = 0) : + text_wiarchive_impl(is, flags) + {} + ~naked_text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class text_wiarchive : + public text_wiarchive_impl, + public detail::shared_ptr_helper +{ +public: + text_wiarchive(std::wistream & is, unsigned int flags = 0) : + text_wiarchive_impl(is, flags) + {} + ~text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_wiarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP diff --git a/thirdparty/boost/archive/text_woarchive.hpp b/thirdparty/boost/archive/text_woarchive.hpp new file mode 100644 index 0000000..10e9120 --- /dev/null +++ b/thirdparty/boost/archive/text_woarchive.hpp @@ -0,0 +1,128 @@ +#ifndef BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include // size_t + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class text_woarchive_impl : + public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; +protected: +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + BOOST_WARCHIVE_DECL(void) + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL(void) + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL(void) + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL(void) + save(const std::wstring &ws); + #endif + text_woarchive_impl(std::wostream & os, unsigned int flags) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) + { + if(0 == (flags & no_header)) + basic_text_oarchive::init(); + } +public: + void save_binary(const void *address, std::size_t count){ + put(L'\n'); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + put(L'\n'); + this->delimiter = this->none; + } + +}; + +// we use the following because we can't use +// typedef text_oarchive_impl > text_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class text_woarchive : + public text_woarchive_impl +{ +public: + text_woarchive(std::wostream & os, unsigned int flags = 0) : + text_woarchive_impl(os, flags) + {} + ~text_woarchive(){} +}; + +typedef text_woarchive naked_text_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_woarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP diff --git a/thirdparty/boost/archive/tmpdir.hpp b/thirdparty/boost/archive/tmpdir.hpp new file mode 100644 index 0000000..1a18e5d --- /dev/null +++ b/thirdparty/boost/archive/tmpdir.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_ARCHIVE_TMPDIR_HPP +#define BOOST_ARCHIVE_TMPDIR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tmpdir.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // getenv +#include + +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::getenv; +} +#endif + +namespace boost { +namespace archive { + +inline char * tmpdir(){ + char *dirname; + dirname = std::getenv("TMP"); + if(NULL == dirname) + dirname = std::getenv("TMPDIR"); + if(NULL == dirname) + dirname = std::getenv("TEMP"); + if(NULL == dirname){ + //assert(false); // no temp directory found + dirname = "."; + } + return dirname; +} + +} // archive +} // boost + +#endif // BOOST_ARCHIVE_TMPDIR_HPP diff --git a/thirdparty/boost/archive/wcslen.hpp b/thirdparty/boost/archive/wcslen.hpp new file mode 100644 index 0000000..88c4ba2 --- /dev/null +++ b/thirdparty/boost/archive/wcslen.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_ARCHIVE_WCSLEN_HPP +#define BOOST_ARCHIVE_WCSLEN_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wcslen.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR + +// a couple of libraries which include wchar_t don't include +// wcslen + +#if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB < 306 \ +|| defined(__LIBCOMO__) + +namespace std { +inline std::size_t wcslen(const wchar_t * ws) +{ + const wchar_t * eows = ws; + while(* eows != 0) + ++eows; + return eows - ws; +} +} // namespace std + +#else + +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif + +#endif // wcslen + +#endif //BOOST_NO_CWCHAR + +#endif //BOOST_ARCHIVE_WCSLEN_HPP diff --git a/thirdparty/boost/archive/xml_iarchive.hpp b/thirdparty/boost/archive/xml_iarchive.hpp new file mode 100644 index 0000000..a44ee8e --- /dev/null +++ b/thirdparty/boost/archive/xml_iarchive.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_ARCHIVE_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +//#include +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_grammar; + +template +class xml_iarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +protected: +#endif + // instances of micro xml parser to parse start preambles + // scoped_ptr doesn't play nice with borland - so use a naked pointer + // scoped_ptr gimpl; + xml_grammar *gimpl; + + std::istream & get_is(){ + return is; + } + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + BOOST_ARCHIVE_DECL(void) + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL(void) + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL(void) + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL(void) + load(std::wstring &ws); + #endif + template + void load_override(T & t, BOOST_PFTO int){ + basic_xml_iarchive::load_override(t, 0); + } + BOOST_ARCHIVE_DECL(void) + load_override(class_name_type & t, int); + BOOST_ARCHIVE_DECL(void) + init(); + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + xml_iarchive_impl(std::istream & is, unsigned int flags); + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + ~xml_iarchive_impl(); +}; + +// do not derive from the classes below. If you want to extend this functionality +// via inhertance, derived from text_iarchive_impl instead. This will +// preserve correct static polymorphism. + +// same as xml_iarchive below - without the shared_ptr_helper +class naked_xml_iarchive : + public xml_iarchive_impl +{ +public: + naked_xml_iarchive(std::istream & is, unsigned int flags = 0) : + xml_iarchive_impl(is, flags) + {} + ~naked_xml_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class xml_iarchive : + public xml_iarchive_impl, + public detail::shared_ptr_helper +{ +public: + xml_iarchive(std::istream & is, unsigned int flags = 0) : + xml_iarchive_impl(is, flags) + {} + ~xml_iarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_iarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_XML_IARCHIVE_HPP diff --git a/thirdparty/boost/archive/xml_oarchive.hpp b/thirdparty/boost/archive/xml_oarchive.hpp new file mode 100644 index 0000000..fa067d4 --- /dev/null +++ b/thirdparty/boost/archive/xml_oarchive.hpp @@ -0,0 +1,114 @@ +#ifndef BOOST_ARCHIVE_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class xml_oarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +protected: +#endif + //void end_preamble(){ + // basic_xml_oarchive::end_preamble(); + //} + template + void save(const T & t){ + basic_text_oprimitive::save(t); + } + BOOST_ARCHIVE_DECL(void) + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL(void) + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL(void) + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL(void) + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) + xml_oarchive_impl(std::ostream & os, unsigned int flags); + ~xml_oarchive_impl(){} +public: + void save_binary(const void *address, std::size_t count){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; + } +}; + +// we use the following because we can't use +// typedef xml_oarchive_impl > xml_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_oarchive_impl instead. This will +// preserve correct static polymorphism. +class xml_oarchive : + public xml_oarchive_impl +{ +public: + xml_oarchive(std::ostream & os, unsigned int flags = 0) : + xml_oarchive_impl(os, flags) + {} + ~xml_oarchive(){} +}; + +typedef xml_oarchive naked_xml_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_oarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/thirdparty/boost/archive/xml_wiarchive.hpp b/thirdparty/boost/archive/xml_wiarchive.hpp new file mode 100644 index 0000000..65ba613 --- /dev/null +++ b/thirdparty/boost/archive/xml_wiarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +//#include +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_wgrammar; + +template +class xml_wiarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +protected: +#endif + // instances of micro xml parser to parse start preambles + // scoped_ptr doesn't play nice with borland - so use a naked pointer + // scoped_ptr gimpl; + xml_wgrammar *gimpl; + std::wistream & get_is(){ + return is; + } + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + BOOST_WARCHIVE_DECL(void) + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL(void) + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL(void) + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL(void) + load(std::wstring &ws); + #endif + template + void load_override(T & t, BOOST_PFTO int){ + basic_xml_iarchive::load_override(t, 0); + } + BOOST_WARCHIVE_DECL(void) + load_override(class_name_type & t, int); + BOOST_WARCHIVE_DECL(void) + init(); + BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) + xml_wiarchive_impl(std::wistream & is, unsigned int flags) ; + BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) + ~xml_wiarchive_impl(); +}; + +// do not derive from the classes below. If you want to extend this functionality +// via inhertance, derived from text_iarchive_impl instead. This will +// preserve correct static polymorphism. + +// same as xml_wiarchive below - without the shared_ptr_helper +class naked_xml_wiarchive : + public xml_wiarchive_impl +{ +public: + naked_xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + xml_wiarchive_impl(is, flags) + {} + ~naked_xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// note special treatment of shared_ptr. This type needs a special +// structure associated with every archive. We created a "mix-in" +// class to provide this functionality. Since shared_ptr holds a +// special esteem in the boost library - we included it here by default. +#include + +namespace boost { +namespace archive { + +class xml_wiarchive : + public xml_wiarchive_impl, + public detail::shared_ptr_helper +{ +public: + xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + xml_wiarchive_impl(is, flags) + {} + ~xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_wiarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_WIARCHIVE_HPP diff --git a/thirdparty/boost/archive/xml_woarchive.hpp b/thirdparty/boost/archive/xml_woarchive.hpp new file mode 100644 index 0000000..2737d28 --- /dev/null +++ b/thirdparty/boost/archive/xml_woarchive.hpp @@ -0,0 +1,127 @@ +#ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +BOOST_WARCHIVE_DECL(std::wostream &) +operator<<(std::wostream &os, const char *t); + +BOOST_WARCHIVE_DECL(std::wostream &) +operator<<(std::wostream &os, const char t); + +template +class xml_woarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +protected: +#endif + //void end_preamble(){ + // basic_xml_oarchive::end_preamble(); + //} + template + void + save(const T & t){ + basic_text_oprimitive::save(t); + } + BOOST_WARCHIVE_DECL(void) + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL(void) + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL(void) + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL(void) + save(const std::wstring &ws); + #endif + BOOST_WARCHIVE_DECL(BOOST_PP_EMPTY()) + xml_woarchive_impl(std::wostream & os, unsigned int flags); + ~xml_woarchive_impl(){} +public: + void + save_binary(const void *address, std::size_t count){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; + } +}; + +// we use the following because we can't use +// typedef xml_woarchive_impl > xml_woarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_woarchive_impl instead. This will +// preserve correct static polymorphism. +class xml_woarchive : + public xml_woarchive_impl +{ +public: + xml_woarchive(std::wostream & os, unsigned int flags = 0) : + xml_woarchive_impl(os, flags) + {} + ~xml_woarchive(){} +}; + +typedef xml_woarchive naked_xml_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/thirdparty/boost/array.hpp b/thirdparty/boost/array.hpp new file mode 100644 index 0000000..3239776 --- /dev/null +++ b/thirdparty/boost/array.hpp @@ -0,0 +1,321 @@ +/* The following code declares class array, + * an STL container (as wrapper) for arrays of constant size. + * + * See + * http://www.boost.org/libs/array/ + * for documentation. + * + * The original author site is at: http://www.josuttis.com/ + * + * (C) Copyright Nicolai M. Josuttis 2001. + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) + * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. + * 05 Aug 2001 - minor update (Nico Josuttis) + * 20 Jan 2001 - STLport fix (Beman Dawes) + * 29 Sep 2000 - Initial Revision (Nico Josuttis) + * + * Jan 29, 2004 + */ +#ifndef BOOST_ARRAY_HPP +#define BOOST_ARRAY_HPP + +#include +#include +#include + +// Handles broken standard libraries better than +#include +#include +#include + +// FIXES for broken compilers +#include + + +namespace boost { + + template + class array { + public: + T elems[N]; // fixed-size array of elements of type T + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return elems; } + const_iterator begin() const { return elems; } + iterator end() { return elems+N; } + const_iterator end() const { return elems+N; } + + // reverse iterator support +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) + // workaround for broken reverse_iterator in VC7 + typedef std::reverse_iterator > reverse_iterator; + typedef std::reverse_iterator > const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type i) + { + BOOST_ASSERT( i < N && "out of range" ); + return elems[i]; + } + + const_reference operator[](size_type i) const + { + BOOST_ASSERT( i < N && "out of range" ); + return elems[i]; + } + + // at() with range check + reference at(size_type i) { rangecheck(i); return elems[i]; } + const_reference at(size_type i) const { rangecheck(i); return elems[i]; } + + // front() and back() + reference front() + { + return elems[0]; + } + + const_reference front() const + { + return elems[0]; + } + + reference back() + { + return elems[N-1]; + } + + const_reference back() const + { + return elems[N-1]; + } + + // size is constant + static size_type size() { return N; } + static bool empty() { return false; } + static size_type max_size() { return N; } + enum { static_size = N }; + + // swap (note: linear complexity) + void swap (array& y) { + std::swap_ranges(begin(),end(),y.begin()); + } + + // direct access to data (read-only) + const T* data() const { return elems; } + T* data() { return elems; } + + // use array as C array (direct read/write access to data) + T* c_array() { return elems; } + + // assignment with type conversion + template + array& operator= (const array& rhs) { + std::copy(rhs.begin(),rhs.end(), begin()); + return *this; + } + + // assign one value to all elements + void assign (const T& value) + { + std::fill_n(begin(),size(),value); + } + + // check range (may be private because it is static) + static void rangecheck (size_type i) { + if (i >= size()) { + throw std::out_of_range("array<>: index out of range"); + } + } + + }; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template< class T > + class array< T, 0 > { + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } + const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + iterator end() { return begin(); } + const_iterator end() const { return begin(); } + + // reverse iterator support +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) + // workaround for broken reverse_iterator in VC7 + typedef std::reverse_iterator > reverse_iterator; + typedef std::reverse_iterator > const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type i) + { + return failed_rangecheck(); + } + + const_reference operator[](size_type i) const + { + return failed_rangecheck(); + } + + // at() with range check + reference at(size_type i) { return failed_rangecheck(); } + const_reference at(size_type i) const { return failed_rangecheck(); } + + // front() and back() + reference front() + { + return failed_rangecheck(); + } + + const_reference front() const + { + return failed_rangecheck(); + } + + reference back() + { + return failed_rangecheck(); + } + + const_reference back() const + { + return failed_rangecheck(); + } + + // size is constant + static size_type size() { return 0; } + static bool empty() { return true; } + static size_type max_size() { return 0; } + enum { static_size = 0 }; + + void swap (array& y) { + } + + // direct access to data (read-only) + const T* data() const { return 0; } + T* data() { return 0; } + + // use array as C array (direct read/write access to data) + T* c_array() { return 0; } + + // assignment with type conversion + template + array& operator= (const array& ) { + return *this; + } + + // assign one value to all elements + void assign (const T& ) { } + + // check range (may be private because it is static) + static reference failed_rangecheck () { + std::out_of_range e("attempt to access element of an empty array"); + boost::throw_exception(e); + // + // We need to return something here to keep + // some compilers happy: however we will never + // actually get here.... + // + static T placeholder; + return placeholder; + } + }; +#endif + + // comparisons + template + bool operator== (const array& x, const array& y) { + return std::equal(x.begin(), x.end(), y.begin()); + } + template + bool operator< (const array& x, const array& y) { + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); + } + template + bool operator!= (const array& x, const array& y) { + return !(x==y); + } + template + bool operator> (const array& x, const array& y) { + return y + bool operator<= (const array& x, const array& y) { + return !(y + bool operator>= (const array& x, const array& y) { + return !(x + inline void swap (array& x, array& y) { + x.swap(y); + } + +} /* namespace boost */ + +#endif /*BOOST_ARRAY_HPP*/ diff --git a/thirdparty/boost/asio.hpp b/thirdparty/boost/asio.hpp new file mode 100644 index 0000000..4f4234c --- /dev/null +++ b/thirdparty/boost/asio.hpp @@ -0,0 +1,73 @@ +// +// asio.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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 www.boost.org/libs/asio for documentation. +// + +#ifndef BOOST_ASIO_HPP +#define BOOST_ASIO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#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 // BOOST_ASIO_HPP diff --git a/thirdparty/boost/asio/basic_datagram_socket.hpp b/thirdparty/boost/asio/basic_datagram_socket.hpp new file mode 100644 index 0000000..f65765e --- /dev/null +++ b/thirdparty/boost/asio/basic_datagram_socket.hpp @@ -0,0 +1,805 @@ +// +// basic_datagram_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP +#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides datagram-oriented socket functionality. +/** + * The basic_datagram_socket class template provides asynchronous and blocking + * datagram-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_datagram_socket + : public basic_socket +{ +public: + /// The native representation of a socket. + typedef typename DatagramSocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_datagram_socket without opening it. + /** + * This constructor creates a datagram socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + */ + explicit basic_datagram_socket(boost::asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_datagram_socket. + /** + * This constructor creates and opens a datagram socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_datagram_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a datagram socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param endpoint An endpoint on the local machine to which the datagram + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket(boost::asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_datagram_socket on an existing native socket. + /** + * This constructor creates a datagram socket object to hold an existing + * native socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code socket.send(boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->service.send(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + */ + template + void async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, flags, handler); + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::ip::udp::endpoint destination( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(boost::asio::buffer(data, size), destination); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination) + { + boost::system::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + return this->service.send_to(this->implementation, + buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::ip::udp::endpoint destination( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * boost::asio::buffer(data, size), destination, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, 0, + handler); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, + flags, handler); + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.receive(boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->service.receive(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + */ + template + void async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, flags, handler); + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * boost::asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * boost::asio::buffer(data, size), sender_endpoint); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint) + { + boost::system::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + return this->service.receive_from(this->implementation, buffers, + sender_endpoint, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.async_receive_from( + * boost::asio::buffer(data, size), 0, sender_endpoint, handler); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, 0, handler); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, flags, handler); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/thirdparty/boost/asio/basic_deadline_timer.hpp b/thirdparty/boost/asio/basic_deadline_timer.hpp new file mode 100644 index 0000000..3282f66 --- /dev/null +++ b/thirdparty/boost/asio/basic_deadline_timer.hpp @@ -0,0 +1,383 @@ +// +// basic_deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP +#define BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides waitable timer functionality. +/** + * The basic_deadline_timer class template provides the ability to perform a + * blocking or asynchronous wait for a timer to expire. + * + * Most applications will use the boost::asio::deadline_timer typedef. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Examples + * Performing a blocking wait: + * @code + * // Construct a timer without setting an expiry time. + * boost::asio::deadline_timer timer(io_service); + * + * // Set an expiry time relative to now. + * timer.expires_from_now(boost::posix_time::seconds(5)); + * + * // Wait for the timer to expire. + * timer.wait(); + * @endcode + * + * @par + * Performing an asynchronous wait: + * @code + * void handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Timer expired. + * } + * } + * + * ... + * + * // Construct a timer with an absolute expiry time. + * boost::asio::deadline_timer timer(io_service, + * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); + * + * // Start an asynchronous wait. + * timer.async_wait(handler); + * @endcode + * + * @par Changing an active deadline_timer's expiry time + * + * Changing the expiry time of a timer while there are pending asynchronous + * waits causes those wait operations to be cancelled. To ensure that the action + * associated with the timer is performed only once, use something like this: + * used: + * + * @code + * void on_some_event() + * { + * if (my_timer.expires_from_now(seconds(5)) > 0) + * { + * // We managed to cancel the timer. Start new asynchronous wait. + * my_timer.async_wait(on_timeout); + * } + * else + * { + * // Too late, timer has already expired! + * } + * } + * + * void on_timeout(const boost::system::error_code& e) + * { + * if (e != boost::asio::error::operation_aborted) + * { + * // Timer was not cancelled, take necessary action. + * } + * } + * @endcode + * + * @li The boost::asio::basic_deadline_timer::expires_from_now() function + * cancels any pending asynchronous waits, and returns the number of + * asynchronous waits that were cancelled. If it returns 0 then you were too + * late and the wait handler has already been executed, or will soon be + * executed. If it returns 1 then the wait handler was successfully cancelled. + * + * @li If a wait handler is cancelled, the boost::system::error_code passed to + * it contains the value boost::asio::error::operation_aborted. + */ +template , + typename TimerService = deadline_timer_service > +class basic_deadline_timer + : public basic_io_object +{ +public: + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_from_now() functions must be called to set an + * expiry time before the timer can be waited on. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + */ + explicit basic_deadline_timer(boost::asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + basic_deadline_timer(boost::asio::io_service& io_service, + const time_type& expiry_time) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.expires_at(this->implementation, expiry_time, ec); + boost::asio::detail::throw_error(ec); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + basic_deadline_timer(boost::asio::io_service& io_service, + const duration_type& expiry_time) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.expires_from_now(this->implementation, expiry_time, ec); + boost::asio::detail::throw_error(ec); + } + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t cancel() + { + boost::system::error_code ec; + std::size_t s = this->service.cancel(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + */ + std::size_t cancel(boost::system::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Get the timer's expiry time as an absolute time. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + time_type expires_at() const + { + return this->service.expires_at(this->implementation); + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t expires_at(const time_type& expiry_time) + { + boost::system::error_code ec; + std::size_t s = this->service.expires_at( + this->implementation, expiry_time, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + */ + std::size_t expires_at(const time_type& expiry_time, + boost::system::error_code& ec) + { + return this->service.expires_at(this->implementation, expiry_time, ec); + } + + /// Get the timer's expiry time relative to now. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + duration_type expires_from_now() const + { + return this->service.expires_from_now(this->implementation); + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t expires_from_now(const duration_type& expiry_time) + { + boost::system::error_code ec; + std::size_t s = this->service.expires_from_now( + this->implementation, expiry_time, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the boost::asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + */ + std::size_t expires_from_now(const duration_type& expiry_time, + boost::system::error_code& ec) + { + return this->service.expires_from_now( + this->implementation, expiry_time, ec); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @throws boost::system::system_error Thrown on failure. + */ + void wait() + { + boost::system::error_code ec; + this->service.wait(this->implementation, ec); + boost::asio::detail::throw_error(ec); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(boost::system::error_code& ec) + { + this->service.wait(this->implementation, ec); + } + + /// Start an asynchronous wait on the timer. + /** + * This function may be used to initiate an asynchronous wait against the + * timer. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li The timer has expired. + * + * @li The timer was cancelled, in which case the handler is passed the error + * code boost::asio::error::operation_aborted. + * + * @param handler The handler to be called when the timer expires. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + void async_wait(WaitHandler handler) + { + this->service.async_wait(this->implementation, handler); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP diff --git a/thirdparty/boost/asio/basic_io_object.hpp b/thirdparty/boost/asio/basic_io_object.hpp new file mode 100644 index 0000000..a9c2a93 --- /dev/null +++ b/thirdparty/boost/asio/basic_io_object.hpp @@ -0,0 +1,91 @@ +// +// basic_io_object.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_IO_OBJECT_HPP +#define BOOST_ASIO_BASIC_IO_OBJECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { + +/// Base class for all I/O objects. +template +class basic_io_object + : private noncopyable +{ +public: + /// The type of the service that will be used to provide I/O operations. + typedef IoObjectService service_type; + + /// The underlying implementation type of I/O object. + typedef typename service_type::implementation_type implementation_type; + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + /** + * This function may be used to obtain the io_service object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& io_service() + { + return service.get_io_service(); + } + + /// Get the io_service associated with the object. + /** + * This function may be used to obtain the io_service object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& get_io_service() + { + return service.get_io_service(); + } + +protected: + /// Construct a basic_io_object. + explicit basic_io_object(boost::asio::io_service& io_service) + : service(boost::asio::use_service(io_service)) + { + service.construct(implementation); + } + + /// Protected destructor to prevent deletion through this type. + ~basic_io_object() + { + service.destroy(implementation); + } + + // The backend service implementation. + service_type& service; + + // The underlying native implementation. + implementation_type implementation; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_IO_OBJECT_HPP diff --git a/thirdparty/boost/asio/basic_socket.hpp b/thirdparty/boost/asio/basic_socket.hpp new file mode 100644 index 0000000..73da51e --- /dev/null +++ b/thirdparty/boost/asio/basic_socket.hpp @@ -0,0 +1,1051 @@ +// +// basic_socket.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_SOCKET_HPP +#define BOOST_ASIO_BASIC_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides socket functionality. +/** + * The basic_socket class template provides functionality that is common to both + * stream-oriented and datagram-oriented sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_socket + : public basic_io_object, + public socket_base +{ +public: + /// The native representation of a socket. + typedef typename SocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// A basic_socket is always the lowest layer. + typedef basic_socket lowest_layer_type; + + /// Construct a basic_socket without opening it. + /** + * This constructor creates a socket without opening it. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + */ + explicit basic_socket(boost::asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct and open a basic_socket. + /** + * This constructor creates and opens a socket. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); + } + + /// Construct a basic_socket, opening it and binding it to the given local + /// endpoint. + /** + * This constructor creates a socket and automatically opens it bound to the + * specified endpoint on the local machine. The protocol used is the protocol + * associated with the given endpoint. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket(boost::asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + boost::asio::detail::throw_error(ec); + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); + } + + /// Construct a basic_socket on an existing native socket. + /** + * This constructor creates a socket object to hold an existing native socket. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket A native socket. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + boost::asio::detail::throw_error(ec); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_socket cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Open the socket using the specified protocol. + /** + * This function opens the socket so that it will use the specified protocol. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * socket.open(boost::asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); + } + + /// Open the socket using the specified protocol. + /** + * This function opens the socket so that it will use the specified protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * boost::system::error_code ec; + * socket.open(boost::asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code open(const protocol_type& protocol, + boost::system::error_code& ec) + { + return this->service.open(this->implementation, protocol, ec); + } + + /// Assign an existing native socket to the socket. + /* + * This function opens the socket to hold an existing native socket. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_socket A native socket. + * + * @throws boost::system::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, const native_type& native_socket) + { + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + boost::asio::detail::throw_error(ec); + } + + /// Assign an existing native socket to the socket. + /* + * This function opens the socket to hold an existing native socket. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_socket A native socket. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code assign(const protocol_type& protocol, + const native_type& native_socket, boost::system::error_code& ec) + { + return this->service.assign(this->implementation, + protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Close the socket. + /** + * This function is used to close the socket. Any asynchronous send, receive + * or connect operations will be cancelled immediately, and will complete + * with the boost::asio::error::operation_aborted error. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note For portable behaviour with respect to graceful closure of a + * connected socket, call shutdown() before closing the socket. + */ + void close() + { + boost::system::error_code ec; + this->service.close(this->implementation, ec); + boost::asio::detail::throw_error(ec); + } + + /// Close the socket. + /** + * This function is used to close the socket. Any asynchronous send, receive + * or connect operations will be cancelled immediately, and will complete + * with the boost::asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::system::error_code ec; + * socket.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + * + * @note For portable behaviour with respect to graceful closure of a + * connected socket, call shutdown() before closing the socket. + */ + boost::system::error_code close(boost::system::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native socket representation. + /** + * This function may be used to obtain the underlying representation of the + * socket. This is intended to allow access to native socket functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note Calls to cancel() will always fail with + * boost::asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has + * two issues that should be considered before enabling its use: + * + * @li It will only cancel asynchronous operations that were initiated in the + * current thread. + * + * @li It can appear to complete without error, but the request to cancel the + * unfinished operations may be silently ignored by the operating system. + * Whether it works or not seems to depend on the drivers that are installed. + * + * For portable cancellation, consider using one of the following + * alternatives: + * + * @li Disable asio's I/O completion port backend by defining + * BOOST_ASIO_DISABLE_IOCP. + * + * @li Use the close() function to simultaneously cancel the outstanding + * operations and close the socket. + * + * When running on Windows Vista, Windows Server 2008, and later, the + * CancelIoEx function is always used. This function does not have the + * problems described above. + */ +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(BOOST_ASIO_ENABLE_CANCELIO) + __declspec(deprecated("By default, this function always fails with " + "operation_not_supported when used on Windows XP, Windows Server 2003, " + "or earlier. Consult documentation for details.")) +#endif + void cancel() + { + boost::system::error_code ec; + this->service.cancel(this->implementation, ec); + boost::asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls to cancel() will always fail with + * boost::asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has + * two issues that should be considered before enabling its use: + * + * @li It will only cancel asynchronous operations that were initiated in the + * current thread. + * + * @li It can appear to complete without error, but the request to cancel the + * unfinished operations may be silently ignored by the operating system. + * Whether it works or not seems to depend on the drivers that are installed. + * + * For portable cancellation, consider using one of the following + * alternatives: + * + * @li Disable asio's I/O completion port backend by defining + * BOOST_ASIO_DISABLE_IOCP. + * + * @li Use the close() function to simultaneously cancel the outstanding + * operations and close the socket. + * + * When running on Windows Vista, Windows Server 2008, and later, the + * CancelIoEx function is always used. This function does not have the + * problems described above. + */ +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(BOOST_ASIO_ENABLE_CANCELIO) + __declspec(deprecated("By default, this function always fails with " + "operation_not_supported when used on Windows XP, Windows Server 2003, " + "or earlier. Consult documentation for details.")) +#endif + boost::system::error_code cancel(boost::system::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + /** + * This function is used to check whether the socket input is currently + * positioned at the out-of-band data mark. + * + * @return A bool indicating whether the socket is at the out-of-band data + * mark. + * + * @throws boost::system::system_error Thrown on failure. + */ + bool at_mark() const + { + boost::system::error_code ec; + bool b = this->service.at_mark(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return b; + } + + /// Determine whether the socket is at the out-of-band data mark. + /** + * This function is used to check whether the socket input is currently + * positioned at the out-of-band data mark. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return A bool indicating whether the socket is at the out-of-band data + * mark. + */ + bool at_mark(boost::system::error_code& ec) const + { + return this->service.at_mark(this->implementation, ec); + } + + /// Determine the number of bytes available for reading. + /** + * This function is used to determine the number of bytes that may be read + * without blocking. + * + * @return The number of bytes that may be read without blocking, or 0 if an + * error occurs. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t available() const + { + boost::system::error_code ec; + std::size_t s = this->service.available(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Determine the number of bytes available for reading. + /** + * This function is used to determine the number of bytes that may be read + * without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of bytes that may be read without blocking, or 0 if an + * error occurs. + */ + std::size_t available(boost::system::error_code& ec) const + { + return this->service.available(this->implementation, ec); + } + + /// Bind the socket to the given local endpoint. + /** + * This function binds the socket to the specified endpoint on the local + * machine. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * socket.open(boost::asio::ip::tcp::v4()); + * socket.bind(boost::asio::ip::tcp::endpoint( + * boost::asio::ip::tcp::v4(), 12345)); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + boost::system::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); + } + + /// Bind the socket to the given local endpoint. + /** + * This function binds the socket to the specified endpoint on the local + * machine. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * socket.open(boost::asio::ip::tcp::v4()); + * boost::system::error_code ec; + * socket.bind(boost::asio::ip::tcp::endpoint( + * boost::asio::ip::tcp::v4(), 12345), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code bind(const endpoint_type& endpoint, + boost::system::error_code& ec) + { + return this->service.bind(this->implementation, endpoint, ec); + } + + /// Connect the socket to the specified endpoint. + /** + * This function is used to connect a socket to the specified remote endpoint. + * The function call will block until the connection is successfully made or + * an error occurs. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.connect(endpoint); + * @endcode + */ + void connect(const endpoint_type& peer_endpoint) + { + boost::system::error_code ec; + if (!is_open()) + { + this->service.open(this->implementation, peer_endpoint.protocol(), ec); + boost::asio::detail::throw_error(ec); + } + this->service.connect(this->implementation, peer_endpoint, ec); + boost::asio::detail::throw_error(ec); + } + + /// Connect the socket to the specified endpoint. + /** + * This function is used to connect a socket to the specified remote endpoint. + * The function call will block until the connection is successfully made or + * an error occurs. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * boost::system::error_code ec; + * socket.connect(endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code connect(const endpoint_type& peer_endpoint, + boost::system::error_code& ec) + { + if (!is_open()) + { + if (this->service.open(this->implementation, + peer_endpoint.protocol(), ec)) + { + return ec; + } + } + + return this->service.connect(this->implementation, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + /** + * This function is used to asynchronously connect a socket to the specified + * remote endpoint. The function call always returns immediately. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. Copies will be made of the endpoint object as required. + * + * @param handler The handler to be called when the connection operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * @code + * void connect_handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Connect succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_connect(endpoint, connect_handler); + * @endcode + */ + template + void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler) + { + if (!is_open()) + { + boost::system::error_code ec; + if (this->service.open(this->implementation, + peer_endpoint.protocol(), ec)) + { + this->get_io_service().post( + boost::asio::detail::bind_handler(handler, ec)); + return; + } + } + + this->service.async_connect(this->implementation, peer_endpoint, handler); + } + + /// Set an option on the socket. + /** + * This function is used to set an option on the socket. + * + * @param option The new option value to be set on the socket. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::broadcast @n + * boost::asio::socket_base::do_not_route @n + * boost::asio::socket_base::keep_alive @n + * boost::asio::socket_base::linger @n + * boost::asio::socket_base::receive_buffer_size @n + * boost::asio::socket_base::receive_low_watermark @n + * boost::asio::socket_base::reuse_address @n + * boost::asio::socket_base::send_buffer_size @n + * boost::asio::socket_base::send_low_watermark @n + * boost::asio::ip::multicast::join_group @n + * boost::asio::ip::multicast::leave_group @n + * boost::asio::ip::multicast::enable_loopback @n + * boost::asio::ip::multicast::outbound_interface @n + * boost::asio::ip::multicast::hops @n + * boost::asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + boost::system::error_code ec; + this->service.set_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); + } + + /// Set an option on the socket. + /** + * This function is used to set an option on the socket. + * + * @param option The new option value to be set on the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::broadcast @n + * boost::asio::socket_base::do_not_route @n + * boost::asio::socket_base::keep_alive @n + * boost::asio::socket_base::linger @n + * boost::asio::socket_base::receive_buffer_size @n + * boost::asio::socket_base::receive_low_watermark @n + * boost::asio::socket_base::reuse_address @n + * boost::asio::socket_base::send_buffer_size @n + * boost::asio::socket_base::send_low_watermark @n + * boost::asio::ip::multicast::join_group @n + * boost::asio::ip::multicast::leave_group @n + * boost::asio::ip::multicast::enable_loopback @n + * boost::asio::ip::multicast::outbound_interface @n + * boost::asio::ip::multicast::hops @n + * boost::asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::no_delay option(true); + * boost::system::error_code ec; + * socket.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code set_option(const SettableSocketOption& option, + boost::system::error_code& ec) + { + return this->service.set_option(this->implementation, option, ec); + } + + /// Get an option from the socket. + /** + * This function is used to get the current value of an option on the socket. + * + * @param option The option value to be obtained from the socket. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::broadcast @n + * boost::asio::socket_base::do_not_route @n + * boost::asio::socket_base::keep_alive @n + * boost::asio::socket_base::linger @n + * boost::asio::socket_base::receive_buffer_size @n + * boost::asio::socket_base::receive_low_watermark @n + * boost::asio::socket_base::reuse_address @n + * boost::asio::socket_base::send_buffer_size @n + * boost::asio::socket_base::send_low_watermark @n + * boost::asio::ip::multicast::join_group @n + * boost::asio::ip::multicast::leave_group @n + * boost::asio::ip::multicast::enable_loopback @n + * boost::asio::ip::multicast::outbound_interface @n + * boost::asio::ip::multicast::hops @n + * boost::asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::socket::keep_alive option; + * socket.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) const + { + boost::system::error_code ec; + this->service.get_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); + } + + /// Get an option from the socket. + /** + * This function is used to get the current value of an option on the socket. + * + * @param option The option value to be obtained from the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::broadcast @n + * boost::asio::socket_base::do_not_route @n + * boost::asio::socket_base::keep_alive @n + * boost::asio::socket_base::linger @n + * boost::asio::socket_base::receive_buffer_size @n + * boost::asio::socket_base::receive_low_watermark @n + * boost::asio::socket_base::reuse_address @n + * boost::asio::socket_base::send_buffer_size @n + * boost::asio::socket_base::send_low_watermark @n + * boost::asio::ip::multicast::join_group @n + * boost::asio::ip::multicast::leave_group @n + * boost::asio::ip::multicast::enable_loopback @n + * boost::asio::ip::multicast::outbound_interface @n + * boost::asio::ip::multicast::hops @n + * boost::asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::socket::keep_alive option; + * boost::system::error_code ec; + * socket.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + boost::system::error_code get_option(GettableSocketOption& option, + boost::system::error_code& ec) const + { + return this->service.get_option(this->implementation, option, ec); + } + + /// Perform an IO control command on the socket. + /** + * This function is used to execute an IO control command on the socket. + * + * @param command The IO control command to be performed on the socket. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * boost::asio::socket_base::bytes_readable @n + * boost::asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::socket::bytes_readable command; + * socket.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + boost::system::error_code ec; + this->service.io_control(this->implementation, command, ec); + boost::asio::detail::throw_error(ec); + } + + /// Perform an IO control command on the socket. + /** + * This function is used to execute an IO control command on the socket. + * + * @param command The IO control command to be performed on the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * boost::asio::socket_base::bytes_readable @n + * boost::asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::socket::bytes_readable command; + * boost::system::error_code ec; + * socket.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + boost::system::error_code io_control(IoControlCommand& command, + boost::system::error_code& ec) + { + return this->service.io_control(this->implementation, command, ec); + } + + /// Get the local endpoint of the socket. + /** + * This function is used to obtain the locally bound endpoint of the socket. + * + * @returns An object that represents the local endpoint of the socket. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + boost::system::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; + } + + /// Get the local endpoint of the socket. + /** + * This function is used to obtain the locally bound endpoint of the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the local endpoint of the socket. + * Returns a default-constructed endpoint object if an error occurred. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(boost::system::error_code& ec) const + { + return this->service.local_endpoint(this->implementation, ec); + } + + /// Get the remote endpoint of the socket. + /** + * This function is used to obtain the remote endpoint of the socket. + * + * @returns An object that represents the remote endpoint of the socket. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); + * @endcode + */ + endpoint_type remote_endpoint() const + { + boost::system::error_code ec; + endpoint_type ep = this->service.remote_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; + } + + /// Get the remote endpoint of the socket. + /** + * This function is used to obtain the remote endpoint of the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the remote endpoint of the socket. + * Returns a default-constructed endpoint object if an error occurred. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type remote_endpoint(boost::system::error_code& ec) const + { + return this->service.remote_endpoint(this->implementation, ec); + } + + /// Disable sends or receives on the socket. + /** + * This function is used to disable send operations, receive operations, or + * both. + * + * @param what Determines what types of operation will no longer be allowed. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * Shutting down the send side of the socket: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); + * @endcode + */ + void shutdown(shutdown_type what) + { + boost::system::error_code ec; + this->service.shutdown(this->implementation, what, ec); + boost::asio::detail::throw_error(ec); + } + + /// Disable sends or receives on the socket. + /** + * This function is used to disable send operations, receive operations, or + * both. + * + * @param what Determines what types of operation will no longer be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Shutting down the send side of the socket: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::system::error_code ec; + * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code shutdown(shutdown_type what, + boost::system::error_code& ec) + { + return this->service.shutdown(this->implementation, what, ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_socket() + { + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_SOCKET_HPP diff --git a/thirdparty/boost/asio/basic_socket_acceptor.hpp b/thirdparty/boost/asio/basic_socket_acceptor.hpp new file mode 100644 index 0000000..307b27d --- /dev/null +++ b/thirdparty/boost/asio/basic_socket_acceptor.hpp @@ -0,0 +1,826 @@ +// +// basic_socket_acceptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP +#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides the ability to accept new connections. +/** + * The basic_socket_acceptor class template is used for accepting new socket + * connections. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * Opening a socket acceptor with the SO_REUSEADDR option enabled: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); + * acceptor.open(endpoint.protocol()); + * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(); + * @endcode + */ +template > +class basic_socket_acceptor + : public basic_io_object, + public socket_base +{ +public: + /// The native representation of an acceptor. + typedef typename SocketAcceptorService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct an acceptor without opening it. + /** + * This constructor creates an acceptor without opening it to listen for new + * connections. The open() function must be called before the acceptor can + * accept new socket connections. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + */ + explicit basic_socket_acceptor(boost::asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct an open acceptor. + /** + * This constructor creates an acceptor and automatically opens it. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket_acceptor(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); + } + + /// Construct an acceptor opened on the given endpoint. + /** + * This constructor creates an acceptor and automatically opens it to listen + * for new connections on the specified endpoint. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param endpoint An endpoint on the local machine on which the acceptor + * will listen for new connections. + * + * @param reuse_addr Whether the constructor should set the socket option + * socket_base::reuse_address. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor acceptor(io_service); + * acceptor.open(endpoint.protocol()); + * if (reuse_addr) + * acceptor.set_option(socket_base::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(listen_backlog); + * @endcode + */ + basic_socket_acceptor(boost::asio::io_service& io_service, + const endpoint_type& endpoint, bool reuse_addr = true) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + boost::asio::detail::throw_error(ec); + if (reuse_addr) + { + this->service.set_option(this->implementation, + socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec); + } + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); + this->service.listen(this->implementation, + socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec); + } + + /// Construct a basic_socket_acceptor on an existing native acceptor. + /** + * This constructor creates an acceptor object to hold an existing native + * acceptor. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket_acceptor(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_acceptor) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec); + } + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(boost::asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); + } + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::system::error_code ec; + * acceptor.open(boost::asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code open(const protocol_type& protocol, + boost::system::error_code& ec) + { + return this->service.open(this->implementation, protocol, ec); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws boost::system::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, const native_type& native_acceptor) + { + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code assign(const protocol_type& protocol, + const native_type& native_acceptor, boost::system::error_code& ec) + { + return this->service.assign(this->implementation, + protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(boost::asio::ip::tcp::v4()); + * acceptor.bind(boost::asio::ip::tcp::endpoint(12345)); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + boost::system::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(boost::asio::ip::tcp::v4()); + * boost::system::error_code ec; + * acceptor.bind(boost::asio::ip::tcp::endpoint(12345), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code bind(const endpoint_type& endpoint, + boost::system::error_code& ec) + { + return this->service.bind(this->implementation, endpoint, ec); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @throws boost::system::system_error Thrown on failure. + */ + void listen(int backlog = socket_base::max_connections) + { + boost::system::error_code ec; + this->service.listen(this->implementation, backlog, ec); + boost::asio::detail::throw_error(ec); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * acceptor.listen(boost::asio::socket_base::max_connections, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code listen(int backlog, boost::system::error_code& ec) + { + return this->service.listen(this->implementation, backlog, ec); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @throws boost::system::system_error Thrown on failure. + */ + void close() + { + boost::system::error_code ec; + this->service.close(this->implementation, ec); + boost::asio::detail::throw_error(ec); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * acceptor.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code close(boost::system::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native acceptor representation. + /** + * This function may be used to obtain the underlying representation of the + * acceptor. This is intended to allow access to native acceptor functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @throws boost::system::system_error Thrown on failure. + */ + void cancel() + { + boost::system::error_code ec; + this->service.cancel(this->implementation, ec); + boost::asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code cancel(boost::system::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::reuse_address + * boost::asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + boost::system::error_code ec; + this->service.set_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::reuse_address + * boost::asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option(true); + * boost::system::error_code ec; + * acceptor.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code set_option(const SettableSocketOption& option, + boost::system::error_code& ec) + { + return this->service.set_option(this->implementation, option, ec); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) + { + boost::system::error_code ec; + this->service.get_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option; + * boost::system::error_code ec; + * acceptor.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + boost::system::error_code get_option(GettableSocketOption& option, + boost::system::error_code& ec) + { + return this->service.get_option(this->implementation, option, ec); + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @returns An object that represents the local endpoint of the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + boost::system::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the local endpoint of the acceptor. + * Returns a default-constructed endpoint object if an error occurred and the + * error handler did not throw an exception. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(boost::system::error_code& ec) const + { + return this->service.local_endpoint(this->implementation, ec); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * acceptor.accept(socket); + * @endcode + */ + template + void accept(basic_socket& peer) + { + boost::system::error_code ec; + this->service.accept(this->implementation, peer, 0, ec); + boost::asio::detail::throw_error(ec); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::soocket socket(io_service); + * boost::system::error_code ec; + * acceptor.accept(socket, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code accept( + basic_socket& peer, + boost::system::error_code& ec) + { + return this->service.accept(this->implementation, peer, 0, ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket. The function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * acceptor.async_accept(socket, accept_handler); + * @endcode + */ + template + void async_accept(basic_socket& peer, + AcceptHandler handler) + { + this->service.async_accept(this->implementation, peer, 0, handler); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint; + * acceptor.accept(socket, endpoint); + * @endcode + */ + template + void accept(basic_socket& peer, + endpoint_type& peer_endpoint) + { + boost::system::error_code ec; + this->service.accept(this->implementation, peer, &peer_endpoint, ec); + boost::asio::detail::throw_error(ec); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint; + * boost::system::error_code ec; + * acceptor.accept(socket, endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code accept( + basic_socket& peer, + endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return this->service.accept(this->implementation, peer, &peer_endpoint, ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket, and additionally obtain the endpoint of the remote peer. The + * function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + void async_accept(basic_socket& peer, + endpoint_type& peer_endpoint, AcceptHandler handler) + { + this->service.async_accept(this->implementation, + peer, &peer_endpoint, handler); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP diff --git a/thirdparty/boost/asio/basic_socket_iostream.hpp b/thirdparty/boost/asio/basic_socket_iostream.hpp new file mode 100644 index 0000000..b262632 --- /dev/null +++ b/thirdparty/boost/asio/basic_socket_iostream.hpp @@ -0,0 +1,150 @@ +// +// basic_socket_iostream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP +#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if !defined(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY) +#define BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY 5 +#endif // !defined(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY) + +// A macro that should expand to: +// template +// explicit basic_socket_iostream(T1 x1, ..., Tn xn) +// : basic_iostream(&this->boost::base_from_member< +// basic_socket_streambuf >::member) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +#define BOOST_ASIO_PRIVATE_CTR_DEF(z, n, data) \ + template \ + explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + : std::basic_iostream(&this->boost::base_from_member< \ + basic_socket_streambuf >::member) \ + { \ + tie(this); \ + if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +// A macro that should expand to: +// template +// void connect(T1 x1, ..., Tn xn) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +#define BOOST_ASIO_PRIVATE_CONNECT_DEF(z, n, data) \ + template \ + void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + { \ + if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +namespace boost { +namespace asio { + +/// Iostream interface for a socket. +template > +class basic_socket_iostream + : public boost::base_from_member< + basic_socket_streambuf >, + public std::basic_iostream +{ +public: + /// Construct a basic_socket_iostream without establishing a connection. + basic_socket_iostream() + : std::basic_iostream(&this->boost::base_from_member< + basic_socket_streambuf >::member) + { + tie(this); + } + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This constructor automatically establishes a connection based on the + * supplied resolver query parameters. The arguments are used to construct + * a resolver query object. + */ + template + explicit basic_socket_iostream(T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY), + BOOST_ASIO_PRIVATE_CTR_DEF, _ ) +#endif + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + */ + template + void connect(T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY), + BOOST_ASIO_PRIVATE_CONNECT_DEF, _ ) +#endif + + /// Close the connection. + void close() + { + if (rdbuf()->close() == 0) + this->setstate(std::ios_base::failbit); + } + + /// Return a pointer to the underlying streambuf. + basic_socket_streambuf* rdbuf() const + { + return const_cast*>( + &this->boost::base_from_member< + basic_socket_streambuf >::member); + } +}; + +} // namespace asio +} // namespace boost + +#undef BOOST_ASIO_PRIVATE_CTR_DEF +#undef BOOST_ASIO_PRIVATE_CONNECT_DEF + +#include + +#endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP diff --git a/thirdparty/boost/asio/basic_socket_streambuf.hpp b/thirdparty/boost/asio/basic_socket_streambuf.hpp new file mode 100644 index 0000000..8f13f57 --- /dev/null +++ b/thirdparty/boost/asio/basic_socket_streambuf.hpp @@ -0,0 +1,286 @@ +// +// basic_socket_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP +#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if !defined(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY) +#define BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY 5 +#endif // !defined(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY) + +// A macro that should expand to: +// template +// basic_socket_streambuf* connect( +// T1 x1, ..., Tn xn) +// { +// init_buffers(); +// boost::system::error_code ec; +// this->basic_socket::close(ec); +// typedef typename Protocol::resolver_query resolver_query; +// resolver_query query(x1, ..., xn); +// resolve_and_connect(query, ec); +// return !ec ? this : 0; +// } +// This macro should only persist within this file. + +#define BOOST_ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \ + template \ + basic_socket_streambuf* connect( \ + BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + { \ + init_buffers(); \ + boost::system::error_code ec; \ + this->basic_socket::close(ec); \ + typedef typename Protocol::resolver_query resolver_query; \ + resolver_query query(BOOST_PP_ENUM_PARAMS(n, x)); \ + resolve_and_connect(query, ec); \ + return !ec ? this : 0; \ + } \ + /**/ + +namespace boost { +namespace asio { + +/// Iostream streambuf for a socket. +template > +class basic_socket_streambuf + : public std::streambuf, + private boost::base_from_member, + public basic_socket +{ +public: + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_socket_streambuf without establishing a connection. + basic_socket_streambuf() + : basic_socket( + boost::base_from_member::member), + unbuffered_(false) + { + init_buffers(); + } + + /// Destructor flushes buffered data. + virtual ~basic_socket_streambuf() + { + if (pptr() != pbase()) + overflow(traits_type::eof()); + } + + /// Establish a connection. + /** + * This function establishes a connection to the specified endpoint. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* connect( + const endpoint_type& endpoint) + { + init_buffers(); + boost::system::error_code ec; + this->basic_socket::close(ec); + this->basic_socket::connect(endpoint, ec); + return !ec ? this : 0; + } + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + template + basic_socket_streambuf* connect( + T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY), + BOOST_ASIO_PRIVATE_CONNECT_DEF, _ ) +#endif + + /// Close the connection. + /** + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* close() + { + boost::system::error_code ec; + sync(); + this->basic_socket::close(ec); + if (!ec) + init_buffers(); + return !ec ? this : 0; + } + +protected: + int_type underflow() + { + if (gptr() == egptr()) + { + boost::system::error_code ec; + std::size_t bytes_transferred = this->service.receive( + this->implementation, + boost::asio::buffer(boost::asio::buffer(get_buffer_) + putback_max), + 0, ec); + if (ec) + return traits_type::eof(); + setg(get_buffer_.begin(), get_buffer_.begin() + putback_max, + get_buffer_.begin() + putback_max + bytes_transferred); + return traits_type::to_int_type(*gptr()); + } + else + { + return traits_type::eof(); + } + } + + int_type overflow(int_type c) + { + if (unbuffered_) + { + if (traits_type::eq_int_type(c, traits_type::eof())) + { + // Nothing to do. + return traits_type::not_eof(c); + } + else + { + // Send the single character immediately. + boost::system::error_code ec; + char_type ch = traits_type::to_char_type(c); + this->service.send(this->implementation, + boost::asio::buffer(&ch, sizeof(char_type)), 0, ec); + if (ec) + return traits_type::eof(); + return c; + } + } + else + { + // Send all data in the output buffer. + boost::asio::const_buffer buffer = + boost::asio::buffer(pbase(), pptr() - pbase()); + while (boost::asio::buffer_size(buffer) > 0) + { + boost::system::error_code ec; + std::size_t bytes_transferred = this->service.send( + this->implementation, boost::asio::buffer(buffer), + 0, ec); + if (ec) + return traits_type::eof(); + buffer = buffer + bytes_transferred; + } + setp(put_buffer_.begin(), put_buffer_.end()); + + // If the new character is eof then our work here is done. + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + + // Add the new character to the output buffer. + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + } + + int sync() + { + return overflow(traits_type::eof()); + } + + std::streambuf* setbuf(char_type* s, std::streamsize n) + { + if (pptr() == pbase() && s == 0 && n == 0) + { + unbuffered_ = true; + setp(0, 0); + return this; + } + + return 0; + } + +private: + void init_buffers() + { + setg(get_buffer_.begin(), + get_buffer_.begin() + putback_max, + get_buffer_.begin() + putback_max); + if (unbuffered_) + setp(0, 0); + else + setp(put_buffer_.begin(), put_buffer_.end()); + } + + void resolve_and_connect(const typename Protocol::resolver_query& query, + boost::system::error_code& ec) + { + typedef typename Protocol::resolver resolver_type; + typedef typename Protocol::resolver_iterator iterator_type; + resolver_type resolver( + boost::base_from_member::member); + iterator_type i = resolver.resolve(query, ec); + if (!ec) + { + iterator_type end; + ec = boost::asio::error::host_not_found; + while (ec && i != end) + { + this->basic_socket::close(); + this->basic_socket::connect(*i, ec); + ++i; + } + } + } + + enum { putback_max = 8 }; + enum { buffer_size = 512 }; + boost::array get_buffer_; + boost::array put_buffer_; + bool unbuffered_; +}; + +} // namespace asio +} // namespace boost + +#undef BOOST_ASIO_PRIVATE_CONNECT_DEF + +#include + +#endif // BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP diff --git a/thirdparty/boost/asio/basic_stream_socket.hpp b/thirdparty/boost/asio/basic_stream_socket.hpp new file mode 100644 index 0000000..6737e07 --- /dev/null +++ b/thirdparty/boost/asio/basic_stream_socket.hpp @@ -0,0 +1,720 @@ +// +// basic_stream_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_HPP +#define BOOST_ASIO_BASIC_STREAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides stream-oriented socket functionality. +/** + * The basic_stream_socket class template provides asynchronous and blocking + * stream-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template > +class basic_stream_socket + : public basic_socket +{ +public: + /// The native representation of a socket. + typedef typename StreamSocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_stream_socket without opening it. + /** + * This constructor creates a stream socket without opening it. The socket + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + */ + explicit basic_stream_socket(boost::asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_stream_socket. + /** + * This constructor creates and opens a stream socket. The socket needs to be + * connected or accepted before data can be sent or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_stream_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a stream socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the stream + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket(boost::asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_stream_socket on an existing native socket. + /** + * This constructor creates a stream socket object to hold an existing native + * socket. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(boost::asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. Returns 0 if an error occurred. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->service.send(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, flags, handler); + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(boost::asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. Returns 0 if an error occurred. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->service.receive(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, flags, handler); + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @returns The number of bytes written. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.write_some(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + return this->service.send(this->implementation, buffers, 0, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the socket. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_write_some(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.read_some(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return this->service.receive(this->implementation, buffers, 0, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_read_some(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP diff --git a/thirdparty/boost/asio/basic_streambuf.hpp b/thirdparty/boost/asio/basic_streambuf.hpp new file mode 100644 index 0000000..6a9f24c --- /dev/null +++ b/thirdparty/boost/asio/basic_streambuf.hpp @@ -0,0 +1,202 @@ +// +// basic_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BASIC_STREAMBUF_HPP +#define BOOST_ASIO_BASIC_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +/// Automatically resizable buffer class based on std::streambuf. +template > +class basic_streambuf + : public std::streambuf, + private noncopyable +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The type used to represent the get area as a list of buffers. + typedef implementation_defined const_buffers_type; + + /// The type used to represent the put area as a list of buffers. + typedef implementation_defined mutable_buffers_type; +#else + typedef boost::asio::const_buffers_1 const_buffers_type; + typedef boost::asio::mutable_buffers_1 mutable_buffers_type; +#endif + + /// Construct a buffer with a specified maximum size. + explicit basic_streambuf( + std::size_t max_size = (std::numeric_limits::max)(), + const Allocator& allocator = Allocator()) + : max_size_(max_size), + buffer_(allocator) + { + std::size_t pend = (std::min)(max_size_, buffer_delta); + buffer_.resize((std::max)(pend, 1)); + setg(&buffer_[0], &buffer_[0], &buffer_[0]); + setp(&buffer_[0], &buffer_[0] + pend); + } + + /// Return the size of the get area in characters. + std::size_t size() const + { + return pptr() - gptr(); + } + + /// Return the maximum size of the buffer. + std::size_t max_size() const + { + return max_size_; + } + + /// Get a list of buffers that represents the get area. + const_buffers_type data() const + { + return boost::asio::buffer(boost::asio::const_buffer(gptr(), + (pptr() - gptr()) * sizeof(char_type))); + } + + /// Get a list of buffers that represents the put area, with the given size. + mutable_buffers_type prepare(std::size_t size) + { + reserve(size); + return boost::asio::buffer(boost::asio::mutable_buffer( + pptr(), size * sizeof(char_type))); + } + + /// Move the start of the put area by the specified number of characters. + void commit(std::size_t n) + { + if (pptr() + n > epptr()) + n = epptr() - pptr(); + pbump(static_cast(n)); + } + + /// Move the start of the get area by the specified number of characters. + void consume(std::size_t n) + { + while (n > 0) + { + sbumpc(); + --n; + } + } + +protected: + enum { buffer_delta = 128 }; + + int_type underflow() + { + if (gptr() < pptr()) + { + setg(&buffer_[0], gptr(), pptr()); + return traits_type::to_int_type(*gptr()); + } + else + { + return traits_type::eof(); + } + } + + int_type overflow(int_type c) + { + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + if (pptr() == epptr()) + { + std::size_t buffer_size = pptr() - gptr(); + if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta) + { + reserve(max_size_ - buffer_size); + } + else + { + reserve(buffer_delta); + } + } + + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + + return traits_type::not_eof(c); + } + + void reserve(std::size_t n) + { + // Get current stream positions as offsets. + std::size_t gnext = gptr() - &buffer_[0]; + std::size_t gend = egptr() - &buffer_[0]; + std::size_t pnext = pptr() - &buffer_[0]; + std::size_t pend = epptr() - &buffer_[0]; + + // Check if there is already enough space in the put area. + if (n <= pend - pnext) + { + return; + } + + // Shift existing contents of get area to start of buffer. + if (gnext > 0) + { + std::rotate(&buffer_[0], &buffer_[0] + gnext, &buffer_[0] + pend); + gend -= gnext; + pnext -= gnext; + } + + // Ensure buffer is large enough to hold at least the specified size. + if (n > pend - pnext) + { + if (n <= max_size_ && pnext <= max_size_ - n) + { + buffer_.resize((std::max)(pnext + n, 1)); + } + else + { + throw std::length_error("boost::asio::streambuf too long"); + } + } + + // Update stream positions. + setg(&buffer_[0], &buffer_[0], &buffer_[0] + gend); + setp(&buffer_[0] + pnext, &buffer_[0] + pnext + n); + } + +private: + std::size_t max_size_; + std::vector buffer_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_STREAMBUF_HPP diff --git a/thirdparty/boost/asio/buffer.hpp b/thirdparty/boost/asio/buffer.hpp new file mode 100644 index 0000000..72b9fc3 --- /dev/null +++ b/thirdparty/boost/asio/buffer.hpp @@ -0,0 +1,805 @@ +// +// buffer.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFER_HPP +#define BOOST_ASIO_BUFFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) +# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) +# if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) +# define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_HAS_ITERATOR_DEBUGGING) +#endif // defined(BOOST_MSVC) + +#if defined(__GNUC__) +# if defined(_GLIBCXX_DEBUG) +# if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) +# define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_GLIBCXX_DEBUG) +#endif // defined(__GNUC__) + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) +# include +# include +# include +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + +namespace boost { +namespace asio { + +class mutable_buffer; +class const_buffer; + +namespace detail { +void* buffer_cast_helper(const mutable_buffer&); +const void* buffer_cast_helper(const const_buffer&); +std::size_t buffer_size_helper(const mutable_buffer&); +std::size_t buffer_size_helper(const const_buffer&); +} // namespace detail + +/// Holds a buffer that can be modified. +/** + * The mutable_buffer class provides a safe representation of a buffer that can + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + */ +class mutable_buffer +{ +public: + /// Construct an empty buffer. + mutable_buffer() + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + mutable_buffer(void* data, std::size_t size) + : data_(data), + size_(size) + { + } + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + mutable_buffer(void* data, std::size_t size, + boost::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const boost::function& get_debug_check() const + { + return debug_check_; + } +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + +private: + friend void* boost::asio::detail::buffer_cast_helper( + const mutable_buffer& b); + friend std::size_t boost::asio::detail::buffer_size_helper( + const mutable_buffer& b); + + void* data_; + std::size_t size_; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + boost::function debug_check_; +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +}; + +namespace detail { + +inline void* buffer_cast_helper(const mutable_buffer& b) +{ +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + if (b.size_ && b.debug_check_) + b.debug_check_(); +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + return b.data_; +} + +inline std::size_t buffer_size_helper(const mutable_buffer& b) +{ + return b.size_; +} + +} // namespace detail + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +/** + * @relates mutable_buffer + */ +template +inline PointerToPodType buffer_cast(const mutable_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/// Get the number of bytes in a non-modifiable buffer. +/** + * @relates mutable_buffer + */ +inline std::size_t buffer_size(const mutable_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Adapts a single modifiable buffer so that it meets the requirements of the +/// MutableBufferSequence concept. +class mutable_buffers_1 + : public mutable_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef mutable_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const mutable_buffer* const_iterator; + + /// Construct to represent a single modifiable buffer. + explicit mutable_buffers_1(const mutable_buffer& b) + : mutable_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const + { + return begin() + 1; + } +}; + +/// Holds a buffer that cannot be modified. +/** + * The const_buffer class provides a safe representation of a buffer that cannot + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + */ +class const_buffer +{ +public: + /// Construct an empty buffer. + const_buffer() + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + const_buffer(const void* data, std::size_t size) + : data_(data), + size_(size) + { + } + + /// Construct a non-modifiable buffer from a modifiable one. + const_buffer(const mutable_buffer& b) + : data_(boost::asio::detail::buffer_cast_helper(b)), + size_(boost::asio::detail::buffer_size_helper(b)) +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , debug_check_(b.get_debug_check()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + { + } + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + const_buffer(const void* data, std::size_t size, + boost::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const boost::function& get_debug_check() const + { + return debug_check_; + } +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + +private: + friend const void* boost::asio::detail::buffer_cast_helper( + const const_buffer& b); + friend std::size_t boost::asio::detail::buffer_size_helper( + const const_buffer& b); + + const void* data_; + std::size_t size_; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + boost::function debug_check_; +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +}; + +namespace detail { + +inline const void* buffer_cast_helper(const const_buffer& b) +{ +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + if (b.size_ && b.debug_check_) + b.debug_check_(); +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + return b.data_; +} + +inline std::size_t buffer_size_helper(const const_buffer& b) +{ + return b.size_; +} + +} // namespace detail + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +/** + * @relates const_buffer + */ +template +inline PointerToPodType buffer_cast(const const_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/// Get the number of bytes in a non-modifiable buffer. +/** + * @relates const_buffer + */ +inline std::size_t buffer_size(const const_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(const const_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(std::size_t start, const const_buffer& b) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Adapts a single non-modifiable buffer so that it meets the requirements of +/// the ConstBufferSequence concept. +class const_buffers_1 + : public const_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef const_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const const_buffer* const_iterator; + + /// Construct to represent a single non-modifiable buffer. + explicit const_buffers_1(const const_buffer& b) + : const_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const + { + return begin() + 1; + } +}; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) +namespace detail { + +template +class buffer_debug_check +{ +public: + buffer_debug_check(Iterator iter) + : iter_(iter) + { + } + + ~buffer_debug_check() + { +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) + // MSVC's string iterator checking may crash in a std::string::iterator + // object's destructor when the iterator points to an already-destroyed + // std::string object, unless the iterator is cleared first. + iter_ = Iterator(); +#endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400) + } + + void operator()() + { + *iter_; + } + +private: + Iterator iter_; +}; + +} // namespace detail +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + +/** @defgroup buffer boost::asio::buffer + * + * @brief The boost::asio::buffer function is used to create a buffer object to + * represent raw memory, an array of POD elements, or a vector of POD elements. + * + * The simplest use case involves reading or writing a single buffer of a + * specified size: + * + * @code sock.write(boost::asio::buffer(data, size)); @endcode + * + * In the above example, the return value of boost::asio::buffer meets the + * requirements of the ConstBufferSequence concept so that it may be directly + * passed to the socket's write function. A buffer created for modifiable + * memory also meets the requirements of the MutableBufferSequence concept. + * + * An individual buffer may be created from a builtin array, std::vector or + * boost::array of POD elements. This helps prevent buffer overruns by + * automatically determining the size of the buffer: + * + * @code char d1[128]; + * size_t bytes_transferred = sock.read(boost::asio::buffer(d1)); + * + * std::vector d2(128); + * bytes_transferred = sock.read(boost::asio::buffer(d2)); + * + * boost::array d3; + * bytes_transferred = sock.read(boost::asio::buffer(d3)); @endcode + * + * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple + * buffer objects may be assigned into a container that supports the + * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts: + * + * @code + * char d1[128]; + * std::vector d2(128); + * boost::array d3; + * + * boost::array bufs1 = { + * boost::asio::buffer(d1), + * boost::asio::buffer(d2), + * boost::asio::buffer(d3) }; + * bytes_transferred = sock.read(bufs1); + * + * std::vector bufs2; + * bufs2.push_back(boost::asio::buffer(d1)); + * bufs2.push_back(boost::asio::buffer(d2)); + * bufs2.push_back(boost::asio::buffer(d3)); + * bytes_transferred = sock.write(bufs2); @endcode + */ +/*@{*/ + +/// Create a new modifiable buffer from an existing buffer. +inline mutable_buffers_1 buffer(const mutable_buffer& b) +{ + return mutable_buffers_1(b); +} + +/// Create a new modifiable buffer from an existing buffer. +inline mutable_buffers_1 buffer(const mutable_buffer& b, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(buffer_cast(b), + buffer_size(b) < max_size_in_bytes + ? buffer_size(b) : max_size_in_bytes +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer from an existing buffer. +inline const_buffers_1 buffer(const const_buffer& b) +{ + return const_buffers_1(b); +} + +/// Create a new non-modifiable buffer from an existing buffer. +inline const_buffers_1 buffer(const const_buffer& b, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(buffer_cast(b), + buffer_size(b) < max_size_in_bytes + ? buffer_size(b) : max_size_in_bytes +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new modifiable buffer that represents the given memory range. +inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes) +{ + return mutable_buffers_1(mutable_buffer(data, size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given memory range. +inline const_buffers_1 buffer(const void* data, + std::size_t size_in_bytes) +{ + return const_buffers_1(const_buffer(data, size_in_bytes)); +} + +/// Create a new modifiable buffer that represents the given POD array. +template +inline mutable_buffers_1 buffer(PodType (&data)[N]) +{ + return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType))); +} + +/// Create a new modifiable buffer that represents the given POD array. +template +inline mutable_buffers_1 buffer(PodType (&data)[N], + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(const PodType (&data)[N]) +{ + return const_buffers_1(const_buffer(data, N * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(const PodType (&data)[N], + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes)); +} + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +// Borland C++ and Sun Studio think the overloads: +// +// unspecified buffer(boost::array& array ...); +// +// and +// +// unspecified buffer(boost::array& array ...); +// +// are ambiguous. This will be worked around by using a buffer_types traits +// class that contains typedefs for the appropriate buffer and container +// classes, based on whether PodType is const or non-const. + +namespace detail { + +template +struct buffer_types_base; + +template <> +struct buffer_types_base +{ + typedef mutable_buffer buffer_type; + typedef mutable_buffers_1 container_type; +}; + +template <> +struct buffer_types_base +{ + typedef const_buffer buffer_type; + typedef const_buffers_1 container_type; +}; + +template +struct buffer_types + : public buffer_types_base::value> +{ +}; + +} // namespace detail + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data) +{ + typedef typename boost::asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename boost::asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), data.size() * sizeof(PodType))); +} + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data, std::size_t max_size_in_bytes) +{ + typedef typename boost::asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename boost::asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +/// Create a new modifiable buffer that represents the given POD array. +template +inline mutable_buffers_1 buffer(boost::array& data) +{ + return mutable_buffers_1( + mutable_buffer(data.c_array(), data.size() * sizeof(PodType))); +} + +/// Create a new modifiable buffer that represents the given POD array. +template +inline mutable_buffers_1 buffer(boost::array& data, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(boost::array& data) +{ + return const_buffers_1( + const_buffer(data.data(), data.size() * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(boost::array& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(const boost::array& data) +{ + return const_buffers_1( + const_buffer(data.data(), data.size() * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +template +inline const_buffers_1 buffer(const boost::array& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline mutable_buffers_1 buffer(std::vector& data) +{ + return mutable_buffers_1( + mutable_buffer(&data[0], data.size() * sizeof(PodType) +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline mutable_buffers_1 buffer(std::vector& data, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(&data[0], + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline const_buffers_1 buffer( + const std::vector& data) +{ + return const_buffers_1( + const_buffer(&data[0], data.size() * sizeof(PodType) +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline const_buffers_1 buffer( + const std::vector& data, std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(&data[0], + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +inline const_buffers_1 buffer(const std::string& data) +{ + return const_buffers_1(const_buffer(data.data(), data.size() +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +inline const_buffers_1 buffer(const std::string& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() < max_size_in_bytes + ? data.size() : max_size_in_bytes +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check(data.begin()) +#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/*@}*/ + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFER_HPP diff --git a/thirdparty/boost/asio/buffered_read_stream.hpp b/thirdparty/boost/asio/buffered_read_stream.hpp new file mode 100644 index 0000000..f1700ee --- /dev/null +++ b/thirdparty/boost/asio/buffered_read_stream.hpp @@ -0,0 +1,416 @@ +// +// buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_READ_STREAM_HPP +#define BOOST_ASIO_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Adds buffering to the read-related operations of a stream. +/** + * The buffered_read_stream class template can be used to add buffering to the + * synchronous and asynchronous read operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream. + */ +template +class buffered_read_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_read_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_read_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + boost::asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + boost::asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + boost::system::error_code close(boost::system::error_code& ec) + { + return next_layer_.close(ec); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return next_layer_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + return next_layer_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + next_layer_.async_write_some(buffers, handler); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill() + { + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size))); + resize_guard.commit(); + return storage_.size() - previous_size; + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(boost::system::error_code& ec) + { + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + ec)); + resize_guard.commit(); + return storage_.size() - previous_size; + } + + template + class fill_handler + { + public: + fill_handler(boost::asio::io_service& io_service, + detail::buffered_stream_storage& storage, + std::size_t previous_size, ReadHandler handler) + : io_service_(io_service), + storage_(storage), + previous_size_(previous_size), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + storage_.resize(previous_size_ + bytes_transferred); + io_service_.dispatch(detail::bind_handler( + handler_, ec, bytes_transferred)); + } + + private: + boost::asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + std::size_t previous_size_; + ReadHandler handler_; + }; + + /// Start an asynchronous fill. + template + void async_fill(ReadHandler handler) + { + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + next_layer_.async_read_some( + buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + fill_handler(get_io_service(), + storage_, previous_size, handler)); + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + if (storage_.empty()) + fill(); + return copy(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + ec = boost::system::error_code(); + if (storage_.empty() && !fill(ec)) + return 0; + return copy(buffers); + } + + template + class read_some_handler + { + public: + read_some_handler(boost::asio::io_service& io_service, + detail::buffered_stream_storage& storage, + const MutableBufferSequence& buffers, ReadHandler handler) + : io_service_(io_service), + storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, std::size_t) + { + if (ec || storage_.empty()) + { + std::size_t length = 0; + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); + } + else + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers_.begin(); + typename MutableBufferSequence::const_iterator end = buffers_.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), + storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + storage_.consume(bytes_copied); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); + } + } + + private: + boost::asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + MutableBufferSequence buffers_; + ReadHandler handler_; + }; + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + if (storage_.empty()) + { + async_fill(read_some_handler( + get_io_service(), storage_, buffers, handler)); + } + else + { + std::size_t length = copy(buffers); + get_io_service().post(detail::bind_handler( + handler, boost::system::error_code(), length)); + } + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + if (storage_.empty()) + fill(); + return peek_copy(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + ec = boost::system::error_code(); + if (storage_.empty() && !fill(ec)) + return 0; + return peek_copy(buffers); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return storage_.size(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(boost::system::error_code& ec) + { + ec = boost::system::error_code(); + return storage_.size(); + } + +private: + /// Copy data out of the internal buffer to the specified target buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const MutableBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + storage_.consume(bytes_copied); + return bytes_copied; + } + + /// Copy data from the internal buffer to the specified target buffer, without + /// removing the data from the internal buffer. Returns the number of bytes + /// copied. + template + std::size_t peek_copy(const MutableBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + return bytes_copied; + } + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_READ_STREAM_HPP diff --git a/thirdparty/boost/asio/buffered_read_stream_fwd.hpp b/thirdparty/boost/asio/buffered_read_stream_fwd.hpp new file mode 100644 index 0000000..5e358e0 --- /dev/null +++ b/thirdparty/boost/asio/buffered_read_stream_fwd.hpp @@ -0,0 +1,31 @@ +// +// buffered_read_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP +#define BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { + +template +class buffered_read_stream; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP diff --git a/thirdparty/boost/asio/buffered_stream.hpp b/thirdparty/boost/asio/buffered_stream.hpp new file mode 100644 index 0000000..45a7a6c --- /dev/null +++ b/thirdparty/boost/asio/buffered_stream.hpp @@ -0,0 +1,252 @@ +// +// buffered_stream.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_STREAM_HPP +#define BOOST_ASIO_BUFFERED_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Adds buffering to the read- and write-related operations of a stream. +/** + * The buffered_stream class template can be used to add buffering to the + * synchronous and asynchronous read and write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a) + : inner_stream_impl_(a), + stream_impl_(inner_stream_impl_) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a, std::size_t read_buffer_size, + std::size_t write_buffer_size) + : inner_stream_impl_(a, write_buffer_size), + stream_impl_(inner_stream_impl_, read_buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return stream_impl_.next_layer().next_layer(); + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return stream_impl_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + boost::asio::io_service& io_service() + { + return stream_impl_.get_io_service(); + } + + /// Get the io_service associated with the object. + boost::asio::io_service& get_io_service() + { + return stream_impl_.get_io_service(); + } + + /// Close the stream. + void close() + { + stream_impl_.close(); + } + + /// Close the stream. + boost::system::error_code close(boost::system::error_code& ec) + { + return stream_impl_.close(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush() + { + return stream_impl_.next_layer().flush(); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(boost::system::error_code& ec) + { + return stream_impl_.next_layer().flush(ec); + } + + /// Start an asynchronous flush. + template + void async_flush(WriteHandler handler) + { + return stream_impl_.next_layer().async_flush(handler); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return stream_impl_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + return stream_impl_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + stream_impl_.async_write_some(buffers, handler); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill() + { + return stream_impl_.fill(); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(boost::system::error_code& ec) + { + return stream_impl_.fill(ec); + } + + /// Start an asynchronous fill. + template + void async_fill(ReadHandler handler) + { + stream_impl_.async_fill(handler); + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return stream_impl_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return stream_impl_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + stream_impl_.async_read_some(buffers, handler); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return stream_impl_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return stream_impl_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return stream_impl_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(boost::system::error_code& ec) + { + return stream_impl_.in_avail(ec); + } + +private: + // The buffered write stream. + typedef buffered_write_stream write_stream_type; + write_stream_type inner_stream_impl_; + + // The buffered read stream. + typedef buffered_read_stream read_stream_type; + read_stream_type stream_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_STREAM_HPP diff --git a/thirdparty/boost/asio/buffered_stream_fwd.hpp b/thirdparty/boost/asio/buffered_stream_fwd.hpp new file mode 100644 index 0000000..b67430b --- /dev/null +++ b/thirdparty/boost/asio/buffered_stream_fwd.hpp @@ -0,0 +1,31 @@ +// +// buffered_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_STREAM_FWD_HPP +#define BOOST_ASIO_BUFFERED_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { + +template +class buffered_stream; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_STREAM_FWD_HPP diff --git a/thirdparty/boost/asio/buffered_write_stream.hpp b/thirdparty/boost/asio/buffered_write_stream.hpp new file mode 100644 index 0000000..6ff703a --- /dev/null +++ b/thirdparty/boost/asio/buffered_write_stream.hpp @@ -0,0 +1,370 @@ +// +// buffered_write_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP +#define BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Adds buffering to the write-related operations of a stream. +/** + * The buffered_write_stream class template can be used to add buffering to the + * synchronous and asynchronous write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_write_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_write_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_write_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + boost::asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + boost::asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + boost::system::error_code close(boost::system::error_code& ec) + { + return next_layer_.close(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush() + { + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size())); + storage_.consume(bytes_written); + return bytes_written; + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(boost::system::error_code& ec) + { + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size()), + transfer_all(), ec); + storage_.consume(bytes_written); + return bytes_written; + } + + template + class flush_handler + { + public: + flush_handler(boost::asio::io_service& io_service, + detail::buffered_stream_storage& storage, WriteHandler handler) + : io_service_(io_service), + storage_(storage), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_written) + { + storage_.consume(bytes_written); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written)); + } + + private: + boost::asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + WriteHandler handler_; + }; + + /// Start an asynchronous flush. + template + void async_flush(WriteHandler handler) + { + async_write(next_layer_, buffer(storage_.data(), storage_.size()), + flush_handler(get_io_service(), storage_, handler)); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + if (storage_.size() == storage_.capacity()) + flush(); + return copy(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred and the error handler did not throw. + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + ec = boost::system::error_code(); + if (storage_.size() == storage_.capacity() && !flush(ec)) + return 0; + return copy(buffers); + } + + template + class write_some_handler + { + public: + write_some_handler(boost::asio::io_service& io_service, + detail::buffered_stream_storage& storage, + const ConstBufferSequence& buffers, WriteHandler handler) + : io_service_(io_service), + storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, std::size_t) + { + if (ec) + { + std::size_t length = 0; + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); + } + else + { + using namespace std; // For memcpy. + + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_copied = 0; + + typename ConstBufferSequence::const_iterator iter = buffers_.begin(); + typename ConstBufferSequence::const_iterator end = buffers_.end(); + for (; iter != end && space_avail > 0; ++iter) + { + std::size_t bytes_avail = buffer_size(*iter); + std::size_t length = (bytes_avail < space_avail) + ? bytes_avail : space_avail; + storage_.resize(orig_size + bytes_copied + length); + memcpy(storage_.data() + orig_size + bytes_copied, + buffer_cast(*iter), length); + bytes_copied += length; + space_avail -= length; + } + + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); + } + } + + private: + boost::asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + ConstBufferSequence buffers_; + WriteHandler handler_; + }; + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + if (storage_.size() == storage_.capacity()) + { + async_flush(write_some_handler( + get_io_service(), storage_, buffers, handler)); + } + else + { + std::size_t bytes_copied = copy(buffers); + get_io_service().post(detail::bind_handler( + handler, boost::system::error_code(), bytes_copied)); + } + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return next_layer_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return next_layer_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + next_layer_.async_read_some(buffers, handler); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return next_layer_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return next_layer_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return next_layer_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(boost::system::error_code& ec) + { + return next_layer_.in_avail(ec); + } + +private: + /// Copy data into the internal buffer from the specified source buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const ConstBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_copied = 0; + + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && space_avail > 0; ++iter) + { + std::size_t bytes_avail = buffer_size(*iter); + std::size_t length = (bytes_avail < space_avail) + ? bytes_avail : space_avail; + storage_.resize(orig_size + bytes_copied + length); + memcpy(storage_.data() + orig_size + bytes_copied, + buffer_cast(*iter), length); + bytes_copied += length; + space_avail -= length; + } + + return bytes_copied; + } + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP diff --git a/thirdparty/boost/asio/buffered_write_stream_fwd.hpp b/thirdparty/boost/asio/buffered_write_stream_fwd.hpp new file mode 100644 index 0000000..d40fefe --- /dev/null +++ b/thirdparty/boost/asio/buffered_write_stream_fwd.hpp @@ -0,0 +1,31 @@ +// +// buffered_write_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP +#define BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { + +template +class buffered_write_stream; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP diff --git a/thirdparty/boost/asio/completion_condition.hpp b/thirdparty/boost/asio/completion_condition.hpp new file mode 100644 index 0000000..05e848d --- /dev/null +++ b/thirdparty/boost/asio/completion_condition.hpp @@ -0,0 +1,147 @@ +// +// completion_condition.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_COMPLETION_CONDITION_HPP +#define BOOST_ASIO_COMPLETION_CONDITION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +namespace detail { + +class transfer_all_t +{ +public: + typedef bool result_type; + + template + bool operator()(const Error& err, std::size_t) + { + return !!err; + } +}; + +class transfer_at_least_t +{ +public: + typedef bool result_type; + + explicit transfer_at_least_t(std::size_t minimum) + : minimum_(minimum) + { + } + + template + bool operator()(const Error& err, std::size_t bytes_transferred) + { + return !!err || bytes_transferred >= minimum_; + } + +private: + std::size_t minimum_; +}; + +} // namespace detail + +/** + * @defgroup completion_condition Completion Condition Function Objects + * + * Function objects used for determining when a read or write operation should + * complete. + */ +/*@{*/ + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until all of the data has been transferred, +/// or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full: + * @code + * boost::array buf; + * boost::system::error_code ec; + * std::size_t n = boost::asio::read( + * sock, boost::asio::buffer(buf), + * boost::asio::transfer_all(), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n == 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_all(); +#else +inline detail::transfer_all_t transfer_all() +{ + return detail::transfer_all_t(); +} +#endif + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until a minimum number of bytes has been +/// transferred, or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full or contains at least 64 bytes: + * @code + * boost::array buf; + * boost::system::error_code ec; + * std::size_t n = boost::asio::read( + * sock, boost::asio::buffer(buf), + * boost::asio::transfer_at_least(64), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n >= 64 && n <= 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_at_least(std::size_t minimum); +#else +inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum) +{ + return detail::transfer_at_least_t(minimum); +} +#endif + +/*@}*/ + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_COMPLETION_CONDITION_HPP diff --git a/thirdparty/boost/asio/datagram_socket_service.hpp b/thirdparty/boost/asio/datagram_socket_service.hpp new file mode 100644 index 0000000..2f362ff --- /dev/null +++ b/thirdparty/boost/asio/datagram_socket_service.hpp @@ -0,0 +1,325 @@ +// +// datagram_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP +#define BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a datagram socket. +template +class datagram_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_EPOLL) + typedef detail::reactive_socket_service< + Protocol, detail::epoll_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + typedef detail::reactive_socket_service< + Protocol, detail::kqueue_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + typedef detail::reactive_socket_service< + Protocol, detail::dev_poll_reactor > service_impl_type; +#else + typedef detail::reactive_socket_service< + Protocol, detail::select_reactor > service_impl_type; +#endif + +public: + /// The type of a datagram socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new datagram socket service for the specified io_service. + explicit datagram_socket_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + datagram_socket_service >(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new datagram socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a datagram socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + // Open a new datagram socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (protocol.type() == SOCK_DGRAM) + service_impl_.open(impl, protocol, ec); + else + ec = boost::asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a datagram socket. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a datagram socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the datagram socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the datagram socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, ConnectHandler handler) + { + service_impl_.async_connect(impl, peer_endpoint, handler); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send(impl, buffers, flags, handler); + } + + /// Send a datagram to the specified endpoint. + template + std::size_t send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send_to(impl, buffers, destination, flags, handler); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive(impl, buffers, flags, handler); + } + + /// Receive a datagram with the endpoint of the sender. + template + std::size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, + ec); + } + + /// Start an asynchronous receive that will get the endpoint of the sender. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags, + handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/thirdparty/boost/asio/deadline_timer.hpp b/thirdparty/boost/asio/deadline_timer.hpp new file mode 100644 index 0000000..c5807b4 --- /dev/null +++ b/thirdparty/boost/asio/deadline_timer.hpp @@ -0,0 +1,39 @@ +// +// deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DEADLINE_TIMER_HPP +#define BOOST_ASIO_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include // Must come before posix_time. + +#include +#include +#include + +#include + +namespace boost { +namespace asio { + +/// Typedef for the typical usage of timer. +typedef basic_deadline_timer deadline_timer; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DEADLINE_TIMER_HPP diff --git a/thirdparty/boost/asio/deadline_timer_service.hpp b/thirdparty/boost/asio/deadline_timer_service.hpp new file mode 100644 index 0000000..56bc78e --- /dev/null +++ b/thirdparty/boost/asio/deadline_timer_service.hpp @@ -0,0 +1,170 @@ +// +// deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP +#define BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a timer. +template > +class deadline_timer_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base< + deadline_timer_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_HAS_IOCP) + typedef detail::deadline_timer_service< + traits_type, detail::win_iocp_io_service> service_impl_type; +#elif defined(BOOST_ASIO_HAS_EPOLL) + typedef detail::deadline_timer_service< + traits_type, detail::epoll_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + typedef detail::deadline_timer_service< + traits_type, detail::kqueue_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + typedef detail::deadline_timer_service< + traits_type, detail::dev_poll_reactor > service_impl_type; +#else + typedef detail::deadline_timer_service< + traits_type, detail::select_reactor > service_impl_type; +#endif + +public: + /// The implementation type of the deadline timer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new timer service for the specified io_service. + explicit deadline_timer_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + deadline_timer_service >(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new timer implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a timer implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return service_impl_.expires_at(impl); + } + + /// Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, boost::system::error_code& ec) + { + return service_impl_.expires_at(impl, expiry_time, ec); + } + + /// Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return service_impl_.expires_from_now(impl); + } + + /// Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, boost::system::error_code& ec) + { + return service_impl_.expires_from_now(impl, expiry_time, ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, boost::system::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + // Start an asynchronous wait on the timer. + template + void async_wait(implementation_type& impl, WaitHandler handler) + { + service_impl_.async_wait(impl, handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/bind_handler.hpp b/thirdparty/boost/asio/detail/bind_handler.hpp new file mode 100644 index 0000000..6f5f4df --- /dev/null +++ b/thirdparty/boost/asio/detail/bind_handler.hpp @@ -0,0 +1,351 @@ +// +// bind_handler.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_BIND_HANDLER_HPP +#define BOOST_ASIO_DETAIL_BIND_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class binder1 +{ +public: + binder1(const Handler& handler, const Arg1& arg1) + : handler_(handler), + arg1_(arg1) + { + } + + void operator()() + { + handler_(arg1_); + } + + void operator()() const + { + handler_(arg1_); + } + +//private: + Handler handler_; + Arg1 arg1_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder1* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder1* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder1* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +template +inline binder1 bind_handler(const Handler& handler, + const Arg1& arg1) +{ + return binder1(handler, arg1); +} + +template +class binder2 +{ +public: + binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2) + : handler_(handler), + arg1_(arg1), + arg2_(arg2) + { + } + + void operator()() + { + handler_(arg1_, arg2_); + } + + void operator()() const + { + handler_(arg1_, arg2_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder2* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder2* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder2* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +template +inline binder2 bind_handler(const Handler& handler, + const Arg1& arg1, const Arg2& arg2) +{ + return binder2(handler, arg1, arg2); +} + +template +class binder3 +{ +public: + binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder3* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder3* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder3* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +template +inline binder3 bind_handler(const Handler& handler, + const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) +{ + return binder3(handler, arg1, arg2, arg3); +} + +template +class binder4 +{ +public: + binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_, arg4_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder4* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder4* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder4* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +template +inline binder4 bind_handler( + const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4) +{ + return binder4(handler, arg1, arg2, arg3, + arg4); +} + +template +class binder5 +{ +public: + binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4), + arg5_(arg5) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; + Arg5 arg5_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder5* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder5* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder5* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +template +inline binder5 bind_handler( + const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) +{ + return binder5(handler, arg1, arg2, + arg3, arg4, arg5); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP diff --git a/thirdparty/boost/asio/detail/buffer_resize_guard.hpp b/thirdparty/boost/asio/detail/buffer_resize_guard.hpp new file mode 100644 index 0000000..f90de23 --- /dev/null +++ b/thirdparty/boost/asio/detail/buffer_resize_guard.hpp @@ -0,0 +1,72 @@ +// +// buffer_resize_guard.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP +#define BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// Helper class to manage buffer resizing in an exception safe way. +template +class buffer_resize_guard +{ +public: + // Constructor. + buffer_resize_guard(Buffer& buffer) + : buffer_(buffer), + old_size_(buffer.size()) + { + } + + // Destructor rolls back the buffer resize unless commit was called. + ~buffer_resize_guard() + { + if (old_size_ + != std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()) + { + buffer_.resize(old_size_); + } + } + + // Commit the resize transaction. + void commit() + { + old_size_ + = std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION(); + } + +private: + // The buffer being managed. + Buffer& buffer_; + + // The size of the buffer at the time the guard was constructed. + size_t old_size_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP diff --git a/thirdparty/boost/asio/detail/buffered_stream_storage.hpp b/thirdparty/boost/asio/detail/buffered_stream_storage.hpp new file mode 100644 index 0000000..cab4a20 --- /dev/null +++ b/thirdparty/boost/asio/detail/buffered_stream_storage.hpp @@ -0,0 +1,129 @@ +// +// buffered_stream_storage.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP +#define BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class buffered_stream_storage +{ +public: + // The type of the bytes stored in the buffer. + typedef unsigned char byte_type; + + // The type used for offsets into the buffer. + typedef std::size_t size_type; + + // Constructor. + explicit buffered_stream_storage(std::size_t capacity) + : begin_offset_(0), + end_offset_(0), + buffer_(capacity) + { + } + + /// Clear the buffer. + void clear() + { + begin_offset_ = 0; + end_offset_ = 0; + } + + // Return a pointer to the beginning of the unread data. + byte_type* data() + { + return &buffer_[0] + begin_offset_; + } + + // Return a pointer to the beginning of the unread data. + const byte_type* data() const + { + return &buffer_[0] + begin_offset_; + } + + // Is there no unread data in the buffer. + bool empty() const + { + return begin_offset_ == end_offset_; + } + + // Return the amount of unread data the is in the buffer. + size_type size() const + { + return end_offset_ - begin_offset_; + } + + // Resize the buffer to the specified length. + void resize(size_type length) + { + assert(length <= capacity()); + if (begin_offset_ + length <= capacity()) + { + end_offset_ = begin_offset_ + length; + } + else + { + using namespace std; // For memmove. + memmove(&buffer_[0], &buffer_[0] + begin_offset_, size()); + end_offset_ = length; + begin_offset_ = 0; + } + } + + // Return the maximum size for data in the buffer. + size_type capacity() const + { + return buffer_.size(); + } + + // Consume multiple bytes from the beginning of the buffer. + void consume(size_type count) + { + assert(begin_offset_ + count <= end_offset_); + begin_offset_ += count; + if (empty()) + clear(); + } + +private: + // The offset to the beginning of the unread data. + size_type begin_offset_; + + // The offset to the end of the unread data. + size_type end_offset_; + + // The data in the buffer. + std::vector buffer_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP diff --git a/thirdparty/boost/asio/detail/call_stack.hpp b/thirdparty/boost/asio/detail/call_stack.hpp new file mode 100644 index 0000000..55c097f --- /dev/null +++ b/thirdparty/boost/asio/detail/call_stack.hpp @@ -0,0 +1,92 @@ +// +// call_stack.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_CALL_STACK_HPP +#define BOOST_ASIO_DETAIL_CALL_STACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// Helper class to determine whether or not the current thread is inside an +// invocation of io_service::run() for a specified io_service object. +template +class call_stack +{ +public: + // Context class automatically pushes an owner on to the stack. + class context + : private noncopyable + { + public: + // Push the owner on to the stack. + explicit context(Owner* d) + : owner_(d), + next_(call_stack::top_) + { + call_stack::top_ = this; + } + + // Pop the owner from the stack. + ~context() + { + call_stack::top_ = next_; + } + + private: + friend class call_stack; + + // The owner associated with the context. + Owner* owner_; + + // The next element in the stack. + context* next_; + }; + + friend class context; + + // Determine whether the specified owner is on the stack. + static bool contains(Owner* d) + { + context* elem = top_; + while (elem) + { + if (elem->owner_ == d) + return true; + elem = elem->next_; + } + return false; + } + +private: + // The top of the stack of calls for the current thread. + static tss_ptr top_; +}; + +template +tss_ptr::context> +call_stack::top_; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_CALL_STACK_HPP diff --git a/thirdparty/boost/asio/detail/const_buffers_iterator.hpp b/thirdparty/boost/asio/detail/const_buffers_iterator.hpp new file mode 100644 index 0000000..c09e546 --- /dev/null +++ b/thirdparty/boost/asio/detail/const_buffers_iterator.hpp @@ -0,0 +1,153 @@ +// +// const_buffers_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP +#define BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +// A proxy iterator for a sub-range in a list of buffers. +template +class const_buffers_iterator + : public boost::iterator_facade, + const char, boost::bidirectional_traversal_tag> +{ +public: + // Default constructor creates an iterator in an undefined state. + const_buffers_iterator() + { + } + + // Create an iterator for the specified position. + const_buffers_iterator(const ConstBufferSequence& buffers, + std::size_t position) + : begin_(buffers.begin()), + current_(buffers.begin()), + end_(buffers.end()), + position_(0) + { + while (current_ != end_) + { + current_buffer_ = *current_; + std::size_t buffer_size = boost::asio::buffer_size(current_buffer_); + if (position - position_ < buffer_size) + { + current_buffer_position_ = position - position_; + position_ = position; + return; + } + position_ += buffer_size; + ++current_; + } + current_buffer_ = boost::asio::const_buffer(); + current_buffer_position_ = 0; + } + + std::size_t position() const + { + return position_; + } + +private: + friend class boost::iterator_core_access; + + void increment() + { + if (current_ == end_) + return; + + ++position_; + + ++current_buffer_position_; + if (current_buffer_position_ != boost::asio::buffer_size(current_buffer_)) + return; + + ++current_; + current_buffer_position_ = 0; + while (current_ != end_) + { + current_buffer_ = *current_; + if (boost::asio::buffer_size(current_buffer_) > 0) + return; + ++current_; + } + } + + void decrement() + { + if (position_ == 0) + return; + + --position_; + + if (current_buffer_position_ != 0) + { + --current_buffer_position_; + return; + } + + typename ConstBufferSequence::const_iterator iter = current_; + while (iter != begin_) + { + --iter; + boost::asio::const_buffer buffer = *iter; + std::size_t buffer_size = boost::asio::buffer_size(buffer); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size - 1; + return; + } + } + } + + bool equal(const const_buffers_iterator& other) const + { + return position_ == other.position_; + } + + const char& dereference() const + { + return boost::asio::buffer_cast( + current_buffer_)[current_buffer_position_]; + } + + boost::asio::const_buffer current_buffer_; + std::size_t current_buffer_position_; + typename ConstBufferSequence::const_iterator begin_; + typename ConstBufferSequence::const_iterator current_; + typename ConstBufferSequence::const_iterator end_; + std::size_t position_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP diff --git a/thirdparty/boost/asio/detail/consuming_buffers.hpp b/thirdparty/boost/asio/detail/consuming_buffers.hpp new file mode 100644 index 0000000..09eac75 --- /dev/null +++ b/thirdparty/boost/asio/detail/consuming_buffers.hpp @@ -0,0 +1,207 @@ +// +// consuming_buffers.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP +#define BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// A proxy iterator for a sub-range in a list of buffers. +template +class consuming_buffers_iterator + : public boost::iterator_facade< + consuming_buffers_iterator, + const Buffer, boost::forward_traversal_tag> +{ +public: + // Default constructor creates an end iterator. + consuming_buffers_iterator() + : at_end_(true) + { + } + + // Construct with a buffer for the first entry and an iterator + // range for the remaining entries. + consuming_buffers_iterator(bool at_end, const Buffer& first, + Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder) + : at_end_(at_end), + first_(buffer(first, max_size)), + begin_remainder_(begin_remainder), + end_remainder_(end_remainder), + offset_(0) + { + } + +private: + friend class boost::iterator_core_access; + + enum { max_size = 65536 }; + + void increment() + { + if (!at_end_) + { + if (begin_remainder_ == end_remainder_ + || offset_ + buffer_size(first_) >= max_size) + { + at_end_ = true; + } + else + { + offset_ += buffer_size(first_); + first_ = buffer(*begin_remainder_++, max_size - offset_); + } + } + } + + bool equal(const consuming_buffers_iterator& other) const + { + if (at_end_ && other.at_end_) + return true; + return !at_end_ && !other.at_end_ + && buffer_cast(first_) + == buffer_cast(other.first_) + && buffer_size(first_) == buffer_size(other.first_) + && begin_remainder_ == other.begin_remainder_ + && end_remainder_ == other.end_remainder_; + } + + const Buffer& dereference() const + { + return first_; + } + + bool at_end_; + Buffer first_; + Buffer_Iterator begin_remainder_; + Buffer_Iterator end_remainder_; + std::size_t offset_; +}; + +// A proxy for a sub-range in a list of buffers. +template +class consuming_buffers +{ +public: + // The type for each element in the list of buffers. + typedef Buffer value_type; + + // A forward-only iterator type that may be used to read elements. + typedef consuming_buffers_iterator + const_iterator; + + // Construct to represent the entire list of buffers. + consuming_buffers(const Buffers& buffers) + : buffers_(buffers), + at_end_(buffers_.begin() == buffers_.end()), + first_(*buffers_.begin()), + begin_remainder_(buffers_.begin()) + { + if (!at_end_) + ++begin_remainder_; + } + + // Copy constructor. + consuming_buffers(const consuming_buffers& other) + : buffers_(other.buffers_), + at_end_(other.at_end_), + first_(other.first_), + begin_remainder_(buffers_.begin()) + { + typename Buffers::const_iterator first = other.buffers_.begin(); + typename Buffers::const_iterator second = other.begin_remainder_; + std::advance(begin_remainder_, std::distance(first, second)); + } + + // Assignment operator. + consuming_buffers& operator=(const consuming_buffers& other) + { + buffers_ = other.buffers_; + at_end_ = other.at_end_; + first_ = other.first_; + begin_remainder_ = buffers_.begin(); + typename Buffers::const_iterator first = other.buffers_.begin(); + typename Buffers::const_iterator second = other.begin_remainder_; + std::advance(begin_remainder_, std::distance(first, second)); + return *this; + } + + // Get a forward-only iterator to the first element. + const_iterator begin() const + { + return const_iterator(at_end_, first_, begin_remainder_, buffers_.end()); + } + + // Get a forward-only iterator for one past the last element. + const_iterator end() const + { + return const_iterator(); + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + // Remove buffers from the start until the specified size is reached. + while (size > 0 && !at_end_) + { + if (buffer_size(first_) <= size) + { + size -= buffer_size(first_); + if (begin_remainder_ == buffers_.end()) + at_end_ = true; + else + first_ = *begin_remainder_++; + } + else + { + first_ = first_ + size; + size = 0; + } + } + + // Remove any more empty buffers at the start. + while (!at_end_ && buffer_size(first_) == 0) + { + if (begin_remainder_ == buffers_.end()) + at_end_ = true; + else + first_ = *begin_remainder_++; + } + } + +private: + Buffers buffers_; + bool at_end_; + Buffer first_; + typename Buffers::const_iterator begin_remainder_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP diff --git a/thirdparty/boost/asio/detail/deadline_timer_service.hpp b/thirdparty/boost/asio/detail/deadline_timer_service.hpp new file mode 100644 index 0000000..dfafd78 --- /dev/null +++ b/thirdparty/boost/asio/detail/deadline_timer_service.hpp @@ -0,0 +1,201 @@ +// +// deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP +#define BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class deadline_timer_service + : public boost::asio::detail::service_base< + deadline_timer_service > +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // The implementation type of the timer. This type is dependent on the + // underlying implementation of the timer service. + struct implementation_type + : private boost::asio::detail::noncopyable + { + time_type expiry; + bool might_have_pending_waits; + }; + + // Constructor. + deadline_timer_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + deadline_timer_service >(io_service), + scheduler_(boost::asio::use_service(io_service)) + { + scheduler_.add_timer_queue(timer_queue_); + } + + // Destructor. + ~deadline_timer_service() + { + scheduler_.remove_timer_queue(timer_queue_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new timer implementation. + void construct(implementation_type& impl) + { + impl.expiry = time_type(); + impl.might_have_pending_waits = false; + } + + // Destroy a timer implementation. + void destroy(implementation_type& impl) + { + boost::system::error_code ec; + cancel(impl, ec); + } + + // Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, boost::system::error_code& ec) + { + if (!impl.might_have_pending_waits) + { + ec = boost::system::error_code(); + return 0; + } + std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl); + impl.might_have_pending_waits = false; + ec = boost::system::error_code(); + return count; + } + + // Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return impl.expiry; + } + + // Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, boost::system::error_code& ec) + { + std::size_t count = cancel(impl, ec); + impl.expiry = expiry_time; + ec = boost::system::error_code(); + return count; + } + + // Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return Time_Traits::subtract(expires_at(impl), Time_Traits::now()); + } + + // Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, boost::system::error_code& ec) + { + return expires_at(impl, + Time_Traits::add(Time_Traits::now(), expiry_time), ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, boost::system::error_code& ec) + { + time_type now = Time_Traits::now(); + while (Time_Traits::less_than(now, impl.expiry)) + { + boost::posix_time::time_duration timeout = + Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now)); + ::timeval tv; + tv.tv_sec = timeout.total_seconds(); + tv.tv_usec = timeout.total_microseconds() % 1000000; + boost::system::error_code ec; + socket_ops::select(0, 0, 0, 0, &tv, ec); + now = Time_Traits::now(); + } + ec = boost::system::error_code(); + } + + template + class wait_handler + { + public: + wait_handler(boost::asio::io_service& io_service, Handler handler) + : io_service_(io_service), + work_(io_service), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& result) + { + io_service_.post(detail::bind_handler(handler_, result)); + } + + private: + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + Handler handler_; + }; + + // Start an asynchronous wait on the timer. + template + void async_wait(implementation_type& impl, Handler handler) + { + impl.might_have_pending_waits = true; + scheduler_.schedule_timer(timer_queue_, impl.expiry, + wait_handler(this->get_io_service(), handler), &impl); + } + +private: + // The queue of timers. + timer_queue timer_queue_; + + // The object that schedules and executes timers. Usually a reactor. + Timer_Scheduler& scheduler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/dev_poll_reactor.hpp b/thirdparty/boost/asio/detail/dev_poll_reactor.hpp new file mode 100644 index 0000000..f5302cd --- /dev/null +++ b/thirdparty/boost/asio/detail/dev_poll_reactor.hpp @@ -0,0 +1,649 @@ +// +// dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP +#define BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_ASIO_HAS_DEV_POLL) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class dev_poll_reactor + : public boost::asio::detail::service_base > +{ +public: + // Constructor. + dev_poll_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + dev_poll_reactor >(io_service), + mutex_(), + dev_poll_fd_(do_dev_poll_create()), + wait_in_progress_(false), + interrupter_(), + read_op_queue_(), + write_op_queue_(), + except_op_queue_(), + pending_cancellations_(), + stop_thread_(false), + thread_(0), + shutdown_(false) + { + // Start the reactor's internal thread only if needed. + if (Own_Thread) + { + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread( + bind_handler(&dev_poll_reactor::call_run_thread, this)); + } + + // Add the interrupter's descriptor to /dev/poll. + ::pollfd ev = { 0 }; + ev.fd = interrupter_.read_descriptor(); + ev.events = POLLIN | POLLERR; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); + } + + // Destructor. + ~dev_poll_reactor() + { + shutdown_service(); + ::close(dev_poll_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + lock.unlock(); + + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } + + read_op_queue_.destroy_operations(); + write_op_queue_.destroy_operations(); + except_op_queue_.destroy_operations(); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->destroy_timers(); + timer_queues_.clear(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type descriptor) + { + return 0; + } + + // Start a new read operation. The handler object will be invoked when the + // given descriptor is ready to be read, or an error has occurred. + template + void start_read_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!read_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (read_op_queue_.enqueue_operation(descriptor, handler)) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLIN | POLLERR | POLLHUP; + if (write_op_queue_.has_operation(descriptor)) + ev.events |= POLLOUT; + if (except_op_queue_.has_operation(descriptor)) + ev.events |= POLLPRI; + interrupter_.interrupt(); + } + } + + // Start a new write operation. The handler object will be invoked when the + // given descriptor is ready to be written, or an error has occurred. + template + void start_write_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!write_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (write_op_queue_.enqueue_operation(descriptor, handler)) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLOUT | POLLERR | POLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= POLLIN; + if (except_op_queue_.has_operation(descriptor)) + ev.events |= POLLPRI; + interrupter_.interrupt(); + } + } + + // Start a new exception operation. The handler object will be invoked when + // the given descriptor has exception information, or an error has occurred. + template + void start_except_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (except_op_queue_.enqueue_operation(descriptor, handler)) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLPRI | POLLERR | POLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= POLLIN; + if (write_op_queue_.has_operation(descriptor)) + ev.events |= POLLOUT; + interrupter_.interrupt(); + } + } + + // Start new write and exception operations. The handler object will be + // invoked when the given descriptor is ready for writing or has exception + // information available, or an error has occurred. + template + void start_write_and_except_ops(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler); + need_mod = except_op_queue_.enqueue_operation(descriptor, handler) + && need_mod; + if (need_mod) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= POLLIN; + interrupter_.interrupt(); + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor); + } + + // Enqueue cancellation of all operations associated with the given + // descriptor. The handlers associated with the descriptor will be invoked + // with the operation_aborted error. This function does not acquire the + // dev_poll_reactor's mutex, and so should only be used from within a reactor + // handler. + void enqueue_cancel_ops_unlocked(socket_type descriptor) + { + pending_cancellations_.push_back(descriptor); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Remove the descriptor from /dev/poll. + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLREMOVE; + interrupter_.interrupt(); + + // Cancel any outstanding operations associated with the descriptor. + cancel_ops_unlocked(descriptor); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.push_back(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + if (timer_queues_[i] == &timer_queue) + { + timer_queues_.erase(timer_queues_.begin() + i); + return; + } + } + } + + // Schedule a timer in the given timer queue to expire at the specified + // absolute time. The handler object will be invoked when the timer expires. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, Handler handler, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (timer_queue.enqueue_timer(time, handler, token)) + interrupter_.interrupt(); + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + std::size_t n = timer_queue.cancel_timer(token); + if (n > 0) + interrupter_.interrupt(); + return n; + } + +private: + friend class task_io_service >; + + // Run /dev/poll once until interrupted or events are ready to be dispatched. + void run(bool block) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Dispatch any operation cancellations that were made while the select + // loop was not running. + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->dispatch_cancellations(); + + // Check if the thread is supposed to stop. + if (stop_thread_) + { + cleanup_operations_and_timers(lock); + return; + } + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && read_op_queue_.empty() && write_op_queue_.empty() + && except_op_queue_.empty() && all_timer_queues_are_empty()) + { + cleanup_operations_and_timers(lock); + return; + } + + // Write the pending event registration changes to the /dev/poll descriptor. + std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size(); + errno = 0; + int result = ::write(dev_poll_fd_, + &pending_event_changes_[0], events_size); + if (result != static_cast(events_size)) + { + for (std::size_t i = 0; i < pending_event_changes_.size(); ++i) + { + int descriptor = pending_event_changes_[i].fd; + boost::system::error_code ec = boost::system::error_code( + errno, boost::asio::error::get_system_category()); + read_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + pending_event_changes_.clear(); + pending_event_change_index_.clear(); + + int timeout = block ? get_timeout() : 0; + wait_in_progress_ = true; + lock.unlock(); + + // Block on the /dev/poll descriptor. + ::pollfd events[128] = { { 0 } }; + ::dvpoll dp = { 0 }; + dp.dp_fds = events; + dp.dp_nfds = 128; + dp.dp_timeout = timeout; + int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp); + + lock.lock(); + wait_in_progress_ = false; + + // Block signals while dispatching operations. + boost::asio::detail::signal_blocker sb; + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].fd; + if (descriptor == interrupter_.read_descriptor()) + { + interrupter_.reset(); + } + else + { + bool more_reads = false; + bool more_writes = false; + bool more_except = false; + boost::system::error_code ec; + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + if (events[i].events & (POLLPRI | POLLERR | POLLHUP)) + more_except = except_op_queue_.dispatch_operation(descriptor, ec); + else + more_except = except_op_queue_.has_operation(descriptor); + + if (events[i].events & (POLLIN | POLLERR | POLLHUP)) + more_reads = read_op_queue_.dispatch_operation(descriptor, ec); + else + more_reads = read_op_queue_.has_operation(descriptor); + + if (events[i].events & (POLLOUT | POLLERR | POLLHUP)) + more_writes = write_op_queue_.dispatch_operation(descriptor, ec); + else + more_writes = write_op_queue_.has_operation(descriptor); + + if ((events[i].events == POLLHUP) + && !more_except && !more_reads && !more_writes) + { + // If we have only an POLLHUP event and no operations associated + // with the descriptor then we need to delete the descriptor from + // /dev/poll. The poll operation might produce POLLHUP events even + // if they are not specifically requested, so if we do not remove the + // descriptor we can end up in a tight polling loop. + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLREMOVE; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); + } + else + { + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLERR | POLLHUP; + if (more_reads) + ev.events |= POLLIN; + if (more_writes) + ev.events |= POLLOUT; + if (more_except) + ev.events |= POLLPRI; + ev.revents = 0; + int result = ::write(dev_poll_fd_, &ev, sizeof(ev)); + if (result != sizeof(ev)) + { + ec = boost::system::error_code(errno, + boost::asio::error::get_system_category()); + read_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + } + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + timer_queues_[i]->dispatch_timers(); + timer_queues_[i]->dispatch_cancellations(); + } + + // Issue any pending cancellations. + for (size_t i = 0; i < pending_cancellations_.size(); ++i) + cancel_ops_unlocked(pending_cancellations_[i]); + pending_cancellations_.clear(); + + cleanup_operations_and_timers(lock); + } + + // Run the select loop in the thread. + void run_thread() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + run(true); + lock.lock(); + } + } + + // Entry point for the select loop thread. + static void call_run_thread(dev_poll_reactor* reactor) + { + reactor->run_thread(); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + + // Create the /dev/poll file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_dev_poll_create() + { + int fd = ::open("/dev/poll", O_RDWR); + if (fd == -1) + { + boost::throw_exception( + boost::system::system_error( + boost::system::error_code(errno, + boost::asio::error::get_system_category()), + "/dev/poll")); + } + return fd; + } + + // Check if all timer queues are empty. + bool all_timer_queues_are_empty() const + { + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + if (!timer_queues_[i]->empty()) + return false; + return true; + } + + // Get the timeout value for the /dev/poll DP_POLL operation. The timeout + // value is returned as a number of milliseconds. A return value of -1 + // indicates that the poll should block indefinitely. + int get_timeout() + { + if (all_timer_queues_are_empty()) + return -1; + + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + boost::posix_time::time_duration minimum_wait_duration + = boost::posix_time::minutes(5); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + boost::posix_time::time_duration wait_duration + = timer_queues_[i]->wait_duration(); + if (wait_duration < minimum_wait_duration) + minimum_wait_duration = wait_duration; + } + + if (minimum_wait_duration > boost::posix_time::time_duration()) + { + int milliseconds = minimum_wait_duration.total_milliseconds(); + return milliseconds > 0 ? milliseconds : 1; + } + else + { + return 0; + } + } + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the dev_poll_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor) + { + bool interrupt = read_op_queue_.cancel_operations(descriptor); + interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt; + interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt; + if (interrupt) + interrupter_.interrupt(); + } + + // Clean up operations and timers. We must not hold the lock since the + // destructors may make calls back into this reactor. We make a copy of the + // vector of timer queues since the original may be modified while the lock + // is not held. + void cleanup_operations_and_timers( + boost::asio::detail::mutex::scoped_lock& lock) + { + timer_queues_for_cleanup_ = timer_queues_; + lock.unlock(); + read_op_queue_.cleanup_operations(); + write_op_queue_.cleanup_operations(); + except_op_queue_.cleanup_operations(); + for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i) + timer_queues_for_cleanup_[i]->cleanup_timers(); + } + + // Add a pending event entry for the given descriptor. + ::pollfd& add_pending_event_change(int descriptor) + { + hash_map::iterator iter + = pending_event_change_index_.find(descriptor); + if (iter == pending_event_change_index_.end()) + { + std::size_t index = pending_event_changes_.size(); + pending_event_changes_.reserve(pending_event_changes_.size() + 1); + pending_event_change_index_.insert(std::make_pair(descriptor, index)); + pending_event_changes_.push_back(::pollfd()); + pending_event_changes_[index].fd = descriptor; + pending_event_changes_[index].revents = 0; + return pending_event_changes_[index]; + } + else + { + return pending_event_changes_[iter->second]; + } + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // The /dev/poll file descriptor. + int dev_poll_fd_; + + // Vector of /dev/poll events waiting to be written to the descriptor. + std::vector< ::pollfd> pending_event_changes_; + + // Hash map to associate a descriptor with a pending event change index. + hash_map pending_event_change_index_; + + // Whether the DP_POLL operation is currently in progress + bool wait_in_progress_; + + // The interrupter is used to break a blocking DP_POLL operation. + select_interrupter interrupter_; + + // The queue of read operations. + reactor_op_queue read_op_queue_; + + // The queue of write operations. + reactor_op_queue write_op_queue_; + + // The queue of except operations. + reactor_op_queue except_op_queue_; + + // The timer queues. + std::vector timer_queues_; + + // A copy of the timer queues, used when cleaning up timers. The copy is + // stored as a class data member to avoid unnecessary memory allocation. + std::vector timer_queues_for_cleanup_; + + // The descriptors that are pending cancellation. + std::vector pending_cancellations_; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + boost::asio::detail::thread* thread_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_DEV_POLL) + +#include + +#endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP diff --git a/thirdparty/boost/asio/detail/dev_poll_reactor_fwd.hpp b/thirdparty/boost/asio/detail/dev_poll_reactor_fwd.hpp new file mode 100644 index 0000000..4a102ce --- /dev/null +++ b/thirdparty/boost/asio/detail/dev_poll_reactor_fwd.hpp @@ -0,0 +1,42 @@ +// +// dev_poll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP +#define BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_DISABLE_DEV_POLL) +#if defined(__sun) // This service is only supported on Solaris. + +// Define this to indicate that /dev/poll is supported on the target platform. +#define BOOST_ASIO_HAS_DEV_POLL 1 + +namespace boost { +namespace asio { +namespace detail { + +template +class dev_poll_reactor; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(__sun) +#endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL) + +#include + +#endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP diff --git a/thirdparty/boost/asio/detail/epoll_reactor.hpp b/thirdparty/boost/asio/detail/epoll_reactor.hpp new file mode 100644 index 0000000..e37ed7f --- /dev/null +++ b/thirdparty/boost/asio/detail/epoll_reactor.hpp @@ -0,0 +1,656 @@ +// +// epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP +#define BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_ASIO_HAS_EPOLL) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class epoll_reactor + : public boost::asio::detail::service_base > +{ +public: + // Constructor. + epoll_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base >(io_service), + mutex_(), + epoll_fd_(do_epoll_create()), + wait_in_progress_(false), + interrupter_(), + read_op_queue_(), + write_op_queue_(), + except_op_queue_(), + pending_cancellations_(), + stop_thread_(false), + thread_(0), + shutdown_(false), + need_epoll_wait_(true) + { + // Start the reactor's internal thread only if needed. + if (Own_Thread) + { + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread( + bind_handler(&epoll_reactor::call_run_thread, this)); + } + + // Add the interrupter's descriptor to epoll. + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR; + ev.data.fd = interrupter_.read_descriptor(); + epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); + } + + // Destructor. + ~epoll_reactor() + { + shutdown_service(); + close(epoll_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + lock.unlock(); + + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } + + read_op_queue_.destroy_operations(); + write_op_queue_.destroy_operations(); + except_op_queue_.destroy_operations(); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->destroy_timers(); + timer_queues_.clear(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type descriptor) + { + // No need to lock according to epoll documentation. + + epoll_event ev = { 0, { 0 } }; + ev.events = 0; + ev.data.fd = descriptor; + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + return errno; + return 0; + } + + // Start a new read operation. The handler object will be invoked when the + // given descriptor is ready to be read, or an error has occurred. + template + void start_read_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!read_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (read_op_queue_.enqueue_operation(descriptor, handler)) + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP; + if (write_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLOUT; + if (except_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLPRI; + ev.data.fd = descriptor; + + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + if (result != 0 && errno == ENOENT) + result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + read_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start a new write operation. The handler object will be invoked when the + // given descriptor is ready to be written, or an error has occurred. + template + void start_write_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!write_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (write_op_queue_.enqueue_operation(descriptor, handler)) + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLIN; + if (except_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLPRI; + ev.data.fd = descriptor; + + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + if (result != 0 && errno == ENOENT) + result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start a new exception operation. The handler object will be invoked when + // the given descriptor has exception information, or an error has occurred. + template + void start_except_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (except_op_queue_.enqueue_operation(descriptor, handler)) + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLPRI | EPOLLERR | EPOLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLIN; + if (write_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLOUT; + ev.data.fd = descriptor; + + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + if (result != 0 && errno == ENOENT) + result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start new write and exception operations. The handler object will be + // invoked when the given descriptor is ready for writing or has exception + // information available, or an error has occurred. + template + void start_write_and_except_ops(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler); + need_mod = except_op_queue_.enqueue_operation(descriptor, handler) + && need_mod; + if (need_mod) + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP; + if (read_op_queue_.has_operation(descriptor)) + ev.events |= EPOLLIN; + ev.data.fd = descriptor; + + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + if (result != 0 && errno == ENOENT) + result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor); + } + + // Enqueue cancellation of all operations associated with the given + // descriptor. The handlers associated with the descriptor will be invoked + // with the operation_aborted error. This function does not acquire the + // epoll_reactor's mutex, and so should only be used from within a reactor + // handler. + void enqueue_cancel_ops_unlocked(socket_type descriptor) + { + pending_cancellations_.push_back(descriptor); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Remove the descriptor from epoll. + epoll_event ev = { 0, { 0 } }; + epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev); + + // Cancel any outstanding operations associated with the descriptor. + cancel_ops_unlocked(descriptor); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.push_back(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + if (timer_queues_[i] == &timer_queue) + { + timer_queues_.erase(timer_queues_.begin() + i); + return; + } + } + } + + // Schedule a timer in the given timer queue to expire at the specified + // absolute time. The handler object will be invoked when the timer expires. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, Handler handler, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (timer_queue.enqueue_timer(time, handler, token)) + interrupter_.interrupt(); + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + std::size_t n = timer_queue.cancel_timer(token); + if (n > 0) + interrupter_.interrupt(); + return n; + } + +private: + friend class task_io_service >; + + // Run epoll once until interrupted or events are ready to be dispatched. + void run(bool block) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Dispatch any operation cancellations that were made while the select + // loop was not running. + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->dispatch_cancellations(); + + // Check if the thread is supposed to stop. + if (stop_thread_) + { + cleanup_operations_and_timers(lock); + return; + } + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && read_op_queue_.empty() && write_op_queue_.empty() + && except_op_queue_.empty() && all_timer_queues_are_empty()) + { + cleanup_operations_and_timers(lock); + return; + } + + int timeout = block ? get_timeout() : 0; + wait_in_progress_ = true; + lock.unlock(); + + // Block on the epoll descriptor. + epoll_event events[128]; + int num_events = (block || need_epoll_wait_) + ? epoll_wait(epoll_fd_, events, 128, timeout) + : 0; + + lock.lock(); + wait_in_progress_ = false; + + // Block signals while dispatching operations. + boost::asio::detail::signal_blocker sb; + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].data.fd; + if (descriptor == interrupter_.read_descriptor()) + { + interrupter_.reset(); + } + else + { + bool more_reads = false; + bool more_writes = false; + bool more_except = false; + boost::system::error_code ec; + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)) + more_except = except_op_queue_.dispatch_operation(descriptor, ec); + else + more_except = except_op_queue_.has_operation(descriptor); + + if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) + more_reads = read_op_queue_.dispatch_operation(descriptor, ec); + else + more_reads = read_op_queue_.has_operation(descriptor); + + if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) + more_writes = write_op_queue_.dispatch_operation(descriptor, ec); + else + more_writes = write_op_queue_.has_operation(descriptor); + + if ((events[i].events == EPOLLHUP) + && !more_except && !more_reads && !more_writes) + { + // If we have only an EPOLLHUP event and no operations associated + // with the descriptor then we need to delete the descriptor from + // epoll. The epoll_wait system call will produce EPOLLHUP events + // even if they are not specifically requested, so if we do not + // remove the descriptor we can end up in a tight loop of repeated + // calls to epoll_wait. + epoll_event ev = { 0, { 0 } }; + epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev); + } + else + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLERR | EPOLLHUP; + if (more_reads) + ev.events |= EPOLLIN; + if (more_writes) + ev.events |= EPOLLOUT; + if (more_except) + ev.events |= EPOLLPRI; + ev.data.fd = descriptor; + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + if (result != 0 && errno == ENOENT) + result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + { + ec = boost::system::error_code(errno, + boost::asio::error::get_system_category()); + read_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + } + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + timer_queues_[i]->dispatch_timers(); + timer_queues_[i]->dispatch_cancellations(); + } + + // Issue any pending cancellations. + for (size_t i = 0; i < pending_cancellations_.size(); ++i) + cancel_ops_unlocked(pending_cancellations_[i]); + pending_cancellations_.clear(); + + // Determine whether epoll_wait should be called when the reactor next runs. + need_epoll_wait_ = !read_op_queue_.empty() + || !write_op_queue_.empty() || !except_op_queue_.empty(); + + cleanup_operations_and_timers(lock); + } + + // Run the select loop in the thread. + void run_thread() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + run(true); + lock.lock(); + } + } + + // Entry point for the select loop thread. + static void call_run_thread(epoll_reactor* reactor) + { + reactor->run_thread(); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + + // The hint to pass to epoll_create to size its data structures. + enum { epoll_size = 20000 }; + + // Create the epoll file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_epoll_create() + { + int fd = epoll_create(epoll_size); + if (fd == -1) + { + boost::throw_exception( + boost::system::system_error( + boost::system::error_code(errno, + boost::asio::error::get_system_category()), + "epoll")); + } + return fd; + } + + // Check if all timer queues are empty. + bool all_timer_queues_are_empty() const + { + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + if (!timer_queues_[i]->empty()) + return false; + return true; + } + + // Get the timeout value for the epoll_wait call. The timeout value is + // returned as a number of milliseconds. A return value of -1 indicates + // that epoll_wait should block indefinitely. + int get_timeout() + { + if (all_timer_queues_are_empty()) + return -1; + + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + boost::posix_time::time_duration minimum_wait_duration + = boost::posix_time::minutes(5); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + boost::posix_time::time_duration wait_duration + = timer_queues_[i]->wait_duration(); + if (wait_duration < minimum_wait_duration) + minimum_wait_duration = wait_duration; + } + + if (minimum_wait_duration > boost::posix_time::time_duration()) + { + int milliseconds = minimum_wait_duration.total_milliseconds(); + return milliseconds > 0 ? milliseconds : 1; + } + else + { + return 0; + } + } + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the epoll_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor) + { + bool interrupt = read_op_queue_.cancel_operations(descriptor); + interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt; + interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt; + if (interrupt) + interrupter_.interrupt(); + } + + // Clean up operations and timers. We must not hold the lock since the + // destructors may make calls back into this reactor. We make a copy of the + // vector of timer queues since the original may be modified while the lock + // is not held. + void cleanup_operations_and_timers( + boost::asio::detail::mutex::scoped_lock& lock) + { + timer_queues_for_cleanup_ = timer_queues_; + lock.unlock(); + read_op_queue_.cleanup_operations(); + write_op_queue_.cleanup_operations(); + except_op_queue_.cleanup_operations(); + for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i) + timer_queues_for_cleanup_[i]->cleanup_timers(); + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // The epoll file descriptor. + int epoll_fd_; + + // Whether the epoll_wait call is currently in progress + bool wait_in_progress_; + + // The interrupter is used to break a blocking epoll_wait call. + select_interrupter interrupter_; + + // The queue of read operations. + reactor_op_queue read_op_queue_; + + // The queue of write operations. + reactor_op_queue write_op_queue_; + + // The queue of except operations. + reactor_op_queue except_op_queue_; + + // The timer queues. + std::vector timer_queues_; + + // A copy of the timer queues, used when cleaning up timers. The copy is + // stored as a class data member to avoid unnecessary memory allocation. + std::vector timer_queues_for_cleanup_; + + // The descriptors that are pending cancellation. + std::vector pending_cancellations_; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + boost::asio::detail::thread* thread_; + + // Whether the service has been shut down. + bool shutdown_; + + // Whether we need to call epoll_wait the next time the reactor is run. + bool need_epoll_wait_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_EPOLL) + +#include + +#endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP diff --git a/thirdparty/boost/asio/detail/epoll_reactor_fwd.hpp b/thirdparty/boost/asio/detail/epoll_reactor_fwd.hpp new file mode 100644 index 0000000..809c70d --- /dev/null +++ b/thirdparty/boost/asio/detail/epoll_reactor_fwd.hpp @@ -0,0 +1,49 @@ +// +// epoll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP +#define BOOST_ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_DISABLE_EPOLL) +#if defined(__linux__) // This service is only supported on Linux. + +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45. + +// Define this to indicate that epoll is supported on the target platform. +#define BOOST_ASIO_HAS_EPOLL 1 + +namespace boost { +namespace asio { +namespace detail { + +template +class epoll_reactor; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) +#endif // defined(__linux__) +#endif // !defined(BOOST_ASIO_DISABLE_EPOLL) + +#include + +#endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP diff --git a/thirdparty/boost/asio/detail/event.hpp b/thirdparty/boost/asio/detail/event.hpp new file mode 100644 index 0000000..e06edd4 --- /dev/null +++ b/thirdparty/boost/asio/detail/event.hpp @@ -0,0 +1,52 @@ +// +// event.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_EVENT_HPP +#define BOOST_ASIO_DETAIL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_WINDOWS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#else +# error Only Windows and POSIX are supported! +#endif + +namespace boost { +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) +typedef null_event event; +#elif defined(BOOST_WINDOWS) +typedef win_event event; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_event event; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_EVENT_HPP diff --git a/thirdparty/boost/asio/detail/fd_set_adapter.hpp b/thirdparty/boost/asio/detail/fd_set_adapter.hpp new file mode 100644 index 0000000..b365b27 --- /dev/null +++ b/thirdparty/boost/asio/detail/fd_set_adapter.hpp @@ -0,0 +1,43 @@ +// +// fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP +#define BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef win_fd_set_adapter fd_set_adapter; +#else +typedef posix_fd_set_adapter fd_set_adapter; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP diff --git a/thirdparty/boost/asio/detail/handler_alloc_helpers.hpp b/thirdparty/boost/asio/detail/handler_alloc_helpers.hpp new file mode 100644 index 0000000..1fd39e5 --- /dev/null +++ b/thirdparty/boost/asio/detail/handler_alloc_helpers.hpp @@ -0,0 +1,258 @@ +// +// handler_alloc_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP +#define BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include + +// Calls to asio_handler_allocate and asio_handler_deallocate must be made from +// a namespace that does not contain any overloads of these functions. The +// boost_asio_handler_alloc_helpers namespace is defined here for that purpose. +namespace boost_asio_handler_alloc_helpers { + +template +inline void* allocate(std::size_t s, Handler* h) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + return ::operator new(s); +#else + using namespace boost::asio; + return asio_handler_allocate(s, h); +#endif +} + +template +inline void deallocate(void* p, std::size_t s, Handler* h) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + ::operator delete(p); +#else + using namespace boost::asio; + asio_handler_deallocate(p, s, h); +#endif +} + +} // namespace boost_asio_handler_alloc_helpers + +namespace boost { +namespace asio { +namespace detail { + +// Traits for handler allocation. +template +struct handler_alloc_traits +{ + typedef Handler handler_type; + typedef Object value_type; + typedef Object* pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object)); +}; + +template +class handler_ptr; + +// Helper class to provide RAII on uninitialised handler memory. +template +class raw_handler_ptr + : private noncopyable +{ +public: + typedef typename Alloc_Traits::handler_type handler_type; + typedef typename Alloc_Traits::value_type value_type; + typedef typename Alloc_Traits::pointer_type pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); + + // Constructor allocates the memory. + raw_handler_ptr(handler_type& handler) + : handler_(handler), + pointer_(static_cast( + boost_asio_handler_alloc_helpers::allocate(value_size, &handler_))) + { + } + + // Destructor automatically deallocates memory, unless it has been stolen by + // a handler_ptr object. + ~raw_handler_ptr() + { + if (pointer_) + boost_asio_handler_alloc_helpers::deallocate( + pointer_, value_size, &handler_); + } + +private: + friend class handler_ptr; + handler_type& handler_; + pointer_type pointer_; +}; + +// Helper class to provide RAII on uninitialised handler memory. +template +class handler_ptr + : private noncopyable +{ +public: + typedef typename Alloc_Traits::handler_type handler_type; + typedef typename Alloc_Traits::value_type value_type; + typedef typename Alloc_Traits::pointer_type pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); + typedef raw_handler_ptr raw_ptr_type; + + // Take ownership of existing memory. + handler_ptr(handler_type& handler, pointer_type pointer) + : handler_(handler), + pointer_(pointer) + { + } + + // Construct object in raw memory and take ownership if construction succeeds. + handler_ptr(raw_ptr_type& raw_ptr) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6, Arg7& a7) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type( + a1, a2, a3, a4, a5, a6, a7, a8)) + { + raw_ptr.pointer_ = 0; + } + + // Destructor automatically deallocates memory, unless it has been released. + ~handler_ptr() + { + reset(); + } + + // Get the memory. + pointer_type get() const + { + return pointer_; + } + + // Release ownership of the memory. + pointer_type release() + { + pointer_type tmp = pointer_; + pointer_ = 0; + return tmp; + } + + // Explicitly destroy and deallocate the memory. + void reset() + { + if (pointer_) + { + pointer_->value_type::~value_type(); + boost_asio_handler_alloc_helpers::deallocate( + pointer_, value_size, &handler_); + pointer_ = 0; + } + } + +private: + handler_type& handler_; + pointer_type pointer_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP diff --git a/thirdparty/boost/asio/detail/handler_invoke_helpers.hpp b/thirdparty/boost/asio/detail/handler_invoke_helpers.hpp new file mode 100644 index 0000000..cca70df --- /dev/null +++ b/thirdparty/boost/asio/detail/handler_invoke_helpers.hpp @@ -0,0 +1,47 @@ +// +// handler_invoke_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP +#define BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include + +// Calls to asio_handler_invoke must be made from a namespace that does not +// contain overloads of this function. The boost_asio_handler_invoke_helpers +// namespace is defined here for that purpose. +namespace boost_asio_handler_invoke_helpers { + +template +inline void invoke(const Function& function, Context* context) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + Function tmp(function); + tmp(); +#else + using namespace boost::asio; + asio_handler_invoke(function, context); +#endif +} + +} // namespace boost_asio_handler_invoke_helpers + +#include + +#endif // BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP diff --git a/thirdparty/boost/asio/detail/handler_queue.hpp b/thirdparty/boost/asio/detail/handler_queue.hpp new file mode 100644 index 0000000..97c2940 --- /dev/null +++ b/thirdparty/boost/asio/detail/handler_queue.hpp @@ -0,0 +1,221 @@ +// +// handler_queue.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP +#define BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class handler_queue + : private noncopyable +{ +public: + // Base class for handlers in the queue. + class handler + : private noncopyable + { + public: + void invoke() + { + invoke_func_(this); + } + + void destroy() + { + destroy_func_(this); + } + + protected: + typedef void (*invoke_func_type)(handler*); + typedef void (*destroy_func_type)(handler*); + + handler(invoke_func_type invoke_func, + destroy_func_type destroy_func) + : next_(0), + invoke_func_(invoke_func), + destroy_func_(destroy_func) + { + } + + ~handler() + { + } + + private: + friend class handler_queue; + handler* next_; + invoke_func_type invoke_func_; + destroy_func_type destroy_func_; + }; + + // Smart point to manager handler lifetimes. + class scoped_ptr + : private noncopyable + { + public: + explicit scoped_ptr(handler* h) + : handler_(h) + { + } + + ~scoped_ptr() + { + if (handler_) + handler_->destroy(); + } + + handler* get() const + { + return handler_; + } + + handler* release() + { + handler* tmp = handler_; + handler_ = 0; + return tmp; + } + + private: + handler* handler_; + }; + + // Constructor. + handler_queue() + : front_(0), + back_(0) + { + } + + // Wrap a handler to be pushed into the queue. + template + static handler* wrap(Handler h) + { + // Allocate and construct an object to wrap the handler. + typedef handler_wrapper value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(h); + handler_ptr ptr(raw_ptr, h); + return ptr.release(); + } + + // Get the handler at the front of the queue. + handler* front() + { + return front_; + } + + // Pop a handler from the front of the queue. + void pop() + { + if (front_) + { + handler* tmp = front_; + front_ = front_->next_; + if (front_ == 0) + back_ = 0; + tmp->next_= 0; + } + } + + // Push a handler on to the back of the queue. + void push(handler* h) + { + h->next_ = 0; + if (back_) + { + back_->next_ = h; + back_ = h; + } + else + { + front_ = back_ = h; + } + } + + // Whether the queue is empty. + bool empty() const + { + return front_ == 0; + } + +private: + // Template wrapper for handlers. + template + class handler_wrapper + : public handler + { + public: + handler_wrapper(Handler h) + : handler( + &handler_wrapper::do_call, + &handler_wrapper::do_destroy), + handler_(h) + { + } + + static void do_call(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(h->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Make the upcall. + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + } + + static void do_destroy(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + } + + private: + Handler handler_; + }; + + // The front of the queue. + handler* front_; + + // The back of the queue. + handler* back_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP diff --git a/thirdparty/boost/asio/detail/hash_map.hpp b/thirdparty/boost/asio/detail/hash_map.hpp new file mode 100644 index 0000000..25703f9 --- /dev/null +++ b/thirdparty/boost/asio/detail/hash_map.hpp @@ -0,0 +1,211 @@ +// +// hash_map.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_HASH_MAP_HPP +#define BOOST_ASIO_DETAIL_HASH_MAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +inline std::size_t calculate_hash_value(const T& t) +{ + return boost::hash_value(t); +} + +#if defined(_WIN64) +inline std::size_t calculate_hash_value(SOCKET s) +{ + return static_cast(s); +} +#endif // defined(_WIN64) + +template +class hash_map + : private noncopyable +{ +public: + // The type of a value in the map. + typedef std::pair value_type; + + // The type of a non-const iterator over the hash map. + typedef typename std::list::iterator iterator; + + // The type of a const iterator over the hash map. + typedef typename std::list::const_iterator const_iterator; + + // Constructor. + hash_map() + { + // Initialise all buckets to empty. + for (size_t i = 0; i < num_buckets; ++i) + buckets_[i].first = buckets_[i].last = values_.end(); + } + + // Get an iterator for the beginning of the map. + iterator begin() + { + return values_.begin(); + } + + // Get an iterator for the beginning of the map. + const_iterator begin() const + { + return values_.begin(); + } + + // Get an iterator for the end of the map. + iterator end() + { + return values_.end(); + } + + // Get an iterator for the end of the map. + const_iterator end() const + { + return values_.end(); + } + + // Check whether the map is empty. + bool empty() const + { + return values_.empty(); + } + + // Find an entry in the map. + iterator find(const K& k) + { + size_t bucket = calculate_hash_value(k) % num_buckets; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + return values_.end(); + iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == k) + return it; + ++it; + } + return values_.end(); + } + + // Find an entry in the map. + const_iterator find(const K& k) const + { + size_t bucket = calculate_hash_value(k) % num_buckets; + const_iterator it = buckets_[bucket].first; + if (it == values_.end()) + return it; + const_iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == k) + return it; + ++it; + } + return values_.end(); + } + + // Insert a new entry into the map. + std::pair insert(const value_type& v) + { + size_t bucket = calculate_hash_value(v.first) % num_buckets; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + { + buckets_[bucket].first = buckets_[bucket].last = + values_.insert(values_.end(), v); + return std::pair(buckets_[bucket].last, true); + } + iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == v.first) + return std::pair(it, false); + ++it; + } + buckets_[bucket].last = values_.insert(end, v); + return std::pair(buckets_[bucket].last, true); + } + + // Erase an entry from the map. + void erase(iterator it) + { + assert(it != values_.end()); + + size_t bucket = calculate_hash_value(it->first) % num_buckets; + bool is_first = (it == buckets_[bucket].first); + bool is_last = (it == buckets_[bucket].last); + if (is_first && is_last) + buckets_[bucket].first = buckets_[bucket].last = values_.end(); + else if (is_first) + ++buckets_[bucket].first; + else if (is_last) + --buckets_[bucket].last; + + values_.erase(it); + } + + // Remove all entries from the map. + void clear() + { + // Clear the values. + values_.clear(); + + // Initialise all buckets to empty. + for (size_t i = 0; i < num_buckets; ++i) + buckets_[i].first = buckets_[i].last = values_.end(); + } + +private: + // The list of all values in the hash map. + std::list values_; + + // The type for a bucket in the hash table. + struct bucket_type + { + iterator first; + iterator last; + }; + + // The number of buckets in the hash. + enum { num_buckets = 1021 }; + + // The buckets in the hash. + bucket_type buckets_[num_buckets]; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_HASH_MAP_HPP diff --git a/thirdparty/boost/asio/detail/io_control.hpp b/thirdparty/boost/asio/detail/io_control.hpp new file mode 100644 index 0000000..395d83a --- /dev/null +++ b/thirdparty/boost/asio/detail/io_control.hpp @@ -0,0 +1,139 @@ +// +// io_control.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_IO_CONTROL_HPP +#define BOOST_ASIO_DETAIL_IO_CONTROL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace io_control { + +// IO control command for non-blocking I/O. +class non_blocking_io +{ +public: + // Default constructor. + non_blocking_io() + : value_(0) + { + } + + // Construct with a specific command value. + non_blocking_io(bool value) + : value_(value ? 1 : 0) + { + } + + // Get the name of the IO control command. + int name() const + { + return FIONBIO; + } + + // Set the value of the I/O control command. + void set(bool value) + { + value_ = value ? 1 : 0; + } + + // Get the current value of the I/O control command. + bool get() const + { + return value_ != 0; + } + + // Get the address of the command data. + detail::ioctl_arg_type* data() + { + return &value_; + } + + // Get the address of the command data. + const detail::ioctl_arg_type* data() const + { + return &value_; + } + +private: + detail::ioctl_arg_type value_; +}; + +// I/O control command for getting number of bytes available. +class bytes_readable +{ +public: + // Default constructor. + bytes_readable() + : value_(0) + { + } + + // Construct with a specific command value. + bytes_readable(std::size_t value) + : value_(static_cast(value)) + { + } + + // Get the name of the IO control command. + int name() const + { + return FIONREAD; + } + + // Set the value of the I/O control command. + void set(std::size_t value) + { + value_ = static_cast(value); + } + + // Get the current value of the I/O control command. + std::size_t get() const + { + return static_cast(value_); + } + + // Get the address of the command data. + detail::ioctl_arg_type* data() + { + return &value_; + } + + // Get the address of the command data. + const detail::ioctl_arg_type* data() const + { + return &value_; + } + +private: + detail::ioctl_arg_type value_; +}; + +} // namespace io_control +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_IO_CONTROL_HPP diff --git a/thirdparty/boost/asio/detail/kqueue_reactor.hpp b/thirdparty/boost/asio/detail/kqueue_reactor.hpp new file mode 100644 index 0000000..2f39e6a --- /dev/null +++ b/thirdparty/boost/asio/detail/kqueue_reactor.hpp @@ -0,0 +1,654 @@ +// +// kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze 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) +// + +#ifndef BOOST_ASIO_DETAIL_KQUEUE_REACTOR_HPP +#define BOOST_ASIO_DETAIL_KQUEUE_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_ASIO_HAS_KQUEUE) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Older versions of Mac OS X may not define EV_OOBAND. +#if !defined(EV_OOBAND) +# define EV_OOBAND EV_FLAG1 +#endif // !defined(EV_OOBAND) + +namespace boost { +namespace asio { +namespace detail { + +template +class kqueue_reactor + : public boost::asio::detail::service_base > +{ +public: + // Constructor. + kqueue_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + kqueue_reactor >(io_service), + mutex_(), + kqueue_fd_(do_kqueue_create()), + wait_in_progress_(false), + interrupter_(), + read_op_queue_(), + write_op_queue_(), + except_op_queue_(), + pending_cancellations_(), + stop_thread_(false), + thread_(0), + shutdown_(false), + need_kqueue_wait_(true) + { + // Start the reactor's internal thread only if needed. + if (Own_Thread) + { + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread( + bind_handler(&kqueue_reactor::call_run_thread, this)); + } + + // Add the interrupter's descriptor to the kqueue. + struct kevent event; + EV_SET(&event, interrupter_.read_descriptor(), + EVFILT_READ, EV_ADD, 0, 0, 0); + ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); + } + + // Destructor. + ~kqueue_reactor() + { + shutdown_service(); + close(kqueue_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + lock.unlock(); + + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } + + read_op_queue_.destroy_operations(); + write_op_queue_.destroy_operations(); + except_op_queue_.destroy_operations(); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->destroy_timers(); + timer_queues_.clear(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type) + { + return 0; + } + + // Start a new read operation. The handler object will be invoked when the + // given descriptor is ready to be read, or an error has occurred. + template + void start_read_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!read_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (read_op_queue_.enqueue_operation(descriptor, handler)) + { + struct kevent event; + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + read_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start a new write operation. The handler object will be invoked when the + // given descriptor is ready to be written, or an error has occurred. + template + void start_write_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (!write_op_queue_.has_operation(descriptor)) + if (handler(boost::system::error_code())) + return; + + if (write_op_queue_.enqueue_operation(descriptor, handler)) + { + struct kevent event; + EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start a new exception operation. The handler object will be invoked when + // the given descriptor has exception information, or an error has occurred. + template + void start_except_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (except_op_queue_.enqueue_operation(descriptor, handler)) + { + struct kevent event; + if (read_op_queue_.has_operation(descriptor)) + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0); + else + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + except_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Start new write and exception operations. The handler object will be + // invoked when the given descriptor is ready for writing or has exception + // information available, or an error has occurred. + template + void start_write_and_except_ops(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (write_op_queue_.enqueue_operation(descriptor, handler)) + { + struct kevent event; + EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + + if (except_op_queue_.enqueue_operation(descriptor, handler)) + { + struct kevent event; + if (read_op_queue_.has_operation(descriptor)) + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0); + else + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + except_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); + } + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor); + } + + // Enqueue cancellation of all operations associated with the given + // descriptor. The handlers associated with the descriptor will be invoked + // with the operation_aborted error. This function does not acquire the + // kqueue_reactor's mutex, and so should only be used from within a reactor + // handler. + void enqueue_cancel_ops_unlocked(socket_type descriptor) + { + pending_cancellations_.push_back(descriptor); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Remove the descriptor from kqueue. + struct kevent event[2]; + EV_SET(&event[0], descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0); + EV_SET(&event[1], descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + ::kevent(kqueue_fd_, event, 2, 0, 0, 0); + + // Cancel any outstanding operations associated with the descriptor. + cancel_ops_unlocked(descriptor); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.push_back(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + if (timer_queues_[i] == &timer_queue) + { + timer_queues_.erase(timer_queues_.begin() + i); + return; + } + } + } + + // Schedule a timer in the given timer queue to expire at the specified + // absolute time. The handler object will be invoked when the timer expires. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, Handler handler, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (timer_queue.enqueue_timer(time, handler, token)) + interrupter_.interrupt(); + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + std::size_t n = timer_queue.cancel_timer(token); + if (n > 0) + interrupter_.interrupt(); + return n; + } + +private: + friend class task_io_service >; + + // Run the kqueue loop. + void run(bool block) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Dispatch any operation cancellations that were made while the select + // loop was not running. + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->dispatch_cancellations(); + + // Check if the thread is supposed to stop. + if (stop_thread_) + { + cleanup_operations_and_timers(lock); + return; + } + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && read_op_queue_.empty() && write_op_queue_.empty() + && except_op_queue_.empty() && all_timer_queues_are_empty()) + { + cleanup_operations_and_timers(lock); + return; + } + + // Determine how long to block while waiting for events. + timespec timeout_buf = { 0, 0 }; + timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf; + + wait_in_progress_ = true; + lock.unlock(); + + // Block on the kqueue descriptor. + struct kevent events[128]; + int num_events = (block || need_kqueue_wait_) + ? kevent(kqueue_fd_, 0, 0, events, 128, timeout) + : 0; + + lock.lock(); + wait_in_progress_ = false; + + // Block signals while dispatching operations. + boost::asio::detail::signal_blocker sb; + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].ident; + if (descriptor == interrupter_.read_descriptor()) + { + interrupter_.reset(); + } + else if (events[i].filter == EVFILT_READ) + { + // Dispatch operations associated with the descriptor. + bool more_reads = false; + bool more_except = false; + if (events[i].flags & EV_ERROR) + { + boost::system::error_code error( + events[i].data, boost::asio::error::get_system_category()); + except_op_queue_.dispatch_all_operations(descriptor, error); + read_op_queue_.dispatch_all_operations(descriptor, error); + } + else if (events[i].flags & EV_OOBAND) + { + boost::system::error_code error; + more_except = except_op_queue_.dispatch_operation(descriptor, error); + if (events[i].data > 0) + more_reads = read_op_queue_.dispatch_operation(descriptor, error); + else + more_reads = read_op_queue_.has_operation(descriptor); + } + else + { + boost::system::error_code error; + more_reads = read_op_queue_.dispatch_operation(descriptor, error); + more_except = except_op_queue_.has_operation(descriptor); + } + + // Update the descriptor in the kqueue. + struct kevent event; + if (more_reads) + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0); + else if (more_except) + EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0); + else + EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + except_op_queue_.dispatch_all_operations(descriptor, error); + read_op_queue_.dispatch_all_operations(descriptor, error); + } + } + else if (events[i].filter == EVFILT_WRITE) + { + // Dispatch operations associated with the descriptor. + bool more_writes = false; + if (events[i].flags & EV_ERROR) + { + boost::system::error_code error( + events[i].data, boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, error); + } + else + { + boost::system::error_code error; + more_writes = write_op_queue_.dispatch_operation(descriptor, error); + } + + // Update the descriptor in the kqueue. + struct kevent event; + if (more_writes) + EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0); + else + EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + write_op_queue_.dispatch_all_operations(descriptor, error); + } + } + } + + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + timer_queues_[i]->dispatch_timers(); + timer_queues_[i]->dispatch_cancellations(); + } + + // Issue any pending cancellations. + for (std::size_t i = 0; i < pending_cancellations_.size(); ++i) + cancel_ops_unlocked(pending_cancellations_[i]); + pending_cancellations_.clear(); + + // Determine whether kqueue needs to be called next time the reactor is run. + need_kqueue_wait_ = !read_op_queue_.empty() + || !write_op_queue_.empty() || !except_op_queue_.empty(); + + cleanup_operations_and_timers(lock); + } + + // Run the select loop in the thread. + void run_thread() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + run(true); + lock.lock(); + } + } + + // Entry point for the select loop thread. + static void call_run_thread(kqueue_reactor* reactor) + { + reactor->run_thread(); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + + // Create the kqueue file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_kqueue_create() + { + int fd = kqueue(); + if (fd == -1) + { + boost::throw_exception( + boost::system::system_error( + boost::system::error_code(errno, + boost::asio::error::get_system_category()), + "kqueue")); + } + return fd; + } + + // Check if all timer queues are empty. + bool all_timer_queues_are_empty() const + { + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + if (!timer_queues_[i]->empty()) + return false; + return true; + } + + // Get the timeout value for the kevent call. + timespec* get_timeout(timespec& ts) + { + if (all_timer_queues_are_empty()) + return 0; + + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + boost::posix_time::time_duration minimum_wait_duration + = boost::posix_time::minutes(5); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + boost::posix_time::time_duration wait_duration + = timer_queues_[i]->wait_duration(); + if (wait_duration < minimum_wait_duration) + minimum_wait_duration = wait_duration; + } + + if (minimum_wait_duration > boost::posix_time::time_duration()) + { + ts.tv_sec = minimum_wait_duration.total_seconds(); + ts.tv_nsec = minimum_wait_duration.total_nanoseconds() % 1000000000; + } + else + { + ts.tv_sec = 0; + ts.tv_nsec = 0; + } + + return &ts; + } + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the kqueue_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor) + { + bool interrupt = read_op_queue_.cancel_operations(descriptor); + interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt; + interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt; + if (interrupt) + interrupter_.interrupt(); + } + + // Clean up operations and timers. We must not hold the lock since the + // destructors may make calls back into this reactor. We make a copy of the + // vector of timer queues since the original may be modified while the lock + // is not held. + void cleanup_operations_and_timers( + boost::asio::detail::mutex::scoped_lock& lock) + { + timer_queues_for_cleanup_ = timer_queues_; + lock.unlock(); + read_op_queue_.cleanup_operations(); + write_op_queue_.cleanup_operations(); + except_op_queue_.cleanup_operations(); + for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i) + timer_queues_for_cleanup_[i]->cleanup_timers(); + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // The kqueue file descriptor. + int kqueue_fd_; + + // Whether the kqueue wait call is currently in progress + bool wait_in_progress_; + + // The interrupter is used to break a blocking kevent call. + select_interrupter interrupter_; + + // The queue of read operations. + reactor_op_queue read_op_queue_; + + // The queue of write operations. + reactor_op_queue write_op_queue_; + + // The queue of except operations. + reactor_op_queue except_op_queue_; + + // The timer queues. + std::vector timer_queues_; + + // A copy of the timer queues, used when cleaning up timers. The copy is + // stored as a class data member to avoid unnecessary memory allocation. + std::vector timer_queues_for_cleanup_; + + // The descriptors that are pending cancellation. + std::vector pending_cancellations_; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + boost::asio::detail::thread* thread_; + + // Whether the service has been shut down. + bool shutdown_; + + // Whether we need to call kqueue the next time the reactor is run. + bool need_kqueue_wait_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_KQUEUE) + +#include + +#endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_HPP diff --git a/thirdparty/boost/asio/detail/kqueue_reactor_fwd.hpp b/thirdparty/boost/asio/detail/kqueue_reactor_fwd.hpp new file mode 100644 index 0000000..f4d8ec0 --- /dev/null +++ b/thirdparty/boost/asio/detail/kqueue_reactor_fwd.hpp @@ -0,0 +1,43 @@ +// +// kqueue_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze 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) +// + +#ifndef BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP +#define BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_DISABLE_KQUEUE) +#if defined(__MACH__) && defined(__APPLE__) + +// Define this to indicate that epoll is supported on the target platform. +#define BOOST_ASIO_HAS_KQUEUE 1 + +namespace boost { +namespace asio { +namespace detail { + +template +class kqueue_reactor; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(__MACH__) && defined(__APPLE__) +#endif // !defined(BOOST_ASIO_DISABLE_KQUEUE) + +#include + +#endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP diff --git a/thirdparty/boost/asio/detail/local_free_on_block_exit.hpp b/thirdparty/boost/asio/detail/local_free_on_block_exit.hpp new file mode 100644 index 0000000..8e45ad7 --- /dev/null +++ b/thirdparty/boost/asio/detail/local_free_on_block_exit.hpp @@ -0,0 +1,61 @@ +// +// local_free_on_block_exit.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP +#define BOOST_ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class local_free_on_block_exit + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + explicit local_free_on_block_exit(void* p) + : p_(p) + { + } + + // Destructor restores the previous signal mask. + ~local_free_on_block_exit() + { + ::LocalFree(p_); + } + +private: + void* p_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP diff --git a/thirdparty/boost/asio/detail/mutex.hpp b/thirdparty/boost/asio/detail/mutex.hpp new file mode 100644 index 0000000..5d5340d --- /dev/null +++ b/thirdparty/boost/asio/detail/mutex.hpp @@ -0,0 +1,52 @@ +// +// mutex.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_MUTEX_HPP +#define BOOST_ASIO_DETAIL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_WINDOWS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#else +# error Only Windows and POSIX are supported! +#endif + +namespace boost { +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) +typedef null_mutex mutex; +#elif defined(BOOST_WINDOWS) +typedef win_mutex mutex; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_mutex mutex; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_MUTEX_HPP diff --git a/thirdparty/boost/asio/detail/noncopyable.hpp b/thirdparty/boost/asio/detail/noncopyable.hpp new file mode 100644 index 0000000..9534965 --- /dev/null +++ b/thirdparty/boost/asio/detail/noncopyable.hpp @@ -0,0 +1,57 @@ +// +// noncopyable.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NONCOPYABLE_HPP +#define BOOST_ASIO_DETAIL_NONCOPYABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +// Redefine the noncopyable class for Borland C++ since that compiler does not +// apply the empty base optimisation unless the base class contains a dummy +// char data member. +class noncopyable +{ +protected: + noncopyable() {} + ~noncopyable() {} +private: + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); + char dummy_; +}; +#else +using boost::noncopyable; +#endif + +} // namespace detail + +using boost::asio::detail::noncopyable; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_NONCOPYABLE_HPP diff --git a/thirdparty/boost/asio/detail/null_event.hpp b/thirdparty/boost/asio/detail/null_event.hpp new file mode 100644 index 0000000..c238315 --- /dev/null +++ b/thirdparty/boost/asio/detail/null_event.hpp @@ -0,0 +1,73 @@ +// +// null_event.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NULL_EVENT_HPP +#define BOOST_ASIO_DETAIL_NULL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class null_event + : private noncopyable +{ +public: + // Constructor. + null_event() + { + } + + // Destructor. + ~null_event() + { + } + + // Signal the event. + template + void signal(Lock&) + { + } + + // Reset the event. + template + void clear(Lock&) + { + } + + // Wait for the event to become signalled. + template + void wait(Lock&) + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_HAS_THREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_NULL_EVENT_HPP diff --git a/thirdparty/boost/asio/detail/null_mutex.hpp b/thirdparty/boost/asio/detail/null_mutex.hpp new file mode 100644 index 0000000..45fbce8 --- /dev/null +++ b/thirdparty/boost/asio/detail/null_mutex.hpp @@ -0,0 +1,68 @@ +// +// null_mutex.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NULL_MUTEX_HPP +#define BOOST_ASIO_DETAIL_NULL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class null_mutex + : private noncopyable +{ +public: + typedef boost::asio::detail::scoped_lock scoped_lock; + + // Constructor. + null_mutex() + { + } + + // Destructor. + ~null_mutex() + { + } + + // Lock the mutex. + void lock() + { + } + + // Unlock the mutex. + void unlock() + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_HAS_THREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_NULL_MUTEX_HPP diff --git a/thirdparty/boost/asio/detail/null_signal_blocker.hpp b/thirdparty/boost/asio/detail/null_signal_blocker.hpp new file mode 100644 index 0000000..1f49257 --- /dev/null +++ b/thirdparty/boost/asio/detail/null_signal_blocker.hpp @@ -0,0 +1,65 @@ +// +// null_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP +#define BOOST_ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class null_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + null_signal_blocker() + { + } + + // Destructor restores the previous signal mask. + ~null_signal_blocker() + { + } + + // Block all signals for the calling thread. + void block() + { + } + + // Restore the previous signal mask. + void unblock() + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_HAS_THREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP diff --git a/thirdparty/boost/asio/detail/null_thread.hpp b/thirdparty/boost/asio/detail/null_thread.hpp new file mode 100644 index 0000000..6cfc54d --- /dev/null +++ b/thirdparty/boost/asio/detail/null_thread.hpp @@ -0,0 +1,70 @@ +// +// null_thread.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NULL_THREAD_HPP +#define BOOST_ASIO_DETAIL_NULL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class null_thread + : private noncopyable +{ +public: + // Constructor. + template + null_thread(Function f) + { + boost::system::system_error e( + boost::asio::error::operation_not_supported, "thread"); + boost::throw_exception(e); + } + + // Destructor. + ~null_thread() + { + } + + // Wait for the thread to exit. + void join() + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_HAS_THREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_NULL_THREAD_HPP diff --git a/thirdparty/boost/asio/detail/null_tss_ptr.hpp b/thirdparty/boost/asio/detail/null_tss_ptr.hpp new file mode 100644 index 0000000..5be6961 --- /dev/null +++ b/thirdparty/boost/asio/detail/null_tss_ptr.hpp @@ -0,0 +1,72 @@ +// +// null_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_NULL_TSS_PTR_HPP +#define BOOST_ASIO_DETAIL_NULL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class null_tss_ptr + : private noncopyable +{ +public: + // Constructor. + null_tss_ptr() + : value_(0) + { + } + + // Destructor. + ~null_tss_ptr() + { + } + + // Get the value. + operator T*() const + { + return value_; + } + + // Set the value. + void operator=(T* value) + { + value_ = value; + } + +private: + T* value_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_HAS_THREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_NULL_TSS_PTR_HPP diff --git a/thirdparty/boost/asio/detail/old_win_sdk_compat.hpp b/thirdparty/boost/asio/detail/old_win_sdk_compat.hpp new file mode 100644 index 0000000..3ba763e --- /dev/null +++ b/thirdparty/boost/asio/detail/old_win_sdk_compat.hpp @@ -0,0 +1,337 @@ +// +// old_win_sdk_compat.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP +#define BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Guess whether we are building against on old Platform SDK. +#if !defined(IN6ADDR_ANY_INIT) +#define BOOST_ASIO_HAS_OLD_WIN_SDK 1 +#endif // !defined(IN6ADDR_ANY_INIT) + +#if defined(BOOST_ASIO_HAS_OLD_WIN_SDK) + +// Emulation of types that are missing from old Platform SDKs. +// +// N.B. this emulation is also used if building for a Windows 2000 target with +// a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support +// in that case. + +namespace boost { +namespace asio { +namespace detail { + +enum +{ + sockaddr_storage_maxsize = 128, // Maximum size. + sockaddr_storage_alignsize = (sizeof(__int64)), // Desired alignment. + sockaddr_storage_pad1size = (sockaddr_storage_alignsize - sizeof(short)), + sockaddr_storage_pad2size = (sockaddr_storage_maxsize - + (sizeof(short) + sockaddr_storage_pad1size + sockaddr_storage_alignsize)) +}; + +struct sockaddr_storage_emulation +{ + short ss_family; + char __ss_pad1[sockaddr_storage_pad1size]; + __int64 __ss_align; + char __ss_pad2[sockaddr_storage_pad2size]; +}; + +struct in6_addr_emulation +{ + union + { + u_char Byte[16]; + u_short Word[8]; + } u; +}; + +#if !defined(s6_addr) +# define _S6_un u +# define _S6_u8 Byte +# define s6_addr _S6_un._S6_u8 +#endif // !defined(s6_addr) + +struct sockaddr_in6_emulation +{ + short sin6_family; + u_short sin6_port; + u_long sin6_flowinfo; + in6_addr_emulation sin6_addr; + u_long sin6_scope_id; +}; + +struct ipv6_mreq_emulation +{ + in6_addr_emulation ipv6mr_multiaddr; + unsigned int ipv6mr_interface; +}; + +#if !defined(IN6ADDR_ANY_INIT) +# define IN6ADDR_ANY_INIT { 0 } +#endif + +#if !defined(IN6ADDR_LOOPBACK_INIT) +# define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } +#endif + +struct addrinfo_emulation +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char* ai_canonname; + sockaddr* ai_addr; + addrinfo_emulation* ai_next; +}; + +#if !defined(AI_PASSIVE) +# define AI_PASSIVE 0x1 +#endif + +#if !defined(AI_CANONNAME) +# define AI_CANONNAME 0x2 +#endif + +#if !defined(AI_NUMERICHOST) +# define AI_NUMERICHOST 0x4 +#endif + +#if !defined(EAI_AGAIN) +# define EAI_AGAIN WSATRY_AGAIN +#endif + +#if !defined(EAI_BADFLAGS) +# define EAI_BADFLAGS WSAEINVAL +#endif + +#if !defined(EAI_FAIL) +# define EAI_FAIL WSANO_RECOVERY +#endif + +#if !defined(EAI_FAMILY) +# define EAI_FAMILY WSAEAFNOSUPPORT +#endif + +#if !defined(EAI_MEMORY) +# define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY +#endif + +#if !defined(EAI_NODATA) +# define EAI_NODATA WSANO_DATA +#endif + +#if !defined(EAI_NONAME) +# define EAI_NONAME WSAHOST_NOT_FOUND +#endif + +#if !defined(EAI_SERVICE) +# define EAI_SERVICE WSATYPE_NOT_FOUND +#endif + +#if !defined(EAI_SOCKTYPE) +# define EAI_SOCKTYPE WSAESOCKTNOSUPPORT +#endif + +#if !defined(NI_NOFQDN) +# define NI_NOFQDN 0x01 +#endif + +#if !defined(NI_NUMERICHOST) +# define NI_NUMERICHOST 0x02 +#endif + +#if !defined(NI_NAMEREQD) +# define NI_NAMEREQD 0x04 +#endif + +#if !defined(NI_NUMERICSERV) +# define NI_NUMERICSERV 0x08 +#endif + +#if !defined(NI_DGRAM) +# define NI_DGRAM 0x10 +#endif + +#if !defined(IPPROTO_IPV6) +# define IPPROTO_IPV6 41 +#endif + +#if !defined(IPV6_UNICAST_HOPS) +# define IPV6_UNICAST_HOPS 4 +#endif + +#if !defined(IPV6_MULTICAST_IF) +# define IPV6_MULTICAST_IF 9 +#endif + +#if !defined(IPV6_MULTICAST_HOPS) +# define IPV6_MULTICAST_HOPS 10 +#endif + +#if !defined(IPV6_MULTICAST_LOOP) +# define IPV6_MULTICAST_LOOP 11 +#endif + +#if !defined(IPV6_JOIN_GROUP) +# define IPV6_JOIN_GROUP 12 +#endif + +#if !defined(IPV6_LEAVE_GROUP) +# define IPV6_LEAVE_GROUP 13 +#endif + +inline int IN6_IS_ADDR_UNSPECIFIED(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0) + && (a->s6_addr[11] == 0) + && (a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && (a->s6_addr[15] == 0)); +} + +inline int IN6_IS_ADDR_LOOPBACK(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0) + && (a->s6_addr[11] == 0) + && (a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && (a->s6_addr[15] == 1)); +} + +inline int IN6_IS_ADDR_MULTICAST(const in6_addr_emulation* a) +{ + return (a->s6_addr[0] == 0xff); +} + +inline int IN6_IS_ADDR_LINKLOCAL(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0x80)); +} + +inline int IN6_IS_ADDR_SITELOCAL(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0xc0)); +} + +inline int IN6_IS_ADDR_V4MAPPED(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0xff) + && (a->s6_addr[11] == 0xff)); +} + +inline int IN6_IS_ADDR_V4COMPAT(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0xff) + && (a->s6_addr[11] == 0xff) + && !((a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && ((a->s6_addr[15] == 0) || (a->s6_addr[15] == 1)))); +} + +inline int IN6_IS_ADDR_MC_NODELOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 1); +} + +inline int IN6_IS_ADDR_MC_LINKLOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 2); +} + +inline int IN6_IS_ADDR_MC_SITELOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 5); +} + +inline int IN6_IS_ADDR_MC_ORGLOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 8); +} + +inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 0xe); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_OLD_WIN_SDK) + +// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY. +#if !defined(IPV6_V6ONLY) +# define IPV6_V6ONLY 27 +#endif + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP diff --git a/thirdparty/boost/asio/detail/pipe_select_interrupter.hpp b/thirdparty/boost/asio/detail/pipe_select_interrupter.hpp new file mode 100644 index 0000000..88115be --- /dev/null +++ b/thirdparty/boost/asio/detail/pipe_select_interrupter.hpp @@ -0,0 +1,116 @@ +// +// pipe_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP +#define BOOST_ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class pipe_select_interrupter +{ +public: + // Constructor. + pipe_select_interrupter() + { + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::system::system_error e(ec, "pipe_select_interrupter"); + boost::throw_exception(e); + } + } + + // Destructor. + ~pipe_select_interrupter() + { + if (read_descriptor_ != -1) + ::close(read_descriptor_); + if (write_descriptor_ != -1) + ::close(write_descriptor_); + } + + // Interrupt the select call. + void interrupt() + { + char byte = 0; + ::write(write_descriptor_, &byte, 1); + } + + // Reset the select interrupt. Returns true if the call was interrupted. + bool reset() + { + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } + + // Get the read descriptor to be passed to select. + int read_descriptor() const + { + return read_descriptor_; + } + +private: + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + int write_descriptor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP diff --git a/thirdparty/boost/asio/detail/pop_options.hpp b/thirdparty/boost/asio/detail/pop_options.hpp new file mode 100644 index 0000000..6cf2c5e --- /dev/null +++ b/thirdparty/boost/asio/detail/pop_options.hpp @@ -0,0 +1,88 @@ +// +// pop_options.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (pop) +# endif + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option pop +# pragma nopushoptwarn +# pragma nopackwarning + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (pop) +# pragma pack (pop) + +#endif diff --git a/thirdparty/boost/asio/detail/posix_event.hpp b/thirdparty/boost/asio/detail/posix_event.hpp new file mode 100644 index 0000000..72d3ada --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_event.hpp @@ -0,0 +1,106 @@ +// +// posix_event.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_EVENT_HPP +#define BOOST_ASIO_DETAIL_POSIX_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class posix_event + : private noncopyable +{ +public: + // Constructor. + posix_event() + : signalled_(false) + { + int error = ::pthread_cond_init(&cond_, 0); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "event"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_event() + { + ::pthread_cond_destroy(&cond_); + } + + // Signal the event. + template + void signal(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + signalled_ = true; + ::pthread_cond_signal(&cond_); // Ignore EINVAL. + } + + // Reset the event. + template + void clear(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + signalled_ = false; + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + while (!signalled_) + ::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL. + } + +private: + ::pthread_cond_t cond_; + bool signalled_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_HAS_PTHREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_EVENT_HPP diff --git a/thirdparty/boost/asio/detail/posix_fd_set_adapter.hpp b/thirdparty/boost/asio/detail/posix_fd_set_adapter.hpp new file mode 100644 index 0000000..d7a2e55 --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_fd_set_adapter.hpp @@ -0,0 +1,79 @@ +// +// posix_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP +#define BOOST_ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace boost { +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class posix_fd_set_adapter +{ +public: + posix_fd_set_adapter() + : max_descriptor_(invalid_socket) + { + using namespace std; // Needed for memset on Solaris. + FD_ZERO(&fd_set_); + } + + bool set(socket_type descriptor) + { + if (descriptor < (socket_type)FD_SETSIZE) + { + if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_) + max_descriptor_ = descriptor; + FD_SET(descriptor, &fd_set_); + return true; + } + return false; + } + + bool is_set(socket_type descriptor) const + { + return FD_ISSET(descriptor, &fd_set_) != 0; + } + + operator fd_set*() + { + return &fd_set_; + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + +private: + mutable fd_set fd_set_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP diff --git a/thirdparty/boost/asio/detail/posix_mutex.hpp b/thirdparty/boost/asio/detail/posix_mutex.hpp new file mode 100644 index 0000000..e9bba40 --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_mutex.hpp @@ -0,0 +1,109 @@ +// +// posix_mutex.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_MUTEX_HPP +#define BOOST_ASIO_DETAIL_POSIX_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class posix_event; + +class posix_mutex + : private noncopyable +{ +public: + typedef boost::asio::detail::scoped_lock scoped_lock; + + // Constructor. + posix_mutex() + { + int error = ::pthread_mutex_init(&mutex_, 0); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_mutex() + { + ::pthread_mutex_destroy(&mutex_); + } + + // Lock the mutex. + void lock() + { + int error = ::pthread_mutex_lock(&mutex_); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Unlock the mutex. + void unlock() + { + int error = ::pthread_mutex_unlock(&mutex_); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + +private: + friend class posix_event; + ::pthread_mutex_t mutex_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_HAS_PTHREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_MUTEX_HPP diff --git a/thirdparty/boost/asio/detail/posix_signal_blocker.hpp b/thirdparty/boost/asio/detail/posix_signal_blocker.hpp new file mode 100644 index 0000000..caa4ea5 --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_signal_blocker.hpp @@ -0,0 +1,92 @@ +// +// posix_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP +#define BOOST_ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +class posix_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + posix_signal_blocker() + : blocked_(false) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + + // Destructor restores the previous signal mask. + ~posix_signal_blocker() + { + if (blocked_) + pthread_sigmask(SIG_SETMASK, &old_mask_, 0); + } + + // Block all signals for the calling thread. + void block() + { + if (!blocked_) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + } + + // Restore the previous signal mask. + void unblock() + { + if (blocked_) + blocked_ = (pthread_sigmask(SIG_SETMASK, &old_mask_, 0) != 0); + } + +private: + // Have signals been blocked. + bool blocked_; + + // The previous signal mask. + sigset_t old_mask_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_HAS_PTHREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP diff --git a/thirdparty/boost/asio/detail/posix_thread.hpp b/thirdparty/boost/asio/detail/posix_thread.hpp new file mode 100644 index 0000000..dd98792 --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_thread.hpp @@ -0,0 +1,131 @@ +// +// posix_thread.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_THREAD_HPP +#define BOOST_ASIO_DETAIL_POSIX_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +extern "C" void* asio_detail_posix_thread_function(void* arg); + +class posix_thread + : private noncopyable +{ +public: + // Constructor. + template + posix_thread(Function f) + : joined_(false) + { + std::auto_ptr arg(new func(f)); + int error = ::pthread_create(&thread_, 0, + asio_detail_posix_thread_function, arg.get()); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + } + + // Destructor. + ~posix_thread() + { + if (!joined_) + ::pthread_detach(thread_); + } + + // Wait for the thread to exit. + void join() + { + if (!joined_) + { + ::pthread_join(thread_, 0); + joined_ = true; + } + } + +private: + friend void* asio_detail_posix_thread_function(void* arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::pthread_t thread_; + bool joined_; +}; + +inline void* asio_detail_posix_thread_function(void* arg) +{ + std::auto_ptr f( + static_cast(arg)); + f->run(); + return 0; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_HAS_PTHREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_THREAD_HPP diff --git a/thirdparty/boost/asio/detail/posix_tss_ptr.hpp b/thirdparty/boost/asio/detail/posix_tss_ptr.hpp new file mode 100644 index 0000000..db3fd7b --- /dev/null +++ b/thirdparty/boost/asio/detail/posix_tss_ptr.hpp @@ -0,0 +1,90 @@ +// +// posix_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_POSIX_TSS_PTR_HPP +#define BOOST_ASIO_DETAIL_POSIX_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class posix_tss_ptr + : private noncopyable +{ +public: + // Constructor. + posix_tss_ptr() + { + int error = ::pthread_key_create(&tss_key_, 0); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "tss"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_tss_ptr() + { + ::pthread_key_delete(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::pthread_getspecific(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::pthread_setspecific(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + pthread_key_t tss_key_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_HAS_PTHREADS) + +#include + +#endif // BOOST_ASIO_DETAIL_POSIX_TSS_PTR_HPP diff --git a/thirdparty/boost/asio/detail/push_options.hpp b/thirdparty/boost/asio/detail/push_options.hpp new file mode 100644 index 0000000..f835c76 --- /dev/null +++ b/thirdparty/boost/asio/detail/push_options.hpp @@ -0,0 +1,112 @@ +// +// push_options.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (push, 8) +# endif + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option push -a8 -b -Ve- -Vx- -w-inl -vi- +# pragma nopushoptwarn +# pragma nopackwarning +# if !defined(__MT__) +# error Multithreaded RTL must be selected. +# endif // !defined(__MT__) + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (disable:4103) +# pragma warning (push) +# pragma warning (disable:4244) +# pragma warning (disable:4355) +# pragma warning (disable:4675) +# if defined(_M_IX86) && defined(_Wp64) +// The /Wp64 option is broken. If you want to check 64 bit portability, use a +// 64 bit compiler! +# pragma warning (disable:4311) +# pragma warning (disable:4312) +# endif // defined(_M_IX86) && defined(_Wp64) +# pragma pack (push, 8) +// Note that if the /Og optimisation flag is enabled with MSVC6, the compiler +// has a tendency to incorrectly optimise away some calls to member template +// functions, even though those functions contain code that should not be +// optimised away! Therefore we will always disable this optimisation option +// for the MSVC6 compiler. +# if (_MSC_VER < 1300) +# pragma optimize ("g", off) +# endif +# if !defined(_MT) +# error Multithreaded RTL must be selected. +# endif // !defined(_MT) + +#endif diff --git a/thirdparty/boost/asio/detail/reactive_socket_service.hpp b/thirdparty/boost/asio/detail/reactive_socket_service.hpp new file mode 100644 index 0000000..d44ff4e --- /dev/null +++ b/thirdparty/boost/asio/detail/reactive_socket_service.hpp @@ -0,0 +1,1578 @@ +// +// reactive_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_service + : public boost::asio::detail::service_base< + reactive_socket_service > +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef socket_type native_type; + + // The implementation type of the socket. + class implementation_type + : private boost::asio::detail::noncopyable + { + public: + // Default constructor. + implementation_type() + : socket_(invalid_socket), + flags_(0), + protocol_(endpoint_type().protocol()) + { + } + + private: + // Only this service will have access to the internal values. + friend class reactive_socket_service; + + // The native socket representation. + socket_type socket_; + + enum + { + user_set_non_blocking = 1, // The user wants a non-blocking socket. + internal_non_blocking = 2, // The socket has been set non-blocking. + enable_connection_aborted = 4, // User wants connection_aborted errors. + user_set_linger = 8 // The user set the linger option. + }; + + // Flags indicating the current state of the socket. + unsigned char flags_; + + // The protocol associated with the socket. + protocol_type protocol_; + }; + + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + + // Constructor. + reactive_socket_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + reactive_socket_service >(io_service), + reactor_(boost::asio::use_service(io_service)) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new socket implementation. + void construct(implementation_type& impl) + { + impl.socket_ = invalid_socket; + impl.flags_ = 0; + } + + // Destroy a socket implementation. + void destroy(implementation_type& impl) + { + if (impl.socket_ != invalid_socket) + { + reactor_.close_descriptor(impl.socket_); + + if (impl.flags_ & implementation_type::internal_non_blocking) + { + ioctl_arg_type non_blocking = 0; + boost::system::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::internal_non_blocking; + } + + if (impl.flags_ & implementation_type::user_set_linger) + { + ::linger opt; + opt.l_onoff = 0; + opt.l_linger = 0; + boost::system::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); + } + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); + + impl.socket_ = invalid_socket; + } + } + + // Open a new socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(protocol.family(), + protocol.type(), protocol.protocol(), ec)); + if (sock.get() == invalid_socket) + return ec; + + if (int err = reactor_.register_descriptor(sock.get())) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = sock.release(); + impl.flags_ = 0; + impl.protocol_ = protocol; + ec = boost::system::error_code(); + return ec; + } + + // Assign a native socket to a socket implementation. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) + { + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor(native_socket)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = native_socket; + impl.flags_ = 0; + impl.protocol_ = protocol; + ec = boost::system::error_code(); + return ec; + } + + // Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + if (is_open(impl)) + { + reactor_.close_descriptor(impl.socket_); + + if (impl.flags_ & implementation_type::internal_non_blocking) + { + ioctl_arg_type non_blocking = 0; + boost::system::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::internal_non_blocking; + } + + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; + + impl.socket_ = invalid_socket; + } + + ec = boost::system::error_code(); + return ec; + } + + // Get the native socket representation. + native_type native(implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + reactor_.cancel_ops(impl.socket_); + ec = boost::system::error_code(); + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return false; + } + + boost::asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); +#if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = boost::asio::error::not_socket; +#endif // defined(ENOTTY) + return ec ? false : value != 0; + } + + // Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + boost::asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); +#if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = boost::asio::error::not_socket; +#endif // defined(ENOTTY) + return ec ? static_cast(0) : static_cast(value); + } + + // Bind the socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + } + else + { + if (*reinterpret_cast(option.data(impl.protocol_))) + impl.flags_ |= implementation_type::enable_connection_aborted; + else + impl.flags_ &= ~implementation_type::enable_connection_aborted; + ec = boost::system::error_code(); + } + return ec; + } + else + { + if (option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_LINGER) + { + impl.flags_ |= implementation_type::user_set_linger; + } + + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + +#if defined(__MACH__) && defined(__APPLE__) \ +|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + // To implement portable behaviour for SO_REUSEADDR with UDP sockets we + // need to also set SO_REUSEPORT on BSD-based platforms. + if (!ec && impl.protocol_.type() == SOCK_DGRAM + && option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_REUSEADDR) + { + boost::system::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, SOL_SOCKET, SO_REUSEPORT, + option.data(impl.protocol_), option.size(impl.protocol_), + ignored_ec); + } +#endif + + return ec; + } + } + + // Set a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + } + else + { + int* target = reinterpret_cast(option.data(impl.protocol_)); + if (impl.flags_ & implementation_type::enable_connection_aborted) + *target = 1; + else + *target = 0; + option.resize(impl.protocol_, sizeof(int)); + ec = boost::system::error_code(); + } + return ec; + } + else + { + size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + } + + // Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (command.name() == static_cast(FIONBIO)) + { + if (command.get()) + impl.flags_ |= implementation_type::user_set_non_blocking; + else + impl.flags_ &= ~implementation_type::user_set_non_blocking; + ec = boost::system::error_code(); + } + else + { + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); + } + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. + template + size_t send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + ec = boost::system::error_code(); + return 0; + } + + // Make socket non-blocking if user wants non-blocking. + if (impl.flags_ & implementation_type::user_set_non_blocking) + { + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return 0; + impl.flags_ |= implementation_type::internal_non_blocking; + } + } + + // Send the data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_sent = socket_ops::send(impl.socket_, bufs, i, flags, ec); + + // Check if operation succeeded. + if (bytes_sent >= 0) + return bytes_sent; + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(impl.socket_, ec) < 0) + return 0; + } + } + + template + class send_handler + { + public: + send_handler(socket_type socket, boost::asio::io_service& io_service, + const ConstBufferSequence& buffers, socket_base::message_flags flags, + Handler handler) + : socket_(socket), + io_service_(io_service), + work_(io_service), + buffers_(buffers), + flags_(flags), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result, 0)); + return true; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers_.begin(); + typename ConstBufferSequence::const_iterator end = buffers_.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Send the data. + boost::system::error_code ec; + int bytes = socket_ops::send(socket_, bufs, i, flags_, ec); + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); + return true; + } + + private: + socket_type socket_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + ConstBufferSequence buffers_; + socket_base::message_flags flags_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + } + else + { + if (impl.protocol_.type() == SOCK_STREAM) + { + // Determine total size of buffers. + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (total_buffer_size == 0) + { + this->get_io_service().post(bind_handler(handler, + boost::system::error_code(), 0)); + return; + } + } + + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec, 0)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + reactor_.start_write_op(impl.socket_, + send_handler( + impl.socket_, this->get_io_service(), buffers, flags, handler)); + } + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Make socket non-blocking if user wants non-blocking. + if (impl.flags_ & implementation_type::user_set_non_blocking) + { + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return 0; + impl.flags_ |= implementation_type::internal_non_blocking; + } + } + + // Send the data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_sent = socket_ops::sendto(impl.socket_, bufs, i, flags, + destination.data(), destination.size(), ec); + + // Check if operation succeeded. + if (bytes_sent >= 0) + return bytes_sent; + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(impl.socket_, ec) < 0) + return 0; + } + } + + template + class send_to_handler + { + public: + send_to_handler(socket_type socket, boost::asio::io_service& io_service, + const ConstBufferSequence& buffers, const endpoint_type& endpoint, + socket_base::message_flags flags, Handler handler) + : socket_(socket), + io_service_(io_service), + work_(io_service), + buffers_(buffers), + destination_(endpoint), + flags_(flags), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result, 0)); + return true; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers_.begin(); + typename ConstBufferSequence::const_iterator end = buffers_.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Send the data. + boost::system::error_code ec; + int bytes = socket_ops::sendto(socket_, bufs, i, flags_, + destination_.data(), destination_.size(), ec); + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); + return true; + } + + private: + socket_type socket_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + ConstBufferSequence buffers_; + endpoint_type destination_; + socket_base::message_flags flags_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + } + else + { + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec, 0)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + reactor_.start_write_op(impl.socket_, + send_to_handler( + impl.socket_, this->get_io_service(), buffers, + destination, flags, handler)); + } + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + ec = boost::system::error_code(); + return 0; + } + + // Make socket non-blocking if user wants non-blocking. + if (impl.flags_ & implementation_type::user_set_non_blocking) + { + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return 0; + impl.flags_ |= implementation_type::internal_non_blocking; + } + } + + // Receive some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_recvd = socket_ops::recv(impl.socket_, bufs, i, flags, ec); + + // Check if operation succeeded. + if (bytes_recvd > 0) + return bytes_recvd; + + // Check for EOF. + if (bytes_recvd == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return 0; + } + } + + template + class receive_handler + { + public: + receive_handler(socket_type socket, boost::asio::io_service& io_service, + const MutableBufferSequence& buffers, socket_base::message_flags flags, + Handler handler) + : socket_(socket), + io_service_(io_service), + work_(io_service), + buffers_(buffers), + flags_(flags), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result, 0)); + return true; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers_.begin(); + typename MutableBufferSequence::const_iterator end = buffers_.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Receive some data. + boost::system::error_code ec; + int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec); + if (bytes == 0) + ec = boost::asio::error::eof; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); + return true; + } + + private: + socket_type socket_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + MutableBufferSequence buffers_; + socket_base::message_flags flags_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + } + else + { + if (impl.protocol_.type() == SOCK_STREAM) + { + // Determine total size of buffers. + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (total_buffer_size == 0) + { + this->get_io_service().post(bind_handler(handler, + boost::system::error_code(), 0)); + return; + } + } + + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec, 0)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + if (flags & socket_base::message_out_of_band) + { + reactor_.start_except_op(impl.socket_, + receive_handler( + impl.socket_, this->get_io_service(), buffers, flags, handler)); + } + else + { + reactor_.start_read_op(impl.socket_, + receive_handler( + impl.socket_, this->get_io_service(), buffers, flags, handler)); + } + } + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Make socket non-blocking if user wants non-blocking. + if (impl.flags_ & implementation_type::user_set_non_blocking) + { + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return 0; + impl.flags_ |= implementation_type::internal_non_blocking; + } + } + + // Receive some data. + for (;;) + { + // Try to complete the operation without blocking. + std::size_t addr_len = sender_endpoint.capacity(); + int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags, + sender_endpoint.data(), &addr_len, ec); + + // Check if operation succeeded. + if (bytes_recvd > 0) + { + sender_endpoint.resize(addr_len); + return bytes_recvd; + } + + // Check for EOF. + if (bytes_recvd == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return 0; + } + } + + template + class receive_from_handler + { + public: + receive_from_handler(socket_type socket, + boost::asio::io_service& io_service, + const MutableBufferSequence& buffers, endpoint_type& endpoint, + socket_base::message_flags flags, Handler handler) + : socket_(socket), + io_service_(io_service), + work_(io_service), + buffers_(buffers), + sender_endpoint_(endpoint), + flags_(flags), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result, 0)); + return true; + } + + // Copy buffers into array. + socket_ops::buf bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers_.begin(); + typename MutableBufferSequence::const_iterator end = buffers_.end(); + size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + socket_ops::init_buf(bufs[i], + boost::asio::buffer_cast(buffer), + boost::asio::buffer_size(buffer)); + } + + // Receive some data. + std::size_t addr_len = sender_endpoint_.capacity(); + boost::system::error_code ec; + int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_, + sender_endpoint_.data(), &addr_len, ec); + if (bytes == 0) + ec = boost::asio::error::eof; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + sender_endpoint_.resize(addr_len); + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); + return true; + } + + private: + socket_type socket_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + MutableBufferSequence buffers_; + endpoint_type& sender_endpoint_; + socket_base::message_flags flags_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + } + else + { + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec, 0)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + reactor_.start_read_op(impl.socket_, + receive_from_handler( + impl.socket_, this->get_io_service(), buffers, + sender_endpoint, flags, handler)); + } + } + + // Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, + Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = boost::asio::error::already_open; + return ec; + } + + // Make socket non-blocking if user wants non-blocking. + if (impl.flags_ & implementation_type::user_set_non_blocking) + { + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return ec; + impl.flags_ |= implementation_type::internal_non_blocking; + } + } + + // Accept a socket. + for (;;) + { + // Try to complete the operation without blocking. + boost::system::error_code ec; + socket_holder new_socket; + std::size_t addr_len = 0; + if (peer_endpoint) + { + addr_len = peer_endpoint->capacity(); + new_socket.reset(socket_ops::accept(impl.socket_, + peer_endpoint->data(), &addr_len, ec)); + } + else + { + new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); + } + + // Check if operation succeeded. + if (new_socket.get() >= 0) + { + if (peer_endpoint) + peer_endpoint->resize(addr_len); + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + return ec; + } + + // Operation failed. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + { + if (impl.flags_ & implementation_type::user_set_non_blocking) + return ec; + // Fall through to retry operation. + } + else if (ec == boost::asio::error::connection_aborted) + { + if (impl.flags_ & implementation_type::enable_connection_aborted) + return ec; + // Fall through to retry operation. + } +#if defined(EPROTO) + else if (ec.value() == EPROTO) + { + if (impl.flags_ & implementation_type::enable_connection_aborted) + return ec; + // Fall through to retry operation. + } +#endif // defined(EPROTO) + else + return ec; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return ec; + } + } + + template + class accept_handler + { + public: + accept_handler(socket_type socket, boost::asio::io_service& io_service, + Socket& peer, const protocol_type& protocol, + endpoint_type* peer_endpoint, bool enable_connection_aborted, + Handler handler) + : socket_(socket), + io_service_(io_service), + work_(io_service), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result)); + return true; + } + + // Accept the waiting connection. + boost::system::error_code ec; + socket_holder new_socket; + std::size_t addr_len = 0; + if (peer_endpoint_) + { + addr_len = peer_endpoint_->capacity(); + new_socket.reset(socket_ops::accept(socket_, + peer_endpoint_->data(), &addr_len, ec)); + } + else + { + new_socket.reset(socket_ops::accept(socket_, 0, 0, ec)); + } + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + if (ec == boost::asio::error::connection_aborted + && !enable_connection_aborted_) + return false; +#if defined(EPROTO) + if (ec.value() == EPROTO && !enable_connection_aborted_) + return false; +#endif // defined(EPROTO) + + // Transfer ownership of the new socket to the peer object. + if (!ec) + { + if (peer_endpoint_) + peer_endpoint_->resize(addr_len); + peer_.assign(protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + } + + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + private: + socket_type socket_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + Socket& peer_; + protocol_type protocol_; + endpoint_type* peer_endpoint_; + bool enable_connection_aborted_; + Handler handler_; + }; + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); + } + else if (peer.is_open()) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::already_open)); + } + else + { + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + reactor_.start_read_op(impl.socket_, + accept_handler( + impl.socket_, this->get_io_service(), + peer, impl.protocol_, peer_endpoint, + (impl.flags_ & implementation_type::enable_connection_aborted) != 0, + handler)); + } + } + + // Connect the socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (impl.flags_ & implementation_type::internal_non_blocking) + { + // Mark the socket as blocking while we perform the connect. + ioctl_arg_type non_blocking = 0; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return ec; + impl.flags_ &= ~implementation_type::internal_non_blocking; + } + + // Perform the connect operation. + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; + } + + template + class connect_handler + { + public: + connect_handler(socket_type socket, boost::shared_ptr completed, + boost::asio::io_service& io_service, Reactor& reactor, Handler handler) + : socket_(socket), + completed_(completed), + io_service_(io_service), + work_(io_service), + reactor_(reactor), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether a handler has already been called for the connection. + // If it has, then we don't want to do anything in this handler. + if (*completed_) + return true; + + // Cancel the other reactor operation for the connection. + *completed_ = true; + reactor_.enqueue_cancel_ops_unlocked(socket_); + + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result)); + return true; + } + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + boost::system::error_code ec; + if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, ec) == socket_error_retval) + { + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + // If connection failed then post the handler with the error code. + if (connect_error) + { + ec = boost::system::error_code(connect_error, + boost::asio::error::get_system_category()); + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + // Post the result of the successful connection operation. + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + private: + socket_type socket_; + boost::shared_ptr completed_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + Reactor& reactor_; + Handler handler_; + }; + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); + return; + } + + // Make socket non-blocking. + if (!(impl.flags_ & implementation_type::internal_non_blocking)) + { + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec)); + return; + } + impl.flags_ |= implementation_type::internal_non_blocking; + } + + // Start the connect operation. The socket is already marked as non-blocking + // so the connection will take place asynchronously. + boost::system::error_code ec; + if (socket_ops::connect(impl.socket_, peer_endpoint.data(), + peer_endpoint.size(), ec) == 0) + { + // The connect operation has finished successfully so we need to post the + // handler immediately. + this->get_io_service().post(bind_handler(handler, + boost::system::error_code())); + } + else if (ec == boost::asio::error::in_progress + || ec == boost::asio::error::would_block) + { + // The connection is happening in the background, and we need to wait + // until the socket becomes writeable. + boost::shared_ptr completed(new bool(false)); + reactor_.start_write_and_except_ops(impl.socket_, + connect_handler(impl.socket_, completed, + this->get_io_service(), reactor_, handler)); + } + else + { + // The connect operation has failed, so post the handler immediately. + this->get_io_service().post(bind_handler(handler, ec)); + } + } + +private: + // The selector that performs event demultiplexing for the service. + Reactor& reactor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/reactor_op_queue.hpp b/thirdparty/boost/asio/detail/reactor_op_queue.hpp new file mode 100644 index 0000000..eea2658 --- /dev/null +++ b/thirdparty/boost/asio/detail/reactor_op_queue.hpp @@ -0,0 +1,391 @@ +// +// reactor_op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP +#define BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactor_op_queue + : private noncopyable +{ +public: + // Constructor. + reactor_op_queue() + : operations_(), + cancelled_operations_(0), + cleanup_operations_(0) + { + } + + // Add a new operation to the queue. Returns true if this is the only + // operation for the given descriptor, in which case the reactor's event + // demultiplexing function call may need to be interrupted and restarted. + template + bool enqueue_operation(Descriptor descriptor, Handler handler) + { + op_base* new_op = new op(descriptor, handler); + + typedef typename operation_map::iterator iterator; + typedef typename operation_map::value_type value_type; + std::pair entry = + operations_.insert(value_type(descriptor, new_op)); + if (entry.second) + return true; + + op_base* current_op = entry.first->second; + while (current_op->next_) + current_op = current_op->next_; + current_op->next_ = new_op; + + return false; + } + + // Cancel all operations associated with the descriptor. Any operations + // pending for the descriptor will be notified that they have been cancelled + // next time dispatch_cancellations is called. Returns true if any operations + // were cancelled, in which case the reactor's event demultiplexing function + // may need to be interrupted and restarted. + bool cancel_operations(Descriptor descriptor) + { + typename operation_map::iterator i = operations_.find(descriptor); + if (i != operations_.end()) + { + op_base* last_op = i->second; + while (last_op->next_) + last_op = last_op->next_; + last_op->next_ = cancelled_operations_; + cancelled_operations_ = i->second; + operations_.erase(i); + return true; + } + + return false; + } + + // Whether there are no operations in the queue. + bool empty() const + { + return operations_.empty(); + } + + // Determine whether there are any operations associated with the descriptor. + bool has_operation(Descriptor descriptor) const + { + return operations_.find(descriptor) != operations_.end(); + } + + // Dispatch the first operation corresponding to the descriptor. Returns true + // if there are more operations queued for the descriptor. + bool dispatch_operation(Descriptor descriptor, + const boost::system::error_code& result) + { + typename operation_map::iterator i = operations_.find(descriptor); + if (i != operations_.end()) + { + op_base* this_op = i->second; + i->second = this_op->next_; + this_op->next_ = cleanup_operations_; + cleanup_operations_ = this_op; + bool done = this_op->invoke(result); + if (done) + { + // Operation has finished. + if (i->second) + { + return true; + } + else + { + operations_.erase(i); + return false; + } + } + else + { + // Operation wants to be called again. Leave it at the front of the + // queue for this descriptor, and remove from the cleanup list. + cleanup_operations_ = this_op->next_; + this_op->next_ = i->second; + i->second = this_op; + return true; + } + } + return false; + } + + // Dispatch all operations corresponding to the descriptor. + void dispatch_all_operations(Descriptor descriptor, + const boost::system::error_code& result) + { + typename operation_map::iterator i = operations_.find(descriptor); + if (i != operations_.end()) + { + while (i->second) + { + op_base* this_op = i->second; + i->second = this_op->next_; + this_op->next_ = cleanup_operations_; + cleanup_operations_ = this_op; + bool done = this_op->invoke(result); + if (!done) + { + // Operation has not finished yet, so leave at front of queue, and + // remove from the cleanup list. + cleanup_operations_ = this_op->next_; + this_op->next_ = i->second; + i->second = this_op; + return; + } + } + operations_.erase(i); + } + } + + // Fill a descriptor set with the descriptors corresponding to each active + // operation. + template + void get_descriptors(Descriptor_Set& descriptors) + { + typename operation_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + Descriptor descriptor = i->first; + ++i; + if (!descriptors.set(descriptor)) + { + boost::system::error_code ec(error::fd_set_failure); + dispatch_all_operations(descriptor, ec); + } + } + } + + // Dispatch the operations corresponding to the ready file descriptors + // contained in the given descriptor set. + template + void dispatch_descriptors(const Descriptor_Set& descriptors, + const boost::system::error_code& result) + { + typename operation_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + typename operation_map::iterator op_iter = i++; + if (descriptors.is_set(op_iter->first)) + { + op_base* this_op = op_iter->second; + op_iter->second = this_op->next_; + this_op->next_ = cleanup_operations_; + cleanup_operations_ = this_op; + bool done = this_op->invoke(result); + if (done) + { + if (!op_iter->second) + operations_.erase(op_iter); + } + else + { + // Operation has not finished yet, so leave at front of queue, and + // remove from the cleanup list. + cleanup_operations_ = this_op->next_; + this_op->next_ = op_iter->second; + op_iter->second = this_op; + } + } + } + } + + // Dispatch any pending cancels for operations. + void dispatch_cancellations() + { + while (cancelled_operations_) + { + op_base* this_op = cancelled_operations_; + cancelled_operations_ = this_op->next_; + this_op->next_ = cleanup_operations_; + cleanup_operations_ = this_op; + this_op->invoke(boost::asio::error::operation_aborted); + } + } + + // Destroy operations that are waiting to be cleaned up. + void cleanup_operations() + { + while (cleanup_operations_) + { + op_base* next_op = cleanup_operations_->next_; + cleanup_operations_->next_ = 0; + cleanup_operations_->destroy(); + cleanup_operations_ = next_op; + } + } + + // Destroy all operations owned by the queue. + void destroy_operations() + { + while (cancelled_operations_) + { + op_base* next_op = cancelled_operations_->next_; + cancelled_operations_->next_ = 0; + cancelled_operations_->destroy(); + cancelled_operations_ = next_op; + } + + while (cleanup_operations_) + { + op_base* next_op = cleanup_operations_->next_; + cleanup_operations_->next_ = 0; + cleanup_operations_->destroy(); + cleanup_operations_ = next_op; + } + + typename operation_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + typename operation_map::iterator op_iter = i++; + op_base* curr_op = op_iter->second; + operations_.erase(op_iter); + while (curr_op) + { + op_base* next_op = curr_op->next_; + curr_op->next_ = 0; + curr_op->destroy(); + curr_op = next_op; + } + } + } + +private: + // Base class for reactor operations. A function pointer is used instead of + // virtual functions to avoid the associated overhead. + class op_base + { + public: + // Get the descriptor associated with the operation. + Descriptor descriptor() const + { + return descriptor_; + } + + // Perform the operation. + bool invoke(const boost::system::error_code& result) + { + return invoke_func_(this, result); + } + + // Destroy the operation. + void destroy() + { + return destroy_func_(this); + } + + protected: + typedef bool (*invoke_func_type)(op_base*, + const boost::system::error_code&); + typedef void (*destroy_func_type)(op_base*); + + // Construct an operation for the given descriptor. + op_base(invoke_func_type invoke_func, + destroy_func_type destroy_func, Descriptor descriptor) + : invoke_func_(invoke_func), + destroy_func_(destroy_func), + descriptor_(descriptor), + next_(0) + { + } + + // Prevent deletion through this type. + ~op_base() + { + } + + private: + friend class reactor_op_queue; + + // The function to be called to dispatch the handler. + invoke_func_type invoke_func_; + + // The function to be called to delete the handler. + destroy_func_type destroy_func_; + + // The descriptor associated with the operation. + Descriptor descriptor_; + + // The next operation for the same file descriptor. + op_base* next_; + }; + + // Adaptor class template for using handlers in operations. + template + class op + : public op_base + { + public: + // Constructor. + op(Descriptor descriptor, Handler handler) + : op_base(&op::invoke_handler, + &op::destroy_handler, descriptor), + handler_(handler) + { + } + + // Invoke the handler. + static bool invoke_handler(op_base* base, + const boost::system::error_code& result) + { + return static_cast*>(base)->handler_(result); + } + + // Delete the handler. + static void destroy_handler(op_base* base) + { + delete static_cast*>(base); + } + + private: + Handler handler_; + }; + + // The type for a map of operations. + typedef hash_map operation_map; + + // The operations that are currently executing asynchronously. + operation_map operations_; + + // The list of operations that have been cancelled. + op_base* cancelled_operations_; + + // The list of operations to be destroyed. + op_base* cleanup_operations_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP diff --git a/thirdparty/boost/asio/detail/resolver_service.hpp b/thirdparty/boost/asio/detail/resolver_service.hpp new file mode 100644 index 0000000..5b5f9f7 --- /dev/null +++ b/thirdparty/boost/asio/detail/resolver_service.hpp @@ -0,0 +1,359 @@ +// +// resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_RESOLVER_SERVICE_HPP +#define BOOST_ASIO_DETAIL_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class resolver_service + : public boost::asio::detail::service_base > +{ +private: + // Helper class to perform exception-safe cleanup of addrinfo objects. + class auto_addrinfo + : private boost::asio::detail::noncopyable + { + public: + explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai) + : ai_(ai) + { + } + + ~auto_addrinfo() + { + if (ai_) + socket_ops::freeaddrinfo(ai_); + } + + operator boost::asio::detail::addrinfo_type*() + { + return ai_; + } + + private: + boost::asio::detail::addrinfo_type* ai_; + }; + +public: + // The implementation type of the resolver. The shared pointer is used as a + // cancellation token to indicate to the background thread that the operation + // has been cancelled. + typedef boost::shared_ptr implementation_type; + struct noop_deleter { void operator()(void*) {} }; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The query type. + typedef typename Protocol::resolver_query query_type; + + // The iterator type. + typedef typename Protocol::resolver_iterator iterator_type; + + // Constructor. + resolver_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + resolver_service >(io_service), + mutex_(), + work_io_service_(new boost::asio::io_service), + work_(new boost::asio::io_service::work(*work_io_service_)), + work_thread_(0) + { + } + + // Destructor. + ~resolver_service() + { + shutdown_service(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + work_.reset(); + if (work_io_service_) + { + work_io_service_->stop(); + if (work_thread_) + { + work_thread_->join(); + work_thread_.reset(); + } + work_io_service_.reset(); + } + } + + // Construct a new resolver implementation. + void construct(implementation_type& impl) + { + impl.reset(static_cast(0), noop_deleter()); + } + + // Destroy a resolver implementation. + void destroy(implementation_type&) + { + } + + // Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + impl.reset(static_cast(0), noop_deleter()); + } + + // Resolve a query to a list of entries. + iterator_type resolve(implementation_type&, const query_type& query, + boost::system::error_code& ec) + { + boost::asio::detail::addrinfo_type* address_info = 0; + std::string host_name = query.host_name(); + std::string service_name = query.service_name(); + boost::asio::detail::addrinfo_type hints = query.hints(); + + socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, ec); + auto_addrinfo auto_address_info(address_info); + + if (ec) + return iterator_type(); + + return iterator_type::create(address_info, host_name, service_name); + } + + template + class resolve_query_handler + { + public: + resolve_query_handler(implementation_type impl, const query_type& query, + boost::asio::io_service& io_service, Handler handler) + : impl_(impl), + query_(query), + io_service_(io_service), + work_(io_service), + handler_(handler) + { + } + + void operator()() + { + // Check if the operation has been cancelled. + if (impl_.expired()) + { + iterator_type iterator; + io_service_.post(boost::asio::detail::bind_handler(handler_, + boost::asio::error::operation_aborted, iterator)); + return; + } + + // Perform the blocking host resolution operation. + boost::asio::detail::addrinfo_type* address_info = 0; + std::string host_name = query_.host_name(); + std::string service_name = query_.service_name(); + boost::asio::detail::addrinfo_type hints = query_.hints(); + boost::system::error_code ec; + socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, ec); + auto_addrinfo auto_address_info(address_info); + + // Invoke the handler and pass the result. + iterator_type iterator; + if (!ec) + iterator = iterator_type::create(address_info, host_name, service_name); + io_service_.post(boost::asio::detail::bind_handler( + handler_, ec, iterator)); + } + + private: + boost::weak_ptr impl_; + query_type query_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + Handler handler_; + }; + + // Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, const query_type& query, + Handler handler) + { + if (work_io_service_) + { + start_work_thread(); + work_io_service_->post( + resolve_query_handler( + impl, query, this->get_io_service(), handler)); + } + } + + // Resolve an endpoint to a list of entries. + iterator_type resolve(implementation_type&, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + // First try resolving with the service name. If that fails try resolving + // but allow the service to be returned as a number. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + if (ec) + { + flags |= NI_NUMERICSERV; + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + } + + if (ec) + return iterator_type(); + + return iterator_type::create(endpoint, host_name, service_name); + } + + template + class resolve_endpoint_handler + { + public: + resolve_endpoint_handler(implementation_type impl, + const endpoint_type& endpoint, boost::asio::io_service& io_service, + Handler handler) + : impl_(impl), + endpoint_(endpoint), + io_service_(io_service), + work_(io_service), + handler_(handler) + { + } + + void operator()() + { + // Check if the operation has been cancelled. + if (impl_.expired()) + { + iterator_type iterator; + io_service_.post(boost::asio::detail::bind_handler(handler_, + boost::asio::error::operation_aborted, iterator)); + return; + } + + + // First try resolving with the service name. If that fails try resolving + // but allow the service to be returned as a number. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; + boost::system::error_code ec; + socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + if (ec) + { + flags |= NI_NUMERICSERV; + socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + } + + // Invoke the handler and pass the result. + iterator_type iterator; + if (!ec) + iterator = iterator_type::create(endpoint_, host_name, service_name); + io_service_.post(boost::asio::detail::bind_handler( + handler_, ec, iterator)); + } + + private: + boost::weak_ptr impl_; + endpoint_type endpoint_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + Handler handler_; + }; + + // Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type& impl, const endpoint_type& endpoint, + Handler handler) + { + if (work_io_service_) + { + start_work_thread(); + work_io_service_->post( + resolve_endpoint_handler( + impl, endpoint, this->get_io_service(), handler)); + } + } + +private: + // Helper class to run the work io_service in a thread. + class work_io_service_runner + { + public: + work_io_service_runner(boost::asio::io_service& io_service) + : io_service_(io_service) {} + void operator()() { io_service_.run(); } + private: + boost::asio::io_service& io_service_; + }; + + // Start the work thread if it's not already running. + void start_work_thread() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (work_thread_ == 0) + { + work_thread_.reset(new boost::asio::detail::thread( + work_io_service_runner(*work_io_service_))); + } + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // Private io_service used for performing asynchronous host resolution. + boost::scoped_ptr work_io_service_; + + // Work for the private io_service to perform. + boost::scoped_ptr work_; + + // Thread used for running the work io_service's run loop. + boost::scoped_ptr work_thread_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_RESOLVER_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/scoped_lock.hpp b/thirdparty/boost/asio/detail/scoped_lock.hpp new file mode 100644 index 0000000..5dfb4fd --- /dev/null +++ b/thirdparty/boost/asio/detail/scoped_lock.hpp @@ -0,0 +1,93 @@ +// +// scoped_lock.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP +#define BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +// Helper class to lock and unlock a mutex automatically. +template +class scoped_lock + : private noncopyable +{ +public: + // Constructor acquires the lock. + scoped_lock(Mutex& m) + : mutex_(m) + { + mutex_.lock(); + locked_ = true; + } + + // Destructor releases the lock. + ~scoped_lock() + { + if (locked_) + mutex_.unlock(); + } + + // Explicitly acquire the lock. + void lock() + { + if (!locked_) + { + mutex_.lock(); + locked_ = true; + } + } + + // Explicitly release the lock. + void unlock() + { + if (locked_) + { + mutex_.unlock(); + locked_ = false; + } + } + + // Test whether the lock is held. + bool locked() const + { + return locked_; + } + + // Get the underlying mutex. + Mutex& mutex() + { + return mutex_; + } + +private: + // The underlying mutex. + Mutex& mutex_; + + // Whether the mutex is currently locked or unlocked. + bool locked_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP diff --git a/thirdparty/boost/asio/detail/select_interrupter.hpp b/thirdparty/boost/asio/detail/select_interrupter.hpp new file mode 100644 index 0000000..d6586bc --- /dev/null +++ b/thirdparty/boost/asio/detail/select_interrupter.hpp @@ -0,0 +1,43 @@ +// +// select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SELECT_INTERRUPTER_HPP +#define BOOST_ASIO_DETAIL_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef socket_select_interrupter select_interrupter; +#else +typedef pipe_select_interrupter select_interrupter; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SELECT_INTERRUPTER_HPP diff --git a/thirdparty/boost/asio/detail/select_reactor.hpp b/thirdparty/boost/asio/detail/select_reactor.hpp new file mode 100644 index 0000000..08c5be5 --- /dev/null +++ b/thirdparty/boost/asio/detail/select_reactor.hpp @@ -0,0 +1,471 @@ +// +// select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP +#define BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include // Must come before posix_time. + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class select_reactor + : public boost::asio::detail::service_base > +{ +public: + // Constructor. + select_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + select_reactor >(io_service), + mutex_(), + select_in_progress_(false), + interrupter_(), + read_op_queue_(), + write_op_queue_(), + except_op_queue_(), + pending_cancellations_(), + stop_thread_(false), + thread_(0), + shutdown_(false) + { + if (Own_Thread) + { + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread( + bind_handler(&select_reactor::call_run_thread, this)); + } + } + + // Destructor. + ~select_reactor() + { + shutdown_service(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + lock.unlock(); + + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } + + read_op_queue_.destroy_operations(); + write_op_queue_.destroy_operations(); + except_op_queue_.destroy_operations(); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->destroy_timers(); + timer_queues_.clear(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type descriptor) + { + return 0; + } + + // Start a new read operation. The handler object will be invoked when the + // given descriptor is ready to be read, or an error has occurred. + template + void start_read_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (read_op_queue_.enqueue_operation(descriptor, handler)) + interrupter_.interrupt(); + } + + // Start a new write operation. The handler object will be invoked when the + // given descriptor is ready to be written, or an error has occurred. + template + void start_write_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (write_op_queue_.enqueue_operation(descriptor, handler)) + interrupter_.interrupt(); + } + + // Start a new exception operation. The handler object will be invoked when + // the given descriptor has exception information, or an error has occurred. + template + void start_except_op(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (except_op_queue_.enqueue_operation(descriptor, handler)) + interrupter_.interrupt(); + } + + // Start new write and exception operations. The handler object will be + // invoked when the given descriptor is ready for writing or has exception + // information available, or an error has occurred. + template + void start_write_and_except_ops(socket_type descriptor, Handler handler) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool interrupt = write_op_queue_.enqueue_operation(descriptor, handler); + interrupt = except_op_queue_.enqueue_operation(descriptor, handler) + || interrupt; + if (interrupt) + interrupter_.interrupt(); + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor); + } + + // Enqueue cancellation of all operations associated with the given + // descriptor. The handlers associated with the descriptor will be invoked + // with the operation_aborted error. This function does not acquire the + // select_reactor's mutex, and so should only be used from within a reactor + // handler. + void enqueue_cancel_ops_unlocked(socket_type descriptor) + { + pending_cancellations_.push_back(descriptor); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.push_back(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + if (timer_queues_[i] == &timer_queue) + { + timer_queues_.erase(timer_queues_.begin() + i); + return; + } + } + } + + // Schedule a timer in the given timer queue to expire at the specified + // absolute time. The handler object will be invoked when the timer expires. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, Handler handler, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + if (timer_queue.enqueue_timer(time, handler, token)) + interrupter_.interrupt(); + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + std::size_t n = timer_queue.cancel_timer(token); + if (n > 0) + interrupter_.interrupt(); + return n; + } + +private: + friend class task_io_service >; + + // Run select once until interrupted or events are ready to be dispatched. + void run(bool block) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Dispatch any operation cancellations that were made while the select + // loop was not running. + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + except_op_queue_.dispatch_cancellations(); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->dispatch_cancellations(); + + // Check if the thread is supposed to stop. + if (stop_thread_) + { + cleanup_operations_and_timers(lock); + return; + } + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && read_op_queue_.empty() && write_op_queue_.empty() + && except_op_queue_.empty() && all_timer_queues_are_empty()) + { + cleanup_operations_and_timers(lock); + return; + } + + // Set up the descriptor sets. + fd_set_adapter read_fds; + read_fds.set(interrupter_.read_descriptor()); + read_op_queue_.get_descriptors(read_fds); + fd_set_adapter write_fds; + write_op_queue_.get_descriptors(write_fds); + fd_set_adapter except_fds; + except_op_queue_.get_descriptors(except_fds); + socket_type max_fd = read_fds.max_descriptor(); + if (write_fds.max_descriptor() > max_fd) + max_fd = write_fds.max_descriptor(); + if (except_fds.max_descriptor() > max_fd) + max_fd = except_fds.max_descriptor(); + + // Block on the select call without holding the lock so that new + // operations can be started while the call is executing. + timeval tv_buf = { 0, 0 }; + timeval* tv = block ? get_timeout(tv_buf) : &tv_buf; + select_in_progress_ = true; + lock.unlock(); + boost::system::error_code ec; + int retval = socket_ops::select(static_cast(max_fd + 1), + read_fds, write_fds, except_fds, tv, ec); + lock.lock(); + select_in_progress_ = false; + + // Block signals while dispatching operations. + boost::asio::detail::signal_blocker sb; + + // Reset the interrupter. + if (retval > 0 && read_fds.is_set(interrupter_.read_descriptor())) + interrupter_.reset(); + + // Dispatch all ready operations. + if (retval > 0) + { + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + except_op_queue_.dispatch_descriptors(except_fds, + boost::system::error_code()); + read_op_queue_.dispatch_descriptors(read_fds, + boost::system::error_code()); + write_op_queue_.dispatch_descriptors(write_fds, + boost::system::error_code()); + except_op_queue_.dispatch_cancellations(); + read_op_queue_.dispatch_cancellations(); + write_op_queue_.dispatch_cancellations(); + } + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + timer_queues_[i]->dispatch_timers(); + timer_queues_[i]->dispatch_cancellations(); + } + + // Issue any pending cancellations. + for (size_t i = 0; i < pending_cancellations_.size(); ++i) + cancel_ops_unlocked(pending_cancellations_[i]); + pending_cancellations_.clear(); + + cleanup_operations_and_timers(lock); + } + + // Run the select loop in the thread. + void run_thread() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + run(true); + lock.lock(); + } + } + + // Entry point for the select loop thread. + static void call_run_thread(select_reactor* reactor) + { + reactor->run_thread(); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + + // Check if all timer queues are empty. + bool all_timer_queues_are_empty() const + { + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + if (!timer_queues_[i]->empty()) + return false; + return true; + } + + // Get the timeout value for the select call. + timeval* get_timeout(timeval& tv) + { + if (all_timer_queues_are_empty()) + return 0; + + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + boost::posix_time::time_duration minimum_wait_duration + = boost::posix_time::minutes(5); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + boost::posix_time::time_duration wait_duration + = timer_queues_[i]->wait_duration(); + if (wait_duration < minimum_wait_duration) + minimum_wait_duration = wait_duration; + } + + if (minimum_wait_duration > boost::posix_time::time_duration()) + { + tv.tv_sec = minimum_wait_duration.total_seconds(); + tv.tv_usec = minimum_wait_duration.total_microseconds() % 1000000; + } + else + { + tv.tv_sec = 0; + tv.tv_usec = 0; + } + + return &tv; + } + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the select_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor) + { + bool interrupt = read_op_queue_.cancel_operations(descriptor); + interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt; + interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt; + if (interrupt) + interrupter_.interrupt(); + } + + // Clean up operations and timers. We must not hold the lock since the + // destructors may make calls back into this reactor. We make a copy of the + // vector of timer queues since the original may be modified while the lock + // is not held. + void cleanup_operations_and_timers( + boost::asio::detail::mutex::scoped_lock& lock) + { + timer_queues_for_cleanup_ = timer_queues_; + lock.unlock(); + read_op_queue_.cleanup_operations(); + write_op_queue_.cleanup_operations(); + except_op_queue_.cleanup_operations(); + for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i) + timer_queues_for_cleanup_[i]->cleanup_timers(); + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // Whether the select loop is currently running or not. + bool select_in_progress_; + + // The interrupter is used to break a blocking select call. + select_interrupter interrupter_; + + // The queue of read operations. + reactor_op_queue read_op_queue_; + + // The queue of write operations. + reactor_op_queue write_op_queue_; + + // The queue of exception operations. + reactor_op_queue except_op_queue_; + + // The timer queues. + std::vector timer_queues_; + + // A copy of the timer queues, used when cleaning up timers. The copy is + // stored as a class data member to avoid unnecessary memory allocation. + std::vector timer_queues_for_cleanup_; + + // The descriptors that are pending cancellation. + std::vector pending_cancellations_; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + boost::asio::detail::thread* thread_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP diff --git a/thirdparty/boost/asio/detail/select_reactor_fwd.hpp b/thirdparty/boost/asio/detail/select_reactor_fwd.hpp new file mode 100644 index 0000000..44b6b59 --- /dev/null +++ b/thirdparty/boost/asio/detail/select_reactor_fwd.hpp @@ -0,0 +1,33 @@ +// +// select_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SELECT_REACTOR_FWD_HPP +#define BOOST_ASIO_DETAIL_SELECT_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class select_reactor; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_FWD_HPP diff --git a/thirdparty/boost/asio/detail/service_base.hpp b/thirdparty/boost/asio/detail/service_base.hpp new file mode 100644 index 0000000..cdcba2e --- /dev/null +++ b/thirdparty/boost/asio/detail/service_base.hpp @@ -0,0 +1,51 @@ +// +// service_base.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SERVICE_BASE_HPP +#define BOOST_ASIO_DETAIL_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// Special service base class to keep classes header-file only. +template +class service_base + : public boost::asio::io_service::service +{ +public: + static boost::asio::detail::service_id id; + + // Constructor. + service_base(boost::asio::io_service& io_service) + : boost::asio::io_service::service(io_service) + { + } +}; + +template +boost::asio::detail::service_id service_base::id; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SERVICE_BASE_HPP diff --git a/thirdparty/boost/asio/detail/service_id.hpp b/thirdparty/boost/asio/detail/service_id.hpp new file mode 100644 index 0000000..ea90468 --- /dev/null +++ b/thirdparty/boost/asio/detail/service_id.hpp @@ -0,0 +1,39 @@ +// +// service_id.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SERVICE_ID_HPP +#define BOOST_ASIO_DETAIL_SERVICE_ID_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +// Special derived service id type to keep classes header-file only. +template +class service_id + : public boost::asio::io_service::id +{ +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SERVICE_ID_HPP diff --git a/thirdparty/boost/asio/detail/service_registry.hpp b/thirdparty/boost/asio/detail/service_registry.hpp new file mode 100644 index 0000000..0e7d416 --- /dev/null +++ b/thirdparty/boost/asio/detail/service_registry.hpp @@ -0,0 +1,202 @@ +// +// service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SERVICE_REGISTRY_HPP +#define BOOST_ASIO_DETAIL_SERVICE_REGISTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class service_registry + : private noncopyable +{ +public: + // Constructor. + service_registry(boost::asio::io_service& o) + : owner_(o), + first_service_(0) + { + } + + // Destructor. + ~service_registry() + { + // Shutdown all services. This must be done in a separate loop before the + // services are destroyed since the destructors of user-defined handler + // objects may try to access other service objects. + boost::asio::io_service::service* service = first_service_; + while (service) + { + service->shutdown_service(); + service = service->next_; + } + + // Destroy all services. + while (first_service_) + { + boost::asio::io_service::service* next_service = first_service_->next_; + delete first_service_; + first_service_ = next_service; + } + } + + // Get the service object corresponding to the specified service type. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + template + Service& use_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // First see if there is an existing service object for the given type. + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (service_id_matches(*service, Service::id)) + return *static_cast(service); + service = service->next_; + } + + // Create a new service object. The service registry's mutex is not locked + // at this time to allow for nested calls into this function from the new + // service's constructor. + lock.unlock(); + std::auto_ptr new_service(new Service(owner_)); + init_service_id(*new_service, Service::id); + Service& new_service_ref = *new_service; + lock.lock(); + + // Check that nobody else created another service object of the same type + // while the lock was released. + service = first_service_; + while (service) + { + if (service_id_matches(*service, Service::id)) + return *static_cast(service); + service = service->next_; + } + + // Service was successfully initialised, pass ownership to registry. + new_service->next_ = first_service_; + first_service_ = new_service.release(); + + return new_service_ref; + } + + // Add a service object. Returns false on error, in which case ownership of + // the object is retained by the caller. + template + bool add_service(Service* new_service) + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Check if there is an existing service object for the given type. + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (service_id_matches(*service, Service::id)) + return false; + service = service->next_; + } + + // Take ownership of the service object. + init_service_id(*new_service, Service::id); + new_service->next_ = first_service_; + first_service_ = new_service; + + return true; + } + + // Check whether a service object of the specified type already exists. + template + bool has_service() const + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (service_id_matches(*service, Service::id)) + return true; + service = service->next_; + } + + return false; + } + +private: + // Set a service's id. + void init_service_id(boost::asio::io_service::service& service, + const boost::asio::io_service::id& id) + { + service.type_info_ = 0; + service.id_ = &id; + } + + // Set a service's id. + template + void init_service_id(boost::asio::io_service::service& service, + const boost::asio::detail::service_id& /*id*/) + { + service.type_info_ = &typeid(Service); + service.id_ = 0; + } + + // Check if a service matches the given id. + static bool service_id_matches( + const boost::asio::io_service::service& service, + const boost::asio::io_service::id& id) + { + return service.id_ == &id; + } + + // Check if a service matches the given id. + template + static bool service_id_matches( + const boost::asio::io_service::service& service, + const boost::asio::detail::service_id& /*id*/) + { + return service.type_info_ != 0 && *service.type_info_ == typeid(Service); + } + + // Mutex to protect access to internal data. + mutable boost::asio::detail::mutex mutex_; + + // The owner of this service registry and the services it contains. + boost::asio::io_service& owner_; + + // The first service in the list of contained services. + boost::asio::io_service::service* first_service_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_HPP diff --git a/thirdparty/boost/asio/detail/service_registry_fwd.hpp b/thirdparty/boost/asio/detail/service_registry_fwd.hpp new file mode 100644 index 0000000..5e1bc29 --- /dev/null +++ b/thirdparty/boost/asio/detail/service_registry_fwd.hpp @@ -0,0 +1,32 @@ +// +// service_registry_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP +#define BOOST_ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class service_registry; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP diff --git a/thirdparty/boost/asio/detail/signal_blocker.hpp b/thirdparty/boost/asio/detail/signal_blocker.hpp new file mode 100644 index 0000000..09f11b3 --- /dev/null +++ b/thirdparty/boost/asio/detail/signal_blocker.hpp @@ -0,0 +1,52 @@ +// +// signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SIGNAL_BLOCKER_HPP +#define BOOST_ASIO_DETAIL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#else +# error Only Windows and POSIX are supported! +#endif + +namespace boost { +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) +typedef null_signal_blocker signal_blocker; +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef win_signal_blocker signal_blocker; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_signal_blocker signal_blocker; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SIGNAL_BLOCKER_HPP diff --git a/thirdparty/boost/asio/detail/signal_init.hpp b/thirdparty/boost/asio/detail/signal_init.hpp new file mode 100644 index 0000000..e295b0a --- /dev/null +++ b/thirdparty/boost/asio/detail/signal_init.hpp @@ -0,0 +1,53 @@ +// +// signal_init.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SIGNAL_INIT_HPP +#define BOOST_ASIO_DETAIL_SIGNAL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class signal_init +{ +public: + // Constructor. + signal_init() + { + std::signal(Signal, SIG_IGN); + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_SIGNAL_INIT_HPP diff --git a/thirdparty/boost/asio/detail/socket_holder.hpp b/thirdparty/boost/asio/detail/socket_holder.hpp new file mode 100644 index 0000000..a213635 --- /dev/null +++ b/thirdparty/boost/asio/detail/socket_holder.hpp @@ -0,0 +1,97 @@ +// +// socket_holder.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_HOLDER_HPP +#define BOOST_ASIO_DETAIL_SOCKET_HOLDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// Implement the resource acquisition is initialisation idiom for sockets. +class socket_holder + : private noncopyable +{ +public: + // Construct as an uninitialised socket. + socket_holder() + : socket_(invalid_socket) + { + } + + // Construct to take ownership of the specified socket. + explicit socket_holder(socket_type s) + : socket_(s) + { + } + + // Destructor. + ~socket_holder() + { + if (socket_ != invalid_socket) + { + boost::system::error_code ec; + socket_ops::close(socket_, ec); + } + } + + // Get the underlying socket. + socket_type get() const + { + return socket_; + } + + // Reset to an uninitialised socket. + void reset() + { + if (socket_ != invalid_socket) + { + boost::system::error_code ec; + socket_ops::close(socket_, ec); + socket_ = invalid_socket; + } + } + + // Reset to take ownership of the specified socket. + void reset(socket_type s) + { + reset(); + socket_ = s; + } + + // Release ownership of the socket. + socket_type release() + { + socket_type tmp = socket_; + socket_ = invalid_socket; + return tmp; + } + +private: + // The underlying socket. + socket_type socket_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_HOLDER_HPP diff --git a/thirdparty/boost/asio/detail/socket_ops.hpp b/thirdparty/boost/asio/detail/socket_ops.hpp new file mode 100644 index 0000000..e418285 --- /dev/null +++ b/thirdparty/boost/asio/detail/socket_ops.hpp @@ -0,0 +1,1879 @@ +// +// socket_ops.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_HPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +struct msghdr { int msg_namelen; }; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) +// HP-UX doesn't declare these functions extern "C", so they are declared again +// here to avoid linker errors about undefined symbols. +extern "C" char* if_indextoname(unsigned int, char*); +extern "C" unsigned int if_nametoindex(const char*); +#endif // defined(__hpux) + +inline void clear_error(boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + WSASetLastError(0); +#else + errno = 0; +#endif + ec = boost::system::error_code(); +} + +template +inline ReturnType error_wrapper(ReturnType return_value, + boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ec = boost::system::error_code(WSAGetLastError(), + boost::asio::error::get_system_category()); +#else + ec = boost::system::error_code(errno, + boost::asio::error::get_system_category()); +#endif + return return_value; +} + +template +inline socket_type call_accept(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0; + socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0); + if (addrlen) + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline socket_type accept(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + clear_error(ec); + + socket_type new_s = error_wrapper(call_accept( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (new_s == invalid_socket) + return new_s; + +#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + int optval = 1; + int result = error_wrapper(::setsockopt(new_s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(new_s); + return invalid_socket; + } +#endif + +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + clear_error(ec); +#endif + + return new_s; +} + +template +inline int call_bind(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::bind(s, addr, (SockLenType)addrlen); +} + +inline int bind(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_bind( + &msghdr::msg_namelen, s, addr, addrlen), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +inline int close(socket_type s, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::closesocket(s), ec); +# if defined(UNDER_CE) + if (result == 0) + clear_error(ec); +# endif + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return error_wrapper(::close(s), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int shutdown(socket_type s, int what, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::shutdown(s, what), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +template +inline int call_connect(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::connect(s, addr, (SockLenType)addrlen); +} + +inline int connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_connect( + &msghdr::msg_namelen, s, addr, addrlen), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +inline int listen(socket_type s, int backlog, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::listen(s, backlog), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef WSABUF buf; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef iovec buf; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +inline void init_buf(buf& b, void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast(data); + b.len = static_cast(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.iov_base = data; + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline void init_buf(buf& b, const void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast(const_cast(data)); + b.len = static_cast(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.iov_base = const_cast(data); + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) +{ + name = addr; +} + +inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr) +{ + name = const_cast(addr); +} + +template +inline void init_msghdr_msg_name(T& name, socket_addr_type* addr) +{ + name = reinterpret_cast(addr); +} + +template +inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) +{ + name = reinterpret_cast(const_cast(addr)); +} + +inline int recv(socket_type s, buf* bufs, size_t count, int flags, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = error_wrapper(::WSARecv(s, bufs, + recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); + if (result != 0) + return -1; +# if defined(UNDER_CE) + clear_error(ec); +# endif + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = bufs; + msg.msg_iovlen = count; + return error_wrapper(::recvmsg(s, &msg, flags), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int tmp_addrlen = (int)*addrlen; + int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, + &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); + *addrlen = (std::size_t)tmp_addrlen; + if (result != 0) + return -1; +# if defined(UNDER_CE) + clear_error(ec); +# endif + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = *addrlen; + msg.msg_iov = bufs; + msg.msg_iovlen = count; + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + *addrlen = msg.msg_namelen; + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int send(socket_type s, const buf* bufs, size_t count, int flags, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD send_flags = flags; + int result = error_wrapper(::WSASend(s, const_cast(bufs), + send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); + if (result != 0) + return -1; +# if defined(UNDER_CE) + clear_error(ec); +# endif + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = const_cast(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + return error_wrapper(::sendmsg(s, &msg, flags), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int sendto(socket_type s, const buf* bufs, size_t count, int flags, + const socket_addr_type* addr, std::size_t addrlen, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + int result = error_wrapper(::WSASendTo(s, const_cast(bufs), + send_buf_count, &bytes_transferred, flags, addr, + static_cast(addrlen), 0, 0), ec); + if (result != 0) + return -1; +# if defined(UNDER_CE) + clear_error(ec); +# endif + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = addrlen; + msg.msg_iov = const_cast(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + return error_wrapper(::sendmsg(s, &msg, flags), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline socket_type socket(int af, int type, int protocol, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, + WSA_FLAG_OVERLAPPED), ec); + if (s == invalid_socket) + return s; + + if (af == AF_INET6) + { + // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to + // false. This will only succeed on Windows Vista and later versions of + // Windows, where a dual-stack IPv4/v6 implementation is available. + DWORD optval = 0; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast(&optval), sizeof(optval)); + } + +# if defined(UNDER_CE) + clear_error(ec); +# endif + + return s; +#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + socket_type s = error_wrapper(::socket(af, type, protocol), ec); + if (s == invalid_socket) + return s; + + int optval = 1; + int result = error_wrapper(::setsockopt(s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(s); + return invalid_socket; + } + + return s; +#else + return error_wrapper(::socket(af, type, protocol), ec); +#endif +} + +template +inline int call_setsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + const void* optval, std::size_t optlen) +{ + return ::setsockopt(s, level, optname, + (const char*)optval, (SockLenType)optlen); +} + +inline int setsockopt(socket_type s, int level, int optname, + const void* optval, std::size_t optlen, boost::system::error_code& ec) +{ + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int); + if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt")) + { + clear_error(ec); + return error_wrapper(sso(s, level, optname, + reinterpret_cast(optval), + static_cast(optlen)), ec); + } + } + ec = boost::asio::error::fault; + return -1; +#else // defined(__BORLANDC__) + clear_error(ec); + int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); +# if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +# endif + return result; +#endif // defined(__BORLANDC__) +} + +template +inline int call_getsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + void* optval, std::size_t* optlen) +{ + SockLenType tmp_optlen = (SockLenType)*optlen; + int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen); + *optlen = (std::size_t)tmp_optlen; + return result; +} + +inline int getsockopt(socket_type s, int level, int optname, void* optval, + size_t* optlen, boost::system::error_code& ec) +{ + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*); + if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt")) + { + clear_error(ec); + int tmp_optlen = static_cast(*optlen); + int result = error_wrapper(gso(s, level, optname, + reinterpret_cast(optval), &tmp_optlen), ec); + *optlen = static_cast(tmp_optlen); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are + // only supported on Windows Vista and later. To simplify program logic + // we will fake success of getting this option and specify that the + // value is non-zero (i.e. true). This corresponds to the behavior of + // IPv6 sockets on Windows platforms pre-Vista. + *static_cast(optval) = 1; + clear_error(ec); + } + return result; + } + } + ec = boost::asio::error::fault; + return -1; +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_error(ec); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only + // supported on Windows Vista and later. To simplify program logic we will + // fake success of getting this option and specify that the value is + // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets + // on Windows platforms pre-Vista. + *static_cast(optval) = 1; + clear_error(ec); + } +# if defined(UNDER_CE) + if (result == 0) + clear_error(ec); +# endif + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_error(ec); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); +#if defined(__linux__) + if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int) + && (optname == SO_SNDBUF || optname == SO_RCVBUF)) + { + // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel + // to set the buffer size to N*2. Linux puts additional stuff into the + // buffers so that only about half is actually available to the application. + // The retrieved value is divided by 2 here to make it appear as though the + // correct value has been set. + *static_cast(optval) /= 2; + } +#endif // defined(__linux__) + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +template +inline int call_getpeername(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getpeername(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline int getpeername(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_getpeername( + &msghdr::msg_namelen, s, addr, addrlen), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +template +inline int call_getsockname(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getsockname(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline int getsockname(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_getsockname( + &msghdr::msg_namelen, s, addr, addrlen), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); +# if defined(UNDER_CE) + if (result == 0) + clear_error(ec); +# endif + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return error_wrapper(::ioctl(s, cmd, arg), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int select(int nfds, fd_set* readfds, fd_set* writefds, + fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (!readfds && !writefds && !exceptfds && timeout) + { + DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; + if (milliseconds == 0) + milliseconds = 1; // Force context switch. + ::Sleep(milliseconds); + ec = boost::system::error_code(); + return 0; + } + + // The select() call allows timeout values measured in microseconds, but the + // system clock (as wrapped by boost::posix_time::microsec_clock) typically + // has a resolution of 10 milliseconds. This can lead to a spinning select + // reactor, meaning increased CPU usage, when waiting for the earliest + // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight + // spin we'll use a minimum timeout of 1 millisecond. + if (timeout && timeout->tv_sec == 0 + && timeout->tv_usec > 0 && timeout->tv_usec < 1000) + timeout->tv_usec = 1000; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) && defined(__HP_aCC) + timespec ts; + ts.tv_sec = timeout ? timeout->tv_sec : 0; + ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0; + return error_wrapper(::pselect(nfds, readfds, + writefds, exceptfds, timeout ? &ts : 0, 0), ec); +#else + int result = error_wrapper(::select(nfds, readfds, + writefds, exceptfds, timeout), ec); +# if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result >= 0) + clear_error(ec); +# endif + return result; +#endif +} + +inline int poll_read(socket_type s, boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + FD_SET fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_error(ec); + int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec); +# if defined(UNDER_CE) + if (result >= 0) + clear_error(ec); +# endif + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + pollfd fds; + fds.fd = s; + fds.events = POLLIN; + fds.revents = 0; + clear_error(ec); + return error_wrapper(::poll(&fds, 1, -1), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int poll_write(socket_type s, boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + FD_SET fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_error(ec); + int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec); +# if defined(UNDER_CE) + if (result >= 0) + clear_error(ec); +# endif + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + clear_error(ec); + return error_wrapper(::poll(&fds, 1, -1), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, + unsigned long scope_id, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy. + + if (af != AF_INET && af != AF_INET6) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + DWORD address_length; + if (af == AF_INET) + { + address_length = sizeof(sockaddr_in4_type); + address.v4.sin_family = AF_INET; + address.v4.sin_port = 0; + memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); + } + else // AF_INET6 + { + address_length = sizeof(sockaddr_in6_type); + address.v6.sin6_family = AF_INET6; + address.v6.sin6_port = 0; + address.v6.sin6_flowinfo = 0; + address.v6.sin6_scope_id = scope_id; + memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type)); + } + + DWORD string_length = static_cast(length); +#if defined(BOOST_NO_ANSI_APIS) + LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); + int result = error_wrapper(::WSAAddressToStringW(&address.base, + address_length, 0, string_buffer, &string_length), ec); + ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0); +#else + int result = error_wrapper(::WSAAddressToStringA( + &address.base, address_length, 0, dest, &string_length), ec); +#endif + + // Windows may set error code on success. + if (result != socket_error_retval) + clear_error(ec); + + // Windows may not set an error code on failure. + else if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; + + return result == socket_error_retval ? 0 : dest; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); + if (result == 0 && !ec) + ec = boost::asio::error::invalid_argument; + if (result != 0 && af == AF_INET6 && scope_id != 0) + { + using namespace std; // For strcat and sprintf. + char if_name[IF_NAMESIZE + 1] = "%"; + const in6_addr_type* ipv6_address = static_cast(src); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) + sprintf(if_name + 1, "%lu", scope_id); + strcat(dest, if_name); + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int inet_pton(int af, const char* src, void* dest, + unsigned long* scope_id, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy and strcmp. + + if (af != AF_INET && af != AF_INET6) + { + ec = boost::asio::error::address_family_not_supported; + return -1; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + int address_length = sizeof(sockaddr_storage_type); +#if defined(BOOST_NO_ANSI_APIS) + int num_wide_chars = strlen(src) + 1; + LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); + ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); + int result = error_wrapper(::WSAStringToAddressW( + wide_buffer, af, 0, &address.base, &address_length), ec); +#else + int result = error_wrapper(::WSAStringToAddressA( + const_cast(src), af, 0, &address.base, &address_length), ec); +#endif + + if (af == AF_INET) + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type)); + clear_error(ec); + } + else if (strcmp(src, "255.255.255.255") == 0) + { + static_cast(dest)->s_addr = INADDR_NONE; + clear_error(ec); + } + } + else // AF_INET6 + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type)); + if (scope_id) + *scope_id = address.v6.sin6_scope_id; + clear_error(ec); + } + } + + // Windows may not set an error code on failure. + if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; + +#if defined(UNDER_CE) + if (result != socket_error_retval) + clear_error(ec); +#endif + + return result == socket_error_retval ? -1 : 1; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::inet_pton(af, src, dest), ec); + if (result <= 0 && !ec) + ec = boost::asio::error::invalid_argument; + if (result > 0 && af == AF_INET6 && scope_id) + { + using namespace std; // For strchr and atoi. + *scope_id = 0; + if (const char* if_name = strchr(src, '%')) + { + in6_addr_type* ipv6_address = static_cast(dest); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (is_link_local) + *scope_id = if_nametoindex(if_name + 1); + if (*scope_id == 0) + *scope_id = atoi(if_name + 1); + } + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int gethostname(char* name, int namelen, boost::system::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::gethostname(name, namelen), ec); +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ + || defined(__MACH__) && defined(__APPLE__) + +// The following functions are only needed for emulation of getaddrinfo and +// getnameinfo. + +inline boost::system::error_code translate_netdb_error(int error) +{ + switch (error) + { + case 0: + return boost::system::error_code(); + case HOST_NOT_FOUND: + return boost::asio::error::host_not_found; + case TRY_AGAIN: + return boost::asio::error::host_not_found_try_again; + case NO_RECOVERY: + return boost::asio::error::no_recovery; + case NO_DATA: + return boost::asio::error::no_data; + default: + BOOST_ASSERT(false); + return boost::asio::error::invalid_argument; + } +} + +inline hostent* gethostbyaddr(const char* addr, int length, int af, + hostent* result, char* buffer, int buflength, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); + if (!retval) + return 0; +# if defined(UNDER_CE) + clear_error(ec); +# endif + *result = *retval; + return retval; +#elif defined(__sun) || defined(__QNX__) + int error = 0; + hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, + buffer, buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyaddr( + addr, length, af, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, + buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline hostent* gethostbyname(const char* name, int af, struct hostent* result, + char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + hostent* retval = error_wrapper(::gethostbyname(name), ec); + if (!retval) + return 0; +# if defined(UNDER_CE) + clear_error(ec); +# endif + *result = *retval; + return result; +#elif defined(__sun) || defined(__QNX__) + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + int error = 0; + hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, + buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyname( + name, af, ai_flags, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyname_r(name, result, + buffer, buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline void freehostent(hostent* h) +{ +#if defined(__MACH__) && defined(__APPLE__) + if (h) + ::freehostent(h); +#else + (void)(h); +#endif +} + +// Emulation of getaddrinfo based on implementation in: +// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998. + +struct gai_search +{ + const char* host; + int family; +}; + +inline int gai_nsearch(const char* host, + const addrinfo_type* hints, gai_search (&search)[2]) +{ + int search_count = 0; + if (host == 0 || host[0] == '\0') + { + if (hints->ai_flags & AI_PASSIVE) + { + // No host and AI_PASSIVE implies wildcard bind. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + else + { + // No host and not AI_PASSIVE means connect to local host. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + } + else + { + // Host is specified. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + return search_count; +} + +template +inline T* gai_alloc(std::size_t size = sizeof(T)) +{ + using namespace std; + T* p = static_cast(::operator new(size, std::nothrow)); + if (p) + memset(p, 0, size); + return p; +} + +inline void gai_free(void* p) +{ + ::operator delete(p); +} + +inline void gai_strcpy(char* target, const char* source, std::size_t max_size) +{ + using namespace std; +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + strcpy_s(target, max_size, source); +#else + *target = 0; + strncat(target, source, max_size); +#endif +} + +enum { gai_clone_flag = 1 << 30 }; + +inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, + const void* addr, int family) +{ + using namespace std; + + addrinfo_type* ai = gai_alloc(); + if (ai == 0) + return EAI_MEMORY; + + ai->ai_next = 0; + **next = ai; + *next = &ai->ai_next; + + ai->ai_canonname = 0; + ai->ai_socktype = hints->ai_socktype; + if (ai->ai_socktype == 0) + ai->ai_flags |= gai_clone_flag; + ai->ai_protocol = hints->ai_protocol; + ai->ai_family = family; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = gai_alloc(); + if (sinptr == 0) + return EAI_MEMORY; + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); + ai->ai_addr = reinterpret_cast(sinptr); + ai->ai_addrlen = sizeof(sockaddr_in4_type); + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = gai_alloc(); + if (sin6ptr == 0) + return EAI_MEMORY; + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); + ai->ai_addr = reinterpret_cast(sin6ptr); + ai->ai_addrlen = sizeof(sockaddr_in6_type); + break; + } + default: + break; + } + + return 0; +} + +inline addrinfo_type* gai_clone(addrinfo_type* ai) +{ + using namespace std; + + addrinfo_type* new_ai = gai_alloc(); + if (new_ai == 0) + return new_ai; + + new_ai->ai_next = ai->ai_next; + ai->ai_next = new_ai; + + new_ai->ai_flags = 0; + new_ai->ai_family = ai->ai_family; + new_ai->ai_socktype = ai->ai_socktype; + new_ai->ai_protocol = ai->ai_protocol; + new_ai->ai_canonname = 0; + new_ai->ai_addrlen = ai->ai_addrlen; + new_ai->ai_addr = gai_alloc(ai->ai_addrlen); + memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return new_ai; +} + +inline int gai_port(addrinfo_type* aihead, int port, int socktype) +{ + int num_found = 0; + + for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next) + { + if (ai->ai_flags & gai_clone_flag) + { + if (ai->ai_socktype != 0) + { + ai = gai_clone(ai); + if (ai == 0) + return -1; + // ai now points to newly cloned entry. + } + } + else if (ai->ai_socktype != socktype) + { + // Ignore if mismatch on socket type. + continue; + } + + ai->ai_socktype = socktype; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = + reinterpret_cast(ai->ai_addr); + sinptr->sin_port = port; + ++num_found; + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = + reinterpret_cast(ai->ai_addr); + sin6ptr->sin6_port = port; + ++num_found; + break; + } + default: + break; + } + } + + return num_found; +} + +inline int gai_serv(addrinfo_type* aihead, + const addrinfo_type* hints, const char* serv) +{ + using namespace std; + + int num_found = 0; + + if ( +#if defined(AI_NUMERICSERV) + (hints->ai_flags & AI_NUMERICSERV) || +#endif + isdigit(serv[0])) + { + int port = htons(atoi(serv)); + if (hints->ai_socktype) + { + // Caller specifies socket type. + int rc = gai_port(aihead, port, hints->ai_socktype); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + else + { + // Caller does not specify socket type. + int rc = gai_port(aihead, port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + rc = gai_port(aihead, port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + else + { + // Try service name with TCP first, then UDP. + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM) + { + servent* sptr = getservbyname(serv, "tcp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM) + { + servent* sptr = getservbyname(serv, "udp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + } + + if (num_found == 0) + { + if (hints->ai_socktype == 0) + { + // All calls to getservbyname() failed. + return EAI_NONAME; + } + else + { + // Service not supported for socket type. + return EAI_SERVICE; + } + } + + return 0; +} + +inline int gai_echeck(const char* host, const char* service, + int flags, int family, int socktype, int protocol) +{ + (void)(flags); + (void)(protocol); + + // Host or service must be specified. + if (host == 0 || host[0] == '\0') + if (service == 0 || service[0] == '\0') + return EAI_NONAME; + + // Check combination of family and socket type. + switch (family) + { + case AF_UNSPEC: + break; + case AF_INET: + case AF_INET6: + if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) + return EAI_SOCKTYPE; + break; + default: + return EAI_FAMILY; + } + + return 0; +} + +inline void freeaddrinfo_emulation(addrinfo_type* aihead) +{ + addrinfo_type* ai = aihead; + while (ai) + { + gai_free(ai->ai_addr); + gai_free(ai->ai_canonname); + addrinfo_type* ainext = ai->ai_next; + gai_free(ai); + ai = ainext; + } +} + +inline int getaddrinfo_emulation(const char* host, const char* service, + const addrinfo_type* hintsp, addrinfo_type** result) +{ + // Set up linked list of addrinfo structures. + addrinfo_type* aihead = 0; + addrinfo_type** ainext = &aihead; + char* canon = 0; + + // Supply default hints if not specified by caller. + addrinfo_type hints = addrinfo_type(); + hints.ai_family = AF_UNSPEC; + if (hintsp) + hints = *hintsp; + + // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED + // and AI_ALL flags. +#if defined(AI_V4MAPPED) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_V4MAPPED; +#endif +#if defined(AI_ALL) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_ALL; +#endif + + // Basic error checking. + int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family, + hints.ai_socktype, hints.ai_protocol); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + + gai_search search[2]; + int search_count = gai_nsearch(host, &hints, search); + for (gai_search* sptr = search; sptr < search + search_count; ++sptr) + { + // Check for IPv4 dotted decimal string. + in4_addr_type inaddr; + boost::system::error_code ec; + if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET) + { + rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Check for IPv6 hex string. + in6_addr_type in6addr; + if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET6) + { + rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Look up hostname. + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyname(sptr->host, + sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); + if (hptr == 0) + { + if (search_count == 2) + { + // Failure is OK if there are multiple searches. + continue; + } + freeaddrinfo_emulation(aihead); + gai_free(canon); + if (ec == boost::asio::error::host_not_found) + return EAI_NONAME; + if (ec == boost::asio::error::host_not_found_try_again) + return EAI_AGAIN; + if (ec == boost::asio::error::no_recovery) + return EAI_FAIL; + if (ec == boost::asio::error::no_data) + return EAI_NONAME; + return EAI_NONAME; + } + + // Check for address family mismatch if one was specified. + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + + // Save canonical name first time. + if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0] + && (hints.ai_flags & AI_CANONNAME) && canon == 0) + { + std::size_t canon_len = strlen(hptr->h_name) + 1; + canon = gai_alloc(canon_len); + if (canon == 0) + { + freeaddrinfo_emulation(aihead); + socket_ops::freehostent(hptr); + return EAI_MEMORY; + } + gai_strcpy(canon, hptr->h_name, canon_len); + } + + // Create an addrinfo structure for each returned address. + for (char** ap = hptr->h_addr_list; *ap; ++ap) + { + rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + } + + socket_ops::freehostent(hptr); + } + + // Check if we found anything. + if (aihead == 0) + { + gai_free(canon); + return EAI_NONAME; + } + + // Return canonical name in first entry. + if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME)) + { + if (canon) + { + aihead->ai_canonname = canon; + canon = 0; + } + else + { + std::size_t canonname_len = strlen(search[0].host) + 1; + aihead->ai_canonname = gai_alloc(canonname_len); + if (aihead->ai_canonname == 0) + { + freeaddrinfo_emulation(aihead); + return EAI_MEMORY; + } + gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len); + } + } + gai_free(canon); + + // Process the service name. + if (service != 0 && service[0] != '\0') + { + rc = gai_serv(aihead, &hints, service); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + } + + // Return result to caller. + *result = aihead; + return 0; +} + +inline boost::system::error_code getnameinfo_emulation( + const socket_addr_type* sa, std::size_t salen, char* host, + std::size_t hostlen, char* serv, std::size_t servlen, int flags, + boost::system::error_code& ec) +{ + using namespace std; + + const char* addr; + size_t addr_len; + unsigned short port; + switch (sa->sa_family) + { + case AF_INET: + if (salen != sizeof(sockaddr_in4_type)) + { + return ec = boost::asio::error::invalid_argument; + } + addr = reinterpret_cast( + &reinterpret_cast(sa)->sin_addr); + addr_len = sizeof(in4_addr_type); + port = reinterpret_cast(sa)->sin_port; + break; + case AF_INET6: + if (salen != sizeof(sockaddr_in6_type)) + { + return ec = boost::asio::error::invalid_argument; + } + addr = reinterpret_cast( + &reinterpret_cast(sa)->sin6_addr); + addr_len = sizeof(in6_addr_type); + port = reinterpret_cast(sa)->sin6_port; + break; + default: + return ec = boost::asio::error::address_family_not_supported; + } + + if (host && hostlen > 0) + { + if (flags & NI_NUMERICHOST) + { + if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + else + { + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyaddr(addr, + static_cast(addr_len), sa->sa_family, + &hent, hbuf, sizeof(hbuf), ec); + if (hptr && hptr->h_name && hptr->h_name[0] != '\0') + { + if (flags & NI_NOFQDN) + { + char* dot = strchr(hptr->h_name, '.'); + if (dot) + { + *dot = 0; + } + } + gai_strcpy(host, hptr->h_name, hostlen); + socket_ops::freehostent(hptr); + } + else + { + socket_ops::freehostent(hptr); + if (flags & NI_NAMEREQD) + { + return ec = boost::asio::error::host_not_found; + } + if (socket_ops::inet_ntop(sa->sa_family, + addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + } + } + + if (serv && servlen > 0) + { + if (flags & NI_NUMERICSERV) + { + if (servlen < 6) + { + return ec = boost::asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } + else + { +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + ::pthread_mutex_lock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); + if (sptr && sptr->s_name && sptr->s_name[0] != '\0') + { + gai_strcpy(serv, sptr->s_name, servlen); + } + else + { + if (servlen < 6) + { + return ec = boost::asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + ::pthread_mutex_unlock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + } + } + + clear_error(ec); + return ec; +} + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // || defined(__MACH__) && defined(__APPLE__) + +inline boost::system::error_code translate_addrinfo_error(int error) +{ + switch (error) + { + case 0: + return boost::system::error_code(); + case EAI_AGAIN: + return boost::asio::error::host_not_found_try_again; + case EAI_BADFLAGS: + return boost::asio::error::invalid_argument; + case EAI_FAIL: + return boost::asio::error::no_recovery; + case EAI_FAMILY: + return boost::asio::error::address_family_not_supported; + case EAI_MEMORY: + return boost::asio::error::no_memory; + case EAI_NONAME: +#if defined(EAI_ADDRFAMILY) + case EAI_ADDRFAMILY: +#endif +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + return boost::asio::error::host_not_found; + case EAI_SERVICE: + return boost::asio::error::service_not_found; + case EAI_SOCKTYPE: + return boost::asio::error::socket_type_not_supported; + default: // Possibly the non-portable EAI_SYSTEM. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return boost::system::error_code( + WSAGetLastError(), boost::asio::error::get_system_category()); +#else + return boost::system::error_code( + errno, boost::asio::error::get_system_category()); +#endif + } +} + +inline boost::system::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type* hints, addrinfo_type** result, + boost::system::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + int error = ::getaddrinfo(host, service, hints, result); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gai_t)(const char*, + const char*, const addrinfo_type*, addrinfo_type**); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) + { + int error = gai(host, service, hints, result); + return ec = translate_addrinfo_error(error); + } + } + int error = getaddrinfo_emulation(host, service, hints, result); + return ec = translate_addrinfo_error(error); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + int error = getaddrinfo_emulation(host, service, hints, result); + return ec = translate_addrinfo_error(error); +#else + int error = ::getaddrinfo(host, service, hints, result); + return ec = translate_addrinfo_error(error); +#endif +} + +inline void freeaddrinfo(addrinfo_type* ai) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + ::freeaddrinfo(ai); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *fai_t)(addrinfo_type*); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo")) + { + fai(ai); + return; + } + } + freeaddrinfo_emulation(ai); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + freeaddrinfo_emulation(ai); +#else + ::freeaddrinfo(ai); +#endif +} + +inline boost::system::error_code getnameinfo(const socket_addr_type* addr, + std::size_t addrlen, char* host, std::size_t hostlen, + char* serv, std::size_t servlen, int flags, boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + clear_error(ec); + int error = ::getnameinfo(addr, static_cast(addrlen), + host, static_cast(hostlen), + serv, static_cast(servlen), flags); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gni_t)(const socket_addr_type*, + int, char*, DWORD, char*, DWORD, int); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) + { + clear_error(ec); + int error = gni(addr, static_cast(addrlen), + host, static_cast(hostlen), + serv, static_cast(servlen), flags); + return ec = translate_addrinfo_error(error); + } + } + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + using namespace std; // For memcpy. + sockaddr_storage_type tmp_addr; + memcpy(&tmp_addr, addr, addrlen); + tmp_addr.ss_len = addrlen; + addr = reinterpret_cast(&tmp_addr); + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +#else + clear_error(ec); + int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); + return ec = translate_addrinfo_error(error); +#endif +} + +inline u_long_type network_to_host_long(u_long_type value) +{ + return ntohl(value); +} + +inline u_long_type host_to_network_long(u_long_type value) +{ + return htonl(value); +} + +inline u_short_type network_to_host_short(u_short_type value) +{ + return ntohs(value); +} + +inline u_short_type host_to_network_short(u_short_type value) +{ + return htons(value); +} + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/thirdparty/boost/asio/detail/socket_option.hpp b/thirdparty/boost/asio/detail/socket_option.hpp new file mode 100644 index 0000000..64bfeca --- /dev/null +++ b/thirdparty/boost/asio/detail/socket_option.hpp @@ -0,0 +1,311 @@ +// +// socket_option.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP +#define BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_option { + +// Helper template for implementing boolean-based options. +template +class boolean +{ +public: + // Default constructor. + boolean() + : value_(0) + { + } + + // Construct with a specific option value. + explicit boolean(bool v) + : value_(v ? 1 : 0) + { + } + + // Set the current value of the boolean. + boolean& operator=(bool v) + { + value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!value_; + } + + // Convert to bool. + operator bool() const + { + return !!value_; + } + + // Test for false. + bool operator!() const + { + return !value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the boolean data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the boolean data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol&, std::size_t s) + { + // On some platforms (e.g. Windows Vista), the getsockopt function will + // return the size of a boolean socket option as one byte, even though a + // four byte integer was passed in. + switch (s) + { + case sizeof(char): + value_ = *reinterpret_cast(&value_) ? 1 : 0; + break; + case sizeof(value_): + break; + default: + throw std::length_error("boolean socket option resize"); + } + } + +private: + int value_; +}; + +// Helper template for implementing integer options. +template +class integer +{ +public: + // Default constructor. + integer() + : value_(0) + { + } + + // Construct with a specific option value. + explicit integer(int v) + : value_(v) + { + } + + // Set the value of the int option. + integer& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the int option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the int data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the int data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the int data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + throw std::length_error("integer socket option resize"); + } + +private: + int value_; +}; + +// Helper template for implementing linger options. +template +class linger +{ +public: + // Default constructor. + linger() + { + value_.l_onoff = 0; + value_.l_linger = 0; + } + + // Construct with specific option values. + linger(bool e, int t) + { + enabled(e); + timeout(t); + } + + // Set the value for whether linger is enabled. + void enabled(bool value) + { + value_.l_onoff = value ? 1 : 0; + } + + // Get the value for whether linger is enabled. + bool enabled() const + { + return value_.l_onoff != 0; + } + + // Set the value for the linger timeout. + void timeout(int value) + { +#if defined(WIN32) + value_.l_linger = static_cast(value); +#else + value_.l_linger = value; +#endif + } + + // Get the value for the linger timeout. + int timeout() const + { + return static_cast(value_.l_linger); + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the linger data. + template + ::linger* data(const Protocol&) + { + return &value_; + } + + // Get the address of the linger data. + template + const ::linger* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the linger data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + throw std::length_error("linger socket option resize"); + } + +private: + ::linger value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_OPTION_HPP diff --git a/thirdparty/boost/asio/detail/socket_select_interrupter.hpp b/thirdparty/boost/asio/detail/socket_select_interrupter.hpp new file mode 100644 index 0000000..4a7b225 --- /dev/null +++ b/thirdparty/boost/asio/detail/socket_select_interrupter.hpp @@ -0,0 +1,189 @@ +// +// socket_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP +#define BOOST_ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class socket_select_interrupter +{ +public: + // Constructor. + socket_select_interrupter() + { + boost::system::error_code ec; + socket_holder acceptor(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (acceptor.get() == invalid_socket) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + int opt = 1; + socket_ops::setsockopt(acceptor.get(), + SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); + + using namespace std; // For memset. + sockaddr_in4_type addr; + std::size_t addr_len = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = 0; + if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, + &addr_len, ec) == socket_error_retval) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + if (socket_ops::listen(acceptor.get(), + SOMAXCONN, ec) == socket_error_retval) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + socket_holder client(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (client.get() == invalid_socket) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); + if (server.get() == invalid_socket) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec)) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + opt = 1; + socket_ops::setsockopt(client.get(), + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + non_blocking = 1; + if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec)) + { + boost::system::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + opt = 1; + socket_ops::setsockopt(server.get(), + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + read_descriptor_ = server.release(); + write_descriptor_ = client.release(); + } + + // Destructor. + ~socket_select_interrupter() + { + boost::system::error_code ec; + if (read_descriptor_ != invalid_socket) + socket_ops::close(read_descriptor_, ec); + if (write_descriptor_ != invalid_socket) + socket_ops::close(write_descriptor_, ec); + } + + // Interrupt the select call. + void interrupt() + { + char byte = 0; + socket_ops::buf b; + socket_ops::init_buf(b, &byte, 1); + boost::system::error_code ec; + socket_ops::send(write_descriptor_, &b, 1, 0, ec); + } + + // Reset the select interrupt. Returns true if the call was interrupted. + bool reset() + { + char data[1024]; + socket_ops::buf b; + socket_ops::init_buf(b, data, sizeof(data)); + boost::system::error_code ec; + int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + return was_interrupted; + } + + // Get the read descriptor to be passed to select. + socket_type read_descriptor() const + { + return read_descriptor_; + } + +private: + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + socket_type read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + socket_type write_descriptor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP diff --git a/thirdparty/boost/asio/detail/socket_types.hpp b/thirdparty/boost/asio/detail/socket_types.hpp new file mode 100644 index 0000000..5aaadd9 --- /dev/null +++ b/thirdparty/boost/asio/detail/socket_types.hpp @@ -0,0 +1,201 @@ +// +// socket_types.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_TYPES_HPP +#define BOOST_ASIO_DETAIL_SOCKET_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# error WinSock.h has already been included +# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) || defined(__BORLANDC__) +# pragma message("Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately") +# pragma message("Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)") +# else // defined(_MSC_VER) || defined(__BORLANDC__) +# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately +# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target) +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# define _WIN32_WINNT 0x0501 +# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) +# if defined(_WIN32) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(_WIN32) && !defined(WIN32) +# endif // defined(_MSC_VER) +# if defined(__BORLANDC__) +# include // Needed for __errno +# if defined(__WIN32__) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(__WIN32__) && !defined(WIN32) +# if !defined(_WSPIAPI_H_) +# define _WSPIAPI_H_ +# define BOOST_ASIO_WSPIAPI_H_DEFINED +# endif // !defined(_WSPIAPI_H_) +# endif // defined(__BORLANDC__) +# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) +# if !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif // !defined(WIN32_LEAN_AND_MEAN) +# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) +# if defined(__CYGWIN__) +# if !defined(__USE_W32_SOCKETS) +# error You must add -D__USE_W32_SOCKETS to your compiler options. +# endif // !defined(__USE_W32_SOCKETS) +# if !defined(NOMINMAX) +# define NOMINMAX 1 +# endif // !defined(NOMINMAX) +# endif // defined(__CYGWIN__) +# include +# include +# include +# if defined(BOOST_ASIO_WSPIAPI_H_DEFINED) +# undef _WSPIAPI_H_ +# undef BOOST_ASIO_WSPIAPI_H_DEFINED +# endif // defined(BOOST_ASIO_WSPIAPI_H_DEFINED) +# if !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS) +# if defined(UNDER_CE) +# pragma comment(lib, "ws2.lib") +# elif defined(_MSC_VER) || defined(__BORLANDC__) +# pragma comment(lib, "ws2_32.lib") +# pragma comment(lib, "mswsock.lib") +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# endif // !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS) +# include +#else +# include +# include +# include +# if defined(__hpux) && !defined(__HP_aCC) +# include +# else +# include +# endif +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(__sun) +# include +# include +# endif +#endif +#include + +namespace boost { +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef SOCKET socket_type; +const SOCKET invalid_socket = INVALID_SOCKET; +const int socket_error_retval = SOCKET_ERROR; +const int max_addr_v4_str_len = 256; +const int max_addr_v6_str_len = 256; +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +typedef ip_mreq in4_mreq_type; +typedef sockaddr_in sockaddr_in4_type; +# if defined(BOOST_ASIO_HAS_OLD_WIN_SDK) +typedef in6_addr_emulation in6_addr_type; +typedef ipv6_mreq_emulation in6_mreq_type; +typedef sockaddr_in6_emulation sockaddr_in6_type; +typedef sockaddr_storage_emulation sockaddr_storage_type; +typedef addrinfo_emulation addrinfo_type; +# else +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef addrinfo addrinfo_type; +# endif +typedef unsigned long ioctl_arg_type; +typedef u_long u_long_type; +typedef u_short u_short_type; +const int shutdown_receive = SD_RECEIVE; +const int shutdown_send = SD_SEND; +const int shutdown_both = SD_BOTH; +const int message_peek = MSG_PEEK; +const int message_out_of_band = MSG_OOB; +const int message_do_not_route = MSG_DONTROUTE; +# if defined (_WIN32_WINNT) +const int max_iov_len = 64; +# else +const int max_iov_len = 16; +# endif +#else +typedef int socket_type; +const int invalid_socket = -1; +const int socket_error_retval = -1; +const int max_addr_v4_str_len = INET_ADDRSTRLEN; +const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE; +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +# if defined(__hpux) +// HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined. +struct in4_mreq_type +{ + struct in_addr imr_multiaddr; + struct in_addr imr_interface; +}; +# else +typedef ip_mreq in4_mreq_type; +# endif +typedef sockaddr_in sockaddr_in4_type; +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef addrinfo addrinfo_type; +typedef int ioctl_arg_type; +typedef uint32_t u_long_type; +typedef uint16_t u_short_type; +const int shutdown_receive = SHUT_RD; +const int shutdown_send = SHUT_WR; +const int shutdown_both = SHUT_RDWR; +const int message_peek = MSG_PEEK; +const int message_out_of_band = MSG_OOB; +const int message_do_not_route = MSG_DONTROUTE; +const int max_iov_len = IOV_MAX; +#endif +const int custom_socket_option_level = 0xA5100000; +const int enable_connection_aborted_option = 1; +const int always_fail_option = 2; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_TYPES_HPP diff --git a/thirdparty/boost/asio/detail/strand_service.hpp b/thirdparty/boost/asio/detail/strand_service.hpp new file mode 100644 index 0000000..b13db71 --- /dev/null +++ b/thirdparty/boost/asio/detail/strand_service.hpp @@ -0,0 +1,527 @@ +// +// strand_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP +#define BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +// Default service implementation for a strand. +class strand_service + : public boost::asio::detail::service_base +{ +public: + class handler_base; + class invoke_current_handler; + class post_next_waiter_on_exit; + + // The underlying implementation of a strand. + class strand_impl + { +#if defined (__BORLANDC__) + public: +#else + private: +#endif + void add_ref() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + ++ref_count_; + } + + void release() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + --ref_count_; + if (ref_count_ == 0) + { + lock.unlock(); + delete this; + } + } + + private: + // Only this service will have access to the internal values. + friend class strand_service; + friend class post_next_waiter_on_exit; + friend class invoke_current_handler; + + strand_impl(strand_service& owner) + : owner_(owner), + current_handler_(0), + first_waiter_(0), + last_waiter_(0), + ref_count_(0) + { + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(owner_.mutex_); + next_ = owner_.impl_list_; + prev_ = 0; + if (owner_.impl_list_) + owner_.impl_list_->prev_ = this; + owner_.impl_list_ = this; + } + + ~strand_impl() + { + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(owner_.mutex_); + if (owner_.impl_list_ == this) + owner_.impl_list_ = next_; + if (prev_) + prev_->next_ = next_; + if (next_) + next_->prev_= prev_; + next_ = 0; + prev_ = 0; + lock.unlock(); + + if (current_handler_) + { + current_handler_->destroy(); + } + + while (first_waiter_) + { + handler_base* next = first_waiter_->next_; + first_waiter_->destroy(); + first_waiter_ = next; + } + } + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // The service that owns this implementation. + strand_service& owner_; + + // The handler that is ready to execute. If this pointer is non-null then it + // indicates that a handler holds the lock. + handler_base* current_handler_; + + // The start of the list of waiting handlers for the strand. + handler_base* first_waiter_; + + // The end of the list of waiting handlers for the strand. + handler_base* last_waiter_; + + // Storage for posted handlers. + typedef boost::aligned_storage<128> handler_storage_type; +#if defined(__BORLANDC__) + boost::aligned_storage<128> handler_storage_; +#else + handler_storage_type handler_storage_; +#endif + + // Pointers to adjacent socket implementations in linked list. + strand_impl* next_; + strand_impl* prev_; + + // The reference count on the strand implementation. + size_t ref_count_; + +#if !defined(__BORLANDC__) + friend void intrusive_ptr_add_ref(strand_impl* p) + { + p->add_ref(); + } + + friend void intrusive_ptr_release(strand_impl* p) + { + p->release(); + } +#endif + }; + + friend class strand_impl; + + typedef boost::intrusive_ptr implementation_type; + + // Base class for all handler types. + class handler_base + { + public: + typedef void (*invoke_func_type)(handler_base*, + strand_service&, implementation_type&); + typedef void (*destroy_func_type)(handler_base*); + + handler_base(invoke_func_type invoke_func, destroy_func_type destroy_func) + : next_(0), + invoke_func_(invoke_func), + destroy_func_(destroy_func) + { + } + + void invoke(strand_service& service_impl, implementation_type& impl) + { + invoke_func_(this, service_impl, impl); + } + + void destroy() + { + destroy_func_(this); + } + + protected: + ~handler_base() + { + } + + private: + friend class strand_service; + friend class strand_impl; + friend class post_next_waiter_on_exit; + handler_base* next_; + invoke_func_type invoke_func_; + destroy_func_type destroy_func_; + }; + + // Helper class to allow handlers to be dispatched. + class invoke_current_handler + { + public: + invoke_current_handler(strand_service& service_impl, + const implementation_type& impl) + : service_impl_(service_impl), + impl_(impl) + { + } + + void operator()() + { + impl_->current_handler_->invoke(service_impl_, impl_); + } + + friend void* asio_handler_allocate(std::size_t size, + invoke_current_handler* this_handler) + { + return this_handler->do_handler_allocate(size); + } + + friend void asio_handler_deallocate(void*, std::size_t, + invoke_current_handler*) + { + } + + void* do_handler_allocate(std::size_t size) + { +#if defined(__BORLANDC__) + BOOST_ASSERT(size <= boost::aligned_storage<128>::size); +#else + BOOST_ASSERT(size <= strand_impl::handler_storage_type::size); +#endif + (void)size; + return impl_->handler_storage_.address(); + } + + // The asio_handler_invoke hook is not defined here since the default one + // provides the correct behaviour, and including it here breaks MSVC 7.1 + // in some situations. + + private: + strand_service& service_impl_; + implementation_type impl_; + }; + + // Helper class to automatically enqueue next waiter on block exit. + class post_next_waiter_on_exit + { + public: + post_next_waiter_on_exit(strand_service& service_impl, + implementation_type& impl) + : service_impl_(service_impl), + impl_(impl), + cancelled_(false) + { + } + + ~post_next_waiter_on_exit() + { + if (!cancelled_) + { + boost::asio::detail::mutex::scoped_lock lock(impl_->mutex_); + impl_->current_handler_ = impl_->first_waiter_; + if (impl_->current_handler_) + { + impl_->first_waiter_ = impl_->first_waiter_->next_; + if (impl_->first_waiter_ == 0) + impl_->last_waiter_ = 0; + lock.unlock(); + service_impl_.get_io_service().post( + invoke_current_handler(service_impl_, impl_)); + } + } + } + + void cancel() + { + cancelled_ = true; + } + + private: + strand_service& service_impl_; + implementation_type& impl_; + bool cancelled_; + }; + + // Class template for a waiter. + template + class handler_wrapper + : public handler_base + { + public: + handler_wrapper(Handler handler) + : handler_base(&handler_wrapper::do_invoke, + &handler_wrapper::do_destroy), + handler_(handler) + { + } + + static void do_invoke(handler_base* base, + strand_service& service_impl, implementation_type& impl) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + post_next_waiter_on_exit p1(service_impl, impl); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(h->handler_); + + // A handler object must still be valid when the next waiter is posted + // since destroying the last handler might cause the strand object to be + // destroyed. Therefore we create a second post_next_waiter_on_exit object + // that will be destroyed before the handler object. + p1.cancel(); + post_next_waiter_on_exit p2(service_impl, impl); + + // Free the memory associated with the handler. + ptr.reset(); + + // Indicate that this strand is executing on the current thread. + call_stack::context ctx(impl.get()); + + // Make the upcall. + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + } + + static void do_destroy(handler_base* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + } + + private: + Handler handler_; + }; + + // Construct a new strand service for the specified io_service. + explicit strand_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service), + mutex_(), + impl_list_(0) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + // Construct a list of all handlers to be destroyed. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + strand_impl* impl = impl_list_; + handler_base* first_handler = 0; + while (impl) + { + if (impl->current_handler_) + { + impl->current_handler_->next_ = first_handler; + first_handler = impl->current_handler_; + impl->current_handler_ = 0; + } + if (impl->first_waiter_) + { + impl->last_waiter_->next_ = first_handler; + first_handler = impl->first_waiter_; + impl->first_waiter_ = 0; + impl->last_waiter_ = 0; + } + impl = impl->next_; + } + + // Destroy all handlers without holding the lock. + lock.unlock(); + while (first_handler) + { + handler_base* next = first_handler->next_; + first_handler->destroy(); + first_handler = next; + } + } + + // Construct a new strand implementation. + void construct(implementation_type& impl) + { + impl = implementation_type(new strand_impl(*this)); + } + + // Destroy a strand implementation. + void destroy(implementation_type& impl) + { + implementation_type().swap(impl); + } + + // Request the io_service to invoke the given handler. + template + void dispatch(implementation_type& impl, Handler handler) + { + if (call_stack::contains(impl.get())) + { + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + } + else + { + // Allocate and construct an object to wrap the handler. + typedef handler_wrapper value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + boost::asio::detail::mutex::scoped_lock lock(impl->mutex_); + + if (impl->current_handler_ == 0) + { + // This handler now has the lock, so can be dispatched immediately. + impl->current_handler_ = ptr.release(); + lock.unlock(); + this->get_io_service().dispatch(invoke_current_handler(*this, impl)); + } + else + { + // Another handler already holds the lock, so this handler must join + // the list of waiters. The handler will be posted automatically when + // its turn comes. + if (impl->last_waiter_) + { + impl->last_waiter_->next_ = ptr.get(); + impl->last_waiter_ = impl->last_waiter_->next_; + } + else + { + impl->first_waiter_ = ptr.get(); + impl->last_waiter_ = ptr.get(); + } + ptr.release(); + } + } + } + + // Request the io_service to invoke the given handler and return immediately. + template + void post(implementation_type& impl, Handler handler) + { + // Allocate and construct an object to wrap the handler. + typedef handler_wrapper value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + boost::asio::detail::mutex::scoped_lock lock(impl->mutex_); + + if (impl->current_handler_ == 0) + { + // This handler now has the lock, so can be dispatched immediately. + impl->current_handler_ = ptr.release(); + lock.unlock(); + this->get_io_service().post(invoke_current_handler(*this, impl)); + } + else + { + // Another handler already holds the lock, so this handler must join the + // list of waiters. The handler will be posted automatically when its turn + // comes. + if (impl->last_waiter_) + { + impl->last_waiter_->next_ = ptr.get(); + impl->last_waiter_ = impl->last_waiter_->next_; + } + else + { + impl->first_waiter_ = ptr.get(); + impl->last_waiter_ = ptr.get(); + } + ptr.release(); + } + } + +private: + // Mutex to protect access to the linked list of implementations. + boost::asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + strand_impl* impl_list_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#if defined(__BORLANDC__) + +namespace boost { + +inline void intrusive_ptr_add_ref( + boost::asio::detail::strand_service::strand_impl* p) +{ + p->add_ref(); +} + +inline void intrusive_ptr_release( + boost::asio::detail::strand_service::strand_impl* p) +{ + p->release(); +} + +} // namespace boost + +#endif // defined(__BORLANDC__) + +#include + +#endif // BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/task_io_service.hpp b/thirdparty/boost/asio/detail/task_io_service.hpp new file mode 100644 index 0000000..c3a3db8 --- /dev/null +++ b/thirdparty/boost/asio/detail/task_io_service.hpp @@ -0,0 +1,421 @@ +// +// task_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP +#define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class task_io_service + : public boost::asio::detail::service_base > +{ +public: + // Constructor. + task_io_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base >(io_service), + mutex_(), + task_(use_service(io_service)), + task_interrupted_(true), + outstanding_work_(0), + stopped_(false), + shutdown_(false), + first_idle_thread_(0) + { + handler_queue_.push(&task_handler_); + } + + void init(size_t /*concurrency_hint*/) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + // Destroy handler objects. + while (!handler_queue_.empty()) + { + handler_queue::handler* h = handler_queue_.front(); + handler_queue_.pop(); + if (h != &task_handler_) + h->destroy(); + } + + // Reset handler queue to initial state. + handler_queue_.push(&task_handler_); + } + + // Run the event loop until interrupted or no more work. + size_t run(boost::system::error_code& ec) + { + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + size_t n = 0; + while (do_one(lock, &this_idle_thread, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Run until interrupted or one operation is performed. + size_t run_one(boost::system::error_code& ec) + { + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + return do_one(lock, &this_idle_thread, ec); + } + + // Poll for operations without blocking. + size_t poll(boost::system::error_code& ec) + { + typename call_stack::context ctx(this); + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + size_t n = 0; + while (do_one(lock, 0, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Poll for one operation without blocking. + size_t poll_one(boost::system::error_code& ec) + { + typename call_stack::context ctx(this); + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + return do_one(lock, 0, ec); + } + + // Interrupt the event processing loop. + void stop() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + stop_all_threads(lock); + } + + // Reset in preparation for a subsequent run invocation. + void reset() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + stopped_ = false; + } + + // Notify that some work has started. + void work_started() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + ++outstanding_work_; + } + + // Notify that some work has finished. + void work_finished() + { + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (--outstanding_work_ == 0) + stop_all_threads(lock); + } + + // Request invocation of the given handler. + template + void dispatch(Handler handler) + { + if (call_stack::contains(this)) + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + else + post(handler); + } + + // Request invocation of the given handler and return immediately. + template + void post(Handler handler) + { + // Allocate and construct an operation to wrap the handler. + handler_queue::scoped_ptr ptr(handler_queue::wrap(handler)); + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // If the service has been shut down we silently discard the handler. + if (shutdown_) + return; + + // Add the handler to the end of the queue. + handler_queue_.push(ptr.get()); + ptr.release(); + + // An undelivered handler is treated as unfinished work. + ++outstanding_work_; + + // Wake up a thread to execute the handler. + if (!interrupt_one_idle_thread(lock)) + { + if (!task_interrupted_) + { + task_interrupted_ = true; + task_.interrupt(); + } + } + } + +private: + struct idle_thread_info; + + size_t do_one(boost::asio::detail::mutex::scoped_lock& lock, + idle_thread_info* this_idle_thread, boost::system::error_code& ec) + { + if (outstanding_work_ == 0 && !stopped_) + { + stop_all_threads(lock); + ec = boost::system::error_code(); + return 0; + } + + bool polling = !this_idle_thread; + bool task_has_run = false; + while (!stopped_) + { + if (!handler_queue_.empty()) + { + // Prepare to execute first handler from queue. + handler_queue::handler* h = handler_queue_.front(); + handler_queue_.pop(); + + if (h == &task_handler_) + { + bool more_handlers = (!handler_queue_.empty()); + task_interrupted_ = more_handlers || polling; + + // If the task has already run and we're polling then we're done. + if (task_has_run && polling) + { + task_interrupted_ = true; + handler_queue_.push(&task_handler_); + ec = boost::system::error_code(); + return 0; + } + task_has_run = true; + + lock.unlock(); + task_cleanup c(lock, *this); + + // Run the task. May throw an exception. Only block if the handler + // queue is empty and we have an idle_thread_info object, otherwise + // we want to return as soon as possible. + task_.run(!more_handlers && !polling); + } + else + { + lock.unlock(); + handler_cleanup c(lock, *this); + + // Invoke the handler. May throw an exception. + h->invoke(); // invoke() deletes the handler object + + ec = boost::system::error_code(); + return 1; + } + } + else if (this_idle_thread) + { + // Nothing to run right now, so just wait for work to do. + this_idle_thread->next = first_idle_thread_; + first_idle_thread_ = this_idle_thread; + this_idle_thread->wakeup_event.clear(lock); + this_idle_thread->wakeup_event.wait(lock); + } + else + { + ec = boost::system::error_code(); + return 0; + } + } + + ec = boost::system::error_code(); + return 0; + } + + // Stop the task and all idle threads. + void stop_all_threads( + boost::asio::detail::mutex::scoped_lock& lock) + { + stopped_ = true; + interrupt_all_idle_threads(lock); + if (!task_interrupted_) + { + task_interrupted_ = true; + task_.interrupt(); + } + } + + // Interrupt a single idle thread. Returns true if a thread was interrupted, + // false if no running thread could be found to interrupt. + bool interrupt_one_idle_thread( + boost::asio::detail::mutex::scoped_lock& lock) + { + if (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(lock); + return true; + } + return false; + } + + // Interrupt all idle threads. + void interrupt_all_idle_threads( + boost::asio::detail::mutex::scoped_lock& lock) + { + while (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(lock); + } + } + + // Helper class to perform task-related operations on block exit. + class task_cleanup; + friend class task_cleanup; + class task_cleanup + { + public: + task_cleanup(boost::asio::detail::mutex::scoped_lock& lock, + task_io_service& task_io_svc) + : lock_(lock), + task_io_service_(task_io_svc) + { + } + + ~task_cleanup() + { + // Reinsert the task at the end of the handler queue. + lock_.lock(); + task_io_service_.task_interrupted_ = true; + task_io_service_.handler_queue_.push(&task_io_service_.task_handler_); + } + + private: + boost::asio::detail::mutex::scoped_lock& lock_; + task_io_service& task_io_service_; + }; + + // Helper class to perform handler-related operations on block exit. + class handler_cleanup; + friend class handler_cleanup; + class handler_cleanup + { + public: + handler_cleanup(boost::asio::detail::mutex::scoped_lock& lock, + task_io_service& task_io_svc) + : lock_(lock), + task_io_service_(task_io_svc) + { + } + + ~handler_cleanup() + { + lock_.lock(); + if (--task_io_service_.outstanding_work_ == 0) + task_io_service_.stop_all_threads(lock_); + } + + private: + boost::asio::detail::mutex::scoped_lock& lock_; + task_io_service& task_io_service_; + }; + + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // The task to be run by this service. + Task& task_; + + // Handler object to represent the position of the task in the queue. + class task_handler + : public handler_queue::handler + { + public: + task_handler() + : handler_queue::handler(0, 0) + { + } + } task_handler_; + + // Whether the task has been interrupted. + bool task_interrupted_; + + // The count of unfinished work. + int outstanding_work_; + + // The queue of handlers that are ready to be delivered. + handler_queue handler_queue_; + + // Flag to indicate that the dispatcher has been stopped. + bool stopped_; + + // Flag to indicate that the dispatcher has been shut down. + bool shutdown_; + + // Structure containing information about an idle thread. + struct idle_thread_info + { + event wakeup_event; + idle_thread_info* next; + }; + + // The number of threads that are currently idle. + idle_thread_info* first_idle_thread_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include +#include + +#endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/task_io_service_fwd.hpp b/thirdparty/boost/asio/detail/task_io_service_fwd.hpp new file mode 100644 index 0000000..ea5ac2d --- /dev/null +++ b/thirdparty/boost/asio/detail/task_io_service_fwd.hpp @@ -0,0 +1,33 @@ +// +// task_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP +#define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class task_io_service; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP diff --git a/thirdparty/boost/asio/detail/thread.hpp b/thirdparty/boost/asio/detail/thread.hpp new file mode 100644 index 0000000..008aeb7 --- /dev/null +++ b/thirdparty/boost/asio/detail/thread.hpp @@ -0,0 +1,60 @@ +// +// thread.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_THREAD_HPP +#define BOOST_ASIO_DETAIL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_WINDOWS) +# if defined(UNDER_CE) +# include +# else +# include +# endif +#elif defined(BOOST_HAS_PTHREADS) +# include +#else +# error Only Windows and POSIX are supported! +#endif + +namespace boost { +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) +typedef null_thread thread; +#elif defined(BOOST_WINDOWS) +# if defined(UNDER_CE) +typedef wince_thread thread; +# else +typedef win_thread thread; +# endif +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_thread thread; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_THREAD_HPP diff --git a/thirdparty/boost/asio/detail/throw_error.hpp b/thirdparty/boost/asio/detail/throw_error.hpp new file mode 100644 index 0000000..b93f3d7 --- /dev/null +++ b/thirdparty/boost/asio/detail/throw_error.hpp @@ -0,0 +1,46 @@ +// +// throw_error.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_THROW_ERROR_HPP +#define BOOST_ASIO_DETAIL_THROW_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + + +namespace boost { +namespace asio { +namespace detail { + +inline void throw_error(const boost::system::error_code& err) +{ + if (err) + { + boost::system::system_error e(err); + boost::throw_exception(e); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_THROW_ERROR_HPP diff --git a/thirdparty/boost/asio/detail/timer_queue.hpp b/thirdparty/boost/asio/detail/timer_queue.hpp new file mode 100644 index 0000000..04a7c21 --- /dev/null +++ b/thirdparty/boost/asio/detail/timer_queue.hpp @@ -0,0 +1,397 @@ +// +// timer_queue.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_TIMER_QUEUE_HPP +#define BOOST_ASIO_DETAIL_TIMER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class timer_queue + : public timer_queue_base +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // Constructor. + timer_queue() + : timers_(), + heap_(), + cancelled_timers_(0), + cleanup_timers_(0) + { + } + + // Add a new timer to the queue. Returns true if this is the timer that is + // earliest in the queue, in which case the reactor's event demultiplexing + // function call may need to be interrupted and restarted. + template + bool enqueue_timer(const time_type& time, Handler handler, void* token) + { + // Ensure that there is space for the timer in the heap. We reserve here so + // that the push_back below will not throw due to a reallocation failure. + heap_.reserve(heap_.size() + 1); + + // Create a new timer object. + std::auto_ptr > new_timer( + new timer(time, handler, token)); + + // Insert the new timer into the hash. + typedef typename hash_map::iterator iterator; + typedef typename hash_map::value_type value_type; + std::pair result = + timers_.insert(value_type(token, new_timer.get())); + if (!result.second) + { + result.first->second->prev_ = new_timer.get(); + new_timer->next_ = result.first->second; + result.first->second = new_timer.get(); + } + + // Put the timer at the correct position in the heap. + new_timer->heap_index_ = heap_.size(); + heap_.push_back(new_timer.get()); + up_heap(heap_.size() - 1); + bool is_first = (heap_[0] == new_timer.get()); + + // Ownership of the timer is transferred to the timer queue. + new_timer.release(); + + return is_first; + } + + // Whether there are no timers in the queue. + virtual bool empty() const + { + return heap_.empty(); + } + + // Get the time for the timer that is earliest in the queue. + virtual boost::posix_time::time_duration wait_duration() const + { + return Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + } + + // Dispatch the timers that are earlier than the specified time. + virtual void dispatch_timers() + { + const time_type now = Time_Traits::now(); + while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_)) + { + timer_base* t = heap_[0]; + remove_timer(t); + t->prev_ = 0; + t->next_ = cleanup_timers_; + cleanup_timers_ = t; + t->invoke(boost::system::error_code()); + } + } + + // Cancel the timers with the given token. Any timers pending for the token + // will be notified that they have been cancelled next time + // dispatch_cancellations is called. Returns the number of timers that were + // cancelled. + std::size_t cancel_timer(void* timer_token) + { + std::size_t num_cancelled = 0; + typedef typename hash_map::iterator iterator; + iterator it = timers_.find(timer_token); + if (it != timers_.end()) + { + timer_base* t = it->second; + while (t) + { + timer_base* next = t->next_; + remove_timer(t); + t->prev_ = 0; + t->next_ = cancelled_timers_; + cancelled_timers_ = t; + t = next; + ++num_cancelled; + } + } + return num_cancelled; + } + + // Dispatch any pending cancels for timers. + virtual void dispatch_cancellations() + { + while (cancelled_timers_) + { + timer_base* this_timer = cancelled_timers_; + cancelled_timers_ = this_timer->next_; + this_timer->next_ = cleanup_timers_; + cleanup_timers_ = this_timer; + this_timer->invoke(boost::asio::error::operation_aborted); + } + } + + // Destroy timers that are waiting to be cleaned up. + virtual void cleanup_timers() + { + destroy_timer_list(cleanup_timers_); + } + + // Destroy all timers. + virtual void destroy_timers() + { + typename hash_map::iterator i = timers_.begin(); + typename hash_map::iterator end = timers_.end(); + while (i != end) + { + timer_base* t = i->second; + typename hash_map::iterator old_i = i++; + timers_.erase(old_i); + destroy_timer_list(t); + } + heap_.clear(); + timers_.clear(); + destroy_timer_list(cancelled_timers_); + destroy_timer_list(cleanup_timers_); + } + +private: + // Base class for timer operations. Function pointers are used instead of + // virtual functions to avoid the associated overhead. + class timer_base + { + public: + // Perform the timer operation and then destroy. + void invoke(const boost::system::error_code& result) + { + invoke_func_(this, result); + } + + // Destroy the timer operation. + void destroy() + { + destroy_func_(this); + } + + protected: + typedef void (*invoke_func_type)(timer_base*, + const boost::system::error_code&); + typedef void (*destroy_func_type)(timer_base*); + + // Constructor. + timer_base(invoke_func_type invoke_func, destroy_func_type destroy_func, + const time_type& time, void* token) + : invoke_func_(invoke_func), + destroy_func_(destroy_func), + time_(time), + token_(token), + next_(0), + prev_(0), + heap_index_( + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()) + { + } + + // Prevent deletion through this type. + ~timer_base() + { + } + + private: + friend class timer_queue; + + // The function to be called to dispatch the handler. + invoke_func_type invoke_func_; + + // The function to be called to destroy the handler. + destroy_func_type destroy_func_; + + // The time when the operation should fire. + time_type time_; + + // The token associated with the timer. + void* token_; + + // The next timer known to the queue. + timer_base* next_; + + // The previous timer known to the queue. + timer_base* prev_; + + // The index of the timer in the heap. + size_t heap_index_; + }; + + // Adaptor class template for using handlers in timers. + template + class timer + : public timer_base + { + public: + // Constructor. + timer(const time_type& time, Handler handler, void* token) + : timer_base(&timer::invoke_handler, + &timer::destroy_handler, time, token), + handler_(handler) + { + } + + // Invoke the handler and then destroy it. + static void invoke_handler(timer_base* base, + const boost::system::error_code& result) + { + static_cast*>(base)->handler_(result); + } + + // Destroy the handler. + static void destroy_handler(timer_base* base) + { + delete static_cast*>(base); + } + + private: + Handler handler_; + }; + + // Move the item at the given index up the heap to its correct position. + void up_heap(size_t index) + { + size_t parent = (index - 1) / 2; + while (index > 0 + && Time_Traits::less_than(heap_[index]->time_, heap_[parent]->time_)) + { + swap_heap(index, parent); + index = parent; + parent = (index - 1) / 2; + } + } + + // Move the item at the given index down the heap to its correct position. + void down_heap(size_t index) + { + size_t child = index * 2 + 1; + while (child < heap_.size()) + { + size_t min_child = (child + 1 == heap_.size() + || Time_Traits::less_than( + heap_[child]->time_, heap_[child + 1]->time_)) + ? child : child + 1; + if (Time_Traits::less_than(heap_[index]->time_, heap_[min_child]->time_)) + break; + swap_heap(index, min_child); + index = min_child; + child = index * 2 + 1; + } + } + + // Swap two entries in the heap. + void swap_heap(size_t index1, size_t index2) + { + timer_base* tmp = heap_[index1]; + heap_[index1] = heap_[index2]; + heap_[index2] = tmp; + heap_[index1]->heap_index_ = index1; + heap_[index2]->heap_index_ = index2; + } + + // Remove a timer from the heap and list of timers. + void remove_timer(timer_base* t) + { + // Remove the timer from the heap. + size_t index = t->heap_index_; + if (!heap_.empty() && index < heap_.size()) + { + if (index == heap_.size() - 1) + { + heap_.pop_back(); + } + else + { + swap_heap(index, heap_.size() - 1); + heap_.pop_back(); + size_t parent = (index - 1) / 2; + if (index > 0 && Time_Traits::less_than( + heap_[index]->time_, heap_[parent]->time_)) + up_heap(index); + else + down_heap(index); + } + } + + // Remove the timer from the hash. + typedef typename hash_map::iterator iterator; + iterator it = timers_.find(t->token_); + if (it != timers_.end()) + { + if (it->second == t) + it->second = t->next_; + if (t->prev_) + t->prev_->next_ = t->next_; + if (t->next_) + t->next_->prev_ = t->prev_; + if (it->second == 0) + timers_.erase(it); + } + } + + // Destroy all timers in a linked list. + void destroy_timer_list(timer_base*& t) + { + while (t) + { + timer_base* next = t->next_; + t->next_ = 0; + t->destroy(); + t = next; + } + } + + // A hash of timer token to linked lists of timers. + hash_map timers_; + + // The heap of timers, with the earliest timer at the front. + std::vector heap_; + + // The list of timers to be cancelled. + timer_base* cancelled_timers_; + + // The list of timers to be destroyed. + timer_base* cleanup_timers_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_HPP diff --git a/thirdparty/boost/asio/detail/timer_queue_base.hpp b/thirdparty/boost/asio/detail/timer_queue_base.hpp new file mode 100644 index 0000000..b13bc05 --- /dev/null +++ b/thirdparty/boost/asio/detail/timer_queue_base.hpp @@ -0,0 +1,64 @@ +// +// timer_queue_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_TIMER_QUEUE_BASE_HPP +#define BOOST_ASIO_DETAIL_TIMER_QUEUE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include // Must come before posix_time. + +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +class timer_queue_base + : private noncopyable +{ +public: + // Destructor. + virtual ~timer_queue_base() {} + + // Whether there are no timers in the queue. + virtual bool empty() const = 0; + + // Get the time to wait until the next timer. + virtual boost::posix_time::time_duration wait_duration() const = 0; + + // Dispatch all ready timers. + virtual void dispatch_timers() = 0; + + // Dispatch any pending cancels for timers. + virtual void dispatch_cancellations() = 0; + + // Destroy timers that are waiting to be cleaned up. + virtual void cleanup_timers() = 0; + + // Destroy all timers. + virtual void destroy_timers() = 0; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_BASE_HPP diff --git a/thirdparty/boost/asio/detail/tss_ptr.hpp b/thirdparty/boost/asio/detail/tss_ptr.hpp new file mode 100644 index 0000000..2871e8d --- /dev/null +++ b/thirdparty/boost/asio/detail/tss_ptr.hpp @@ -0,0 +1,67 @@ +// +// tss_ptr.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_TSS_PTR_HPP +#define BOOST_ASIO_DETAIL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_WINDOWS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#else +# error Only Windows and POSIX are supported! +#endif + +namespace boost { +namespace asio { +namespace detail { + +template +class tss_ptr +#if !defined(BOOST_HAS_THREADS) + : public null_tss_ptr +#elif defined(BOOST_WINDOWS) + : public win_tss_ptr +#elif defined(BOOST_HAS_PTHREADS) + : public posix_tss_ptr +#endif +{ +public: + void operator=(T* value) + { +#if !defined(BOOST_HAS_THREADS) + null_tss_ptr::operator=(value); +#elif defined(BOOST_WINDOWS) + win_tss_ptr::operator=(value); +#elif defined(BOOST_HAS_PTHREADS) + posix_tss_ptr::operator=(value); +#endif + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_TSS_PTR_HPP diff --git a/thirdparty/boost/asio/detail/win_event.hpp b/thirdparty/boost/asio/detail/win_event.hpp new file mode 100644 index 0000000..289d378 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_event.hpp @@ -0,0 +1,105 @@ +// +// win_event.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_EVENT_HPP +#define BOOST_ASIO_DETAIL_WIN_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class win_event + : private noncopyable +{ +public: + // Constructor. + win_event() + : event_(::CreateEvent(0, true, false, 0)) + { + if (!event_) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "event"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_event() + { + ::CloseHandle(event_); + } + + // Signal the event. + template + void signal(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + ::SetEvent(event_); + } + + // Reset the event. + template + void clear(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + ::ResetEvent(event_); + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + lock.unlock(); + ::WaitForSingleObject(event_, INFINITE); + lock.lock(); + } + +private: + HANDLE event_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_EVENT_HPP diff --git a/thirdparty/boost/asio/detail/win_fd_set_adapter.hpp b/thirdparty/boost/asio/detail/win_fd_set_adapter.hpp new file mode 100644 index 0000000..b055a89 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_fd_set_adapter.hpp @@ -0,0 +1,90 @@ +// +// win_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP +#define BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +namespace boost { +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class win_fd_set_adapter +{ +public: + enum { win_fd_set_size = 1024 }; + + win_fd_set_adapter() + : max_descriptor_(invalid_socket) + { + fd_set_.fd_count = 0; + } + + bool set(socket_type descriptor) + { + for (u_int i = 0; i < fd_set_.fd_count; ++i) + if (fd_set_.fd_array[i] == descriptor) + return true; + if (fd_set_.fd_count < win_fd_set_size) + { + fd_set_.fd_array[fd_set_.fd_count++] = descriptor; + return true; + } + return false; + } + + bool is_set(socket_type descriptor) const + { + return !!__WSAFDIsSet(descriptor, + const_cast(reinterpret_cast(&fd_set_))); + } + + operator fd_set*() + { + return reinterpret_cast(&fd_set_); + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + +private: + // This structure is defined to be compatible with the Windows API fd_set + // structure, but without being dependent on the value of FD_SETSIZE. + struct win_fd_set + { + u_int fd_count; + SOCKET fd_array[win_fd_set_size]; + }; + + win_fd_set fd_set_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP diff --git a/thirdparty/boost/asio/detail/win_iocp_io_service.hpp b/thirdparty/boost/asio/detail/win_iocp_io_service.hpp new file mode 100644 index 0000000..6426a10 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_iocp_io_service.hpp @@ -0,0 +1,707 @@ +// +// win_iocp_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class win_iocp_io_service + : public boost::asio::detail::service_base +{ +public: + // Base class for all operations. A function pointer is used instead of + // virtual functions to avoid the associated overhead. + // + // This class inherits from OVERLAPPED so that we can downcast to get back to + // the operation pointer from the LPOVERLAPPED out parameter of + // GetQueuedCompletionStatus. + class operation + : public OVERLAPPED + { + public: + typedef void (*invoke_func_type)(operation*, DWORD, size_t); + typedef void (*destroy_func_type)(operation*); + + operation(win_iocp_io_service& iocp_service, + invoke_func_type invoke_func, destroy_func_type destroy_func) + : outstanding_operations_(&iocp_service.outstanding_operations_), + invoke_func_(invoke_func), + destroy_func_(destroy_func) + { + Internal = 0; + InternalHigh = 0; + Offset = 0; + OffsetHigh = 0; + hEvent = 0; + + ::InterlockedIncrement(outstanding_operations_); + } + + void do_completion(DWORD last_error, size_t bytes_transferred) + { + invoke_func_(this, last_error, bytes_transferred); + } + + void destroy() + { + destroy_func_(this); + } + + protected: + // Prevent deletion through this type. + ~operation() + { + ::InterlockedDecrement(outstanding_operations_); + } + + private: + long* outstanding_operations_; + invoke_func_type invoke_func_; + destroy_func_type destroy_func_; + }; + + + // Constructor. + win_iocp_io_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service), + iocp_(), + outstanding_work_(0), + outstanding_operations_(0), + stopped_(0), + shutdown_(0), + timer_thread_(0), + timer_interrupt_issued_(false) + { + } + + void init(size_t concurrency_hint) + { + iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, + static_cast((std::min)(concurrency_hint, DWORD(~0)))); + if (!iocp_.handle) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "iocp"); + boost::throw_exception(e); + } + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + ::InterlockedExchange(&shutdown_, 1); + + while (::InterlockedExchangeAdd(&outstanding_operations_, 0) > 0) + { + DWORD bytes_transferred = 0; +#if (WINVER < 0x0500) + DWORD completion_key = 0; +#else + DWORD_PTR completion_key = 0; +#endif + LPOVERLAPPED overlapped = 0; + ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, INFINITE); + if (overlapped) + static_cast(overlapped)->destroy(); + } + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + timer_queues_[i]->destroy_timers(); + timer_queues_.clear(); + } + + // Register a handle with the IO completion port. + void register_handle(HANDLE handle) + { + ::CreateIoCompletionPort(handle, iocp_.handle, 0, 0); + } + + // Run the event loop until stopped or no more work. + size_t run(boost::system::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + call_stack::context ctx(this); + + size_t n = 0; + while (do_one(true, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Run until stopped or one operation is performed. + size_t run_one(boost::system::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + call_stack::context ctx(this); + + return do_one(true, ec); + } + + // Poll for operations without blocking. + size_t poll(boost::system::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + call_stack::context ctx(this); + + size_t n = 0; + while (do_one(false, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Poll for one operation without blocking. + size_t poll_one(boost::system::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + call_stack::context ctx(this); + + return do_one(false, ec); + } + + // Stop the event processing loop. + void stop() + { + if (::InterlockedExchange(&stopped_, 1) == 0) + { + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "pqcs"); + boost::throw_exception(e); + } + } + } + + // Reset in preparation for a subsequent run invocation. + void reset() + { + ::InterlockedExchange(&stopped_, 0); + } + + // Notify that some work has started. + void work_started() + { + ::InterlockedIncrement(&outstanding_work_); + } + + // Notify that some work has finished. + void work_finished() + { + if (::InterlockedDecrement(&outstanding_work_) == 0) + stop(); + } + + // Request invocation of the given handler. + template + void dispatch(Handler handler) + { + if (call_stack::contains(this)) + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + else + post(handler); + } + + // Request invocation of the given handler and return immediately. + template + void post(Handler handler) + { + // If the service has been shut down we silently discard the handler. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return; + + // Allocate and construct an operation to wrap the handler. + typedef handler_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, *this, handler); + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get())) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "pqcs"); + boost::throw_exception(e); + } + + // Operation has been successfully posted. + ptr.release(); + } + + // Request invocation of the given OVERLAPPED-derived operation. + void post_completion(operation* op, DWORD op_last_error, + DWORD bytes_transferred) + { + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + bytes_transferred, op_last_error, op)) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "pqcs"); + boost::throw_exception(e); + } + } + + // Add a new timer queue to the service. + template + void add_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_queues_.push_back(&timer_queue); + } + + // Remove a timer queue from the service. + template + void remove_timer_queue(timer_queue& timer_queue) + { + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + if (timer_queues_[i] == &timer_queue) + { + timer_queues_.erase(timer_queues_.begin() + i); + return; + } + } + } + + // Schedule a timer in the given timer queue to expire at the specified + // absolute time. The handler object will be invoked when the timer expires. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, Handler handler, void* token) + { + // If the service has been shut down we silently discard the timer. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return; + + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + if (timer_queue.enqueue_timer(time, handler, token)) + { + if (!timer_interrupt_issued_) + { + timer_interrupt_issued_ = true; + lock.unlock(); + ::PostQueuedCompletionStatus(iocp_.handle, + 0, steal_timer_dispatching, 0); + } + } + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + // If the service has been shut down we silently ignore the cancellation. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return 0; + + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + std::size_t n = timer_queue.cancel_timer(token); + if (n > 0 && !timer_interrupt_issued_) + { + timer_interrupt_issued_ = true; + lock.unlock(); + ::PostQueuedCompletionStatus(iocp_.handle, + 0, steal_timer_dispatching, 0); + } + return n; + } + +private: + // Dequeues at most one operation from the I/O completion port, and then + // executes it. Returns the number of operations that were dequeued (i.e. + // either 0 or 1). + size_t do_one(bool block, boost::system::error_code& ec) + { + long this_thread_id = static_cast(::GetCurrentThreadId()); + + for (;;) + { + // Try to acquire responsibility for dispatching timers. + bool dispatching_timers = (::InterlockedCompareExchange( + &timer_thread_, this_thread_id, 0) == 0); + + // Calculate timeout for GetQueuedCompletionStatus call. + DWORD timeout = max_timeout; + if (dispatching_timers) + { + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_interrupt_issued_ = false; + timeout = get_timeout(); + } + + // Get the next operation from the queue. + DWORD bytes_transferred = 0; +#if (WINVER < 0x0500) + DWORD completion_key = 0; +#else + DWORD_PTR completion_key = 0; +#endif + LPOVERLAPPED overlapped = 0; + ::SetLastError(0); + BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, block ? timeout : 0); + DWORD last_error = ::GetLastError(); + + // Dispatch any pending timers. + if (dispatching_timers) + { + try + { + boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_queues_copy_ = timer_queues_; + for (std::size_t i = 0; i < timer_queues_copy_.size(); ++i) + { + timer_queues_copy_[i]->dispatch_timers(); + timer_queues_copy_[i]->dispatch_cancellations(); + timer_queues_copy_[i]->cleanup_timers(); + } + } + catch (...) + { + // Transfer responsibility for dispatching timers to another thread. + if (::InterlockedCompareExchange(&timer_thread_, + 0, this_thread_id) == this_thread_id) + { + ::PostQueuedCompletionStatus(iocp_.handle, + 0, transfer_timer_dispatching, 0); + } + + throw; + } + } + + if (!ok && overlapped == 0) + { + if (block && last_error == WAIT_TIMEOUT) + { + // Relinquish responsibility for dispatching timers. + if (dispatching_timers) + { + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + + continue; + } + + // Transfer responsibility for dispatching timers to another thread. + if (dispatching_timers && ::InterlockedCompareExchange( + &timer_thread_, 0, this_thread_id) == this_thread_id) + { + ::PostQueuedCompletionStatus(iocp_.handle, + 0, transfer_timer_dispatching, 0); + } + + ec = boost::system::error_code(); + return 0; + } + else if (overlapped) + { + // We may have been passed a last_error value in the completion_key. + if (last_error == 0) + { + last_error = completion_key; + } + + // Transfer responsibility for dispatching timers to another thread. + if (dispatching_timers && ::InterlockedCompareExchange( + &timer_thread_, 0, this_thread_id) == this_thread_id) + { + ::PostQueuedCompletionStatus(iocp_.handle, + 0, transfer_timer_dispatching, 0); + } + + // Ensure that the io_service does not exit due to running out of work + // while we make the upcall. + auto_work work(*this); + + // Dispatch the operation. + operation* op = static_cast(overlapped); + op->do_completion(last_error, bytes_transferred); + + ec = boost::system::error_code(); + return 1; + } + else if (completion_key == transfer_timer_dispatching) + { + // Woken up to try to acquire responsibility for dispatching timers. + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + else if (completion_key == steal_timer_dispatching) + { + // Woken up to steal responsibility for dispatching timers. + ::InterlockedExchange(&timer_thread_, 0); + } + else + { + // The stopped_ flag is always checked to ensure that any leftover + // interrupts from a previous run invocation are ignored. + if (::InterlockedExchangeAdd(&stopped_, 0) != 0) + { + // Relinquish responsibility for dispatching timers. + if (dispatching_timers) + { + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + + // Wake up next thread that is blocked on GetQueuedCompletionStatus. + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + ec = boost::system::error_code(); + return 0; + } + } + } + } + + // Check if all timer queues are empty. + bool all_timer_queues_are_empty() const + { + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + if (!timer_queues_[i]->empty()) + return false; + return true; + } + + // Get the timeout value for the GetQueuedCompletionStatus call. The timeout + // value is returned as a number of milliseconds. We will wait no longer than + // 1000 milliseconds. + DWORD get_timeout() + { + if (all_timer_queues_are_empty()) + return max_timeout; + + boost::posix_time::time_duration minimum_wait_duration + = boost::posix_time::milliseconds(max_timeout); + + for (std::size_t i = 0; i < timer_queues_.size(); ++i) + { + boost::posix_time::time_duration wait_duration + = timer_queues_[i]->wait_duration(); + if (wait_duration < minimum_wait_duration) + minimum_wait_duration = wait_duration; + } + + if (minimum_wait_duration > boost::posix_time::time_duration()) + { + int milliseconds = minimum_wait_duration.total_milliseconds(); + return static_cast(milliseconds > 0 ? milliseconds : 1); + } + else + { + return 0; + } + } + + struct auto_work + { + auto_work(win_iocp_io_service& io_service) + : io_service_(io_service) + { + io_service_.work_started(); + } + + ~auto_work() + { + io_service_.work_finished(); + } + + private: + win_iocp_io_service& io_service_; + }; + + template + struct handler_operation + : public operation + { + handler_operation(win_iocp_io_service& io_service, + Handler handler) + : operation(io_service, &handler_operation::do_completion_impl, + &handler_operation::destroy_impl), + io_service_(io_service), + handler_(handler) + { + io_service_.work_started(); + } + + ~handler_operation() + { + io_service_.work_finished(); + } + + private: + // Prevent copying and assignment. + handler_operation(const handler_operation&); + void operator=(const handler_operation&); + + static void do_completion_impl(operation* op, DWORD, size_t) + { + // Take ownership of the operation object. + typedef handler_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Make the upcall. + boost_asio_handler_invoke_helpers::invoke(handler, &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef handler_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + win_iocp_io_service& io_service_; + Handler handler_; + }; + + // The IO completion port used for queueing operations. + struct iocp_holder + { + HANDLE handle; + iocp_holder() : handle(0) {} + ~iocp_holder() { if (handle) ::CloseHandle(handle); } + } iocp_; + + // The count of unfinished work. + long outstanding_work_; + + // The count of unfinished operations. + long outstanding_operations_; + friend class operation; + + // Flag to indicate whether the event loop has been stopped. + long stopped_; + + // Flag to indicate whether the service has been shut down. + long shutdown_; + + enum + { + // Maximum GetQueuedCompletionStatus timeout, in milliseconds. + max_timeout = 500, + + // Completion key value to indicate that responsibility for dispatching + // timers is being cooperatively transferred from one thread to another. + transfer_timer_dispatching = 1, + + // Completion key value to indicate that responsibility for dispatching + // timers should be stolen from another thread. + steal_timer_dispatching = 2 + }; + + // The thread that's currently in charge of dispatching timers. + long timer_thread_; + + // Mutex for protecting access to the timer queues. + mutex timer_mutex_; + + // Whether a thread has been interrupted to process a new timeout. + bool timer_interrupt_issued_; + + // The timer queues. + std::vector timer_queues_; + + // A copy of the timer queues, used when dispatching, cancelling and cleaning + // up timers. The copy is stored as a class data member to avoid unnecessary + // memory allocation. + std::vector timer_queues_copy_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/win_iocp_io_service_fwd.hpp b/thirdparty/boost/asio/detail/win_iocp_io_service_fwd.hpp new file mode 100644 index 0000000..04f4d6c --- /dev/null +++ b/thirdparty/boost/asio/detail/win_iocp_io_service_fwd.hpp @@ -0,0 +1,52 @@ +// +// win_iocp_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include + +// This service is only supported on Win32 (NT4 and later). +#if !defined(BOOST_ASIO_DISABLE_IOCP) +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +#if !defined(UNDER_CE) + +// Define this to indicate that IOCP is supported on the target platform. +#define BOOST_ASIO_HAS_IOCP 1 + +namespace boost { +namespace asio { +namespace detail { + +class win_iocp_io_service; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // !defined(UNDER_CE) +#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_DISABLE_IOCP) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP diff --git a/thirdparty/boost/asio/detail/win_iocp_socket_service.hpp b/thirdparty/boost/asio/detail/win_iocp_socket_service.hpp new file mode 100644 index 0000000..8129706 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_iocp_socket_service.hpp @@ -0,0 +1,2093 @@ +// +// win_iocp_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class win_iocp_socket_service + : public boost::asio::detail::service_base > +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // Base class for all operations. + typedef win_iocp_io_service::operation operation; + + struct noop_deleter { void operator()(void*) {} }; + typedef boost::shared_ptr shared_cancel_token_type; + typedef boost::weak_ptr weak_cancel_token_type; + + // The native type of a socket. + class native_type + { + public: + native_type(socket_type s) + : socket_(s), + have_remote_endpoint_(false) + { + } + + native_type(socket_type s, const endpoint_type& ep) + : socket_(s), + have_remote_endpoint_(true), + remote_endpoint_(ep) + { + } + + void operator=(socket_type s) + { + socket_ = s; + have_remote_endpoint_ = false; + remote_endpoint_ = endpoint_type(); + } + + operator socket_type() const + { + return socket_; + } + + HANDLE as_handle() const + { + return reinterpret_cast(socket_); + } + + bool have_remote_endpoint() const + { + return have_remote_endpoint_; + } + + endpoint_type remote_endpoint() const + { + return remote_endpoint_; + } + + private: + socket_type socket_; + bool have_remote_endpoint_; + endpoint_type remote_endpoint_; + }; + + // The implementation type of the socket. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : socket_(invalid_socket), + flags_(0), + cancel_token_(), + protocol_(endpoint_type().protocol()), + next_(0), + prev_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class win_iocp_socket_service; + + // The native socket representation. + native_type socket_; + + enum + { + enable_connection_aborted = 1, // User wants connection_aborted errors. + close_might_block = 2, // User set linger option for blocking close. + user_set_non_blocking = 4 // The user wants a non-blocking socket. + }; + + // Flags indicating the current state of the socket. + unsigned char flags_; + + // We use a shared pointer as a cancellation token here to work around the + // broken Windows support for cancellation. MSDN says that when you call + // closesocket any outstanding WSARecv or WSASend operations will complete + // with the error ERROR_OPERATION_ABORTED. In practice they complete with + // ERROR_NETNAME_DELETED, which means you can't tell the difference between + // a local cancellation and the socket being hard-closed by the peer. + shared_cancel_token_type cancel_token_; + + // The protocol associated with the socket. + protocol_type protocol_; + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the socket. + DWORD safe_cancellation_thread_id_; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Pointers to adjacent socket implementations in linked list. + implementation_type* next_; + implementation_type* prev_; + }; + + // The type of the reactor used for connect operations. + typedef detail::select_reactor reactor_type; + + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + + // Constructor. + win_iocp_socket_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + win_iocp_socket_service >(io_service), + iocp_service_(boost::asio::use_service(io_service)), + reactor_(0), + mutex_(), + impl_list_(0) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + // Close all implementations, causing all operations to complete. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + implementation_type* impl = impl_list_; + while (impl) + { + boost::system::error_code ignored_ec; + close_for_destruction(*impl); + impl = impl->next_; + } + } + + // Construct a new socket implementation. + void construct(implementation_type& impl) + { + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; + } + + // Destroy a socket implementation. + void destroy(implementation_type& impl) + { + close_for_destruction(impl); + + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; + } + + // Open a new socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(), + protocol.protocol(), ec)); + if (sock.get() == invalid_socket) + return ec; + + HANDLE sock_as_handle = reinterpret_cast(sock.get()); + iocp_service_.register_handle(sock_as_handle); + + impl.socket_ = sock.release(); + impl.flags_ = 0; + impl.cancel_token_.reset(static_cast(0), noop_deleter()); + impl.protocol_ = protocol; + ec = boost::system::error_code(); + return ec; + } + + // Assign a native socket to a socket implementation. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) + { + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + iocp_service_.register_handle(native_socket.as_handle()); + + impl.socket_ = native_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(static_cast(0), noop_deleter()); + impl.protocol_ = protocol; + ec = boost::system::error_code(); + return ec; + } + + // Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor_type* reactor = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (reactor) + reactor->close_descriptor(impl.socket_); + + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; + + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + } + + ec = boost::system::error_code(); + return ec; + } + + // Get the native socket representation. + native_type native(implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + } + else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( + ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) + { + // The version of Windows supports cancellation from any thread. + typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); + cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast(sock); + if (!cancel_io_ex(sock_as_handle, 0)) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_NOT_FOUND) + { + // ERROR_NOT_FOUND means that there were no operations to be + // cancelled. We swallow this error to match the behaviour on other + // platforms. + ec = boost::system::error_code(); + } + else + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + } + else + { + ec = boost::system::error_code(); + } + } +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + else if (impl.safe_cancellation_thread_id_ == 0) + { + // No operations have been started, so there's nothing to cancel. + ec = boost::system::error_code(); + } + else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) + { + // Asynchronous operations have been started from the current thread only, + // so it is safe to try to cancel them using CancelIo. + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast(sock); + if (!::CancelIo(sock_as_handle)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + else + { + ec = boost::system::error_code(); + } + } + else + { + // Asynchronous operations have been started from more than one thread, + // so cancellation is not safe. + ec = boost::asio::error::operation_not_supported; + } +#else // defined(BOOST_ASIO_ENABLE_CANCELIO) + else + { + // Cancellation is not supported as CancelIo may not be used. + ec = boost::asio::error::operation_not_supported; + } +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return false; + } + + boost::asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); + return ec ? false : value != 0; + } + + // Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + boost::asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); + return ec ? static_cast(0) : static_cast(value); + } + + // Bind the socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + } + else + { + if (*reinterpret_cast(option.data(impl.protocol_))) + impl.flags_ |= implementation_type::enable_connection_aborted; + else + impl.flags_ &= ~implementation_type::enable_connection_aborted; + ec = boost::system::error_code(); + } + return ec; + } + else + { + if (option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_LINGER) + { + const ::linger* linger_option = + reinterpret_cast(option.data(impl.protocol_)); + if (linger_option->l_onoff != 0 && linger_option->l_linger != 0) + impl.flags_ |= implementation_type::close_might_block; + else + impl.flags_ &= ~implementation_type::close_might_block; + } + + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; + } + } + + // Set a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + } + else + { + int* target = reinterpret_cast(option.data(impl.protocol_)); + if (impl.flags_ & implementation_type::enable_connection_aborted) + *target = 1; + else + *target = 0; + option.resize(impl.protocol_, sizeof(int)); + ec = boost::system::error_code(); + } + return ec; + } + else + { + size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + } + + // Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); + + if (!ec && command.name() == static_cast(FIONBIO)) + { + if (command.get()) + impl.flags_ |= implementation_type::user_set_non_blocking; + else + impl.flags_ &= ~implementation_type::user_set_non_blocking; + } + + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return endpoint_type(); + } + + if (impl.socket_.have_remote_endpoint()) + { + // Check if socket is still connected. + DWORD connect_time = 0; + size_t connect_time_len = sizeof(connect_time); + if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME, + &connect_time, &connect_time_len, ec) == socket_error_retval) + { + return endpoint_type(); + } + if (connect_time == 0xFFFFFFFF) + { + ec = boost::asio::error::not_connected; + return endpoint_type(); + } + + ec = boost::system::error_code(); + return impl.socket_.remote_endpoint(); + } + else + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. Returns the number of bytes sent. + template + size_t send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = const_cast( + boost::asio::buffer_cast(buffer)); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + ec = boost::system::error_code(); + return 0; + } + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASend(impl.socket_, bufs, + i, &bytes_transferred, flags, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; + } + + template + class send_operation + : public operation + { + public: + send_operation(win_iocp_io_service& io_service, + weak_cancel_token_type cancel_token, + const ConstBufferSequence& buffers, Handler handler) + : operation(io_service, + &send_operation::do_completion_impl, + &send_operation::destroy_impl), + work_(io_service.get_io_service()), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + private: + static void do_completion_impl(operation* op, + DWORD last_error, size_t bytes_transferred) + { + // Take ownership of the operation object. + typedef send_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + typename ConstBufferSequence::const_iterator iter + = handler_op->buffers_.begin(); + typename ConstBufferSequence::const_iterator end + = handler_op->buffers_.end(); + while (iter != end) + { + boost::asio::const_buffer buffer(*iter); + boost::asio::buffer_cast(buffer); + ++iter; + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (handler_op->cancel_token_.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Call the handler. + boost_asio_handler_invoke_helpers::invoke( + detail::bind_handler(handler, ec, bytes_transferred), &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef send_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + boost::asio::io_service::work work_; + weak_cancel_token_type cancel_token_; + ConstBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Allocate and construct an operation to wrap the handler. + typedef send_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, iocp_service_, + impl.cancel_token_, buffers, handler); + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = const_cast( + boost::asio::buffer_cast(buffer)); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code error; + iocp_service_.post(bind_handler(handler, error, 0)); + return; + } + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASend(impl.socket_, bufs, i, + &bytes_transferred, flags, ptr.get(), 0); + DWORD last_error = ::WSAGetLastError(); + + // Check if the operation completed immediately. + if (result != 0 && last_error != WSA_IO_PENDING) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); + } + else + { + ptr.release(); + } + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = const_cast( + boost::asio::buffer_cast(buffer)); + } + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASendTo(impl.socket_, bufs, i, &bytes_transferred, + flags, destination.data(), static_cast(destination.size()), 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; + } + + template + class send_to_operation + : public operation + { + public: + send_to_operation(win_iocp_io_service& io_service, + const ConstBufferSequence& buffers, Handler handler) + : operation(io_service, + &send_to_operation::do_completion_impl, + &send_to_operation::destroy_impl), + work_(io_service.get_io_service()), + buffers_(buffers), + handler_(handler) + { + } + + private: + static void do_completion_impl(operation* op, + DWORD last_error, size_t bytes_transferred) + { + // Take ownership of the operation object. + typedef send_to_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + typename ConstBufferSequence::const_iterator iter + = handler_op->buffers_.begin(); + typename ConstBufferSequence::const_iterator end + = handler_op->buffers_.end(); + while (iter != end) + { + boost::asio::const_buffer buffer(*iter); + boost::asio::buffer_cast(buffer); + ++iter; + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Call the handler. + boost_asio_handler_invoke_helpers::invoke( + detail::bind_handler(handler, ec, bytes_transferred), &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef send_to_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + boost::asio::io_service::work work_; + ConstBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Allocate and construct an operation to wrap the handler. + typedef send_to_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, iocp_service_, buffers, handler); + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::const_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = const_cast( + boost::asio::buffer_cast(buffer)); + } + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASendTo(impl.socket_, bufs, i, &bytes_transferred, flags, + destination.data(), static_cast(destination.size()), ptr.get(), 0); + DWORD last_error = ::WSAGetLastError(); + + // Check if the operation completed immediately. + if (result != 0 && last_error != WSA_IO_PENDING) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); + } + else + { + ptr.release(); + } + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = boost::asio::buffer_cast(buffer); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + ec = boost::system::error_code(); + return 0; + } + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecv(impl.socket_, bufs, i, + &bytes_transferred, &recv_flags, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + if (bytes_transferred == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; + } + + template + class receive_operation + : public operation + { + public: + receive_operation(win_iocp_io_service& io_service, + weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler handler) + : operation(io_service, + &receive_operation< + MutableBufferSequence, Handler>::do_completion_impl, + &receive_operation< + MutableBufferSequence, Handler>::destroy_impl), + work_(io_service.get_io_service()), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + private: + static void do_completion_impl(operation* op, + DWORD last_error, size_t bytes_transferred) + { + // Take ownership of the operation object. + typedef receive_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + typename MutableBufferSequence::const_iterator iter + = handler_op->buffers_.begin(); + typename MutableBufferSequence::const_iterator end + = handler_op->buffers_.end(); + while (iter != end) + { + boost::asio::mutable_buffer buffer(*iter); + boost::asio::buffer_cast(buffer); + ++iter; + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (handler_op->cancel_token_.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Check for connection closed. + else if (!ec && bytes_transferred == 0) + { + ec = boost::asio::error::eof; + } + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Call the handler. + boost_asio_handler_invoke_helpers::invoke( + detail::bind_handler(handler, ec, bytes_transferred), &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef receive_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + boost::asio::io_service::work work_; + weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Allocate and construct an operation to wrap the handler. + typedef receive_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, iocp_service_, + impl.cancel_token_, buffers, handler); + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + size_t total_buffer_size = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = boost::asio::buffer_cast(buffer); + total_buffer_size += boost::asio::buffer_size(buffer); + } + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code error; + iocp_service_.post(bind_handler(handler, error, 0)); + return; + } + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecv(impl.socket_, bufs, i, + &bytes_transferred, &recv_flags, ptr.get(), 0); + DWORD last_error = ::WSAGetLastError(); + if (result != 0 && last_error != WSA_IO_PENDING) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); + } + else + { + ptr.release(); + } + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = boost::asio::buffer_cast(buffer); + } + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int endpoint_size = static_cast(sender_endpoint.capacity()); + int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred, + &recv_flags, sender_endpoint.data(), &endpoint_size, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + if (bytes_transferred == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + sender_endpoint.resize(static_cast(endpoint_size)); + + ec = boost::system::error_code(); + return bytes_transferred; + } + + template + class receive_from_operation + : public operation + { + public: + receive_from_operation(win_iocp_io_service& io_service, + endpoint_type& endpoint, const MutableBufferSequence& buffers, + Handler handler) + : operation(io_service, + &receive_from_operation< + MutableBufferSequence, Handler>::do_completion_impl, + &receive_from_operation< + MutableBufferSequence, Handler>::destroy_impl), + endpoint_(endpoint), + endpoint_size_(static_cast(endpoint.capacity())), + work_(io_service.get_io_service()), + buffers_(buffers), + handler_(handler) + { + } + + int& endpoint_size() + { + return endpoint_size_; + } + + private: + static void do_completion_impl(operation* op, + DWORD last_error, size_t bytes_transferred) + { + // Take ownership of the operation object. + typedef receive_from_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + typename MutableBufferSequence::const_iterator iter + = handler_op->buffers_.begin(); + typename MutableBufferSequence::const_iterator end + = handler_op->buffers_.end(); + while (iter != end) + { + boost::asio::mutable_buffer buffer(*iter); + boost::asio::buffer_cast(buffer); + ++iter; + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Check for connection closed. + if (!ec && bytes_transferred == 0) + { + ec = boost::asio::error::eof; + } + + // Record the size of the endpoint returned by the operation. + handler_op->endpoint_.resize(handler_op->endpoint_size_); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Call the handler. + boost_asio_handler_invoke_helpers::invoke( + detail::bind_handler(handler, ec, bytes_transferred), &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef receive_from_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + endpoint_type& endpoint_; + int endpoint_size_; + boost::asio::io_service::work work_; + MutableBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endp, + socket_base::message_flags flags, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Allocate and construct an operation to wrap the handler. + typedef receive_from_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, iocp_service_, + sender_endp, buffers, handler); + + // Copy buffers into WSABUF array. + ::WSABUF bufs[max_buffers]; + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + DWORD i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + { + boost::asio::mutable_buffer buffer(*iter); + bufs[i].len = static_cast(boost::asio::buffer_size(buffer)); + bufs[i].buf = boost::asio::buffer_cast(buffer); + } + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred, + &recv_flags, sender_endp.data(), &ptr.get()->endpoint_size(), + ptr.get(), 0); + DWORD last_error = ::WSAGetLastError(); + if (result != 0 && last_error != WSA_IO_PENDING) + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); + } + else + { + ptr.release(); + } + } + + // Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = boost::asio::error::already_open; + return ec; + } + + for (;;) + { + boost::system::error_code ec; + socket_holder new_socket; + std::size_t addr_len = 0; + if (peer_endpoint) + { + addr_len = peer_endpoint->capacity(); + new_socket.reset(socket_ops::accept(impl.socket_, + peer_endpoint->data(), &addr_len, ec)); + } + else + { + new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); + } + + if (ec) + { + if (ec == boost::asio::error::connection_aborted + && !(impl.flags_ & implementation_type::enable_connection_aborted)) + { + // Retry accept operation. + continue; + } + else + { + return ec; + } + } + + if (peer_endpoint) + peer_endpoint->resize(addr_len); + + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + return ec; + } + } + + template + class accept_operation + : public operation + { + public: + accept_operation(win_iocp_io_service& io_service, + socket_type socket, socket_type new_socket, Socket& peer, + const protocol_type& protocol, endpoint_type* peer_endpoint, + bool enable_connection_aborted, Handler handler) + : operation(io_service, + &accept_operation::do_completion_impl, + &accept_operation::destroy_impl), + io_service_(io_service), + socket_(socket), + new_socket_(new_socket), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + work_(io_service.get_io_service()), + enable_connection_aborted_(enable_connection_aborted), + handler_(handler) + { + } + + socket_type new_socket() + { + return new_socket_.get(); + } + + void* output_buffer() + { + return output_buffer_; + } + + DWORD address_length() + { + return sizeof(sockaddr_storage_type) + 16; + } + + private: + static void do_completion_impl(operation* op, + DWORD last_error, size_t bytes_transferred) + { + // Take ownership of the operation object. + typedef accept_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + + // Map Windows error ERROR_NETNAME_DELETED to connection_aborted. + if (last_error == ERROR_NETNAME_DELETED) + { + last_error = WSAECONNABORTED; + } + + // Restart the accept operation if we got the connection_aborted error + // and the enable_connection_aborted socket option is not set. + if (last_error == WSAECONNABORTED + && !ptr.get()->enable_connection_aborted_) + { + // Reset OVERLAPPED structure. + ptr.get()->Internal = 0; + ptr.get()->InternalHigh = 0; + ptr.get()->Offset = 0; + ptr.get()->OffsetHigh = 0; + ptr.get()->hEvent = 0; + + // Create a new socket for the next connection, since the AcceptEx call + // fails with WSAEINVAL if we try to reuse the same socket. + boost::system::error_code ec; + ptr.get()->new_socket_.reset(); + ptr.get()->new_socket_.reset(socket_ops::socket( + ptr.get()->protocol_.family(), ptr.get()->protocol_.type(), + ptr.get()->protocol_.protocol(), ec)); + if (ptr.get()->new_socket() != invalid_socket) + { + // Accept a connection. + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(ptr.get()->socket_, ptr.get()->new_socket(), + ptr.get()->output_buffer(), 0, ptr.get()->address_length(), + ptr.get()->address_length(), &bytes_read, ptr.get()); + last_error = ::WSAGetLastError(); + + // Check if the operation completed immediately. + if (!result && last_error != WSA_IO_PENDING) + { + if (last_error == ERROR_NETNAME_DELETED + || last_error == WSAECONNABORTED) + { + // Post this handler so that operation will be restarted again. + ptr.get()->io_service_.post_completion(ptr.get(), last_error, 0); + ptr.release(); + return; + } + else + { + // Operation already complete. Continue with rest of this handler. + } + } + else + { + // Asynchronous operation has been successfully restarted. + ptr.release(); + return; + } + } + } + + // Get the address of the peer. + endpoint_type peer_endpoint; + if (last_error == 0) + { + LPSOCKADDR local_addr = 0; + int local_addr_length = 0; + LPSOCKADDR remote_addr = 0; + int remote_addr_length = 0; + GetAcceptExSockaddrs(handler_op->output_buffer(), 0, + handler_op->address_length(), handler_op->address_length(), + &local_addr, &local_addr_length, &remote_addr, &remote_addr_length); + if (static_cast(remote_addr_length) + > peer_endpoint.capacity()) + { + last_error = WSAEINVAL; + } + else + { + using namespace std; // For memcpy. + memcpy(peer_endpoint.data(), remote_addr, remote_addr_length); + peer_endpoint.resize(static_cast(remote_addr_length)); + } + } + + // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname + // and getpeername will work on the accepted socket. + if (last_error == 0) + { + SOCKET update_ctx_param = handler_op->socket_; + boost::system::error_code ec; + if (socket_ops::setsockopt(handler_op->new_socket_.get(), + SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + &update_ctx_param, sizeof(SOCKET), ec) != 0) + { + last_error = ec.value(); + } + } + + // If the socket was successfully accepted, transfer ownership of the + // socket to the peer object. + if (last_error == 0) + { + boost::system::error_code ec; + handler_op->peer_.assign(handler_op->protocol_, + native_type(handler_op->new_socket_.get(), peer_endpoint), ec); + if (ec) + last_error = ec.value(); + else + handler_op->new_socket_.release(); + } + + // Pass endpoint back to caller. + if (handler_op->peer_endpoint_) + *handler_op->peer_endpoint_ = peer_endpoint; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(handler_op->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Call the handler. + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost_asio_handler_invoke_helpers::invoke( + detail::bind_handler(handler, ec), &handler); + } + + static void destroy_impl(operation* op) + { + // Take ownership of the operation object. + typedef accept_operation op_type; + op_type* handler_op(static_cast(op)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(handler_op->handler_, handler_op); + } + + win_iocp_io_service& io_service_; + socket_type socket_; + socket_holder new_socket_; + Socket& peer_; + protocol_type protocol_; + endpoint_type* peer_endpoint_; + boost::asio::io_service::work work_; + unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; + bool enable_connection_aborted_; + Handler handler_; + }; + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler handler) + { + // Check whether acceptor has been initialised. + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); + return; + } + + // Check that peer socket has not already been opened. + if (peer.is_open()) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::already_open)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Create a new socket for the connection. + boost::system::error_code ec; + socket_holder sock(socket_ops::socket(impl.protocol_.family(), + impl.protocol_.type(), impl.protocol_.protocol(), ec)); + if (sock.get() == invalid_socket) + { + this->get_io_service().post(bind_handler(handler, ec)); + return; + } + + // Allocate and construct an operation to wrap the handler. + typedef accept_operation value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + socket_type new_socket = sock.get(); + bool enable_connection_aborted = + (impl.flags_ & implementation_type::enable_connection_aborted); + handler_ptr ptr(raw_ptr, + iocp_service_, impl.socket_, new_socket, peer, impl.protocol_, + peer_endpoint, enable_connection_aborted, handler); + sock.release(); + + // Accept a connection. + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(impl.socket_, ptr.get()->new_socket(), + ptr.get()->output_buffer(), 0, ptr.get()->address_length(), + ptr.get()->address_length(), &bytes_read, ptr.get()); + DWORD last_error = ::WSAGetLastError(); + + // Check if the operation completed immediately. + if (!result && last_error != WSA_IO_PENDING) + { + if (!enable_connection_aborted + && (last_error == ERROR_NETNAME_DELETED + || last_error == WSAECONNABORTED)) + { + // Post handler so that operation will be restarted again. We do not + // perform the AcceptEx again here to avoid the possibility of starving + // other handlers. + iocp_service_.post_completion(ptr.get(), last_error, 0); + ptr.release(); + } + else + { + boost::asio::io_service::work work(this->get_io_service()); + ptr.reset(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + iocp_service_.post(bind_handler(handler, ec)); + } + } + else + { + ptr.release(); + } + } + + // Connect the socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + // Perform the connect operation. + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; + } + + template + class connect_handler + { + public: + connect_handler(socket_type socket, bool user_set_non_blocking, + boost::shared_ptr completed, + boost::asio::io_service& io_service, + reactor_type& reactor, Handler handler) + : socket_(socket), + user_set_non_blocking_(user_set_non_blocking), + completed_(completed), + io_service_(io_service), + reactor_(reactor), + work_(io_service), + handler_(handler) + { + } + + bool operator()(const boost::system::error_code& result) + { + // Check whether a handler has already been called for the connection. + // If it has, then we don't want to do anything in this handler. + if (*completed_) + return true; + + // Cancel the other reactor operation for the connection. + *completed_ = true; + reactor_.enqueue_cancel_ops_unlocked(socket_); + + // Check whether the operation was successful. + if (result) + { + io_service_.post(bind_handler(handler_, result)); + return true; + } + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + boost::system::error_code ec; + if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, ec) == socket_error_retval) + { + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + // If connection failed then post the handler with the error code. + if (connect_error) + { + ec = boost::system::error_code(connect_error, + boost::asio::error::get_system_category()); + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + // Revert socket to blocking mode unless the user requested otherwise. + if (!user_set_non_blocking_) + { + ioctl_arg_type non_blocking = 0; + if (socket_ops::ioctl(socket_, FIONBIO, &non_blocking, ec)) + { + io_service_.post(bind_handler(handler_, ec)); + return true; + } + } + + // Post the result of the successful connection operation. + ec = boost::system::error_code(); + io_service_.post(bind_handler(handler_, ec)); + return true; + } + + private: + socket_type socket_; + bool user_set_non_blocking_; + boost::shared_ptr completed_; + boost::asio::io_service& io_service_; + reactor_type& reactor_; + boost::asio::io_service::work work_; + Handler handler_; + }; + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler handler) + { + if (!is_open(impl)) + { + this->get_io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); + return; + } + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // Update the ID of the thread from which cancellation is safe. + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Check if the reactor was already obtained from the io_service. + reactor_type* reactor = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (!reactor) + { + reactor = &(boost::asio::use_service( + this->get_io_service())); + interlocked_exchange_pointer( + reinterpret_cast(&reactor_), reactor); + } + + // Mark the socket as non-blocking so that the connection will take place + // asynchronously. + ioctl_arg_type non_blocking = 1; + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + { + this->get_io_service().post(bind_handler(handler, ec)); + return; + } + + // Start the connect operation. + if (socket_ops::connect(impl.socket_, peer_endpoint.data(), + peer_endpoint.size(), ec) == 0) + { + // Revert socket to blocking mode unless the user requested otherwise. + if (!(impl.flags_ & implementation_type::user_set_non_blocking)) + { + non_blocking = 0; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec); + } + + // The connect operation has finished successfully so we need to post the + // handler immediately. + this->get_io_service().post(bind_handler(handler, ec)); + } + else if (ec == boost::asio::error::in_progress + || ec == boost::asio::error::would_block) + { + // The connection is happening in the background, and we need to wait + // until the socket becomes writeable. + boost::shared_ptr completed(new bool(false)); + reactor->start_write_and_except_ops(impl.socket_, + connect_handler( + impl.socket_, + (impl.flags_ & implementation_type::user_set_non_blocking) != 0, + completed, this->get_io_service(), *reactor, handler)); + } + else + { + // Revert socket to blocking mode unless the user requested otherwise. + if (!(impl.flags_ & implementation_type::user_set_non_blocking)) + { + non_blocking = 0; + boost::system::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); + } + + // The connect operation has failed, so post the handler immediately. + this->get_io_service().post(bind_handler(handler, ec)); + } + } + +private: + // Helper function to close a socket when the associated object is being + // destroyed. + void close_for_destruction(implementation_type& impl) + { + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor_type* reactor = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (reactor) + reactor->close_descriptor(impl.socket_); + + // The socket destructor must not block. If the user has changed the + // linger option to block in the foreground, we will change it back to the + // default so that the closure is performed in the background. + if (impl.flags_ & implementation_type::close_might_block) + { + ::linger opt; + opt.l_onoff = 0; + opt.l_linger = 0; + boost::system::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); + } + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + } + } + + // Helper function to emulate InterlockedCompareExchangePointer functionality + // for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp) + { +#if defined(_M_IX86) + return reinterpret_cast(InterlockedCompareExchange( + reinterpret_cast(dest), reinterpret_cast(exch), + reinterpret_cast(cmp))); +#else + return InterlockedCompareExchangePointer(dest, exch, cmp); +#endif + } + + // Helper function to emulate InterlockedExchangePointer functionality for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + void* interlocked_exchange_pointer(void** dest, void* val) + { +#if defined(_M_IX86) + return reinterpret_cast(InterlockedExchange( + reinterpret_cast(dest), reinterpret_cast(val))); +#else + return InterlockedExchangePointer(dest, val); +#endif + } + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_service& iocp_service_; + + // The reactor used for performing connect operations. This object is created + // only if needed. + reactor_type* reactor_; + + // Mutex to protect access to the linked list of implementations. + boost::asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP diff --git a/thirdparty/boost/asio/detail/win_mutex.hpp b/thirdparty/boost/asio/detail/win_mutex.hpp new file mode 100644 index 0000000..4c83a4c --- /dev/null +++ b/thirdparty/boost/asio/detail/win_mutex.hpp @@ -0,0 +1,151 @@ +// +// win_mutex.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_MUTEX_HPP +#define BOOST_ASIO_DETAIL_WIN_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +class win_mutex + : private noncopyable +{ +public: + typedef boost::asio::detail::scoped_lock scoped_lock; + + // Constructor. + win_mutex() + { + int error = do_init(); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_mutex() + { + ::DeleteCriticalSection(&crit_section_); + } + + // Lock the mutex. + void lock() + { + int error = do_lock(); + if (error != 0) + { + boost::system::system_error e( + boost::system::error_code(error, + boost::asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Unlock the mutex. + void unlock() + { + ::LeaveCriticalSection(&crit_section_); + } + +private: + // Initialisation must be performed in a separate function to the constructor + // since the compiler does not support the use of structured exceptions and + // C++ exceptions in the same function. + int do_init() + { +#if defined(__MINGW32__) + // Not sure if MinGW supports structured exception handling, so for now + // we'll just call the Windows API and hope. + ::InitializeCriticalSection(&crit_section_); + return 0; +#else + __try + { + ::InitializeCriticalSection(&crit_section_); + } + __except(GetExceptionCode() == STATUS_NO_MEMORY + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + return ERROR_OUTOFMEMORY; + } + + return 0; +#endif + } + + // Locking must be performed in a separate function to lock() since the + // compiler does not support the use of structured exceptions and C++ + // exceptions in the same function. + int do_lock() + { +#if defined(__MINGW32__) + // Not sure if MinGW supports structured exception handling, so for now + // we'll just call the Windows API and hope. + ::EnterCriticalSection(&crit_section_); + return 0; +#else + __try + { + ::EnterCriticalSection(&crit_section_); + } + __except(GetExceptionCode() == STATUS_INVALID_HANDLE + || GetExceptionCode() == STATUS_NO_MEMORY + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + if (GetExceptionCode() == STATUS_NO_MEMORY) + return ERROR_OUTOFMEMORY; + return ERROR_INVALID_HANDLE; + } + + return 0; +#endif + } + + ::CRITICAL_SECTION crit_section_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_MUTEX_HPP diff --git a/thirdparty/boost/asio/detail/win_signal_blocker.hpp b/thirdparty/boost/asio/detail/win_signal_blocker.hpp new file mode 100644 index 0000000..7820608 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_signal_blocker.hpp @@ -0,0 +1,69 @@ +// +// win_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP +#define BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class win_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + win_signal_blocker() + { + // No-op. + } + + // Destructor restores the previous signal mask. + ~win_signal_blocker() + { + // No-op. + } + + // Block all signals for the calling thread. + void block() + { + // No-op. + } + + // Restore the previous signal mask. + void unblock() + { + // No-op. + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP diff --git a/thirdparty/boost/asio/detail/win_thread.hpp b/thirdparty/boost/asio/detail/win_thread.hpp new file mode 100644 index 0000000..c1e7023 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_thread.hpp @@ -0,0 +1,127 @@ +// +// win_thread.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_THREAD_HPP +#define BOOST_ASIO_DETAIL_WIN_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +unsigned int __stdcall win_thread_function(void* arg); + +class win_thread + : private noncopyable +{ +public: + // Constructor. + template + win_thread(Function f) + { + std::auto_ptr arg(new func(f)); + unsigned int thread_id = 0; + thread_ = reinterpret_cast(::_beginthreadex(0, 0, + win_thread_function, arg.get(), 0, &thread_id)); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + } + + // Destructor. + ~win_thread() + { + ::CloseHandle(thread_); + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObject(thread_, INFINITE); + } + +private: + friend unsigned int __stdcall win_thread_function(void* arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; +}; + +inline unsigned int __stdcall win_thread_function(void* arg) +{ + std::auto_ptr func( + static_cast(arg)); + func->run(); + return 0; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_THREAD_HPP diff --git a/thirdparty/boost/asio/detail/win_tss_ptr.hpp b/thirdparty/boost/asio/detail/win_tss_ptr.hpp new file mode 100644 index 0000000..9810693 --- /dev/null +++ b/thirdparty/boost/asio/detail/win_tss_ptr.hpp @@ -0,0 +1,97 @@ +// +// win_tss_ptr.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_TSS_PTR_HPP +#define BOOST_ASIO_DETAIL_WIN_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) + +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class win_tss_ptr + : private noncopyable +{ +public: +#if defined(UNDER_CE) + enum { out_of_indexes = 0xFFFFFFFF }; +#else + enum { out_of_indexes = TLS_OUT_OF_INDEXES }; +#endif + + // Constructor. + win_tss_ptr() + { + tss_key_ = ::TlsAlloc(); + if (tss_key_ == out_of_indexes) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "tss"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_tss_ptr() + { + ::TlsFree(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::TlsGetValue(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::TlsSetValue(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + DWORD tss_key_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) + +#include + +#endif // BOOST_ASIO_DETAIL_WIN_TSS_PTR_HPP diff --git a/thirdparty/boost/asio/detail/wince_thread.hpp b/thirdparty/boost/asio/detail/wince_thread.hpp new file mode 100644 index 0000000..9a18b36 --- /dev/null +++ b/thirdparty/boost/asio/detail/wince_thread.hpp @@ -0,0 +1,126 @@ +// +// wince_thread.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WINCE_THREAD_HPP +#define BOOST_ASIO_DETAIL_WINCE_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +DWORD WINAPI wince_thread_function(LPVOID arg); + +class wince_thread + : private noncopyable +{ +public: + // Constructor. + template + wince_thread(Function f) + { + std::auto_ptr arg(new func(f)); + DWORD thread_id = 0; + thread_ = ::CreateThread(0, 0, wince_thread_function, + arg.get(), 0, &thread_id); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + } + + // Destructor. + ~wince_thread() + { + ::CloseHandle(thread_); + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObject(thread_, INFINITE); + } + +private: + friend DWORD WINAPI wince_thread_function(LPVOID arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; +}; + +inline DWORD WINAPI wince_thread_function(LPVOID arg) +{ + std::auto_ptr func( + static_cast(arg)); + func->run(); + return 0; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE) + +#include + +#endif // BOOST_ASIO_DETAIL_WINCE_THREAD_HPP diff --git a/thirdparty/boost/asio/detail/winsock_init.hpp b/thirdparty/boost/asio/detail/winsock_init.hpp new file mode 100644 index 0000000..5e56d03 --- /dev/null +++ b/thirdparty/boost/asio/detail/winsock_init.hpp @@ -0,0 +1,122 @@ +// +// winsock_init.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP +#define BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class winsock_init + : private noncopyable +{ +private: + // Structure to perform the actual initialisation. + struct do_init + { + do_init() + { + WSADATA wsa_data; + result_ = ::WSAStartup(MAKEWORD(Major, Minor), &wsa_data); + } + + ~do_init() + { + ::WSACleanup(); + } + + int result() const + { + return result_; + } + + // Helper function to manage a do_init singleton. The static instance of the + // winsock_init object ensures that this function is always called before + // main, and therefore before any other threads can get started. The do_init + // instance must be static in this function to ensure that it gets + // initialised before any other global objects try to use it. + static boost::shared_ptr instance() + { + static boost::shared_ptr init(new do_init); + return init; + } + + private: + int result_; + }; + +public: + // Constructor. + winsock_init() + : ref_(do_init::instance()) + { + // Check whether winsock was successfully initialised. This check is not + // performed for the global instance since there will be nobody around to + // catch the exception. + if (this != &instance_ && ref_->result() != 0) + { + boost::system::system_error e( + boost::system::error_code(ref_->result(), + boost::asio::error::get_system_category()), + "winsock"); + boost::throw_exception(e); + } + } + + // Destructor. + ~winsock_init() + { + } + +private: + // Instance to force initialisation of winsock at global scope. + static winsock_init instance_; + + // Reference to singleton do_init object to ensure that winsock does not get + // cleaned up until the last user has finished with it. + boost::shared_ptr ref_; +}; + +template +winsock_init winsock_init::instance_; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include + +#endif // BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP diff --git a/thirdparty/boost/asio/detail/wrapped_handler.hpp b/thirdparty/boost/asio/detail/wrapped_handler.hpp new file mode 100644 index 0000000..70df4e9 --- /dev/null +++ b/thirdparty/boost/asio/detail/wrapped_handler.hpp @@ -0,0 +1,195 @@ +// +// wrapped_handler.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_DETAIL_WRAPPED_HANDLER_HPP +#define BOOST_ASIO_DETAIL_WRAPPED_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class wrapped_handler +{ +public: + typedef void result_type; + + wrapped_handler( + typename boost::add_reference::type dispatcher, + Handler handler) + : dispatcher_(dispatcher), + handler_(handler) + { + } + + void operator()() + { + dispatcher_.dispatch(handler_); + } + + void operator()() const + { + dispatcher_.dispatch(handler_); + } + + template + void operator()(const Arg1& arg1) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + +//private: + Dispatcher dispatcher_; + Handler handler_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + wrapped_handler* this_handler) +{ + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + wrapped_handler* this_handler) +{ + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +class rewrapped_handler +{ +public: + explicit rewrapped_handler(const Handler& handler, const Context& context) + : handler_(handler), + context_(context) + { + } + + void operator()() + { + handler_(); + } + + void operator()() const + { + handler_(); + } + +//private: + Handler handler_; + Context context_; +}; + +template +inline void asio_handler_invoke(const Function& function, + wrapped_handler* this_handler) +{ + this_handler->dispatcher_.dispatch( + rewrapped_handler( + function, this_handler->handler_)); +} + +template +inline void asio_handler_invoke(const Function& function, + rewrapped_handler* this_handler) +{ + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->context_); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_WRAPPED_HANDLER_HPP diff --git a/thirdparty/boost/asio/error.hpp b/thirdparty/boost/asio/error.hpp new file mode 100644 index 0000000..7d36b7c --- /dev/null +++ b/thirdparty/boost/asio/error.hpp @@ -0,0 +1,439 @@ +// +// error.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_ERROR_HPP +#define BOOST_ASIO_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include + +#if defined(GENERATING_DOCUMENTATION) +/// INTERNAL ONLY. +# define BOOST_ASIO_NATIVE_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define BOOST_ASIO_SOCKET_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define BOOST_ASIO_NETDB_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define BOOST_ASIO_GETADDRINFO_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# define BOOST_ASIO_NATIVE_ERROR(e) e +# define BOOST_ASIO_SOCKET_ERROR(e) WSA ## e +# define BOOST_ASIO_NETDB_ERROR(e) WSA ## e +# define BOOST_ASIO_GETADDRINFO_ERROR(e) WSA ## e +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_win +#else +# define BOOST_ASIO_NATIVE_ERROR(e) e +# define BOOST_ASIO_SOCKET_ERROR(e) e +# define BOOST_ASIO_NETDB_ERROR(e) e +# define BOOST_ASIO_GETADDRINFO_ERROR(e) e +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix +#endif + +namespace boost { +namespace asio { +namespace error { + +enum basic_errors +{ + /// Permission denied. + access_denied = BOOST_ASIO_SOCKET_ERROR(EACCES), + + /// Address family not supported by protocol. + address_family_not_supported = BOOST_ASIO_SOCKET_ERROR(EAFNOSUPPORT), + + /// Address already in use. + address_in_use = BOOST_ASIO_SOCKET_ERROR(EADDRINUSE), + + /// Transport endpoint is already connected. + already_connected = BOOST_ASIO_SOCKET_ERROR(EISCONN), + + /// Operation already in progress. + already_started = BOOST_ASIO_SOCKET_ERROR(EALREADY), + + /// Broken pipe. + broken_pipe = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_BROKEN_PIPE), + BOOST_ASIO_NATIVE_ERROR(EPIPE)), + + /// A connection has been aborted. + connection_aborted = BOOST_ASIO_SOCKET_ERROR(ECONNABORTED), + + /// Connection refused. + connection_refused = BOOST_ASIO_SOCKET_ERROR(ECONNREFUSED), + + /// Connection reset by peer. + connection_reset = BOOST_ASIO_SOCKET_ERROR(ECONNRESET), + + /// Bad file descriptor. + bad_descriptor = BOOST_ASIO_SOCKET_ERROR(EBADF), + + /// Bad address. + fault = BOOST_ASIO_SOCKET_ERROR(EFAULT), + + /// No route to host. + host_unreachable = BOOST_ASIO_SOCKET_ERROR(EHOSTUNREACH), + + /// Operation now in progress. + in_progress = BOOST_ASIO_SOCKET_ERROR(EINPROGRESS), + + /// Interrupted system call. + interrupted = BOOST_ASIO_SOCKET_ERROR(EINTR), + + /// Invalid argument. + invalid_argument = BOOST_ASIO_SOCKET_ERROR(EINVAL), + + /// Message too long. + message_size = BOOST_ASIO_SOCKET_ERROR(EMSGSIZE), + + /// Network is down. + network_down = BOOST_ASIO_SOCKET_ERROR(ENETDOWN), + + /// Network dropped connection on reset. + network_reset = BOOST_ASIO_SOCKET_ERROR(ENETRESET), + + /// Network is unreachable. + network_unreachable = BOOST_ASIO_SOCKET_ERROR(ENETUNREACH), + + /// Too many open files. + no_descriptors = BOOST_ASIO_SOCKET_ERROR(EMFILE), + + /// No buffer space available. + no_buffer_space = BOOST_ASIO_SOCKET_ERROR(ENOBUFS), + + /// Cannot allocate memory. + no_memory = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY), + BOOST_ASIO_NATIVE_ERROR(ENOMEM)), + + /// Operation not permitted. + no_permission = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED), + BOOST_ASIO_NATIVE_ERROR(EPERM)), + + /// Protocol not available. + no_protocol_option = BOOST_ASIO_SOCKET_ERROR(ENOPROTOOPT), + + /// Transport endpoint is not connected. + not_connected = BOOST_ASIO_SOCKET_ERROR(ENOTCONN), + + /// Socket operation on non-socket. + not_socket = BOOST_ASIO_SOCKET_ERROR(ENOTSOCK), + + /// Operation cancelled. + operation_aborted = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED), + BOOST_ASIO_NATIVE_ERROR(ECANCELED)), + + /// Operation not supported. + operation_not_supported = BOOST_ASIO_SOCKET_ERROR(EOPNOTSUPP), + + /// Cannot send after transport endpoint shutdown. + shut_down = BOOST_ASIO_SOCKET_ERROR(ESHUTDOWN), + + /// Connection timed out. + timed_out = BOOST_ASIO_SOCKET_ERROR(ETIMEDOUT), + + /// Resource temporarily unavailable. + try_again = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_RETRY), + BOOST_ASIO_NATIVE_ERROR(EAGAIN)), + + /// The socket is marked non-blocking and the requested operation would block. + would_block = BOOST_ASIO_SOCKET_ERROR(EWOULDBLOCK) +}; + +enum netdb_errors +{ + /// Host not found (authoritative). + host_not_found = BOOST_ASIO_NETDB_ERROR(HOST_NOT_FOUND), + + /// Host not found (non-authoritative). + host_not_found_try_again = BOOST_ASIO_NETDB_ERROR(TRY_AGAIN), + + /// The query is valid but does not have associated address data. + no_data = BOOST_ASIO_NETDB_ERROR(NO_DATA), + + /// A non-recoverable error occurred. + no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY) +}; + +enum addrinfo_errors +{ + /// The service is not supported for the given socket type. + service_not_found = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND), + BOOST_ASIO_GETADDRINFO_ERROR(EAI_SERVICE)), + + /// The socket type is not supported. + socket_type_not_supported = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT), + BOOST_ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)) +}; + +enum misc_errors +{ + /// Already open. + already_open = 1, + + /// End of file or stream. + eof, + + /// Element not found. + not_found, + + /// The descriptor cannot fit into the select system call's fd_set. + fd_set_failure +}; + +enum ssl_errors +{ +}; + +inline const boost::system::error_category& get_system_category() +{ + return boost::system::get_system_category(); +} + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace detail { + +class netdb_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.netdb"; + } + + std::string message(int value) const + { + if (value == error::host_not_found) + return "Host not found (authoritative)"; + if (value == error::host_not_found_try_again) + return "Host not found (non-authoritative), try again later"; + if (value == error::no_data) + return "The query is valid, but it does not have associated data"; + if (value == error::no_recovery) + return "A non-recoverable error occurred during database lookup"; + return "asio.netdb error"; + } +}; + +} // namespace detail + +inline const boost::system::error_category& get_netdb_category() +{ + static detail::netdb_category instance; + return instance; +} + +namespace detail { + +class addrinfo_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.addrinfo"; + } + + std::string message(int value) const + { + if (value == error::service_not_found) + return "Service not found"; + if (value == error::socket_type_not_supported) + return "Socket type not supported"; + return "asio.addrinfo error"; + } +}; + +} // namespace detail + +inline const boost::system::error_category& get_addrinfo_category() +{ + static detail::addrinfo_category instance; + return instance; +} + +#else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +inline const boost::system::error_category& get_netdb_category() +{ + return get_system_category(); +} + +inline const boost::system::error_category& get_addrinfo_category() +{ + return get_system_category(); +} + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace detail { + +class misc_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.misc"; + } + + std::string message(int value) const + { + if (value == error::already_open) + return "Already open"; + if (value == error::eof) + return "End of file"; + if (value == error::not_found) + return "Element not found"; + if (value == error::fd_set_failure) + return "The descriptor does not fit into the select call's fd_set"; + return "asio.misc error"; + } +}; + +} // namespace detail + +inline const boost::system::error_category& get_misc_category() +{ + static detail::misc_category instance; + return instance; +} + +namespace detail { + +class ssl_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.ssl"; + } + + std::string message(int) const + { + return "asio.ssl error"; + } +}; + +} // namespace detail + +inline const boost::system::error_category& get_ssl_category() +{ + static detail::ssl_category instance; + return instance; +} + +static const boost::system::error_category& system_category + = boost::asio::error::get_system_category(); +static const boost::system::error_category& netdb_category + = boost::asio::error::get_netdb_category(); +static const boost::system::error_category& addrinfo_category + = boost::asio::error::get_addrinfo_category(); +static const boost::system::error_category& misc_category + = boost::asio::error::get_misc_category(); +static const boost::system::error_category& ssl_category + = boost::asio::error::get_ssl_category(); + +} // namespace error +} // namespace asio + +namespace system { + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +template<> struct is_error_code_enum +{ + static const bool value = true; +}; + +} // namespace system + +namespace asio { +namespace error { + +inline boost::system::error_code make_error_code(basic_errors e) +{ + return boost::system::error_code( + static_cast(e), get_system_category()); +} + +inline boost::system::error_code make_error_code(netdb_errors e) +{ + return boost::system::error_code( + static_cast(e), get_netdb_category()); +} + +inline boost::system::error_code make_error_code(addrinfo_errors e) +{ + return boost::system::error_code( + static_cast(e), get_addrinfo_category()); +} + +inline boost::system::error_code make_error_code(misc_errors e) +{ + return boost::system::error_code( + static_cast(e), get_misc_category()); +} + +inline boost::system::error_code make_error_code(ssl_errors e) +{ + return boost::system::error_code( + static_cast(e), get_ssl_category()); +} + +} // namespace error +} // namespace asio +} // namespace boost + +#undef BOOST_ASIO_NATIVE_ERROR +#undef BOOST_ASIO_SOCKET_ERROR +#undef BOOST_ASIO_NETDB_ERROR +#undef BOOST_ASIO_GETADDRINFO_ERROR +#undef BOOST_ASIO_WIN_OR_POSIX + + +#include + +#endif // BOOST_ASIO_ERROR_HPP diff --git a/thirdparty/boost/asio/handler_alloc_hook.hpp b/thirdparty/boost/asio/handler_alloc_hook.hpp new file mode 100644 index 0000000..dbb0967 --- /dev/null +++ b/thirdparty/boost/asio/handler_alloc_hook.hpp @@ -0,0 +1,90 @@ +// +// handler_alloc_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_HANDLER_ALLOC_HOOK_HPP +#define BOOST_ASIO_HANDLER_ALLOC_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Default allocation function for handlers. +/** + * Asynchronous operations may need to allocate temporary objects. Since + * asynchronous operations have a handler function object, these temporary + * objects can be said to be associated with the handler. + * + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for these temporary objects. + * + * This default implementation is simply: + * @code + * return ::operator new(bytes); + * @endcode + * + * @note All temporary objects associated with a handler will be deallocated + * before the upcall to the handler is performed. This allows the same memory to + * be reused for a subsequent asynchronous operation initiated by the handler. + * + * @par Example + * @code + * class my_handler; + * + * void* asio_handler_allocate(std::size_t size, my_handler* context) + * { + * return ::operator new(size); + * } + * + * void asio_handler_deallocate(void* pointer, std::size_t size, + * my_handler* context) + * { + * ::operator delete(pointer); + * } + * @endcode + */ +inline void* asio_handler_allocate(std::size_t size, ...) +{ + return ::operator new(size); +} + +/// Default deallocation function for handlers. +/** + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for the associated temporary objects. + * + * This default implementation is simply: + * @code + * ::operator delete(pointer); + * @endcode + * + * @sa asio_handler_allocate. + */ +inline void asio_handler_deallocate(void* pointer, std::size_t size, ...) +{ + (void)(size); + ::operator delete(pointer); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_HANDLER_ALLOC_HOOK_HPP diff --git a/thirdparty/boost/asio/handler_invoke_hook.hpp b/thirdparty/boost/asio/handler_invoke_hook.hpp new file mode 100644 index 0000000..039b44d --- /dev/null +++ b/thirdparty/boost/asio/handler_invoke_hook.hpp @@ -0,0 +1,71 @@ +// +// handler_invoke_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_HANDLER_INVOKE_HOOK_HPP +#define BOOST_ASIO_HANDLER_INVOKE_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { + +/// Default invoke function for handlers. +/** + * Completion handlers for asynchronous operations are invoked by the + * io_service associated with the corresponding object (e.g. a socket or + * deadline_timer). Certain guarantees are made on when the handler may be + * invoked, in particular that a handler can only be invoked from a thread that + * is currently calling boost::asio::io_service::run() on the corresponding + * io_service object. Handlers may subsequently be invoked through other + * objects (such as boost::asio::strand objects) that provide additional + * guarantees. + * + * When asynchronous operations are composed from other asynchronous + * operations, all intermediate handlers should be invoked using the same + * method as the final handler. This is required to ensure that user-defined + * objects are not accessed in a way that may violate the guarantees. This + * hooking function ensures that the invoked method used for the final handler + * is accessible at each intermediate step. + * + * Implement asio_handler_invoke for your own handlers to specify a custom + * invocation strategy. + * + * This default implementation is simply: + * @code + * function(); + * @endcode + * + * @par Example + * @code + * class my_handler; + * + * template + * void asio_handler_invoke(Function function, my_handler* context) + * { + * context->strand_.dispatch(function); + * } + * @endcode + */ +template +inline void asio_handler_invoke(Function function, ...) +{ + function(); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_HANDLER_INVOKE_HOOK_HPP diff --git a/thirdparty/boost/asio/impl/io_service.ipp b/thirdparty/boost/asio/impl/io_service.ipp new file mode 100644 index 0000000..a794ff0 --- /dev/null +++ b/thirdparty/boost/asio/impl/io_service.ipp @@ -0,0 +1,226 @@ +// +// io_service.ipp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IO_SERVICE_IPP +#define BOOST_ASIO_IO_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +inline io_service::io_service() + : service_registry_(new boost::asio::detail::service_registry(*this)), + impl_(service_registry_->use_service()) +{ + impl_.init((std::numeric_limits::max)()); +} + +inline io_service::io_service(std::size_t concurrency_hint) + : service_registry_(new boost::asio::detail::service_registry(*this)), + impl_(service_registry_->use_service()) +{ + impl_.init(concurrency_hint); +} + +inline io_service::~io_service() +{ + delete service_registry_; +} + +inline std::size_t io_service::run() +{ + boost::system::error_code ec; + std::size_t s = impl_.run(ec); + boost::asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::run(boost::system::error_code& ec) +{ + return impl_.run(ec); +} + +inline std::size_t io_service::run_one() +{ + boost::system::error_code ec; + std::size_t s = impl_.run_one(ec); + boost::asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::run_one(boost::system::error_code& ec) +{ + return impl_.run_one(ec); +} + +inline std::size_t io_service::poll() +{ + boost::system::error_code ec; + std::size_t s = impl_.poll(ec); + boost::asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::poll(boost::system::error_code& ec) +{ + return impl_.poll(ec); +} + +inline std::size_t io_service::poll_one() +{ + boost::system::error_code ec; + std::size_t s = impl_.poll_one(ec); + boost::asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::poll_one(boost::system::error_code& ec) +{ + return impl_.poll_one(ec); +} + +inline void io_service::stop() +{ + impl_.stop(); +} + +inline void io_service::reset() +{ + impl_.reset(); +} + +template +inline void io_service::dispatch(Handler handler) +{ + impl_.dispatch(handler); +} + +template +inline void io_service::post(Handler handler) +{ + impl_.post(handler); +} + +template +#if defined(GENERATING_DOCUMENTATION) +unspecified +#else +inline detail::wrapped_handler +#endif +io_service::wrap(Handler handler) +{ + return detail::wrapped_handler(*this, handler); +} + +inline io_service::work::work(boost::asio::io_service& io_service) + : io_service_(io_service) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::work(const work& other) + : io_service_(other.io_service_) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::~work() +{ + io_service_.impl_.work_finished(); +} + +inline boost::asio::io_service& io_service::work::io_service() +{ + return io_service_; +} + +inline boost::asio::io_service& io_service::work::get_io_service() +{ + return io_service_; +} + +inline io_service::service::service(boost::asio::io_service& owner) + : owner_(owner), + type_info_(0), + next_(0) +{ +} + +inline io_service::service::~service() +{ +} + +inline boost::asio::io_service& io_service::service::io_service() +{ + return owner_; +} + +inline boost::asio::io_service& io_service::service::get_io_service() +{ + return owner_; +} + +template +inline Service& use_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + return ios.service_registry_->template use_service(); +} + +template +void add_service(io_service& ios, Service* svc) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + if (&ios != &svc->io_service()) + boost::throw_exception(invalid_service_owner()); + if (!ios.service_registry_->template add_service(svc)) + boost::throw_exception(service_already_exists()); +} + +template +bool has_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + return ios.service_registry_->template has_service(); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IO_SERVICE_IPP diff --git a/thirdparty/boost/asio/impl/read.ipp b/thirdparty/boost/asio/impl/read.ipp new file mode 100644 index 0000000..b2ca266 --- /dev/null +++ b/thirdparty/boost/asio/impl/read.ipp @@ -0,0 +1,316 @@ +// +// read.ipp +// ~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_READ_IPP +#define BOOST_ASIO_READ_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, boost::system::error_code& ec) +{ + boost::asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = s.read_some(tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + if (completion_condition(ec, total_transferred)) + return total_transferred; + } + ec = boost::system::error_code(); + return total_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, buffers, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t read(SyncReadStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition, boost::system::error_code& ec) +{ + std::size_t total_transferred = 0; + for (;;) + { + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); + b.commit(bytes_transferred); + total_transferred += bytes_transferred; + if (b.size() == b.max_size() + || completion_condition(ec, total_transferred)) + return total_transferred; + } +} + +template +inline std::size_t read(SyncReadStream& s, + boost::asio::basic_streambuf& b) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, b, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, b, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + template + class read_handler + { + public: + typedef boost::asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> buffers_type; + + read_handler(AsyncReadStream& stream, const buffers_type& buffers, + CompletionCondition completion_condition, ReadHandler handler) + : stream_(stream), + buffers_(buffers), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + if (completion_condition_(ec, total_transferred_) + || buffers_.begin() == buffers_.end()) + { + handler_(ec, total_transferred_); + } + else + { + stream_.async_read_some(buffers_, *this); + } + } + + //private: + AsyncReadStream& stream_; + buffers_type buffers_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) +{ + boost::asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> tmp(buffers); + s.async_read_some(tmp, + detail::read_handler( + s, tmp, completion_condition, handler)); +} + +template +inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ReadHandler handler) +{ + async_read(s, buffers, transfer_all(), handler); +} + +namespace detail +{ + template + class read_streambuf_handler + { + public: + read_streambuf_handler(AsyncReadStream& stream, + basic_streambuf& streambuf, + CompletionCondition completion_condition, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + streambuf_.commit(bytes_transferred); + if (streambuf_.size() == streambuf_.max_size() + || completion_condition_(ec, total_transferred_)) + { + handler_(ec, total_transferred_); + } + else + { + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf& streambuf_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_streambuf_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_streambuf_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_streambuf_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +inline void async_read(AsyncReadStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler) +{ + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_streambuf_handler( + s, b, completion_condition, handler)); +} + +template +inline void async_read(AsyncReadStream& s, + boost::asio::basic_streambuf& b, ReadHandler handler) +{ + async_read(s, b, transfer_all(), handler); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_READ_IPP diff --git a/thirdparty/boost/asio/impl/read_until.ipp b/thirdparty/boost/asio/impl/read_until.ipp new file mode 100644 index 0000000..b626594 --- /dev/null +++ b/thirdparty/boost/asio/impl/read_until.ipp @@ -0,0 +1,758 @@ +// +// read_until.ipp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_READ_UNTIL_IPP +#define BOOST_ASIO_READ_UNTIL_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +template +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, char delim) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, char delim, + boost::system::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, next_search_start); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + iterator iter = std::find(begin, end, delim); + if (iter != end) + { + // Found a match. We're done. + ec = boost::system::error_code(); + return iter.position() + 1; + } + else + { + // No match. Next search can start with the new data. + next_search_start = end.position(); + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + // Algorithm that finds a subsequence of equal values in a sequence. Returns + // (iterator,true) if a full match was found, in which case the iterator + // points to the beginning of the match. Returns (iterator,false) if a + // partial match was found at the end of the first sequence, in which case + // the iterator points to the beginning of the partial match. Returns + // (last1,false) if no full or partial match was found. + template + std::pair partial_search( + Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + { + for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) + { + Iterator1 test_iter1 = iter1; + Iterator2 test_iter2 = first2; + for (;; ++test_iter1, ++test_iter2) + { + if (test_iter2 == last2) + return std::make_pair(iter1, true); + if (test_iter1 == last1) + { + if (test_iter2 != first2) + return std::make_pair(iter1, false); + else + break; + } + if (*test_iter1 != *test_iter2) + break; + } + } + return std::make_pair(last1, false); + } +} // namespace detail + +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim, + boost::system::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, next_search_start); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + std::pair result = boost::asio::detail::partial_search( + begin, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + ec = boost::system::error_code(); + return result.first.position() + delim.length(); + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end.position(); + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, expr, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr, + boost::system::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, next_search_start); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + boost::match_results match_results; + if (boost::regex_search(begin, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + ec = boost::system::error_code(); + return match_results[0].second.position(); + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = match_results[0].first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end.position(); + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +namespace detail +{ + template + class read_until_delim_handler + { + public: + read_until_delim_handler(AsyncReadStream& stream, + boost::asio::basic_streambuf& streambuf, char delim, + std::size_t next_search_start, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin(buffers, next_search_start_); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + iterator iter = std::find(begin, end, delim_); + if (iter != end) + { + // Found a match. We're done. + std::size_t bytes = iter.position() + 1; + handler_(ec, bytes); + return; + } + + // No match. Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + boost::system::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Next search can start with the new data. + next_search_start_ = end.position(); + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf& streambuf_; + char delim_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, char delim, ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, 0); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + iterator iter = std::find(begin, end, delim); + if (iter != end) + { + // Found a match. We're done. + boost::system::error_code ec; + std::size_t bytes = iter.position() + 1; + s.io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + + // No match. Check if buffer is full. + if (b.size() == b.max_size()) + { + boost::system::error_code ec(error::not_found); + s.io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_delim_handler( + s, b, delim, end.position(), handler)); +} + +namespace detail +{ + template + class read_until_delim_string_handler + { + public: + read_until_delim_string_handler(AsyncReadStream& stream, + boost::asio::basic_streambuf& streambuf, + const std::string& delim, std::size_t next_search_start, + ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin(buffers, next_search_start_); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + std::pair result = boost::asio::detail::partial_search( + begin, end, delim_.begin(), delim_.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + std::size_t bytes = result.first.position() + delim_.length(); + handler_(ec, bytes); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start_ = result.first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start_ = end.position(); + } + + // Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + boost::system::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf& streambuf_; + std::string delim_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_string_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_string_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_string_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim, + ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, 0); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + std::size_t next_search_start; + std::pair result = boost::asio::detail::partial_search( + begin, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + boost::system::error_code ec; + std::size_t bytes = result.first.position() + delim.length(); + s.io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end.position(); + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + boost::system::error_code ec(error::not_found); + s.io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_delim_string_handler< + AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, next_search_start, handler)); +} + +namespace detail +{ + template + class read_until_expr_handler + { + public: + read_until_expr_handler(AsyncReadStream& stream, + boost::asio::basic_streambuf& streambuf, + const boost::regex& expr, std::size_t next_search_start, + ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + expr_(expr), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin(buffers, next_search_start_); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + boost::match_results match_results; + if (boost::regex_search(begin, end, match_results, expr_, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + std::size_t bytes = match_results[0].second.position(); + handler_(ec, bytes); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start_ = match_results[0].first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start_ = end.position(); + } + + // Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + boost::system::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf& streambuf_; + boost::regex expr_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_expr_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_expr_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_expr_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr, + ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::detail::const_buffers_iterator< + const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin(buffers, 0); + iterator end(buffers, (std::numeric_limits::max)()); + + // Look for a match. + std::size_t next_search_start; + boost::match_results match_results; + if (boost::regex_search(begin, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + boost::system::error_code ec; + std::size_t bytes = match_results[0].second.position(); + s.io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = match_results[0].first.position(); + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end.position(); + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + boost::system::error_code ec(error::not_found); + s.io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_expr_handler( + s, b, expr, next_search_start, handler)); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_READ_UNTIL_IPP diff --git a/thirdparty/boost/asio/impl/write.ipp b/thirdparty/boost/asio/impl/write.ipp new file mode 100644 index 0000000..1a53c26 --- /dev/null +++ b/thirdparty/boost/asio/impl/write.ipp @@ -0,0 +1,281 @@ +// +// write.ipp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_WRITE_IPP +#define BOOST_ASIO_WRITE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, boost::system::error_code& ec) +{ + boost::asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = s.write_some(tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + if (completion_condition(ec, total_transferred)) + return total_transferred; + } + ec = boost::system::error_code(); + return total_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, buffers, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t write(SyncWriteStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition, boost::system::error_code& ec) +{ + std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec); + b.consume(bytes_transferred); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + boost::asio::basic_streambuf& b) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, b, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, b, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + template + class write_handler + { + public: + typedef boost::asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> buffers_type; + + write_handler(AsyncWriteStream& stream, const buffers_type& buffers, + CompletionCondition completion_condition, WriteHandler handler) + : stream_(stream), + buffers_(buffers), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + if (completion_condition_(ec, total_transferred_) + || buffers_.begin() == buffers_.end()) + { + handler_(ec, total_transferred_); + } + else + { + stream_.async_write_some(buffers_, *this); + } + } + + //private: + AsyncWriteStream& stream_; + buffers_type buffers_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) +{ + boost::asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> tmp(buffers); + s.async_write_some(tmp, + detail::write_handler( + s, tmp, completion_condition, handler)); +} + +template +inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + WriteHandler handler) +{ + async_write(s, buffers, transfer_all(), handler); +} + +namespace detail +{ + template + class write_streambuf_handler + { + public: + write_streambuf_handler(boost::asio::basic_streambuf& streambuf, + WriteHandler handler) + : streambuf_(streambuf), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + streambuf_.consume(bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + boost::asio::basic_streambuf& streambuf_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_streambuf_handler* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_streambuf_handler* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_streambuf_handler* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); + } +} // namespace detail + +template +inline void async_write(AsyncWriteStream& s, + boost::asio::basic_streambuf& b, + CompletionCondition completion_condition, WriteHandler handler) +{ + async_write(s, b.data(), completion_condition, + detail::write_streambuf_handler< + AsyncWriteStream, Allocator, WriteHandler>(b, handler)); +} + +template +inline void async_write(AsyncWriteStream& s, + boost::asio::basic_streambuf& b, WriteHandler handler) +{ + async_write(s, b, transfer_all(), handler); +} + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_WRITE_IPP diff --git a/thirdparty/boost/asio/io_service.hpp b/thirdparty/boost/asio/io_service.hpp new file mode 100644 index 0000000..ef88b5d --- /dev/null +++ b/thirdparty/boost/asio/io_service.hpp @@ -0,0 +1,521 @@ +// +// io_service.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IO_SERVICE_HPP +#define BOOST_ASIO_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +class io_service; +template Service& use_service(io_service& ios); +template void add_service(io_service& ios, Service* svc); +template bool has_service(io_service& ios); + +/// Provides core I/O functionality. +/** + * The io_service class provides the core I/O functionality for users of the + * asynchronous I/O objects, including: + * + * @li boost::asio::ip::tcp::socket + * @li boost::asio::ip::tcp::acceptor + * @li boost::asio::ip::udp::socket + * @li boost::asio::deadline_timer. + * + * The io_service class also includes facilities intended for developers of + * custom asynchronous services. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe, with the exception that calling reset() + * while there are unfinished run() calls results in undefined behaviour. + * + * @par Concepts: + * Dispatcher. + * + * @par Effect of exceptions thrown from handlers + * + * If an exception is thrown from a handler, the exception is allowed to + * propagate through the throwing thread's invocation of + * boost::asio::io_service::run(), boost::asio::io_service::run_one(), + * boost::asio::io_service::poll() or boost::asio::io_service::poll_one(). + * No other threads that are calling any of these functions are affected. It is + * then the responsibility of the application to catch the exception. + * + * After the exception has been caught, the + * boost::asio::io_service::run(), boost::asio::io_service::run_one(), + * boost::asio::io_service::poll() or boost::asio::io_service::poll_one() + * call may be restarted @em without the need for an intervening call to + * boost::asio::io_service::reset(). This allows the thread to rejoin the + * io_service's thread pool without impacting any other threads in the pool. + * + * For example: + * + * @code + * boost::asio::io_service io_service; + * ... + * for (;;) + * { + * try + * { + * io_service.run(); + * break; // run() exited normally + * } + * catch (my_exception& e) + * { + * // Deal with exception as appropriate. + * } + * } + * @endcode + */ +class io_service + : private noncopyable +{ +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_io_service impl_type; +#elif defined(BOOST_ASIO_HAS_EPOLL) + typedef detail::task_io_service > impl_type; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + typedef detail::task_io_service > impl_type; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + typedef detail::task_io_service > impl_type; +#else + typedef detail::task_io_service > impl_type; +#endif + +public: + class work; + friend class work; + + class id; + + class service; + + class strand; + + /// Constructor. + io_service(); + + /// Constructor. + /** + * Construct with a hint about the required level of concurrency. + * + * @param concurrency_hint A suggestion to the implementation on how many + * threads it should allow to run simultaneously. + */ + explicit io_service(std::size_t concurrency_hint); + + /// Destructor. + ~io_service(); + + /// Run the io_service's event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_service has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_service may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_service may choose any one + * of them to invoke a handler. + * + * The run() function may be safely called again once it has completed only + * after a call to reset(). + * + * @return The number of handlers that were executed. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t run(); + + /// Run the io_service's event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_service has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_service may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_service may choose any one + * of them to invoke a handler. + * + * The run() function may be safely called again once it has completed only + * after a call to reset(). + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t run(boost::system::error_code& ec); + + /// Run the io_service's event processing loop to execute at most one handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_service has been stopped. + * + * @return The number of handlers that were executed. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t run_one(); + + /// Run the io_service's event processing loop to execute at most one handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_service has been stopped. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t run_one(boost::system::error_code& ec); + + /// Run the io_service's event processing loop to execute ready handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_service has been stopped or there are no more ready handlers. + * + * @return The number of handlers that were executed. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t poll(); + + /// Run the io_service's event processing loop to execute ready handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_service has been stopped or there are no more ready handlers. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t poll(boost::system::error_code& ec); + + /// Run the io_service's event processing loop to execute one ready handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @return The number of handlers that were executed. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t poll_one(); + + /// Run the io_service's event processing loop to execute one ready handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t poll_one(boost::system::error_code& ec); + + /// Stop the io_service's event processing loop. + /** + * This function does not block, but instead simply signals the io_service to + * stop. All invocations of its run() or run_one() member functions should + * return as soon as possible. Subsequent calls to run(), run_one(), poll() + * or poll_one() will return immediately until reset() is called. + */ + void stop(); + + /// Reset the io_service in preparation for a subsequent run() invocation. + /** + * This function must be called prior to any second or later set of + * invocations of the run(), run_one(), poll() or poll_one() functions when a + * previous invocation of these functions returned due to the io_service + * being stopped or running out of work. This function allows the io_service + * to reset any internal state, such as a "stopped" flag. + * + * This function must not be called while there are any unfinished calls to + * the run(), run_one(), poll() or poll_one() functions. + */ + void reset(); + + /// Request the io_service to invoke the given handler. + /** + * This function is used to ask the io_service to execute the given handler. + * + * The io_service guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. The handler may be executed inside this function + * if the guarantee can be met. + * + * @param handler The handler to be called. The io_service will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + */ + template + void dispatch(CompletionHandler handler); + + /// Request the io_service to invoke the given handler and return immediately. + /** + * This function is used to ask the io_service to execute the given handler, + * but without allowing the io_service to call the handler from inside this + * function. + * + * The io_service guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. + * + * @param handler The handler to be called. The io_service will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + */ + template + void post(CompletionHandler handler); + + /// Create a new handler that automatically dispatches the wrapped handler + /// on the io_service. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the io_service's + * dispatch function. + * + * @param handler The handler to be wrapped. The io_service will make a copy + * of the handler object as required. The function signature of the handler + * must be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the io_service's dispatch function. Given a function object with the + * signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code io_service.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code io_service.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler); + + /// Obtain the service object corresponding to the given type. + /** + * This function is used to locate a service object that corresponds to + * the given service type. If there is no existing implementation of the + * service, then the io_service will create a new instance of the service. + * + * @param ios The io_service object that owns the service. + * + * @return The service interface implementing the specified service type. + * Ownership of the service interface is not transferred to the caller. + */ + template + friend Service& use_service(io_service& ios); + + /// Add a service object to the io_service. + /** + * This function is used to add a service to the io_service. + * + * @param ios The io_service object that owns the service. + * + * @param svc The service object. On success, ownership of the service object + * is transferred to the io_service. When the io_service object is destroyed, + * it will destroy the service object by performing: + * @code delete static_cast(svc) @endcode + * + * @throws boost::asio::service_already_exists Thrown if a service of the + * given type is already present in the io_service. + * + * @throws boost::asio::invalid_service_owner Thrown if the service's owning + * io_service is not the io_service object specified by the ios parameter. + */ + template + friend void add_service(io_service& ios, Service* svc); + + /// Determine if an io_service contains a specified service type. + /** + * This function is used to determine whether the io_service contains a + * service object corresponding to the given service type. + * + * @param ios The io_service object that owns the service. + * + * @return A boolean indicating whether the io_service contains the service. + */ + template + friend bool has_service(io_service& ios); + +private: +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + detail::winsock_init<> init_; +#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ + || defined(__osf__) + detail::signal_init<> init_; +#endif + + // The service registry. + boost::asio::detail::service_registry* service_registry_; + + // The implementation. + impl_type& impl_; +}; + +/// Class to inform the io_service when it has work to do. +/** + * The work class is used to inform the io_service when work starts and + * finishes. This ensures that the io_service's run() function will not exit + * while work is underway, and that it does exit when there is no unfinished + * work remaining. + * + * The work class is copy-constructible so that it may be used as a data member + * in a handler class. It is not assignable. + */ +class io_service::work +{ +public: + /// Constructor notifies the io_service that work is starting. + /** + * The constructor is used to inform the io_service that some work has begun. + * This ensures that the io_service's run() function will not exit while the + * work is underway. + */ + explicit work(boost::asio::io_service& io_service); + + /// Copy constructor notifies the io_service that work is starting. + /** + * The constructor is used to inform the io_service that some work has begun. + * This ensures that the io_service's run() function will not exit while the + * work is underway. + */ + work(const work& other); + + /// Destructor notifies the io_service that the work is complete. + /** + * The destructor is used to inform the io_service that some work has + * finished. Once the count of unfinished work reaches zero, the io_service's + * run() function is permitted to exit. + */ + ~work(); + + /// (Deprecated: use get_io_service().) Get the io_service associated with the + /// work. + boost::asio::io_service& io_service(); + + /// Get the io_service associated with the work. + boost::asio::io_service& get_io_service(); + +private: + // Prevent assignment. + void operator=(const work& other); + + // The io_service. + boost::asio::io_service& io_service_; +}; + +/// Class used to uniquely identify a service. +class io_service::id + : private noncopyable +{ +public: + /// Constructor. + id() {} +}; + +/// Base class for all io_service services. +class io_service::service + : private noncopyable +{ +public: + /// (Deprecated: use get_io_service().) Get the io_service object that owns + /// the service. + boost::asio::io_service& io_service(); + + /// Get the io_service object that owns the service. + boost::asio::io_service& get_io_service(); + +protected: + /// Constructor. + /** + * @param owner The io_service object that owns the service. + */ + service(boost::asio::io_service& owner); + + /// Destructor. + virtual ~service(); + +private: + /// Destroy all user-defined handler objects owned by the service. + virtual void shutdown_service() = 0; + + friend class boost::asio::detail::service_registry; + boost::asio::io_service& owner_; + const std::type_info* type_info_; + const boost::asio::io_service::id* id_; + service* next_; +}; + +/// Exception thrown when trying to add a duplicate service to an io_service. +class service_already_exists + : public std::logic_error +{ +public: + service_already_exists() + : std::logic_error("Service already exists.") + { + } +}; + +/// Exception thrown when trying to add a service object to an io_service where +/// the service has a different owner. +class invalid_service_owner + : public std::logic_error +{ +public: + invalid_service_owner() + : std::logic_error("Invalid service owner.") + { + } +}; + +} // namespace asio +} // namespace boost + +#include + +#include + +#endif // BOOST_ASIO_IO_SERVICE_HPP diff --git a/thirdparty/boost/asio/ip/address.hpp b/thirdparty/boost/asio/ip/address.hpp new file mode 100644 index 0000000..dd11b70 --- /dev/null +++ b/thirdparty/boost/asio/ip/address.hpp @@ -0,0 +1,279 @@ +// +// address.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_ADDRESS_HPP +#define BOOST_ASIO_IP_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Implements version-independent IP addresses. +/** + * The boost::asio::ip::address class provides the ability to use either IP + * version 4 or version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address +{ +public: + /// Default constructor. + address() + : type_(ipv4), + ipv4_address_(), + ipv6_address_() + { + } + + /// Construct an address from an IPv4 address. + address(const boost::asio::ip::address_v4& ipv4_address) + : type_(ipv4), + ipv4_address_(ipv4_address), + ipv6_address_() + { + } + + /// Construct an address from an IPv6 address. + address(const boost::asio::ip::address_v6& ipv6_address) + : type_(ipv6), + ipv4_address_(), + ipv6_address_(ipv6_address) + { + } + + /// Copy constructor. + address(const address& other) + : type_(other.type_), + ipv4_address_(other.ipv4_address_), + ipv6_address_(other.ipv6_address_) + { + } + + /// Assign from another address. + address& operator=(const address& other) + { + type_ = other.type_; + ipv4_address_ = other.ipv4_address_; + ipv6_address_ = other.ipv6_address_; + return *this; + } + + /// Assign from an IPv4 address. + address& operator=(const boost::asio::ip::address_v4& ipv4_address) + { + type_ = ipv4; + ipv4_address_ = ipv4_address; + ipv6_address_ = boost::asio::ip::address_v6(); + return *this; + } + + /// Assign from an IPv6 address. + address& operator=(const boost::asio::ip::address_v6& ipv6_address) + { + type_ = ipv6; + ipv4_address_ = boost::asio::ip::address_v4(); + ipv6_address_ = ipv6_address; + return *this; + } + + /// Get whether the address is an IP version 4 address. + bool is_v4() const + { + return type_ == ipv4; + } + + /// Get whether the address is an IP version 6 address. + bool is_v6() const + { + return type_ == ipv6; + } + + /// Get the address as an IP version 4 address. + boost::asio::ip::address_v4 to_v4() const + { + if (type_ != ipv4) + { + boost::system::system_error e( + boost::asio::error::address_family_not_supported); + boost::throw_exception(e); + } + return ipv4_address_; + } + + /// Get the address as an IP version 6 address. + boost::asio::ip::address_v6 to_v6() const + { + if (type_ != ipv6) + { + boost::system::system_error e( + boost::asio::error::address_family_not_supported); + boost::throw_exception(e); + } + return ipv6_address_; + } + + /// Get the address as a string in dotted decimal format. + std::string to_string() const + { + if (type_ == ipv6) + return ipv6_address_.to_string(); + return ipv4_address_.to_string(); + } + + /// Get the address as a string in dotted decimal format. + std::string to_string(boost::system::error_code& ec) const + { + if (type_ == ipv6) + return ipv6_address_.to_string(ec); + return ipv4_address_.to_string(ec); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const char* str) + { + boost::system::error_code ec; + address addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const char* str, boost::system::error_code& ec) + { + boost::asio::ip::address_v6 ipv6_address = + boost::asio::ip::address_v6::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv6; + tmp.ipv6_address_ = ipv6_address; + return tmp; + } + + boost::asio::ip::address_v4 ipv4_address = + boost::asio::ip::address_v4::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv4; + tmp.ipv4_address_ = ipv4_address; + return tmp; + } + + return address(); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const std::string& str, + boost::system::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Compare two addresses for equality. + friend bool operator==(const address& a1, const address& a2) + { + if (a1.type_ != a2.type_) + return false; + if (a1.type_ == ipv6) + return a1.ipv6_address_ == a2.ipv6_address_; + return a1.ipv4_address_ == a2.ipv4_address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, const address& a2) + { + if (a1.type_ != a2.type_) + return true; + if (a1.type_ == ipv6) + return a1.ipv6_address_ != a2.ipv6_address_; + return a1.ipv4_address_ != a2.ipv4_address_; + } + + /// Compare addresses for ordering. + friend bool operator<(const address& a1, const address& a2) + { + if (a1.type_ < a2.type_) + return true; + if (a1.type_ > a2.type_) + return false; + if (a1.type_ == ipv6) + return a1.ipv6_address_ < a2.ipv6_address_; + return a1.ipv4_address_ < a2.ipv4_address_; + } + +private: + // The type of the address. + enum { ipv4, ipv6 } type_; + + // The underlying IPv4 address. + boost::asio::ip::address_v4 ipv4_address_; + + // The underlying IPv6 address. + boost::asio::ip::address_v6 ipv6_address_; +}; + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates boost::asio::ip::address + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address& addr) +{ + os << addr.to_string(); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_ADDRESS_HPP diff --git a/thirdparty/boost/asio/ip/address_v4.hpp b/thirdparty/boost/asio/ip/address_v4.hpp new file mode 100644 index 0000000..451b238 --- /dev/null +++ b/thirdparty/boost/asio/ip/address_v4.hpp @@ -0,0 +1,290 @@ +// +// address_v4.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_ADDRESS_V4_HPP +#define BOOST_ASIO_IP_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Implements IP version 4 style addresses. +/** + * The boost::asio::ip::address_v4 class provides the ability to use and + * manipulate IP version 4 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v4 +{ +public: + /// The type used to represent an address as an array of bytes. + typedef boost::array bytes_type; + + /// Default constructor. + address_v4() + { + addr_.s_addr = 0; + } + + /// Construct an address from raw bytes. + explicit address_v4(const bytes_type& bytes) + { + using namespace std; // For memcpy. + memcpy(&addr_.s_addr, bytes.elems, 4); + } + + /// Construct an address from a unsigned long in host byte order. + explicit address_v4(unsigned long addr) + { + addr_.s_addr = boost::asio::detail::socket_ops::host_to_network_long(addr); + } + + /// Copy constructor. + address_v4(const address_v4& other) + : addr_(other.addr_) + { + } + + /// Assign from another address. + address_v4& operator=(const address_v4& other) + { + addr_ = other.addr_; + return *this; + } + + /// Get the address in bytes. + bytes_type to_bytes() const + { + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, &addr_.s_addr, 4); + return bytes; + } + + /// Get the address as an unsigned long in host byte order + unsigned long to_ulong() const + { + return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr); + } + + /// Get the address as a string in dotted decimal format. + std::string to_string() const + { + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; + } + + /// Get the address as a string in dotted decimal format. + std::string to_string(boost::system::error_code& ec) const + { + char addr_str[boost::asio::detail::max_addr_v4_str_len]; + const char* addr = + boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, + boost::asio::detail::max_addr_v4_str_len, 0, ec); + if (addr == 0) + return std::string(); + return addr; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const char* str) + { + boost::system::error_code ec; + address_v4 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const char* str, boost::system::error_code& ec) + { + address_v4 tmp; + if (boost::asio::detail::socket_ops::inet_pton( + AF_INET, str, &tmp.addr_, 0, ec) <= 0) + return address_v4(); + return tmp; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const std::string& str, + boost::system::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Determine whether the address is a class A address. + bool is_class_a() const + { + return IN_CLASSA(to_ulong()); + } + + /// Determine whether the address is a class B address. + bool is_class_b() const + { + return IN_CLASSB(to_ulong()); + } + + /// Determine whether the address is a class C address. + bool is_class_c() const + { + return IN_CLASSC(to_ulong()); + } + + /// Determine whether the address is a multicast address. + bool is_multicast() const + { + return IN_MULTICAST(to_ulong()); + } + + /// Compare two addresses for equality. + friend bool operator==(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr == a2.addr_.s_addr; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr != a2.addr_.s_addr; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() < a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() > a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() <= a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() >= a2.to_ulong(); + } + + /// Obtain an address object that represents any address. + static address_v4 any() + { + return address_v4(static_cast(INADDR_ANY)); + } + + /// Obtain an address object that represents the loopback address. + static address_v4 loopback() + { + return address_v4(static_cast(INADDR_LOOPBACK)); + } + + /// Obtain an address object that represents the broadcast address. + static address_v4 broadcast() + { + return address_v4(static_cast(INADDR_BROADCAST)); + } + + /// Obtain an address object that represents the broadcast address that + /// corresponds to the specified address and netmask. + static address_v4 broadcast(const address_v4& addr, const address_v4& mask) + { + return address_v4(addr.to_ulong() | ~mask.to_ulong()); + } + + /// Obtain the netmask that corresponds to the address, based on its address + /// class. + static address_v4 netmask(const address_v4& addr) + { + if (addr.is_class_a()) + return address_v4(0xFF000000); + if (addr.is_class_b()) + return address_v4(0xFFFF0000); + if (addr.is_class_c()) + return address_v4(0xFFFFFF00); + return address_v4(0xFFFFFFFF); + } + +private: + // The underlying IPv4 address. + boost::asio::detail::in4_addr_type addr_; +}; + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates boost::asio::ip::address_v4 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v4& addr) +{ + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_ADDRESS_V4_HPP diff --git a/thirdparty/boost/asio/ip/address_v6.hpp b/thirdparty/boost/asio/ip/address_v6.hpp new file mode 100644 index 0000000..1326dd1 --- /dev/null +++ b/thirdparty/boost/asio/ip/address_v6.hpp @@ -0,0 +1,408 @@ +// +// address_v6.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_ADDRESS_V6_HPP +#define BOOST_ASIO_IP_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Implements IP version 6 style addresses. +/** + * The boost::asio::ip::address_v6 class provides the ability to use and + * manipulate IP version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v6 +{ +public: + /// The type used to represent an address as an array of bytes. + typedef boost::array bytes_type; + + /// Default constructor. + address_v6() + : scope_id_(0) + { + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + addr_ = tmp_addr; + } + + /// Construct an address from raw bytes and scope ID. + explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0) + : scope_id_(scope_id) + { + using namespace std; // For memcpy. + memcpy(addr_.s6_addr, bytes.elems, 16); + } + + /// Copy constructor. + address_v6(const address_v6& other) + : addr_(other.addr_), + scope_id_(other.scope_id_) + { + } + + /// Assign from another address. + address_v6& operator=(const address_v6& other) + { + addr_ = other.addr_; + scope_id_ = other.scope_id_; + return *this; + } + + /// The scope ID of the address. + /** + * Returns the scope ID associated with the IPv6 address. + */ + unsigned long scope_id() const + { + return scope_id_; + } + + /// The scope ID of the address. + /** + * Modifies the scope ID associated with the IPv6 address. + */ + void scope_id(unsigned long id) + { + scope_id_ = id; + } + + /// Get the address in bytes. + bytes_type to_bytes() const + { + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, addr_.s6_addr, 16); + return bytes; + } + + /// Get the address as a string. + std::string to_string() const + { + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; + } + + /// Get the address as a string. + std::string to_string(boost::system::error_code& ec) const + { + char addr_str[boost::asio::detail::max_addr_v6_str_len]; + const char* addr = + boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str, + boost::asio::detail::max_addr_v6_str_len, scope_id_, ec); + if (addr == 0) + return std::string(); + return addr; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const char* str) + { + boost::system::error_code ec; + address_v6 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const char* str, boost::system::error_code& ec) + { + address_v6 tmp; + if (boost::asio::detail::socket_ops::inet_pton( + AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0) + return address_v6(); + return tmp; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IP address string. + static address_v6 from_string(const std::string& str, + boost::system::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. + address_v4 to_v4() const + { + if (!is_v4_mapped() && !is_v4_compatible()) + throw std::bad_cast(); + address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], + addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; + return address_v4(v4_bytes); + } + + /// Determine whether the address is a loopback address. + bool is_loopback() const + { +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); +#else + using namespace boost::asio::detail; + return IN6_IS_ADDR_LOOPBACK(&addr_) != 0; +#endif + } + + /// Determine whether the address is unspecified. + bool is_unspecified() const + { +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); +#else + using namespace boost::asio::detail; + return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0; +#endif + } + + /// Determine whether the address is link local. + bool is_link_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0; + } + + /// Determine whether the address is site local. + bool is_site_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_SITELOCAL(&addr_) != 0; + } + + /// Determine whether the address is a mapped IPv4 address. + bool is_v4_mapped() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_V4MAPPED(&addr_) != 0; + } + + /// Determine whether the address is an IPv4-compatible address. + bool is_v4_compatible() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_V4COMPAT(&addr_) != 0; + } + + /// Determine whether the address is a multicast address. + bool is_multicast() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MULTICAST(&addr_) != 0; + } + + /// Determine whether the address is a global multicast address. + bool is_multicast_global() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0; + } + + /// Determine whether the address is a link-local multicast address. + bool is_multicast_link_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0; + } + + /// Determine whether the address is a node-local multicast address. + bool is_multicast_node_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0; + } + + /// Determine whether the address is a org-local multicast address. + bool is_multicast_org_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0; + } + + /// Determine whether the address is a site-local multicast address. + bool is_multicast_site_local() const + { + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0; + } + + /// Compare two addresses for equality. + friend bool operator==(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(boost::asio::detail::in6_addr_type)) == 0 + && a1.scope_id_ == a2.scope_id_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(boost::asio::detail::in6_addr_type)) != 0 + || a1.scope_id_ != a2.scope_id_; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + int memcmp_result = memcmp(&a1.addr_, &a2.addr_, + sizeof(boost::asio::detail::in6_addr_type)); + if (memcmp_result < 0) + return true; + if (memcmp_result > 0) + return false; + return a1.scope_id_ < a2.scope_id_; + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v6& a1, const address_v6& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v6& a1, const address_v6& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v6& a1, const address_v6& a2) + { + return !(a1 < a2); + } + + /// Obtain an address object that represents any address. + static address_v6 any() + { + return address_v6(); + } + + /// Obtain an address object that represents the loopback address. + static address_v6 loopback() + { + address_v6 tmp; + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT; + tmp.addr_ = tmp_addr; + return tmp; + } + + /// Create an IPv4-mapped IPv6 address. + static address_v6 v4_mapped(const address_v4& addr) + { + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); + } + + /// Create an IPv4-compatible IPv6 address. + static address_v6 v4_compatible(const address_v4& addr) + { + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); + } + +private: + // The underlying IPv6 address. + boost::asio::detail::in6_addr_type addr_; + + // The scope ID associated with the address. + unsigned long scope_id_; +}; + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates boost::asio::ip::address_v6 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v6& addr) +{ + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_ADDRESS_V6_HPP diff --git a/thirdparty/boost/asio/ip/basic_endpoint.hpp b/thirdparty/boost/asio/ip/basic_endpoint.hpp new file mode 100644 index 0000000..543d4f3 --- /dev/null +++ b/thirdparty/boost/asio/ip/basic_endpoint.hpp @@ -0,0 +1,370 @@ +// +// basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_BASIC_ENDPOINT_HPP +#define BOOST_ASIO_IP_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Describes an endpoint for a version-independent IP socket. +/** + * The boost::asio::ip::basic_endpoint class template describes an endpoint that + * may be associated with a particular socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef InternetProtocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef boost::asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + : data_() + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = 0; + data_.v4.sin_addr.s_addr = INADDR_ANY; + } + + /// Construct an endpoint using a port number, specified in the host's byte + /// order. The IP address will be the any address (i.e. INADDR_ANY or + /// in6addr_any). This constructor would typically be used for accepting new + /// connections. + /** + * @par Examples + * To initialise an IPv4 TCP endpoint for port 1234, use: + * @code + * boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), 1234); + * @endcode + * + * To specify an IPv6 UDP endpoint for port 9876, use: + * @code + * boost::asio::ip::udp::endpoint ep(boost::asio::ip::udp::v6(), 9876); + * @endcode + */ + basic_endpoint(const InternetProtocol& protocol, unsigned short port_num) + : data_() + { + using namespace std; // For memcpy. + if (protocol.family() == PF_INET) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = INADDR_ANY; + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + data_.v6.sin6_addr = tmp_addr; + data_.v6.sin6_scope_id = 0; + } + } + + /// Construct an endpoint using a port number and an IP address. This + /// constructor may be used for accepting connections on a specific interface + /// or for making a connection to a remote endpoint. + basic_endpoint(const boost::asio::ip::address& addr, unsigned short port_num) + : data_() + { + using namespace std; // For memcpy. + if (addr.is_v4()) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + addr.to_v4().to_ulong()); + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + boost::asio::ip::address_v6 v6_addr = addr.to_v6(); + boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); + memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16); + data_.v6.sin6_scope_id = v6_addr.scope_id(); + } + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : data_(other.data_) + { + } + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + data_ = other.data_; + return *this; + } + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + if (is_v4()) + return InternetProtocol::v4(); + return InternetProtocol::v6(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return &data_.base; + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return &data_.base; + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + if (is_v4()) + return sizeof(boost::asio::detail::sockaddr_in4_type); + else + return sizeof(boost::asio::detail::sockaddr_in6_type); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t size) + { + if (size > sizeof(boost::asio::detail::sockaddr_storage_type)) + { + boost::system::system_error e(boost::asio::error::invalid_argument); + boost::throw_exception(e); + } + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(boost::asio::detail::sockaddr_storage_type); + } + + /// Get the port associated with the endpoint. The port number is always in + /// the host's byte order. + unsigned short port() const + { + if (is_v4()) + { + return boost::asio::detail::socket_ops::network_to_host_short( + data_.v4.sin_port); + } + else + { + return boost::asio::detail::socket_ops::network_to_host_short( + data_.v6.sin6_port); + } + } + + /// Set the port associated with the endpoint. The port number is always in + /// the host's byte order. + void port(unsigned short port_num) + { + if (is_v4()) + { + data_.v4.sin_port + = boost::asio::detail::socket_ops::host_to_network_short(port_num); + } + else + { + data_.v6.sin6_port + = boost::asio::detail::socket_ops::host_to_network_short(port_num); + } + } + + /// Get the IP address associated with the endpoint. + boost::asio::ip::address address() const + { + using namespace std; // For memcpy. + if (is_v4()) + { + return boost::asio::ip::address_v4( + boost::asio::detail::socket_ops::network_to_host_long( + data_.v4.sin_addr.s_addr)); + } + else + { + boost::asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); + return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); + } + } + + /// Set the IP address associated with the endpoint. + void address(const boost::asio::ip::address& addr) + { + basic_endpoint tmp_endpoint(addr, port()); + data_ = tmp_endpoint.data_; + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.address() == e2.address() && e1.port() == e2.port(); + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.address() != e2.address() || e1.port() != e2.port(); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + if (e1.address() < e2.address()) + return true; + if (e1.address() != e2.address()) + return false; + return e1.port() < e2.port(); + } + +private: + // Helper function to determine whether the endpoint is IPv4. + bool is_v4() const + { + return data_.base.sa_family == AF_INET; + } + + // The underlying IP socket address. + union data_union + { + boost::asio::detail::socket_addr_type base; + boost::asio::detail::sockaddr_storage_type storage; + boost::asio::detail::sockaddr_in4_type v4; + boost::asio::detail::sockaddr_in6_type v6; + } data_; +}; + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates boost::asio::ip::basic_endpoint + */ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +std::ostream& operator<<(std::ostream& os, + const basic_endpoint& endpoint) +{ + const address& addr = endpoint.address(); + boost::system::error_code ec; + std::string a = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + { + if (addr.is_v4()) + os << a; + else + os << '[' << a << ']'; + os << ':' << endpoint.port(); + } + return os; +} +#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + const address& addr = endpoint.address(); + boost::system::error_code ec; + std::string a = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + { + if (addr.is_v4()) + os << a; + else + os << '[' << a << ']'; + os << ':' << endpoint.port(); + } + return os; +} +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_BASIC_ENDPOINT_HPP diff --git a/thirdparty/boost/asio/ip/basic_resolver.hpp b/thirdparty/boost/asio/ip/basic_resolver.hpp new file mode 100644 index 0000000..cdd885d --- /dev/null +++ b/thirdparty/boost/asio/ip/basic_resolver.hpp @@ -0,0 +1,247 @@ +// +// basic_resolver.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_BASIC_RESOLVER_HPP +#define BOOST_ASIO_IP_BASIC_RESOLVER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Provides endpoint resolution functionality. +/** + * The basic_resolver class template provides the ability to resolve a query + * to a list of endpoints. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_resolver + : public basic_io_object +{ +public: + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef typename InternetProtocol::resolver_query query; + + /// The iterator type. + typedef typename InternetProtocol::resolver_iterator iterator; + + /// Constructor. + /** + * This constructor creates a basic_resolver. + * + * @param io_service The io_service object that the resolver will use to + * dispatch handlers for any asynchronous operations performed on the timer. + */ + explicit basic_resolver(boost::asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Cancel any asynchronous operations that are waiting on the resolver. + /** + * This function forces the completion of any pending asynchronous + * operations on the host resolver. The handler for each cancelled operation + * will be invoked with the boost::asio::error::operation_aborted error code. + */ + void cancel() + { + return this->service.cancel(this->implementation); + } + + /// Resolve a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const query& q) + { + boost::system::error_code ec; + iterator i = this->service.resolve(this->implementation, q, ec); + boost::asio::detail::throw_error(ec); + return i; + } + + /// Resolve a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. Returns a default constructed iterator if an error + * occurs. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const query& q, boost::system::error_code& ec) + { + return this->service.resolve(this->implementation, q, ec); + } + + /// Asynchronously resolve a query to a list of entries. + /** + * This function is used to asynchronously resolve a query into a list of + * endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note A default constructed iterator represents the end of the list. + * + * A successful resolve operation is guaranteed to pass at least one entry to + * the handler. + */ + template + void async_resolve(const query& q, ResolveHandler handler) + { + return this->service.async_resolve(this->implementation, q, handler); + } + + /// Resolve an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const endpoint_type& e) + { + boost::system::error_code ec; + iterator i = this->service.resolve(this->implementation, e, ec); + boost::asio::detail::throw_error(ec); + return i; + } + + /// Resolve an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. Returns a default constructed iterator if an error + * occurs. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const endpoint_type& e, boost::system::error_code& ec) + { + return this->service.resolve(this->implementation, e, ec); + } + + /// Asynchronously resolve an endpoint to a list of entries. + /** + * This function is used to asynchronously resolve an endpoint into a list of + * endpoint entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note A default constructed iterator represents the end of the list. + * + * A successful resolve operation is guaranteed to pass at least one entry to + * the handler. + */ + template + void async_resolve(const endpoint_type& e, ResolveHandler handler) + { + return this->service.async_resolve(this->implementation, e, handler); + } +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_BASIC_RESOLVER_HPP diff --git a/thirdparty/boost/asio/ip/basic_resolver_entry.hpp b/thirdparty/boost/asio/ip/basic_resolver_entry.hpp new file mode 100644 index 0000000..4bb41ae --- /dev/null +++ b/thirdparty/boost/asio/ip/basic_resolver_entry.hpp @@ -0,0 +1,97 @@ +// +// basic_resolver_entry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_BASIC_RESOLVER_ENTRY_HPP +#define BOOST_ASIO_IP_BASIC_RESOLVER_ENTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// An entry produced by a resolver. +/** + * The boost::asio::ip::basic_resolver_entry class template describes an entry + * as returned by a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_entry +{ +public: + /// The protocol type associated with the endpoint entry. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the endpoint entry. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// Default constructor. + basic_resolver_entry() + { + } + + /// Construct with specified endpoint, host name and service name. + basic_resolver_entry(const endpoint_type& endpoint, + const std::string& host_name, const std::string& service_name) + : endpoint_(endpoint), + host_name_(host_name), + service_name_(service_name) + { + } + + /// Get the endpoint associated with the entry. + endpoint_type endpoint() const + { + return endpoint_; + } + + /// Convert to the endpoint associated with the entry. + operator endpoint_type() const + { + return endpoint_; + } + + /// Get the host name associated with the entry. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the entry. + std::string service_name() const + { + return service_name_; + } + +private: + endpoint_type endpoint_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_BASIC_RESOLVER_ENTRY_HPP diff --git a/thirdparty/boost/asio/ip/basic_resolver_iterator.hpp b/thirdparty/boost/asio/ip/basic_resolver_iterator.hpp new file mode 100644 index 0000000..fdaf273 --- /dev/null +++ b/thirdparty/boost/asio/ip/basic_resolver_iterator.hpp @@ -0,0 +1,156 @@ +// +// basic_resolver_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP +#define BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// An iterator over the entries produced by a resolver. +/** + * The boost::asio::ip::basic_resolver_iterator class template is used to define + * iterators over the results returned by a resolver. + * + * The iterator's value_type, obtained when the iterator is dereferenced, is: + * @code const basic_resolver_entry @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_iterator + : public boost::iterator_facade< + basic_resolver_iterator, + const basic_resolver_entry, + boost::forward_traversal_tag> +{ +public: + /// Default constructor creates an end iterator. + basic_resolver_iterator() + { + } + + /// Create an iterator from an addrinfo list returned by getaddrinfo. + static basic_resolver_iterator create( + boost::asio::detail::addrinfo_type* address_info, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_iterator iter; + if (!address_info) + return iter; + + std::string actual_host_name = host_name; + if (address_info->ai_canonname) + actual_host_name = address_info->ai_canonname; + + iter.values_.reset(new values_type); + + while (address_info) + { + if (address_info->ai_family == PF_INET + || address_info->ai_family == PF_INET6) + { + using namespace std; // For memcpy. + typename InternetProtocol::endpoint endpoint; + endpoint.resize(static_cast(address_info->ai_addrlen)); + memcpy(endpoint.data(), address_info->ai_addr, + address_info->ai_addrlen); + iter.values_->push_back( + basic_resolver_entry(endpoint, + actual_host_name, service_name)); + } + address_info = address_info->ai_next; + } + + if (iter.values_->size()) + iter.iter_ = iter.values_->begin(); + else + iter.values_.reset(); + + return iter; + } + + /// Create an iterator from an endpoint, host name and service name. + static basic_resolver_iterator create( + const typename InternetProtocol::endpoint& endpoint, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_iterator iter; + iter.values_.reset(new values_type); + iter.values_->push_back( + basic_resolver_entry( + endpoint, host_name, service_name)); + iter.iter_ = iter.values_->begin(); + return iter; + } + +private: + friend class boost::iterator_core_access; + + void increment() + { + if (++*iter_ == values_->end()) + { + // Reset state to match a default constructed end iterator. + values_.reset(); + typedef typename values_type::const_iterator values_iterator_type; + iter_.reset(); + } + } + + bool equal(const basic_resolver_iterator& other) const + { + if (!values_ && !other.values_) + return true; + if (values_ != other.values_) + return false; + return *iter_ == *other.iter_; + } + + const basic_resolver_entry& dereference() const + { + return **iter_; + } + + typedef std::vector > values_type; + typedef typename values_type::const_iterator values_iter_type; + boost::shared_ptr values_; + boost::optional iter_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP diff --git a/thirdparty/boost/asio/ip/basic_resolver_query.hpp b/thirdparty/boost/asio/ip/basic_resolver_query.hpp new file mode 100644 index 0000000..9be32c4 --- /dev/null +++ b/thirdparty/boost/asio/ip/basic_resolver_query.hpp @@ -0,0 +1,151 @@ +// +// basic_resolver_query.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_BASIC_RESOLVER_QUERY_HPP +#define BOOST_ASIO_IP_BASIC_RESOLVER_QUERY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// An query to be passed to a resolver. +/** + * The boost::asio::ip::basic_resolver_query class template describes a query + * that can be passed to a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_query + : public resolver_query_base +{ +public: + /// The protocol type associated with the endpoint query. + typedef InternetProtocol protocol_type; + + /// Construct with specified service name for any protocol. + basic_resolver_query(const std::string& service_name, + int flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service_name) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = flags; + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified service name for a given protocol. + basic_resolver_query(const protocol_type& protocol, + const std::string& service_name, + int flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service_name) + { + hints_.ai_flags = flags; + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for any protocol. + basic_resolver_query(const std::string& host_name, + const std::string& service_name, int flags = address_configured) + : hints_(), + host_name_(host_name), + service_name_(service_name) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = flags; + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for a given protocol. + basic_resolver_query(const protocol_type& protocol, + const std::string& host_name, const std::string& service_name, + int flags = address_configured) + : hints_(), + host_name_(host_name), + service_name_(service_name) + { + hints_.ai_flags = flags; + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Get the hints associated with the query. + const boost::asio::detail::addrinfo_type& hints() const + { + return hints_; + } + + /// Get the host name associated with the query. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the query. + std::string service_name() const + { + return service_name_; + } + +private: + boost::asio::detail::addrinfo_type hints_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_BASIC_RESOLVER_QUERY_HPP diff --git a/thirdparty/boost/asio/ip/detail/socket_option.hpp b/thirdparty/boost/asio/ip/detail/socket_option.hpp new file mode 100644 index 0000000..f35ff8d --- /dev/null +++ b/thirdparty/boost/asio/ip/detail/socket_option.hpp @@ -0,0 +1,580 @@ +// +// socket_option.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_DETAIL_SOCKET_OPTION_HPP +#define BOOST_ASIO_IP_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { +namespace detail { +namespace socket_option { + +// Helper template for implementing multicast enable loopback options. +template +class multicast_enable_loopback +{ +public: +#if defined(__sun) || defined(__osf__) + typedef unsigned char ipv4_value_type; + typedef unsigned char ipv6_value_type; +#elif defined(_AIX) || defined(__hpux) + typedef unsigned char ipv4_value_type; + typedef unsigned int ipv6_value_type; +#else + typedef int ipv4_value_type; + typedef int ipv6_value_type; +#endif + + // Default constructor. + multicast_enable_loopback() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_enable_loopback(bool v) + : ipv4_value_(v ? 1 : 0), + ipv6_value_(v ? 1 : 0) + { + } + + // Set the value of the boolean. + multicast_enable_loopback& operator=(bool v) + { + ipv4_value_ = v ? 1 : 0; + ipv6_value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!ipv4_value_; + } + + // Convert to bool. + operator bool() const + { + return !!ipv4_value_; + } + + // Test for false. + bool operator!() const + { + return !ipv4_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the boolean data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the boolean data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + throw std::length_error( + "multicast_enable_loopback socket option resize"); + } + ipv4_value_ = ipv6_value_ ? 1 : 0; + } + else + { + if (s != sizeof(ipv4_value_)) + { + throw std::length_error( + "multicast_enable_loopback socket option resize"); + } + ipv6_value_ = ipv4_value_ ? 1 : 0; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing unicast hops options. +template +class unicast_hops +{ +public: + // Default constructor. + unicast_hops() + : value_(0) + { + } + + // Construct with a specific option value. + explicit unicast_hops(int v) + : value_(v) + { + } + + // Set the value of the option. + unicast_hops& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + throw std::length_error("unicast hops socket option resize"); +#if defined(__hpux) + if (value_ < 0) + value_ = value_ & 0xFF; +#endif + } + +private: + int value_; +}; + +// Helper template for implementing multicast hops options. +template +class multicast_hops +{ +public: +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + typedef int ipv4_value_type; +#else + typedef unsigned char ipv4_value_type; +#endif + typedef int ipv6_value_type; + + // Default constructor. + multicast_hops() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_hops(int v) + { + if (v < 0 || v > 255) + throw std::out_of_range("multicast hops value out of range"); + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + } + + // Set the value of the option. + multicast_hops& operator=(int v) + { + if (v < 0 || v > 255) + throw std::out_of_range("multicast hops value out of range"); + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return ipv6_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + throw std::length_error("multicast hops socket option resize"); + if (ipv6_value_ < 0) + ipv4_value_ = 0; + else if (ipv6_value_ > 255) + ipv4_value_ = 255; + else + ipv4_value_ = (ipv4_value_type)ipv6_value_; + } + else + { + if (s != sizeof(ipv4_value_)) + throw std::length_error("multicast hops socket option resize"); + ipv6_value_ = ipv4_value_; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing ip_mreq-based options. +template +class multicast_request +{ +public: + // Default constructor. + multicast_request() + { + ipv4_value_.imr_multiaddr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + + // Construct with multicast address only. + explicit multicast_request(const boost::asio::ip::address& multicast_address) + { + if (multicast_address.is_v6()) + { + ipv4_value_.imr_multiaddr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + + using namespace std; // For memcpy. + boost::asio::ip::address_v6 ipv6_address = multicast_address.to_v6(); + boost::asio::ip::address_v6::bytes_type bytes = ipv6_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.elems, 16); + ipv6_value_.ipv6mr_interface = 0; + } + else + { + ipv4_value_.imr_multiaddr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + multicast_address.to_v4().to_ulong()); + ipv4_value_.imr_interface.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + } + + // Construct with multicast address and IPv4 address specifying an interface. + explicit multicast_request( + const boost::asio::ip::address_v4& multicast_address, + const boost::asio::ip::address_v4& network_interface + = boost::asio::ip::address_v4::any()) + { + ipv4_value_.imr_multiaddr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + multicast_address.to_ulong()); + ipv4_value_.imr_interface.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + network_interface.to_ulong()); + + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + + // Construct with multicast address and IPv6 network interface index. + explicit multicast_request( + const boost::asio::ip::address_v6& multicast_address, + unsigned long network_interface = 0) + { + ipv4_value_.imr_multiaddr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + + using namespace std; // For memcpy. + boost::asio::ip::address_v6::bytes_type bytes = + multicast_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.elems, 16); + ipv6_value_.ipv6mr_interface = network_interface; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + boost::asio::detail::in4_mreq_type ipv4_value_; + boost::asio::detail::in6_mreq_type ipv6_value_; +}; + +// Helper template for implementing options that specify a network interface. +template +class network_interface +{ +public: + // Default constructor. + network_interface() + { + ipv4_value_.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + ipv6_value_ = 0; + } + + // Construct with IPv4 interface. + explicit network_interface(const boost::asio::ip::address_v4& ipv4_interface) + { + ipv4_value_.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + ipv4_interface.to_ulong()); + ipv6_value_ = 0; + } + + // Construct with IPv6 interface. + explicit network_interface(unsigned int ipv6_interface) + { + ipv4_value_.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + boost::asio::ip::address_v4::any().to_ulong()); + ipv6_value_ = ipv6_interface; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + boost::asio::detail::in4_addr_type ipv4_value_; + unsigned int ipv6_value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_DETAIL_SOCKET_OPTION_HPP diff --git a/thirdparty/boost/asio/ip/host_name.hpp b/thirdparty/boost/asio/ip/host_name.hpp new file mode 100644 index 0000000..778e525 --- /dev/null +++ b/thirdparty/boost/asio/ip/host_name.hpp @@ -0,0 +1,64 @@ +// +// host_name.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_HOST_NAME_HPP +#define BOOST_ASIO_IP_HOST_NAME_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Get the current host name. +std::string host_name(); + +/// Get the current host name. +std::string host_name(boost::system::error_code& ec); + +inline std::string host_name() +{ + char name[1024]; + boost::system::error_code ec; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + { + boost::asio::detail::throw_error(ec); + return std::string(); + } + return std::string(name); +} + +inline std::string host_name(boost::system::error_code& ec) +{ + char name[1024]; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + return std::string(); + return std::string(name); +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_HOST_NAME_HPP diff --git a/thirdparty/boost/asio/ip/multicast.hpp b/thirdparty/boost/asio/ip/multicast.hpp new file mode 100644 index 0000000..0888d08 --- /dev/null +++ b/thirdparty/boost/asio/ip/multicast.hpp @@ -0,0 +1,183 @@ +// +// multicast.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_MULTICAST_HPP +#define BOOST_ASIO_IP_MULTICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace ip { +namespace multicast { + +/// Socket option to join a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_ADD_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to join a multicast group: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::address multicast_address = + * boost::asio::ip::address::from_string("225.0.0.1"); + * boost::asio::ip::multicast::join_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined join_group; +#else +typedef boost::asio::ip::detail::socket_option::multicast_request< + IPPROTO_IP, IP_ADD_MEMBERSHIP, IPPROTO_IPV6, IPV6_JOIN_GROUP> join_group; +#endif + +/// Socket option to leave a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_DROP_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to leave a multicast group: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::address multicast_address = + * boost::asio::ip::address::from_string("225.0.0.1"); + * boost::asio::ip::multicast::leave_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined leave_group; +#else +typedef boost::asio::ip::detail::socket_option::multicast_request< + IPPROTO_IP, IP_DROP_MEMBERSHIP, IPPROTO_IPV6, IPV6_LEAVE_GROUP> leave_group; +#endif + +/// Socket option for local interface to use for outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_IF socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::address_v4 local_interface = + * boost::asio::ip::address_v4::from_string("1.2.3.4"); + * boost::asio::ip::multicast::outbound_interface option(local_interface); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined outbound_interface; +#else +typedef boost::asio::ip::detail::socket_option::network_interface< + IPPROTO_IP, IP_MULTICAST_IF, IPPROTO_IPV6, IPV6_MULTICAST_IF> + outbound_interface; +#endif + +/// Socket option for time-to-live associated with outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::multicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::multicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef boost::asio::ip::detail::socket_option::multicast_hops< + IPPROTO_IP, IP_MULTICAST_TTL, IPPROTO_IPV6, IPV6_MULTICAST_HOPS> hops; +#endif + +/// Socket option determining whether outgoing multicast packets will be +/// received on the same socket if it is a member of the multicast group. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_LOOP socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::multicast::enable_loopback option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::multicast::enable_loopback option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined enable_loopback; +#else +typedef boost::asio::ip::detail::socket_option::multicast_enable_loopback< + IPPROTO_IP, IP_MULTICAST_LOOP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP> + enable_loopback; +#endif + +} // namespace multicast +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_MULTICAST_HPP diff --git a/thirdparty/boost/asio/ip/resolver_query_base.hpp b/thirdparty/boost/asio/ip/resolver_query_base.hpp new file mode 100644 index 0000000..40f7e78 --- /dev/null +++ b/thirdparty/boost/asio/ip/resolver_query_base.hpp @@ -0,0 +1,109 @@ +// +// resolver_query_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_RESOLVER_QUERY_BASE_HPP +#define BOOST_ASIO_IP_RESOLVER_QUERY_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace ip { + +/// The resolver_query_base class is used as a base for the +/// basic_resolver_query class templates to provide a common place to define +/// the flag constants. +class resolver_query_base +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// Determine the canonical name of the host specified in the query. + static const int canonical_name = implementation_defined; + + /// Indicate that returned endpoint is intended for use as a locally bound + /// socket endpoint. + static const int passive = implementation_defined; + + /// Host name should be treated as a numeric string defining an IPv4 or IPv6 + /// address and no name resolution should be attempted. + static const int numeric_host = implementation_defined; + + /// Service name should be treated as a numeric string defining a port number + /// and no name resolution should be attempted. + static const int numeric_service = implementation_defined; + + /// If the query protocol family is specified as IPv6, return IPv4-mapped + /// IPv6 addresses on finding no IPv6 addresses. + static const int v4_mapped = implementation_defined; + + /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses. + static const int all_matching = implementation_defined; + + /// Only return IPv4 addresses if a non-loopback IPv4 address is configured + /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address + /// is configured for the system. + static const int address_configured = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, canonical_name = AI_CANONNAME); + BOOST_STATIC_CONSTANT(int, passive = AI_PASSIVE); + BOOST_STATIC_CONSTANT(int, numeric_host = AI_NUMERICHOST); +# if defined(AI_NUMERICSERV) + BOOST_STATIC_CONSTANT(int, numeric_service = AI_NUMERICSERV); +# else + BOOST_STATIC_CONSTANT(int, numeric_service = 0); +# endif +# if defined(AI_V4MAPPED) + BOOST_STATIC_CONSTANT(int, v4_mapped = AI_V4MAPPED); +# else + BOOST_STATIC_CONSTANT(int, v4_mapped = 0); +# endif +# if defined(AI_ALL) + BOOST_STATIC_CONSTANT(int, all_matching = AI_ALL); +# else + BOOST_STATIC_CONSTANT(int, all_matching = 0); +# endif +# if defined(AI_ADDRCONFIG) + BOOST_STATIC_CONSTANT(int, address_configured = AI_ADDRCONFIG); +# else + BOOST_STATIC_CONSTANT(int, address_configured = 0); +# endif +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_query_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_RESOLVER_QUERY_BASE_HPP diff --git a/thirdparty/boost/asio/ip/resolver_service.hpp b/thirdparty/boost/asio/ip/resolver_service.hpp new file mode 100644 index 0000000..0460f54 --- /dev/null +++ b/thirdparty/boost/asio/ip/resolver_service.hpp @@ -0,0 +1,142 @@ +// +// resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_RESOLVER_SERVICE_HPP +#define BOOST_ASIO_IP_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Default service implementation for a resolver. +template +class resolver_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base< + resolver_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef typename InternetProtocol::resolver_query query_type; + + /// The iterator type. + typedef typename InternetProtocol::resolver_iterator iterator_type; + +private: + // The type of the platform-specific implementation. + typedef boost::asio::detail::resolver_service + service_impl_type; + +public: + /// The type of a resolver implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new resolver service for the specified io_service. + explicit resolver_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + resolver_service >(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new resolver implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a resolver implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + service_impl_.cancel(impl); + } + + /// Resolve a query to a list of entries. + iterator_type resolve(implementation_type& impl, const query_type& query, + boost::system::error_code& ec) + { + return service_impl_.resolve(impl, query, ec); + } + + /// Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, const query_type& query, + Handler handler) + { + service_impl_.async_resolve(impl, query, handler); + } + + /// Resolve an endpoint to a list of entries. + iterator_type resolve(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.resolve(impl, endpoint, ec); + } + + /// Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type& impl, const endpoint_type& endpoint, + ResolveHandler handler) + { + return service_impl_.async_resolve(impl, endpoint, handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_RESOLVER_SERVICE_HPP diff --git a/thirdparty/boost/asio/ip/tcp.hpp b/thirdparty/boost/asio/ip/tcp.hpp new file mode 100644 index 0000000..582e6f8 --- /dev/null +++ b/thirdparty/boost/asio/ip/tcp.hpp @@ -0,0 +1,160 @@ +// +// tcp.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_TCP_HPP +#define BOOST_ASIO_IP_TCP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for TCP. +/** + * The boost::asio::ip::tcp class contains flags necessary for TCP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class tcp +{ +public: + /// The type of a TCP endpoint. + typedef basic_endpoint endpoint; + + /// The type of a resolver query. + typedef basic_resolver_query resolver_query; + + /// The type of a resolver iterator. + typedef basic_resolver_iterator resolver_iterator; + + /// Construct to represent the IPv4 TCP protocol. + static tcp v4() + { + return tcp(PF_INET); + } + + /// Construct to represent the IPv6 TCP protocol. + static tcp v6() + { + return tcp(PF_INET6); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_STREAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return IPPROTO_TCP; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The TCP socket type. + typedef basic_stream_socket socket; + + /// The TCP acceptor type. + typedef basic_socket_acceptor acceptor; + + /// The TCP resolver type. + typedef basic_resolver resolver; + + /// The TCP iostream type. + typedef basic_socket_iostream iostream; + + /// Socket option for disabling the Nagle algorithm. + /** + * Implements the IPPROTO_TCP/TCP_NODELAY socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::tcp::no_delay option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined no_delay; +#else + typedef boost::asio::detail::socket_option::boolean< + IPPROTO_TCP, TCP_NODELAY> no_delay; +#endif + + /// Compare two protocols for equality. + friend bool operator==(const tcp& p1, const tcp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const tcp& p1, const tcp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit tcp(int family) + : family_(family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_TCP_HPP diff --git a/thirdparty/boost/asio/ip/udp.hpp b/thirdparty/boost/asio/ip/udp.hpp new file mode 100644 index 0000000..458ab9e --- /dev/null +++ b/thirdparty/boost/asio/ip/udp.hpp @@ -0,0 +1,118 @@ +// +// udp.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_UDP_HPP +#define BOOST_ASIO_IP_UDP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for UDP. +/** + * The boost::asio::ip::udp class contains flags necessary for UDP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class udp +{ +public: + /// The type of a UDP endpoint. + typedef basic_endpoint endpoint; + + /// The type of a resolver query. + typedef basic_resolver_query resolver_query; + + /// The type of a resolver iterator. + typedef basic_resolver_iterator resolver_iterator; + + /// Construct to represent the IPv4 UDP protocol. + static udp v4() + { + return udp(PF_INET); + } + + /// Construct to represent the IPv6 UDP protocol. + static udp v6() + { + return udp(PF_INET6); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_DGRAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return IPPROTO_UDP; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The UDP socket type. + typedef basic_datagram_socket socket; + + /// The UDP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const udp& p1, const udp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const udp& p1, const udp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit udp(int family) + : family_(family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_UDP_HPP diff --git a/thirdparty/boost/asio/ip/unicast.hpp b/thirdparty/boost/asio/ip/unicast.hpp new file mode 100644 index 0000000..775934a --- /dev/null +++ b/thirdparty/boost/asio/ip/unicast.hpp @@ -0,0 +1,72 @@ +// +// unicast.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_UNICAST_HPP +#define BOOST_ASIO_IP_UNICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace ip { +namespace unicast { + +/// Socket option for time-to-live associated with outgoing unicast packets. +/** + * Implements the IPPROTO_IP/IP_UNICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::unicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::ip::unicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef boost::asio::ip::detail::socket_option::unicast_hops< + IPPROTO_IP, IP_TTL, IPPROTO_IPV6, IPV6_UNICAST_HOPS> hops; +#endif + +} // namespace unicast +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_UNICAST_HPP diff --git a/thirdparty/boost/asio/ip/v6_only.hpp b/thirdparty/boost/asio/ip/v6_only.hpp new file mode 100644 index 0000000..7af5c31 --- /dev/null +++ b/thirdparty/boost/asio/ip/v6_only.hpp @@ -0,0 +1,70 @@ +// +// v6_only.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IP_V6_ONLY_HPP +#define BOOST_ASIO_IP_V6_ONLY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Socket option for determining whether an IPv6 socket supports IPv6 +/// communication only. +/** + * Implements the IPPROTO_IPV6/IP_V6ONLY socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::v6_only option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::ip::v6_only option; + * socket.get_option(option); + * bool v6_only = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined v6_only; +#elif defined(IPV6_V6ONLY) +typedef boost::asio::detail::socket_option::boolean< + IPPROTO_IPV6, IPV6_V6ONLY> v6_only; +#else +typedef boost::asio::detail::socket_option::boolean< + boost::asio::detail::custom_socket_option_level, + boost::asio::detail::always_fail_option> v6_only; +#endif + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_V6_ONLY_HPP diff --git a/thirdparty/boost/asio/is_read_buffered.hpp b/thirdparty/boost/asio/is_read_buffered.hpp new file mode 100644 index 0000000..4122870 --- /dev/null +++ b/thirdparty/boost/asio/is_read_buffered.hpp @@ -0,0 +1,64 @@ +// +// is_read_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IS_READ_BUFFERED_HPP +#define BOOST_ASIO_IS_READ_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +namespace detail { + +template +char is_read_buffered_helper(buffered_stream* s); + +template +char is_read_buffered_helper(buffered_read_stream* s); + +struct is_read_buffered_big_type { char data[10]; }; +is_read_buffered_big_type is_read_buffered_helper(...); + +} // namespace detail + +/// The is_read_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of read data. +template +class is_read_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// read data. + static const bool value; +#else + BOOST_STATIC_CONSTANT(bool, + value = sizeof(detail::is_read_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IS_READ_BUFFERED_HPP diff --git a/thirdparty/boost/asio/is_write_buffered.hpp b/thirdparty/boost/asio/is_write_buffered.hpp new file mode 100644 index 0000000..0cf3259 --- /dev/null +++ b/thirdparty/boost/asio/is_write_buffered.hpp @@ -0,0 +1,64 @@ +// +// is_write_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_IS_WRITE_BUFFERED_HPP +#define BOOST_ASIO_IS_WRITE_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +namespace detail { + +template +char is_write_buffered_helper(buffered_stream* s); + +template +char is_write_buffered_helper(buffered_write_stream* s); + +struct is_write_buffered_big_type { char data[10]; }; +is_write_buffered_big_type is_write_buffered_helper(...); + +} // namespace detail + +/// The is_write_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of written data. +template +class is_write_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// written data. + static const bool value; +#else + BOOST_STATIC_CONSTANT(bool, + value = sizeof(detail::is_write_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IS_WRITE_BUFFERED_HPP diff --git a/thirdparty/boost/asio/placeholders.hpp b/thirdparty/boost/asio/placeholders.hpp new file mode 100644 index 0000000..bb152e3 --- /dev/null +++ b/thirdparty/boost/asio/placeholders.hpp @@ -0,0 +1,109 @@ +// +// placeholders.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_PLACEHOLDERS_HPP +#define BOOST_ASIO_PLACEHOLDERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace placeholders { + +#if defined(GENERATING_DOCUMENTATION) + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the error argument of a handler for any of the asynchronous functions. +unspecified error; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the bytes_transferred argument of a handler for asynchronous functions such +/// as boost::asio::basic_stream_socket::async_write_some or +/// boost::asio::async_write. +unspecified bytes_transferred; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the iterator argument of a handler for asynchronous functions such as +/// boost::asio::basic_resolver::resolve. +unspecified iterator; + +#elif defined(__BORLANDC__) || defined(__GNUC__) + +inline boost::arg<1> error() +{ + return boost::arg<1>(); +} + +inline boost::arg<2> bytes_transferred() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> iterator() +{ + return boost::arg<2>(); +} + +#else + +namespace detail +{ + template + struct placeholder + { + static boost::arg& get() + { + static boost::arg result; + return result; + } + }; +} + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) + +static boost::arg<1>& error + = boost::asio::placeholders::detail::placeholder<1>::get(); +static boost::arg<2>& bytes_transferred + = boost::asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& iterator + = boost::asio::placeholders::detail::placeholder<2>::get(); + +#else + +namespace +{ + boost::arg<1>& error + = boost::asio::placeholders::detail::placeholder<1>::get(); + boost::arg<2>& bytes_transferred + = boost::asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& iterator + = boost::asio::placeholders::detail::placeholder<2>::get(); +} // namespace + +#endif + +#endif + +} // namespace placeholders +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_PLACEHOLDERS_HPP diff --git a/thirdparty/boost/asio/read.hpp b/thirdparty/boost/asio/read.hpp new file mode 100644 index 0000000..7908ee2 --- /dev/null +++ b/thirdparty/boost/asio/read.hpp @@ -0,0 +1,518 @@ +// +// read.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_READ_HPP +#define BOOST_ASIO_READ_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +/** + * @defgroup read boost::asio::read + */ +/*@{*/ + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code boost::asio::read(s, boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code boost::asio::read( + * s, buffers, + * boost::asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's read_some function are required. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code boost::asio::read(s, boost::asio::buffer(data, size), + * boost::asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's read_some function are required. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, boost::system::error_code& ec); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code boost::asio::read( + * s, b, + * boost::asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's read_some function are required. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's read_some function are required. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, boost::system::error_code& ec); + +/*@}*/ +/** + * @defgroup async_read boost::asio::async_read + */ +/*@{*/ + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::async_read(s, boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code boost::asio::async_read( + * s, buffers, + * boost::asio::transfer_all(), + * handler); @endcode + */ +template +void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's async_read_some function are + * required. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code boost::asio::async_read(s, + * boost::asio::buffer(data, size), + * boost::asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note This overload is equivalent to calling: + * @code boost::asio::async_read( + * s, b, + * boost::asio::transfer_all(), + * handler); @endcode + */ +template +void async_read(AsyncReadStream& s, basic_streambuf& b, + ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest read_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the read operation is complete. False + * indicates that further calls to the stream's async_read_some function are + * required. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ +template +void async_read(AsyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler); + +/*@}*/ + +} // namespace asio +} // namespace boost + +#include + +#include + +#endif // BOOST_ASIO_READ_HPP diff --git a/thirdparty/boost/asio/read_until.hpp b/thirdparty/boost/asio/read_until.hpp new file mode 100644 index 0000000..4e103ff --- /dev/null +++ b/thirdparty/boost/asio/read_until.hpp @@ -0,0 +1,454 @@ +// +// read_until.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_READ_UNTIL_HPP +#define BOOST_ASIO_READ_UNTIL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +/** + * @defgroup read_until boost::asio::read_until + */ +/*@{*/ + +/// Read data into a streambuf until a delimiter is encountered. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code boost::asio::streambuf b; + * boost::asio::read_until(s, b, '\n'); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, char delim); + +/// Read data into a streambuf until a delimiter is encountered. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, char delim, + boost::system::error_code& ec); + +/// Read data into a streambuf until a delimiter is encountered. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code boost::asio::streambuf b; + * boost::asio::read_until(s, b, "\r\n"); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim); + +/// Read data into a streambuf until a delimiter is encountered. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim, + boost::system::error_code& ec); + +/// Read data into a streambuf until a regular expression is located. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To read data into a streambuf until a CR-LF sequence is encountered: + * @code boost::asio::streambuf b; + * boost::asio::read_until(s, b, boost::regex("\r\n")); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr); + +/// Read data into a streambuf until a regular expression is located. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. Returns 0 if an error + * occurred. + */ +template +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr, + boost::system::error_code& ec); + +/*@}*/ +/** +* @defgroup async_read_until boost::asio::async_read_until +*/ +/*@{*/ + +/// Start an asynchronous operation to read data into a streambuf until a +/// delimiter is encountered. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function. If the streambuf's get area already contains the + * delimiter, the asynchronous operation completes immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter character. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the delimiter. + * // 0 if an error occurred. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code boost::asio::streambuf b; + * ... + * void handler(const boost::system::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * boost::asio::async_read_until(s, b, '\n', handler); @endcode + */ +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, + char delim, ReadHandler handler); + +/// Start an asynchronous operation to read data into a streambuf until a +/// delimiter is encountered. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function. If the streambuf's get area already contains the + * delimiter, the asynchronous operation completes immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter string. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the delimiter. + * // 0 if an error occurred. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code boost::asio::streambuf b; + * ... + * void handler(const boost::system::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * boost::asio::async_read_until(s, b, "\r\n", handler); @endcode + */ +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, const std::string& delim, + ReadHandler handler); + +/// Start an asynchronous operation to read data into a streambuf until a +/// regular expression is located. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains some data that matches a + * regular expression. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function. If the streambuf's get area already contains data + * that matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param expr The regular expression. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the substring + * // that matches the regular. + * // expression. 0 if an error + * // occurred. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To asynchronously read data into a streambuf until a CR-LF sequence is + * encountered: + * @code boost::asio::streambuf b; + * ... + * void handler(const boost::system::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * boost::asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode + */ +template +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf& b, const boost::regex& expr, + ReadHandler handler); + +/*@}*/ + +} // namespace asio +} // namespace boost + +#include + +#include + +#endif // BOOST_ASIO_READ_UNTIL_HPP diff --git a/thirdparty/boost/asio/socket_acceptor_service.hpp b/thirdparty/boost/asio/socket_acceptor_service.hpp new file mode 100644 index 0000000..3b435b2 --- /dev/null +++ b/thirdparty/boost/asio/socket_acceptor_service.hpp @@ -0,0 +1,227 @@ +// +// socket_acceptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP +#define BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a socket acceptor. +template +class socket_acceptor_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename protocol_type::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_EPOLL) + typedef detail::reactive_socket_service< + Protocol, detail::epoll_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + typedef detail::reactive_socket_service< + Protocol, detail::kqueue_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + typedef detail::reactive_socket_service< + Protocol, detail::dev_poll_reactor > service_impl_type; +#else + typedef detail::reactive_socket_service< + Protocol, detail::select_reactor > service_impl_type; +#endif + +public: + /// The native type of the socket acceptor. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native acceptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new socket acceptor service for the specified io_service. + explicit socket_acceptor_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + socket_acceptor_service >(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new socket acceptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a socket acceptor implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a new socket acceptor implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + return service_impl_.open(impl, protocol, ec); + } + + /// Assign an existing native acceptor to a socket acceptor. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_acceptor, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Cancel all asynchronous operations associated with the acceptor. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Bind the socket acceptor to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Place the socket acceptor into the state where it will listen for new + /// connections. + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) + { + return service_impl_.listen(impl, backlog, ec); + } + + /// Close a socket acceptor implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native acceptor implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, boost::system::error_code& ec) + { + return service_impl_.accept(impl, peer, peer_endpoint, ec); + } + + /// Start an asynchronous accept. + template + void async_accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, AcceptHandler handler) + { + service_impl_.async_accept(impl, peer, peer_endpoint, handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP diff --git a/thirdparty/boost/asio/socket_base.hpp b/thirdparty/boost/asio/socket_base.hpp new file mode 100644 index 0000000..fec77c8 --- /dev/null +++ b/thirdparty/boost/asio/socket_base.hpp @@ -0,0 +1,517 @@ +// +// socket_base.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SOCKET_BASE_HPP +#define BOOST_ASIO_SOCKET_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { + +/// The socket_base class is used as a base for the basic_stream_socket and +/// basic_datagram_socket class templates so that we have a common place to +/// define the shutdown_type and enum. +class socket_base +{ +public: + /// Different ways a socket may be shutdown. + enum shutdown_type + { +#if defined(GENERATING_DOCUMENTATION) + /// Shutdown the receive side of the socket. + shutdown_receive = implementation_defined, + + /// Shutdown the send side of the socket. + shutdown_send = implementation_defined, + + /// Shutdown both send and receive on the socket. + shutdown_both = implementation_defined +#else + shutdown_receive = boost::asio::detail::shutdown_receive, + shutdown_send = boost::asio::detail::shutdown_send, + shutdown_both = boost::asio::detail::shutdown_both +#endif + }; + + /// Bitmask type for flags that can be passed to send and receive operations. + typedef int message_flags; + +#if defined(GENERATING_DOCUMENTATION) + /// Peek at incoming data without removing it from the input queue. + static const int message_peek = implementation_defined; + + /// Process out-of-band data. + static const int message_out_of_band = implementation_defined; + + /// Specify that the data should not be subject to routing. + static const int message_do_not_route = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, + message_peek = boost::asio::detail::message_peek); + BOOST_STATIC_CONSTANT(int, + message_out_of_band = boost::asio::detail::message_out_of_band); + BOOST_STATIC_CONSTANT(int, + message_do_not_route = boost::asio::detail::message_do_not_route); +#endif + + /// Socket option to permit sending of broadcast messages. + /** + * Implements the SOL_SOCKET/SO_BROADCAST socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::socket_base::broadcast option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::socket_base::broadcast option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined broadcast; +#else + typedef boost::asio::detail::socket_option::boolean< + SOL_SOCKET, SO_BROADCAST> broadcast; +#endif + + /// Socket option to enable socket-level debugging. + /** + * Implements the SOL_SOCKET/SO_DEBUG socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::debug option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::debug option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined debug; +#else + typedef boost::asio::detail::socket_option::boolean< + SOL_SOCKET, SO_DEBUG> debug; +#endif + + /// Socket option to prevent routing, use local interfaces only. + /** + * Implements the SOL_SOCKET/SO_DONTROUTE socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::socket_base::do_not_route option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::udp::socket socket(io_service); + * ... + * boost::asio::socket_base::do_not_route option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined do_not_route; +#else + typedef boost::asio::detail::socket_option::boolean< + SOL_SOCKET, SO_DONTROUTE> do_not_route; +#endif + + /// Socket option to send keep-alives. + /** + * Implements the SOL_SOCKET/SO_KEEPALIVE socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::keep_alive option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::keep_alive option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined keep_alive; +#else + typedef boost::asio::detail::socket_option::boolean< + SOL_SOCKET, SO_KEEPALIVE> keep_alive; +#endif + + /// Socket option for the send buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_SNDBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::send_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::send_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_buffer_size; +#else + typedef boost::asio::detail::socket_option::integer< + SOL_SOCKET, SO_SNDBUF> send_buffer_size; +#endif + + /// Socket option for the send low watermark. + /** + * Implements the SOL_SOCKET/SO_SNDLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::send_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::send_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_low_watermark; +#else + typedef boost::asio::detail::socket_option::integer< + SOL_SOCKET, SO_SNDLOWAT> send_low_watermark; +#endif + + /// Socket option for the receive buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_RCVBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::receive_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::receive_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_buffer_size; +#else + typedef boost::asio::detail::socket_option::integer< + SOL_SOCKET, SO_RCVBUF> receive_buffer_size; +#endif + + /// Socket option for the receive low watermark. + /** + * Implements the SOL_SOCKET/SO_RCVLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::receive_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::receive_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_low_watermark; +#else + typedef boost::asio::detail::socket_option::integer< + SOL_SOCKET, SO_RCVLOWAT> receive_low_watermark; +#endif + + /// Socket option to allow the socket to be bound to an address that is + /// already in use. + /** + * Implements the SOL_SOCKET/SO_REUSEADDR socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::socket_base::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::socket_base::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined reuse_address; +#else + typedef boost::asio::detail::socket_option::boolean< + SOL_SOCKET, SO_REUSEADDR> reuse_address; +#endif + + /// Socket option to specify whether the socket lingers on close if unsent + /// data is present. + /** + * Implements the SOL_SOCKET/SO_LINGER socket option. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::linger option(true, 30); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::linger option; + * socket.get_option(option); + * bool is_set = option.enabled(); + * unsigned short timeout = option.timeout(); + * @endcode + * + * @par Concepts: + * Socket_Option, Linger_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined linger; +#else + typedef boost::asio::detail::socket_option::linger< + SOL_SOCKET, SO_LINGER> linger; +#endif + + /// Socket option to report aborted connections on accept. + /** + * Implements a custom socket option that determines whether or not an accept + * operation is permitted to fail with boost::asio::error::connection_aborted. + * By default the option is false. + * + * @par Examples + * Setting the option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::socket_base::enable_connection_aborted option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::socket_base::enable_connection_aborted option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined enable_connection_aborted; +#else + typedef boost::asio::detail::socket_option::boolean< + boost::asio::detail::custom_socket_option_level, + boost::asio::detail::enable_connection_aborted_option> + enable_connection_aborted; +#endif + + /// IO control command to set the blocking mode of the socket. + /** + * Implements the FIONBIO IO control command. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::non_blocking_io command(true); + * socket.io_control(command); + * @endcode + * + * @par Concepts: + * IO_Control_Command, Boolean_IO_Control_Command. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined non_blocking_io; +#else + typedef boost::asio::detail::io_control::non_blocking_io non_blocking_io; +#endif + + /// IO control command to get the amount of data that can be read without + /// blocking. + /** + * Implements the FIONREAD IO control command. + * + * @par Example + * @code + * boost::asio::ip::tcp::socket socket(io_service); + * ... + * boost::asio::socket_base::bytes_readable command(true); + * socket.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + * + * @par Concepts: + * IO_Control_Command, Size_IO_Control_Command. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined bytes_readable; +#else + typedef boost::asio::detail::io_control::bytes_readable bytes_readable; +#endif + + /// The maximum length of the queue of pending incoming connections. +#if defined(GENERATING_DOCUMENTATION) + static const int max_connections = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, max_connections = SOMAXCONN); +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~socket_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SOCKET_BASE_HPP diff --git a/thirdparty/boost/asio/ssl.hpp b/thirdparty/boost/asio/ssl.hpp new file mode 100644 index 0000000..97c61c9 --- /dev/null +++ b/thirdparty/boost/asio/ssl.hpp @@ -0,0 +1,26 @@ +// +// ssl.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_HPP +#define BOOST_ASIO_SSL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_ASIO_SSL_HPP diff --git a/thirdparty/boost/asio/ssl/basic_context.hpp b/thirdparty/boost/asio/ssl/basic_context.hpp new file mode 100644 index 0000000..d452e24 --- /dev/null +++ b/thirdparty/boost/asio/ssl/basic_context.hpp @@ -0,0 +1,436 @@ +// +// basic_context.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_BASIC_CONTEXT_HPP +#define BOOST_ASIO_SSL_BASIC_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// SSL context. +template +class basic_context + : public context_base, + private boost::noncopyable +{ +public: + /// The type of the service that will be used to provide context operations. + typedef Service service_type; + + /// The native implementation type of the locking dispatcher. + typedef typename service_type::impl_type impl_type; + + /// Constructor. + basic_context(boost::asio::io_service& io_service, method m) + : service_(boost::asio::use_service(io_service)), + impl_(service_.null()) + { + service_.create(impl_, m); + } + + /// Destructor. + ~basic_context() + { + service_.destroy(impl_); + } + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + */ + impl_type impl() + { + return impl_; + } + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @throws boost::system::system_error Thrown on failure. + */ + void set_options(options o) + { + boost::system::error_code ec; + service_.set_options(impl_, o, ec); + boost::asio::detail::throw_error(ec); + } + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code set_options(options o, + boost::system::error_code& ec) + { + return service_.set_options(impl_, o, ec); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. The available verify_mode + * values are defined in the context_base class. + * + * @throws boost::system::system_error Thrown on failure. + */ + void set_verify_mode(verify_mode v) + { + boost::system::error_code ec; + service_.set_verify_mode(impl_, v, ec); + boost::asio::detail::throw_error(ec); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. The available verify_mode + * values are defined in the context_base class. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code set_verify_mode(verify_mode v, + boost::system::error_code& ec) + { + return service_.set_verify_mode(impl_, v, ec); + } + + /// Load a certification authority file for performing verification. + /** + * This function is used to load one or more trusted certification authorities + * from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @throws boost::system::system_error Thrown on failure. + */ + void load_verify_file(const std::string& filename) + { + boost::system::error_code ec; + service_.load_verify_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); + } + + /// Load a certification authority file for performing verification. + /** + * This function is used to load the certificates for one or more trusted + * certification authorities from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code load_verify_file(const std::string& filename, + boost::system::error_code& ec) + { + return service_.load_verify_file(impl_, filename, ec); + } + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @throws boost::system::system_error Thrown on failure. + */ + void add_verify_path(const std::string& path) + { + boost::system::error_code ec; + service_.add_verify_path(impl_, path, ec); + boost::asio::detail::throw_error(ec); + } + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code add_verify_path(const std::string& path, + boost::system::error_code& ec) + { + return service_.add_verify_path(impl_, path, ec); + } + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + */ + void use_certificate_file(const std::string& filename, file_format format) + { + boost::system::error_code ec; + service_.use_certificate_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); + } + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code use_certificate_file(const std::string& filename, + file_format format, boost::system::error_code& ec) + { + return service_.use_certificate_file(impl_, filename, format, ec); + } + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @throws boost::system::system_error Thrown on failure. + */ + void use_certificate_chain_file(const std::string& filename) + { + boost::system::error_code ec; + service_.use_certificate_chain_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); + } + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code use_certificate_chain_file( + const std::string& filename, boost::system::error_code& ec) + { + return service_.use_certificate_chain_file(impl_, filename, ec); + } + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + */ + void use_private_key_file(const std::string& filename, file_format format) + { + boost::system::error_code ec; + service_.use_private_key_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); + } + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code use_private_key_file(const std::string& filename, + file_format format, boost::system::error_code& ec) + { + return service_.use_private_key_file(impl_, filename, format, ec); + } + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws boost::system::system_error Thrown on failure. + */ + void use_rsa_private_key_file(const std::string& filename, file_format format) + { + boost::system::error_code ec; + service_.use_rsa_private_key_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); + } + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code use_rsa_private_key_file( + const std::string& filename, file_format format, + boost::system::error_code& ec) + { + return service_.use_rsa_private_key_file(impl_, filename, format, ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @throws boost::system::system_error Thrown on failure. + */ + void use_tmp_dh_file(const std::string& filename) + { + boost::system::error_code ec; + service_.use_tmp_dh_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code use_tmp_dh_file(const std::string& filename, + boost::system::error_code& ec) + { + return service_.use_tmp_dh_file(impl_, filename, ec); + } + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + void set_password_callback(PasswordCallback callback) + { + boost::system::error_code ec; + service_.set_password_callback(impl_, callback, ec); + boost::asio::detail::throw_error(ec); + } + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @param ec Set to indicate what error occurred, if any. + */ + template + boost::system::error_code set_password_callback(PasswordCallback callback, + boost::system::error_code& ec) + { + return service_.set_password_callback(impl_, callback, ec); + } + +private: + /// The backend service implementation. + service_type& service_; + + /// The underlying native implementation. + impl_type impl_; +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_BASIC_CONTEXT_HPP diff --git a/thirdparty/boost/asio/ssl/context.hpp b/thirdparty/boost/asio/ssl/context.hpp new file mode 100644 index 0000000..3618277 --- /dev/null +++ b/thirdparty/boost/asio/ssl/context.hpp @@ -0,0 +1,37 @@ +// +// context.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_CONTEXT_HPP +#define BOOST_ASIO_SSL_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// Typedef for the typical usage of context. +typedef basic_context context; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_CONTEXT_HPP diff --git a/thirdparty/boost/asio/ssl/context_base.hpp b/thirdparty/boost/asio/ssl/context_base.hpp new file mode 100644 index 0000000..b03e8fd --- /dev/null +++ b/thirdparty/boost/asio/ssl/context_base.hpp @@ -0,0 +1,166 @@ +// +// context_base.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_CONTEXT_BASE_HPP +#define BOOST_ASIO_SSL_CONTEXT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// The context_base class is used as a base for the basic_context class +/// template so that we have a common place to define various enums. +class context_base +{ +public: + /// Different methods supported by a context. + enum method + { + /// Generic SSL version 2. + sslv2, + + /// SSL version 2 client. + sslv2_client, + + /// SSL version 2 server. + sslv2_server, + + /// Generic SSL version 3. + sslv3, + + /// SSL version 3 client. + sslv3_client, + + /// SSL version 3 server. + sslv3_server, + + /// Generic TLS version 1. + tlsv1, + + /// TLS version 1 client. + tlsv1_client, + + /// TLS version 1 server. + tlsv1_server, + + /// Generic SSL/TLS. + sslv23, + + /// SSL/TLS client. + sslv23_client, + + /// SSL/TLS server. + sslv23_server + }; + + /// Bitmask type for SSL options. + typedef int options; + +#if defined(GENERATING_DOCUMENTATION) + /// Implement various bug workarounds. + static const int default_workarounds = implementation_defined; + + /// Always create a new key when using tmp_dh parameters. + static const int single_dh_use = implementation_defined; + + /// Disable SSL v2. + static const int no_sslv2 = implementation_defined; + + /// Disable SSL v3. + static const int no_sslv3 = implementation_defined; + + /// Disable TLS v1. + static const int no_tlsv1 = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, default_workarounds = SSL_OP_ALL); + BOOST_STATIC_CONSTANT(int, single_dh_use = SSL_OP_SINGLE_DH_USE); + BOOST_STATIC_CONSTANT(int, no_sslv2 = SSL_OP_NO_SSLv2); + BOOST_STATIC_CONSTANT(int, no_sslv3 = SSL_OP_NO_SSLv3); + BOOST_STATIC_CONSTANT(int, no_tlsv1 = SSL_OP_NO_TLSv1); +#endif + + /// File format types. + enum file_format + { + /// ASN.1 file. + asn1, + + /// PEM file. + pem + }; + + /// Bitmask type for peer verification. + typedef int verify_mode; + +#if defined(GENERATING_DOCUMENTATION) + /// No verification. + static const int verify_none = implementation_defined; + + /// Verify the peer. + static const int verify_peer = implementation_defined; + + /// Fail verification if the peer has no certificate. Ignored unless + /// verify_peer is set. + static const int verify_fail_if_no_peer_cert = implementation_defined; + + /// Do not request client certificate on renegotiation. Ignored unless + /// verify_peer is set. + static const int verify_client_once = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE); + BOOST_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER); + BOOST_STATIC_CONSTANT(int, + verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + BOOST_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE); +#endif + + /// Purpose of PEM password. + enum password_purpose + { + /// The password is needed for reading/decryption. + for_reading, + + /// The password is needed for writing/encryption. + for_writing + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~context_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_CONTEXT_BASE_HPP diff --git a/thirdparty/boost/asio/ssl/context_service.hpp b/thirdparty/boost/asio/ssl/context_service.hpp new file mode 100644 index 0000000..4ef53c0 --- /dev/null +++ b/thirdparty/boost/asio/ssl/context_service.hpp @@ -0,0 +1,177 @@ +// +// context_service.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP +#define BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// Default service implementation for a context. +class context_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base +#endif +{ +private: + // The type of the platform-specific implementation. + typedef detail::openssl_context_service service_impl_type; + +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The type of the context. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined impl_type; +#else + typedef service_impl_type::impl_type impl_type; +#endif + + /// Constructor. + explicit context_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Return a null context implementation. + impl_type null() const + { + return service_impl_.null(); + } + + /// Create a new context implementation. + void create(impl_type& impl, context_base::method m) + { + service_impl_.create(impl, m); + } + + /// Destroy a context implementation. + void destroy(impl_type& impl) + { + service_impl_.destroy(impl); + } + + /// Set options on the context. + boost::system::error_code set_options(impl_type& impl, + context_base::options o, boost::system::error_code& ec) + { + return service_impl_.set_options(impl, o, ec); + } + + /// Set peer verification mode. + boost::system::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, boost::system::error_code& ec) + { + return service_impl_.set_verify_mode(impl, v, ec); + } + + /// Load a certification authority file for performing verification. + boost::system::error_code load_verify_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + return service_impl_.load_verify_file(impl, filename, ec); + } + + /// Add a directory containing certification authority files to be used for + /// performing verification. + boost::system::error_code add_verify_path(impl_type& impl, + const std::string& path, boost::system::error_code& ec) + { + return service_impl_.add_verify_path(impl, path, ec); + } + + /// Use a certificate from a file. + boost::system::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + return service_impl_.use_certificate_file(impl, filename, format, ec); + } + + /// Use a certificate chain from a file. + boost::system::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + return service_impl_.use_certificate_chain_file(impl, filename, ec); + } + + /// Use a private key from a file. + boost::system::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + return service_impl_.use_private_key_file(impl, filename, format, ec); + } + + /// Use an RSA private key from a file. + boost::system::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + return service_impl_.use_rsa_private_key_file(impl, filename, format, ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + boost::system::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + return service_impl_.use_tmp_dh_file(impl, filename, ec); + } + + /// Set the password callback. + template + boost::system::error_code set_password_callback(impl_type& impl, + PasswordCallback callback, boost::system::error_code& ec) + { + return service_impl_.set_password_callback(impl, callback, ec); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_CONTEXT_SERVICE_HPP diff --git a/thirdparty/boost/asio/ssl/detail/openssl_context_service.hpp b/thirdparty/boost/asio/ssl/detail/openssl_context_service.hpp new file mode 100644 index 0000000..5afd0e7 --- /dev/null +++ b/thirdparty/boost/asio/ssl/detail/openssl_context_service.hpp @@ -0,0 +1,381 @@ +// +// openssl_context_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP +#define BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { +namespace detail { + +class openssl_context_service + : public boost::asio::detail::service_base +{ +public: + // The native type of the context. + typedef ::SSL_CTX* impl_type; + + // The type for the password callback function object. + typedef boost::function password_callback_type; + + // Constructor. + openssl_context_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Return a null context implementation. + static impl_type null() + { + return 0; + } + + // Create a new context implementation. + void create(impl_type& impl, context_base::method m) + { + ::SSL_METHOD* ssl_method = 0; + switch (m) + { + case context_base::sslv2: + ssl_method = ::SSLv2_method(); + break; + case context_base::sslv2_client: + ssl_method = ::SSLv2_client_method(); + break; + case context_base::sslv2_server: + ssl_method = ::SSLv2_server_method(); + break; + case context_base::sslv3: + ssl_method = ::SSLv3_method(); + break; + case context_base::sslv3_client: + ssl_method = ::SSLv3_client_method(); + break; + case context_base::sslv3_server: + ssl_method = ::SSLv3_server_method(); + break; + case context_base::tlsv1: + ssl_method = ::TLSv1_method(); + break; + case context_base::tlsv1_client: + ssl_method = ::TLSv1_client_method(); + break; + case context_base::tlsv1_server: + ssl_method = ::TLSv1_server_method(); + break; + case context_base::sslv23: + ssl_method = ::SSLv23_method(); + break; + case context_base::sslv23_client: + ssl_method = ::SSLv23_client_method(); + break; + case context_base::sslv23_server: + ssl_method = ::SSLv23_server_method(); + break; + default: + break; + } + impl = ::SSL_CTX_new(ssl_method); + } + + // Destroy a context implementation. + void destroy(impl_type& impl) + { + if (impl != null()) + { + if (impl->default_passwd_callback_userdata) + { + password_callback_type* callback = + static_cast( + impl->default_passwd_callback_userdata); + delete callback; + impl->default_passwd_callback_userdata = 0; + } + + ::SSL_CTX_free(impl); + impl = null(); + } + } + + // Set options on the context. + boost::system::error_code set_options(impl_type& impl, + context_base::options o, boost::system::error_code& ec) + { + ::SSL_CTX_set_options(impl, o); + + ec = boost::system::error_code(); + return ec; + } + + // Set peer verification mode. + boost::system::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, boost::system::error_code& ec) + { + ::SSL_CTX_set_verify(impl, v, 0); + + ec = boost::system::error_code(); + return ec; + } + + // Load a certification authority file for performing verification. + boost::system::error_code load_verify_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Add a directory containing certification authority files to be used for + // performing verification. + boost::system::error_code add_verify_path(impl_type& impl, + const std::string& path, boost::system::error_code& ec) + { + if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Use a certificate from a file. + boost::system::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = boost::asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Use a certificate chain from a file. + boost::system::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Use a private key from a file. + boost::system::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = boost::asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Use an RSA private key from a file. + boost::system::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = boost::asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_RSAPrivateKey_file( + impl, filename.c_str(), file_type) != 1) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Use the specified file to obtain the temporary Diffie-Hellman parameters. + boost::system::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) + { + ::BIO* bio = ::BIO_new_file(filename.c_str(), "r"); + if (!bio) + { + ec = boost::asio::error::invalid_argument; + return ec; + } + + ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0); + if (!dh) + { + ::BIO_free(bio); + ec = boost::asio::error::invalid_argument; + return ec; + } + + ::BIO_free(bio); + int result = ::SSL_CTX_set_tmp_dh(impl, dh); + if (result != 1) + { + ::DH_free(dh); + ec = boost::asio::error::invalid_argument; + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + static int password_callback(char* buf, int size, int purpose, void* data) + { + using namespace std; // For strncat and strlen. + + if (data) + { + password_callback_type* callback = + static_cast(data); + std::string passwd = (*callback)(static_cast(size), + purpose ? context_base::for_writing : context_base::for_reading); + *buf = '\0'; + strncat(buf, passwd.c_str(), size); + return strlen(buf); + } + + return 0; + } + + // Set the password callback. + template + boost::system::error_code set_password_callback(impl_type& impl, + Password_Callback callback, boost::system::error_code& ec) + { + // Allocate callback function object if not already present. + if (impl->default_passwd_callback_userdata) + { + password_callback_type* callback_function = + static_cast( + impl->default_passwd_callback_userdata); + *callback_function = callback; + } + else + { + password_callback_type* callback_function = + new password_callback_type(callback); + impl->default_passwd_callback_userdata = callback_function; + } + + // Set the password callback. + SSL_CTX_set_default_passwd_cb(impl, + &openssl_context_service::password_callback); + + ec = boost::system::error_code(); + return ec; + } + +private: + // Ensure openssl is initialised. + openssl_init<> init_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP diff --git a/thirdparty/boost/asio/ssl/detail/openssl_init.hpp b/thirdparty/boost/asio/ssl/detail/openssl_init.hpp new file mode 100644 index 0000000..96af533 --- /dev/null +++ b/thirdparty/boost/asio/ssl/detail/openssl_init.hpp @@ -0,0 +1,145 @@ +// +// openssl_init.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP +#define BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { +namespace detail { + +template +class openssl_init + : private boost::noncopyable +{ +private: + // Structure to perform the actual initialisation. + class do_init + { + public: + do_init() + { + if (Do_Init) + { + ::SSL_library_init(); + ::SSL_load_error_strings(); + ::OpenSSL_add_ssl_algorithms(); + + mutexes_.resize(::CRYPTO_num_locks()); + for (size_t i = 0; i < mutexes_.size(); ++i) + mutexes_[i].reset(new boost::asio::detail::mutex); + ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); + ::CRYPTO_set_id_callback(&do_init::openssl_id_func); + } + } + + ~do_init() + { + if (Do_Init) + { + ::CRYPTO_set_id_callback(0); + ::CRYPTO_set_locking_callback(0); + ::ERR_free_strings(); + ::ERR_remove_state(0); + ::EVP_cleanup(); + ::CRYPTO_cleanup_all_ex_data(); + ::CONF_modules_unload(1); + ::ENGINE_cleanup(); + } + } + + // Helper function to manage a do_init singleton. The static instance of the + // openssl_init object ensures that this function is always called before + // main, and therefore before any other threads can get started. The do_init + // instance must be static in this function to ensure that it gets + // initialised before any other global objects try to use it. + static boost::shared_ptr instance() + { + static boost::shared_ptr init(new do_init); + return init; + } + + private: + static unsigned long openssl_id_func() + { + void* id = instance()->thread_id_; + if (id == 0) + instance()->thread_id_ = id = &id; // Ugh. + BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*)); + return reinterpret_cast(id); + } + + static void openssl_locking_func(int mode, int n, + const char *file, int line) + { + if (mode & CRYPTO_LOCK) + instance()->mutexes_[n]->lock(); + else + instance()->mutexes_[n]->unlock(); + } + + // Mutexes to be used in locking callbacks. + std::vector > mutexes_; + + // The thread identifiers to be used by openssl. + boost::asio::detail::tss_ptr thread_id_; + }; + +public: + // Constructor. + openssl_init() + : ref_(do_init::instance()) + { + while (&instance_ == 0); // Ensure openssl_init::instance_ is linked in. + } + + // Destructor. + ~openssl_init() + { + } + +private: + // Instance to force initialisation of openssl at global scope. + static openssl_init instance_; + + // Reference to singleton do_init object to ensure that openssl does not get + // cleaned up until the last user has finished with it. + boost::shared_ptr ref_; +}; + +template +openssl_init openssl_init::instance_; + +} // namespace detail +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP diff --git a/thirdparty/boost/asio/ssl/detail/openssl_operation.hpp b/thirdparty/boost/asio/ssl/detail/openssl_operation.hpp new file mode 100644 index 0000000..1612fa7 --- /dev/null +++ b/thirdparty/boost/asio/ssl/detail/openssl_operation.hpp @@ -0,0 +1,521 @@ +// +// openssl_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster 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) +// + +#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP +#define BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { +namespace detail { + +typedef boost::function ssl_primitive_func; +typedef boost::function + user_handler_func; + +// Network send_/recv buffer implementation +// +// +class net_buffer +{ + static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare + + unsigned char buf_[NET_BUF_SIZE]; + unsigned char* data_start_; + unsigned char* data_end_; + +public: + net_buffer() + { + data_start_ = data_end_ = buf_; + } + unsigned char* get_unused_start() { return data_end_; } + unsigned char* get_data_start() { return data_start_; } + size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); } + size_t get_data_len() { return (data_end_ - data_start_); } + void data_added(size_t count) + { + data_end_ += count; + data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)? + (buf_ + NET_BUF_SIZE): + data_end_; + } + void data_removed(size_t count) + { + data_start_ += count; + if (data_start_ >= data_end_) reset(); + } + void reset() { data_start_ = buf_; data_end_ = buf_; } + bool has_data() { return (data_start_ < data_end_); } +}; // class net_buffer + +// +// Operation class +// +// +template +class openssl_operation +{ +public: + + // Constructor for asynchronous operations + openssl_operation(ssl_primitive_func primitive, + Stream& socket, + net_buffer& recv_buf, + SSL* session, + BIO* ssl_bio, + user_handler_func handler, + boost::asio::io_service::strand& strand + ) + : primitive_(primitive) + , user_handler_(handler) + , strand_(&strand) + , recv_buf_(recv_buf) + , socket_(socket) + , ssl_bio_(ssl_bio) + , session_(session) + { + write_ = boost::bind( + &openssl_operation::do_async_write, + this, boost::arg<1>(), boost::arg<2>() + ); + read_ = boost::bind( + &openssl_operation::do_async_read, + this + ); + handler_= boost::bind( + &openssl_operation::async_user_handler, + this, boost::arg<1>(), boost::arg<2>() + ); + } + + // Constructor for synchronous operations + openssl_operation(ssl_primitive_func primitive, + Stream& socket, + net_buffer& recv_buf, + SSL* session, + BIO* ssl_bio) + : primitive_(primitive) + , strand_(0) + , recv_buf_(recv_buf) + , socket_(socket) + , ssl_bio_(ssl_bio) + , session_(session) + { + write_ = boost::bind( + &openssl_operation::do_sync_write, + this, boost::arg<1>(), boost::arg<2>() + ); + read_ = boost::bind( + &openssl_operation::do_sync_read, + this + ); + handler_ = boost::bind( + &openssl_operation::sync_user_handler, + this, boost::arg<1>(), boost::arg<2>() + ); + } + + // Start operation + // In case of asynchronous it returns 0, in sync mode returns success code + // or throws an error... + int start() + { + int rc = primitive_( session_ ); + + bool is_operation_done = (rc > 0); + // For connect/accept/shutdown, the operation + // is done, when return code is 1 + // for write, it is done, when is retcode > 0 + // for read, is is done when retcode > 0 + + int error_code = !is_operation_done ? + ::SSL_get_error( session_, rc ) : + 0; + int sys_error_code = ERR_get_error(); + + bool is_read_needed = (error_code == SSL_ERROR_WANT_READ); + bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE || + ::BIO_ctrl_pending( ssl_bio_ )); + bool is_shut_down_received = + ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) == + SSL_RECEIVED_SHUTDOWN); + bool is_shut_down_sent = + ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) == + SSL_SENT_SHUTDOWN); + + if (is_shut_down_sent && is_shut_down_received && is_operation_done) + // SSL connection is shut down cleanly + return handler_(boost::system::error_code(), 1); + + if (is_shut_down_received && !is_write_needed) + return handler_(boost::asio::error::eof, 0); + + if (is_shut_down_received) + // Shutdown has been requested, while we were reading or writing... + // abort our action... + return handler_(boost::asio::error::shut_down, 0); + + if (!is_operation_done && !is_read_needed && !is_write_needed + && !is_shut_down_sent) + { + // The operation has failed... It is not completed and does + // not want network communication nor does want to send shutdown out... + if (error_code == SSL_ERROR_SYSCALL) + { + return handler_(boost::system::error_code( + sys_error_code, boost::asio::error::system_category), rc); + } + else + { + return handler_(boost::system::error_code( + error_code, boost::asio::error::get_ssl_category()), rc); + } + } + + if (!is_operation_done && !is_write_needed) + { + // We may have left over data that we can pass to SSL immediately + if (recv_buf_.get_data_len() > 0) + { + // Pass the buffered data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + return handler_(boost::asio::error::no_recovery, 0); + } + } + + return start(); + } + else if (is_read_needed) + { + return read_(); + } + } + + // Continue with operation, flush any SSL data out to network... + return write_(is_operation_done, rc); + } + +// Private implementation +private: + typedef boost::function + int_handler_func; + typedef boost::function write_func; + typedef boost::function read_func; + + ssl_primitive_func primitive_; + user_handler_func user_handler_; + boost::asio::io_service::strand* strand_; + write_func write_; + read_func read_; + int_handler_func handler_; + + net_buffer send_buf_; // buffers for network IO + + // The recv buffer is owned by the stream, not the operation, since there can + // be left over bytes after passing the data up to the application, and these + // bytes need to be kept around for the next read operation issued by the + // application. + net_buffer& recv_buf_; + + Stream& socket_; + BIO* ssl_bio_; + SSL* session_; + + // + int sync_user_handler(const boost::system::error_code& error, int rc) + { + if (!error) + return rc; + + throw boost::system::system_error(error); + } + + int async_user_handler(boost::system::error_code error, int rc) + { + if (rc < 0) + { + if (!error) + error = boost::asio::error::no_recovery; + rc = 0; + } + + user_handler_(error, rc); + return 0; + } + + // Writes bytes asynchronously from SSL to NET + int do_async_write(bool is_operation_done, int rc) + { + int len = ::BIO_ctrl_pending( ssl_bio_ ); + if ( len ) + { + // There is something to write into net, do it... + len = (int)send_buf_.get_unused_len() > len? + len: + send_buf_.get_unused_len(); + + if (len == 0) + { + // In case our send buffer is full, we have just to wait until + // previous send to complete... + return 0; + } + + // Read outgoing data from bio + len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); + + if (len > 0) + { + unsigned char *data_start = send_buf_.get_unused_start(); + send_buf_.data_added(len); + + BOOST_ASSERT(strand_); + boost::asio::async_write + ( + socket_, + boost::asio::buffer(data_start, len), + strand_->wrap + ( + boost::bind + ( + &openssl_operation::async_write_handler, + this, + is_operation_done, + rc, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred + ) + ) + ); + + return 0; + } + else if (!BIO_should_retry(ssl_bio_)) + { + // Seems like fatal error + // reading from SSL BIO has failed... + handler_(boost::asio::error::no_recovery, 0); + return 0; + } + } + + if (is_operation_done) + { + // Finish the operation, with success + handler_(boost::system::error_code(), rc); + return 0; + } + + // OPeration is not done and writing to net has been made... + // start operation again + start(); + + return 0; + } + + void async_write_handler(bool is_operation_done, int rc, + const boost::system::error_code& error, size_t bytes_sent) + { + if (!error) + { + // Remove data from send buffer + send_buf_.data_removed(bytes_sent); + + if (is_operation_done) + handler_(boost::system::error_code(), rc); + else + // Since the operation was not completed, try it again... + start(); + } + else + handler_(error, rc); + } + + int do_async_read() + { + // Wait for new data + BOOST_ASSERT(strand_); + socket_.async_read_some + ( + boost::asio::buffer(recv_buf_.get_unused_start(), + recv_buf_.get_unused_len()), + strand_->wrap + ( + boost::bind + ( + &openssl_operation::async_read_handler, + this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred + ) + ) + ); + return 0; + } + + void async_read_handler(const boost::system::error_code& error, + size_t bytes_recvd) + { + if (!error) + { + recv_buf_.data_added(bytes_recvd); + + // Pass the received data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + handler_(boost::asio::error::no_recovery, 0); + return; + } + } + + // and try the SSL primitive again + start(); + } + else + { + // Error in network level... + // SSL can't continue either... + handler_(error, 0); + } + } + + // Syncronous functions... + int do_sync_write(bool is_operation_done, int rc) + { + int len = ::BIO_ctrl_pending( ssl_bio_ ); + if ( len ) + { + // There is something to write into net, do it... + len = (int)send_buf_.get_unused_len() > len? + len: + send_buf_.get_unused_len(); + + // Read outgoing data from bio + len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); + + if (len > 0) + { + size_t sent_len = boost::asio::write( + socket_, + boost::asio::buffer(send_buf_.get_unused_start(), len) + ); + + send_buf_.data_added(len); + send_buf_.data_removed(sent_len); + } + else if (!BIO_should_retry(ssl_bio_)) + { + // Seems like fatal error + // reading from SSL BIO has failed... + throw boost::system::system_error(boost::asio::error::no_recovery); + } + } + + if (is_operation_done) + // Finish the operation, with success + return rc; + + // Operation is not finished, start again. + return start(); + } + + int do_sync_read() + { + size_t len = socket_.read_some + ( + boost::asio::buffer(recv_buf_.get_unused_start(), + recv_buf_.get_unused_len()) + ); + + // Write data to ssl + recv_buf_.data_added(len); + + // Pass the received data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + throw boost::system::system_error(boost::asio::error::no_recovery); + } + } + + // Try the operation again + return start(); + } +}; // class openssl_operation + +} // namespace detail +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP diff --git a/thirdparty/boost/asio/ssl/detail/openssl_stream_service.hpp b/thirdparty/boost/asio/ssl/detail/openssl_stream_service.hpp new file mode 100644 index 0000000..0471c35 --- /dev/null +++ b/thirdparty/boost/asio/ssl/detail/openssl_stream_service.hpp @@ -0,0 +1,533 @@ +// +// stream_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP +#define BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { +namespace detail { + +class openssl_stream_service + : public boost::asio::detail::service_base +{ +private: + enum { max_buffer_size = INT_MAX }; + + //Base handler for asyncrhonous operations + template + class base_handler + { + public: + typedef boost::function< + void (const boost::system::error_code&, size_t)> func_t; + + base_handler(boost::asio::io_service& io_service) + : op_(NULL) + , io_service_(io_service) + , work_(io_service) + {} + + void do_func(const boost::system::error_code& error, size_t size) + { + func_(error, size); + } + + void set_operation(openssl_operation* op) { op_ = op; } + void set_func(func_t func) { func_ = func; } + + ~base_handler() + { + delete op_; + } + + private: + func_t func_; + openssl_operation* op_; + boost::asio::io_service& io_service_; + boost::asio::io_service::work work_; + }; // class base_handler + + // Handler for asynchronous IO (write/read) operations + template + class io_handler + : public base_handler + { + public: + io_handler(Handler handler, boost::asio::io_service& io_service) + : base_handler(io_service) + , handler_(handler) + { + set_func(boost::bind( + &io_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const boost::system::error_code& error, size_t size) + { + handler_(error, size); + delete this; + } + }; // class io_handler + + // Handler for asyncrhonous handshake (connect, accept) functions + template + class handshake_handler + : public base_handler + { + public: + handshake_handler(Handler handler, boost::asio::io_service& io_service) + : base_handler(io_service) + , handler_(handler) + { + set_func(boost::bind( + &handshake_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const boost::system::error_code& error, size_t) + { + handler_(error); + delete this; + } + + }; // class handshake_handler + + // Handler for asyncrhonous shutdown + template + class shutdown_handler + : public base_handler + { + public: + shutdown_handler(Handler handler, boost::asio::io_service& io_service) + : base_handler(io_service), + handler_(handler) + { + set_func(boost::bind( + &shutdown_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const boost::system::error_code& error, size_t) + { + handler_(error); + delete this; + } + }; // class shutdown_handler + +public: + // The implementation type. + typedef struct impl_struct + { + ::SSL* ssl; + ::BIO* ext_bio; + net_buffer recv_buf; + } * impl_type; + + // Construct a new stream socket service for the specified io_service. + explicit openssl_stream_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service), + strand_(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Return a null stream implementation. + impl_type null() const + { + return 0; + } + + // Create a new stream implementation. + template + void create(impl_type& impl, Stream& next_layer, + basic_context& context) + { + impl = new impl_struct; + impl->ssl = ::SSL_new(context.impl()); + ::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + ::BIO* int_bio = 0; + impl->ext_bio = 0; + ::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192); + ::SSL_set_bio(impl->ssl, int_bio, int_bio); + } + + // Destroy a stream implementation. + template + void destroy(impl_type& impl, Stream& next_layer) + { + if (impl != 0) + { + ::BIO_free(impl->ext_bio); + ::SSL_free(impl->ssl); + delete impl; + impl = 0; + } + } + + // Perform SSL handshaking. + template + boost::system::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, boost::system::error_code& ec) + { + try + { + openssl_operation op( + type == stream_base::client ? + &ssl_wrap::SSL_connect: + &ssl_wrap::SSL_accept, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio); + op.start(); + } + catch (boost::system::system_error& e) + { + ec = e.code(); + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Start an asynchronous SSL handshake. + template + void async_handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, Handler handler) + { + typedef handshake_handler connect_handler; + + connect_handler* local_handler = + new connect_handler(handler, get_io_service()); + + openssl_operation* op = new openssl_operation + ( + type == stream_base::client ? + &ssl_wrap::SSL_connect: + &ssl_wrap::SSL_accept, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Shut down SSL on the stream. + template + boost::system::error_code shutdown(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) + { + try + { + openssl_operation op( + &ssl_wrap::SSL_shutdown, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio); + op.start(); + } + catch (boost::system::system_error& e) + { + ec = e.code(); + return ec; + } + + ec = boost::system::error_code(); + return ec; + } + + // Asynchronously shut down SSL on the stream. + template + void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler) + { + typedef shutdown_handler disconnect_handler; + + disconnect_handler* local_handler = + new disconnect_handler(handler, get_io_service()); + + openssl_operation* op = new openssl_operation + ( + &ssl_wrap::SSL_shutdown, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Write some data to the stream. + template + std::size_t write_some(impl_type& impl, Stream& next_layer, + const Const_Buffers& buffers, boost::system::error_code& ec) + { + size_t bytes_transferred = 0; + try + { + std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin()); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + + boost::function send_func = + boost::bind(&::SSL_write, boost::arg<1>(), + boost::asio::buffer_cast(*buffers.begin()), + static_cast(buffer_size)); + openssl_operation op( + send_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio + ); + bytes_transferred = static_cast(op.start()); + } + catch (boost::system::system_error& e) + { + ec = e.code(); + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; + } + + // Start an asynchronous write. + template + void async_write_some(impl_type& impl, Stream& next_layer, + const Const_Buffers& buffers, Handler handler) + { + typedef io_handler send_handler; + + send_handler* local_handler = new send_handler(handler, get_io_service()); + + std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin()); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + + boost::function send_func = + boost::bind(&::SSL_write, boost::arg<1>(), + boost::asio::buffer_cast(*buffers.begin()), + static_cast(buffer_size)); + + openssl_operation* op = new openssl_operation + ( + send_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Read some data from the stream. + template + std::size_t read_some(impl_type& impl, Stream& next_layer, + const Mutable_Buffers& buffers, boost::system::error_code& ec) + { + size_t bytes_transferred = 0; + try + { + std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin()); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + + boost::function recv_func = + boost::bind(&::SSL_read, boost::arg<1>(), + boost::asio::buffer_cast(*buffers.begin()), + static_cast(buffer_size)); + openssl_operation op(recv_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio + ); + + bytes_transferred = static_cast(op.start()); + } + catch (boost::system::system_error& e) + { + ec = e.code(); + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; + } + + // Start an asynchronous read. + template + void async_read_some(impl_type& impl, Stream& next_layer, + const Mutable_Buffers& buffers, Handler handler) + { + typedef io_handler recv_handler; + + recv_handler* local_handler = new recv_handler(handler, get_io_service()); + + std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin()); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + + boost::function recv_func = + boost::bind(&::SSL_read, boost::arg<1>(), + boost::asio::buffer_cast(*buffers.begin()), + static_cast(buffer_size)); + + openssl_operation* op = new openssl_operation + ( + recv_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Peek at the incoming data on the stream. + template + std::size_t peek(impl_type& impl, Stream& next_layer, + const Mutable_Buffers& buffers, boost::system::error_code& ec) + { + ec = boost::system::error_code(); + return 0; + } + + // Determine the amount of data that may be read without blocking. + template + std::size_t in_avail(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) + { + ec = boost::system::error_code(); + return 0; + } + +private: + boost::asio::io_service::strand strand_; + + typedef boost::asio::detail::mutex mutex_type; + + template + struct ssl_wrap + { + static Mutex ssl_mutex_; + + static int SSL_accept(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_accept(ssl); + } + + static int SSL_connect(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_connect(ssl); + } + + static int SSL_shutdown(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_shutdown(ssl); + } + }; +}; + +template +Mutex openssl_stream_service::ssl_wrap::ssl_mutex_; + +} // namespace detail +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP diff --git a/thirdparty/boost/asio/ssl/detail/openssl_types.hpp b/thirdparty/boost/asio/ssl/detail/openssl_types.hpp new file mode 100644 index 0000000..f89b801 --- /dev/null +++ b/thirdparty/boost/asio/ssl/detail/openssl_types.hpp @@ -0,0 +1,31 @@ +// +// openssl_types.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP +#define BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP diff --git a/thirdparty/boost/asio/ssl/stream.hpp b/thirdparty/boost/asio/ssl/stream.hpp new file mode 100644 index 0000000..43a9792 --- /dev/null +++ b/thirdparty/boost/asio/ssl/stream.hpp @@ -0,0 +1,505 @@ +// +// stream.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_STREAM_HPP +#define BOOST_ASIO_SSL_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// Provides stream-oriented functionality using SSL. +/** + * The stream class template provides asynchronous and blocking stream-oriented + * functionality using SSL. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * To use the SSL stream template with an ip::tcp::socket, you would write: + * @code + * boost::asio::io_service io_service; + * boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23); + * boost::asio::ssl::stream sock(io_service, context); + * @endcode + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream. + */ +template +class stream + : public stream_base, + private boost::noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the service that will be used to provide stream operations. + typedef Service service_type; + + /// The native implementation type of the stream. + typedef typename service_type::impl_type impl_type; + + /// Construct a stream. + /** + * This constructor creates a stream and initialises the underlying stream + * object. + * + * @param arg The argument to be passed to initialise the underlying stream. + * + * @param context The SSL context to be used for the stream. + */ + template + explicit stream(Arg& arg, basic_context& context) + : next_layer_(arg), + service_(boost::asio::use_service(next_layer_.get_io_service())), + impl_(service_.null()) + { + service_.create(impl_, next_layer_, context); + } + + /// Destructor. + ~stream() + { + service_.destroy(impl_, next_layer_); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + /** + * This function may be used to obtain the io_service object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that stream will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + /** + * This function may be used to obtain the io_service object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that stream will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to stream functionality that is + * not otherwise provided. + */ + impl_type impl() + { + return impl_; + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @throws boost::system::system_error Thrown on failure. + */ + void handshake(handshake_type type) + { + boost::system::error_code ec; + service_.handshake(impl_, next_layer_, type, ec); + boost::asio::detail::throw_error(ec); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code handshake(handshake_type type, + boost::system::error_code& ec) + { + return service_.handshake(impl_, next_layer_, type, ec); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + */ + template + void async_handshake(handshake_type type, HandshakeHandler handler) + { + service_.async_handshake(impl_, next_layer_, type, handler); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @throws boost::system::system_error Thrown on failure. + */ + void shutdown() + { + boost::system::error_code ec; + service_.shutdown(impl_, next_layer_, ec); + boost::asio::detail::throw_error(ec); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code shutdown(boost::system::error_code& ec) + { + return service_.shutdown(impl_, next_layer_, ec); + } + + /// Asynchronously shut down SSL on the stream. + /** + * This function is used to asynchronously shut down SSL on the stream. This + * function call always returns immediately. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + */ + template + void async_shutdown(ShutdownHandler handler) + { + service_.async_shutdown(impl_, next_layer_, handler); + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written. + * + * @returns The number of bytes written. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written to the stream. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + return service_.write_some(impl_, next_layer_, buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write one or more bytes of data to + * the stream. The function call always returns immediately. + * + * @param buffers The data to be written to the stream. Although the buffers + * object may be copied as necessary, ownership of the underlying buffers is + * retained by the caller, which must guarantee that they remain valid until + * the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * + * @note The async_write_some operation may not transmit all of the data to + * the peer. Consider using the @ref async_write function if you need to + * ensure that all data is written before the blocking operation completes. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + service_.async_write_some(impl_, next_layer_, buffers, handler); + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return service_.read_some(impl_, next_layer_, buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read one or more bytes of data from + * the stream. The function call always returns immediately. + * + * @param buffers The buffers into which the data will be read. Although the + * buffers object may be copied as necessary, ownership of the underlying + * buffers is retained by the caller, which must guarantee that they remain + * valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * + * @note The async_read_some operation may not read all of the requested + * number of bytes. Consider using the @ref async_read function if you need to + * ensure that the requested amount of data is read before the asynchronous + * operation completes. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + service_.async_read_some(impl_, next_layer_, buffers, handler); + } + + /// Peek at the incoming data on the stream. + /** + * This function is used to peek at the incoming data on the stream, without + * removing it from the input queue. The function call will block until data + * has been read successfully or an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + std::size_t peek(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = service_.peek(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Peek at the incoming data on the stream. + /** + * This function is used to peek at the incoming data on the stream, withoutxi + * removing it from the input queue. The function call will block until data + * has been read successfully or an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + */ + template + std::size_t peek(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return service_.peek(impl_, next_layer_, buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + /** + * This function is used to determine the amount of data, in bytes, that may + * be read from the stream without blocking. + * + * @returns The number of bytes of data that can be read without blocking. + * + * @throws boost::system::system_error Thrown on failure. + */ + std::size_t in_avail() + { + boost::system::error_code ec; + std::size_t s = service_.in_avail(impl_, next_layer_, ec); + boost::asio::detail::throw_error(ec); + return s; + } + + /// Determine the amount of data that may be read without blocking. + /** + * This function is used to determine the amount of data, in bytes, that may + * be read from the stream without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes of data that can be read without blocking. + */ + std::size_t in_avail(boost::system::error_code& ec) + { + return service_.in_avail(impl_, next_layer_, ec); + } + +private: + /// The next layer. + Stream next_layer_; + + /// The backend service implementation. + service_type& service_; + + /// The underlying native implementation. + impl_type impl_; +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_STREAM_HPP diff --git a/thirdparty/boost/asio/ssl/stream_base.hpp b/thirdparty/boost/asio/ssl/stream_base.hpp new file mode 100644 index 0000000..df46c68 --- /dev/null +++ b/thirdparty/boost/asio/ssl/stream_base.hpp @@ -0,0 +1,62 @@ +// +// stream_base.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_STREAM_BASE_HPP +#define BOOST_ASIO_SSL_STREAM_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// The stream_base class is used as a base for the boost::asio::ssl::stream +/// class template so that we have a common place to define various enums. +class stream_base +{ +public: + /// Different handshake types. + enum handshake_type + { + /// Perform handshaking as a client. + client, + + /// Perform handshaking as a server. + server + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~stream_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_STREAM_BASE_HPP diff --git a/thirdparty/boost/asio/ssl/stream_service.hpp b/thirdparty/boost/asio/ssl/stream_service.hpp new file mode 100644 index 0000000..a8d76a2 --- /dev/null +++ b/thirdparty/boost/asio/ssl/stream_service.hpp @@ -0,0 +1,188 @@ +// +// stream_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_SSL_STREAM_SERVICE_HPP +#define BOOST_ASIO_SSL_STREAM_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { +namespace ssl { + +/// Default service implementation for an SSL stream. +class stream_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base +#endif +{ +private: + // The type of the platform-specific implementation. + typedef detail::openssl_stream_service service_impl_type; + +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The type of a stream implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined impl_type; +#else + typedef service_impl_type::impl_type impl_type; +#endif + + /// Construct a new stream service for the specified io_service. + explicit stream_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Return a null stream implementation. + impl_type null() const + { + return service_impl_.null(); + } + + /// Create a new stream implementation. + template + void create(impl_type& impl, Stream& next_layer, + basic_context& context) + { + service_impl_.create(impl, next_layer, context); + } + + /// Destroy a stream implementation. + template + void destroy(impl_type& impl, Stream& next_layer) + { + service_impl_.destroy(impl, next_layer); + } + + /// Perform SSL handshaking. + template + boost::system::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, boost::system::error_code& ec) + { + return service_impl_.handshake(impl, next_layer, type, ec); + } + + /// Start an asynchronous SSL handshake. + template + void async_handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, HandshakeHandler handler) + { + service_impl_.async_handshake(impl, next_layer, type, handler); + } + + /// Shut down SSL on the stream. + template + boost::system::error_code shutdown(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) + { + return service_impl_.shutdown(impl, next_layer, ec); + } + + /// Asynchronously shut down SSL on the stream. + template + void async_shutdown(impl_type& impl, Stream& next_layer, + ShutdownHandler handler) + { + service_impl_.async_shutdown(impl, next_layer, handler); + } + + /// Write some data to the stream. + template + std::size_t write_some(impl_type& impl, Stream& next_layer, + const ConstBufferSequence& buffers, boost::system::error_code& ec) + { + return service_impl_.write_some(impl, next_layer, buffers, ec); + } + + /// Start an asynchronous write. + template + void async_write_some(impl_type& impl, Stream& next_layer, + const ConstBufferSequence& buffers, WriteHandler handler) + { + service_impl_.async_write_some(impl, next_layer, buffers, handler); + } + + /// Read some data from the stream. + template + std::size_t read_some(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, boost::system::error_code& ec) + { + return service_impl_.read_some(impl, next_layer, buffers, ec); + } + + /// Start an asynchronous read. + template + void async_read_some(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, ReadHandler handler) + { + service_impl_.async_read_some(impl, next_layer, buffers, handler); + } + + /// Peek at the incoming data on the stream. + template + std::size_t peek(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, boost::system::error_code& ec) + { + return service_impl_.peek(impl, next_layer, buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + template + std::size_t in_avail(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) + { + return service_impl_.in_avail(impl, next_layer, ec); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ssl +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SSL_STREAM_SERVICE_HPP diff --git a/thirdparty/boost/asio/strand.hpp b/thirdparty/boost/asio/strand.hpp new file mode 100644 index 0000000..a36425c --- /dev/null +++ b/thirdparty/boost/asio/strand.hpp @@ -0,0 +1,188 @@ +// +// strand.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_STRAND_HPP +#define BOOST_ASIO_STRAND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include + +namespace boost { +namespace asio { + +/// Provides serialised handler execution. +/** + * The io_service::strand class provides the ability to post and dispatch + * handlers with the guarantee that none of those handlers will execute + * concurrently. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Dispatcher. + */ +class io_service::strand +{ +public: + /// Constructor. + /** + * Constructs the strand. + * + * @param io_service The io_service object that the strand will use to + * dispatch handlers that are ready to be run. + */ + explicit strand(boost::asio::io_service& io_service) + : service_(boost::asio::use_service< + boost::asio::detail::strand_service>(io_service)) + { + service_.construct(impl_); + } + + /// Destructor. + /** + * Destroys a strand. + * + * Handlers posted through the strand that have not yet been invoked will + * still be dispatched in a way that meets the guarantee of non-concurrency. + */ + ~strand() + { + service_.destroy(impl_); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the strand. + /** + * This function may be used to obtain the io_service object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& io_service() + { + return service_.get_io_service(); + } + + /// Get the io_service associated with the strand. + /** + * This function may be used to obtain the io_service object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_service& get_io_service() + { + return service_.get_io_service(); + } + + /// Request the strand to invoke the given handler. + /** + * This function is used to ask the strand to execute the given handler. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The handler may be executed + * inside this function if the guarantee can be met. If this function is + * called from within a handler that was posted or dispatched through the same + * strand, then the new handler will be executed immediately. + * + * The strand's guarantee is in addition to the guarantee provided by the + * underlying io_service. The io_service guarantees that the handler will only + * be called in a thread in which the io_service's run member function is + * currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + void dispatch(Handler handler) + { + service_.dispatch(impl_, handler); + } + + /// Request the strand to invoke the given handler and return + /// immediately. + /** + * This function is used to ask the strand to execute the given handler, but + * without allowing the strand to call the handler from inside this function. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The strand's guarantee is in + * addition to the guarantee provided by the underlying io_service. The + * io_service guarantees that the handler will only be called in a thread in + * which the io_service's run member function is currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + void post(Handler handler) + { + service_.post(impl_, handler); + } + + /// Create a new handler that automatically dispatches the wrapped handler + /// on the strand. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the strand's + * dispatch function. + * + * @param handler The handler to be wrapped. The strand will make a copy of + * the handler object as required. The function signature of the handler must + * be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the strand's dispatch function. Given a function object with the signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code strand.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler) + { + return detail::wrapped_handler(*this, handler); + } + +private: + boost::asio::detail::strand_service& service_; + boost::asio::detail::strand_service::implementation_type impl_; +}; + +/// Typedef for backwards compatibility. +typedef boost::asio::io_service::strand strand; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_STRAND_HPP diff --git a/thirdparty/boost/asio/stream_socket_service.hpp b/thirdparty/boost/asio/stream_socket_service.hpp new file mode 100644 index 0000000..83e6c20 --- /dev/null +++ b/thirdparty/boost/asio/stream_socket_service.hpp @@ -0,0 +1,288 @@ +// +// stream_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_HPP +#define BOOST_ASIO_STREAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a stream socket. +template +class stream_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_EPOLL) + typedef detail::reactive_socket_service< + Protocol, detail::epoll_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + typedef detail::reactive_socket_service< + Protocol, detail::kqueue_reactor > service_impl_type; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + typedef detail::reactive_socket_service< + Protocol, detail::dev_poll_reactor > service_impl_type; +#else + typedef detail::reactive_socket_service< + Protocol, detail::select_reactor > service_impl_type; +#endif + +public: + /// The type of a stream socket implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new stream socket service for the specified io_service. + explicit stream_socket_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + stream_socket_service >(io_service), + service_impl_(boost::asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new stream socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a stream socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a stream socket. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (protocol.type() == SOCK_STREAM) + service_impl_.open(impl, protocol, ec); + else + ec = boost::asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a stream socket. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + /// Bind the stream socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the stream socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, ConnectHandler handler) + { + service_impl_.async_connect(impl, peer_endpoint, handler); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send(impl, buffers, flags, handler); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive(impl, buffers, flags, handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_HPP diff --git a/thirdparty/boost/asio/streambuf.hpp b/thirdparty/boost/asio/streambuf.hpp new file mode 100644 index 0000000..8b3c7a4 --- /dev/null +++ b/thirdparty/boost/asio/streambuf.hpp @@ -0,0 +1,33 @@ +// +// streambuf.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_STREAMBUF_HPP +#define BOOST_ASIO_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +namespace boost { +namespace asio { + +/// Typedef for the typical usage of basic_streambuf. +typedef basic_streambuf<> streambuf; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_STREAMBUF_HPP diff --git a/thirdparty/boost/asio/time_traits.hpp b/thirdparty/boost/asio/time_traits.hpp new file mode 100644 index 0000000..c6f9c71 --- /dev/null +++ b/thirdparty/boost/asio/time_traits.hpp @@ -0,0 +1,80 @@ +// +// time_traits.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_TIME_TRAITS_HPP +#define BOOST_ASIO_TIME_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include // Must come before posix_time. + +#include +#include +#include + +namespace boost { +namespace asio { + +/// Time traits suitable for use with the deadline timer. +template +struct time_traits; + +/// Time traits specialised for posix_time. +template <> +struct time_traits +{ + /// The time type. + typedef boost::posix_time::ptime time_type; + + /// The duration type. + typedef boost::posix_time::time_duration duration_type; + + /// Get the current time. + static time_type now() + { + return boost::posix_time::microsec_clock::universal_time(); + } + + /// Add a duration to a time. + static time_type add(const time_type& t, const duration_type& d) + { + return t + d; + } + + /// Subtract one time from another. + static duration_type subtract(const time_type& t1, const time_type& t2) + { + return t1 - t2; + } + + /// Test whether one time is less than another. + static bool less_than(const time_type& t1, const time_type& t2) + { + return t1 < t2; + } + + /// Convert to POSIX duration type. + static boost::posix_time::time_duration to_posix_duration( + const duration_type& d) + { + return d; + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_TIME_TRAITS_HPP diff --git a/thirdparty/boost/asio/version.hpp b/thirdparty/boost/asio/version.hpp new file mode 100644 index 0000000..b3bf4ea --- /dev/null +++ b/thirdparty/boost/asio/version.hpp @@ -0,0 +1,23 @@ +// +// version.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_VERSION_HPP +#define BOOST_ASIO_VERSION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +// BOOST_ASIO_VERSION % 100 is the sub-minor version +// BOOST_ASIO_VERSION / 100 % 1000 is the minor version +// BOOST_ASIO_VERSION / 100000 is the major version +#define BOOST_ASIO_VERSION 100000 // 1.0.0 + +#endif // BOOST_ASIO_VERSION_HPP diff --git a/thirdparty/boost/asio/write.hpp b/thirdparty/boost/asio/write.hpp new file mode 100644 index 0000000..bb73e77 --- /dev/null +++ b/thirdparty/boost/asio/write.hpp @@ -0,0 +1,517 @@ +// +// write.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#ifndef BOOST_ASIO_WRITE_HPP +#define BOOST_ASIO_WRITE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace asio { + +/** + * @defgroup write boost::asio::write + */ +/*@{*/ + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code boost::asio::write(s, boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code boost::asio::write( + * s, buffers, + * boost::asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's write_some function are + * required. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code boost::asio::write(s, boost::asio::buffer(data, size), + * boost::asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's write_some function are + * required. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, boost::system::error_code& ec); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code boost::asio::write( + * s, b, + * boost::asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's write_some function are + * required. + * + * @returns The number of bytes transferred. + * + * @throws boost::system::system_error Thrown on failure. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's write_some function are + * required. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, boost::system::error_code& ec); + +/*@}*/ +/** + * @defgroup async_write boost::asio::async_write + */ +/*@{*/ + +/// Start an asynchronous operation to write of all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::async_write(s, boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's async_write_some function are + * required. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code boost::asio::async_write(s, + * boost::asio::buffer(data, size), + * boost::asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ +template +void async_write(AsyncWriteStream& s, basic_streambuf& b, + WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns true. + * + * This operation is implemented in terms of one or more calls to the stream's + * async_write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code bool completion_condition( + * const boost::system::error_code& error, // Result of latest write_some + * // operation. + * + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. + * ); @endcode + * A return value of true indicates that the write operation is complete. False + * indicates that further calls to the stream's async_write_some function are + * required. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ +template +void async_write(AsyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, WriteHandler handler); + +/*@}*/ + +} // namespace asio +} // namespace boost + +#include + +#include + +#endif // BOOST_ASIO_WRITE_HPP diff --git a/thirdparty/boost/assert.hpp b/thirdparty/boost/assert.hpp new file mode 100644 index 0000000..281c465 --- /dev/null +++ b/thirdparty/boost/assert.hpp @@ -0,0 +1,50 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/utility/assert.html for documentation. +// + +#undef BOOST_ASSERT + +#if defined(BOOST_DISABLE_ASSERTS) + +# define BOOST_ASSERT(expr) ((void)0) + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) + +#include + +namespace boost +{ + +void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + +} // namespace boost + +#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else +# include // .h to support old libraries w/o - effect is the same +# define BOOST_ASSERT(expr) assert(expr) +#endif + +#undef BOOST_VERIFY + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) + +#endif diff --git a/thirdparty/boost/assign.hpp b/thirdparty/boost/assign.hpp new file mode 100644 index 0000000..6857f12 --- /dev/null +++ b/thirdparty/boost/assign.hpp @@ -0,0 +1,24 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_HPP +#define BOOST_ASSIGN_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/assign/assignment_exception.hpp b/thirdparty/boost/assign/assignment_exception.hpp new file mode 100644 index 0000000..15d23c0 --- /dev/null +++ b/thirdparty/boost/assign/assignment_exception.hpp @@ -0,0 +1,43 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_ASSIGNMENT_EXCEPTION_HPP +#define BOOST_ASSIGN_ASSIGNMENT_EXCEPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace boost +{ + namespace assign + { + class assignment_exception : public std::exception + { + public: + assignment_exception( const char* what ) + : what_( what ) + { } + + virtual const char* what() const throw() + { + return what_; + } + + private: + const char* what_; + }; + } +} + +#endif diff --git a/thirdparty/boost/assign/list_inserter.hpp b/thirdparty/boost/assign/list_inserter.hpp new file mode 100644 index 0000000..a0317f3 --- /dev/null +++ b/thirdparty/boost/assign/list_inserter.hpp @@ -0,0 +1,404 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_LIST_INSERTER_HPP +#define BOOST_ASSIGN_LIST_INSERTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost +{ +namespace assign_detail +{ + template< class T > + struct repeater + { + std::size_t sz; + T val; + + repeater( std::size_t sz, T r ) : sz( sz ), val( r ) + { } + }; + + template< class Fun > + struct fun_repeater + { + std::size_t sz; + Fun val; + + fun_repeater( std::size_t sz, Fun r ) : sz( sz ), val( r ) + { } + }; + + template< class C > + class call_push_back + { + C& c_; + public: + call_push_back( C& c ) : c_( c ) + { } + + template< class T > + void operator()( T r ) + { + c_.push_back( r ); + } + }; + + template< class C > + class call_push_front + { + C& c_; + public: + call_push_front( C& c ) : c_( c ) + { } + + template< class T > + void operator()( T r ) + { + c_.push_front( r ); + } + }; + + template< class C > + class call_push + { + C& c_; + public: + call_push( C& c ) : c_( c ) + { } + + template< class T > + void operator()( T r ) + { + c_.push( r ); + } + }; + + template< class C > + class call_insert + { + C& c_; + public: + call_insert( C& c ) : c_( c ) + { } + + template< class T > + void operator()( T r ) + { + c_.insert( r ); + } + }; + + template< class C > + class call_add_edge + { + C& c_; + public: + call_add_edge( C& c ) : c_(c) + { } + + template< class T > + void operator()( T l, T r ) + { + add_edge( l, r, c_ ); + } + + template< class T, class EP > + void operator()( T l, T r, const EP& ep ) + { + add_edge( l, r, ep, c_ ); + } + + }; + + struct forward_n_arguments {}; + +} // namespace 'assign_detail' + +namespace assign +{ + + template< class T > + inline assign_detail::repeater + repeat( std::size_t sz, T r ) + { + return assign_detail::repeater( sz, r ); + } + + template< class Function > + inline assign_detail::fun_repeater + repeat_fun( std::size_t sz, Function r ) + { + return assign_detail::fun_repeater( sz, r ); + } + + + template< class Function, class Argument = assign_detail::forward_n_arguments > + class list_inserter + { + struct single_arg_type {}; + struct n_arg_type {}; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same::value, + n_arg_type, + single_arg_type >::type arg_type; + + public: + + list_inserter( Function fun ) : insert_( fun ) + {} + + template< class Function2, class Arg > + list_inserter( const list_inserter& r ) + : insert_( r.fun_private() ) + {} + + list_inserter( const list_inserter& r ) : insert_( r.insert_ ) + {} + + list_inserter& operator()() + { + insert_( Argument() ); + return *this; + } + + template< class T > + list_inserter& operator=( const T& r ) + { + insert_( r ); + return *this; + } + + template< class T > + list_inserter& operator=( assign_detail::repeater r ) + { + return operator,( r ); + } + + template< class Nullary_function > + list_inserter& operator=( const assign_detail::fun_repeater& r ) + { + //BOOST_STATIC_ASSERT( function_traits::arity == 0 ); + //BOOST_STATIC_ASSERT( is_convertible< BOOST_DEDUCED_TYPENAME function_traits< + // Nullary_function>::result_type >,T>::value ); + + return operator,( r ); + } + + template< class T > + list_inserter& operator,( const T& r ) + { + insert_( r ); + return *this; + } + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + template< class T > + list_inserter& operator,( const assign_detail::repeater & r ) + { + return repeat( r.sz, r.val ); + } +#else + template< class T > + list_inserter& operator,( assign_detail::repeater r ) + { + return repeat( r.sz, r.val ); + } +#endif + + template< class Nullary_function > + list_inserter& operator,( const assign_detail::fun_repeater& r ) + { + return repeat_fun( r.sz, r.val ); + } + + template< class T > + list_inserter& repeat( std::size_t sz, T r ) + { + std::size_t i = 0; + while( i++ != sz ) + insert_( r ); + return *this; + } + + template< class Nullary_function > + list_inserter& repeat_fun( std::size_t sz, Nullary_function fun ) + { + std::size_t i = 0; + while( i++ != sz ) + insert_( fun() ); + return *this; + } + + template< class SinglePassIterator > + list_inserter& range( SinglePassIterator first, + SinglePassIterator last ) + { + for( ; first != last; ++first ) + insert_( *first ); + return *this; + } + + template< class SinglePassRange > + list_inserter& range( const SinglePassRange& r ) + { + return range( boost::begin(r), boost::end(r) ); + } + + template< class T > + list_inserter& operator()( const T& t ) + { + insert_( t ); + return *this; + } + +#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value +#define BOOST_ASSIGN_MAX_PARAMS 5 +#endif +#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) +#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) +#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) +#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, BOOST_ASSIGN_PARAMS1(n) > \ + list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \ + return *this; \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, BOOST_ASSIGN_PARAMS1(n) > \ + void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \ + { \ + insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, BOOST_ASSIGN_PARAMS1(n) > \ + void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \ + { \ + insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + + Function fun_private() const + { + return insert_; + } + + private: + + list_inserter& operator=( const list_inserter& ); + Function insert_; + }; + + template< class Function > + inline list_inserter< Function > + make_list_inserter( Function fun ) + { + return list_inserter< Function >( fun ); + } + + template< class Function, class Argument > + inline list_inserter + make_list_inserter( Function fun, Argument* ) + { + return list_inserter( fun ); + } + + template< class C > + inline list_inserter< assign_detail::call_push_back, + BOOST_DEDUCED_TYPENAME C::value_type > + push_back( C& c ) + { + static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; + return make_list_inserter( assign_detail::call_push_back( c ), + p ); + } + + template< class C > + inline list_inserter< assign_detail::call_push_front, + BOOST_DEDUCED_TYPENAME C::value_type > + push_front( C& c ) + { + static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; + return make_list_inserter( assign_detail::call_push_front( c ), + p ); + } + + template< class C > + inline list_inserter< assign_detail::call_insert, + BOOST_DEDUCED_TYPENAME C::value_type > + insert( C& c ) + { + static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; + return make_list_inserter( assign_detail::call_insert( c ), + p ); + } + + template< class C > + inline list_inserter< assign_detail::call_push, + BOOST_DEDUCED_TYPENAME C::value_type > + push( C& c ) + { + static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; + return make_list_inserter( assign_detail::call_push( c ), + p ); + } + + template< class C > + inline list_inserter< assign_detail::call_add_edge > + add_edge( C& c ) + { + return make_list_inserter( assign_detail::call_add_edge( c ) ); + } + +} // namespace 'assign' +} // namespace 'boost' + +#undef BOOST_ASSIGN_PARAMS1 +#undef BOOST_ASSIGN_PARAMS2 +#undef BOOST_ASSIGN_PARAMS3 +#undef BOOST_ASSIGN_MAX_PARAMETERS + +#endif diff --git a/thirdparty/boost/assign/list_of.hpp b/thirdparty/boost/assign/list_of.hpp new file mode 100644 index 0000000..a9e822c --- /dev/null +++ b/thirdparty/boost/assign/list_of.hpp @@ -0,0 +1,593 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_LIST_OF_HPP +#define BOOST_ASSIGN_LIST_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# 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(__BORLANDC__, BOOST_TESTED_AT(0x564)) +// BCB requires full type definition for is_array<> to work correctly. +#include +#endif + +namespace boost +{ + +// this here is necessary to avoid compiler error in +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class T, std::size_t sz > + class array; +#endif + +namespace assign_detail +{ + ///////////////////////////////////////////////////////////////////////// + // Part 0: common conversion code + ///////////////////////////////////////////////////////////////////////// + + template< class T > + struct assign_decay + { + // + // Add constness to array parameters + // to support string literals properly + // + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + ::boost::is_array, + ::boost::decay, + ::boost::decay >::type type; + }; + + template< class T, std::size_t sz > + type_traits::yes_type assign_is_array( const array* ); + type_traits::no_type assign_is_array( ... ); + template< class T, class U > + type_traits::yes_type assign_is_pair( const std::pair* ); + type_traits::no_type assign_is_pair( ... ); + + + + struct array_type_tag + { + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + private: + char dummy_; // BCB would by default use 8 bytes + #endif + }; + struct adapter_type_tag + { + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + private: + char dummy_; // BCB would by default use 8 bytes + #endif + }; + struct pair_type_tag + { + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + private: + char dummy_; // BCB would by default use 8 bytes + #endif + }; + struct default_type_tag + { + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + private: + char dummy_; // BCB would by default use 8 bytes + #endif + }; + + + + template< class DerivedTAssign > + class converter + { + public: + + template< class Container > + Container convert_to_container() const + { + static Container* c = 0; + BOOST_STATIC_CONSTANT( bool, is_array_flag = sizeof( assign_detail::assign_is_array( c ) ) + == sizeof( type_traits::yes_type ) ); + + typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_array_flag, + array_type_tag, + default_type_tag >::type tag_type; + + return convert( c, tag_type() ); + } + + private: + + template< class Container > + Container convert( const Container*, default_type_tag ) const + { + +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +// old Dinkumware doesn't support iterator type as template + Container result; + BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator + it = static_cast(this)->begin(), + end = static_cast(this)->end(); + while( it != end ) + { + result.insert( result.end(), *it ); + ++it; + } + return result; +#else + return Container( static_cast(this)->begin(), + static_cast(this)->end() ); +#endif + } + + template< class Array > + Array convert( const Array*, array_type_tag ) const + { + typedef BOOST_DEDUCED_TYPENAME Array::value_type value_type; + +#if BOOST_WORKAROUND(BOOST_INTEL, <= 910 ) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580 ) + BOOST_DEDUCED_TYPENAME remove_const::type ar; +#else + Array ar; +#endif + const std::size_t sz = ar.size(); + if( sz < static_cast(this)->size() ) + throw assign::assignment_exception( "array initialized with too many elements" ); + std::size_t n = 0; + BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator + i = static_cast(this)->begin(), + end = static_cast(this)->end(); + for( ; i != end; ++i, ++n ) + ar[n] = *i; + for( ; n < sz; ++n ) + ar[n] = value_type(); + return ar; + } + + template< class Adapter > + Adapter convert_to_adapter( const Adapter* = 0 ) const + { + Adapter a; + BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator + i = static_cast(this)->begin(), + end = static_cast(this)->end(); + for( ; i != end; ++i ) + a.push( *i ); + return a; + } + + private: + struct adapter_converter; + friend struct adapter_converter; + + struct adapter_converter + { + const converter& gl; + adapter_converter( const converter& this_ ) : gl( this_ ) + {} + + adapter_converter( const adapter_converter& r ) + : gl( r.gl ) + { } + + template< class Adapter > + operator Adapter() const + { + return gl.convert_to_adapter(); + } + }; + + public: + template< class Container > + Container to_container( Container& c ) const + { + return convert( &c, default_type_tag() ); + } + + adapter_converter to_adapter() const + { + return adapter_converter( *this ); + } + + template< class Adapter > + Adapter to_adapter( Adapter& a ) const + { + return this->convert_to_adapter( &a ); + } + + template< class Array > + Array to_array( Array& a ) const + { + return convert( &a, array_type_tag() ); + } + }; + + ///////////////////////////////////////////////////////////////////////// + // Part 1: flexible, but inefficient interface + ///////////////////////////////////////////////////////////////////////// + + template< class T > + class generic_list : + public converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay::type > > + { + typedef converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay::type > > + base_type; + typedef BOOST_DEDUCED_TYPENAME assign_decay::type Ty; + typedef std::deque impl_type; + mutable impl_type values_; + + public: + typedef BOOST_DEDUCED_TYPENAME impl_type::iterator iterator; + typedef BOOST_DEDUCED_TYPENAME impl_type::const_iterator const_iterator; + typedef BOOST_DEDUCED_TYPENAME impl_type::value_type value_type; + typedef BOOST_DEDUCED_TYPENAME impl_type::size_type size_type; + typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type difference_type; + + public: + iterator begin() const { return values_.begin(); } + iterator end() const { return values_.end(); } + bool empty() const { return values_.empty(); } + size_type size() const { return values_.size(); } + + private: + void push_back( value_type r ) { values_.push_back( r ); } + + public: + generic_list& operator,( const Ty& u ) + { + this->push_back( u ); + return *this; + } + + generic_list& operator()() + { + this->push_back( Ty() ); + return *this; + } + + generic_list& operator()( const Ty& u ) + { + this->push_back( u ); + return *this; + } + + +#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value +#define BOOST_ASSIGN_MAX_PARAMS 5 +#endif +#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) +#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U) +#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u) +#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u) +#define BOOST_ASSIGN_PARAMS4(n) BOOST_PP_ENUM_PARAMS(n, U) +#define BOOST_ASSIGN_PARAMS2_NO_REF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, u) + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class U, BOOST_ASSIGN_PARAMS1(n) > \ + generic_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + this->push_back( Ty(u, BOOST_ASSIGN_PARAMS3(n))); \ + return *this; \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + + template< class U > + generic_list& repeat( std::size_t sz, U u ) + { + std::size_t i = 0; + while( i++ != sz ) + this->push_back( u ); + return *this; + } + + template< class Nullary_function > + generic_list& repeat_fun( std::size_t sz, Nullary_function fun ) + { + std::size_t i = 0; + while( i++ != sz ) + this->push_back( fun() ); + return *this; + } + + template< class SinglePassIterator > + generic_list& range( SinglePassIterator first, + SinglePassIterator last ) + { + for( ; first != last; ++first ) + this->push_back( *first ); + return *this; + } + + template< class SinglePassRange > + generic_list& range( const SinglePassRange& r ) + { + return range( boost::begin(r), boost::end(r) ); + } + + template< class Container > + operator Container() const + { + return this-> BOOST_NESTED_TEMPLATE convert_to_container(); + } + }; + + ///////////////////////////////////////////////////////////////////////// + // Part 2: efficient, but inconvenient interface + ///////////////////////////////////////////////////////////////////////// + + template< class T > + struct assign_reference + { + assign_reference() + { /* intentionally empty */ } + + assign_reference( T& r ) : ref_(&r) + { } + + void operator=( T& r ) + { + ref_ = &r; + } + + operator T&() const + { + return *ref_; + } + + void swap( assign_reference& r ) + { + std::swap( *ref_, *r.ref_ ); + } + + T& get_ref() const + { + return *ref_; + } + + private: + T* ref_; + + }; + + template< class T > + inline bool operator<( const assign_reference& l, + const assign_reference& r ) + { + return l.get_ref() < r.get_ref(); + } + + template< class T > + inline bool operator>( const assign_reference& l, + const assign_reference& r ) + { + return l.get_ref() > r.get_ref(); + } + + template< class T > + inline void swap( assign_reference& l, + assign_reference& r ) + { + l.swap( r ); + } + + + + template< class T, int N > + struct static_generic_list : + public converter< static_generic_list > + { + private: + typedef converter< static_generic_list > base_class; + typedef T internal_value_type; + + public: + typedef assign_reference value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + + static_generic_list( T& r ) : + current_(1) + { + refs_[0] = r; + } + + static_generic_list& operator()( T& r ) + { + insert( r ); + return *this; + } + + iterator begin() const + { + return &refs_[0]; + } + + iterator end() const + { + return &refs_[current_]; + } + + size_type size() const + { + return static_cast( current_ ); + } + + bool empty() const + { + return false; + } + + template< class ForwardIterator > + static_generic_list& range( ForwardIterator first, + ForwardIterator last ) + { + for( ; first != last; ++first ) + this->insert( *first ); + return *this; + } + + template< class ForwardRange > + static_generic_list& range( ForwardRange& r ) + { + return range( boost::begin(r), boost::end(r) ); + } + + template< class ForwardRange > + static_generic_list& range( const ForwardRange& r ) + { + return range( boost::begin(r), boost::end(r) ); + } + + template< class Container > + operator Container() const + { + return this-> BOOST_NESTED_TEMPLATE convert_to_container(); + } + + private: + void insert( T& r ) + { + refs_[current_] = r; + ++current_; + } + + static_generic_list(); + + mutable assign_reference refs_[N]; + int current_; + }; + +} // namespace 'assign_detail' + +namespace assign +{ + template< class T > + inline assign_detail::generic_list + list_of() + { + return assign_detail::generic_list()( T() ); + } + + template< class T > + inline assign_detail::generic_list + list_of( const T& t ) + { + return assign_detail::generic_list()( t ); + } + + template< int N, class T > + inline assign_detail::static_generic_list< BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type,N> + ref_list_of( T& t ) + { + return assign_detail::static_generic_list::type,N>( t ); + } + + template< int N, class T > + inline assign_detail::static_generic_list::type,N> + cref_list_of( const T& t ) + { + return assign_detail::static_generic_list::type,N>( t ); + } + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \ + inline assign_detail::generic_list \ + list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + return assign_detail::generic_list()(u, BOOST_ASSIGN_PARAMS3(n)); \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class U, BOOST_ASSIGN_PARAMS1(n) > \ + inline assign_detail::generic_list< tuple > \ + tuple_list_of(U u, BOOST_ASSIGN_PARAMS2_NO_REF(n) ) \ + { \ + return assign_detail::generic_list< tuple >()( tuple( u, BOOST_ASSIGN_PARAMS3(n) )); \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + + template< class Key, class T > + inline assign_detail::generic_list< std::pair + < + BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type, + BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type + > > + map_list_of( const Key& k, const T& t ) + { + typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type k_type; + typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type t_type; + return assign_detail::generic_list< std::pair >()( k, t ); + } + + template< class F, class S > + inline assign_detail::generic_list< std::pair + < + BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type, + BOOST_DEDUCED_TYPENAME assign_detail::assign_decay::type + > > + pair_list_of( const F& f, const S& s ) + { + return map_list_of( f, s ); + } + + +} // namespace 'assign' +} // namespace 'boost' + + +#undef BOOST_ASSIGN_PARAMS1 +#undef BOOST_ASSIGN_PARAMS2 +#undef BOOST_ASSIGN_PARAMS3 +#undef BOOST_ASSIGN_PARAMS4 +#undef BOOST_ASSIGN_PARAMS2_NO_REF +#undef BOOST_ASSIGN_MAX_PARAMETERS + +#endif diff --git a/thirdparty/boost/assign/ptr_list_inserter.hpp b/thirdparty/boost/assign/ptr_list_inserter.hpp new file mode 100644 index 0000000..aa8302c --- /dev/null +++ b/thirdparty/boost/assign/ptr_list_inserter.hpp @@ -0,0 +1,164 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2005. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_PTR_LIST_INSERTER_HPP +#define BOOST_ASSIGN_PTR_LIST_INSERTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + +namespace assign +{ + template< class Function, class Obj > + class ptr_list_inserter + { + typedef BOOST_DEDUCED_TYPENAME + remove_pointer< BOOST_DEDUCED_TYPENAME + remove_reference::type >::type + obj_type; + public: + + ptr_list_inserter( Function fun ) : insert_( fun ) + {} + + template< class Function2, class Obj2 > + ptr_list_inserter( const ptr_list_inserter& r ) + : insert_( r.fun_private() ) + {} + + ptr_list_inserter( const ptr_list_inserter& r ) : insert_( r.insert_ ) + {} + + ptr_list_inserter& operator()() + { + insert_( new obj_type() ); + return *this; + } + + template< class T > + ptr_list_inserter& operator()( const T& t ) + { + insert_( new obj_type(t) ); + return *this; + } + +#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value +#define BOOST_ASSIGN_MAX_PARAMS 5 +#endif +#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) +#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) +#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) +#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, BOOST_ASSIGN_PARAMS1(n) > \ + ptr_list_inserter& operator()( const T& t, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + insert_( new obj_type(t, BOOST_ASSIGN_PARAMS3(n) )); \ + return *this; \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + private: + + ptr_list_inserter& operator=( const ptr_list_inserter& ); + Function insert_; + }; + + template< class Obj, class Function > + inline ptr_list_inserter< Function, Obj > + make_ptr_list_inserter( Function fun ) + { + return ptr_list_inserter< Function, Obj >( fun ); + } + + template< class C > + inline ptr_list_inserter< assign_detail::call_push_back, + BOOST_DEDUCED_TYPENAME C::reference > + ptr_push_back( C& c ) + { + return make_ptr_list_inserter + ( assign_detail::call_push_back( c ) ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class T, class C > + inline ptr_list_inserter< assign_detail::call_push_back, T > + ptr_push_back( C& c ) + { + return make_ptr_list_inserter( + assign_detail::call_push_back( c ) ); + } + +#endif + + template< class C > + inline ptr_list_inserter< assign_detail::call_push_front, + BOOST_DEDUCED_TYPENAME C::reference > + ptr_push_front( C& c ) + { + return make_ptr_list_inserter + ( assign_detail::call_push_front( c ) ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class T, class C > + inline ptr_list_inserter< assign_detail::call_push_front, T > + ptr_push_front( C& c ) + { + return make_ptr_list_inserter( + assign_detail::call_push_front( c ) ); + } + +#endif + + template< class C > + inline ptr_list_inserter< assign_detail::call_insert, + BOOST_DEDUCED_TYPENAME C::reference> + ptr_insert( C& c ) + { + return make_ptr_list_inserter + ( assign_detail::call_insert( c ) ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class T, class C > + inline ptr_list_inserter< assign_detail::call_insert, T > + ptr_insert( C& c ) + { + return make_ptr_list_inserter( assign_detail::call_insert( c ) ); + } + +#endif + + +} // namespace 'assign' +} // namespace 'boost' + +#undef BOOST_ASSIGN_PARAMS1 +#undef BOOST_ASSIGN_PARAMS2 +#undef BOOST_ASSIGN_PARAMS3 +#undef BOOST_ASSIGN_MAX_PARAMETERS + +#endif diff --git a/thirdparty/boost/assign/ptr_list_of.hpp b/thirdparty/boost/assign/ptr_list_of.hpp new file mode 100644 index 0000000..7925c0a --- /dev/null +++ b/thirdparty/boost/assign/ptr_list_of.hpp @@ -0,0 +1,195 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2005. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_PTR_LIST_OF_HPP +#define BOOST_ASSIGN_PTR_LIST_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost +{ + +namespace assign_detail +{ + ///////////////////////////////////////////////////////////////////////// + // Part 1: flexible and efficient interface + ///////////////////////////////////////////////////////////////////////// + + template< class T > + class generic_ptr_list + { + protected: + typedef boost::ptr_vector impl_type; + typedef std::auto_ptr release_type; + mutable impl_type values_; + + public: + typedef BOOST_DEDUCED_TYPENAME impl_type::iterator iterator; + typedef BOOST_DEDUCED_TYPENAME impl_type::const_iterator const_iterator; + typedef BOOST_DEDUCED_TYPENAME impl_type::value_type value_type; + typedef BOOST_DEDUCED_TYPENAME impl_type::size_type size_type; + typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type difference_type; + public: + generic_ptr_list() : values_( 32u ) + { } + + /* + generic_ptr_list( const generic_ptr_list& r ) + { + values_.swap(r.values_); + }*/ + + generic_ptr_list( release_type r ) : values_(r) + { } + + release_type release() + { + return values_.release(); + } + + public: + iterator begin() const { return values_.begin(); } + iterator end() const { return values_.end(); } + bool empty() const { return values_.empty(); } + size_type size() const { return values_.size(); } + + public: + + operator impl_type() const + { + return values_; + } + + template< template class Seq, class U, + class CA, class A > + operator Seq() const + { + Seq result; + result.transfer( result.end(), values_ ); + BOOST_ASSERT( empty() ); + return result; + } + + template< class PtrContainer > + std::auto_ptr convert( const PtrContainer* c ) const + { + std::auto_ptr res( new PtrContainer() ); + while( !empty() ) + res->insert( res->end(), + values_.pop_back().release() ); + return res; + } + + template< class PtrContainer > + std::auto_ptr to_container( const PtrContainer& c ) const + { + return convert( &c ); + } + + protected: + void push_back( T* r ) { values_.push_back( r ); } + + public: + generic_ptr_list& operator()() + { + this->push_back( new T() ); + return *this; + } + + template< class U > + generic_ptr_list& operator()( const U& u ) + { + this->push_back( new T(u) ); + return *this; + } + + +#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value +#define BOOST_ASSIGN_MAX_PARAMS 5 +#endif +#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) +#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U) +#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u) +#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u) + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class U, BOOST_ASSIGN_PARAMS1(n) > \ + generic_ptr_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + this->push_back( new T(u, BOOST_ASSIGN_PARAMS3(n))); \ + return *this; \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + }; // class 'generic_ptr_list' + +} // namespace 'assign_detail' + +namespace assign +{ + template< class T > + inline assign_detail::generic_ptr_list + ptr_list_of() + { + return assign_detail::generic_ptr_list()(); + } + + template< class T, class U > + inline assign_detail::generic_ptr_list + ptr_list_of( const U& t ) + { + return assign_detail::generic_ptr_list()( t ); + } + + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \ + inline assign_detail::generic_ptr_list \ + ptr_list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + return assign_detail::generic_ptr_list()(u, BOOST_ASSIGN_PARAMS3(n)); \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + +} // namespace 'assign' +} // namespace 'boost' + + +#undef BOOST_ASSIGN_PARAMS1 +#undef BOOST_ASSIGN_PARAMS2 +#undef BOOST_ASSIGN_PARAMS3 +#undef BOOST_ASSIGN_MAX_PARAMETERS + +#endif diff --git a/thirdparty/boost/assign/ptr_map_inserter.hpp b/thirdparty/boost/assign/ptr_map_inserter.hpp new file mode 100644 index 0000000..69de771 --- /dev/null +++ b/thirdparty/boost/assign/ptr_map_inserter.hpp @@ -0,0 +1,103 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_PTR_CONTAINER_PTR_MAP_INSERTER_HPP +#define BOOST_ASSIGN_PTR_CONTAINER_PTR_MAP_INSERTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + +namespace assign +{ + template< class PtrMap, class Obj > + class ptr_map_inserter + { + typedef BOOST_DEDUCED_TYPENAME + remove_pointer< BOOST_DEDUCED_TYPENAME + remove_reference::type >::type + obj_type; + typedef BOOST_DEDUCED_TYPENAME PtrMap::key_type + key_type; + + public: + + ptr_map_inserter( PtrMap& m ) : m_( m ) + {} + + template< class Key > + ptr_map_inserter& operator()( const Key& t ) + { + key_type k(t); + m_.insert( k, new obj_type ); + return *this; + } + +#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value +#define BOOST_ASSIGN_MAX_PARAMS 6 +#endif +#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) +#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) +#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) +#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) +#define BOOST_PP_LOCAL_MACRO(n) \ + template< class T, BOOST_ASSIGN_PARAMS1(n) > \ + ptr_map_inserter& operator()( const T& t, BOOST_ASSIGN_PARAMS2(n) ) \ + { \ + key_type k(t); \ + m_.insert( k, new obj_type( BOOST_ASSIGN_PARAMS3(n) ) ); \ + return *this; \ + } \ + /**/ + +#include BOOST_PP_LOCAL_ITERATE() + + private: + + ptr_map_inserter& operator=( const ptr_map_inserter& ); + PtrMap& m_; + }; + + template< class PtrMap > + inline ptr_map_inserter< PtrMap, typename PtrMap::mapped_reference > + ptr_map_insert( PtrMap& m ) + { + return ptr_map_inserter< PtrMap, typename PtrMap::mapped_reference >( m ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class T, class PtrMap > + inline ptr_map_inserter< PtrMap, T > + ptr_map_insert( PtrMap& m ) + { + return ptr_map_inserter< PtrMap, T >( m ); + } + +#endif + +} // namespace 'assign' +} // namespace 'boost' + +#undef BOOST_ASSIGN_PARAMS1 +#undef BOOST_ASSIGN_PARAMS2 +#undef BOOST_ASSIGN_PARAMS3 +#undef BOOST_ASSIGN_MAX_PARAMETERS + +#endif diff --git a/thirdparty/boost/assign/std.hpp b/thirdparty/boost/assign/std.hpp new file mode 100644 index 0000000..68c8a67 --- /dev/null +++ b/thirdparty/boost/assign/std.hpp @@ -0,0 +1,27 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_STD_HPP +#define BOOST_ASSIGN_STD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/assign/std/deque.hpp b/thirdparty/boost/assign/std/deque.hpp new file mode 100644 index 0000000..97484e5 --- /dev/null +++ b/thirdparty/boost/assign/std/deque.hpp @@ -0,0 +1,38 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_STD_DEQUE_HPP +#define BOOST_ASSIGN_STD_DEQUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class V, class A, class V2 > + inline list_inserter< assign_detail::call_push_back< std::deque >, V > + operator+=( std::deque& c, V2 v ) + { + return push_back( c )( v ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/list.hpp b/thirdparty/boost/assign/std/list.hpp new file mode 100644 index 0000000..10b1a9b --- /dev/null +++ b/thirdparty/boost/assign/std/list.hpp @@ -0,0 +1,38 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_STD_LIST_HPP +#define BOOST_ASSIGN_STD_LIST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class V, class A, class V2 > + inline list_inserter< assign_detail::call_push_back< std::list >, V > + operator+=( std::list& c, V2 v ) + { + return push_back( c )( v ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/map.hpp b/thirdparty/boost/assign/std/map.hpp new file mode 100644 index 0000000..9ecbedd --- /dev/null +++ b/thirdparty/boost/assign/std/map.hpp @@ -0,0 +1,45 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_STD_MAP_HPP +#define BOOST_ASSIGN_STD_MAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class K, class V, class C, class A, class P > + inline list_inserter< assign_detail::call_insert< std::map >, P > + operator+=( std::map& m, const P& p ) + { + return insert( m )( p ); + } + + template< class K, class V, class C, class A, class P > + inline list_inserter< assign_detail::call_insert< std::multimap >, P > + operator+=( std::multimap& m, const P& p ) + { + return insert( m )( p ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/queue.hpp b/thirdparty/boost/assign/std/queue.hpp new file mode 100644 index 0000000..e654511 --- /dev/null +++ b/thirdparty/boost/assign/std/queue.hpp @@ -0,0 +1,45 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_STD_QUEUE_HPP +#define BOOST_ASSIGN_STD_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class V, class C, class V2 > + inline list_inserter< assign_detail::call_push< std::queue >, V > + operator+=( std::queue& c, V2 v ) + { + return push( c )( v ); + } + + template< class V, class C, class V2 > + inline list_inserter< assign_detail::call_push< std::priority_queue >, V > + operator+=( std::priority_queue& c, V2 v ) + { + return push( c )( v ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/set.hpp b/thirdparty/boost/assign/std/set.hpp new file mode 100644 index 0000000..3ca0316 --- /dev/null +++ b/thirdparty/boost/assign/std/set.hpp @@ -0,0 +1,44 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + + +#ifndef BOOST_ASSIGN_STD_SET_HPP +#define BOOST_ASSIGN_STD_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + template< class K, class C, class A, class K2 > + inline list_inserter< assign_detail::call_insert< std::set >, K > + operator+=( std::set& c, K2 k ) + { + return insert( c )( k ); + } + + template< class K, class C, class A, class K2 > + inline list_inserter< assign_detail::call_insert< std::multiset >, K > + operator+=( std::multiset& c, K2 k ) + { + return insert( c )( k ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/slist.hpp b/thirdparty/boost/assign/std/slist.hpp new file mode 100644 index 0000000..c357335 --- /dev/null +++ b/thirdparty/boost/assign/std/slist.hpp @@ -0,0 +1,45 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_STD_SLIST_HPP +#define BOOST_ASSIGN_STD_SLIST_HPP + +#include +#ifdef BOOST_HAS_SLIST + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#ifdef BOOST_SLIST_HEADER +# include BOOST_SLIST_HEADER +#else +# include +#endif + +namespace boost +{ +namespace assign +{ + + template< class V, class A, class V2 > + inline list_inserter< assign_detail::call_push_back< BOOST_STD_EXTENSION_NAMESPACE::slist >, V > + operator+=( BOOST_STD_EXTENSION_NAMESPACE::slist& c, V2 v ) + { + return push_back( c )( v ); + } + +} +} + +#endif // BOOST_HAS_SLIST + +#endif diff --git a/thirdparty/boost/assign/std/stack.hpp b/thirdparty/boost/assign/std/stack.hpp new file mode 100644 index 0000000..003a8d6 --- /dev/null +++ b/thirdparty/boost/assign/std/stack.hpp @@ -0,0 +1,37 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_STD_STACK_HPP +#define BOOST_ASSIGN_STD_STACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class V, class C, class V2 > + inline list_inserter< assign_detail::call_push< std::stack >, V > + operator+=( std::stack& c, V2 v ) + { + return push( c )( v ); + } + +} +} + +#endif diff --git a/thirdparty/boost/assign/std/vector.hpp b/thirdparty/boost/assign/std/vector.hpp new file mode 100644 index 0000000..f955ea2 --- /dev/null +++ b/thirdparty/boost/assign/std/vector.hpp @@ -0,0 +1,37 @@ +// Boost.Assign library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/assign/ +// + +#ifndef BOOST_ASSIGN_STD_VECTOR_HPP +#define BOOST_ASSIGN_STD_VECTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ +namespace assign +{ + + template< class V, class A, class V2 > + inline list_inserter< assign_detail::call_push_back< std::vector >, V > + operator+=( std::vector& c, V2 v ) + { + return push_back( c )( v ); + } + +} +} + +#endif diff --git a/thirdparty/boost/bimap.hpp b/thirdparty/boost/bimap.hpp new file mode 100644 index 0000000..015097a --- /dev/null +++ b/thirdparty/boost/bimap.hpp @@ -0,0 +1,19 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost 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/bimap for documentation. + +// Convenience header + +#include + +namespace boost +{ + using ::boost::bimaps::bimap; +} + diff --git a/thirdparty/boost/bimap/bimap.hpp b/thirdparty/boost/bimap/bimap.hpp new file mode 100644 index 0000000..9135ad9 --- /dev/null +++ b/thirdparty/boost/bimap/bimap.hpp @@ -0,0 +1,430 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file bimap.hpp +/// \brief Includes the basic bimap container + +/** \mainpage notitle +\n +\image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png + +\section Introduction + +This is the complete reference of Boost.Bimap. + +After getting a good understanding of the library from a user perspective +the next step will be: + + - Understand the tagged idiom. (boost::bimaps::tags) + - Understand the internals of the relation class (boost::bimaps::relation) + - Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor) + - Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views + and boost::bimaps::detail) + + + **/ + +/** \defgroup mutant_group mutant idiom +\brief A safe wrapper around reinterpret_cast + **/ + +/** \defgroup relation_group relation +\brief The relation + **/ + +/** \defgroup tags_group tagged idiom +\brief The tagged idiom + **/ + + +#ifndef BOOST_BIMAP_BIMAP_HPP +#define BOOST_BIMAP_BIMAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include +#include +#include + +#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + #include +#endif // BOOST_BIMAP_DISABLE_SERIALIZATION + +// Boost.Bimap +#include +#include +#include +#include +#include + +#include +#include +#include + +/// \brief The namespace where all the boost libraries lives. + +namespace boost { + +/// \brief Boost.Bimap library namespace +/** +All the entities in the library are defined in this namespace. + **/ +namespace bimaps { + +/// \brief The bimap class is the entry point to the library. +/** +This class manages the instantiation of the desired bimap type. +As there are several types of bidirectional maps that can be +created using it. the main job of it is to find the desired +type. This is done using metaprogramming to obtain the relation +type that will be stored, the map_view type of each side and +the set_view type of the general relationship. The instantiation +is kept simple using an extended standard set theory, where a +bidirectional map type is defined by the set types it relates. +For example, a bidirectional map that has multimap semantics +viewed from both sides is defined by specifying that the two +keys sets are of \c multiset_of type. +This allows the bimap class to support seamingless N-N, 1-N, +ordered/unordered and even vector-list types of mapping. +The three last parameters are used to specify the set type of +the relation, an inplace hooked data class and the allocator +type. As a help to the bimap user, these parameters support +default types but use a special idiom that allow them to be +specified without interleaving the usual use_default keyword. +The possible bimap instantiation are enumerated here: +\c {Side}KeyType can be directly a type, this is default to +\c set_of<{Side}KeyType>, or can be a \c {SetType}_of +specification. Additionally this two parameters can be tagged +to specify others tags instead of the usual \c member_at::{Side} +ones. + + +\code + + typedef bimap + < + LeftCollectionType, RightCollectionType + + [ , SetTypeOfRelation ] // Default to left_based + [ , info_hook< Info > ] // Default to no info + [ , Allocator ] // Default to std::allocator<> + + > bm; + +\endcode + + **/ + + +template +< + class KeyTypeA, class KeyTypeB, + class AP1 = ::boost::mpl::na, + class AP2 = ::boost::mpl::na, + class AP3 = ::boost::mpl::na +> +class bimap +: + // Bimap Core, use mpl magic to find the desired bimap type + + public ::boost::bimaps::detail::bimap_core, + + // You can use bimap as a collection of relations + + public ::boost::bimaps::detail::bimap_core + ::relation_set, + + // Include extra typedefs (i.e. left_local_iterator for unordered_map) + + public ::boost::bimaps::detail:: left_map_view_extra_typedefs< + BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::left_map_view_type< + ::boost::bimaps::detail::bimap_core + >::type + >, + public ::boost::bimaps::detail::right_map_view_extra_typedefs< + BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::right_map_view_type< + ::boost::bimaps::detail::bimap_core + >::type + > +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: + bimap_core base_; + + BOOST_DEDUCED_TYPENAME base_::core_type core; + + public: + + // metadata -------------------------------------------------------- + + /* + // The rest is computed in the core, because it is quite difficult to + // expose a nice interface with so many metaprogramming stuff. + // Here it is the complete metadat list. + + // Map by {side} metadata + + typedef -unspecified- {side}_tag; + typedef -unspecified- {side}_data_type; + typedef -unspecified- {side}_value_type; + typedef -unspecified- {side}_key_type; + typedef -unspecified- {side}_iterator; + typedef -unspecified- {side}_const_iterator; + + ------------------------------------------------------------------*/ + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: + left_map_view_type::type left_map; + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: + right_map_view_type::type right_map; + + typedef BOOST_DEDUCED_TYPENAME + left_map::reference left_reference; + typedef BOOST_DEDUCED_TYPENAME + left_map::const_reference left_const_reference; + + typedef BOOST_DEDUCED_TYPENAME + right_map::reference right_reference; + typedef BOOST_DEDUCED_TYPENAME + right_map::const_reference right_const_reference; + + typedef BOOST_DEDUCED_TYPENAME base_::relation::info_type info_type; + + /// Left map view + left_map left; + + /// Right map view + right_map right; + + bimap() : + + base_::relation_set( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag + >(core) + ), + left ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_left_tag + >(core) + ), + right ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_right_tag + >(core) + ) + + {} + + template< class InputIterator > + bimap(InputIterator first,InputIterator last) : + + base_::relation_set( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag + >(core) + ), + + core(first,last), + + left ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_left_tag + >(core) + ), + right ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_right_tag + >(core) + ) + + {} + + bimap(const bimap& x) : + + base_::relation_set( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag + >(core) + ), + + core(x.core), + + left ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_left_tag + >(core) + ), + right ( + ::boost::multi_index::get< + BOOST_DEDUCED_TYPENAME base_::logic_right_tag + >(core) + ) + + {} + + bimap& operator=(const bimap& x) + { + core = x.core; + return *this; + } + + // Projection of iterators + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::left_iterator + project_left(IteratorType iter) + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base()); + } + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::left_const_iterator + project_left(IteratorType iter) const + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base()); + } + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::right_iterator + project_right(IteratorType iter) + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base()); + } + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::right_const_iterator + project_right(IteratorType iter) const + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base()); + } + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::relation_set::iterator + project_up(IteratorType iter) + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base()); + } + + template< class IteratorType > + BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator + project_up(IteratorType iter) const + { + return core.template project< + BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base()); + } + + // Support for tags + + template< class Tag, class IteratorType > + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type + project(IteratorType iter + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + return core.template project(iter.base()); + } + + template< class Tag, class IteratorType > + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type + project(IteratorType iter + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const + { + return core.template project(iter.base()); + } + + template< class Tag > + struct map_by : + public ::boost::bimaps::support::map_type_by::type + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + map_type_by::type type; + + private: map_by() {} + }; + + template< class Tag > + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + map_type_by::type & + by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + return ::boost::bimaps::support::map_by(*this); + } + + template< class Tag > + const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + map_type_by::type & + by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const + { + return ::boost::bimaps::support::map_by(*this); + } + + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + // Serialization support + + private: + + friend class boost::serialization::access; + + template + void serialize(Archive & ar, const unsigned int version) + { + ar & serialization::make_nvp("mi_core",core); + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + +} // namespace bimaps +} // namespace boost + + +/** \namespace boost::bimaps::support +\brief Metafunctions to help working with bimaps. + **/ + +/** \namespace boost::bimaps::views +\brief Bimap views. + **/ + +/** \namespace boost::bimaps::views::detail +\brief Bimap views details. + **/ + + + +// Include basic tools for user commodity + +#include +#include +#include + +// Bring the most used namespaces directly to the user main namespace +namespace boost { +namespace bimaps { + +using ::boost::bimaps::tags::tagged; + +namespace member_at = ::boost::bimaps::relation::member_at; + +using ::boost::multi_index::unbounded; + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_BIMAP_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/associative_container_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/associative_container_adaptor.hpp new file mode 100644 index 0000000..0c6f4c1 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/associative_container_adaptor.hpp @@ -0,0 +1,287 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/associative_container_adaptor.hpp +/// \brief Container adaptor to build a type that is compliant to the concept of an associative container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Base, class Iterator, class ConstIterator, class KeyType, + class IteratorToBaseConverter, class IteratorFromBaseConverter, + class ValueToBaseConverter, class ValueFromBaseConverter, class KeyToBaseConverter, + class FunctorsFromDerivedClasses +> +struct associative_container_adaptor_base +{ + typedef container_adaptor + < + Base, + + Iterator, ConstIterator, + + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter , ValueFromBaseConverter, + + BOOST_DEDUCED_TYPENAME mpl::push_front< + + FunctorsFromDerivedClasses, + + BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + detail::key_to_base_identity + < + BOOST_DEDUCED_TYPENAME Base::key_type, KeyType + >, + // } + // else + // { + KeyToBaseConverter + // } + + >::type + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +/// \brief Container adaptor to build a type that is compliant to the concept of an associative container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + + class KeyType, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class associative_container_adaptor : + + public associative_container_adaptor_base + < + Base, Iterator, ConstIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type +{ + + // MetaData ------------------------------------------------------------- + + typedef typename associative_container_adaptor_base + < + Base, Iterator, ConstIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type base_; + + public: + + typedef KeyType key_type; + + protected: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + detail::key_to_base_identity + < + BOOST_DEDUCED_TYPENAME Base::key_type, KeyType + >, + // } + // else + // { + KeyToBaseConverter + // } + + >::type key_to_base; + + public: + + explicit associative_container_adaptor(Base & c) + : base_(c) {} + + protected: + + + typedef associative_container_adaptor associative_container_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::size_type erase(const CompatibleKey & k) + { + return this->base().erase + ( + this->template functor()(k) + ); + } + + // As we redefine erase, the other overloads need to be manually routed + + BOOST_DEDUCED_TYPENAME base_::iterator erase( + BOOST_DEDUCED_TYPENAME base_::iterator pos) + { + return base_::container_adaptor_::erase(pos); + } + + BOOST_DEDUCED_TYPENAME base_::iterator erase( + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + return base_::container_adaptor_::erase(first,last); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::size_type count(const CompatibleKey & k) + { + return this->base().count( + this->template functor()(k) + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::iterator find(const CompatibleKey & k) + { + return this->template functor() + ( + this->base().find( + this->template functor()(k) + ) + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::const_iterator + find(const CompatibleKey & k) const + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>() + ( + this->base().find( + this->template functor()(k) + ) + ); + } + + template< class CompatibleKey > + std::pair + < + BOOST_DEDUCED_TYPENAME base_::iterator, + BOOST_DEDUCED_TYPENAME base_::iterator + > + equal_range(const CompatibleKey & k) + { + std::pair< + + BOOST_DEDUCED_TYPENAME Base::iterator, + BOOST_DEDUCED_TYPENAME Base::iterator + + > r( this->base().equal_range( + this->template functor()(k) + ) + ); + + return std::pair + < + BOOST_DEDUCED_TYPENAME base_::iterator, + BOOST_DEDUCED_TYPENAME base_::iterator + >( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base + >() ( r.first ), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base + >() ( r.second ) + ); + } + + template< class CompatibleKey > + std::pair + < + BOOST_DEDUCED_TYPENAME base_::const_iterator, + BOOST_DEDUCED_TYPENAME base_::const_iterator + > + equal_range(const CompatibleKey & k) const + { + std::pair< + + BOOST_DEDUCED_TYPENAME Base::const_iterator, + BOOST_DEDUCED_TYPENAME Base::const_iterator + + > r( this->base().equal_range( + this->template functor()(k) + ) + ); + + return std::pair + < + BOOST_DEDUCED_TYPENAME base_::const_iterator, + BOOST_DEDUCED_TYPENAME base_::const_iterator + >( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base + >() ( r.first ), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base + >() ( r.second ) + ); + } + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP + + + diff --git a/thirdparty/boost/bimap/container_adaptor/container_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/container_adaptor.hpp new file mode 100644 index 0000000..e69209c --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/container_adaptor.hpp @@ -0,0 +1,291 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/container_adaptor.hpp +/// \brief Container adaptor to build a type that is compliant to the concept of a container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +namespace boost { +namespace bimaps { + +/// \brief Container Adaptor toolbox, easy way to build new containers from existing ones. + +namespace container_adaptor { + +/// \brief Container adaptor to build a type that is compliant to the concept of a container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class container_adaptor +{ + // MetaData ------------------------------------------------------------- + + public: + + typedef Iterator iterator; + typedef ConstIterator const_iterator; + + typedef BOOST_DEDUCED_TYPENAME iterator_value < iterator >::type value_type; + typedef BOOST_DEDUCED_TYPENAME iterator_pointer < iterator >::type pointer; + typedef BOOST_DEDUCED_TYPENAME iterator_reference< iterator >::type reference; + typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference; + + typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type; + typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + ::boost::bimaps::container_adaptor::detail:: + iterator_to_base_identity + < + BOOST_DEDUCED_TYPENAME Base::iterator , iterator, + BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator + >, + // } + // else + // { + IteratorToBaseConverter + // } + + >::type iterator_to_base; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + ::boost::bimaps::container_adaptor::detail:: + iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::iterator , iterator, + BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator + >, + // } + // else + // { + IteratorFromBaseConverter + // } + + >::type iterator_from_base; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + ::boost::bimaps::container_adaptor::detail:: + value_to_base_identity + < + BOOST_DEDUCED_TYPENAME Base::value_type, + value_type + >, + // } + // else + // { + ValueToBaseConverter + // } + + >::type value_to_base; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + ::boost::bimaps::container_adaptor::detail:: + value_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::value_type, + value_type + >, + // } + // else + // { + ValueFromBaseConverter + // } + + >::type value_from_base; + + // ACCESS ----------------------------------------------------------------- + + public: + + explicit container_adaptor(Base & c) : dwfb(c) {} + + protected: + + typedef Base base_type; + + typedef container_adaptor container_adaptor_; + + const Base & base() const { return dwfb.data; } + Base & base() { return dwfb.data; } + + // Interface -------------------------------------------------------------- + + public: + + size_type size() const { return base().size(); } + size_type max_size() const { return base().max_size(); } + bool empty() const { return base().empty(); } + + iterator begin() + { + return this->template functor()( base().begin() ); + } + + iterator end() + { + return this->template functor()( base().end() ); + } + + const_iterator begin() const + { + return this->template functor()( base().begin() ); + } + + const_iterator end() const + { + return this->template functor()( base().end() ); + } + + + iterator erase(iterator pos) + { + return this->template functor()( + base().erase(this->template functor()(pos)) + ); + } + + iterator erase(iterator first, iterator last) + { + return this->template functor()( + base().erase( + this->template functor()(first), + this->template functor()(last) + ) + ); + } + + void clear() + { + base().clear(); + } + + template< class InputIterator > + void insert(InputIterator iterBegin, InputIterator iterEnd) + { + for( ; iterBegin != iterEnd ; ++iterBegin ) + { + base().insert( this->template + functor()( *iterBegin ) + ); + } + } + + std::pair insert( + BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) + { + std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r( + base().insert( this->template functor()(x) ) + ); + + return std::pair( this->template + functor()(r.first),r.second + ); + } + + iterator insert(iterator pos, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) + { + return this->template functor()( + base().insert( + this->template functor()(pos), + this->template functor()(x)) + ); + } + + void swap( container_adaptor & c ) + { + base().swap( c.base() ); + } + + // Access to functors ---------------------------------------------------- + + protected: + + template< class Functor > + Functor & functor() + { + return dwfb.template functor(); + } + + template< class Functor > + Functor const & functor() const + { + return dwfb.template functor(); + } + + // Data ------------------------------------------------------------------ + + private: + + ::boost::bimaps::container_adaptor::detail::data_with_functor_bag + < + Base &, + + BOOST_DEDUCED_TYPENAME mpl::copy + < + mpl::vector + < + iterator_to_base, + iterator_from_base, + value_to_base, + value_from_base + >, + + mpl::front_inserter< FunctorsFromDerivedClasses > + + >::type + + > dwfb; +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp new file mode 100644 index 0000000..bc142c2 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp @@ -0,0 +1,101 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/detail/comparison_adaptor.hpp +/// \brief Comparison adaptor. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { +namespace detail { + +/// \brief Comparison adaptor +/** + +A simple comparison adaptor. + **/ + +template < class Compare, class NewType, class Converter > +struct comparison_adaptor : std::binary_function +{ + comparison_adaptor( const Compare & comp, const Converter & conv) + : compare(comp), converter(conv) {} + + bool operator()( BOOST_DEDUCED_TYPENAME call_traits::param_type x, + BOOST_DEDUCED_TYPENAME call_traits::param_type y) const + { + return compare( converter(x), converter(y) ); + } + + private: + Compare compare; + Converter converter; +}; + +template < class Compare, class NewType, class Converter > +struct compatible_comparison_adaptor : std::binary_function +{ + compatible_comparison_adaptor( const Compare & comp, const Converter & conv) + : compare(comp), converter(conv) {} + + template< class CompatibleTypeLeft, class CompatibleTypeRight > + bool operator()( const CompatibleTypeLeft & x, + const CompatibleTypeRight & y) const + { + return compare( converter(x), converter(y) ); + } + + private: + Compare compare; + Converter converter; +}; + + +/// \brief Unary Check adaptor +/** + +A simple unary check adaptor. + **/ + +template < class Compare, class NewType, class Converter > +struct unary_check_adaptor : std::unary_function +{ + unary_check_adaptor( const Compare & comp, const Converter & conv ) : + compare(comp), converter(conv) {} + + bool operator()( BOOST_DEDUCED_TYPENAME call_traits::param_type x) const + { + return compare( converter(x) ); + } + + private: + Compare compare; + Converter converter; +}; + +} // namespace detail +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/detail/functor_bag.hpp b/thirdparty/boost/bimap/container_adaptor/detail/functor_bag.hpp new file mode 100644 index 0000000..d622507 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/detail/functor_bag.hpp @@ -0,0 +1,100 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/detail/functor_bag.hpp +/// \brief Defines a EBO optimizacion helper for functors. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#if defined(BOOST_MSVC) +// This bogus warning will appear when add_const is applied to a +// const volatile reference because we can't detect const volatile +// references with MSVC6. +# pragma warning(push) +# pragma warning(disable:4181) +// warning C4181: qualifier applied to reference type ignored +#endif + +#include + +#include +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { +namespace detail { + +/// \brief EBO optimizacion helper for functors +/** + +This class is a generalization of a helper class explained in an article by +Nathan C. Myers.\n +See it at \link http://www.cantrip.org/emptyopt.html + **/ + +template < class Data, class FunctorList > +struct data_with_functor_bag : + + public mpl::inherit_linearly< + + FunctorList, + mpl::if_< is_base_of< mpl::_2, mpl::_1 >, + // { + mpl::_1, + // } + // else + // { + mpl::inherit< mpl::_1, mpl::_2 > + // } + > + + >::type +{ + Data data; + + data_with_functor_bag() {} + + data_with_functor_bag(BOOST_DEDUCED_TYPENAME add_reference::type d) + : data(d) {} + + template< class Functor > + Functor& functor() + { + return *(static_cast(this)); + } + + template< class Functor > + const Functor& functor() const + { + return *(static_cast(this)); + } +}; + +} // namespace detail +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/detail/identity_converters.hpp b/thirdparty/boost/bimap/container_adaptor/detail/identity_converters.hpp new file mode 100644 index 0000000..b7b9101 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/detail/identity_converters.hpp @@ -0,0 +1,191 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/detail/identity_converters.hpp +/// \brief Value and iterators identity converters. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Details of the container adaptor toolbox + +namespace detail { + +/// \brief Iterator identity converter used by default in container adaptors. +/** +If Iterator and ConstIterator are of the same type one of the convert function is not +included. + **/ + +template +< + class BaseIterator , class Iterator, + class BaseConstIterator , class ConstIterator +> +struct iterator_to_base_identity +{ + BaseIterator operator()(Iterator iter) const + { + return BaseIterator(iter); + } + + BaseConstIterator operator()(ConstIterator iter) const + { + return BaseConstIterator(iter); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class BaseIterator, class Iterator > +struct iterator_to_base_identity +{ + BaseIterator operator()(Iterator iter) const + { + return BaseIterator(iter); + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Iterator from base identity converter used by default in container adaptors. +/** +If Iterator and ConstIterator are of the same type one of the convert function is not +included. + **/ + +template +< + class BaseIterator , class Iterator, + class BaseConstIterator , class ConstIterator +> +struct iterator_from_base_identity +{ + Iterator operator()(BaseIterator iter) const + { + return Iterator(iter); + } + ConstIterator operator()(BaseConstIterator iter) const + { + return ConstIterator(iter); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class BaseIterator, class Iterator, class ConstIterator > +struct iterator_from_base_identity +{ + Iterator operator()(BaseIterator iter) const + { + return Iterator(iter); + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Value to base identity converter used by default in container adaptors. + +template< class BaseValue, class Value > +struct value_to_base_identity +{ + BaseValue operator()(const Value & val) const + { + return BaseValue(val); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Value > +struct value_to_base_identity< Value, Value > +{ + const Value & operator()(const Value & val) const + { + return val; + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Value from base identity converter used by default in container adaptors. + +template< class BaseValue, class Value > +struct value_from_base_identity +{ + Value operator()(const BaseValue & val) const + { + return Value(val); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Value > +struct value_from_base_identity +{ + Value & operator()(Value & val) const + { + return val; + } + + const Value & operator()(const Value & val) const + { + return val; + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Key to base identity converter used by default in container adaptors. + +template< class BaseKey, class Key > +struct key_to_base_identity +{ + BaseKey operator()(const Key & k) const + { + return BaseKey(k); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Key > +struct key_to_base_identity< Key, Key > +{ + // As default accept any type as key in order to allow container + // adaptors to work with compatible key types + + template< class CompatibleKey > + const CompatibleKey & operator()(const CompatibleKey & k) const + { + return k; + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +} // namespace detail +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/detail/key_extractor.hpp b/thirdparty/boost/bimap/container_adaptor/detail/key_extractor.hpp new file mode 100644 index 0000000..a8ff92a --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/detail/key_extractor.hpp @@ -0,0 +1,45 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/detail/key_extractor.hpp +/// \brief Key extractor for a pair. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { +namespace detail { + +/// \brief Key Extractor + +template < class T > +struct key_from_pair_extractor + : std::unary_function< T, BOOST_DEDUCED_TYPENAME T::first_type > +{ + bool operator()( const T & p ) { return p.first; } +}; + +} // namespace detail +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp b/thirdparty/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp new file mode 100644 index 0000000..0481db3 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp @@ -0,0 +1,62 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/detail/non_unique_container_helper.hpp +/// \brief Details for non unique containers + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +/*****************************************************************************/ +#define BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS \ + \ +template \ +void insert(InputIterator iterBegin, InputIterator iterEnd) \ +{ \ + for( ; iterBegin != iterEnd ; ++iterBegin ) \ + { \ + this->base().insert( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_to_base>()( \ + BOOST_DEDUCED_TYPENAME base_::value_type(*iterBegin)) ); \ + } \ +} \ + \ +BOOST_DEDUCED_TYPENAME base_::iterator insert( \ + BOOST_DEDUCED_TYPENAME ::boost::call_traits< \ + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \ +{ \ + return this->base().insert( this->template functor< \ + BOOST_DEDUCED_TYPENAME base_:: \ + value_to_base>()(x) ); \ +} \ + \ +BOOST_DEDUCED_TYPENAME base_::iterator \ + insert(BOOST_DEDUCED_TYPENAME base_::iterator pos, \ + BOOST_DEDUCED_TYPENAME ::boost::call_traits< \ + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( \ + this->base().insert(this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(pos), \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)) \ + ); \ +} +/*****************************************************************************/ + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/list_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/list_adaptor.hpp new file mode 100644 index 0000000..11f3c8d --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/list_adaptor.hpp @@ -0,0 +1,249 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/list_adaptor.hpp +/// \brief Container adaptor to easily build a std::list signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::list signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class list_adaptor : + + public ::boost::bimaps::container_adaptor::sequence_container_adaptor + < + Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef ::boost::bimaps::container_adaptor::sequence_container_adaptor + < + Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + explicit list_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef list_adaptor list_adaptor_; + + // Interface ------------------------------------------------------------- + + public: + + void splice(Iterator position, list_adaptor & x) + { + this->base().splice( + this->template functor() + (position), + x.base() + ); + } + + void splice(Iterator position, list_adaptor & x, Iterator i) + { + this->base().splice( + this->template functor() + (position), + x.base(), + this->template functor()(i) + ); + } + + void splice(Iterator position, list_adaptor & x, + Iterator first, Iterator last) + { + this->base().splice( + this->template functor() + (position), + x.base(), + this->template functor()(first), + this->template functor()(last) + ); + } + + void remove( + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type + >::param_type value + ) + { + this->base().remove( + this->template functor()(value) + ); + } + + template< class Predicate > + void remove_if(Predicate pred) + { + this->base().remove_if( + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + Predicate, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( pred, this->template functor() ) + ); + } + + void unique() + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::equal_to, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::equal_to(), + this->template functor() + ) + ); + } + + template< class BinaryPredicate > + void unique(BinaryPredicate binary_pred) + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + BinaryPredicate, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( binary_pred, + this->template functor() ) + ); + } + + void merge(list_adaptor & x) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::less(), + this->template functor() + ) + ); + } + + template< class Compare > + void merge(list_adaptor & x, Compare comp) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( comp, this->template functor() ) + ); + } + + void sort() + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::less(), + this->template functor() + ) + ); + } + + template< class Compare > + void sort(Compare comp) + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME Base::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( comp, this->template functor() ) + ); + } + + void reverse() + { + this->base().reverse(); + } + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/list_map_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/list_map_adaptor.hpp new file mode 100644 index 0000000..bd1d52b --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/list_map_adaptor.hpp @@ -0,0 +1,282 @@ + // Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/list_map_adaptor.hpp +/// \brief Container adaptor. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Base, class Iterator, class ConstIterator, + class ReverseIterator, class ConstReverseIterator, + class IteratorToBaseConverter, class IteratorFromBaseConverter, + class ReverseIteratorFromBaseConverter, + class ValueToBaseConverter, class ValueFromBaseConverter, + class KeyFromBaseValueConverter, + class FunctorsFromDerivedClasses +> +struct list_map_adaptor_base +{ + typedef list_adaptor + < + Base, + + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + + IteratorToBaseConverter, IteratorFromBaseConverter, + + ReverseIteratorFromBaseConverter, + + ValueToBaseConverter, ValueFromBaseConverter, + + BOOST_DEDUCED_TYPENAME mpl::push_front< + + FunctorsFromDerivedClasses, + + BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + detail::key_from_pair_extractor + < + BOOST_DEDUCED_TYPENAME Iterator::value_type + >, + // } + // else + // { + KeyFromBaseValueConverter + // } + + >::type + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Container adaptor to easily build a list map container + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyFromBaseValueConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class list_map_adaptor : + + public list_map_adaptor_base + < + Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyFromBaseValueConverter, + FunctorsFromDerivedClasses + + >::type +{ + typedef BOOST_DEDUCED_TYPENAME list_map_adaptor_base + < + Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyFromBaseValueConverter, + FunctorsFromDerivedClasses + + >::type base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type key_type; + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + protected: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na, + // { + detail::key_from_pair_extractor< BOOST_DEDUCED_TYPENAME Iterator::value_type >, + // } + // else + // { + KeyFromBaseValueConverter + // } + + >::type key_from_base_value; + + // Access ----------------------------------------------------------------- + + public: + + explicit list_map_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef list_map_adaptor list_map_adaptor_; + + // Functions ------------------------------------------------------------- + + public: + + // The following functions are overwritten in order to work + // with key_type instead of value_type + + template< class Predicate > + void remove_if(Predicate pred) + { + this->base().remove_if( + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + Predicate, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( pred, this->template functor() ) + ); + } + + void unique() + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::equal_to, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( + std::equal_to(), + this->template functor() + ) + ); + } + + template< class BinaryPredicate > + void unique(BinaryPredicate binary_pred) + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + BinaryPredicate, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( binary_pred, this->template functor() ) + ); + } + + void merge(list_map_adaptor & x) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( + std::less(), + this->template functor() + ) + ); + } + + template< class Compare > + void merge(list_map_adaptor & x, Compare comp) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( comp, this->template functor() ) + ); + } + + void sort() + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( + std::less(), + this->template functor() + ) + ); + } + + template< class Compare > + void sort(Compare comp) + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME Base::value_type, + key_from_base_value + + >( comp, this->template functor() ) + ); + } + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/map_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/map_adaptor.hpp new file mode 100644 index 0000000..b922529 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/map_adaptor.hpp @@ -0,0 +1,131 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/map_adaptor.hpp +/// \brief Container adaptor to easily build a std::map signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::map signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class map_adaptor : + + public ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + + typedef ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + // Access ----------------------------------------------------------------- + + public: + + explicit map_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef map_adaptor map_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + template< class CompatibleKey > + data_type& operator[](const CompatibleKey & k) + { + return this->base() + [this->template functor()(k)]; + } + + template< class CompatibleKey > + data_type& at(const CompatibleKey & k) + { + return this->base(). + at(this->template functor()(k)); + } + + template< class CompatibleKey > + const data_type& at(const CompatibleKey & k) const + { + return this->base(). + at(this->template functor()(k)); + } + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/multimap_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/multimap_adaptor.hpp new file mode 100644 index 0000000..468d083 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/multimap_adaptor.hpp @@ -0,0 +1,109 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/multimap_adaptor.hpp +/// \brief Container adaptor to easily build a std::multimap signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::multimap signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class multimap_adaptor : + + public ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + // Access ----------------------------------------------------------------- + + public: + + explicit multimap_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef multimap_adaptor multimap_adaptor_; + + public: + + BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/multiset_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/multiset_adaptor.hpp new file mode 100644 index 0000000..caab643 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/multiset_adaptor.hpp @@ -0,0 +1,103 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/multiset_adaptor.hpp +/// \brief Container adaptor to easily build a std::multiset signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::multiset signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class multiset_adaptor : + + public ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + + typedef ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + explicit multiset_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef multiset_adaptor multiset_adaptor_; + + public: + + BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp new file mode 100644 index 0000000..5fed363 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp @@ -0,0 +1,312 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/ordered_associative_container_adaptor.hpp +/// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Base, class Iterator, class ConstIterator, + class ReverseIterator, class ConstReverseIterator, class KeyType, + class IteratorToBaseConverter, class IteratorFromBaseConverter, + class ReverseIteratorFromBaseConverter, + class ValueToBaseConverter, class ValueFromBaseConverter, + class KeyToBaseConverter, + class FunctorsFromDerivedClasses +> +struct ordered_associative_container_adaptor_base +{ + typedef associative_container_adaptor< + Base, Iterator, ConstIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter, + + BOOST_DEDUCED_TYPENAME mpl::push_front< + + FunctorsFromDerivedClasses, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::reverse_iterator, + ReverseIterator, + BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, + ConstReverseIterator + >, + // } + // else + // { + ReverseIteratorFromBaseConverter + // } + + >::type + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class KeyType, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class ordered_associative_container_adaptor : + + public ordered_associative_container_adaptor_base + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type, + + ::boost::totally_ordered + < + ordered_associative_container_adaptor + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, + KeyType, IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, FunctorsFromDerivedClasses + > + > +{ + // MetaData ------------------------------------------------------------- + + typedef BOOST_DEDUCED_TYPENAME ordered_associative_container_adaptor_base + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type base_; + + public: + + typedef detail::compatible_comparison_adaptor + < + BOOST_DEDUCED_TYPENAME Base::key_compare, + BOOST_DEDUCED_TYPENAME base_::key_type, + BOOST_DEDUCED_TYPENAME base_::key_to_base + + > key_compare; + + typedef detail::comparison_adaptor + < + BOOST_DEDUCED_TYPENAME Base::value_compare, + BOOST_DEDUCED_TYPENAME base_::value_type, + BOOST_DEDUCED_TYPENAME base_::value_to_base + + > value_compare; + + typedef ReverseIterator reverse_iterator; + typedef ConstReverseIterator const_reverse_iterator; + + protected: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::reverse_iterator, + reverse_iterator, + BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, + const_reverse_iterator + >, + // } + // else + // { + ReverseIteratorFromBaseConverter + // } + + >::type reverse_iterator_from_base; + + // Access ----------------------------------------------------------------- + + public: + + explicit ordered_associative_container_adaptor(Base & c) + : base_(c) {} + + protected: + + typedef ordered_associative_container_adaptor + ordered_associative_container_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + reverse_iterator rbegin() + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rbegin() ); + + } + + reverse_iterator rend() + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rend() ); + } + + const_reverse_iterator rbegin() const + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rbegin() ); + } + + const_reverse_iterator rend() const + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rend() ); + } + + key_compare key_comp() const + { + typedef BOOST_DEDUCED_TYPENAME base_::key_to_base key_to_base_; + + return key_compare( + this->base().key_comp(), + this->template functor() + ); + } + + value_compare value_comp() const + { + typedef BOOST_DEDUCED_TYPENAME base_::value_to_base value_to_base_; + + return value_compare( + this->base().value_comp(), + this->template functor() + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::iterator lower_bound(const CompatibleKey & k) + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( + this->base().lower_bound( + this->template functor()(k) + ) + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::const_iterator lower_bound(const CompatibleKey & k) const + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( + this->base().lower_bound( + this->template functor()(k) + ) + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::iterator upper_bound(const CompatibleKey & k) + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( + this->base().upper_bound( + this->template functor()(k) + ) + ); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::const_iterator upper_bound(const CompatibleKey & k) const + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( + this->base().upper_bound( + this->template functor()(k) + ) + ); + } + + // Totally ordered implementation + + bool operator==(const ordered_associative_container_adaptor & c) const + { + return ( this->base() == c.base() ); + } + + bool operator<(const ordered_associative_container_adaptor & c) const + { + return ( this->base() < c.base() ); + } +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/sequence_container_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/sequence_container_adaptor.hpp new file mode 100644 index 0000000..9424312 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/sequence_container_adaptor.hpp @@ -0,0 +1,355 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/sequence_container_adaptor.hpp +/// \brief Container adaptor to build a type that is compliant to the concept of a weak associative container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Base, class Iterator, class ConstIterator, + class ReverseIterator, class ConstReverseIterator, + class IteratorToBaseConverter, class IteratorFromBaseConverter, + class ReverseIteratorFromBaseConverter, + class ValueToBaseConverter, class ValueFromBaseConverter, + class FunctorsFromDerivedClasses +> +struct sequence_container_adaptor_base +{ + typedef container_adaptor + < + Base, Iterator, ConstIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + + BOOST_DEDUCED_TYPENAME mpl::push_front< + + FunctorsFromDerivedClasses, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::reverse_iterator, + ReverseIterator, + BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, + ConstReverseIterator + >, + // } + // else + // { + ReverseIteratorFromBaseConverter + // } + + >::type + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief Container adaptor to build a type that is compliant to the concept of a sequence container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class sequence_container_adaptor : + + public sequence_container_adaptor_base + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + + >::type, + + ::boost::totally_ordered + < + sequence_container_adaptor + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + > + > +{ + typedef BOOST_DEDUCED_TYPENAME sequence_container_adaptor_base + < + Base, Iterator, ConstIterator, + ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + + >::type base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef ReverseIterator reverse_iterator; + typedef ConstReverseIterator const_reverse_iterator; + + protected: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::reverse_iterator, + reverse_iterator, + BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, + const_reverse_iterator + >, + // } + // else + // { + ReverseIteratorFromBaseConverter + // } + + >::type reverse_iterator_from_base; + + + // Access ----------------------------------------------------------------- + + public: + + explicit sequence_container_adaptor(Base & c) + : base_(c) {} + + protected: + + + typedef sequence_container_adaptor sequence_container_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + reverse_iterator rbegin() + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rbegin() ); + + } + + reverse_iterator rend() + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rend() ); + } + + const_reverse_iterator rbegin() const + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rbegin() ); + } + + const_reverse_iterator rend() const + { + return this->template functor< + reverse_iterator_from_base + >() ( this->base().rend() ); + } + + void resize(BOOST_DEDUCED_TYPENAME base_::size_type n, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x = + BOOST_DEDUCED_TYPENAME base_::value_type()) + { + this->base().resize(n, + this->template functor()(x) + ); + } + + BOOST_DEDUCED_TYPENAME base_::reference front() + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ( + this->base().front() + ); + } + + BOOST_DEDUCED_TYPENAME base_::reference back() + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ( + this->base().back() + ); + } + + BOOST_DEDUCED_TYPENAME base_::const_reference front() const + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ( + this->base().front() + ); + } + + BOOST_DEDUCED_TYPENAME base_::const_reference back() const + { + return this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ( + this->base().back() + ); + } + + void push_front( + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) + { + this->base().push_front( + this->template functor()(x)); + } + + void pop_front() + { + this->base().pop_front(); + } + + void push_back( + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) + { + this->base().push_back( + this->template functor()(x)); + } + + void pop_back() + { + this->base().pop_back(); + } + + std::pair + insert(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) + { + std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r( + this->base().insert( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_to_base >()(x) + ) + ); + + return std::pair( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(r.first), + r.second + ); + } + + void insert(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::size_type m, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) + { + this->base().insert( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + m, + this->template functor()(x) + ); + } + + template< class InputIterator > + void insert(BOOST_DEDUCED_TYPENAME base_::iterator position, + InputIterator first, InputIterator last) + { + // This is the same problem found in the insert function + // of container_adaptor + // For now, do the simple thing. This can be optimized + + for( ; first != last ; ++first ) + { + this->base().insert( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()( position ), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_to_base >()( *first ) + ); + } + } + + // Totally ordered implementation + + bool operator==(const sequence_container_adaptor & c) const + { + return ( this->base() == c.base() ); + } + + bool operator<(const sequence_container_adaptor & c) const + { + return ( this->base() < c.base() ); + } +}; + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/set_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/set_adaptor.hpp new file mode 100644 index 0000000..bcff933 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/set_adaptor.hpp @@ -0,0 +1,100 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/set_adaptor.hpp +/// \brief Container adaptor to easily build a std::set signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::set signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class set_adaptor : + + public ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + + typedef ::boost::bimaps::container_adaptor:: + ordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + explicit set_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef set_adaptor set_adaptor_; + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp b/thirdparty/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp new file mode 100644 index 0000000..36b8579 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp @@ -0,0 +1,77 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/support/iterator_facade_converters.hpp +/// \brief Converter for Boost.Iterators based iterators. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Utilities to help in the construction of a container adaptor + +namespace support { + +/// \brief Converter for Boost.Iterators based iterators. +/** +Container adaptor is dessigned to play well with Boost.Iterators. This +converter can be used if this library is used to adapt the iterators. + **/ +template +< + class Iterator, + class ConstIterator +> +struct iterator_facade_to_base +{ + BOOST_DEDUCED_TYPENAME Iterator::base_type operator()(Iterator iter) const + { + return iter.base(); + } + + BOOST_DEDUCED_TYPENAME ConstIterator::base_type operator()(ConstIterator iter) const + { + return iter.base(); + } +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Iterator +> +struct iterator_facade_to_base +{ + BOOST_DEDUCED_TYPENAME Iterator::base_type operator()(Iterator iter) const + { + return iter.base(); + } +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#undef BOOST_BIMAP_CONTAINER_ADAPTOR_IMPLEMENT_CONVERT_FACADE_FUNCTION + + +} // namespace support +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp new file mode 100644 index 0000000..e64bc6a --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp @@ -0,0 +1,293 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/unordered_associative_container_adaptor.hpp +/// \brief Container adaptor to build a type that is compliant to the concept of an unordered associative container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class Base, class Iterator, class ConstIterator, + class LocalIterator, class ConstLocalIterator, + class KeyType, + class IteratorToBaseConverter, class IteratorFromBaseConverter, + class LocalIteratorFromBaseConverter, + class ValueToBaseConverter, class ValueFromBaseConverter, + class KeyToBaseConverter, + class FunctorsFromDerivedClasses +> +struct unordered_associative_container_adaptor_base +{ + + typedef associative_container_adaptor + < + Base, Iterator, ConstIterator, KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + ValueToBaseConverter , ValueFromBaseConverter, + KeyToBaseConverter, + + BOOST_DEDUCED_TYPENAME mpl::push_front< + + FunctorsFromDerivedClasses, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::local_iterator, + LocalIterator, + BOOST_DEDUCED_TYPENAME Base::const_local_iterator, + ConstLocalIterator + >, + // } + // else + // { + LocalIteratorFromBaseConverter + // } + + >::type + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +/// \brief Container adaptor to build a type that is compliant to the concept of an unordered associative container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + + class LocalIterator, + class ConstLocalIterator, + + class KeyType, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class LocalIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> + +> +class unordered_associative_container_adaptor : + + public unordered_associative_container_adaptor_base + < + Base, Iterator, ConstIterator, + LocalIterator, ConstLocalIterator, + KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type +{ + typedef BOOST_DEDUCED_TYPENAME unordered_associative_container_adaptor_base + < + Base, Iterator, ConstIterator, + LocalIterator, ConstLocalIterator, + KeyType, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + >::type base_; + + // Metadata --------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Base::key_equal key_equal; + typedef BOOST_DEDUCED_TYPENAME Base::hasher hasher; + + typedef LocalIterator local_iterator; + typedef ConstLocalIterator const_local_iterator; + + protected: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::mpl::is_na, + // { + detail::iterator_from_base_identity + < + BOOST_DEDUCED_TYPENAME Base::local_iterator, + local_iterator, + BOOST_DEDUCED_TYPENAME Base::const_local_iterator, + const_local_iterator + >, + // } + // else + // { + LocalIteratorFromBaseConverter + // } + + >::type local_iterator_from_base; + + // Access ----------------------------------------------------------------- + + public: + + explicit unordered_associative_container_adaptor(Base & c) + : base_(c) {} + + protected: + + + typedef unordered_associative_container_adaptor + unordered_associative_container_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + // bucket interface: + + BOOST_DEDUCED_TYPENAME base_::size_type bucket_count() const + { + return this->base().bucket_count(); + } + + BOOST_DEDUCED_TYPENAME base_::size_type max_bucket_count() const + { + return this->base().max_bucket_count(); + } + + BOOST_DEDUCED_TYPENAME base_::size_type bucket_size( + BOOST_DEDUCED_TYPENAME base_::size_type n) const + { + return this->base().bucket_size(n); + } + + template< class CompatibleKey > + BOOST_DEDUCED_TYPENAME base_::size_type bucket( + const CompatibleKey & k) const + { + typedef BOOST_DEDUCED_TYPENAME base_::key_to_base key_to_base; + return this->base().bucket( + this->template functor()(k) + ); + } + + local_iterator begin(BOOST_DEDUCED_TYPENAME base_::size_type n) + { + return this->template functor< + local_iterator_from_base + >() ( this->base().begin(n) ); + } + + const_local_iterator begin(BOOST_DEDUCED_TYPENAME base_::size_type n) const + { + return this->template functor< + local_iterator_from_base + >() ( this->base().begin(n) ); + } + + local_iterator end(BOOST_DEDUCED_TYPENAME base_::size_type n) + { + return this->template functor< + local_iterator_from_base + >() ( this->base().end(n) ); + } + + const_local_iterator end(BOOST_DEDUCED_TYPENAME base_::size_type n) const + { + return this->template functor< + local_iterator_from_base + >() ( this->base().end(n) ); + } + + // hash policy + + float load_factor() const + { + return this->base().load_factor(); + } + + float max_load_factor() const + { + return this->base().max_load_factor(); + } + + void max_load_factor(float z) + { + return this->base().max_load_factor(z); + } + + void rehash(BOOST_DEDUCED_TYPENAME base_::size_type n) + { + return this->base().rehash(n); + } + + // We have redefined end and begin so we have to manually route the old ones + + BOOST_DEDUCED_TYPENAME base_::iterator begin() + { + return base_::container_adaptor_::begin(); + } + + BOOST_DEDUCED_TYPENAME base_::iterator end() + { + return base_::container_adaptor_::end(); + } + + BOOST_DEDUCED_TYPENAME base_::const_iterator begin() const + { + return base_::container_adaptor_::begin(); + } + + BOOST_DEDUCED_TYPENAME base_::const_iterator end() const + { + return base_::container_adaptor_::end(); + } + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP diff --git a/thirdparty/boost/bimap/container_adaptor/unordered_map_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/unordered_map_adaptor.hpp new file mode 100644 index 0000000..1e09386 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/unordered_map_adaptor.hpp @@ -0,0 +1,132 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/unordered_map_adaptor.hpp +/// \brief Container adaptor to easily build a std::unordered_map signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::unordered_map signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class LocalIterator, + class ConstLocalIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class LocalIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class unordered_map_adaptor : + + public ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + + typedef ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + // Access ----------------------------------------------------------------- + + public: + + explicit unordered_map_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef unordered_map_adaptor unordered_map_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + template< class CompatibleKey > + data_type& operator[](const CompatibleKey & k) + { + return this->base() + [this->template functor()(k)]; + } + + template< class CompatibleKey > + data_type& at(const CompatibleKey & k) + { + return this->base(). + at(this->template functor()(k)); + } + + template< class CompatibleKey > + const data_type& at(const CompatibleKey & k) const + { + return this->base(). + at(this->template functor()(k)); + } + +}; + + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp new file mode 100644 index 0000000..b3cbae1 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp @@ -0,0 +1,110 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/unordered_multimap_adaptor.hpp +/// \brief Container adaptor to easily build a std::unordered_multimap signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::unordered_multimap signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class LocalIterator, + class ConstLocalIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class LocalIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class unordered_multimap_adaptor : + + public ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + // Access ----------------------------------------------------------------- + + public: + + explicit unordered_multimap_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef unordered_multimap_adaptor unordered_multimap_adaptor_; + + public: + + BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS +}; + + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp new file mode 100644 index 0000000..d611a42 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp @@ -0,0 +1,102 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/unordered_multiset_adaptor.hpp +/// \brief Container adaptor to easily build a std::unordered_multiset signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::unordered_multiset signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class LocalIterator, + class ConstLocalIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class LocalIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class unordered_multiset_adaptor : + + public ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + explicit unordered_multiset_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef unordered_multiset_adaptor unordered_multiset_adaptor_; + + public: + + BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/unordered_set_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/unordered_set_adaptor.hpp new file mode 100644 index 0000000..3b3d3bd --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/unordered_set_adaptor.hpp @@ -0,0 +1,98 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/unordered_set_adaptor.hpp +/// \brief Container adaptor to easily build a std::unordered_set signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::unordered_set signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class LocalIterator, + class ConstLocalIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class LocalIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + class KeyToBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class unordered_set_adaptor : + + public ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef ::boost::bimaps::container_adaptor:: + unordered_associative_container_adaptor + < + Base, + Iterator, ConstIterator, LocalIterator, ConstLocalIterator, + BOOST_DEDUCED_TYPENAME Iterator::value_type, + IteratorToBaseConverter, IteratorFromBaseConverter, + LocalIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + KeyToBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + explicit unordered_set_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef unordered_set_adaptor unordered_set_adaptor_; + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/container_adaptor/vector_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/vector_adaptor.hpp new file mode 100644 index 0000000..d0ce022 --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/vector_adaptor.hpp @@ -0,0 +1,142 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/vector_adaptor.hpp +/// \brief Container adaptor to easily build a std::vector signature compatible container. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor to easily build a std::vector signature compatible container. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class vector_adaptor : + + public ::boost::bimaps::container_adaptor::sequence_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + > +{ + + typedef ::boost::bimaps::container_adaptor::sequence_container_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // Access ----------------------------------------------------------------- + + public: + + vector_adaptor() {} + + explicit vector_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef vector_adaptor vector_adaptor_; + + // Interface -------------------------------------------------------------- + + public: + + BOOST_DEDUCED_TYPENAME base_::size_type capacity() const + { + return this->base().capacity(); + } + + void reserve(BOOST_DEDUCED_TYPENAME base_::size_type m) + { + this->base().resize(m); + } + + void resize(BOOST_DEDUCED_TYPENAME base_::size_type n, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x = + BOOST_DEDUCED_TYPENAME base_::value_type()) + { + this->base().resize(n, + this->template functor()(x) + ); + } + + BOOST_DEDUCED_TYPENAME base_::const_reference + operator[](BOOST_DEDUCED_TYPENAME base_::size_type n) const + { + return this->base().operator[](n); + } + + BOOST_DEDUCED_TYPENAME base_::const_reference + at(BOOST_DEDUCED_TYPENAME base_::size_type n) const + { + return this->base().at(n); + } + + BOOST_DEDUCED_TYPENAME base_::reference + operator[](BOOST_DEDUCED_TYPENAME base_::size_type n) + { + return this->base().operator[](n); + } + + BOOST_DEDUCED_TYPENAME base_::reference + at(BOOST_DEDUCED_TYPENAME base_::size_type n) + { + return this->base().at(n); + } +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP + + diff --git a/thirdparty/boost/bimap/container_adaptor/vector_map_adaptor.hpp b/thirdparty/boost/bimap/container_adaptor/vector_map_adaptor.hpp new file mode 100644 index 0000000..c099c3c --- /dev/null +++ b/thirdparty/boost/bimap/container_adaptor/vector_map_adaptor.hpp @@ -0,0 +1,103 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file container_adaptor/vector_map_adaptor.hpp +/// \brief Container adaptor. + +#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP +#define BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace container_adaptor { + +/// \brief Container adaptor. + +template +< + class Base, + + class Iterator, + class ConstIterator, + class ReverseIterator, + class ConstReverseIterator, + + class IteratorToBaseConverter = ::boost::mpl::na, + class IteratorFromBaseConverter = ::boost::mpl::na, + class ReverseIteratorFromBaseConverter = ::boost::mpl::na, + class ValueToBaseConverter = ::boost::mpl::na, + class ValueFromBaseConverter = ::boost::mpl::na, + + class FunctorsFromDerivedClasses = mpl::vector<> +> +class vector_map_adaptor : + + public vector_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + > +{ + typedef vector_adaptor + < + Base, + Iterator, ConstIterator, ReverseIterator, ConstReverseIterator, + IteratorToBaseConverter, IteratorFromBaseConverter, + ReverseIteratorFromBaseConverter, + ValueToBaseConverter, ValueFromBaseConverter, + FunctorsFromDerivedClasses + + > base_; + + // MetaData ------------------------------------------------------------- + + public: + + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type key_type; + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type; + + // Access ----------------------------------------------------------------- + + public: + + vector_map_adaptor() {} + + explicit vector_map_adaptor(Base & c) : + base_(c) {} + + protected: + + typedef vector_map_adaptor vector_map_adaptor_; + +}; + + +} // namespace container_adaptor +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP + diff --git a/thirdparty/boost/bimap/detail/bimap_core.hpp b/thirdparty/boost/bimap/detail/bimap_core.hpp new file mode 100644 index 0000000..b515049 --- /dev/null +++ b/thirdparty/boost/bimap/detail/bimap_core.hpp @@ -0,0 +1,520 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/bimap_core.hpp +/// \brief Bimap base definition. + +#ifndef BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP +#define BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +// Boost.MultiIndex +#include +#include + +// Boost.Bimap +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace bimaps { + +/// \brief Library details + +namespace detail { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Type > +struct get_value_type +{ + typedef BOOST_DEDUCED_TYPENAME Type::value_type type; +}; + +struct independent_index_tag {}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +/// \brief Base for the bimap class. +/** + + +See also bimap. + **/ + + +template< class LeftSetType, class RightSetType, class AP1, class AP2, class AP3 > +class bimap_core +{ + // Manage bimap key instantiation + // -------------------------------------------------------------------- + public: + + typedef BOOST_DEDUCED_TYPENAME manage_bimap_key + < + LeftSetType + + >::type left_set_type; + + typedef BOOST_DEDUCED_TYPENAME manage_bimap_key + < + RightSetType + + >::type right_set_type; + + + private: + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::default_tagged + < + BOOST_DEDUCED_TYPENAME left_set_type::user_type, + ::boost::bimaps::relation::member_at::left + + >::type left_tagged_type; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::default_tagged + < + BOOST_DEDUCED_TYPENAME right_set_type::user_type, + ::boost::bimaps::relation::member_at::right + + >::type right_tagged_type; + + public: + + //@{ + + typedef BOOST_DEDUCED_TYPENAME left_tagged_type::tag left_tag; + typedef BOOST_DEDUCED_TYPENAME right_tagged_type::tag right_tag; + + //@} + + //@{ + + typedef BOOST_DEDUCED_TYPENAME left_set_type::value_type left_key_type; + typedef BOOST_DEDUCED_TYPENAME right_set_type::value_type right_key_type; + + //@} + + //@{ + + typedef right_key_type left_data_type; + typedef left_key_type right_data_type; + + //@} + + // Manage the additional parameters + // -------------------------------------------------------------------- + private: + + typedef BOOST_DEDUCED_TYPENAME manage_additional_parameters::type parameters; + + /// \brief Relation type stored by the bimap. + // -------------------------------------------------------------------- + public: + + typedef ::boost::bimaps::relation::mutant_relation + < + + ::boost::bimaps::tags::tagged< + BOOST_DEDUCED_TYPENAME mpl::if_< + mpl::and_ + < + BOOST_DEDUCED_TYPENAME left_set_type::mutable_key, + BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation::left_mutable_key + >, + // { + left_key_type, + // } + // else + // { + BOOST_DEDUCED_TYPENAME ::boost::add_const< left_key_type >::type + // } + + >::type, + left_tag + >, + + ::boost::bimaps::tags::tagged< + BOOST_DEDUCED_TYPENAME mpl::if_< + mpl::and_ + < + BOOST_DEDUCED_TYPENAME right_set_type::mutable_key, + BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation::right_mutable_key + >, + // { + right_key_type, + // } + // else + // { + BOOST_DEDUCED_TYPENAME ::boost::add_const< right_key_type >::type + // } + + >::type, + right_tag + >, + + // It is ::boost::mpl::na if no info_hook was included + BOOST_DEDUCED_TYPENAME parameters::additional_info, + + // Force mutable keys + true + + > relation; + + //@{ + + typedef BOOST_DEDUCED_TYPENAME relation::left_pair left_value_type; + typedef BOOST_DEDUCED_TYPENAME relation::right_pair right_value_type; + + //@} + + // Bind the member of the relation, so multi_index can manage them + // -------------------------------------------------------------------- + private: + + typedef BOOST_DEDUCED_TYPENAME relation::storage_base relation_storage_base; + + typedef BOOST_MULTI_INDEX_MEMBER(relation_storage_base, left_key_type, left) + left_member_extractor; + + typedef BOOST_MULTI_INDEX_MEMBER(relation_storage_base,right_key_type,right) + right_member_extractor; + + // The core indices are somewhat complicated to calculate, because they + // can be zero, one, two or three indices, depending on the use of + // {side}_based set type of relations and unconstrained_set_of and + // unconstrained_set_of_relation specifications. + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >, + // { + mpl::vector<>, + // } + // else + // { + mpl::vector + < + BOOST_DEDUCED_TYPENAME left_set_type:: + BOOST_NESTED_TEMPLATE index_bind + < + left_member_extractor, + left_tag + + >::type + > + // } + >::type left_core_indices; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >, + // { + left_core_indices, + // } + // else + // { + BOOST_DEDUCED_TYPENAME mpl::push_front + < + left_core_indices, + + BOOST_DEDUCED_TYPENAME right_set_type:: + BOOST_NESTED_TEMPLATE index_bind + < + right_member_extractor, + right_tag + + >::type + + >::type + // } + >::type basic_core_indices; + + // If it is based either on the left or on the right, then only the side + // indices are needed. But the set type of the relation can be completely + // diferent from the one used for the sides in wich case we have to add yet + // another index to the core. + + // TODO + // If all the set types are unsconstrained there must be readable compile + // time error. + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + + is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, left_based >, + // { + ::boost::bimaps::tags::tagged< left_set_type, left_tag >, + // } + /* else */ BOOST_DEDUCED_TYPENAME mpl::if_< + is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, right_based >, + // { + ::boost::bimaps::tags::tagged< right_set_type, right_tag >, + // } + // else + // { + tags::tagged + < + BOOST_DEDUCED_TYPENAME parameters:: + set_type_of_relation::BOOST_NESTED_TEMPLATE bind_to + < + relation + + >::type, + independent_index_tag + > + // } + >::type + >::type tagged_set_of_relation_type; + + protected: + + typedef BOOST_DEDUCED_TYPENAME tagged_set_of_relation_type::tag + relation_set_tag; + + typedef BOOST_DEDUCED_TYPENAME tagged_set_of_relation_type::value_type + relation_set_type_of; + + // Logic tags + // This is a necesary extra level of indirection to allow unconstrained + // sets to be plug in the design. The bimap constructors use this logic + // tags. + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >, + + independent_index_tag, + right_tag + + >::type, + + left_tag + + >::type logic_left_tag; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >, + + independent_index_tag, + left_tag + + >::type, + + right_tag + + >::type logic_right_tag; + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + is_same< relation_set_tag, independent_index_tag >, + + BOOST_DEDUCED_TYPENAME mpl::if_< + ::boost::bimaps::detail:: + is_unconstrained_set_of< relation_set_type_of >, + + logic_left_tag, + independent_index_tag + + >::type, + + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, left_based >, + + logic_left_tag, + logic_right_tag + + >::type + + >::type logic_relation_set_tag; + + private: + + typedef BOOST_DEDUCED_TYPENAME mpl::if_< + mpl::and_< is_same< relation_set_tag, independent_index_tag >, + mpl::not_< + ::boost::bimaps::detail:: + is_unconstrained_set_of< relation_set_type_of > + > + >, + // { + BOOST_DEDUCED_TYPENAME mpl::push_front + < + basic_core_indices, + + BOOST_DEDUCED_TYPENAME relation_set_type_of:: + BOOST_NESTED_TEMPLATE index_bind + < + ::boost::bimaps::relation::support::both_keys_extractor, + independent_index_tag + + >::type + + >::type, + // } + // else + // { + basic_core_indices + // } + + >::type complete_core_indices; + + struct core_indices : public complete_core_indices {}; + + // Define the core using compute_index_type to translate the + // set type to an multi-index specification + // -------------------------------------------------------------------- + public: + + typedef multi_index::multi_index_container + < + relation, + core_indices, + BOOST_DEDUCED_TYPENAME parameters::allocator:: + BOOST_NESTED_TEMPLATE rebind::other + + > core_type; + + // Core metadata + // -------------------------------------------------------------------- + public: + + typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index:: + index::type left_index; + + typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index:: + index::type right_index; + + typedef BOOST_DEDUCED_TYPENAME left_index::iterator left_core_iterator; + typedef BOOST_DEDUCED_TYPENAME left_index::const_iterator left_core_const_iterator; + + typedef BOOST_DEDUCED_TYPENAME right_index::iterator right_core_iterator; + typedef BOOST_DEDUCED_TYPENAME right_index::const_iterator right_core_const_iterator; + + // Map by {side} iterator metadata + // -------------------------------------------------------------------- + public: + + //@{ + + typedef ::boost::bimaps::detail::map_view_iterator + < + left_tag, + relation, + left_core_iterator + + > left_iterator; + + typedef ::boost::bimaps::detail::map_view_iterator + < + right_tag, + relation, + right_core_iterator + + > right_iterator; + + //@} + + //@{ + + typedef ::boost::bimaps::detail::const_map_view_iterator + < + left_tag, + relation, + left_core_const_iterator + + > left_const_iterator; + + typedef ::boost::bimaps::detail::const_map_view_iterator + < + right_tag, + relation, + right_core_const_iterator + + > right_const_iterator; + + //@} + + // Relation set view + + typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index::index + < + core_type, logic_relation_set_tag + + >::type relation_set_core_index; + + typedef BOOST_DEDUCED_TYPENAME relation_set_type_of:: + BOOST_NESTED_TEMPLATE set_view_bind + < + relation_set_core_index + + >::type relation_set; + + public: + + typedef bimap_core bimap_core_; +}; + +// Two auxiliar metafunctions to compute the map view types +// The map view type can not be computed inside the bimap core because a +// they need the bimap core to be parsed first. + +template< class BimapBaseType > +struct left_map_view_type +{ + typedef BOOST_DEDUCED_TYPENAME BimapBaseType::left_set_type left_set_type; + typedef BOOST_DEDUCED_TYPENAME + left_set_type::BOOST_NESTED_TEMPLATE map_view_bind< + BOOST_DEDUCED_TYPENAME BimapBaseType::left_tag, BimapBaseType + >::type type; +}; + +template< class BimapBaseType > +struct right_map_view_type +{ + typedef BOOST_DEDUCED_TYPENAME BimapBaseType::right_set_type right_set_type; + typedef BOOST_DEDUCED_TYPENAME + right_set_type::BOOST_NESTED_TEMPLATE map_view_bind< + BOOST_DEDUCED_TYPENAME BimapBaseType::right_tag, BimapBaseType + >::type type; +}; + +} // namespace detail +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP diff --git a/thirdparty/boost/bimap/detail/concept_tags.hpp b/thirdparty/boost/bimap/detail/concept_tags.hpp new file mode 100644 index 0000000..cd20e15 --- /dev/null +++ b/thirdparty/boost/bimap/detail/concept_tags.hpp @@ -0,0 +1,97 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/concept_tags.hpp +/// \brief Bimap tags and concepts + +#ifndef BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP +#define BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace detail { + +/// \brief Tag of {SetType}_of definition classes +/** +The {SetType}_of classes are derived from this class so it is easy to construct +metafunctions. For example now is easy to create a is_set_type_of metafunction. + **/ + +struct set_type_of_tag {}; + +/// \brief Tag of {SetType}_of_relation defition classes + +struct set_type_of_relation_tag {}; + +/// \brief Tag of {Side}_based identifiers + +struct side_based_tag : set_type_of_relation_tag {}; + +} // namespace detail + + +/** \struct boost::bimaps::left_based + \brief Tag to indicate that the main view will be based on the left side. + +This is convenient because the multi-index core will be more efficient. +If possible use this options or the right based one. + +See also right_based. + **/ + +/** \struct boost::bimaps::right_based + \brief Tag to indicate that the main view will be based on the right side. + +This is convenient because the multi-index core will be more efficient. +If possible use this options or the right based one. + +See also left_based. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +struct left_based : ::boost::bimaps::detail::side_based_tag +{ + // I run into troubles if I do not define bind for side based tags. + // Maybe a more coherent way of binding the relation can be developped. + template< class Relation > struct bind_to { typedef void type; }; + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + +struct right_based : ::boost::bimaps::detail::side_based_tag +{ + // I run into troubles if I do not define bind for side based tags. + // Maybe a more coherent way of binding the relation can be developped. + template< class Relation > struct bind_to { typedef void type; }; + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +typedef mpl::_ _relation; + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP + diff --git a/thirdparty/boost/bimap/detail/debug/static_error.hpp b/thirdparty/boost/bimap/detail/debug/static_error.hpp new file mode 100644 index 0000000..59a75af --- /dev/null +++ b/thirdparty/boost/bimap/detail/debug/static_error.hpp @@ -0,0 +1,36 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/debug/static_error.hpp +/// \brief Formatted compile time error + +#ifndef BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP +#define BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +// Easier way to call BOOST_MPL_ASSERT_MSG in class scope to generate +// a static error. +/*===========================================================================*/ +#define BOOST_BIMAP_STATIC_ERROR(MESSAGE,VARIABLES) \ + struct BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE) {}; \ + BOOST_MPL_ASSERT_MSG(false, \ + BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE), \ + VARIABLES) +/*===========================================================================*/ + + + +#endif // BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP diff --git a/thirdparty/boost/bimap/detail/generate_index_binder.hpp b/thirdparty/boost/bimap/detail/generate_index_binder.hpp new file mode 100644 index 0000000..1ac5b59 --- /dev/null +++ b/thirdparty/boost/bimap/detail/generate_index_binder.hpp @@ -0,0 +1,125 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/generate_index_binder.hpp +/// \brief Define macros to help building the set type of definitions + + +#ifndef BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP +#define BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP( \ + \ + MULTI_INDEX_TYPE \ + \ +) \ + \ +template< class KeyExtractor, class Tag > \ +struct index_bind \ +{ \ + typedef MULTI_INDEX_TYPE \ + < \ + multi_index::tag< Tag >, \ + KeyExtractor \ + \ + > type; \ +}; +/*===========================================================================*/ + + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_INDEX_BINDER_1CP( \ + \ + MULTI_INDEX_TYPE, \ + CONFIG_PARAMETER \ + \ +) \ + \ +template< class KeyExtractor, class Tag > \ +struct index_bind \ +{ \ + typedef MULTI_INDEX_TYPE \ + < \ + multi_index::tag< Tag >, \ + KeyExtractor, \ + CONFIG_PARAMETER \ + \ + > type; \ +}; +/*===========================================================================*/ + + + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_INDEX_BINDER_2CP( \ + \ + MULTI_INDEX_TYPE, \ + CONFIG_PARAMETER_1, \ + CONFIG_PARAMETER_2 \ +) \ + \ +template< class KeyExtractor, class Tag > \ +struct index_bind \ +{ \ + typedef MULTI_INDEX_TYPE \ + < \ + multi_index::tag< Tag >, \ + KeyExtractor, \ + CONFIG_PARAMETER_1, \ + CONFIG_PARAMETER_2 \ + \ + > type; \ + \ +}; +/*===========================================================================*/ + + +// This is a special registration to allow sequenced and random access indices +// to play along smoothly with the other index types. + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP_NO_EXTRACTOR( \ + \ + MULTI_INDEX_TYPE \ + \ +) \ + \ +template< class KeyExtractor, class Tag > \ +struct index_bind \ +{ \ + typedef MULTI_INDEX_TYPE< multi_index::tag< Tag > > type; \ +}; +/*===========================================================================*/ + + +// This is yet another special registration to allow unconstrained sets +// to play along smoothly with the other index types. + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_INDEX_BINDER_FAKE \ + \ +template< class KeyExtractor, class Tag > \ +struct index_bind \ +{ \ + typedef void type; \ +}; \ +/*===========================================================================*/ + +#endif // BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP diff --git a/thirdparty/boost/bimap/detail/generate_relation_binder.hpp b/thirdparty/boost/bimap/detail/generate_relation_binder.hpp new file mode 100644 index 0000000..f3add9e --- /dev/null +++ b/thirdparty/boost/bimap/detail/generate_relation_binder.hpp @@ -0,0 +1,88 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/generate_relation_binder.hpp +/// \brief Define macros to help building the set type of definitions + +#ifndef BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP +#define BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP( \ + \ + SET_TYPE_OF \ + ) \ + \ + template< class Relation > \ + struct bind_to \ + { \ + typedef SET_TYPE_OF type; \ + \ + }; +/*===========================================================================*/ + + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_RELATION_BINDER_1CP( \ + \ + SET_TYPE_OF, \ + CP1 \ + ) \ + \ + template< class Relation > \ + struct bind_to \ + { \ + typedef SET_TYPE_OF \ + < \ + Relation, \ + BOOST_DEDUCED_TYPENAME mpl::apply::type \ + \ + > type; \ + \ + }; +/*===========================================================================*/ + + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_RELATION_BINDER_2CP( \ + \ + SET_TYPE_OF, \ + CP1, \ + CP2 \ + ) \ + \ + template< class Relation > \ + struct bind_to \ + { \ + typedef SET_TYPE_OF \ + < \ + Relation, \ + BOOST_DEDUCED_TYPENAME mpl::apply::type, \ + BOOST_DEDUCED_TYPENAME mpl::apply::type \ + \ + > type; \ + \ + }; +/*===========================================================================*/ + + + +#endif // BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP diff --git a/thirdparty/boost/bimap/detail/generate_view_binder.hpp b/thirdparty/boost/bimap/detail/generate_view_binder.hpp new file mode 100644 index 0000000..1442e5f --- /dev/null +++ b/thirdparty/boost/bimap/detail/generate_view_binder.hpp @@ -0,0 +1,58 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/generate_view_binder.hpp +/// \brief Define macros to help building the set type of definitions + +#ifndef BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP +#define BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( \ + \ + MAP_VIEW_TYPE \ + \ +) \ + \ +template< class Tag, class BimapType > \ +struct map_view_bind \ +{ \ + typedef MAP_VIEW_TYPE \ + < \ + Tag, \ + BimapType \ + \ + > type; \ +}; +/*===========================================================================*/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( \ + \ + SET_VIEW_TYPE \ + \ +) \ + \ +template< class IndexType > \ +struct set_view_bind \ +{ \ + typedef SET_VIEW_TYPE type; \ +}; +/*===========================================================================*/ + + +#endif // BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP diff --git a/thirdparty/boost/bimap/detail/is_set_type_of.hpp b/thirdparty/boost/bimap/detail/is_set_type_of.hpp new file mode 100644 index 0000000..109733c --- /dev/null +++ b/thirdparty/boost/bimap/detail/is_set_type_of.hpp @@ -0,0 +1,66 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/is_set_type_of.hpp +/// \brief Is set type of and is set type of relation metafunctions. + +#ifndef BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP +#define BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +/** \struct boost::bimaps::detail::is_set_type_of + +\brief Type trait to check if a class is a set_type_of specification + +\code +template< class Type > +struct is_set_type_of : {true_|false_} {}; +\endcode + **/ + +/** \struct boost::bimaps::detail::is_set_type_of_relation + +\brief Type trait to check if a class is a set_type_of_relation specification + +\code +template< class Type > +struct is_set_type_of_relation : {true_|false_} {}; +\endcode + + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace detail { + +template< class Type > +struct is_set_type_of : + is_base_of< set_type_of_tag, Type > {}; + +template< class Type > +struct is_set_type_of_relation : + is_base_of< set_type_of_relation_tag, Type > {}; + +} // namespace detail +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP + diff --git a/thirdparty/boost/bimap/detail/manage_additional_parameters.hpp b/thirdparty/boost/bimap/detail/manage_additional_parameters.hpp new file mode 100644 index 0000000..7947f76 --- /dev/null +++ b/thirdparty/boost/bimap/detail/manage_additional_parameters.hpp @@ -0,0 +1,243 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/manage_additional_parameters.hpp +/// \brief Utility class to extract the additional parameters from the template parameters. + +#ifndef BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP +#define BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +// Boost.MPL +#include +#include +#include +#include + +#include + +namespace boost { +namespace bimaps { + +template< class Type > +struct with_info +{ + typedef Type value_type; +}; + +namespace detail { + +/// \brief Metafunction to check if a given type is a data_hook specification. + +template< class Type > +struct is_with_info : ::boost::mpl::false_ {}; + +template< class ValueType > +struct is_with_info< with_info > : ::boost::mpl::true_ {}; + +/** \struct boost::bimaps::detail::manage_additional_parameters +\brief Utility class to extract the additional parameters from the template parameters. + +\code +template< class AP1, class AP2, class AP3 > +struct manage_additional_parameters +{ + struct parameters + { + typedef -unspecified- set_type_of_relation; + typedef -unspecified- data_hook; + typedef -unspecified- allocator; + }; + + typedef parameters type; +}; +\endcode + +See also bimap, bimap_core. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class AP1, class AP2, class AP3 > +struct manage_additional_parameters +{ + // (1) manage_additional_parameters< + // not_specified,not_specified,not_specified> + // + // set_type_of_relation: based on the left key type + // info_hook: no additional info + // allocator: default allocator + + struct case_NNN + { + typedef left_based set_type_of_relation; + typedef std::allocator allocator; + typedef ::boost::mpl::na additional_info; + }; + + // (2) manage_additional_parameters + // + // set_type_of_relation: based on the left key type + // info_hook: no additional info + // allocator: Allocator + + struct case_ANN + { + typedef left_based set_type_of_relation; + typedef AP1 allocator; + typedef ::boost::mpl::na additional_info; + }; + + // (3) manage_additional_parameters< + // SetOfRelationType,not_specified,not_specified> + // + // set_type_of_relation: SetTypeOfRelation + // info_hook: no additional info + // allocator: default allocator + + struct case_SNN + { + typedef AP1 set_type_of_relation; + typedef std::allocator allocator; + typedef ::boost::mpl::na additional_info; + }; + + // (4) manage_additional_parameters< + // SetTypeOfRelation,Allocator,not_specified> + // + // set_type_of_relation: SetTypeOfRelation + // info_hook: no additional info + // allocator: Allocator + + struct case_SAN + { + typedef AP1 set_type_of_relation; + typedef AP2 allocator; + typedef ::boost::mpl::na additional_info; + }; + + // (5) manage_additional_parameters + // + // set_type_of_relation: based on the left key type + // info_hook: InfoToHook + // allocator: default allocator + + struct case_HNN + { + typedef left_based set_type_of_relation; + typedef std::allocator allocator; + typedef BOOST_DEDUCED_TYPENAME AP1::value_type additional_info; + }; + + // (6) manage_additional_parameters< + // SetTypeOfRelation,InfoToHook,not_specified> + // + // set_type_of_relation: SetTypeOfRelation + // info_hook: InfoToHook + // allocator: default allocator + + struct case_SHN + { + typedef AP1 set_type_of_relation; + typedef std::allocator allocator; + typedef BOOST_DEDUCED_TYPENAME AP2::value_type additional_info; + }; + + // (7) manage_additional_parameters< + // DataToHook,Allocator,not_specified> + // + // set_type_of_relation: SetTypeOfRelation + // info_hook: InfoToHook + // allocator: default allocator + + struct case_HAN + { + typedef left_based set_type_of_relation; + typedef AP2 allocator; + typedef BOOST_DEDUCED_TYPENAME AP1::value_type additional_info; + }; + + // (8) manage_additional_parameters< + // SetTypeOfRelation,DataToHook,Allocator> + // + // set_type_of_relation: SetTypeOfRelation + // info_hook: InfoToHook + // allocator: Allocator + + struct case_SHA + { + typedef AP1 set_type_of_relation; + typedef AP2 allocator; + typedef BOOST_DEDUCED_TYPENAME AP2::value_type additional_info; + }; + + // Some annidated mpl::if_ and we are done! + + typedef BOOST_DEDUCED_TYPENAME mpl::if_ + < + ::boost::mpl::is_na, + case_NNN, // (1) + BOOST_DEDUCED_TYPENAME mpl::if_ + < + ::boost::mpl::is_na, + BOOST_DEDUCED_TYPENAME mpl::if_ + < + is_set_type_of_relation, + case_SNN, // (3) + BOOST_DEDUCED_TYPENAME mpl::if_ + < + is_with_info, + case_HNN, // (5) + case_ANN // (2) + + >::type + + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_ + < + ::boost::mpl::is_na, + BOOST_DEDUCED_TYPENAME mpl::if_ + < + is_with_info, + case_HAN, // (7) + BOOST_DEDUCED_TYPENAME mpl::if_ + < + is_with_info, + case_SHN, // (6) + case_SAN // (4) + + >::type + + >::type, + + case_SHA // (8) + + >::type + + >::type + + >::type type; + +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +} // namespace detail +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP + diff --git a/thirdparty/boost/bimap/detail/manage_bimap_key.hpp b/thirdparty/boost/bimap/detail/manage_bimap_key.hpp new file mode 100644 index 0000000..95bcdd7 --- /dev/null +++ b/thirdparty/boost/bimap/detail/manage_bimap_key.hpp @@ -0,0 +1,84 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/manage_bimap_key.hpp +/// \brief Utility class to manage the set types of a bimap. + +#ifndef BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP +#define BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#include + +#include + +namespace boost { +namespace bimaps { +namespace detail { + +/** \struct boost::bimaps::detail::manage_bimap_key +\brief Metafunction to manage the set types of a bimap. + +\code +template< class Type > +struct manage_bimap_key +{ + typedef -SetType- type; +} +\endcode + +See also bimap, bimap_core. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Type > +struct manage_bimap_key +{ + +typedef BOOST_DEDUCED_TYPENAME + + mpl::eval_if< BOOST_DEDUCED_TYPENAME is_set_type_of< Type >::type, + // { + mpl::identity< Type >, + // } + // else + // { + // Default it to a set + mpl::identity< set_of< Type > > + // } + + >::type set_type; + + // Returns set_type and evaluate the concept_checked_type + + typedef BOOST_DEDUCED_TYPENAME mpl::if_c< true, set_type, + BOOST_DEDUCED_TYPENAME set_type::lazy_concept_checked::type + >::type type; +}; + + + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +} // namespace detail +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP + + diff --git a/thirdparty/boost/bimap/detail/map_view_base.hpp b/thirdparty/boost/bimap/detail/map_view_base.hpp new file mode 100644 index 0000000..ee70931 --- /dev/null +++ b/thirdparty/boost/bimap/detail/map_view_base.hpp @@ -0,0 +1,552 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/map_view_base.hpp +/// \brief Helper base for the construction of the bimap views types. + +#ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP +#define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { + +namespace detail { + + +// The next macro can be converted in a metafunctor to gain code robustness. +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( \ + CONTAINER_ADAPTOR, TAG,BIMAP, OTHER_ITER, CONST_OTHER_ITER \ +) \ +::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \ +< \ + BOOST_DEDUCED_TYPENAME BIMAP::core_type:: \ + BOOST_NESTED_TEMPLATE index::type, \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + iterator_type_by::type, \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + const_iterator_type_by::type, \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + OTHER_ITER::type, \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + CONST_OTHER_ITER::type, \ + ::boost::bimaps::container_adaptor::support::iterator_facade_to_base \ + < \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + iterator_type_by::type, \ + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ + const_iterator_type_by::type \ + \ + >, \ + ::boost::mpl::na, \ + ::boost::mpl::na, \ + ::boost::bimaps::relation::detail:: \ + pair_to_relation_functor, \ + ::boost::bimaps::relation::support:: \ + get_pair_functor \ +> +/*===========================================================================*/ + + +#if defined(BOOST_MSVC) +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \ + typedef ::boost::bimaps::detail::map_view_base< \ + TYPE,TAG,BIMAP > friend_map_view_base; \ + friend class friend_map_view_base; +/*===========================================================================*/ +#else +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \ + friend class ::boost::bimaps::detail::map_view_base< \ + TYPE,TAG,BIMAP >; +/*===========================================================================*/ +#endif + + +/// \brief Common base for map views. + +template< class Derived, class Tag, class BimapType> +class map_view_base +{ + typedef ::boost::bimaps::container_adaptor::support:: + iterator_facade_to_base< + + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type, + + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type + + > iterator_to_base_; + + typedef ::boost::bimaps::relation::detail:: + pair_to_relation_functor value_to_base_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + key_type_by::type key_type_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + data_type_by::type data_type_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type value_type_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type iterator_; + + public: + + bool replace(iterator_ position, const value_type_ & x) + { + return derived().base().replace( + derived().template functor()(position), + derived().template functor()(x) + ); + } + + template< class CompatibleKey > + bool replace_key(iterator_ position, const CompatibleKey & k) + { + return derived().base().replace( + derived().template functor()(position), + derived().template functor()( + value_type_(k,position->second) + ) + ); + } + + template< class CompatibleData > + bool replace_data(iterator_ position, const CompatibleData & d) + { + return derived().base().replace( + derived().template functor()(position), + derived().template functor()( + value_type_(position->first,d) + ) + ); + } + + /* This function may be provided in the future + + template< class Modifier > + bool modify(iterator_ position, Modifier mod) + { + return derived().base().modify( + + derived().template functor()(position), + + ::boost::bimaps::detail::relation_modifier_adaptor + < + Modifier, + BOOST_DEDUCED_TYPENAME BimapType::relation, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + Tag, BOOST_DEDUCED_TYPENAME BimapType::relation + + >::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + opossite_tag::type, + BOOST_DEDUCED_TYPENAME BimapType::relation + + >::type + + >(mod) + ); + } + */ + + template< class Modifier > + bool modify_key(iterator_ position, Modifier mod) + { + return derived().base().modify_key( + derived().template functor()(position), mod + ); + } + + template< class Modifier > + bool modify_data(iterator_ position, Modifier mod) + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + opossite_tag::type, + BOOST_DEDUCED_TYPENAME BimapType::relation + + >::type data_extractor_; + + return derived().base().modify( + + derived().template functor()(position), + + // this may be replaced later by + // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) ) + + ::boost::bimaps::detail::unary_modifier_adaptor + < + Modifier, + BOOST_DEDUCED_TYPENAME BimapType::relation, + data_extractor_ + + >(mod) + ); + } + + protected: + + typedef map_view_base map_view_base_; + + private: + + // Curiously Recurring Template interface. + + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } +}; + + + + +template< class Derived, class Tag, class BimapType> +class mutable_data_unique_map_view_access +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + data_type_by::type data_type_; + + public: + + template< class CompatibleKey > + data_type_ & at(const CompatibleKey& k) + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type iterator; + + iterator iter = derived().find(k); + if( iter == derived().end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->second; + } + + template< class CompatibleKey > + const data_type_ & at(const CompatibleKey& k) const + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type const_iterator; + + const_iterator iter = derived().find(k); + if( iter == derived().end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->second; + } + + template< class CompatibleKey > + data_type_ & operator[](const CompatibleKey& k) + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type iterator; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + value_type_by::type value_type; + + iterator iter = derived().find(k); + if( iter == derived().end() ) + { + iter = derived().insert( value_type(k,data_type_()) ).first; + } + return iter->second; + } + + protected: + + typedef mutable_data_unique_map_view_access + mutable_data_unique_map_view_access_; + + private: + + // Curiously Recurring Template interface. + + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } +}; + + +template< class Derived, class Tag, class BimapType> +class non_mutable_data_unique_map_view_access +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + data_type_by::type data_type_; + + public: + + template< class CompatibleKey > + const data_type_ & at(const CompatibleKey& k) const + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type const_iterator; + + const_iterator iter = derived().find(k); + if( iter == derived().end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->second; + } + + template< class CompatibleKey > + data_type_ & operator[](const CompatibleKey& k) + { + BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived)); + } + + protected: + + typedef non_mutable_data_unique_map_view_access + non_mutable_data_unique_map_view_access_; + + private: + + // Curiously Recurring Template interface. + + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } +}; + + +template< class Derived, class Tag, class BimapType> +struct unique_map_view_access +{ + private: + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + value_type_by::type value_type; + + public: + typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_ + < + typename ::boost::is_const< + BOOST_DEDUCED_TYPENAME value_type::second_type >::type, + + non_mutable_data_unique_map_view_access, + mutable_data_unique_map_view_access + + >::type type; +}; + +// Map views specialize the following structs to provide to the bimap class +// the extra side typedefs (i.e. left_local_iterator for unordered_maps, +// right_range_type for maps) + +template< class MapView > +struct left_map_view_extra_typedefs {}; + +template< class MapView > +struct right_map_view_extra_typedefs {}; + +} // namespace detail + +// This function is already part of Boost.Lambda. +// They may be moved to Boost.Utility. + +template inline const T& make_const(const T& t) { return t; } + +} // namespace bimaps +} // namespace boost + + +// The following macros avoids code duplication in map views +// Maybe this can be changed in the future using a scheme similar to +// the one used with map_view_base. + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE) \ + \ +typedef std::pair< \ + BOOST_DEDUCED_TYPENAME base_::iterator, \ + BOOST_DEDUCED_TYPENAME base_::iterator> range_type; \ + \ +typedef std::pair< \ + BOOST_DEDUCED_TYPENAME base_::const_iterator, \ + BOOST_DEDUCED_TYPENAME base_::const_iterator> const_range_type; \ + \ + \ +template< class LowerBounder, class UpperBounder> \ +range_type range(LowerBounder lower,UpperBounder upper) \ +{ \ + std::pair< \ + \ + BOOST_DEDUCED_TYPENAME BASE::base_type::iterator, \ + BOOST_DEDUCED_TYPENAME BASE::base_type::iterator \ + \ + > r( this->base().range(lower,upper) ); \ + \ + return range_type( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ + >() ( r.first ), \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ + >() ( r.second ) \ + ); \ +} \ + \ +template< class LowerBounder, class UpperBounder> \ +const_range_type range(LowerBounder lower,UpperBounder upper) const \ +{ \ + std::pair< \ + \ + BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator, \ + BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator \ + \ + > r( this->base().range(lower,upper) ); \ + \ + return const_range_type( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ + >() ( r.first ), \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ + >() ( r.second ) \ + ); \ +} +/*===========================================================================*/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE) \ + \ +template< class InputIterator > \ +void assign(InputIterator first,InputIterator last) \ +{ \ + this->clear(); \ + this->insert(this->end(),first,last); \ +} \ + \ +void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n, \ + const BOOST_DEDUCED_TYPENAME BASE::value_type& v) \ +{ \ + this->clear(); \ + for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n) \ + { \ + this->push_back(v); \ + } \ +} +/*===========================================================================*/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE) \ + \ +BOOST_DEDUCED_TYPENAME BASE::reference front() \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_from_base>() \ + ( \ + const_cast \ + < \ + BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \ + \ + > ( this->base().front() ) \ + ); \ +} \ + \ +BOOST_DEDUCED_TYPENAME BASE::reference back() \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_from_base>() \ + ( \ + const_cast \ + < \ + BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \ + \ + >( this->base().back() ) \ + ); \ +} \ + \ +BOOST_DEDUCED_TYPENAME BASE::const_reference front() const \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \ + ( \ + this->base().front() \ + ); \ +} \ + \ +BOOST_DEDUCED_TYPENAME BASE::const_reference back() const \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \ + ( \ + this->base().back() \ + ); \ +} +/*===========================================================================*/ + + +#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP diff --git a/thirdparty/boost/bimap/detail/map_view_iterator.hpp b/thirdparty/boost/bimap/detail/map_view_iterator.hpp new file mode 100644 index 0000000..10b62dd --- /dev/null +++ b/thirdparty/boost/bimap/detail/map_view_iterator.hpp @@ -0,0 +1,200 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/map_view_iterator.hpp +/// \brief Iterator adaptors from multi-index to bimap. + +#ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP +#define BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +// Boost +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace detail { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Tag, class Relation, class CoreIterator > struct map_view_iterator; + +template< class Tag, class Relation, class CoreIterator > +struct map_view_iterator_base +{ + typedef iterator_adaptor + < + map_view_iterator< Tag, Relation, CoreIterator >, + CoreIterator, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/** \brief Map View Iterator adaptor from multi index to bimap. + +This is class is based on transform iterator from Boost.Iterator that is +modified to allow serialization. It has been specialized for this +library, and EBO optimization was applied to the functor. + + **/ + +template< class Tag, class Relation, class CoreIterator > +struct map_view_iterator : public map_view_iterator_base::type +{ + typedef BOOST_DEDUCED_TYPENAME + map_view_iterator_base::type base_; + + public: + + map_view_iterator() {} + + map_view_iterator(CoreIterator const& iter) + : base_(iter) {} + + map_view_iterator(map_view_iterator const & iter) + : base_(iter.base()) {} + + BOOST_DEDUCED_TYPENAME base_::reference dereference() const + { + return ::boost::bimaps::relation::support::pair_by( + *const_cast( + &(*this->base()) + ) + ); + } + + private: + + friend class iterator_core_access; + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + // Serialization support + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class ::boost::serialization::access; + + template< class Archive > + void save(Archive & ar, const unsigned int version) const + { + ar << ::boost::serialization::make_nvp("mi_iterator",this->base()); + } + + template< class Archive > + void load(Archive & ar, const unsigned int version) + { + CoreIterator iter; + ar >> ::boost::serialization::make_nvp("mi_iterator",iter); + this->base_reference() = iter; + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Tag, class Relation, class CoreIterator > struct const_map_view_iterator; + +template< class Tag, class Relation, class CoreIterator > +struct const_map_view_iterator_base +{ + typedef iterator_adaptor + < + const_map_view_iterator< Tag, Relation, CoreIterator >, + CoreIterator, + const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +/** \brief Const Map View Iterator adaptor from multi index to bimap. + +See also map_view_iterator. + **/ + +template< class Tag, class Relation, class CoreIterator > +struct const_map_view_iterator : + + public const_map_view_iterator_base::type +{ + typedef BOOST_DEDUCED_TYPENAME + const_map_view_iterator_base::type base_; + + public: + + const_map_view_iterator() {} + + const_map_view_iterator(CoreIterator const& iter) + : base_(iter) {} + + const_map_view_iterator(const_map_view_iterator const & iter) + : base_(iter.base()) {} + + const_map_view_iterator(map_view_iterator i) + : base_(i.base()) {} + + BOOST_DEDUCED_TYPENAME base_::reference dereference() const + { + return ::boost::bimaps::relation::support::pair_by(*this->base()); + } + + private: + + friend class iterator_core_access; + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + // Serialization support + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class ::boost::serialization::access; + + template< class Archive > + void save(Archive & ar, const unsigned int version) const + { + ar << ::boost::serialization::make_nvp("mi_iterator",this->base()); + } + + template< class Archive > + void load(Archive & ar, const unsigned int version) + { + CoreIterator iter; + ar >> ::boost::serialization::make_nvp("mi_iterator",iter); + this->base_reference() = iter; + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + + +} // namespace detail +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP + + diff --git a/thirdparty/boost/bimap/detail/modifier_adaptor.hpp b/thirdparty/boost/bimap/detail/modifier_adaptor.hpp new file mode 100644 index 0000000..43f2f4b --- /dev/null +++ b/thirdparty/boost/bimap/detail/modifier_adaptor.hpp @@ -0,0 +1,89 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/modifier_adaptor.hpp +/// \brief A binary to unary functor relation modifier adaptor. + +#ifndef BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP +#define BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +namespace boost { +namespace bimaps { +namespace detail { + +/// \brief A binary to unary functor relation modifier adaptor. + +template +< + class Modifier, + class NewArgument, + class FirstExtractor, + class SecondExtractor +> +struct relation_modifier_adaptor : + public std::unary_function, + Modifier, + FirstExtractor, + SecondExtractor +{ + relation_modifier_adaptor( const Modifier & m ) : Modifier(m) {} + relation_modifier_adaptor( const Modifier & m, + const FirstExtractor & fe, + const SecondExtractor & se ) : + Modifier(m), FirstExtractor(fe), SecondExtractor(se) {} + + void operator()( NewArgument & x ) const + { + Modifier::operator()( + FirstExtractor ::operator()( x ), + SecondExtractor::operator()( x ) + ); + } +}; + +/// \brief A simple unary modifier adaptor. +// This modifier is equivalent to bind( Modifier, bind( Extractor, _1 ) ) +// It may be a good idea to start using Boost.Bind instead of it. + +template +< + class Modifier, + class NewArgument, + class Extractor +> +struct unary_modifier_adaptor : + public std::unary_function, + Modifier, + Extractor +{ + unary_modifier_adaptor( const Modifier & m ) : Modifier(m) {} + unary_modifier_adaptor( const Modifier & m, + const Extractor & fe) : + Modifier(m), Extractor(fe) {} + + void operator()( NewArgument & x ) const + { + Modifier::operator()( Extractor::operator()( x ) ); + } +}; + + +} // namespace detail +} // namespace bimap +} // namespace boost + + +#endif // BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP diff --git a/thirdparty/boost/bimap/detail/non_unique_views_helper.hpp b/thirdparty/boost/bimap/detail/non_unique_views_helper.hpp new file mode 100644 index 0000000..6ea05c0 --- /dev/null +++ b/thirdparty/boost/bimap/detail/non_unique_views_helper.hpp @@ -0,0 +1,71 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/non_unique_views_helper.hpp +/// \brief Details for non unique views + +#ifndef BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP +#define BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +/*===========================================================================*/ +#define BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS \ + \ +template \ +void insert(InputIterator iterBegin, InputIterator iterEnd) \ +{ \ + for( ; iterBegin != iterEnd ; ++iterBegin ) \ + { \ + this->base().insert( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_to_base>()( \ + BOOST_DEDUCED_TYPENAME base_::value_type(*iterBegin)) ); \ + } \ +} \ + \ +std::pair insert( \ + BOOST_DEDUCED_TYPENAME ::boost::call_traits< \ + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \ +{ \ + typedef BOOST_DEDUCED_TYPENAME base_::base_type::iterator base_iterator; \ + \ + std::pair< base_iterator, bool > r( \ + this->base().insert( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x) ) \ + ); \ + \ + return std::pair( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(r.first), \ + r.second \ + ); \ +} \ + \ +BOOST_DEDUCED_TYPENAME base_::iterator insert( \ + BOOST_DEDUCED_TYPENAME base_::iterator pos, \ + BOOST_DEDUCED_TYPENAME ::boost::call_traits< \ + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \ +{ \ + return this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( \ + this->base().insert( \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(pos), \ + this->template functor< \ + BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)) \ + ); \ +} +/*===========================================================================*/ + +#endif // BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP diff --git a/thirdparty/boost/bimap/detail/set_view_base.hpp b/thirdparty/boost/bimap/detail/set_view_base.hpp new file mode 100644 index 0000000..3db43f7 --- /dev/null +++ b/thirdparty/boost/bimap/detail/set_view_base.hpp @@ -0,0 +1,330 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/set_view_base.hpp +/// \brief Helper base for the construction of the bimap views types. + +#ifndef BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP +#define BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace detail { + +template< class Key, class Value, class KeyToBase > +class set_view_key_to_base +{ + public: + const Key operator()( const Value & v ) const + { + return keyToBase( v ); + } + private: + KeyToBase keyToBase; +}; + +template< class MutantRelationStorage, class KeyToBase > +class set_view_key_to_base +{ + typedef BOOST_DEDUCED_TYPENAME MutantRelationStorage::non_mutable_storage non_mutable_storage; + public: + const MutantRelationStorage & operator()( const non_mutable_storage & k ) const + { + return ::boost::bimaps::relation::detail::mutate(k); + } + const MutantRelationStorage & operator()( const MutantRelationStorage & k ) const + { + return k; + } +}; + + +// The next macro can be converted in a metafunctor to gain code robustness. +/*===========================================================================*/ +#define BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( \ + CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER \ +) \ +::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \ +< \ + CORE_INDEX, \ + ::boost::bimaps::detail:: \ + set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator >, \ + ::boost::bimaps::detail:: \ + const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator >, \ + ::boost::bimaps::detail:: \ + set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER >, \ + ::boost::bimaps::detail:: \ + const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >, \ + ::boost::bimaps::container_adaptor::support::iterator_facade_to_base \ + < \ + ::boost::bimaps::detail:: set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>, \ + ::boost::bimaps::detail::const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator> \ + \ + >, \ + ::boost::mpl::na, \ + ::boost::mpl::na, \ + ::boost::bimaps::relation::detail:: \ + get_mutable_relation_functor< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \ + ::boost::bimaps::relation::support:: \ + get_above_view_functor< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \ + ::boost::bimaps::detail::set_view_key_to_base< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::key_type, \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type, \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::key_from_value \ + > \ +> +/*===========================================================================*/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( \ + CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER \ +) \ +::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \ +< \ + CORE_INDEX, \ + ::boost::bimaps::detail:: \ + set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator >, \ + ::boost::bimaps::detail:: \ + const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator >, \ + ::boost::bimaps::detail:: \ + set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER >, \ + ::boost::bimaps::detail:: \ + const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >, \ + ::boost::bimaps::container_adaptor::support::iterator_facade_to_base \ + < \ + ::boost::bimaps::detail:: set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>, \ + ::boost::bimaps::detail::const_set_view_iterator< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator> \ + \ + >, \ + ::boost::mpl::na, \ + ::boost::mpl::na, \ + ::boost::bimaps::relation::detail:: \ + get_mutable_relation_functor< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \ + ::boost::bimaps::relation::support:: \ + get_above_view_functor< \ + BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type > \ +> +/*===========================================================================*/ + + +#if defined(BOOST_MSVC) +/*===========================================================================*/ +#define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE) \ + typedef ::boost::bimaps::detail::set_view_base< \ + TYPE< INDEX_TYPE >, INDEX_TYPE > template_class_friend; \ + friend class template_class_friend; +/*===========================================================================*/ +#else +/*===========================================================================*/ +#define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE) \ + friend class ::boost::bimaps::detail::set_view_base< \ + TYPE< INDEX_TYPE >, INDEX_TYPE >; +/*===========================================================================*/ +#endif + + +/// \brief Common base for set views. + +template< class Derived, class Index > +class set_view_base +{ + typedef ::boost::bimaps::container_adaptor::support:: + iterator_facade_to_base + < + ::boost::bimaps::detail:: + set_view_iterator, + ::boost::bimaps::detail:: + const_set_view_iterator + + > iterator_to_base_; + + typedef BOOST_DEDUCED_TYPENAME Index::value_type::left_value_type left_type_; + + typedef BOOST_DEDUCED_TYPENAME Index::value_type::right_value_type right_type_; + + typedef BOOST_DEDUCED_TYPENAME Index::value_type value_type_; + + typedef ::boost::bimaps::detail:: + set_view_iterator iterator_; + + public: + + bool replace(iterator_ position, + const value_type_ & x) + { + return derived().base().replace( + derived().template functor()(position),x + ); + } + + template< class CompatibleLeftType > + bool replace_left(iterator_ position, + const CompatibleLeftType & l) + { + return derived().base().replace( + derived().template functor()(position), + value_type_(l,position->right) + ); + } + + template< class CompatibleRightType > + bool replace_right(iterator_ position, + const CompatibleRightType & r) + { + return derived().base().replace( + derived().template functor()(position), + value_type_(position->left,r) + ); + } + + /* This function may be provided in the future + + template< class Modifier > + bool modify(iterator_ position, + Modifier mod) + { + return derived().base().modify( + + derived().template functor()(position), + + ::boost::bimaps::detail::relation_modifier_adaptor + < + Modifier, + BOOST_DEDUCED_TYPENAME Index::value_type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + ::boost::bimaps::relation::member_at::left, + BOOST_DEDUCED_TYPENAME Index::value_type + + >::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + ::boost::bimaps::relation::member_at::right, + BOOST_DEDUCED_TYPENAME Index::value_type + + >::type + + >(mod) + ); + } + */ + /* + template< class Modifier > + bool modify_left(iterator_ position, Modifier mod) + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right, + BOOST_DEDUCED_TYPENAME Index::value_type + + >::type left_data_extractor_; + + return derived().base().modify( + + derived().template functor()(position), + + // this may be replaced later by + // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) ) + + ::boost::bimaps::detail::unary_modifier_adaptor + < + Modifier, + BOOST_DEDUCED_TYPENAME Index::value_type, + left_data_extractor_ + + >(mod) + ); + } + + template< class Modifier > + bool modify_right(iterator_ position, Modifier mod) + { + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + data_extractor + < + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right, + BOOST_DEDUCED_TYPENAME Index::value_type + + >::type right_data_extractor_; + + return derived().base().modify( + + derived().template functor()(position), + + // this may be replaced later by + // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) ) + + ::boost::bimaps::detail::unary_modifier_adaptor + < + Modifier, + BOOST_DEDUCED_TYPENAME Index::value_type, + right_data_extractor_ + + >(mod) + ); + } + */ + protected: + + typedef set_view_base set_view_base_; + + private: + + // Curiously Recurring Template interface. + + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } +}; + + + +} // namespace detail +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP diff --git a/thirdparty/boost/bimap/detail/set_view_iterator.hpp b/thirdparty/boost/bimap/detail/set_view_iterator.hpp new file mode 100644 index 0000000..011e6ce --- /dev/null +++ b/thirdparty/boost/bimap/detail/set_view_iterator.hpp @@ -0,0 +1,193 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/set_view_iterator.hpp +/// \brief Iterator adaptors from multi-index to bimap. + +#ifndef BOOST_BIMAP_DETAIL_SET_VIEW_ITERATOR_HPP +#define BOOST_BIMAP_DETAIL_SET_VIEW_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +// Boost +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace detail { + + +/** \brief Set View Iterator adaptor from multi index to bimap. + +This is class is based on transform iterator from Boost.Iterator that is +modified to allow serialization. It has been specialized for this +library, and EBO optimization was applied to the functor. + + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class CoreIterator > struct set_view_iterator; + +template< class CoreIterator > +struct set_view_iterator_base +{ + typedef iterator_adaptor + < + set_view_iterator< CoreIterator >, + CoreIterator, + BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class CoreIterator > +struct set_view_iterator : public set_view_iterator_base::type +{ + typedef BOOST_DEDUCED_TYPENAME set_view_iterator_base::type base_; + + public: + + set_view_iterator() {} + + set_view_iterator(CoreIterator const& iter) + : base_(iter) {} + + set_view_iterator(set_view_iterator const & iter) + : base_(iter.base()) {} + + typename base_::reference dereference() const + { + return const_cast< + BOOST_DEDUCED_TYPENAME base_::base_type::value_type*>( + &(*this->base()) + )->get_view(); + } + + private: + + friend class iterator_core_access; + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + // Serialization support + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class ::boost::serialization::access; + + template< class Archive > + void save(Archive & ar, const unsigned int version) const + { + ar << ::boost::serialization::make_nvp("mi_iterator",this->base()); + } + + template< class Archive > + void load(Archive & ar, const unsigned int version) + { + CoreIterator iter; + ar >> ::boost::serialization::make_nvp("mi_iterator",iter); + this->base_reference() = iter; + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class CoreIterator > struct const_set_view_iterator; + +template< class CoreIterator > +struct const_set_view_iterator_base +{ + typedef iterator_adaptor + < + const_set_view_iterator< CoreIterator >, + CoreIterator, + const BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +/** \brief Const Set View Iterator adaptor from multi index to bimap. + +See also set_view_iterator. + **/ + +template< class CoreIterator > +struct const_set_view_iterator : public const_set_view_iterator_base::type +{ + typedef BOOST_DEDUCED_TYPENAME const_set_view_iterator_base::type base_; + + public: + + const_set_view_iterator() {} + + const_set_view_iterator(CoreIterator const& iter) + : base_(iter) {} + + const_set_view_iterator(const_set_view_iterator const & iter) + : base_(iter.base()) {} + + const_set_view_iterator(set_view_iterator i) + : base_(i.base()) {} + + BOOST_DEDUCED_TYPENAME base_::reference dereference() const + { + return this->base()->get_view(); + } + + private: + + friend class iterator_core_access; + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + // Serialization support + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class ::boost::serialization::access; + + template< class Archive > + void save(Archive & ar, const unsigned int version) const + { + ar << ::boost::serialization::make_nvp("mi_iterator",this->base()); + } + + template< class Archive > + void load(Archive & ar, const unsigned int version) + { + CoreIterator iter; + ar >> ::boost::serialization::make_nvp("mi_iterator",iter); + this->base_reference() = iter; + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + + +} // namespace detail +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP + + diff --git a/thirdparty/boost/bimap/detail/test/check_metadata.hpp b/thirdparty/boost/bimap/detail/test/check_metadata.hpp new file mode 100644 index 0000000..13ffa7e --- /dev/null +++ b/thirdparty/boost/bimap/detail/test/check_metadata.hpp @@ -0,0 +1,113 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_BIMAP_DETAIL_CHECK_METADATA_HPP +#define BOOST_BIMAP_DETAIL_CHECK_METADATA_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + + +// Easier way to call BOOST_MPL_ASSERT_MSG in class scope +/*===========================================================================*/ +#define BOOST_BIMAP_MPL_ASSERT_MSG_ACS(p1,p2,p3) \ + \ + struct p2 {}; \ + BOOST_MPL_ASSERT_MSG(p1,p2,p3); \ +/*===========================================================================*/ + + +// Build a descriptive name. +/*===========================================================================*/ +#define BOOST_BIMAP_WRONG_METADATA_MESSAGE( \ + \ + P_CLASS, \ + P_NAME, \ + P_CORRECT_TYPE \ + \ + ) \ + \ + BOOST_PP_CAT \ + ( \ + WRONG_METADATA__, \ + BOOST_PP_CAT \ + ( \ + P_CLASS, \ + BOOST_PP_CAT \ + ( \ + __AT__, \ + BOOST_PP_CAT \ + ( \ + P_NAME, \ + BOOST_PP_CAT \ + ( \ + __IS_DIFERENT_TO__, \ + P_CORRECT_TYPE \ + ) \ + ) \ + ) \ + ) \ + ) +/*===========================================================================*/ + + +// Check if the metadata have the correct type, and if not inform +// it with a useful compile time message. +/*===========================================================================*/ +#define BOOST_BIMAP_CHECK_METADATA( \ + \ + P_CLASS, \ + P_NAME, \ + P_CORRECT_TYPE \ + \ + ) \ + \ + BOOST_BIMAP_MPL_ASSERT_MSG_ACS \ + ( \ + ( \ + ::boost::is_same \ + < \ + P_CLASS::P_NAME, \ + P_CORRECT_TYPE \ + \ + >::value \ + ), \ + BOOST_BIMAP_WRONG_METADATA_MESSAGE \ + ( \ + P_CLASS, \ + P_NAME, \ + P_CORRECT_TYPE \ + ), \ + (P_CLASS::P_NAME,P_CORRECT_TYPE) \ + ) +/*===========================================================================*/ + + +// Just for autodocumment the test code +/*===========================================================================*/ +#define BOOST_BIMAP_TEST_STATIC_FUNCTION(NAME) \ + namespace NAME +/*===========================================================================*/ + + +// Just for autodocument the test code +/*===========================================================================*/ +#define BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION(NAME) +/*===========================================================================*/ + + + +#endif // BOOST_BIMAP_DETAIL_CHECK_METADATA_HPP + diff --git a/thirdparty/boost/bimap/detail/user_interface_config.hpp b/thirdparty/boost/bimap/detail/user_interface_config.hpp new file mode 100644 index 0000000..7c9887a --- /dev/null +++ b/thirdparty/boost/bimap/detail/user_interface_config.hpp @@ -0,0 +1,24 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file detail/user_interface_config.hpp +/// \brief General configuration directives + + +#ifndef BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP +#define BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#ifdef BOOST_BIMAP_DISABLE_SERIALIZATION + #define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION +#endif + +#endif // BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP diff --git a/thirdparty/boost/bimap/list_of.hpp b/thirdparty/boost/bimap/list_of.hpp new file mode 100644 index 0000000..b665d83 --- /dev/null +++ b/thirdparty/boost/bimap/list_of.hpp @@ -0,0 +1,181 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file list_of.hpp +/// \brief Include support for list constrains for the bimap container + +#ifndef BOOST_BIMAP_LIST_OF_HPP +#define BOOST_BIMAP_LIST_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + + +/// \brief Set Type Specification +/** +This struct is used to specify a set specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an std::list instantiation, except +that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the set +type specification, rather it is a container configuration +parameter. + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< list_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + list_of::index_bind + < + KeyExtractor, + Tag + + >::type, + + sequenced< tag, KeyExtractor > + + >::value +) + +typedef bimap +< + list_of, RightKeyType + +> bimap_with_left_type_as_list; + +BOOST_STATIC_ASSERT +( + is_same + < + list_of::map_view_bind + < + member_at::left, + bimap_with_left_type_as_list + + >::type, + list_map_view< member_at::left, bimap_with_left_type_as_list > + + >::value +) + +\endcode + +See also list_of_relation. + **/ + +template< class Type > +struct list_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef Type user_type; + + /// Type of the object that will be stored in the list + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + typedef list_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP_NO_EXTRACTOR( + + // binds to + multi_index::sequenced + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::list_map_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::list_set_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief List Of Relation Specification +/** +This struct is similar to list_of but it is bind logically to a +relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also list_of, is_set_type_of_relation. + **/ + +struct list_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP( + + // binds to + list_of + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_LIST_OF_HPP + diff --git a/thirdparty/boost/bimap/multiset_of.hpp b/thirdparty/boost/bimap/multiset_of.hpp new file mode 100644 index 0000000..f1461b8 --- /dev/null +++ b/thirdparty/boost/bimap/multiset_of.hpp @@ -0,0 +1,205 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file multiset_of.hpp +/// \brief Include support for multiset constrains for the bimap container + +#ifndef BOOST_BIMAP_MULTISET_OF_HPP +#define BOOST_BIMAP_MULTISET_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + +/// \brief Set Type Specification +/** +This struct is used to specify a multiset specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an std::set instantiation, except +that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the set +type specification, rather it is a container configuration +parameter. +The first parameter is the type of the objects in the multiset, +and the second one is a Functor that compares them. +Bimap binding metafunctions can be used with this class in +the following way: + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< multiset_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + compute_index_type + < + multiset_of, + KeyExtractor, + Tag + + >::type + , + ordered_nonunique< tag, KeyExtractor, KeyCompare > + + >::value +) + +typedef bimap +< + multiset_of, RightKeyType + +> bimap_with_left_type_as_multiset; + +BOOST_STATIC_ASSERT +( + is_same + < + compute_map_view_type + < + member_at::left, + bimap_with_left_type_as_multiset + + >::type, + multimap_view< member_at::left, bimap_with_left_type_as_multiset > + + >::value +) + +\endcode + +See also multiset_of_relation. + **/ + +template +< + class KeyType, + class KeyCompare = std::less< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type > +> +struct multiset_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef KeyType user_type; + + /// Type of the object that will be stored in the multiset + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + /// Functor that compare two keys + typedef KeyCompare key_compare; + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + BOOST_CLASS_REQUIRE4( key_compare, bool, value_type, value_type, + boost, BinaryFunctionConcept ); + + typedef multiset_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_1CP( + + // binds to + multi_index::ordered_non_unique, + + // with + key_compare + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::multimap_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::multiset_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief Set Of Relation Specification +/** +This struct is similar to multiset_of but it is bind logically to a +relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also multiset_of, is_set_type_of_relation. + **/ + +template< class KeyCompare = std::less< _relation > > +struct multiset_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + /// Functor that compare two keys + typedef KeyCompare key_compare; + + + BOOST_BIMAP_GENERATE_RELATION_BINDER_1CP( + + // binds to + multiset_of, + + // with + key_compare + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_MULTISET_OF_HPP diff --git a/thirdparty/boost/bimap/property_map/set_support.hpp b/thirdparty/boost/bimap/property_map/set_support.hpp new file mode 100644 index 0000000..0db5753 --- /dev/null +++ b/thirdparty/boost/bimap/property_map/set_support.hpp @@ -0,0 +1,55 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file property_map/set_support.hpp +/// \brief Support for the property map concept. + +#ifndef BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP +#define BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { + +template< class Tag, class Bimap > +struct property_traits< ::boost::bimaps::views::map_view > +{ + typedef BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support::data_type_by::type value_type; + typedef BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support:: key_type_by::type key_type; + + typedef readable_property_map_tag category; +}; + + +template< class Tag, class Bimap > +const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::data_type_by::type & + get(const ::boost::bimaps::views::map_view & m, + const BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support::key_type_by::type & key) +{ + return m.at(key); +} + +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP diff --git a/thirdparty/boost/bimap/property_map/unordered_set_support.hpp b/thirdparty/boost/bimap/property_map/unordered_set_support.hpp new file mode 100644 index 0000000..8a1bb7d --- /dev/null +++ b/thirdparty/boost/bimap/property_map/unordered_set_support.hpp @@ -0,0 +1,55 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file property_map/unordered_set_support.hpp +/// \brief Support for the property map concept. + +#ifndef BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP +#define BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { + +template< class Tag, class Bimap > +struct property_traits< ::boost::bimaps::views::unordered_map_view > +{ + typedef BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support::data_type_by::type value_type; + typedef BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support:: key_type_by::type key_type; + + typedef readable_property_map_tag category; +}; + + +template< class Tag, class Bimap > +const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::data_type_by::type & + get(const ::boost::bimaps::views::unordered_map_view & m, + const BOOST_DEDUCED_TYPENAME + ::boost::bimaps::support::key_type_by::type & key) +{ + return m.at(key); +} + +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP diff --git a/thirdparty/boost/bimap/relation/detail/access_builder.hpp b/thirdparty/boost/bimap/relation/detail/access_builder.hpp new file mode 100644 index 0000000..2358430 --- /dev/null +++ b/thirdparty/boost/bimap/relation/detail/access_builder.hpp @@ -0,0 +1,170 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/detail/access_builder.hpp +/// \brief Define macros to help building metafunctions + +#ifndef BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP +#define BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + + +/****************************************************************************** + BIMAP SYMMETRIC ACCESS RESULT OF +******************************************************************************* + +namespace result_of { + +template< class Tag, class SymmetricType > +struct NAME +{ + typedef -unspecified- type; +}; + +} // namespace result_of + +******************************************************************************/ + +/*===========================================================================*/ +#define BOOST_BIMAP_SYMMETRIC_ACCESS_RESULT_OF_BUILDER( \ + \ + NAME, \ + METAFUNCTION_BASE \ + ) \ + \ + namespace result_of { \ + \ + template< class Tag, class SymmetricType > \ + struct NAME \ + { \ + typedef BOOST_DEDUCED_TYPENAME METAFUNCTION_BASE \ + < \ + Tag,SymmetricType \ + \ + >::type value_type; \ + \ + typedef BOOST_DEDUCED_TYPENAME mpl::if_< is_const, \ + \ + BOOST_DEDUCED_TYPENAME call_traits::const_reference, \ + \ + BOOST_DEDUCED_TYPENAME call_traits::reference \ + \ + >::type type; \ + }; \ + \ + } +/*===========================================================================*/ + + + +/****************************************************************************** + BIMAP SYMMETRIC ACCESS IMPLEMENTATION +******************************************************************************* + +namespace detail { + +template< class Tag, class SymmetricType > +typename result_of::NAME::type + NAME( Tag , const Relation & ); + +} // namespace detail + +******************************************************************************/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_SYMMETRIC_ACCESS_IMPLEMENTATION_BUILDER( \ + \ + NAME, \ + TP_SYMMETRIC, \ + PARAMETER_NAME, \ + LEFT_BODY, \ + RIGHT_BODY \ + ) \ + \ + namespace detail { \ + \ + \ + \ + template< class TP_SYMMETRIC > \ + BOOST_DEDUCED_TYPENAME result_of::NAME \ + < \ + ::boost::bimaps::relation::member_at::left,TP_SYMMETRIC \ + \ + >::type \ + \ + NAME( ::boost::bimaps::relation::member_at::left, \ + TP_SYMMETRIC & PARAMETER_NAME ) \ + { \ + LEFT_BODY; \ + } \ + \ + template< class TP_SYMMETRIC > \ + BOOST_DEDUCED_TYPENAME result_of::NAME \ + < \ + ::boost::bimaps::relation::member_at::right,TP_SYMMETRIC \ + \ + >::type \ + \ + NAME( ::boost::bimaps::relation::member_at::right, \ + TP_SYMMETRIC & PARAMETER_NAME ) \ + { \ + RIGHT_BODY; \ + } \ + \ + } +/*===========================================================================*/ + + +/****************************************************************************** + BIMAP RELATION ACCESS INTERFACE +******************************************************************************* + +template< class Tag, class SymmetricType > +typename result_of::NAME::type + NAME( const SymmetricType & ); + +******************************************************************************/ + +/*===========================================================================*/ +#define BOOST_BIMAP_SYMMETRIC_ACCESS_INTERFACE_BUILDER( \ + \ + NAME \ + ) \ + \ + template< class Tag, class SymmetricType > \ + BOOST_DEDUCED_TYPENAME result_of::NAME::type \ + NAME( SymmetricType & s ) \ + { \ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: \ + member_with_tag \ + < \ + Tag,SymmetricType \ + \ + >::type member_at_tag; \ + \ + return detail::NAME(member_at_tag(),s); \ + } +/*===========================================================================*/ + + +#endif // BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP + diff --git a/thirdparty/boost/bimap/relation/detail/metadata_access_builder.hpp b/thirdparty/boost/bimap/relation/detail/metadata_access_builder.hpp new file mode 100644 index 0000000..d98e89a --- /dev/null +++ b/thirdparty/boost/bimap/relation/detail/metadata_access_builder.hpp @@ -0,0 +1,103 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/detail/metadata_access_builder.hpp +/// \brief Define macros to help building metafunctions + +#ifndef BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCESS_BUILDER_HPP +#define BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCESS_BUILDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + + + +/****************************************************************************** + BIMAP SYMMETRIC METADATA ACCESS INTERFACE +******************************************************************************* + +template< class Tag, class SymmetricType > +struct NAME +{ + typedef -unspecified- type; +}; + +******************************************************************************/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER( \ + \ + NAME, \ + METADATA_BY_LEFT, \ + METADATA_BY_RIGHT \ + ) \ + \ + template \ + < \ + class Tag, \ + class SymmetricType, \ + class Enable = void \ + > \ + struct NAME \ + { \ + BOOST_BIMAP_STATIC_ERROR( \ + BOOST_PP_CAT(NAME,_FAILURE), \ + (SymmetricType,Tag) \ + ); \ + }; \ + \ + template< class Tag, class SymmetricType > \ + struct NAME \ + < \ + Tag, SymmetricType, \ + BOOST_DEDUCED_TYPENAME enable_if \ + < \ + ::boost::bimaps::relation::support::is_tag_of_member_at_left \ + < \ + Tag, \ + SymmetricType \ + > \ + \ + >::type \ + > \ + { \ + typedef BOOST_DEDUCED_TYPENAME SymmetricType::METADATA_BY_LEFT type; \ + }; \ + \ + template< class Tag, class SymmetricType > \ + struct NAME \ + < \ + Tag, SymmetricType, \ + BOOST_DEDUCED_TYPENAME enable_if \ + < \ + ::boost::bimaps::relation::support::is_tag_of_member_at_right \ + < \ + Tag, \ + SymmetricType \ + > \ + \ + >::type \ + > \ + { \ + typedef BOOST_DEDUCED_TYPENAME SymmetricType::METADATA_BY_RIGHT type; \ + }; +/*===========================================================================*/ + + +#endif // BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCES_BUILDER_HPP + + diff --git a/thirdparty/boost/bimap/relation/detail/mutant.hpp b/thirdparty/boost/bimap/relation/detail/mutant.hpp new file mode 100644 index 0000000..a2a0e80 --- /dev/null +++ b/thirdparty/boost/bimap/relation/detail/mutant.hpp @@ -0,0 +1,83 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/detail/mutant.hpp +/// \brief Mutate functions to extract views of mutant classes. + +#ifndef BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP +#define BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace relation { + +/// \brief Relation details, mutant idiom and symmetrical metafunctions builders. + +namespace detail { + +//@{ +/// \brief Converts a mutant class to a view with zero overhead. +/** + +This function is a safe wrapper around reinterpret_cast. It checks at +compile time that the desired view is supported by the mutant class. +See also mutant, can_mutate_in. +\ingroup mutant_group + **/ + + +template< class View, class Type > +BOOST_DEDUCED_TYPENAME enable_if< mpl::not_< is_const< Type > >, + +View& + +>::type mutate( Type & m ) +{ + BOOST_MPL_ASSERT(( + ::boost::mpl::contains + )); + return *reinterpret_cast< View* >(addressof(m)); +} + +template< class View, class Type > +BOOST_DEDUCED_TYPENAME enable_if< is_const< Type >, + +const View& + +>::type mutate( Type & m ) +{ + BOOST_MPL_ASSERT(( + ::boost::mpl::contains + )); + return *reinterpret_cast< const View* >(addressof(m)); +} + +//@} + +} // namespace detail +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP + diff --git a/thirdparty/boost/bimap/relation/detail/static_access_builder.hpp b/thirdparty/boost/bimap/relation/detail/static_access_builder.hpp new file mode 100644 index 0000000..7630b4e --- /dev/null +++ b/thirdparty/boost/bimap/relation/detail/static_access_builder.hpp @@ -0,0 +1,105 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +/// \file relation/detail/static_access_builder.hpp +/// \brief Define macros to help building metafunctions + +#ifndef BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCESS_BUILDER_HPP +#define BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCESS_BUILDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + + + +/****************************************************************************** + BIMAP SYMMETRIC STATIC ACCESS INTERFACE +******************************************************************************* + +template< class Tag, class SYMETRIC_TYPE > +struct NAME +{ + -UNDEFINED BODY-; +}; + +******************************************************************************/ + + +/*===========================================================================*/ +#define BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER( \ + \ + NAME, \ + SYMMETRIC_TYPE, \ + LEFT_BODY, \ + RIGHT_BODY \ + ) \ + \ + template \ + < \ + class Tag, \ + class SYMMETRIC_TYPE, \ + class Enable = void \ + > \ + struct NAME \ + { \ + BOOST_BIMAP_STATIC_ERROR( \ + BOOST_PP_CAT(NAME,_FAILURE), \ + (SYMMETRIC_TYPE,Tag) \ + ); \ + }; \ + \ + template< class Tag, class SYMMETRIC_TYPE > \ + struct NAME \ + < \ + Tag, SYMMETRIC_TYPE, \ + BOOST_DEDUCED_TYPENAME enable_if \ + < \ + ::boost::bimaps::relation::support::is_tag_of_member_at_left \ + < \ + Tag, \ + SYMMETRIC_TYPE \ + > \ + \ + >::type \ + > \ + { \ + LEFT_BODY; \ + }; \ + \ + template< class Tag, class SYMMETRIC_TYPE > \ + struct NAME \ + < \ + Tag, SYMMETRIC_TYPE, \ + BOOST_DEDUCED_TYPENAME enable_if \ + < \ + ::boost::bimaps::relation::support::is_tag_of_member_at_right \ + < \ + Tag, \ + SYMMETRIC_TYPE \ + > \ + \ + >::type \ + > \ + { \ + RIGHT_BODY; \ + }; +/*===========================================================================*/ + + +#endif // BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCES_BUILDER_HPP + + diff --git a/thirdparty/boost/bimap/relation/detail/to_mutable_relation_functor.hpp b/thirdparty/boost/bimap/relation/detail/to_mutable_relation_functor.hpp new file mode 100644 index 0000000..19bc6ad --- /dev/null +++ b/thirdparty/boost/bimap/relation/detail/to_mutable_relation_functor.hpp @@ -0,0 +1,102 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/detail/to_mutable_relation_functor.hpp +/// \brief functors to convert types to mutable relations + +#ifndef BOOST_BIMAP_RELATION_DETAIL_TO_MUTABLE_RELATION_FUNCTOR_HPP +#define BOOST_BIMAP_RELATION_DETAIL_TO_MUTABLE_RELATION_FUNCTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace relation { +namespace detail { + +/// \brief Functor used in map views + +template< class Tag, class Relation > +struct pair_to_relation_functor +{ + const Relation + operator()(const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type & p) const + { + return Relation(p); + } +}; + +template< class Tag, class TA, class TB, class Info > +struct pair_to_relation_functor< + Tag,::boost::bimaps::relation::mutant_relation > +{ + typedef ::boost::bimaps::relation::mutant_relation Relation; + + Relation & + operator()( BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type & p ) const + { + return ::boost::bimaps::relation::detail::mutate(p); + } + + const Relation & + operator()( const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + pair_type_by::type & p) const + { + return ::boost::bimaps::relation::detail::mutate(p); + } +}; + + +/// \brief Used in set views + +template< class Relation > +struct get_mutable_relation_functor +{ + const Relation + operator()( const BOOST_DEDUCED_TYPENAME Relation::above_view & r ) const + { + return Relation(r); + } +}; + +template< class TA, class TB, class Info > +struct get_mutable_relation_functor< ::boost::bimaps::relation::mutant_relation > +{ + typedef ::boost::bimaps::relation::mutant_relation Relation; + + Relation & + operator()( BOOST_DEDUCED_TYPENAME Relation::above_view & r ) const + { + return ::boost::bimaps::relation::detail::mutate(r); + } + + const Relation & + operator()( const BOOST_DEDUCED_TYPENAME Relation::above_view & r ) const + { + return ::boost::bimaps::relation::detail::mutate(r); + } +}; + +} // namespace detail +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_DETAIL_TO_MUTABLE_RELATION_FUNCTOR_HPP + diff --git a/thirdparty/boost/bimap/relation/member_at.hpp b/thirdparty/boost/bimap/relation/member_at.hpp new file mode 100644 index 0000000..b4c7371 --- /dev/null +++ b/thirdparty/boost/bimap/relation/member_at.hpp @@ -0,0 +1,72 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/member_at.hpp +/// \brief Defines the tags for the member_at::side idiom + +#ifndef BOOST_BIMAP_RELATION_MEMBER_AT_HPP +#define BOOST_BIMAP_RELATION_MEMBER_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace relation { + +/// \brief member_at::side idiom to access relation values and types using metaprogramming. +/** + +This tags are used to specify which member you want to acces when using a metafunction over +a symmetrical type. The idea is to be able to write code like: + +\code +result_of::get::type data = get(rel); +\endcode + +The relation class supports this idiom even when the elements are tagged. This is useful +because a user can decide to start tagging in any moment of the development. + +See also member_with_tag, is_tag_of_member_at_left, is_tag_of_member_at_right, get +value_type_of, pair_by, pair_type_by. + +\ingroup relation_group + **/ +namespace member_at { + + /// \brief Member at left tag + /** + See also member_at, rigth. + **/ + + struct left {}; + + /// \brief Member at right tag + /** + See also member_at, left. + **/ + + struct right {}; + + /// \brief Member info tag + /** + See also member_at, left, right. + **/ + + struct info {}; + +} + +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_RELATION_MEMBER_AT_HPP diff --git a/thirdparty/boost/bimap/relation/mutant_relation.hpp b/thirdparty/boost/bimap/relation/mutant_relation.hpp new file mode 100644 index 0000000..8e5a205 --- /dev/null +++ b/thirdparty/boost/bimap/relation/mutant_relation.hpp @@ -0,0 +1,430 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/mutant_relation.hpp +/// \brief Defines the mutant_relation class + +#ifndef BOOST_BIMAP_RELATION_MUTANT_RELATION_HPP +#define BOOST_BIMAP_RELATION_MUTANT_RELATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +#include + +#include + +// Boost.Bimap +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace relation { + +namespace detail { + +// This class is included so structured_pair and mutant_relation share +// exactly the same class layout + +template< class LeftType, class RightType, bool force_mutable > +class relation_storage : + public symmetrical_base +{ + typedef symmetrical_base base_; + + typedef relation_storage storage_; + + public: + + typedef relation_storage non_mutable_storage; + + typedef ::boost::mpl::vector2 + < + relation_storage< LeftType, RightType, true >, + relation_storage< LeftType, RightType, false > + + > mutant_views; + + //@{ + /// data + BOOST_DEDUCED_TYPENAME base_::left_value_type left; + BOOST_DEDUCED_TYPENAME base_::right_value_type right; + //@} + + relation_storage() {} + + relation_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::left_value_type + >::param_type l, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::right_value_type + >::param_type r) + + : left(l), right(r) {} + + BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return left; } + const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return left; } + BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return right; } + const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return right; } +}; + + + +template< class TA, class TB, class Info, bool force_mutable > +class relation_info_hook : public + ::boost::bimaps::relation::detail::relation_storage +{ + typedef ::boost::bimaps::relation::detail:: + relation_storage base_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + default_tagged::type tagged_info_type; + + public: + typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type; + typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag; + + info_type info; + + protected: + + relation_info_hook() {} + + relation_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::left_value_type + >::param_type l, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::right_value_type + >::param_type r, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + info_type + >::param_type i = info_type() ) + + : base_(l,r), info(i) {} + + template< class Relation > + relation_info_hook( const Relation & rel ) : + base_(rel.left,rel.right), + info(rel.info) {} + + template< class Relation > + void change_to( const Relation & rel ) + { + base_::left = rel.left ; + base_::right = rel.right; + info = rel.info ; + } + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + template< class Archive > + void serialize(Archive & ar, const unsigned int version) + { + ar & ::boost::serialization::make_nvp("left" , base_::left ); + ar & ::boost::serialization::make_nvp("right", base_::right); + ar & ::boost::serialization::make_nvp("info" , info ); + } + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + +template< class TA, class TB, bool force_mutable> +class relation_info_hook : + public ::boost::bimaps::relation::detail::relation_storage +{ + typedef ::boost::bimaps::relation::detail:: + relation_storage base_; + + public: + typedef ::boost::mpl::na info_type; + typedef member_at::info info_tag; + + protected: + + relation_info_hook() {} + + relation_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::left_value_type + >::param_type l, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::right_value_type + >::param_type r) + + : base_(l,r) {} + + template< class Relation > + relation_info_hook( const Relation & rel ) : + base_(rel.left,rel.right) {} + + template< class Relation > + void change_to( const Relation & rel ) + { + base_::left = rel.left ; + base_::right = rel.right; + } + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + template< class Archive > + void serialize(Archive & ar, const unsigned int version) + { + ar & ::boost::serialization::make_nvp("left" , base_::left ); + ar & ::boost::serialization::make_nvp("right", base_::right); + } + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + + +} // namespace detail + +/// \brief Abstraction of a related pair of values, that extends the std::pair class. +/** +The mutant_relation is a mutant class. A mutant class can mutate +with zero overhead in other classes that are called views. +Each view has to be StorageCompatible with the base class +of the mutant. Note that all the views have the following +storage structure: + +\verbatim + __________ + | | + | TA | + |__________| + | | + | TB | + |__________| + +\endverbatim + +See also select_relation, standard_relation. +\ingroup relation_group + **/ + + +template< class TA, class TB, class Info = ::boost::mpl::na, bool force_mutable = false > +class mutant_relation : public + ::boost::bimaps::relation::detail:: + relation_info_hook +{ + typedef ::boost::bimaps::relation::detail:: + relation_info_hook base_; + + public: + + // We have to know the type of the base where the types are + // defined because Boost.MultiIndex requires it. + + typedef ::boost::bimaps::relation::detail:: + relation_storage storage_base; + + /// Above view, non mutable view of the relation + + typedef mutant_relation above_view; + + //@{ + /// A signature compatible std::pair that is a view of the relation. + + typedef structured_pair< TA, TB, Info, normal_layout > left_pair; + typedef structured_pair< TB, TA, Info, mirror_layout > right_pair; + //@} + + typedef ::boost::mpl::vector4 + < + left_pair, + right_pair, + + mutant_relation< TA, TB, Info, true >, + mutant_relation< TA, TB, Info, false > + + > mutant_views; + + mutant_relation() {} + + mutant_relation(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_:: left_value_type + >::param_type l, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::right_value_type + >::param_type r) : + base_(l,r) {} + + mutant_relation(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_:: left_value_type + >::param_type l, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::right_value_type + >::param_type r, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::info_type + >::param_type i) : + base_(l,r,i) {} + + mutant_relation(const mutant_relation & rel) : + base_(rel) {} + + mutant_relation(const mutant_relation & rel) : + base_(rel) {} + + // Operators + + template< bool FM > + mutant_relation& operator=(const mutant_relation & rel) + { + base_::change_to(rel); + return *this; + } + + // The following functions are redundant if you only consider this class. + // They are included to make easier the construction of the get and the + // pair_by metafunction. Remember that not all compiler supports the mutant + // idiom. + + left_pair & get_left_pair() + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + const left_pair & get_left_pair() const + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + right_pair & get_right_pair() + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + const right_pair & get_right_pair() const + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + above_view & get_view() + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + const above_view & get_view() const + { + return ::boost::bimaps::relation::detail::mutate(*this); + } + + template< class Tag > + const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + result_of::get::type + get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const + { + return ::boost::bimaps::relation::support::get(*this); + } + + template< class Tag > + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + result_of::get::type + get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + return ::boost::bimaps::relation::support::get(*this); + } + + #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION + + private: + friend class ::boost::serialization::access; + + template + void serialize(Archive & ar, const unsigned int version) + { + base_::serialize(ar,version); + } + + #endif // BOOST_BIMAP_DISABLE_SERIALIZATION +}; + +// hash value + +template< class FirstType, class SecondType, bool FM > +std::size_t hash_value(const detail::relation_storage & r) +{ + std::size_t seed = 0; + ::boost::hash_combine(seed, r. left ); + ::boost::hash_combine(seed, r.right ); + + return seed; +} + +// mutant_relation - mutant_relation + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator==(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ( ( a.left == b.left ) && + ( a.right == b.right ) ); +} + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator!=(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ! ( a == b ); +} + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator<(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ( ( a.left < b.left ) || + (( a.left == b.left ) && ( a.right < b.right ))); +} + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator<=(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ( ( a.left < b.left ) || + (( a.left == b.left ) && ( a.right <= b.right ))); +} + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator>(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ( ( a.left > b.left ) || + (( a.left == b.left ) && ( a.right > b.right ))); +} + +template< class FirstType, class SecondType, bool FM1, bool FM2 > +bool operator>=(const detail::relation_storage & a, + const detail::relation_storage & b) +{ + return ( ( a.left > b.left ) || + (( a.left == b.left ) && ( a.right >= b.right ))); +} + +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_MUTANT_RELATION_HPP + + + diff --git a/thirdparty/boost/bimap/relation/pair_layout.hpp b/thirdparty/boost/bimap/relation/pair_layout.hpp new file mode 100644 index 0000000..09d89b2 --- /dev/null +++ b/thirdparty/boost/bimap/relation/pair_layout.hpp @@ -0,0 +1,72 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/pair_layout.hpp +/// \brief Tags for pair layouts + +#ifndef BOOST_BIMAP_RELATION_PAIR_LAYOUT_HPP +#define BOOST_BIMAP_RELATION_PAIR_LAYOUT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace relation { + +//@{ + +/// \brief Tag for normal layout. ( A,B -> A,B ) + +struct normal_layout {}; + +/// \brief Tag for mirror layout. ( A,B -> B,A ) + +struct mirror_layout {}; + +//@} + +/** \struct boost::bimaps::relation::inverse_layout +\brief Metafunction to obtain the inverse of a layout. + +\code +template< class Layout > +struct inverse_layout +{ + typedef {InverseLayout} type; +}; +\endcode + +See also normal_layout, mirror_layout. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Layout > +struct inverse_layout +{ + typedef normal_layout type; +}; + +template<> +struct inverse_layout< normal_layout > +{ + typedef mirror_layout type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_RELATION_DETAIL_PAIR_LAYOUT_HPP + diff --git a/thirdparty/boost/bimap/relation/structured_pair.hpp b/thirdparty/boost/bimap/relation/structured_pair.hpp new file mode 100644 index 0000000..53c1618 --- /dev/null +++ b/thirdparty/boost/bimap/relation/structured_pair.hpp @@ -0,0 +1,508 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/structured_pair.hpp +/// \brief Defines the structured_pair class. + +#ifndef BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP +#define BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +namespace boost { +namespace bimaps { +namespace relation { + +namespace detail { + +/// \brief Storage definition of the left view of a mutant relation. +/** + +See also storage_finder, mirror_storage. + **/ + +template< class FirstType, class SecondType > +class normal_storage : + public symmetrical_base +{ + typedef symmetrical_base base_; + + public: + + typedef normal_storage storage_; + + typedef BOOST_DEDUCED_TYPENAME base_::left_value_type first_type; + typedef BOOST_DEDUCED_TYPENAME base_::right_value_type second_type; + + first_type first; + second_type second; + + normal_storage() {} + + normal_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + first_type >::param_type f, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + second_type>::param_type s) + + : first(f), second(s) {} + + BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return first; } + const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return first; } + BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return second; } + const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return second; } +}; + +/// \brief Storage definition of the right view of a mutant relation. +/** + +See also storage_finder, normal_storage. + **/ + +template< class FirstType, class SecondType > +class mirror_storage : + public symmetrical_base +{ + typedef symmetrical_base base_; + + public: + + typedef mirror_storage storage_; + + typedef BOOST_DEDUCED_TYPENAME base_::left_value_type second_type; + typedef BOOST_DEDUCED_TYPENAME base_::right_value_type first_type; + + second_type second; + first_type first; + + mirror_storage() {} + + mirror_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits::param_type f, + BOOST_DEDUCED_TYPENAME ::boost::call_traits::param_type s) + + : second(s), first(f) {} + + BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return second; } + const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return second; } + BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return first; } + const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return first; } +}; + +/** \struct boost::bimaps::relation::storage_finder +\brief Obtain the a storage with the correct layout. + +\code +template< class FirstType, class SecondType, class Layout > +struct storage_finder +{ + typedef {normal/mirror}_storage type; +}; +\endcode + +See also normal_storage, mirror_storage. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template +< + class FirstType, + class SecondType, + class Layout +> +struct storage_finder +{ + typedef normal_storage type; +}; + +template +< + class FirstType, + class SecondType +> +struct storage_finder +{ + typedef mirror_storage type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +template< class TA, class TB, class Info, class Layout > +class pair_info_hook : + public ::boost::bimaps::relation::detail::storage_finder::type +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder::type base_; + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + default_tagged::type tagged_info_type; + + public: + typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type; + typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag; + + info_type info; + + protected: + + pair_info_hook() {} + + pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::first_type + >::param_type f, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::second_type + >::param_type s, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + info_type + >::param_type i = info_type() ) + : base_(f,s), info(i) {} + + template< class Pair > + pair_info_hook( const Pair & p) : + base_(p.first,p.second), + info(p.info) {} + + template< class Pair > + void change_to( const Pair & p ) + { + base_::first = p.first ; + base_::second = p.second; + info = p.info ; + } + + void clear_info() + { + info = info_type(); + }; +}; + +template< class TA, class TB, class Layout> +class pair_info_hook : + public ::boost::bimaps::relation::detail::storage_finder::type +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder::type base_; + + public: + typedef ::boost::mpl::na info_type; + typedef member_at::info info_tag; + + protected: + + pair_info_hook() {} + + pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::first_type + >::param_type f, + BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::second_type + >::param_type s) + + : base_(f,s) {} + + template< class Pair > + pair_info_hook( const Pair & p ) : + base_(p.first,p.second) {} + + template< class Pair > + void change_to( const Pair & p ) + { + base_::first = p.first ; + base_::second = p.second; + } + + void clear_info() {}; +}; + + + +} // namespace detail + +template< class TA, class TB, class Info, bool FM > +class mutant_relation; + + +/// \brief A std::pair signature compatible class that allows you to control +/// the internal structure of the data. +/** +This class allows you to specify the order in wich the two data types will be +in the layout of the class. + **/ + +template< class FirstType, class SecondType, class Info, class Layout = normal_layout > +class structured_pair : + + public ::boost::bimaps::relation::detail::pair_info_hook + < + FirstType, SecondType, + Info, + Layout + + > + +{ + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::pair_info_hook + < + FirstType, SecondType, + Info, + Layout + + > base_; + + public: + + typedef ::boost::mpl::vector3< + structured_pair< FirstType, SecondType, Info, normal_layout >, + structured_pair< FirstType, SecondType, Info, mirror_layout >, + BOOST_DEDUCED_TYPENAME ::boost::mpl::if_< + BOOST_DEDUCED_TYPENAME ::boost::is_same::type, + mutant_relation< FirstType, SecondType, Info, true >, + mutant_relation< SecondType, FirstType, Info, true > + >::type + + > mutant_views; + + structured_pair() {} + + structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f, + BOOST_DEDUCED_TYPENAME boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s) + : base_(f,s) {} + + structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f, + BOOST_DEDUCED_TYPENAME boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s, + BOOST_DEDUCED_TYPENAME boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::info_type >::param_type i) + : base_(f,s,i) {} + + template< class OtherLayout > + structured_pair( + const structured_pair & p) + : base_(p) {} + + template< class OtherLayout > + structured_pair& operator=( + const structured_pair & p) + { + base_::change_to(p); + return *this; + } + + template< class First, class Second > + structured_pair(const std::pair & p) : + base_(p.first,p.second) + {} + + template< class First, class Second > + structured_pair& operator=(const std::pair & p) + { + base_::first = p.first; + base_::second = p.second; + base_::clear_info(); + return *this; + } + + template< class Tag > + const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + result_of::get::type + get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const + { + return ::boost::bimaps::relation::support::get(*this); + } + + template< class Tag > + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: + result_of::get::type + get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + return ::boost::bimaps::relation::support::get(*this); + } +}; + +// structured_pair - structured_pair + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator==(const structured_pair & a, + const structured_pair & b) +{ + return ( ( a.first == b.first ) && + ( a.second == b.second ) ); +} + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator!=(const structured_pair & a, + const structured_pair & b) +{ + return ! ( a == b ); +} + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator<(const structured_pair & a, + const structured_pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second < b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator<=(const structured_pair & a, + const structured_pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second <= b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator>(const structured_pair & a, + const structured_pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second > b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > +bool operator>=(const structured_pair & a, + const structured_pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second >= b.second ))); +} + +// structured_pair - std::pair + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator==(const structured_pair & a, + const std::pair & b) +{ + return ( ( a.first == b.first ) && + ( a.second == b.second ) ); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator!=(const structured_pair & a, + const std::pair & b) +{ + return ! ( a == b ); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator<(const structured_pair & a, + const std::pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second < b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator<=(const structured_pair & a, + const std::pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second <= b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator>(const structured_pair & a, + const std::pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second > b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator>=(const structured_pair & a, + const std::pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second >= b.second ))); +} + +// std::pair - sturctured_pair + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator==(const std::pair & a, + const structured_pair & b) +{ + return ( ( a.first == b.first ) && + ( a.second == b.second ) ); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator!=(const std::pair & a, + const structured_pair & b) +{ + return ! ( a == b ); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator<(const std::pair & a, + const structured_pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second < b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator<=(const std::pair & a, + const structured_pair & b) +{ + return ( ( a.first < b.first ) || + (( a.first == b.first ) && ( a.second <= b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator>(const std::pair & a, + const structured_pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second > b.second ))); +} + +template< class FirstType, class SecondType, class Info, class Layout, class F, class S > +bool operator>=(const std::pair & a, + const structured_pair & b) +{ + return ( ( a.first > b.first ) || + (( a.first == b.first ) && ( a.second >= b.second ))); +} + + + +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP + diff --git a/thirdparty/boost/bimap/relation/support/data_extractor.hpp b/thirdparty/boost/bimap/relation/support/data_extractor.hpp new file mode 100644 index 0000000..fc4a400 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/data_extractor.hpp @@ -0,0 +1,109 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/data_extractor.hpp +/// \brief Data extraction functor. + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_DATA_EXTRACTOR_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_DATA_EXTRACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::relation::support::data_extractor + +\brief Data extraction functor. + +\ingroup relation_group + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +template< class Tag, class Relation > +struct data_extractor_implementation; + +template< class Relation > +struct data_extractor_implementation< member_at::left, Relation > : + public std::unary_function +{ + BOOST_DEDUCED_TYPENAME Relation::left_value_type const & + operator()(Relation const & rel) const + { + return rel.left; + } + + BOOST_DEDUCED_TYPENAME Relation::left_value_type & + operator()(Relation & rel) const + { + return rel.left; + } +}; + +template< class Relation > +struct data_extractor_implementation< member_at::right, Relation > : + public std::unary_function +{ + BOOST_DEDUCED_TYPENAME Relation::right_value_type const & + operator()(Relation const & rel) const + { + return rel.right; + } + + BOOST_DEDUCED_TYPENAME Relation::right_value_type & + operator()(Relation & rel) const + { + return rel.right; + } +}; + +template< class Tag, class Relation > +struct data_extractor +{ + typedef data_extractor_implementation + < + BOOST_DEDUCED_TYPENAME member_with_tag::type, + Relation + + > type; +}; + +template< class Relation > +struct both_keys_extractor +{ + typedef BOOST_DEDUCED_TYPENAME Relation::storage_base result_type; + + const result_type & operator()(const Relation & rel) const + { + return rel; + } + + result_type & operator()( Relation & rel) const + { + return rel; + } +}; + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_RELATION_SUPPORT_DATA_EXTRACTOR_HPP + diff --git a/thirdparty/boost/bimap/relation/support/get.hpp b/thirdparty/boost/bimap/relation/support/get.hpp new file mode 100644 index 0000000..6ed4582 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/get.hpp @@ -0,0 +1,140 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/get.hpp +/// \brief get(r) function + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_GET_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_GET_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include + +#include +#include +#include + +#ifdef BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +/** \brief Gets a pair view of the relation. + +\ingroup relation_group + **/ + +template< class Tag, class SymmetricType > +BOOST_DEDUCED_TYPENAME result_of::get::type + get( SymmetricType & ); + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + + + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +// Since it is very error-prone to directly write the hole bunch +// of relation accesor. They are buil from litle macro blocks that +// are both more readable, leading to self docummenting code and a +// lot more easier to understand and mantain. +// It is very important to note that the three building blocks have +// to laid in the same namespace in order to work. There is also +// important to keep them in order. +// The forward declaration are not necesary but they help a lot to +// the reader, as they undercover what is the signature of the +// result code. +// In the end, it is not quicker to do it in this way because you +// write a lot. But this code has no complexity at all and almost +// every word writed is for documentation. + +// Result of +// ------------------------------------------------------------------------- +/* + namespace result_of { + + template< class Tag, class Relation > + struct get; + { + typedef -unspecified- type; + }; + + } // namespace result_of + +*/ + +BOOST_BIMAP_SYMMETRIC_ACCESS_RESULT_OF_BUILDER +( + get, + value_type_of +) + + + +// Implementation +// ------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_IMPLEMENTATION_BUILDER +( + get, + SymmetricType, + st, + return st.get_left(), + return st.get_right() +) + +namespace detail { + +template< class SymmetricType > +BOOST_DEDUCED_TYPENAME result_of::get< + ::boost::bimaps::relation::member_at::info, SymmetricType >::type +get(::boost::bimaps::relation::member_at::info, SymmetricType & rel) +{ + return rel.info; +} + +} // namespace detail + +// Interface +//---------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_INTERFACE_BUILDER +( + get +) + + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_RELATION_SUPPORT_GET_HPP + diff --git a/thirdparty/boost/bimap/relation/support/get_pair_functor.hpp b/thirdparty/boost/bimap/relation/support/get_pair_functor.hpp new file mode 100644 index 0000000..278d105 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/get_pair_functor.hpp @@ -0,0 +1,85 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/get_pair_functor.hpp +/// \brief get_pair_functor definition + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_GET_PAIR_FUNCTOR_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_GET_PAIR_FUNCTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +/// \brief A Functor that takes a relation as a parameter an return the desired view. +/** + +This functor is included to help users of the relation class when using +stl algorithms. + +See also member_at, pair_by(). +\ingroup relation_group + + **/ + +template< class Tag, class Relation > +struct get_pair_functor +{ + BOOST_DEDUCED_TYPENAME result_of::pair_by::type + operator()( Relation & r ) const + { + return pair_by(r); + } + + BOOST_DEDUCED_TYPENAME result_of::pair_by::type + operator()( const Relation & r ) const + { + return pair_by(r); + } +}; + + +/// \brief A Functor that takes a relation as a parameter an return the above view. +/** + +\ingroup relation_group + **/ + +template< class Relation > +struct get_above_view_functor +{ + BOOST_DEDUCED_TYPENAME Relation::above_view & + operator()( Relation & r ) const + { + return r.get_view(); + } + + const BOOST_DEDUCED_TYPENAME Relation::above_view & + operator()( const Relation & r ) const + { + return r.get_view(); + } +}; + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_SUPPORT_GET_PAIR_FUNCTOR_HPP + diff --git a/thirdparty/boost/bimap/relation/support/is_tag_of_member_at.hpp b/thirdparty/boost/bimap/relation/support/is_tag_of_member_at.hpp new file mode 100644 index 0000000..151ec11 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/is_tag_of_member_at.hpp @@ -0,0 +1,181 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/is_tag_of_member_at.hpp +/// \brief is_tag_of_member_at metafunction + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_IS_TAG_OF_MEMBER_AT_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_IS_TAG_OF_MEMBER_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#include +#include +#include + +/** \struct boost::bimaps::relation::support::is_tag_of_member_at_left + +\brief Metafunction to test if a user tag is refering to the left member. + +\code + +template< class Tag, class Relation > +struct is_tag_of_member_at_left : {true_|false_} {}; + +\endcode + +This metafunction is somewhat redundant with member_with_tag, but it is included +because it is a lot easier to metaprogram with it. The result type is the +same that: + +\code + + is_same< member_with_tag::type , member_at::left >::type + +\endcode + +See also member_with_tag, member_at, is_tag_of_member_at_right. +\ingroup relation_group + **/ + + +/** \struct boost::bimaps::relation::support::is_tag_of_member_at_right + +\brief Metafunction to test if a user tag is refering to the left member. + +\code + +template< class Tag, class Relation > +struct is_tag_of_member_at_right : {true_|false_} {}; + +\endcode + +This metafunction is somewhat redundat with member_with_tag, but it is included +because it is a lot easier to metaprogram with it. The result type is the +same that: + +\code + + is_same< member_with_tag::type , member_at::right >::type + +\endcode + +See also member_with_tag, member_at, is_tag_of_member_at_left. +\ingroup relation_group + **/ + + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +// Metafunction is_tag_of_member_at_left +// Easiear metaprogramming + +template +< + class Tag, + class Relation, + class Enable = void +> +struct is_tag_of_member_at_left : + ::boost::mpl::false_ {}; + +template< class Tag, class Relation > +struct is_tag_of_member_at_left +< + Tag, Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + is_same + < + BOOST_DEDUCED_TYPENAME member_with_tag::type, + member_at::left + > + + >::type +> : + ::boost::mpl::true_ {}; + +// Metafunction is_tag_of_member_at_right +// Easiear metaprogramming + +template +< + class Tag, + class Relation, + class Enable = void +> +struct is_tag_of_member_at_right : + ::boost::mpl::false_ {}; + +template< class Tag, class Relation > +struct is_tag_of_member_at_right +< + Tag, Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + is_same + < + BOOST_DEDUCED_TYPENAME member_with_tag::type, + member_at::right + > + + >::type +> : + ::boost::mpl::true_ {}; + + +// Metafunction is_tag_of_member_at_info +// Easiear metaprogramming + +template +< + class Tag, + class Relation, + class Enable = void +> +struct is_tag_of_member_at_info : + ::boost::mpl::false_ {}; + +template< class Tag, class Relation > +struct is_tag_of_member_at_info +< + Tag, Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + is_same + < + BOOST_DEDUCED_TYPENAME member_with_tag::type, + member_at::info + > + + >::type +> : + ::boost::mpl::true_ {}; + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_RELATION_SUPPORT_IS_TAG_OF_MEMBER_AT_HPP + + diff --git a/thirdparty/boost/bimap/relation/support/member_with_tag.hpp b/thirdparty/boost/bimap/relation/support/member_with_tag.hpp new file mode 100644 index 0000000..35844dd --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/member_with_tag.hpp @@ -0,0 +1,180 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/member_with_tag.hpp +/// \brief member_with_tag metafunction + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +/** \struct boost::bimaps::relation::support::member_with_tag + +\brief Metafunction to convert user tags to the member_at idiom. + +\code + +template< class Tag, class Relation > +struct member_with_tag +{ + typedef member_at::{side} type; +}; + +\endcode + +We have to allow that all the metafunctions that works with tags +and retrieves data from a Relation will work with member_at idiom +even if the type was tagged. This will be great for the user, +because he can choose to tag a member after he is using the +relation and the code will still work. + +If we perform this check in every metafunction it will be very +tedious and error prone, so instead of that all metafunctions +that works with relations first call this metafunction that +convert the tag to a member_at tag. + +See also member_at, is_tag_of_member_at_left, is_tag_of_member_at_right. +\ingroup relation_group + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +template +< + class Tag, + class Relation, + class Enable = void +> +struct member_with_tag +{ + BOOST_BIMAP_STATIC_ERROR( MEMBER_WITH_TAG_FAILURE, (Relation,Tag) ); +}; + +template< class Relation > +struct member_with_tag +< + member_at::left, Relation, void +> +{ + typedef member_at::left type; +}; + +template< class Relation > +struct member_with_tag +< + member_at::right, Relation, void +> +{ + typedef member_at::right type; +}; + +template< class Relation > +struct member_with_tag +< + member_at::info, Relation, void +> +{ + typedef member_at::info type; +}; + + +template< class Tag, class Relation > +struct member_with_tag +< + Tag, Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + mpl::and_ + < + mpl::not_< is_same >, + is_same + < + Tag, + BOOST_DEDUCED_TYPENAME Relation::left_tag + > + > + + >::type +> +{ + typedef member_at::left type; +}; + +template< class Tag, class Relation > +struct member_with_tag +< + Tag, + Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + mpl::and_ + < + mpl::not_< is_same >, + is_same + < + Tag, + BOOST_DEDUCED_TYPENAME Relation::right_tag + > + > + + >::type +> +{ + typedef member_at::right type; +}; + +template< class Tag, class Relation > +struct member_with_tag +< + Tag, Relation, + BOOST_DEDUCED_TYPENAME enable_if + < + mpl::and_ + < + mpl::not_< is_same >, + is_same + < + Tag, + BOOST_DEDUCED_TYPENAME Relation::info_tag + > + > + + >::type +> +{ + typedef member_at::info type; +}; + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP + + diff --git a/thirdparty/boost/bimap/relation/support/opposite_tag.hpp b/thirdparty/boost/bimap/relation/support/opposite_tag.hpp new file mode 100644 index 0000000..24a6a63 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/opposite_tag.hpp @@ -0,0 +1,61 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/opposite_tag.hpp +/// \brief Metafunction to obtain the opposite tag in a relation. + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_OPPOSITE_TAG_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_OPPOSITE_TAG_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::relation::support::opposite_tag + +\brief Metafunction to obtain the opposite tag in a relation. + +\code + +template< class Tag, class Relation > +struct opposite_tag +{ + typedef {OppositeTag} type; +}; + +\endcode + +\ingroup relation_group + **/ + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +// Implementation of const pair reference type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + opossite_tag, + right_tag, + left_tag +) + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_SUPPORT_OPPOSITE_TAG_HPP + diff --git a/thirdparty/boost/bimap/relation/support/pair_by.hpp b/thirdparty/boost/bimap/relation/support/pair_by.hpp new file mode 100644 index 0000000..218172d --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/pair_by.hpp @@ -0,0 +1,120 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/pair_by.hpp +/// \brief pair_by(r) function + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_PAIR_BY_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_PAIR_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#ifdef BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +/** \brief Gets a pair view of the relation. + +\ingroup relation_group + **/ + +template< class Tag, class Relation > +BOOST_DEDUCED_TYPENAME result_of::pair_by::type + pair_by( Relation & rel ); + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + + +// Since it is very error-prone to directly write the hole bunch +// of relation accesor. They are buil from litle macro blocks that +// are both more readable, leading to self docummenting code and a +// lot more easier to understand and mantain. +// It is very important to note that the three building blocks have +// to laid in the same namespace in order to work. There is also +// important to keep them in order. +// The forward declaration are not necesary but they help a lot to +// the reader, as they undercover what is the signature of the +// result code. +// In the end, it is not quicker to do it in this way because you +// write a lot. But this code has no complexity at all and almost +// every word writed is for documentation. + +// Result of +// ------------------------------------------------------------------------- +/* + namespace result_of { + + template< class Tag, class Relation > + struct pair_by; + { + typedef -unspecified- type; + }; + + } // namespace result_of +*/ + +BOOST_BIMAP_SYMMETRIC_ACCESS_RESULT_OF_BUILDER +( + pair_by, + pair_type_by +) + + + +// Implementation +// ------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_IMPLEMENTATION_BUILDER +( + pair_by, + Relation, + rel, + return rel.get_left_pair(), + return rel.get_right_pair() +) + +// Interface +// -------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_INTERFACE_BUILDER +( + pair_by +) + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_DOXIGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_RELATION_SUPPORT_PAIR_BY_HPP diff --git a/thirdparty/boost/bimap/relation/support/pair_type_by.hpp b/thirdparty/boost/bimap/relation/support/pair_type_by.hpp new file mode 100644 index 0000000..03fc945 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/pair_type_by.hpp @@ -0,0 +1,62 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/pair_type_by.hpp +/// \brief pair_type_by metafunction + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_PAIR_TYPE_BY_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_PAIR_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::relation::support::pair_type_by + +\brief Metafunction to obtain the view type indexed by one of the sides. + +\code + +template< class Tag, class Relation > +struct pair_type_by +{ + typedef {signature-compatible with std::pair} type; +}; + +\endcode + +See also member_at, pair_by(). +\ingroup relation_group + **/ + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +// Implementation of pair type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + pair_type_by, + left_pair, + right_pair +) + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_SUPPORT_PAIR_BY_TYPE_HPP + diff --git a/thirdparty/boost/bimap/relation/support/value_type_of.hpp b/thirdparty/boost/bimap/relation/support/value_type_of.hpp new file mode 100644 index 0000000..fb64654 --- /dev/null +++ b/thirdparty/boost/bimap/relation/support/value_type_of.hpp @@ -0,0 +1,91 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/support/value_type_of.hpp +/// \brief value_type_of metafunction + +#ifndef BOOST_BIMAP_RELATION_SUPPORT_VALUE_TYPE_OF_HPP +#define BOOST_BIMAP_RELATION_SUPPORT_VALUE_TYPE_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::relation::support::value_type_of + +\brief Metafunction to obtain the value type of one of the sides. + +\code + +template< class Tag, class Relation > +struct value_type_of +{ + typedef typename Relation::{side}_type type; +}; + +\endcode + +See also member_at, get(). +\ingroup relation_group + **/ + +namespace boost { +namespace bimaps { +namespace relation { +namespace support { + +// Metafunction value_type_of +/* + + template< class Tag, class Relation > + struct value_type_of + { + typedef -unspecified- type; + }; + +*/ + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + value_type_of, + left_value_type, + right_value_type +) + +// Add support for info tags to value_type_of + +template< class Tag, class SymmetricType > +struct value_type_of +< + Tag, SymmetricType, + BOOST_DEDUCED_TYPENAME enable_if + < + ::boost::bimaps::relation::support::is_tag_of_member_at_info + < + Tag, + SymmetricType + > + + >::type +> +{ + typedef BOOST_DEDUCED_TYPENAME SymmetricType::info_type type; +}; + +} // namespace support +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_SUPPORT_VALUE_TYPE_OF_HPP + diff --git a/thirdparty/boost/bimap/relation/symmetrical_base.hpp b/thirdparty/boost/bimap/relation/symmetrical_base.hpp new file mode 100644 index 0000000..934aa04 --- /dev/null +++ b/thirdparty/boost/bimap/relation/symmetrical_base.hpp @@ -0,0 +1,97 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file relation/symmetrical_base.hpp +/// \brief Base class for symmetrical types + +#ifndef BOOST_BIMAP_RELATION_SYMMETRICAL_BASE_HPP +#define BOOST_BIMAP_RELATION_SYMMETRICAL_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +// Boost.Bimap +#include +#include + +#include + + +namespace boost { +namespace bimaps { +namespace relation { + +/// \brief Base of symetrical tagged types. +/** + + **/ + +template< class TA, class TB, bool force_mutable = false > +class symmetrical_base +{ + + public: + + typedef BOOST_DEDUCED_TYPENAME tags::support::default_tagged + < + TA, + member_at::left + + >::type tagged_left_type; + + typedef BOOST_DEDUCED_TYPENAME tags::support::default_tagged + < + TB, + member_at::right + + >::type tagged_right_type; + + public: + + //@{ + /// The type stored in the relation + + typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c< force_mutable, + + BOOST_DEDUCED_TYPENAME ::boost::remove_const< + BOOST_DEDUCED_TYPENAME tagged_left_type::value_type >::type, + BOOST_DEDUCED_TYPENAME tagged_left_type::value_type + + >::type left_value_type; + + typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c< force_mutable, + + BOOST_DEDUCED_TYPENAME ::boost::remove_const< + BOOST_DEDUCED_TYPENAME tagged_right_type::value_type >::type, + BOOST_DEDUCED_TYPENAME tagged_right_type::value_type + + >::type right_value_type; + //@} + + //@{ + /// The tag of the member. By default it is \c member_at::{side} + typedef BOOST_DEDUCED_TYPENAME tagged_left_type ::tag left_tag; + typedef BOOST_DEDUCED_TYPENAME tagged_right_type::tag right_tag; + //@} +}; + + + +} // namespace relation +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_RELATION_SYMMETRICAL_BASE_HPP + diff --git a/thirdparty/boost/bimap/set_of.hpp b/thirdparty/boost/bimap/set_of.hpp new file mode 100644 index 0000000..5c8d8e8 --- /dev/null +++ b/thirdparty/boost/bimap/set_of.hpp @@ -0,0 +1,206 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file set_of.hpp +/// \brief Include support for set constrains for the bimap container + +#ifndef BOOST_BIMAP_SET_OF_HPP +#define BOOST_BIMAP_SET_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + +/// \brief Set Type Specification +/** +This struct is used to specify a set specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an std::set instantiation, except +that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the set +type specification, rather it is a container configuration +parameter. +The first parameter is the type of the objects in the set, and +the second one is a Functor that compares them. +Bimap binding metafunctions can be used with this class in +the following way: + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< set_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + set_of::index_bind + < + KeyExtractor, + Tag + + >::type, + + ordered_unique< tag, KeyExtractor, KeyCompare > + + >::value +) + +typedef bimap +< + set_of, RightKeyType + +> bimap_with_left_type_as_set; + +BOOST_STATIC_ASSERT +( + is_same + < + set_of::map_view_bind + < + member_at::left, + bimap_with_left_type_as_set + + >::type, + + map_view< member_at::left, bimap_with_left_type_as_set > + + >::value +) + +\endcode + +See also set_of_relation. + **/ + +template +< + class KeyType, + class KeyCompare = std::less< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type > +> +struct set_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef KeyType user_type; + + /// Type of the object that will be stored in the set + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + /// Functor that compare two keys + typedef KeyCompare key_compare; + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + BOOST_CLASS_REQUIRE4( key_compare, bool, value_type, value_type, + boost, BinaryFunctionConcept ); + + typedef set_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_1CP( + + // binds to + multi_index::ordered_unique, + + // with + key_compare + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::map_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::set_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief Set Of Relation Specification +/** +This struct is similar to set_of but it is bind logically to a +relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also set_of, is_set_type_of_relation. + **/ + +template< class KeyCompare = std::less< _relation > > +struct set_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + /// Functor that compare two keys + typedef KeyCompare key_compare; + + BOOST_BIMAP_GENERATE_RELATION_BINDER_1CP( + + // binds to + set_of, + + // with + key_compare + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_SET_OF_HPP + diff --git a/thirdparty/boost/bimap/support/data_type_by.hpp b/thirdparty/boost/bimap/support/data_type_by.hpp new file mode 100644 index 0000000..c979c78 --- /dev/null +++ b/thirdparty/boost/bimap/support/data_type_by.hpp @@ -0,0 +1,73 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/data_type_by.hpp +/// \brief Metafunction to access the data types of a bimap + +#ifndef BOOST_BIMAP_SUPPORT_DATA_TYPE_BY_HPP +#define BOOST_BIMAP_SUPPORT_DATA_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::support::data_type_by + +\brief Metafunction to obtain the data type of one of the sides in a bimap + +The tag parameter can be either a user defined tag or \c member_at::{side}. +This is the actual data type stored in the bimap. +\code + +template< class Tag, class Bimap > +struct data_type_by +{ + typedef typename Bimap::{side}_data_type type; +}; + +\endcode + +The following holds: + +\code + +BOOST_STATIC_ASSERT +( + is_same< data_type_by< member_at::left, bimap >::type, A >::value +) + +\endcode + +See also member_at. +\ingroup bimap_group + **/ + +namespace boost { +namespace bimaps { +namespace support { + +// Implementation of data type of metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + data_type_by, + left_data_type, + right_data_type +) + +} // namespace support +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_SUPPORT_DATA_TYPE_BY_HPP + diff --git a/thirdparty/boost/bimap/support/iterator_type_by.hpp b/thirdparty/boost/bimap/support/iterator_type_by.hpp new file mode 100644 index 0000000..3d7f090 --- /dev/null +++ b/thirdparty/boost/bimap/support/iterator_type_by.hpp @@ -0,0 +1,228 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/iterator_type_by.hpp +/// \brief Metafunctions to access the iterator types of a bimap + +#ifndef BOOST_BIMAP_SUPPORT_ITERATOR_TYPE_BY_HPP +#define BOOST_BIMAP_SUPPORT_ITERATOR_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +#include + +#include + +/** \struct boost::bimaps::support::iterator_type_by + +\brief Metafunction to obtain the iterator type of the map view by one of the sides. + +\code + +template< class Tag, class Bimap > +struct iterator_type_by +{ + typedef -unspecified- type; +}; + +template< class Tag, class Bimap > +struct const_iterator_type_by +{ + typedef -unspecified- type; +}; + +template< class Tag, class Bimap > +struct reverse_iterator_type_by +{ + typedef -unspecified- type; +}; + +template< class Tag, class Bimap > +struct const_reverse_iterator_type_by +{ + typedef -unspecified- type; +}; + +template< class Tag, class Bimap > +struct local_iterator_type_by +{ + typedef -unspecified- type; +}; + +template< class Tag, class Bimap > +struct const_local_iterator_type_by +{ + typedef -unspecified- type; +}; + +\endcode + +See also member_at. +\ingroup bimap_group + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace support { + + +// Implementation of iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + iterator_type_by, + left_iterator, + right_iterator +) + +// Implementation of const iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + const_iterator_type_by, + left_const_iterator, + right_const_iterator +) + + +// Implementation of reverse iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER +( + core_reverse_iterator_type_by, + BimapCore, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::reverse_iterator type, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::reverse_iterator type +) + +template< class Tag, class BimapCore > +struct reverse_iterator_type_by +{ + typedef ::boost::bimaps::detail::map_view_iterator + < + Tag, + BOOST_DEDUCED_TYPENAME BimapCore::relation, + BOOST_DEDUCED_TYPENAME core_reverse_iterator_type_by::type + + > type; +}; + +// Implementation of const reverse iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER +( + core_const_reverse_iterator_type_by, + BimapCore, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::const_reverse_iterator type, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::const_reverse_iterator type +) + +template< class Tag, class BimapCore > +struct const_reverse_iterator_type_by +{ + + typedef ::boost::bimaps::detail::map_view_iterator + < + Tag, + BOOST_DEDUCED_TYPENAME BimapCore::relation, + BOOST_DEDUCED_TYPENAME core_const_reverse_iterator_type_by::type + + > type; +}; + + +// Implementation of local iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER +( + core_local_iterator_type_by, + BimapCore, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::local_iterator type, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::local_iterator type +) + + +template< class Tag, class BimapCore > +struct local_iterator_type_by +{ + + typedef ::boost::bimaps::detail::map_view_iterator + < + Tag, + BOOST_DEDUCED_TYPENAME BimapCore::relation, + BOOST_DEDUCED_TYPENAME core_local_iterator_type_by::type + + > type; +}; + + +// Implementation of const local iterator type by metafunction + +BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER +( + core_const_local_iterator_type_by, + BimapCore, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::const_local_iterator type, + + typedef BOOST_DEDUCED_TYPENAME BimapCore::core_type::BOOST_NESTED_TEMPLATE + index + ::type::const_local_iterator type +) + +template< class Tag, class BimapCore > +struct const_local_iterator_type_by +{ + + typedef ::boost::bimaps::detail::map_view_iterator + < + Tag, + BOOST_DEDUCED_TYPENAME BimapCore::relation, + BOOST_DEDUCED_TYPENAME core_const_local_iterator_type_by::type + + > type; +}; + + +} // namespace support +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_SUPPORT_ITERATOR_TYPE_BY_HPP + diff --git a/thirdparty/boost/bimap/support/key_type_by.hpp b/thirdparty/boost/bimap/support/key_type_by.hpp new file mode 100644 index 0000000..e98b074 --- /dev/null +++ b/thirdparty/boost/bimap/support/key_type_by.hpp @@ -0,0 +1,64 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/key_type_by.hpp +/// \brief Metafunction to access the set types of a bimap + +#ifndef BOOST_BIMAP_SUPPORT_KEY_TYPE_BY_HPP +#define BOOST_BIMAP_SUPPORT_KEY_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::support::key_type_by + +\brief Metafunction to obtain the key type of one of the sides in a bimap + +The tag parameter can be either a user defined tag or \c member_at::{side}. +The returned type is one of the {SetType}_of definition classes. + +\code + +template< class Tag, class Bimap > +struct key_type_by +{ + typedef typename Bimap::{side}_key_type type; +}; + +\endcode + +See also member_at. +\ingroup bimap_group + **/ + + +namespace boost { +namespace bimaps { +namespace support { + +// Implementation of key type type of metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + key_type_by, + left_key_type, + right_key_type +) + + +} // namespace support +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_SUPPORT_KEY_TYPE_BY_HPP + diff --git a/thirdparty/boost/bimap/support/lambda.hpp b/thirdparty/boost/bimap/support/lambda.hpp new file mode 100644 index 0000000..60f946b --- /dev/null +++ b/thirdparty/boost/bimap/support/lambda.hpp @@ -0,0 +1,46 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/lambda.hpp +/// \brief Placeholders definition to help in bimap modify function + +#ifndef BOOST_BIMAP_SUPPORT_LAMBDA_HPP +#define BOOST_BIMAP_SUPPORT_LAMBDA_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +namespace boost { +namespace bimaps { + +namespace { + +/* +boost::lambda::placeholder1_type & _first = boost::lambda::_1; +boost::lambda::placeholder2_type & _second = boost::lambda::_2; + +boost::lambda::placeholder1_type & _left = boost::lambda::_1; +boost::lambda::placeholder2_type & _right = boost::lambda::_2; +*/ + +boost::lambda::placeholder1_type & _key = boost::lambda::_1; +boost::lambda::placeholder1_type & _data = boost::lambda::_1; + +} + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_SUPPORT_LAMBDA_HPP + diff --git a/thirdparty/boost/bimap/support/map_by.hpp b/thirdparty/boost/bimap/support/map_by.hpp new file mode 100644 index 0000000..6b6d69b --- /dev/null +++ b/thirdparty/boost/bimap/support/map_by.hpp @@ -0,0 +1,132 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/map_by.hpp +/// \brief map_by(b) function + +#ifndef BOOST_BIMAP_SUPPORT_MAP_BY_HPP +#define BOOST_BIMAP_SUPPORT_MAP_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + + +#ifdef BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace support { + +/** \brief Gets a map view of a bidirectional map + +Convertible to \c map_type_by::type +Instead of using \c map_type_by::type this functions use +\b Boost.call_traits to find the best way to return this value. To help +the user of this function the following metafunction is provided +\code + +namespace result_of { + +template< class Tag, class Bimap > +struct map_by( Bimap & b ); + +} // namespace result_of + +\endcode + +See also member_at, value_type_of. +\ingroup bimap_group + **/ + +template< class Tag, class Bimap > +BOOST_DEDUCED_TYPENAME result_of::map_by::type + map_by( Bimap & b ); + +} // namespace support +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_ONLY_DOXYGEN_WILL_PROCESS_THE_FOLLOWING_LINES + + + +#ifndef BOOST_BIMAP_DOXIGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace support { + +// Since it is very error-prone to directly write the hole bunch +// of relation accesor. They are buil from litle macro blocks that +// are both more readable, leading to self docummenting code and a +// lot more easier to understand and mantain. +// It is very important to note that the three building blocks have +// to laid in the same namespace in order to work. There is also +// important to keep them in order. +// The forward declaration are not necesary but they help a lot to +// the reader, as they undercover what is the signature of the +// result code. +// In the end, it is not quicker to do it in this way because you +// write a lot. But this code has no complexity at all and almost +// every word writed is for documentation. + +// Result of +// ------------------------------------------------------------------------- +/* + namespace result_of { + + template< class Tag, class Bimap > + struct map_by; + { + typedef -unspecified- type; + }; + + } // namespace result_of + +*/ + +BOOST_BIMAP_SYMMETRIC_ACCESS_RESULT_OF_BUILDER +( + map_by, + map_type_by +) + +// Implementation +// ------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_IMPLEMENTATION_BUILDER +( + map_by, + Bimap, + b, + return b.left, + return b.right +) + +// Interface +// -------------------------------------------------------------------------- + +BOOST_BIMAP_SYMMETRIC_ACCESS_INTERFACE_BUILDER +( + map_by +) + +} // namespace support +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXIGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_SUPPORT_MAP_BY_HPP + diff --git a/thirdparty/boost/bimap/support/map_type_by.hpp b/thirdparty/boost/bimap/support/map_type_by.hpp new file mode 100644 index 0000000..57e4831 --- /dev/null +++ b/thirdparty/boost/bimap/support/map_type_by.hpp @@ -0,0 +1,65 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/map_type_by.hpp +/// \brief Metafunction to access the map view types of a bimap + +#ifndef BOOST_BIMAP_SUPPORT_MAP_TYPE_BY_HPP +#define BOOST_BIMAP_SUPPORT_MAP_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::support::map_type_by + +\brief Metafunction to obtain the map view type of a bimap indexed by one of the sides. + +The tag parameter can be either a user defined tag or \c member_at::{side}. +The returned type is signature-compatible with std::pair. + +\code + +template< class Tag, class Bimap > +struct map_type_by +{ + typedef typename Bimap::{side}_map_type type; +}; + +\endcode + +See also member_at. +\ingroup bimap_group + **/ + +namespace boost { +namespace bimaps { +namespace support { + +// Implementation of map type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + map_type_by, + left_map, + right_map +) + + + +} // namespace support +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_SUPPORT_MAP_TYPE_BY_HPP + diff --git a/thirdparty/boost/bimap/support/value_type_by.hpp b/thirdparty/boost/bimap/support/value_type_by.hpp new file mode 100644 index 0000000..9c1e7d9 --- /dev/null +++ b/thirdparty/boost/bimap/support/value_type_by.hpp @@ -0,0 +1,65 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file support/value_type_by.hpp +/// \brief Metafunction to access the value types (std::pair compatibles) of a bimap + +#ifndef BOOST_BIMAP_SUPPORT_VALUE_TYPE_BY_HPP +#define BOOST_BIMAP_SUPPORT_VALUE_TYPE_BY_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::support::value_type_by + +\brief Metafunction to obtain the value type of a bimap indexed by one of the sides. + +The tag parameter can be either a user defined tag or \c member_at::{side}. +The returned type is signature-compatible with std::pair. + +\code + +template< class Tag, class Bimap > +struct value_type_by +{ + typedef typename Bimap::{side}_value_type type; +}; + +\endcode + +See also member_at. +\ingroup bimap_group + **/ + +namespace boost { +namespace bimaps { +namespace support { + +// Implementation of value type by metafunction + +BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER +( + value_type_by, + left_value_type, + right_value_type +) + + + +} // namespace support +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_SUPPORT_VALUE_TYPE_BY_HPP + diff --git a/thirdparty/boost/bimap/tags/support/apply_to_value_type.hpp b/thirdparty/boost/bimap/tags/support/apply_to_value_type.hpp new file mode 100644 index 0000000..88249db --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/apply_to_value_type.hpp @@ -0,0 +1,70 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/apply_to_value_type.hpp +/// \brief Similar to mpl::apply but for tagged types. + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_APPLY_TO_VALUE_TYPE_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_APPLY_TO_VALUE_TYPE_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +/** \struct boost::bimaps::tags::support::apply_to_value_type +\brief Higger order metafunction similar to mpl::apply but for tagged types. + +\code +template< class Metafunction, class TaggedType > +struct apply_to_value_type +{ + typedef tagged + < + Metafuntion< value_type_of< TaggedType >::type >::type, + tag_of< TaggedType >::type + + > type; +}; +\endcode + +This higher order metafunctions is very useful, and it can be used with lambda +expresions. + +See also tagged. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + +template < class F, class TaggedType > +struct apply_to_value_type; + +template < class F, class ValueType, class Tag > +struct apply_to_value_type > +{ + typedef BOOST_DEDUCED_TYPENAME mpl::apply< F, ValueType >::type new_value_type; + typedef tagged< new_value_type, Tag > type; +}; + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_APPLY_TO_VALUE_TYPE_HPP diff --git a/thirdparty/boost/bimap/tags/support/default_tagged.hpp b/thirdparty/boost/bimap/tags/support/default_tagged.hpp new file mode 100644 index 0000000..46fa72e --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/default_tagged.hpp @@ -0,0 +1,73 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/default_tagged.hpp +/// \brief Weak tagging + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_DEFAULT_TAGGED_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_DEFAULT_TAGGED_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::tags::support::default_tagged +\brief Weak tagging metafunction + +\code +template< class Type, class Tag > +struct default_tagged +{ + typedef {TaggedType} type; +}; +\endcode + +If the type is not tagged, this metafunction returns a tagged type with the +default tag. If it is tagged, the returns the type unchanged. + +See also tagged, overwrite_tagged. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + + +// Default Tagging +// A metafunction that create a tagged type with a default tag value. + +template< class Type, class DefaultTag > +struct default_tagged +{ + typedef tagged type; +}; + +template< class Type, class OldTag, class NewTag > +struct default_tagged< tagged< Type, OldTag >, NewTag > +{ + typedef tagged type; +}; + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_DEFAULT_TAGGED_HPP + + + diff --git a/thirdparty/boost/bimap/tags/support/is_tagged.hpp b/thirdparty/boost/bimap/tags/support/is_tagged.hpp new file mode 100644 index 0000000..35e2599 --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/is_tagged.hpp @@ -0,0 +1,64 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/is_tagged.hpp +/// \brief type_traits extension + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_IS_TAGGED_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_IS_TAGGED_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +/** \struct boost::bimaps::tags::support::is_tagged +\brief Type trait to check if a type is tagged. + +\code +template< class Type > +struct is_tagged +{ + typedef {mpl::true_/mpl::false_} type; +}; +\endcode + +See also tagged. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + + +// is_tagged metafunction + +template< class Type > +struct is_tagged : + ::boost::mpl::false_ {}; + +template< class Type, class Tag > +struct is_tagged< tagged< Type, Tag > > : + ::boost::mpl::true_ {}; + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_IS_TAGGED_HPP + diff --git a/thirdparty/boost/bimap/tags/support/overwrite_tagged.hpp b/thirdparty/boost/bimap/tags/support/overwrite_tagged.hpp new file mode 100644 index 0000000..de21b1c --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/overwrite_tagged.hpp @@ -0,0 +1,73 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/overwrite_tagged.hpp +/// \brief Hard tagging + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_OVERWRITE_TAGGED_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_OVERWRITE_TAGGED_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::tags::support::overwrite_tagged +\brief Hard tagging metafunction + +\code +template< class Type, class Tag > +struct overwrite_tagged +{ + typedef {TaggedType} type; +}; +\endcode + +If the type is not tagged, this metafunction returns a tagged type with the +passed tag. If it is tagged it returns a new tagged type with the tag replaced +by the one passed as a parameter. + +See also tagged, default_tagged. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + + +// Change the tag + +template< class Type, class NewTag > +struct overwrite_tagged +{ + typedef tagged type; +}; + +template< class Type, class OldTag, class NewTag > +struct overwrite_tagged< tagged< Type, OldTag >, NewTag > +{ + typedef tagged type; +}; + + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_OVERWRITE_TAGGED_HPP + + diff --git a/thirdparty/boost/bimap/tags/support/tag_of.hpp b/thirdparty/boost/bimap/tags/support/tag_of.hpp new file mode 100644 index 0000000..8e67f0a --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/tag_of.hpp @@ -0,0 +1,75 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/tag_of.hpp +/// \brief Safe way to acces the tag of a type + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_TAG_OF_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_TAG_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +/** \struct boost::bimaps::tags::support::tag_of +\brief Metafunction to obtain the tag of a type. + +\code +template< class TaggedType > +struct tag_of +{ + typedef {Tag} type; +}; +\endcode + +If the type is not tagged you will get a compile timer error with the following message: + +\verbatim +USING_TAG_OF_WITH_AN_UNTAGGED_TYPE, TaggedType +\endverbatim + +See also tagged, value_type_of. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + + +// tag_of metafunction + +template< class Type > +struct tag_of +{ + BOOST_BIMAP_STATIC_ERROR( USING_TAG_OF_WITH_AN_UNTAGGED_TYPE, (Type) ); +}; + +template< class Type, class Tag > +struct tag_of< tagged< Type, Tag > > +{ + typedef Tag type; +}; + + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_TAG_OF_HPP + diff --git a/thirdparty/boost/bimap/tags/support/value_type_of.hpp b/thirdparty/boost/bimap/tags/support/value_type_of.hpp new file mode 100644 index 0000000..f791752 --- /dev/null +++ b/thirdparty/boost/bimap/tags/support/value_type_of.hpp @@ -0,0 +1,74 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/support/value_type_of.hpp +/// \brief Consistent way to access the value type of a tagged or untagged type. + +#ifndef BOOST_BIMAP_TAGS_SUPPORT_VALUE_TYPE_OF_HPP +#define BOOST_BIMAP_TAGS_SUPPORT_VALUE_TYPE_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +/** \struct boost::bimaps::tags::support::value_type_of +\brief Metafunction to work with tagged and untagged type uniformly + +\code +template< class Type > +struct value_type_of +{ + typedef {UntaggedType} type; +}; +\endcode + +If the type is tagged this metafunction returns Type::value_type, and if it is not +tagged it return the same type. This allows to work consistenly with tagged and +untagged types. + +See also tagged, tag_of. + **/ + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + + +namespace boost { +namespace bimaps { +namespace tags { +namespace support { + + +// value_type_of metafunction + +template< class Type > +struct value_type_of +{ + typedef Type type; +}; + +template< class Type, class Tag > +struct value_type_of< tagged< Type, Tag > > +{ + typedef Type type; +}; + + +} // namespace support +} // namespace tags +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +#endif // BOOST_BIMAP_TAGS_SUPPORT_VALUE_TYPE_OF_HPP + + diff --git a/thirdparty/boost/bimap/tags/tagged.hpp b/thirdparty/boost/bimap/tags/tagged.hpp new file mode 100644 index 0000000..7786d10 --- /dev/null +++ b/thirdparty/boost/bimap/tags/tagged.hpp @@ -0,0 +1,107 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file tags/tagged.hpp +/// \brief Defines the tagged class + +#ifndef BOOST_BIMAP_TAGS_TAGGED_HPP +#define BOOST_BIMAP_TAGS_TAGGED_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { + +/// \brief A light non-invasive idiom to tag a type. +/** + +There are a lot of ways of tagging a type. The standard library for example +defines tags (empty structs) that are then inherited by the tagged class. To +support built-in types and other types that simple cannot inherit from the +tag, the standard builds another level of indirection. An example of this is +the type_traits metafunction. This approach is useful if the tags are intended +to be used in the library internals, and if the user does not have to create +new tagged types often. + +Boost.MultiIndex is an example of a library that defines a tagged idiom that +is better suited to the user. As an option, in the indexed by declaration +of a multi-index container a user can \b attach a tag to each index, so it +can be referred by it instead of by the index number. It is a very user +friendly way of specifying a tag but is very invasive from the library writer's +point of view. Each index must now support this additional parameter. Maybe +not in the case of the multi-index container, but in simpler classes +the information of the tags is used by the father class rather than by the +tagged types. + +\b tagged is a light non-invasive idiom to tag a type. It is very intuitive +and user-friendly. With the use of the defined metafunctions the library +writer can enjoy the coding too. + + **/ + +namespace tags { + +/// \brief The tag holder +/** + +The idea is to add a level of indirection to the type being tagged. With this +class you wrapped a type and apply a tag to it. The only thing to remember is +that if you write + +\code +typedef tagged taggedType; +\endcode + +Then instead to use directly the tagged type, in order to access it you have +to write \c taggedType::value_type. The tag can be obtained using \c taggedType::tag. +The idea is not to use this metadata directly but rather using the metafunctions +that are defined in the support namespace. With this metafunctions you can work +with tagged and untagged types in a consistent way. For example, the following +code is valid: + +\code +BOOST_STATIC_ASSERT( is_same< value_type_of, value_type_of >::value ); +\endcode + +The are other useful metafunctions there too. +See also value_type_of, tag_of, is_tagged, apply_to_value_type. + +\ingroup tagged_group + **/ +template< class Type, class Tag > +struct tagged +{ + typedef Type value_type; + typedef Tag tag; +}; + +} // namespace tags +} // namespace bimaps +} // namespace boost + +/** \namespace boost::bimaps::tags::support +\brief Metafunctions to work with tagged types. + +This metafunctions aims to make easier the manage of tagged types. They are all mpl +compatible metafunctions and can be used with lambda expresions. +The metafunction value_type_of and tag_of get the data in a tagged type in a secure +and consistent way. +default_tagged and overwrite_tagged allows to work with the tag of a tagged type, +and apply_to_value_type is a higher order metafunction that allow the user to change +the type of a TaggedType. + **/ + +#endif // BOOST_BIMAP_TAGS_TAGGED_HPP + + + + diff --git a/thirdparty/boost/bimap/unconstrained_set_of.hpp b/thirdparty/boost/bimap/unconstrained_set_of.hpp new file mode 100644 index 0000000..ffba2f9 --- /dev/null +++ b/thirdparty/boost/bimap/unconstrained_set_of.hpp @@ -0,0 +1,150 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file unconstrained_set_of.hpp +/// \brief Include support for set constrains for the bimap container + +#ifndef BOOST_BIMAP_UNCONSTRAINED_SET_OF_HPP +#define BOOST_BIMAP_UNCONSTRAINED_SET_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include + +#include +#include + +namespace boost { +namespace bimaps { + +/// \brief Set Type Specification +/** +This struct is used to specify a set specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +The first parameter is the type of the objects in the set. + +\code + +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< unconstrained_set_of >::value ) + +\endcode + +See also unconstrained_set_of_relation. + **/ + +template +< + class KeyType +> +struct unconstrained_set_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef KeyType user_type; + + /// Type of the object that will be stored in the container + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + typedef unconstrained_set_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_FAKE + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::unconstrained_map_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::unconstrained_set_view + ) + + typedef mpl::bool_ mutable_key; +}; + +/// \brief Set Of Relation Specification +/** +This struct is similar to unconstrained_set_of but it is bind +logically to a relation. It is used in the bimap instantiation to +specify the desired type of the main view. + +See also unconstrained_set_of, is_set_type_of_relation. + **/ + +struct unconstrained_set_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + + BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP( + + // binds to + unconstrained_set_of + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +namespace detail { + +template +struct is_unconstrained_set_of : + ::boost::mpl::false_ {}; + +template +struct is_unconstrained_set_of< unconstrained_set_of > : + ::boost::mpl::true_ {}; + +} // namespace detail + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +} // namespace bimaps +} // namespace boost + + +/** \struct boost::bimaps::detail::is_unconstrained_set_of +\brief Trait to check if a type is unconstrained_set_of. +\code +template< class T > +struct is_unconstrained_set_of; +\endcode + **/ + + +#endif // BOOST_BIMAP_UNCONSTRAINED_SET_OF_HPP + diff --git a/thirdparty/boost/bimap/unordered_multiset_of.hpp b/thirdparty/boost/bimap/unordered_multiset_of.hpp new file mode 100644 index 0000000..a8ebc82 --- /dev/null +++ b/thirdparty/boost/bimap/unordered_multiset_of.hpp @@ -0,0 +1,233 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file unordered_multiset_of.hpp +/// \brief Include support for unordered_multiset constrains for the bimap container + +#ifndef BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP +#define BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + + +/// \brief Set Type Specification +/** +This struct is used to specify an unordered_multiset specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an tr1::unordered_multiset instantiation, +except that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the +unordered_multiset type specification, rather it is a container +configuration parameter. +The first parameter is the type of the objects in the set, the +second one is a Hash Functor that takes objects of this type, and +the third one is a Functor that compares them for equality. +Bimap binding metafunctions can be used with this class in +the following way: + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< unordered_multiset_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + compute_index_type + < + unordered_multiset_of, + KeyExtractor, + Tag + + >::type + , + hashed_nonunique< tag, KeyExtractor, HashFunctor, EqualKey > + + >::value +) + +typedef bimap +< + unordered_multiset_of, RightKeyType + +> bimap_with_left_type_as_unordered_multiset; + +BOOST_STATIC_ASSERT +( + is_same + < + compute_map_view_type + < + member_at::left, + bimap_with_left_type_as_unordered_multiset + + >::type, + + unordered_multimap_view + < + member_at::left, + bimap_with_left_type_as_unordered_multiset + > + + >::value +) + +\endcode + +See also unordered_multiset_of_relation. + **/ + +template +< + class KeyType, + class HashFunctor = hash< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type >, + class EqualKey = std::equal_to< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type > +> +struct unordered_multiset_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef KeyType user_type; + + /// Type of the object that will be stored in the container + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + /// Hash Functor that takes value_type objects + typedef HashFunctor hasher; + + /// Functor that compare two value_type objects for equality + typedef EqualKey key_equal; + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + BOOST_CLASS_REQUIRE3( hasher, std::size_t, value_type, + boost, UnaryFunctionConcept ); + + BOOST_CLASS_REQUIRE4( key_equal, bool, value_type, value_type, + boost, BinaryFunctionConcept ); + + typedef unordered_multiset_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_2CP( + + // binds to + multi_index::hashed_non_unique, + + // with + hasher, + key_equal + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::unordered_multimap_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::unordered_multiset_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief Set Of Relation Specification +/** +This struct is similar to unordered_multiset_of but it is bind logically +to a relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also unordered_multiset_of, is_set_type_of_relation. + **/ + +template +< + class HashFunctor = hash< _relation >, + class EqualKey = std::equal_to< _relation > +> +struct unordered_multiset_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + /// Hash Functor that takes value_type objects + typedef HashFunctor hasher; + + /// Functor that compare two value_type objects for equality + typedef EqualKey key_equal; + + + BOOST_BIMAP_GENERATE_RELATION_BINDER_2CP( + + // binds to + unordered_multiset_of, + + // with + hasher, + key_equal + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP + diff --git a/thirdparty/boost/bimap/unordered_set_of.hpp b/thirdparty/boost/bimap/unordered_set_of.hpp new file mode 100644 index 0000000..034df3d --- /dev/null +++ b/thirdparty/boost/bimap/unordered_set_of.hpp @@ -0,0 +1,230 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file unordered_set_of.hpp +/// \brief Include support for unordered_set constrains for the bimap container + +#ifndef BOOST_BIMAP_UNORDERED_SET_OF_HPP +#define BOOST_BIMAP_UNORDERED_SET_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + +/// \brief Set Type Specification +/** +This struct is used to specify an unordered_set specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an tr1::unordered_set instantiation, +except that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the +unordered_set type specification, rather it is a container +configuration parameter. +The first parameter is the type of the objects in the set, the +second one is a Hash Functor that takes objects of this type, and +the third one is a Functor that compares them for equality. +Bimap binding metafunctions can be used with this class in +the following way: + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< unordered_set_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + unordered_set_of::index_bind + < + KeyExtractor, + Tag + + >::type, + + hashed_unique< tag, KeyExtractor, HashFunctor, EqualKey > + + >::value +) + +typedef bimap +< + unordered_set_of, RightKeyType + +> bimap_with_left_type_as_unordered_set; + +BOOST_STATIC_ASSERT +( + is_same + < + unordered_set_of::map_view_bind + < + member_at::left, + bimap_with_left_type_as_unordered_set + + >::type, + + unordered_map_view + < + member_at::left, + bimap_with_left_type_as_unordered_set + > + + >::value +) + +\endcode + +See also unordered_set_of_relation. + **/ + +template +< + class KeyType, + class HashFunctor = hash< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type >, + class EqualKey = std::equal_to< BOOST_DEDUCED_TYPENAME + ::boost::bimaps::tags::support::value_type_of::type > +> +struct unordered_set_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef KeyType user_type; + + /// Type of the object that will be stored in the container + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + /// Hash Functor that takes value_type objects + typedef HashFunctor hasher; + + /// Functor that compare two value_type objects for equality + typedef EqualKey key_equal; + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + BOOST_CLASS_REQUIRE3( hasher, std::size_t, value_type, + boost, UnaryFunctionConcept ); + + BOOST_CLASS_REQUIRE4( key_equal, bool, value_type, value_type, + boost, BinaryFunctionConcept ); + + typedef unordered_set_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_2CP( + + // binds to + multi_index::hashed_unique, + + // with + hasher, + key_equal + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::unordered_map_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::unordered_set_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief Set Of Relation Specification +/** +This struct is similar to unordered_set_of but it is bind logically to +a relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also unordered_set_of, is_set_type_of_relation. + **/ + +template +< + class HashFunctor = hash< _relation >, + class EqualKey = std::equal_to< _relation > +> +struct unordered_set_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + /// Hash Functor that takes value_type objects + typedef HashFunctor hasher; + + /// Functor that compare two value_type objects for equality + typedef EqualKey key_equal; + + + BOOST_BIMAP_GENERATE_RELATION_BINDER_2CP( + + // binds to + unordered_set_of, + + // with + hasher, + key_equal + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_UNORDERED_SET_OF_HPP + diff --git a/thirdparty/boost/bimap/vector_of.hpp b/thirdparty/boost/bimap/vector_of.hpp new file mode 100644 index 0000000..ce8be21 --- /dev/null +++ b/thirdparty/boost/bimap/vector_of.hpp @@ -0,0 +1,186 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file vector_of.hpp +/// \brief Include support for vector constrains for the bimap container + +#ifndef BOOST_BIMAP_VECTOR_OF_HPP +#define BOOST_BIMAP_VECTOR_OF_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { + + +/// \brief Set Type Specification +/** +This struct is used to specify a set specification. +It is not a container, it is just a metaprogramming facility to +express the type of a set. Generally, this specification will +be used in other place to create a container. +It has the same syntax that an std::vector instantiation, except +that the allocator cannot be specified. The rationale behind +this difference is that the allocator is not part of the set +type specification, rather it is a container configuration +parameter. +The first parameter is the type of the objects in the set, and +the second one is a Functor that compares them. +Bimap binding metafunctions can be used with this class in +the following way: + +\code +using namespace support; + +BOOST_STATIC_ASSERT( is_set_type_of< vector_of >::value ) + +BOOST_STATIC_ASSERT +( + is_same + < + vector_of::index_bind + < + KeyExtractor, + Tag + + >::type, + + random_access< tag, KeyExtractor > + + >::value +) + +typedef bimap +< + vector_of, RightKeyType + +> bimap_with_left_type_as_vector; + +BOOST_STATIC_ASSERT +( + is_same + < + vector_of::map_view_bind + < + member_at::left, + bimap_with_left_type_as_vector + + >::type, + + vector_map_view< member_at::left, bimap_with_left_type_as_vector > + + >::value +) + +\endcode + +See also vector_of_relation. + **/ + +template< class Type > +struct vector_of : public ::boost::bimaps::detail::set_type_of_tag +{ + /// User type, can be tagged + typedef Type user_type; + + /// Type of the object that will be stored in the vector + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: + value_type_of::type value_type; + + + struct lazy_concept_checked + { + BOOST_CLASS_REQUIRE ( value_type, + boost, AssignableConcept ); + + typedef vector_of type; + }; + + BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP_NO_EXTRACTOR( + + // binds to + multi_index::random_access + ) + + BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( + + // binds to + views::vector_map_view + ) + + BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( + + // binds to + views::vector_set_view + ) + + typedef mpl::bool_ mutable_key; +}; + + +/// \brief Set Of Relation Specification +/** +This struct is similar to vector_of but it is bind logically to a +relation. It is used in the bimap instantiation to specify the +desired type of the main view. This struct implements internally +a metafunction named bind_to that manages the quite complicated +task of finding the right type of the set for the relation. + +\code +template +struct bind_to +{ + typedef -unspecified- type; +}; +\endcode + +See also vector_of, is_set_type_of_relation. + **/ + +struct vector_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag +{ + BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP( + + // binds to + vector_of + ) + + typedef mpl::bool_ left_mutable_key; + typedef mpl::bool_ right_mutable_key; +}; + + +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_VECTOR_OF_HPP + diff --git a/thirdparty/boost/bimap/views/list_map_view.hpp b/thirdparty/boost/bimap/views/list_map_view.hpp new file mode 100644 index 0000000..a5dc058 --- /dev/null +++ b/thirdparty/boost/bimap/views/list_map_view.hpp @@ -0,0 +1,182 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/list_map_view.hpp +/// \brief View of a side of a bimap. + +#ifndef BOOST_BIMAP_VIEWS_LIST_MAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_LIST_MAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +template< class Tag, class BimapType > +struct list_map_view_base +{ + typedef ::boost::bimaps::container_adaptor::list_map_adaptor + < + BOOST_DEDUCED_TYPENAME BimapType::core_type::BOOST_NESTED_TEMPLATE index::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + reverse_iterator_type_by::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_reverse_iterator_type_by::type, + ::boost::bimaps::container_adaptor::support::iterator_facade_to_base + < + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + iterator_type_by::type, + BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: + const_iterator_type_by::type + + >, + ::boost::mpl::na, + ::boost::mpl::na, + ::boost::bimaps::relation::detail:: + pair_to_relation_functor, + ::boost::bimaps::relation::support:: + get_pair_functor, + + BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::data_extractor + < + Tag, + BOOST_DEDUCED_TYPENAME BimapType::relation + + >::type + + > type; +}; + +#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES + +/// \brief View of a side of a bimap. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core. + +See also const_list_map_view. + **/ +template< class Tag, class BimapType > +class list_map_view +: + public list_map_view_base::type, + public ::boost::bimaps::detail:: + map_view_base< list_map_view,Tag,BimapType > + +{ + typedef BOOST_DEDUCED_TYPENAME list_map_view_base::type base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(list_map_view,Tag,BimapType) + + public: + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + list_map_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : + base_(c) {} + + list_map_view & operator=(const list_map_view & v) + { + this->base() = v.base(); + return *this; + } + + BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(base_) + + BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(base_) + + // Rearrange Operations + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } +}; + + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_reverse_iterator) \ +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::list_map_view > +{ + private: typedef ::boost::bimaps::views::list_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::list_map_view > +{ + private: typedef ::boost::bimaps::views::list_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_LIST_MAP_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/list_set_view.hpp b/thirdparty/boost/bimap/views/list_set_view.hpp new file mode 100644 index 0000000..f837a92 --- /dev/null +++ b/thirdparty/boost/bimap/views/list_set_view.hpp @@ -0,0 +1,108 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/list_set_view.hpp +/// \brief View of a side of a bimap that is signature compatible with std::list. + +#ifndef BOOST_BIMAP_VIEWS_LIST_SET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_LIST_SET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::list. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::list. + +See also const_list_set_view. + **/ + +template< class CoreIndex > +class list_set_view +: + public BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( + list_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + ), + + public ::boost::bimaps::detail:: + set_view_base< list_set_view< CoreIndex >, CoreIndex > +{ + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(list_set_view,CoreIndex) + + typedef BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( + list_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + + ) base_; + + public: + + list_set_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : + base_(c) {} + + list_set_view & operator=(const list_set_view & v) + { + this->base() = v.base(); + return *this; + } + + BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(base_) + + BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(base_) + + // Rearrange Operations + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_VIEWS_LIST_SET_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/map_view.hpp b/thirdparty/boost/bimap/views/map_view.hpp new file mode 100644 index 0000000..efa3217 --- /dev/null +++ b/thirdparty/boost/bimap/views/map_view.hpp @@ -0,0 +1,156 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/map_view.hpp +/// \brief View of a side of a bimap that is signature compatible with std::map. + +#ifndef BOOST_BIMAP_VIEWS_MAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_MAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a side of a bimap that is signature compatible with std::map. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::map. + +See also const_map_view. + **/ + +template< class Tag, class BimapType > +class map_view +: + public BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + map_adaptor, + Tag,BimapType, + reverse_iterator_type_by,const_reverse_iterator_type_by + ), + public ::boost::bimaps::detail:: + map_view_base< map_view,Tag,BimapType >, + public ::boost::bimaps::detail:: + unique_map_view_access< map_view, Tag, BimapType>::type +{ + typedef BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + map_adaptor, + Tag,BimapType, + reverse_iterator_type_by,const_reverse_iterator_type_by + + ) base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(map_view,Tag,BimapType) + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: + unique_map_view_access< + map_view, Tag, BimapType + + >::type unique_map_view_access_; + + public: + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + map_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : base_(c) {} + + using unique_map_view_access_::at; + using unique_map_view_access_::operator[]; + + BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(base_) + + map_view & operator=(const map_view & v) + { + this->base() = v.base(); + return *this; + } + + // It can be used enable_if here but the error message when there + // is no info is very clear like this + + template< class CompatibleKey > + const info_type & info_at(const CompatibleKey& k) const + { + BOOST_DEDUCED_TYPENAME base_::const_iterator iter = this->find(k); + if( iter == this->end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->info; + } + + template< class CompatibleKey > + info_type & info_at(const CompatibleKey& k) + { + BOOST_DEDUCED_TYPENAME base_::iterator iter = this->find(k); + if( iter == this->end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->info; + } +}; + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,key_compare) +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::map_view > +{ + private: typedef ::boost::bimaps::views::map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::map_view > +{ + private: typedef ::boost::bimaps::views::map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_MAP_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/multimap_view.hpp b/thirdparty/boost/bimap/views/multimap_view.hpp new file mode 100644 index 0000000..a991a32 --- /dev/null +++ b/thirdparty/boost/bimap/views/multimap_view.hpp @@ -0,0 +1,123 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/multimap_view.hpp +/// \brief View of a side of a bimap that is signature compatible with std::multimap. + +#ifndef BOOST_BIMAP_VIEWS_MULTIMAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_MULTIMAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a side of a bimap that is signature compatible with std::multimap. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::multimap. + +See also const_multimap_view. + **/ + +template< class Tag, class BimapType > +class multimap_view +: + public BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + multimap_adaptor, + Tag,BimapType, + reverse_iterator_type_by,const_reverse_iterator_type_by + ), + public ::boost::bimaps::detail:: + map_view_base< multimap_view,Tag,BimapType > + +{ + typedef BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + multimap_adaptor, + Tag,BimapType, + reverse_iterator_type_by,const_reverse_iterator_type_by + + ) base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(multimap_view,Tag,BimapType) + + public: + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + multimap_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) + : base_(c) {} + + BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(base_) + + multimap_view & operator=(const multimap_view & v) + { + this->base() = v.base(); + return *this; + } + + BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS +}; + + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,key_compare) +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::multimap_view > +{ + private: typedef ::boost::bimaps::views::multimap_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::multimap_view > +{ + private: typedef ::boost::bimaps::views::multimap_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_MAP_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/multiset_view.hpp b/thirdparty/boost/bimap/views/multiset_view.hpp new file mode 100644 index 0000000..c6d2513 --- /dev/null +++ b/thirdparty/boost/bimap/views/multiset_view.hpp @@ -0,0 +1,110 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/multiset_view.hpp +/// \brief View of a bimap that is signature compatible with std::multiset. + +#ifndef BOOST_BIMAP_VIEWS_MULTISET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_MULTISET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::multiset. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::multiset. + +See also const_multiset_view. + **/ + +template< class CoreIndex > +class multiset_view +: + public BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + multiset_adaptor, + CoreIndex, + reverse_iterator, + const_reverse_iterator + ), + + public ::boost::bimaps::detail:: + set_view_base< multiset_view< CoreIndex >, CoreIndex > +{ + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(multiset_view, CoreIndex) + + typedef BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + multiset_adaptor, + CoreIndex, + reverse_iterator, + const_reverse_iterator + + ) base_; + + public: + + multiset_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : base_(c) {} + + /* + template< class LowerBounder, class UpperBounder > + std::pair + range(LowerBounder lower,UpperBounder upper) const + { + return this->base().range( + + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + LowerBounder, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( lower, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ), + + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + UpperBounder, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( upper, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ) + + ); + } + */ + + multiset_view & operator=(const multiset_view & v) + { + this->base() = v.base(); return *this; + } + + BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_MULTISET_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/set_view.hpp b/thirdparty/boost/bimap/views/set_view.hpp new file mode 100644 index 0000000..e38a5f8 --- /dev/null +++ b/thirdparty/boost/bimap/views/set_view.hpp @@ -0,0 +1,106 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/set_view.hpp +/// \brief View of a bimap that is signature compatible with std::set. + +#ifndef BOOST_BIMAP_VIEWS_SET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_SET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::set. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::set. + +See also const_set_view. + **/ + +template< class CoreIndex > +class set_view +: + public BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + set_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + ), + + public ::boost::bimaps::detail:: + set_view_base< set_view< CoreIndex >, CoreIndex > +{ + typedef BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + set_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + + ) base_; + + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(set_view,CoreIndex) + + public: + + set_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : base_(c) {} + + /* + template< class LowerBounder, class UpperBounder > + std::pair + range(LowerBounder lower,UpperBounder upper) const + { + return this->base().range( + + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + LowerBounder, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( lower, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ), + + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + UpperBounder, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( upper, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ) + + ); + } + */ + + set_view & operator=(const set_view & v) + { + this->base() = v.base(); + return *this; + } +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_SET_VIEW_HPP + + diff --git a/thirdparty/boost/bimap/views/unconstrained_map_view.hpp b/thirdparty/boost/bimap/views/unconstrained_map_view.hpp new file mode 100644 index 0000000..7c740de --- /dev/null +++ b/thirdparty/boost/bimap/views/unconstrained_map_view.hpp @@ -0,0 +1,44 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unconstrained_map_view.hpp +/// \brief Unconstrained view of a side of a bimap. + +#ifndef BOOST_BIMAP_VIEWS_UNCONSTRAINED_MAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNCONSTRAINED_MAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief Unconstrained view of a side of a bimap. + +template< class Tag, class BimapType> +class unconstrained_map_view +{ + public: + template< class T > + unconstrained_map_view(const T & t) {} + + typedef void reference; + typedef void const_reference; + typedef void info_type; +}; + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNCONSTRAINED_MAP_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/unconstrained_set_view.hpp b/thirdparty/boost/bimap/views/unconstrained_set_view.hpp new file mode 100644 index 0000000..525b637 --- /dev/null +++ b/thirdparty/boost/bimap/views/unconstrained_set_view.hpp @@ -0,0 +1,42 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unconstrained_set_view.hpp +/// \brief Unconstrained view of a bimap. + +#ifndef BOOST_BIMAP_VIEWS_UNCONSTRAINED_SET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNCONSTRAINED_SET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief Unconstrained view of a bimap. + +template< class CoreIndex > +class unconstrained_set_view +{ + public: + template< class T > + unconstrained_set_view(const T & t) {} + + typedef void iterator; + typedef void const_iterator; +}; + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNCONSTRAINED_SET_VIEW_HPP diff --git a/thirdparty/boost/bimap/views/unordered_map_view.hpp b/thirdparty/boost/bimap/views/unordered_map_view.hpp new file mode 100644 index 0000000..0241a33 --- /dev/null +++ b/thirdparty/boost/bimap/views/unordered_map_view.hpp @@ -0,0 +1,174 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unordered_map_view.hpp +/// \brief View of a side of a bimap that is signature compatible with tr1::unordered_map. + +#ifndef BOOST_BIMAP_VIEWS_UNOREDERED_MAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNOREDERED_MAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief Map View of a bimap, signature compatible with tr1::unordered_map. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a tr1::unordered_map. + +See also const_unordered_map_view. + **/ + + +template< class Tag, class BimapType > +class unordered_map_view +: + public BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + unordered_map_adaptor, + Tag,BimapType, + local_iterator_type_by,const_local_iterator_type_by + ), + + public ::boost::bimaps::detail::map_view_base< + unordered_map_view,Tag,BimapType >, + public ::boost::bimaps::detail:: + unique_map_view_access< + unordered_map_view, Tag, BimapType>::type + +{ + typedef BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + unordered_map_adaptor, + Tag,BimapType, + local_iterator_type_by,const_local_iterator_type_by + + ) base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(unordered_map_view,Tag,BimapType) + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: + unique_map_view_access< + unordered_map_view, Tag, BimapType + + >::type unique_map_view_access_; + + public: + + typedef std::pair< + BOOST_DEDUCED_TYPENAME base_::iterator, + BOOST_DEDUCED_TYPENAME base_::iterator + > range_type; + + typedef std::pair< + BOOST_DEDUCED_TYPENAME base_::const_iterator, + BOOST_DEDUCED_TYPENAME base_::const_iterator + > const_range_type; + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + unordered_map_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) + : base_(c) {} + + using unique_map_view_access_::at; + using unique_map_view_access_::operator[]; + + unordered_map_view & operator=(const unordered_map_view & v) + { + this->base() = v.base(); + return *this; + } + + // It can be used enable_if here but the error message when there + // is no info is very clear like this + + template< class CompatibleKey > + const info_type & info_at(const CompatibleKey& k) const + { + BOOST_DEDUCED_TYPENAME base_::const_iterator iter = this->find(k); + if( iter == this->end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->info; + } + + template< class CompatibleKey > + info_type & info_at(const CompatibleKey& k) + { + BOOST_DEDUCED_TYPENAME base_::iterator iter = this->find(k); + if( iter == this->end() ) + { + ::boost::throw_exception( + std::out_of_range("bimap<>: invalid key") + ); + } + return iter->info; + } +}; + + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,local_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_local_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,hasher) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,key_equal) +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::unordered_map_view > +{ + private: typedef ::boost::bimaps::views::unordered_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::unordered_map_view > +{ + private: typedef ::boost::bimaps::views::unordered_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNOREDERED_MAP_VIEW_HPP + + diff --git a/thirdparty/boost/bimap/views/unordered_multimap_view.hpp b/thirdparty/boost/bimap/views/unordered_multimap_view.hpp new file mode 100644 index 0000000..d222adf --- /dev/null +++ b/thirdparty/boost/bimap/views/unordered_multimap_view.hpp @@ -0,0 +1,136 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unordered_multimap_view.hpp +/// \brief View of a side of a bimap that is signature compatible with tr1::unordered_multimap. + +#ifndef BOOST_BIMAP_VIEWS_UNOREDERED_MULTIMAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNOREDERED_MULTIMAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a side of a bimap that is signature compatible with tr1::unordered_multimap. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a tr1::unordered_multimap. + +See also const_unordered_multimap_view. + **/ + +template< class Tag, class BimapType > +class unordered_multimap_view +: + public BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + unordered_multimap_adaptor, + Tag,BimapType, + local_iterator_type_by,const_local_iterator_type_by + ), + + public ::boost::bimaps::detail::map_view_base< + unordered_multimap_view,Tag,BimapType > + +{ + typedef BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + unordered_multimap_adaptor, + Tag,BimapType, + local_iterator_type_by,const_local_iterator_type_by + + ) base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(unordered_multimap_view,Tag,BimapType) + + public: + + typedef std::pair< + BOOST_DEDUCED_TYPENAME base_::iterator, + BOOST_DEDUCED_TYPENAME base_::iterator + > range_type; + + typedef std::pair< + BOOST_DEDUCED_TYPENAME base_::const_iterator, + BOOST_DEDUCED_TYPENAME base_::const_iterator + > const_range_type; + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + unordered_multimap_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) + : base_(c) {} + + BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS + + unordered_multimap_view & operator=(const unordered_multimap_view & v) + { + this->base() = v.base(); + return *this; + } +}; + + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,local_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_local_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_range_type) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,hasher) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,key_equal) +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::unordered_multimap_view > +{ + private: typedef ::boost::bimaps::views::unordered_multimap_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::unordered_multimap_view > +{ + private: typedef ::boost::bimaps::views::unordered_multimap_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNOREDERED_MULTIMAP_VIEW_HPP + + diff --git a/thirdparty/boost/bimap/views/unordered_multiset_view.hpp b/thirdparty/boost/bimap/views/unordered_multiset_view.hpp new file mode 100644 index 0000000..4771952 --- /dev/null +++ b/thirdparty/boost/bimap/views/unordered_multiset_view.hpp @@ -0,0 +1,83 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unordered_multiset_view.hpp +/// \brief View of a bimap that is signature compatible with tr1::unordered_multiset. + +#ifndef BOOST_BIMAP_VIEWS_UNORDERED_MULTISET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNORDERED_MULTISET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::unordered_multiset. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::unordered_multiset. + +See also const_unordered_multiset_view. + **/ + +template< class CoreIndex > +class unordered_multiset_view +: + public BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + unordered_multiset_adaptor, + CoreIndex, + local_iterator, + const_local_iterator + + ), + + public ::boost::bimaps::detail:: + set_view_base< unordered_multiset_view< CoreIndex >, CoreIndex > +{ + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(unordered_multiset_view,CoreIndex) + + typedef BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + unordered_multiset_adaptor, + CoreIndex, + local_iterator, + const_local_iterator + + ) base_; + + public: + + unordered_multiset_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) + : base_(c) {} + + BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS + + unordered_multiset_view & operator=(const unordered_multiset_view & v) + { + this->base() = v.base(); + return *this; + } +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNORDERED_MULTISET_VIEW_HPP + + diff --git a/thirdparty/boost/bimap/views/unordered_set_view.hpp b/thirdparty/boost/bimap/views/unordered_set_view.hpp new file mode 100644 index 0000000..df8c7e5 --- /dev/null +++ b/thirdparty/boost/bimap/views/unordered_set_view.hpp @@ -0,0 +1,78 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/unordered_set_view.hpp +/// \brief View of a bimap that is signature compatible with tr1::unordered_set. + +#ifndef BOOST_BIMAP_VIEWS_UNORDERED_SET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_UNORDERED_SET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::unordered_set. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::unordered_set. + +See also const_unordered_set_view. + **/ + +template< class CoreIndex > +class unordered_set_view +: + public BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + unordered_set_adaptor, + CoreIndex, + local_iterator, + const_local_iterator + ), + + public ::boost::bimaps::detail:: + set_view_base< unordered_set_view< CoreIndex >, CoreIndex > +{ + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(unordered_set_view,CoreIndex) + + typedef BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( + unordered_set_adaptor, + CoreIndex, + local_iterator, + const_local_iterator + + ) base_; + + public: + + unordered_set_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) + : base_(c) {} + + unordered_set_view & operator=(const unordered_set_view & v) + { + this->base() = v.base(); + return *this; + } +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_UNORDERED_SET_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/vector_map_view.hpp b/thirdparty/boost/bimap/views/vector_map_view.hpp new file mode 100644 index 0000000..126b884 --- /dev/null +++ b/thirdparty/boost/bimap/views/vector_map_view.hpp @@ -0,0 +1,306 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/vector_map_view.hpp +/// \brief View of a side of a bimap. + +#ifndef BOOST_BIMAP_VIEWS_VECTOR_MAP_VIEW_HPP +#define BOOST_BIMAP_VIEWS_VECTOR_MAP_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a side of a bimap. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core. + +See also const_map_view. + **/ +template< class Tag, class BimapType > +class vector_map_view +: + public BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + vector_map_adaptor, + Tag,BimapType, + reverse_iterator_type_by, const_reverse_iterator_type_by + ), + + public ::boost::bimaps::detail:: + map_view_base< vector_map_view,Tag,BimapType > +{ + typedef BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( + vector_map_adaptor, + Tag,BimapType, + reverse_iterator_type_by, const_reverse_iterator_type_by + + ) base_; + + BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(vector_map_view,Tag,BimapType) + + typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::data_extractor + < + Tag, + BOOST_DEDUCED_TYPENAME BimapType::relation + + >::type key_from_base_value; + + public: + + typedef BOOST_DEDUCED_TYPENAME base_::value_type::info_type info_type; + + vector_map_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : + base_(c) {} + + vector_map_view & operator=(const vector_map_view & v) + { + this->base() = v.base(); + return *this; + } + + BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(base_) + + BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(base_) + + // Lists operations + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, vector_map_view & x) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base() + ); + } + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, + vector_map_view & x, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, + vector_map_view & x, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } + + void remove(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type value) + { + this->base().remove( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_to_base>()(value) + ); + } + + template< class Predicate > + void remove_if(Predicate pred) + { + this->base().remove_if( + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + Predicate, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( pred, key_from_base_value() ) + ); + } + + void unique() + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::equal_to, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >(std::equal_to(), + key_from_base_value() ) + ); + } + + template< class BinaryPredicate > + void unique(BinaryPredicate binary_pred) + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + BinaryPredicate, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( binary_pred, key_from_base_value() ) + ); + } + + void merge(vector_map_view & x) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( std::less(), + key_from_base_value() ) + ); + } + + template< class Compare > + void merge(vector_map_view & x, Compare comp) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( comp, key_from_base_value() ) + ); + } + + void sort() + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( std::less(), + key_from_base_value() ) + ); + } + + template< class Compare > + void sort(Compare comp) + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + key_from_base_value + + >( comp, key_from_base_value() ) + ); + } + + void reverse() + { + this->base().reverse(); + } + + // Rearrange Operations + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } + +}; + + +} // namespace views + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,TYPENAME) \ +typedef BOOST_DEDUCED_TYPENAME MAP_VIEW::TYPENAME \ + BOOST_PP_CAT(SIDE,BOOST_PP_CAT(_,TYPENAME)); +/*===========================================================================*/ + +/*===========================================================================*/ +#define BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(MAP_VIEW,SIDE) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,reverse_iterator) \ + BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF(MAP_VIEW,SIDE,const_reverse_iterator) \ +/*===========================================================================*/ + +namespace detail { + +template< class Tag, class BimapType > +struct left_map_view_extra_typedefs< ::boost::bimaps::views::vector_map_view > +{ + private: typedef ::boost::bimaps::views::vector_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,left) +}; + +template< class Tag, class BimapType > +struct right_map_view_extra_typedefs< ::boost::bimaps::views::vector_map_view > +{ + private: typedef ::boost::bimaps::views::vector_map_view map_view_; + public : BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY(map_view_,right) +}; + +} // namespace detail + +/*===========================================================================*/ +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEF +#undef BOOST_BIMAP_MAP_VIEW_EXTRA_TYPEDEFS_BODY +/*===========================================================================*/ + +} // namespace bimaps +} // namespace boost + +#endif // BOOST_BIMAP_VIEWS_VECTOR_MAP_VIEW_HPP + diff --git a/thirdparty/boost/bimap/views/vector_set_view.hpp b/thirdparty/boost/bimap/views/vector_set_view.hpp new file mode 100644 index 0000000..2f51229 --- /dev/null +++ b/thirdparty/boost/bimap/views/vector_set_view.hpp @@ -0,0 +1,279 @@ +// Boost.Bimap +// +// Copyright (c) 2006-2007 Matias Capeletto +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// \file views/vector_set_view.hpp +/// \brief View of a side of a bimap that is signature compatible with std::vector. + +#ifndef BOOST_BIMAP_VIEWS_VECTOR_SET_VIEW_HPP +#define BOOST_BIMAP_VIEWS_VECTOR_SET_VIEW_HPP + +#if defined(_MSC_VER) && (_MSC_VER>=1200) +#pragma once +#endif + +#include + +#include +#include +#include + + +namespace boost { +namespace bimaps { +namespace views { + +/// \brief View of a bimap that is signature compatible with std::vector. +/** + +This class uses container_adaptor and iterator_adaptor to wrapped a index of the +multi_index bimap core so it can be used as a std::vector. + +See also const_set_view. + **/ + +template< class CoreIndex > +class vector_set_view +: + public BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( + vector_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + ), + + public ::boost::bimaps::detail:: + set_view_base< vector_set_view< CoreIndex >, CoreIndex > +{ + BOOST_BIMAP_SET_VIEW_BASE_FRIEND(vector_set_view,CoreIndex) + + typedef BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( + vector_adaptor, + CoreIndex, + reverse_iterator, const_reverse_iterator + + ) base_; + + public: + + vector_set_view(BOOST_DEDUCED_TYPENAME base_::base_type & c) : + base_(c) {} + + vector_set_view & operator=(const vector_set_view & v) + { + this->base() = v.base(); + return *this; + } + + BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(base_) + + BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(base_) + + // List operations + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, + vector_set_view & x) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base() + ); + } + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, + vector_set_view & x, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void splice(BOOST_DEDUCED_TYPENAME base_::iterator position, + vector_set_view & x, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().splice( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + x.base(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } + + void remove(BOOST_DEDUCED_TYPENAME ::boost::call_traits< + BOOST_DEDUCED_TYPENAME base_::value_type >::param_type value) + { + this->base().remove( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_to_base>()(value) + ); + } + + template + void remove_if(Predicate pred) + { + this->base().remove_if( + ::boost::bimaps::container_adaptor::detail::unary_check_adaptor + < + Predicate, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( pred, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ) + ); + } + + void unique() + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::equal_to, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::equal_to(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ) + ); + } + + template< class BinaryPredicate > + void unique(BinaryPredicate binary_pred) + { + this->base().unique( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + BinaryPredicate, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( binary_pred, + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ) + ); + } + + void merge(vector_set_view & x) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::less(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ) + ); + } + + template< class Compare > + void merge(vector_set_view & x, Compare comp) + { + this->base().merge(x.base(), + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( comp, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ) + ); + } + + void sort() + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + std::less, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( + std::less(), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() + ) + ); + } + + template< class Compare > + void sort(Compare comp) + { + this->base().sort( + ::boost::bimaps::container_adaptor::detail::comparison_adaptor + < + Compare, + BOOST_DEDUCED_TYPENAME base_::base_type::value_type, + BOOST_DEDUCED_TYPENAME base_::value_from_base + + >( comp, this->template functor< + BOOST_DEDUCED_TYPENAME base_::value_from_base>() ) + ); + } + + void reverse() + { + this->base().reverse(); + } + + // Rearrange Operations + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator i) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i) + ); + } + + void relocate(BOOST_DEDUCED_TYPENAME base_::iterator position, + BOOST_DEDUCED_TYPENAME base_::iterator first, + BOOST_DEDUCED_TYPENAME base_::iterator last) + { + this->base().relocate( + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first), + this->template functor< + BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last) + ); + } + +}; + + +} // namespace views +} // namespace bimaps +} // namespace boost + + +#endif // BOOST_BIMAP_VIEWS_VECTOR_SET_VIEW_HPP + diff --git a/thirdparty/boost/bind.hpp b/thirdparty/boost/bind.hpp new file mode 100644 index 0000000..5f0821b --- /dev/null +++ b/thirdparty/boost/bind.hpp @@ -0,0 +1,1689 @@ +#ifndef BOOST_BIND_HPP_INCLUDED +#define BOOST_BIND_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind.hpp - binds function objects to arguments +// +// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// Copyright (c) 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +// Borland-specific bug, visit_each() silently fails to produce code + +#if defined(__BORLANDC__) +# define BOOST_BIND_VISIT_EACH boost::visit_each +#else +# define BOOST_BIND_VISIT_EACH visit_each +#endif + +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +namespace _bi // implementation details +{ + +// result_traits + +template struct result_traits +{ + typedef R type; +}; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +struct unspecified {}; + +template struct result_traits +{ + typedef typename F::result_type type; +}; + +template struct result_traits< unspecified, reference_wrapper > +{ + typedef typename F::result_type type; +}; + +#endif + +// ref_compare + +template bool ref_compare( T const & a, T const & b, long ) +{ + return a == b; +} + +template bool ref_compare( arg const &, arg const &, int ) +{ + return true; +} + +template bool ref_compare( arg (*) (), arg (*) (), int ) +{ + return true; +} + +template bool ref_compare( reference_wrapper const & a, reference_wrapper const & b, int ) +{ + return a.get_pointer() == b.get_pointer(); +} + +// bind_t forward declaration for listN + +template class bind_t; + +// value + +template class value +{ +public: + + value(T const & t): t_(t) {} + + T & get() { return t_; } + T const & get() const { return t_; } + + bool operator==(value const & rhs) const + { + return t_ == rhs.t_; + } + +private: + + T t_; +}; + +// type + +template class type {}; + +// unwrap + +template struct unwrapper +{ + static inline F & unwrap( F & f, long ) + { + return f; + } + + template static inline F2 & unwrap( reference_wrapper rf, int ) + { + return rf.get(); + } + + template static inline _mfi::dm unwrap( R T::* pm, int ) + { + return _mfi::dm( pm ); + } +}; + +// listN + +class list0 +{ +public: + + list0() {} + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A &, long) + { + return unwrapper::unwrap(f, 0)(); + } + + template R operator()(type, F const & f, A &, long) const + { + return unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F & f, A &, int) + { + unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F const & f, A &, int) const + { + unwrapper::unwrap(f, 0)(); + } + + template void accept(V &) const + { + } + + bool operator==(list0 const &) const + { + return true; + } +}; + +template< class A1 > class list1: private storage1< A1 > +{ +private: + + typedef storage1< A1 > base_type; + +public: + + explicit list1( A1 a1 ): base_type( a1 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list1 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0); + } +}; + +template< class A1, class A2 > class list2: private storage2< A1, A2 > +{ +private: + + typedef storage2< A1, A2 > base_type; + +public: + + list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list2 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0) && ref_compare(base_type::a2_, rhs.a2_, 0); + } +}; + +template< class A1, class A2, class A3 > class list3: private storage3< A1, A2, A3 > +{ +private: + + typedef storage3< A1, A2, A3 > base_type; + +public: + + list3( A1 a1, A2 a2, A3 a3 ): base_type( a1, a2, a3 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list3 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4 > class list4: private storage4< A1, A2, A3, A4 > +{ +private: + + typedef storage4< A1, A2, A3, A4 > base_type; + +public: + + list4( A1 a1, A2 a2, A3 a3, A4 a4 ): base_type( a1, a2, a3, a4 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list4 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class list5: private storage5< A1, A2, A3, A4, A5 > +{ +private: + + typedef storage5< A1, A2, A3, A4, A5 > base_type; + +public: + + list5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): base_type( a1, a2, a3, a4, a5 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list5 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ); + } +}; + +template class list6: private storage6< A1, A2, A3, A4, A5, A6 > +{ +private: + + typedef storage6< A1, A2, A3, A4, A5, A6 > base_type; + +public: + + list6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): base_type( a1, a2, a3, a4, a5, a6 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list6 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ); + } +}; + +template class list7: private storage7< A1, A2, A3, A4, A5, A6, A7 > +{ +private: + + typedef storage7< A1, A2, A3, A4, A5, A6, A7 > base_type; + +public: + + list7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): base_type( a1, a2, a3, a4, a5, a6, a7 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list7 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class list8: private storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ +private: + + typedef storage8< A1, A2, A3, A4, A5, A6, A7, A8 > base_type; + +public: + + list8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list8 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ); + } +}; + +template class list9: private storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > +{ +private: + + typedef storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > base_type; + +public: + + list9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + A9 operator[] (boost::arg<9>) const { return base_type::a9_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + A9 operator[] (boost::arg<9> (*) ()) const { return base_type::a9_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list9 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ) && + ref_compare( base_type::a9_, rhs.a9_, 0 ); + } +}; + +// bind_t + +#ifndef BOOST_NO_VOID_RETURNS + +template class bind_t +{ +public: + + typedef bind_t this_type; + + bind_t(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +#else + +template struct bind_t_generator +{ + +template class implementation +{ +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template<> struct bind_t_generator +{ + +template class implementation +{ +private: + + typedef void R; + +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template class bind_t: public bind_t_generator::BOOST_NESTED_TEMPLATE implementation +{ +public: + + bind_t(F f, L const & l): bind_t_generator::BOOST_NESTED_TEMPLATE implementation(f, l) {} + +}; + +#endif + +// function_equal + +#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in _bi, rely on ADL + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( bind_t const & a, bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( bind_t const & a, bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in boost + +} // namespace _bi + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( _bi::bind_t const & a, _bi::bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( _bi::bind_t const & a, _bi::bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +namespace _bi +{ + +#endif // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// add_value + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || (__SUNPRO_CC >= 0x530) + +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x582) ) + +template struct add_value +{ + typedef _bi::value type; +}; + +#else + +template< class T, int I > struct add_value_2 +{ + typedef boost::arg type; +}; + +template< class T > struct add_value_2< T, 0 > +{ + typedef _bi::value< T > type; +}; + +template struct add_value +{ + typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type; +}; + +#endif + +template struct add_value< value > +{ + typedef _bi::value type; +}; + +template struct add_value< reference_wrapper > +{ + typedef reference_wrapper type; +}; + +template struct add_value< arg > +{ + typedef boost::arg type; +}; + +template struct add_value< arg (*) () > +{ + typedef boost::arg (*type) (); +}; + +template struct add_value< bind_t > +{ + typedef bind_t type; +}; + +#else + +template struct _avt_0; + +template<> struct _avt_0<1> +{ + template struct inner + { + typedef T type; + }; +}; + +template<> struct _avt_0<2> +{ + template struct inner + { + typedef value type; + }; +}; + +typedef char (&_avt_r1) [1]; +typedef char (&_avt_r2) [2]; + +template _avt_r1 _avt_f(value); +template _avt_r1 _avt_f(reference_wrapper); +template _avt_r1 _avt_f(arg); +template _avt_r1 _avt_f(arg (*) ()); +template _avt_r1 _avt_f(bind_t); + +_avt_r2 _avt_f(...); + +template struct add_value +{ + static T t(); + typedef typename _avt_0::template inner::type type; +}; + +#endif + +// list_av_N + +template struct list_av_1 +{ + typedef typename add_value::type B1; + typedef list1 type; +}; + +template struct list_av_2 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef list2 type; +}; + +template struct list_av_3 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef list3 type; +}; + +template struct list_av_4 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef list4 type; +}; + +template struct list_av_5 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef list5 type; +}; + +template struct list_av_6 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef list6 type; +}; + +template struct list_av_7 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef list7 type; +}; + +template struct list_av_8 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef list8 type; +}; + +template struct list_av_9 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef typename add_value::type B9; + typedef list9 type; +}; + +// operator! + +struct logical_not +{ + template bool operator()(V const & v) const { return !v; } +}; + +template + bind_t< bool, logical_not, list1< bind_t > > + operator! (bind_t const & f) +{ + typedef list1< bind_t > list_type; + return bind_t ( logical_not(), list_type(f) ); +} + +// relational operators + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +struct name \ +{ \ + template bool operator()(V const & v, W const & w) const { return v op w; } \ +}; \ + \ +template \ + bind_t< bool, name, list2< bind_t, typename add_value::type > > \ + operator op (bind_t const & f, A2 a2) \ +{ \ + typedef typename add_value::type B2; \ + typedef list2< bind_t, B2> list_type; \ + return bind_t ( name(), list_type(f, a2) ); \ +} + +BOOST_BIND_OPERATOR( ==, equal ) +BOOST_BIND_OPERATOR( !=, not_equal ) + +BOOST_BIND_OPERATOR( <, less ) +BOOST_BIND_OPERATOR( <=, less_equal ) + +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +#undef BOOST_BIND_OPERATOR + +#if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) + +// resolve ambiguity with rel_ops + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +template \ + bind_t< bool, name, list2< bind_t, bind_t > > \ + operator op (bind_t const & f, bind_t const & g) \ +{ \ + typedef list2< bind_t, bind_t > list_type; \ + return bind_t ( name(), list_type(f, g) ); \ +} + +BOOST_BIND_OPERATOR( !=, not_equal ) +BOOST_BIND_OPERATOR( <=, less_equal ) +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +#endif + +// visit_each, ADL + +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) \ + && !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, value const & t, int ) +{ + using boost::visit_each; + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +} // namespace _bi + +// visit_each, no ADL + +#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) || defined( __BORLANDC__ ) \ + || (defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, _bi::value const & t, int ) +{ + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, _bi::bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +// is_bind_expression + +template< class T > struct is_bind_expression +{ + enum _vt { value = 0 }; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > > +{ + enum _vt { value = 1 }; +}; + +#endif + +// bind + +#ifndef BOOST_BIND +#define BOOST_BIND bind +#endif + +// generic function objects + +template + _bi::bind_t + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +// generic function objects, alternative syntax + +template + _bi::bind_t + BOOST_BIND(boost::type, F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// adaptable function objects + +template + _bi::bind_t<_bi::unspecified, F, _bi::list0> + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type()); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_1::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_2::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1, a2)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_3::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_4::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_5::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_6::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_7::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_8::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_9::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// function pointers + +#define BOOST_BIND_CC +#define BOOST_BIND_ST + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST + +#ifdef BOOST_BIND_ENABLE_STDCALL + +#define BOOST_BIND_CC __stdcall +#define BOOST_BIND_ST + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST + +#endif + +#ifdef BOOST_BIND_ENABLE_FASTCALL + +#define BOOST_BIND_CC __fastcall +#define BOOST_BIND_ST + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST + +#endif + +#ifdef BOOST_BIND_ENABLE_PASCAL + +#define BOOST_BIND_ST pascal +#define BOOST_BIND_CC + +#include + +#undef BOOST_BIND_ST +#undef BOOST_BIND_CC + +#endif + +// member function pointers + +#define BOOST_BIND_MF_NAME(X) X +#define BOOST_BIND_MF_CC + +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_BIND_MF_NAME(X) X##_cdecl +#define BOOST_BIND_MF_CC __cdecl + +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_BIND_MF_NAME(X) X##_stdcall +#define BOOST_BIND_MF_CC __stdcall + +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_BIND_MF_NAME(X) X##_fastcall +#define BOOST_BIND_MF_CC __fastcall + +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC + +#endif + +// data member pointers + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + || ( defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) ) + +template +_bi::bind_t< R, _mfi::dm, typename _bi::list_av_1::type > + BOOST_BIND(R T::*f, A1 a1) +{ + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t( F(f), list_type(a1) ); +} + +#else + +namespace _bi +{ + +template< class Pm, int I > struct add_cref; + +template< class M, class T > struct add_cref< M T::*, 0 > +{ + typedef M type; +}; + +template< class M, class T > struct add_cref< M T::*, 1 > +{ + typedef M const & type; +}; + +template< class R, class T > struct add_cref< R (T::*) (), 1 > +{ + typedef void type; +}; + +#if !( defined(__IBMCPP__) && BOOST_WORKAROUND( __IBMCPP__, BOOST_TESTED_AT(600) ) ) + +template< class R, class T > struct add_cref< R (T::*) () const, 1 > +{ + typedef void type; +}; + +#endif // __IBMCPP__ + +template struct isref +{ + enum value_type { value = 0 }; +}; + +template struct isref< R& > +{ + enum value_type { value = 1 }; +}; + +template struct isref< R* > +{ + enum value_type { value = 1 }; +}; + +template struct dm_result +{ + typedef typename add_cref< Pm, 1 >::type type; +}; + +template struct dm_result< Pm, bind_t > +{ + typedef typename bind_t::result_type result_type; + typedef typename add_cref< Pm, isref< result_type >::value >::type type; +}; + +} // namespace _bi + +template< class A1, class M, class T > + +_bi::bind_t< + typename _bi::dm_result< M T::*, A1 >::type, + _mfi::dm, + typename _bi::list_av_1::type +> + +BOOST_BIND( M T::*f, A1 a1 ) +{ + typedef typename _bi::dm_result< M T::*, A1 >::type result_type; + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) ); +} + +#endif + +} // namespace boost + +#ifndef BOOST_BIND_NO_PLACEHOLDERS + +# include + +#endif + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_HPP_INCLUDED diff --git a/thirdparty/boost/bind/apply.hpp b/thirdparty/boost/bind/apply.hpp new file mode 100644 index 0000000..5ca4e1d --- /dev/null +++ b/thirdparty/boost/bind/apply.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_BIND_APPLY_HPP_INCLUDED +#define BOOST_BIND_APPLY_HPP_INCLUDED + +// +// apply.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +template struct apply +{ + typedef R result_type; + + template result_type operator()(F & f) const + { + return f(); + } + + template result_type operator()(F & f, A1 & a1) const + { + return f(a1); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2) const + { + return f(a1, a2); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3) const + { + return f(a1, a2, a3); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4) const + { + return f(a1, a2, a3, a4); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const + { + return f(a1, a2, a3, a4, a5); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const + { + return f(a1, a2, a3, a4, a5, a6); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const + { + return f(a1, a2, a3, a4, a5, a6, a7); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const + { + return f(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const + { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_BIND_APPLY_HPP_INCLUDED diff --git a/thirdparty/boost/bind/arg.hpp b/thirdparty/boost/bind/arg.hpp new file mode 100644 index 0000000..c08291a --- /dev/null +++ b/thirdparty/boost/bind/arg.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_BIND_ARG_HPP_INCLUDED +#define BOOST_BIND_ARG_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/arg.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +namespace boost +{ + +template< int I > struct arg +{ + arg() + { + } + + template< class T > arg( T const & /* t */ ) + { + // static assert I == is_placeholder::value + typedef char T_must_be_placeholder[ I == is_placeholder::value? 1: -1 ]; + } +}; + +template< int I > bool operator==( arg const &, arg const & ) +{ + return true; +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< int I > struct is_placeholder< arg > +{ + enum _vt { value = I }; +}; + +template< int I > struct is_placeholder< arg (*) () > +{ + enum _vt { value = I }; +}; + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED diff --git a/thirdparty/boost/bind/bind_cc.hpp b/thirdparty/boost/bind/bind_cc.hpp new file mode 100644 index 0000000..9d8ca21 --- /dev/null +++ b/thirdparty/boost/bind/bind_cc.hpp @@ -0,0 +1,117 @@ +// +// bind/bind_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +template + _bi::bind_t + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) ()) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (); + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1), A1 a1) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1); + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2), A1 a1, A2 a2) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2); + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3), A1 a1, A2 a2, A3 a3) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3); + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4); + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5); + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6); + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7); + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8); + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8, B9), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8, B9); + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/thirdparty/boost/bind/bind_mf_cc.hpp b/thirdparty/boost/bind/bind_mf_cc.hpp new file mode 100644 index 0000000..49f43a1 --- /dev/null +++ b/thirdparty/boost/bind/bind_mf_cc.hpp @@ -0,0 +1,227 @@ +// +// bind/bind_mf_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +// 0 + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (), A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +// 1 + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +// 2 + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +// 3 + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +// 4 + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +// 5 + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +// 6 + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +// 7 + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +// 8 + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/thirdparty/boost/bind/bind_template.hpp b/thirdparty/boost/bind/bind_template.hpp new file mode 100644 index 0000000..d394a9b --- /dev/null +++ b/thirdparty/boost/bind/bind_template.hpp @@ -0,0 +1,345 @@ +// +// bind/bind_template.hpp +// +// Do not include this header directly. +// +// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + + typedef typename result_traits::type result_type; + + result_type operator()() + { + list0 a; + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + result_type operator()() const + { + list0 a; + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1) + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1) const + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1) + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1) const + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + + template result_type operator()(A1 & a1, A2 const & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 const & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + + template result_type operator()(A1 const & a1, A2 const & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) const + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) const + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) const + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) const + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) const + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) const + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) const + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) const + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) const + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type eval(A & a) + { + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type eval(A & a) const + { + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template void accept(V & v) const + { +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) + + using boost::visit_each; + +#endif + BOOST_BIND_VISIT_EACH(v, f_, 0); + l_.accept(v); + } + + bool compare(this_type const & rhs) const + { + return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_; + } + +private: + + F f_; + L l_; diff --git a/thirdparty/boost/bind/make_adaptable.hpp b/thirdparty/boost/bind/make_adaptable.hpp new file mode 100644 index 0000000..06ecccf --- /dev/null +++ b/thirdparty/boost/bind/make_adaptable.hpp @@ -0,0 +1,187 @@ +#ifndef BOOST_BIND_MAKE_ADAPTABLE_HPP_INCLUDED +#define BOOST_BIND_MAKE_ADAPTABLE_HPP_INCLUDED + +// +// make_adaptable.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace _bi +{ + +template class af0 +{ +public: + + typedef R result_type; + + explicit af0(F f): f_(f) + { + } + + result_type operator()() + { + return f_(); + } + + result_type operator()() const + { + return f_(); + } + +private: + + F f_; +}; + +template class af1 +{ +public: + + typedef R result_type; + typedef A1 argument_type; + typedef A1 arg1_type; + + explicit af1(F f): f_(f) + { + } + + result_type operator()(A1 a1) + { + return f_(a1); + } + + result_type operator()(A1 a1) const + { + return f_(a1); + } + +private: + + F f_; +}; + +template class af2 +{ +public: + + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + typedef A1 arg1_type; + typedef A2 arg2_type; + + explicit af2(F f): f_(f) + { + } + + result_type operator()(A1 a1, A2 a2) + { + return f_(a1, a2); + } + + result_type operator()(A1 a1, A2 a2) const + { + return f_(a1, a2); + } + +private: + + F f_; +}; + +template class af3 +{ +public: + + typedef R result_type; + typedef A1 arg1_type; + typedef A2 arg2_type; + typedef A3 arg3_type; + + explicit af3(F f): f_(f) + { + } + + result_type operator()(A1 a1, A2 a2, A3 a3) + { + return f_(a1, a2, a3); + } + + result_type operator()(A1 a1, A2 a2, A3 a3) const + { + return f_(a1, a2, a3); + } + +private: + + F f_; +}; + +template class af4 +{ +public: + + typedef R result_type; + typedef A1 arg1_type; + typedef A2 arg2_type; + typedef A3 arg3_type; + typedef A4 arg4_type; + + explicit af4(F f): f_(f) + { + } + + result_type operator()(A1 a1, A2 a2, A3 a3, A4 a4) + { + return f_(a1, a2, a3, a4); + } + + result_type operator()(A1 a1, A2 a2, A3 a3, A4 a4) const + { + return f_(a1, a2, a3, a4); + } + +private: + + F f_; +}; + +} // namespace _bi + +template _bi::af0 make_adaptable(F f) +{ + return _bi::af0(f); +} + +template _bi::af1 make_adaptable(F f) +{ + return _bi::af1(f); +} + +template _bi::af2 make_adaptable(F f) +{ + return _bi::af2(f); +} + +template _bi::af3 make_adaptable(F f) +{ + return _bi::af3(f); +} + +template _bi::af4 make_adaptable(F f) +{ + return _bi::af4(f); +} + +} // namespace boost + +#endif // #ifndef BOOST_BIND_MAKE_ADAPTABLE_HPP_INCLUDED diff --git a/thirdparty/boost/bind/mem_fn_cc.hpp b/thirdparty/boost/bind/mem_fn_cc.hpp new file mode 100644 index 0000000..afc35bf --- /dev/null +++ b/thirdparty/boost/bind/mem_fn_cc.hpp @@ -0,0 +1,103 @@ +// +// bind/mem_fn_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +template _mfi::BOOST_MEM_FN_NAME(mf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) ()) +{ + return _mfi::BOOST_MEM_FN_NAME(mf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) () const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf8)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf8)(f); +} diff --git a/thirdparty/boost/bind/mem_fn_template.hpp b/thirdparty/boost/bind/mem_fn_template.hpp new file mode 100644 index 0000000..ab42d63 --- /dev/null +++ b/thirdparty/boost/bind/mem_fn_template.hpp @@ -0,0 +1,1020 @@ +// +// bind/mem_fn_template.hpp +// +// Do not include this header directly +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +# define BOOST_MEM_FN_ENABLE_CONST_OVERLOADS +#endif + +// mf0 + +template class BOOST_MEM_FN_NAME(mf0) +{ +public: + + typedef R result_type; + typedef T * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) ()) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf0)(F f): f_(f) {} + + R operator()(T * p) const + { + BOOST_MEM_FN_RETURN (p->*f_)(); + } + + template R operator()(U & u) const + { + BOOST_MEM_FN_RETURN call(u, &u); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u) const + { + BOOST_MEM_FN_RETURN call(u, &u); + } + +#endif + + R operator()(T & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf0 + +template class BOOST_MEM_FN_NAME(cmf0) +{ +public: + + typedef R result_type; + typedef T const * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) () const) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf0)(F f): f_(f) {} + + template R operator()(U const & u) const + { + BOOST_MEM_FN_RETURN call(u, &u); + } + + R operator()(T const & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf1 + +template class BOOST_MEM_FN_NAME(mf1) +{ +public: + + typedef R result_type; + typedef T * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1)) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf1)(F f): f_(f) {} + + R operator()(T * p, A1 a1) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1); + } + + template R operator()(U & u, A1 a1) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1); + } + +#endif + + R operator()(T & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf1 + +template class BOOST_MEM_FN_NAME(cmf1) +{ +public: + + typedef R result_type; + typedef T const * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1) const) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf1)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1); + } + + R operator()(T const & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf2 + +template class BOOST_MEM_FN_NAME(mf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf2)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2); + } + + template R operator()(U & u, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf2 + +template class BOOST_MEM_FN_NAME(cmf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf2)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + } + + R operator()(T const & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf3 + +template class BOOST_MEM_FN_NAME(mf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf3)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf3 + +template class BOOST_MEM_FN_NAME(cmf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf3)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf4 + +template class BOOST_MEM_FN_NAME(mf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf4)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf4 + +template class BOOST_MEM_FN_NAME(cmf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf4)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf5 + +template class BOOST_MEM_FN_NAME(mf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf5)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf5 + +template class BOOST_MEM_FN_NAME(cmf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf5)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf6 + +template class BOOST_MEM_FN_NAME(mf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf6)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf6 + +template class BOOST_MEM_FN_NAME(cmf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf6)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf7 + +template class BOOST_MEM_FN_NAME(mf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf7)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf7 + +template class BOOST_MEM_FN_NAME(cmf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf7)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf8 + +template class BOOST_MEM_FN_NAME(mf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf8)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf8 + +template class BOOST_MEM_FN_NAME(cmf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf8)(F f): f_(f) {} + + R operator()(T const * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +#undef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS diff --git a/thirdparty/boost/bind/mem_fn_vw.hpp b/thirdparty/boost/bind/mem_fn_vw.hpp new file mode 100644 index 0000000..7f7daef --- /dev/null +++ b/thirdparty/boost/bind/mem_fn_vw.hpp @@ -0,0 +1,130 @@ +// +// bind/mem_fn_vw.hpp - void return helper wrappers +// +// Do not include this header directly +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +template struct BOOST_MEM_FN_NAME(mf0): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf0) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (); + explicit BOOST_MEM_FN_NAME(mf0)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf0)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf0): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf0) +{ + typedef R (BOOST_MEM_FN_CC T::*F) () const; + explicit BOOST_MEM_FN_NAME(cmf0)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf0)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf1): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf1) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1); + explicit BOOST_MEM_FN_NAME(mf1)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf1)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf1): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf1) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1) const; + explicit BOOST_MEM_FN_NAME(cmf1)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf1)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf2): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf2) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2); + explicit BOOST_MEM_FN_NAME(mf2)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf2)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf2): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf2) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2) const; + explicit BOOST_MEM_FN_NAME(cmf2)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf2)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf3): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf3) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3); + explicit BOOST_MEM_FN_NAME(mf3)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf3)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf3): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf3) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const; + explicit BOOST_MEM_FN_NAME(cmf3)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf3)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf4): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf4) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4); + explicit BOOST_MEM_FN_NAME(mf4)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf4)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf4): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf4) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const; + explicit BOOST_MEM_FN_NAME(cmf4)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf4)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf5): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf5) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5); + explicit BOOST_MEM_FN_NAME(mf5)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf5)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf5): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf5) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const; + explicit BOOST_MEM_FN_NAME(cmf5)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf5)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf6): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf6) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6); + explicit BOOST_MEM_FN_NAME(mf6)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf6)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf6): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf6) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const; + explicit BOOST_MEM_FN_NAME(cmf6)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf6)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf7): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf7) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7); + explicit BOOST_MEM_FN_NAME(mf7)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf7)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf7): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf7) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const; + explicit BOOST_MEM_FN_NAME(cmf7)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf7)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf8): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf8) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8); + explicit BOOST_MEM_FN_NAME(mf8)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf8)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf8): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf8) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const; + explicit BOOST_MEM_FN_NAME(cmf8)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf8)(f) {} +}; + diff --git a/thirdparty/boost/bind/placeholders.hpp b/thirdparty/boost/bind/placeholders.hpp new file mode 100644 index 0000000..dae5de3 --- /dev/null +++ b/thirdparty/boost/bind/placeholders.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED +#define BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/placeholders.hpp - _N definitions +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +namespace +{ + +#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400) + +static inline boost::arg<1> _1() { return boost::arg<1>(); } +static inline boost::arg<2> _2() { return boost::arg<2>(); } +static inline boost::arg<3> _3() { return boost::arg<3>(); } +static inline boost::arg<4> _4() { return boost::arg<4>(); } +static inline boost::arg<5> _5() { return boost::arg<5>(); } +static inline boost::arg<6> _6() { return boost::arg<6>(); } +static inline boost::arg<7> _7() { return boost::arg<7>(); } +static inline boost::arg<8> _8() { return boost::arg<8>(); } +static inline boost::arg<9> _9() { return boost::arg<9>(); } + +#elif defined(BOOST_MSVC) || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) || defined(__MWERKS__) + +static boost::arg<1> _1; +static boost::arg<2> _2; +static boost::arg<3> _3; +static boost::arg<4> _4; +static boost::arg<5> _5; +static boost::arg<6> _6; +static boost::arg<7> _7; +static boost::arg<8> _8; +static boost::arg<9> _9; + +#else + +boost::arg<1> _1; +boost::arg<2> _2; +boost::arg<3> _3; +boost::arg<4> _4; +boost::arg<5> _5; +boost::arg<6> _6; +boost::arg<7> _7; +boost::arg<8> _8; +boost::arg<9> _9; + +#endif + +} // unnamed namespace + +#endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED diff --git a/thirdparty/boost/bind/protect.hpp b/thirdparty/boost/bind/protect.hpp new file mode 100644 index 0000000..74ee1b9 --- /dev/null +++ b/thirdparty/boost/bind/protect.hpp @@ -0,0 +1,144 @@ +#ifndef BOOST_BIND_PROTECT_HPP_INCLUDED +#define BOOST_BIND_PROTECT_HPP_INCLUDED + +// +// protect.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace _bi +{ + +template class protected_bind_t +{ +public: + + typedef typename F::result_type result_type; + + explicit protected_bind_t(F f): f_(f) + { + } + + result_type operator()() + { + return f_(); + } + + result_type operator()() const + { + return f_(); + } + + template result_type operator()(A1 & a1) + { + return f_(a1); + } + + template result_type operator()(A1 & a1) const + { + return f_(a1); + } + + template result_type operator()(A1 & a1, A2 & a2) + { + return f_(a1, a2); + } + + template result_type operator()(A1 & a1, A2 & a2) const + { + return f_(a1, a2); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) + { + return f_(a1, a2, a3); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) const + { + return f_(a1, a2, a3); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) + { + return f_(a1, a2, a3, a4); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) const + { + return f_(a1, a2, a3, a4); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) + { + return f_(a1, a2, a3, a4, a5); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const + { + return f_(a1, a2, a3, a4, a5); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) + { + return f_(a1, a2, a3, a4, a5, a6); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const + { + return f_(a1, a2, a3, a4, a5, a6); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) + { + return f_(a1, a2, a3, a4, a5, a6, a7); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const + { + return f_(a1, a2, a3, a4, a5, a6, a7); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + +private: + + F f_; +}; + +} // namespace _bi + +template _bi::protected_bind_t protect(F f) +{ + return _bi::protected_bind_t(f); +} + +} // namespace boost + +#endif // #ifndef BOOST_BIND_PROTECT_HPP_INCLUDED diff --git a/thirdparty/boost/bind/storage.hpp b/thirdparty/boost/bind/storage.hpp new file mode 100644 index 0000000..512adc5 --- /dev/null +++ b/thirdparty/boost/bind/storage.hpp @@ -0,0 +1,475 @@ +#ifndef BOOST_BIND_STORAGE_HPP_INCLUDED +#define BOOST_BIND_STORAGE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/storage.hpp +// +// boost/bind.hpp support header, optimized storage +// +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +namespace _bi +{ + +// 1 + +template struct storage1 +{ + explicit storage1( A1 a1 ): a1_( a1 ) {} + + template void accept(V & v) const + { + BOOST_BIND_VISIT_EACH(v, a1_, 0); + } + + A1 a1_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( __BORLANDC__ ) + +template struct storage1< boost::arg > +{ + explicit storage1( boost::arg ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +template struct storage1< boost::arg (*) () > +{ + explicit storage1( boost::arg (*) () ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +#endif + +// 2 + +template struct storage2: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, A2 a2 ): storage1( a1 ), a2_( a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a2_, 0); + } + + A2 a2_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage2< A1, boost::arg >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +template struct storage2< A1, boost::arg (*) () >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg (*) () ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +#endif + +// 3 + +template struct storage3: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, A3 a3 ): storage2( a1, a2 ), a3_( a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a3_, 0); + } + + A3 a3_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage3< A1, A2, boost::arg >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +template struct storage3< A1, A2, boost::arg (*) () >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg (*) () ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +#endif + +// 4 + +template struct storage4: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, A4 a4 ): storage3( a1, a2, a3 ), a4_( a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a4_, 0); + } + + A4 a4_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage4< A1, A2, A3, boost::arg >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +template struct storage4< A1, A2, A3, boost::arg (*) () >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg (*) () ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +#endif + +// 5 + +template struct storage5: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): storage4( a1, a2, a3, a4 ), a5_( a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a5_, 0); + } + + A5 a5_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage5< A1, A2, A3, A4, boost::arg >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +template struct storage5< A1, A2, A3, A4, boost::arg (*) () >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg (*) () ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +#endif + +// 6 + +template struct storage6: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): storage5( a1, a2, a3, a4, a5 ), a6_( a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a6_, 0); + } + + A6 a6_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage6< A1, A2, A3, A4, A5, boost::arg >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +template struct storage6< A1, A2, A3, A4, A5, boost::arg (*) () >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg (*) () ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +#endif + +// 7 + +template struct storage7: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): storage6( a1, a2, a3, a4, a5, a6 ), a7_( a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a7_, 0); + } + + A7 a7_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg (*) () >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg (*) () ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +#endif + +// 8 + +template struct storage8: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): storage7( a1, a2, a3, a4, a5, a6, a7 ), a8_( a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a8_, 0); + } + + A8 a8_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg (*) () >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg (*) () ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +#endif + +// 9 + +template struct storage9: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ), a9_( a9 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a9_, 0); + } + + A9 a9_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg (*) () >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg (*) () ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +#endif + +} // namespace _bi + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_STORAGE_HPP_INCLUDED diff --git a/thirdparty/boost/blank.hpp b/thirdparty/boost/blank.hpp new file mode 100644 index 0000000..d67c869 --- /dev/null +++ b/thirdparty/boost/blank.hpp @@ -0,0 +1,100 @@ +//----------------------------------------------------------------------------- +// 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" + +#include // for std::basic_ostream forward declare + +#include "boost/detail/templated_streams.hpp" +#include "boost/mpl/bool.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 > + : mpl::true_ +{ +}; + +template <> +struct is_empty< blank > + : mpl::true_ +{ +}; + +template <> +struct is_stateless< blank > + : mpl::true_ +{ +}; + +// 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 +// +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; +} + +} // namespace boost + +#endif // BOOST_BLANK_HPP diff --git a/thirdparty/boost/blank_fwd.hpp b/thirdparty/boost/blank_fwd.hpp new file mode 100644 index 0000000..076a1f5 --- /dev/null +++ b/thirdparty/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/thirdparty/boost/call_traits.hpp b/thirdparty/boost/call_traits.hpp new file mode 100644 index 0000000..9add20e --- /dev/null +++ b/thirdparty/boost/call_traits.hpp @@ -0,0 +1,24 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp +// for full copyright notices. + +#ifndef BOOST_CALL_TRAITS_HPP +#define BOOST_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#include +#else +#include +#endif + +#endif // BOOST_CALL_TRAITS_HPP diff --git a/thirdparty/boost/cast.hpp b/thirdparty/boost/cast.hpp new file mode 100644 index 0000000..c2fadea --- /dev/null +++ b/thirdparty/boost/cast.hpp @@ -0,0 +1,107 @@ +// boost cast.hpp header file ----------------------------------------------// + +// (C) Copyright Kevlin Henney and Dave Abrahams 1999. +// Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/conversion for Documentation. + +// Revision History +// 23 JUn 05 numeric_cast removed and redirected to the new verion (Fernando Cacciola) +// 02 Apr 01 Removed BOOST_NO_LIMITS workarounds and included +// instead (the workaround did not +// actually compile when BOOST_NO_LIMITS was defined in +// any case, so we loose nothing). (John Maddock) +// 21 Jan 01 Undid a bug I introduced yesterday. numeric_cast<> never +// worked with stock GCC; trying to get it to do that broke +// vc-stlport. +// 20 Jan 01 Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp. +// Removed unused BOOST_EXPLICIT_TARGET macro. Moved +// boost::detail::type to boost/type.hpp. Made it compile with +// stock gcc again (Dave Abrahams) +// 29 Nov 00 Remove nested namespace cast, cleanup spacing before Formal +// Review (Beman Dawes) +// 19 Oct 00 Fix numeric_cast for floating-point types (Dave Abrahams) +// 15 Jul 00 Suppress numeric_cast warnings for GCC, Borland and MSVC +// (Dave Abrahams) +// 30 Jun 00 More MSVC6 wordarounds. See comments below. (Dave Abrahams) +// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes) +// 27 Jun 00 More MSVC6 workarounds +// 15 Jun 00 Add workarounds for MSVC6 +// 2 Feb 00 Remove bad_numeric_cast ";" syntax error (Doncho Angelov) +// 26 Jan 00 Add missing throw() to bad_numeric_cast::what(0 (Adam Levar) +// 29 Dec 99 Change using declarations so usages in other namespaces work +// correctly (Dave Abrahams) +// 23 Sep 99 Change polymorphic_downcast assert to also detect M.I. errors +// as suggested Darin Adler and improved by Valentin Bonnard. +// 2 Sep 99 Remove controversial asserts, simplify, rename. +// 30 Aug 99 Move to cast.hpp, replace value_cast with numeric_cast, +// place in nested namespace. +// 3 Aug 99 Initial version + +#ifndef BOOST_CAST_HPP +#define BOOST_CAST_HPP + +# include +# include +# include +# include +# include +# include + +// It has been demonstrated numerous times that MSVC 6.0 fails silently at link +// time if you use a template function which has template parameters that don't +// appear in the function's argument list. +// +// TODO: Add this to config.hpp? +# if defined(BOOST_MSVC) && BOOST_MSVC < 1300 +# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type* = 0 +# else +# define BOOST_EXPLICIT_DEFAULT_TARGET +# endif + +namespace boost +{ +// See the documentation for descriptions of how to choose between +// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<> + +// polymorphic_cast --------------------------------------------------------// + + // Runtime checked polymorphic downcasts and crosscasts. + // Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup, + // section 15.8 exercise 1, page 425. + + template + inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET) + { + Target tmp = dynamic_cast(x); + if ( tmp == 0 ) throw std::bad_cast(); + return tmp; + } + +// polymorphic_downcast ----------------------------------------------------// + + // BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited. + + // WARNING: Because this cast uses BOOST_ASSERT(), it violates + // the One Definition Rule if used in multiple translation units + // where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER + // NDEBUG are defined inconsistently. + + // Contributed by Dave Abrahams + + template + inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET) + { + BOOST_ASSERT( dynamic_cast(x) == x ); // detect logic error + return static_cast(x); + } + +# undef BOOST_EXPLICIT_DEFAULT_TARGET + +} // namespace boost + +# include + +#endif // BOOST_CAST_HPP diff --git a/thirdparty/boost/cerrno.hpp b/thirdparty/boost/cerrno.hpp new file mode 100644 index 0000000..1205455 --- /dev/null +++ b/thirdparty/boost/cerrno.hpp @@ -0,0 +1,331 @@ +// Boost cerrno.hpp header -------------------------------------------------// + +// Copyright Beman Dawes 2005. +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_CERRNO_HPP +#define BOOST_CERRNO_HPP + +#include + +// supply errno values likely to be missing, particularly on Windows + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 9901 +#endif + +#ifndef EADDRINUSE +#define EADDRINUSE 9902 +#endif + +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 9903 +#endif + +#ifndef EISCONN +#define EISCONN 9904 +#endif + +#ifndef EBADMSG +#define EBADMSG 9905 +#endif + +#ifndef ECONNABORTED +#define ECONNABORTED 9906 +#endif + +#ifndef EALREADY +#define EALREADY 9907 +#endif + +#ifndef ECONNREFUSED +#define ECONNREFUSED 9908 +#endif + +#ifndef ECONNRESET +#define ECONNRESET 9909 +#endif + +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 9910 +#endif + +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 9911 +#endif + +#ifndef EIDRM +#define EIDRM 9912 +#endif + +#ifndef EMSGSIZE +#define EMSGSIZE 9913 +#endif + +#ifndef ENETDOWN +#define ENETDOWN 9914 +#endif + +#ifndef ENETRESET +#define ENETRESET 9915 +#endif + +#ifndef ENETUNREACH +#define ENETUNREACH 9916 +#endif + +#ifndef ENOBUFS +#define ENOBUFS 9917 +#endif + +#ifndef ENOLINK +#define ENOLINK 9918 +#endif + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#ifndef ENOMSG +#define ENOMSG 9920 +#endif + +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 9921 +#endif + +#ifndef ENOSR +#define ENOSR 9922 +#endif + +#ifndef ENOTSOCK +#define ENOTSOCK 9923 +#endif + +#ifndef ENOSTR +#define ENOSTR 9924 +#endif + +#ifndef ENOTCONN +#define ENOTCONN 9925 +#endif + +#ifndef ENOTSUP +#define ENOTSUP 9926 +#endif + +#ifndef ECANCELED +#define ECANCELED 9927 +#endif + +#ifndef EINPROGRESS +#define EINPROGRESS 9928 +#endif + +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 9929 +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 9930 +#endif + +#ifndef EOWNERDEAD +#define EOWNERDEAD 9931 +#endif + +#ifndef EPROTO +#define EPROTO 9932 +#endif + +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 9933 +#endif + +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 9934 +#endif + +#ifndef ETIME +#define ETIME 9935 +#endif + +#ifndef ETXTBSY +#define ETXTBSY 9936 +#endif + +#ifndef ETIMEDOUT +#define ETIMEDOUT 9938 +#endif + +#ifndef ELOOP +#define ELOOP 9939 +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW 9940 +#endif + +#ifndef EPROTOTYPE +#define EPROTOTYPE 9941 +#endif + +#ifndef ENOSYS +#define ENOSYS 9942 +#endif + +#ifndef EINVAL +#define EINVAL 9943 +#endif + +#ifndef ERANGE +#define ERANGE 9944 +#endif + +#ifndef EILSEQ +#define EILSEQ 9945 +#endif + +// Windows Mobile doesn't appear to define these: + +#ifndef E2BIG +#define E2BIG 9946 +#endif + +#ifndef EDOM +#define EDOM 9947 +#endif + +#ifndef EFAULT +#define EFAULT 9948 +#endif + +#ifndef EBADF +#define EBADF 9949 +#endif + +#ifndef EPIPE +#define EPIPE 9950 +#endif + +#ifndef EXDEV +#define EXDEV 9951 +#endif + +#ifndef EBUSY +#define EBUSY 9952 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 9953 +#endif + +#ifndef ENOEXEC +#define ENOEXEC 9954 +#endif + +#ifndef EEXIST +#define EEXIST 9955 +#endif + +#ifndef EFBIG +#define EFBIG 9956 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 9957 +#endif + +#ifndef ENOTTY +#define ENOTTY 9958 +#endif + +#ifndef EINTR +#define EINTR 9959 +#endif + +#ifndef ESPIPE +#define ESPIPE 9960 +#endif + +#ifndef EIO +#define EIO 9961 +#endif + +#ifndef EISDIR +#define EISDIR 9962 +#endif + +#ifndef ECHILD +#define ECHILD 9963 +#endif + +#ifndef ENOLCK +#define ENOLCK 9964 +#endif + +#ifndef ENOSPC +#define ENOSPC 9965 +#endif + +#ifndef ENXIO +#define ENXIO 9966 +#endif + +#ifndef ENODEV +#define ENODEV 9967 +#endif + +#ifndef ENOENT +#define ENOENT 9968 +#endif + +#ifndef ESRCH +#define ESRCH 9969 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 9970 +#endif + +#ifndef ENOMEM +#define ENOMEM 9971 +#endif + +#ifndef EPERM +#define EPERM 9972 +#endif + +#ifndef EACCES +#define EACCES 9973 +#endif + +#ifndef EROFS +#define EROFS 9974 +#endif + +#ifndef EDEADLK +#define EDEADLK 9975 +#endif + +#ifndef EAGAIN +#define EAGAIN 9976 +#endif + +#ifndef ENFILE +#define ENFILE 9977 +#endif + +#ifndef EMFILE +#define EMFILE 9978 +#endif + +#ifndef EMLINK +#define EMLINK 9979 +#endif + +#endif // include guard diff --git a/thirdparty/boost/checked_delete.hpp b/thirdparty/boost/checked_delete.hpp new file mode 100644 index 0000000..e8f479f --- /dev/null +++ b/thirdparty/boost/checked_delete.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED +#define BOOST_CHECKED_DELETE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/checked_delete.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) 2003 Daniel Frey +// Copyright (c) 2003 Howard Hinnant +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/utility/checked_delete.html for documentation. +// + +namespace boost +{ + +// verify that types are complete for increased safety + +template inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +} + +template inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // boost:: disables ADL + boost::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + boost::checked_array_delete(x); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED diff --git a/thirdparty/boost/circular_buffer.hpp b/thirdparty/boost/circular_buffer.hpp new file mode 100644 index 0000000..01c6b90 --- /dev/null +++ b/thirdparty/boost/circular_buffer.hpp @@ -0,0 +1,74 @@ +// Circular buffer library header file. + +// Copyright (c) 2003-2007 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_HPP) +#define BOOST_CIRCULAR_BUFFER_HPP + +#if defined(_MSC_VER) && _MSC_VER >= 1200 + #pragma once +#endif + +#include "circular_buffer_fwd.hpp" +#include + +// BOOST_CB_ENABLE_DEBUG: Debug support control. +#if defined(NDEBUG) || defined(BOOST_CB_DISABLE_DEBUG) + #define BOOST_CB_ENABLE_DEBUG 0 +#else + #define BOOST_CB_ENABLE_DEBUG 1 +#endif + +// BOOST_CB_ASSERT: Runtime assertion. +#if BOOST_CB_ENABLE_DEBUG + #include + #define BOOST_CB_ASSERT(Expr) BOOST_ASSERT(Expr) +#else + #define BOOST_CB_ASSERT(Expr) ((void)0) +#endif + +// BOOST_CB_STATIC_ASSERT: Compile time assertion. +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + #define BOOST_CB_STATIC_ASSERT(Expr) ((void)0) +#else + #include + #define BOOST_CB_STATIC_ASSERT(Expr) BOOST_STATIC_ASSERT(Expr) +#endif + +// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type. +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) || \ + BOOST_WORKAROUND(BOOST_MSVC, < 1300) + #define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0) +#else + #include + #include + #define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \ + BOOST_CB_STATIC_ASSERT((is_convertible::value_type, Type>::value)) +#endif + +// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS: +// Check if the STL provides templated iterator constructors for its containers. +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + #define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_CB_STATIC_ASSERT(false); +#else + #define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0); +#endif + +#include "circular_buffer/debug.hpp" +#include "circular_buffer/details.hpp" +#include "circular_buffer/base.hpp" +#include "circular_buffer/space_optimized.hpp" + +#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS +#undef BOOST_CB_IS_CONVERTIBLE +#undef BOOST_CB_STATIC_ASSERT +#undef BOOST_CB_ASSERT +#undef BOOST_CB_ENABLE_DEBUG + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP) diff --git a/thirdparty/boost/circular_buffer/base.hpp b/thirdparty/boost/circular_buffer/base.hpp new file mode 100644 index 0000000..2d77c7a --- /dev/null +++ b/thirdparty/boost/circular_buffer/base.hpp @@ -0,0 +1,2617 @@ +// Implementation of the base circular buffer. + +// Copyright (c) 2003-2007 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_BASE_HPP) +#define BOOST_CIRCULAR_BUFFER_BASE_HPP + +#if defined(_MSC_VER) && _MSC_VER >= 1200 + #pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_EXCEPTIONS) + #include +#endif +#if BOOST_CB_ENABLE_DEBUG + #include +#endif +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + #include +#endif + +namespace boost { + +/*! + \class circular_buffer + \brief Circular buffer - a STL compliant container. + \param 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. + \param 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 */ +{ + +// Requirements + BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); + +public: +// Basic types + + //! The type of elements stored in the circular_buffer. + typedef typename Alloc::value_type value_type; + + //! A pointer to an element. + typedef typename Alloc::pointer pointer; + + //! A const pointer to the element. + typedef typename Alloc::const_pointer const_pointer; + + //! A reference to an element. + typedef typename Alloc::reference reference; + + //! A const reference to an element. + typedef typename Alloc::const_reference const_reference; + + //! The distance type. + /*! + (A signed integral type used to represent the distance between two iterators.) + */ + typedef typename Alloc::difference_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 Alloc::size_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 boost::reverse_iterator const_reverse_iterator; + + //! An iterator used to iterate backwards through a circular_buffer. + typedef boost::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 + 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 typename call_traits::param_type param_value_type; + + // A type representing the "best" way to return the value_type from a const method. + typedef typename call_traits::param_type return_value_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; + + //! The allocator. + allocator_type m_alloc; + +// 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 { return m_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() { return m_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() { 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() { 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 { return const_iterator(this, empty() ? 0 : m_first); } + + //! 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 { return const_iterator(this, 0); } + + //! 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() { 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() { 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 { 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 { 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 + */ + return_value_type 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 operator[] + */ + 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 + */ + return_value_type 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 + */ + return_value_type 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 + */ + return_value_type 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 Whatever T::T(const T&) throws. + \throws Whatever T::operator = (const T&) throws. + \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. + */ + 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)) { + m_alloc.construct(dest, *src); + ++constructed; + } else { + value_type tmp = *src; + replace(src, *dest); + replace(dest, 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; + } + +// 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 { 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 { + return (std::min)(m_alloc.max_size(), (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 { 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 { 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 { 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 { return m_end - m_buff; } + + //! Change the capacity of the circular_buffer. + /*! + \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). + \throws Whatever T::T(const T&) throws. + \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_copy_with_alloc(b, b + (std::min)(new_capacity, size()), buff, m_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). + \throws 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()) 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. + /*! + \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). + \throws Whatever T::T(const T&) throws. + \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_copy_with_alloc(e - (std::min)(new_capacity, size()), + e, buff, m_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). + \throws 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()) 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 a maximum capacity. + /*! + \post capacity() == max_size() \&\& size() == 0 + \param alloc The allocator. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Complexity + Constant. + \warning This constructor has been defined only due to compatibility with the STL container definition. Avoid + using it because it may allocate very large amount of memory (depending on allocator's + %max_size()). + */ + explicit circular_buffer(const allocator_type& alloc = allocator_type()) + : m_size(0), m_alloc(alloc) { + initialize(max_size()); + } + + //! Create an empty circular_buffer with the specified capacity. + /*! + \post capacity() == capacity \&\& size() == 0 + \param 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 capacity, const allocator_type& alloc = allocator_type()) + : m_size(0), m_alloc(alloc) { + initialize(capacity); + } + + /*! \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). + \throws 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()) + : m_size(n), m_alloc(alloc) { + initialize(n, item); + } + + /*! \brief Create a circular_buffer with the specified capacity and filled with n + copies of item. + \pre capacity >= n + \post capacity() == capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... + \&\& (*this)[n - 1] == item + \param 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). + \throws Whatever T::T(const T&) throws. + \par Complexity + Linear (in the n). + */ + circular_buffer(capacity_type capacity, size_type n, param_value_type item, + const allocator_type& alloc = allocator_type()) + : m_size(n), m_alloc(alloc) { + BOOST_CB_ASSERT(capacity >= size()); // check for capacity lower than size + initialize(capacity, item); + } + + //! 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). + \throws Whatever T::T(const T&) throws. + \par Complexity + Linear (in the size of cb). + */ + circular_buffer(const circular_buffer& cb) + : m_size(cb.size()), m_alloc(cb.get_allocator()) { + m_first = m_last = m_buff = allocate(cb.capacity()); + BOOST_TRY { + m_end = cb_details::uninitialized_copy_with_alloc(cb.begin(), cb.end(), m_buff, m_alloc); + } BOOST_CATCH(...) { + deallocate(m_buff, cb.capacity()); + BOOST_RETHROW + } + BOOST_CATCH_END + } + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + /*! \cond */ + template + circular_buffer(InputIterator first, InputIterator last) + : m_alloc(allocator_type()) { + initialize(first, last, is_integral()); + } + + template + circular_buffer(capacity_type capacity, InputIterator first, InputIterator last) + : m_alloc(allocator_type()) { + initialize(capacity, first, last, is_integral()); + } + /*! \endcond */ + +#else + + //! 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). + \throws 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()) + : m_alloc(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() == capacity \&\& 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. + \param 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). + \throws 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 capacity, InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : m_alloc(alloc) { + initialize(capacity, first, last, is_integral()); + } + +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + //! 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 + Linear (in the size of the circular_buffer). + \sa clear() + */ + ~circular_buffer() { + 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). + \throws 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_with_alloc(cb.begin(), cb.end(), buff, m_alloc), cb.capacity()); + } BOOST_CATCH(...) { + deallocate(buff, cb.capacity()); + BOOST_RETHROW + } + BOOST_CATCH_END + return *this; + } + + //! 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). + \throws 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 operator=, \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, m_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() == capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item + \&\& ... \&\& (*this) [n - 1] == item + \param 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). + \throws 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 operator=, \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, size_type n, param_value_type item) { + BOOST_CB_ASSERT(capacity >= n); // check for new capacity lower than n + assign_n(capacity, n, cb_details::assign_n(n, item, m_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). + \throws 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 operator=, \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() == capacity \&\& 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. + \param 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). + \throws 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 operator=, \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, InputIterator first, InputIterator last) { + assign(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) { + swap_allocator(cb, is_stateless()); + std::swap(m_buff, cb.m_buff); + std::swap(m_end, cb.m_end); + std::swap(m_first, cb.m_first); + std::swap(m_last, cb.m_last); + std::swap(m_size, cb.m_size); +#if BOOST_CB_ENABLE_DEBUG + invalidate_all_iterators(); + cb.invalidate_all_iterators(); +#endif + } + +// push and pop + + //! 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. + \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 = value_type()) { + if (full()) { + if (empty()) + return; + replace(m_last, item); + increment(m_last); + m_first = m_last; + } else { + m_alloc.construct(m_last, item); + increment(m_last); + ++m_size; + } + } + + //! 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. + \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 = value_type()) { + BOOST_TRY { + if (full()) { + if (empty()) + return; + decrement(m_first); + replace(m_first, item); + m_last = m_first; + } else { + decrement(m_first); + m_alloc.construct(m_first, item); + ++m_size; + } + } BOOST_CATCH(...) { + increment(m_first); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + //! 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; + } + +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. + \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 + 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 = value_type()) { + 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, item); + } + + //! 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. + \throws Whatever T::operator = (const T&) throws. + \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. + \throws Whatever T::operator = (const T&) throws. + \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()); + } + + //! 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. + \throws Whatever T::operator = (const T&) throws. + \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 = value_type()) { + 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, 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, *src); + increment(src); + increment(dest); + construct = false; + } + decrement(pos.m_it); + replace(pos.m_it, 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); + } + + //! 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. + \throws Whatever T::operator = (const T&) throws. + \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. + \throws Whatever T::operator = (const T&) throws. + \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 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 + 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), 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, *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 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 + 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), + 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, *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 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 + 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 symetric 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), 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, *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 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 + 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 symetric 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), + 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, *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 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 + Linear (in the size of the circular_buffer). + \sa ~circular_buffer(), erase(iterator), erase(iterator, iterator), + rerase(iterator), rerase(iterator, iterator) + */ + void clear() { + destroy_content(); + m_size = 0; + } + +private: +// Helper methods + + //! Check if the index is valid. + void check_position(size_type index) const { + if (index >= size()) + throw_exception(std::out_of_range("circular_buffer")); + } + + //! Increment the pointer. + template + void increment(Pointer& p) const { + if (++p == m_end) + p = m_buff; + } + + //! Decrement the pointer. + template + void decrement(Pointer& p) const { + if (p == m_buff) + p = m_end; + --p; + } + + //! Add n to the pointer. + template + Pointer add(Pointer p, difference_type n) const { + return p + (n < (m_end - p) ? n : n - capacity()); + } + + //! Subtract n from the pointer. + template + Pointer sub(Pointer p, difference_type n) const { + return p - (n > (p - m_buff) ? n - capacity() : n); + } + + //! Map the null pointer to virtual end of circular buffer. + pointer map_pointer(pointer p) const { return p == 0 ? m_last : p; } + + //! Allocate memory. + 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 : m_alloc.allocate(n, 0); + ::memset(p, cb_details::UNINITIALIZED, sizeof(value_type) * n); + return p; +#else + return (n == 0) ? 0 : m_alloc.allocate(n, 0); +#endif + } + + //! Deallocate memory. + void deallocate(pointer p, size_type n) { + if (p != 0) + m_alloc.deallocate(p, n); + } + + //! Does the pointer point to the uninitialized memory? + bool is_uninitialized(const_pointer p) const { + return p >= m_last && (m_first < m_last || p < m_first); + } + + //! Replace an element. + void replace(pointer pos, param_value_type item) { + *pos = item; +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, pos)); +#endif + } + + //! Construct or replace an element. + /*! + construct has to be set to true if and only if + pos points to an uninitialized memory. + */ + void construct_or_replace(bool construct, pointer pos, param_value_type item) { + if (construct) + m_alloc.construct(pos, item); + else + replace(pos, item); + } + + //! Destroy an item. + void destroy_item(pointer p) { + m_alloc.destroy(p); +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, p)); + ::memset(p, cb_details::UNINITIALIZED, sizeof(value_type)); +#endif + } + + //! Destroy an item only if it has been constructed. + void destroy_if_constructed(pointer pos) { + if (is_uninitialized(pos)) + destroy_item(pos); + } + + //! Destroy the whole content of the circular buffer. + void destroy_content() { + for (size_type ii = 0; ii < size(); ++ii, increment(m_first)) + destroy_item(m_first); + } + + //! Destroy content and free allocated memory. + void destroy() { + destroy_content(); + deallocate(m_buff, capacity()); +#if BOOST_CB_ENABLE_DEBUG + m_buff = 0; + m_first = 0; + m_last = 0; + m_end = 0; +#endif + } + + //! Initialize the circular buffer. + void initialize(capacity_type capacity) { + m_first = m_last = m_buff = allocate(capacity); + m_end = m_buff + capacity; + } + + //! Initialize the circular buffer. + void initialize(capacity_type capacity, param_value_type item) { + initialize(capacity); + BOOST_TRY { + cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, m_alloc); + } BOOST_CATCH(...) { + deallocate(m_buff, size()); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + //! Specialized initialize method. + template + void initialize(IntegralType n, IntegralType item, const true_type&) { + m_size = static_cast(n); + initialize(size(), item); + } + + //! Specialized initialize method. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + initialize(first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + initialize(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized initialize method. + 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, m_alloc); + size_type distance = tmp.size(); + initialize(distance, tmp.begin(), tmp.end(), distance); + } + + //! Specialized initialize method. + 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); + } + + //! Specialized initialize method. + template + void initialize(capacity_type capacity, IntegralType n, IntegralType item, const true_type&) { + BOOST_CB_ASSERT(capacity >= static_cast(n)); // check for capacity lower than n + m_size = static_cast(n); + initialize(capacity, item); + } + + //! Specialized initialize method. + template + void initialize(capacity_type capacity, Iterator first, Iterator last, const false_type&) { + BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) + initialize(capacity, first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + initialize(capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized initialize method. + template + void initialize(capacity_type capacity, + InputIterator first, + InputIterator last, + const std::input_iterator_tag&) { + initialize(capacity); + m_size = 0; + if (capacity == 0) + return; + while (first != last && !full()) { + m_alloc.construct(m_last, *first++); + increment(m_last); + ++m_size; + } + while (first != last) { + replace(m_last, *first++); + increment(m_last); + m_first = m_last; + } + } + + //! Specialized initialize method. + template + void initialize(capacity_type capacity, + ForwardIterator first, + ForwardIterator last, + const std::forward_iterator_tag&) { + BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range + initialize(capacity, first, last, std::distance(first, last)); + } + + //! Helper initialize method. + template + void initialize(capacity_type capacity, + ForwardIterator first, + ForwardIterator last, + size_type distance) { + initialize(capacity); + if (distance > capacity) { + std::advance(first, distance - capacity); + m_size = capacity; + } else { + m_size = distance; + if (distance != capacity) + m_last = m_buff + size(); + } + BOOST_TRY { + cb_details::uninitialized_copy_with_alloc(first, last, m_buff, m_alloc); + } BOOST_CATCH(...) { + deallocate(m_buff, capacity); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + //! Reset the circular buffer. + 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; + } + + //! Specialized method for swapping the allocator. + void swap_allocator(circular_buffer& cb, const true_type&) { + // Swap is not needed because allocators have no state. + } + + //! Specialized method for swapping the allocator. + void swap_allocator(circular_buffer& cb, const false_type&) { + std::swap(m_alloc, cb.m_alloc); + } + + //! Specialized assign method. + template + void assign(IntegralType n, IntegralType item, const true_type&) { + assign(static_cast(n), static_cast(item)); + } + + //! Specialized assign method. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + assign(first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + assign(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized assign method. + 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, m_alloc); + size_type distance = tmp.size(); + assign_n(distance, distance, + cb_details::assign_range::iterator, + allocator_type>(tmp.begin(), tmp.end(), m_alloc)); + } + + //! Specialized assign method. + 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::assign_range(first, last, m_alloc)); + } + + //! Specialized assign method. + template + void assign(capacity_type new_capacity, IntegralType n, IntegralType item, const true_type&) { + assign(new_capacity, static_cast(n), static_cast(item)); + } + + //! Specialized assign method. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + assign(new_capacity, first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized assign method. + 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 { +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + circular_buffer tmp(new_capacity, m_alloc); + tmp.insert(begin(), first, last); +#else + circular_buffer tmp(new_capacity, first, last, m_alloc); +#endif + tmp.swap(*this); + } + } + + //! Specialized assign method. + 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::assign_range(first, last, m_alloc)); + } + + //! Helper assign method. + 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()); + } + + //! Helper insert method. + iterator insert_item(const iterator& pos, param_value_type item) { + pointer p = pos.m_it; + if (p == 0) { + construct_or_replace(!full(), m_last, 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, *src); + decrement(dest); + construct = false; + } + replace(p, 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); + } + + //! Specialized insert method. + template + void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + insert(pos, static_cast(n), static_cast(item)); + } + + //! Specialized insert method. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + insert(pos, first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + insert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized insert method. + template + void insert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) { + if (!full() || pos != begin()) { + for (;first != last; ++pos) + pos = insert_item(pos, *first++); + } + } + + //! Specialized insert method. + 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)); + } + + //! Helper insert method. + 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)) + m_alloc.construct(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; + } + + //! Specialized rinsert method. + template + void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + rinsert(pos, static_cast(n), static_cast(item)); + } + + //! Specialized rinsert method. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + rinsert(pos, first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized insert method. + 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; + } + } + } + + //! Specialized rinsert method. + 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)); + } + + //! Helper rinsert method. + 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)) + m_alloc.construct(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; + } +}; + +// 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) { + 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/thirdparty/boost/circular_buffer/debug.hpp b/thirdparty/boost/circular_buffer/debug.hpp new file mode 100644 index 0000000..06ba45f --- /dev/null +++ b/thirdparty/boost/circular_buffer/debug.hpp @@ -0,0 +1,227 @@ +// Debug support for the circular buffer library. + +// Copyright (c) 2003-2007 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) && _MSC_VER >= 1200 + #pragma once +#endif + +namespace boost { + +namespace cb_details { + +#if BOOST_CB_ENABLE_DEBUG + +// The value the uninitialized memory is filled with. +const int UNINITIALIZED = 0xcc; + +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/thirdparty/boost/circular_buffer/details.hpp b/thirdparty/boost/circular_buffer/details.hpp new file mode 100644 index 0000000..7e5272e --- /dev/null +++ b/thirdparty/boost/circular_buffer/details.hpp @@ -0,0 +1,519 @@ +// Helper classes and functions for the circular buffer. + +// Copyright (c) 2003-2007 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_DETAILS_HPP) +#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP + +#if defined(_MSC_VER) && _MSC_VER >= 1200 + #pragma once +#endif + +#include +#include +#include +#include + +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_with_alloc( + InputIterator first, InputIterator last, ForwardIterator dest, Alloc& alloc); + +/*! + \struct const_traits + \brief Defines the data types for a const iterator. +*/ +template +struct const_traits { + // Basic types + typedef typename Traits::value_type value_type; + typedef typename Traits::const_pointer pointer; + typedef typename Traits::const_reference reference; + typedef typename Traits::size_type size_type; + typedef typename Traits::difference_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 Traits::value_type value_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef typename Traits::size_type size_type; + typedef typename Traits::difference_type difference_type; + + // Non-const traits + typedef nonconst_traits nonconst_self; +}; + +/*! + \struct helper_pointer + \brief Helper pointer used in the iterator. +*/ +template +struct helper_pointer { + bool m_end; + typename Traits::pointer m_it; +}; + +/*! + \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 Alloc::size_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 { + const Iterator& m_first; + const 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 { + uninitialized_copy_with_alloc(m_first, m_last, p, m_alloc); + } +private: + assign_range& operator = (const assign_range&); // do not generate +}; + +/*! + \struct 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 capacity of the adapted circular buffer. + Size m_min_capacity; + +public: + + //! Constructor. + capacity_control(Size capacity, Size min_capacity = 0) + : m_capacity(capacity), m_min_capacity(min_capacity) { + BOOST_CB_ASSERT(capacity >= min_capacity); // check for capacity lower than min_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; } +}; + +/*! + \class 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 +class iterator : + public boost::iterator< + std::random_access_iterator_tag, + typename Traits::value_type, + typename Traits::difference_type, + typename Traits::pointer, + typename Traits::reference> +#if BOOST_CB_ENABLE_DEBUG + , public debug_iterator_base +#endif // #if BOOST_CB_ENABLE_DEBUG +{ +private: +// Helper types + + //! Base iterator. + typedef boost::iterator< + std::random_access_iterator_tag, + typename Traits::value_type, + typename Traits::difference_type, + typename Traits::pointer, + typename Traits::reference> base_iterator; + + //! Non-const iterator. + typedef iterator nonconst_self; + +public: +// Basic types + + //! The type of the elements stored in the circular buffer. + typedef typename base_iterator::value_type value_type; + + //! Pointer to the element. + typedef typename base_iterator::pointer pointer; + + //! Reference to the element. + typedef typename base_iterator::reference reference; + + //! Size type. + typedef typename Traits::size_type size_type; + + //! Difference type. + typedef typename base_iterator::difference_type difference_type; + +public: +// Member variables + + //! The circular buffer where the iterator points to. + const Buff* m_buff; + + //! An internal iterator. + pointer m_it; + +public: +// 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. + 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; + } + +// 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. + 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 + helper_pointer lhs = create_helper_pointer(*this); + helper_pointer rhs = create_helper_pointer(it); + if (less(rhs, lhs) && lhs.m_it <= rhs.m_it) + return (lhs.m_it - rhs.m_it) + static_cast(m_buff->capacity()); + if (less(lhs, rhs) && lhs.m_it >= rhs.m_it) + return (lhs.m_it - rhs.m_it) - static_cast(m_buff->capacity()); + return lhs.m_it - rhs.m_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(m_buff->begin() - *this <= -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 less(create_helper_pointer(*this), create_helper_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); } + +private: +// Helpers + + //! Create helper pointer. + template + helper_pointer create_helper_pointer(const iterator& it) const { + helper_pointer helper; + helper.m_end = (it.m_it == 0); + helper.m_it = helper.m_end ? m_buff->m_last : it.m_it; + return helper; + } + + //! Less. + template + bool less(const InternalIterator0& lhs, const InternalIterator1& rhs) const { + difference_type ldiff = lhs.m_it - m_buff->m_first; + difference_type rdiff = rhs.m_it - m_buff->m_first; + if (ldiff < 0) { + if (rdiff < 0) + return lhs.m_it < rhs.m_it; + else if (rdiff == 0) + return rhs.m_end; + } else if (ldiff == 0) { + if (rdiff < 0) + return !lhs.m_end; + else if (rdiff == 0) + return !lhs.m_end && rhs.m_end; + else + return !lhs.m_end; + } else { // ldiff > 0 + if (rdiff < 0) + return true; + else if (rdiff == 0) + return rhs.m_end; + else + return lhs.m_it < rhs.m_it; + } + return false; + } +}; + +//! Iterator addition. +template +inline iterator +operator + (typename Traits::difference_type n, const iterator& it) { + return it + n; +} + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) + +//! Iterator category. +template +inline std::random_access_iterator_tag iterator_category(const iterator&) { + return std::random_access_iterator_tag(); +} + +//! The type of the elements stored in the circular buffer. +template +inline typename Traits::value_type* value_type(const iterator&) { return 0; } + +//! Distance type. +template +inline typename Traits::difference_type* distance_type(const iterator&) { return 0; } + +#endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) + +/*! + \fn ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest, + Alloc& alloc) + \brief Equivalent of std::uninitialized_copy with allocator. +*/ +template +inline ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest, + Alloc& alloc) { + ForwardIterator next = dest; + BOOST_TRY { + for (; first != last; ++first, ++dest) + alloc.construct(dest, *first); + } BOOST_CATCH(...) { + for (; next != dest; ++next) + alloc.destroy(next); + BOOST_RETHROW + } + BOOST_CATCH_END + return dest; +} + +/*! + \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) + alloc.construct(first, item); + } BOOST_CATCH(...) { + for (; next != first; ++next) + alloc.destroy(next); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +} // namespace cb_details + +} // namespace boost + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) diff --git a/thirdparty/boost/circular_buffer/space_optimized.hpp b/thirdparty/boost/circular_buffer/space_optimized.hpp new file mode 100644 index 0000000..7aa2069 --- /dev/null +++ b/thirdparty/boost/circular_buffer/space_optimized.hpp @@ -0,0 +1,1422 @@ +// Implementation of the circular buffer adaptor. + +// Copyright (c) 2003-2007 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_SPACE_OPTIMIZED_HPP) +#define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP + +#if defined(_MSC_VER) && _MSC_VER >= 1200 + #pragma once +#endif + +#include +#include + +namespace boost { + +/*! + \class circular_buffer_space_optimized + \brief Space optimized circular buffer container adaptor. + + For detailed documentation of the space_optimized_circular_buffer visit: + http://www.boost.org/libs/circular_buffer/doc/space_optimized.html +*/ +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::return_value_type return_value_type; + + //! Capacity controller of the space optimized circular buffer. + /*! +

+class capacity_control {
+   size_type m_capacity;
+   size_type m_min_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; }
+};

+ \pre 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::size; + using circular_buffer::max_size; + using circular_buffer::empty; + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + reference operator [] (size_type n) { return circular_buffer::operator[](n); } + return_value_type 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 { 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 { 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 { 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 { 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). + \throws Whatever T::T(const T&) throws. + \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). + \throws 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). + \throws Whatever T::T(const T&) throws. + \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). + \throws 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 a maximum capacity. + /*! + \post capacity().%capacity() == max_size() \&\& capacity().min_capacity() == 0 \&\& size() == 0 +

There is no memory allocated in the internal buffer. + \param alloc The allocator. + \throws Nothing. + \par Complexity + Constant. + */ + explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) + : circular_buffer(0, alloc) + , m_capacity_ctrl(max_size()) {} + + //! 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). + \throws 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) {} + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + /*! \cond */ + circular_buffer_space_optimized(const circular_buffer_space_optimized& cb) + : circular_buffer(cb.begin(), cb.end()) + , m_capacity_ctrl(cb.m_capacity_ctrl) {} + + template + circular_buffer_space_optimized(InputIterator first, InputIterator last) + : circular_buffer(first, last) + , m_capacity_ctrl(circular_buffer::capacity()) {} + + template + circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last) + : circular_buffer( + init_capacity(capacity_ctrl, first, last, is_integral()), + first, last) + , m_capacity_ctrl(capacity_ctrl) { + reduce_capacity( + is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type, std::input_iterator_tag >()); + } + /*! \endcond */ + +#else + + //! 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). + \throws 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) {} + + //! 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). + \throws Whatever T::T(const T&) throws. + \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). + \throws 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 BOOST_ITERATOR_CATEGORY::type, std::input_iterator_tag >()); + } + +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +#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(); + +#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; + } + + //! 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). + \throws 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 operator=, \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). + \throws 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 operator=, \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). + \throws 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 std::distance(first, last)). + \sa operator=, \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). + \throws 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 std::distance(first, last); in + min[capacity_ctrl.%capacity(), std::distance(first, last)] if the InputIterator + is a RandomAccessIterator). + \sa operator=, \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 \link swap(circular_buffer&, circular_buffer&) + swap(circular_buffer_space_optimized&, circular_buffer_space_optimized&)\endlink + */ + void swap(circular_buffer_space_optimized& cb) { + 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). + \throws 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 = value_type()) { + check_low_capacity(); + circular_buffer::push_back(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). + \throws 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 = value_type()) { + check_low_capacity(); + circular_buffer::push_front(item); + } + + //! 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). + \throws Whatever T::T(const T&) throws. + \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 = value_type()) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index, item); + } + + //! 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). + \throws Whatever T::T(const T&) throws. + \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). + \throws Whatever T::T(const T&) throws. + \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 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). + \throws Whatever T::T(const T&) throws. + \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 = value_type()) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index, item); + } + + //! 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). + \throws Whatever T::T(const T&) throws. + \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). + \throws Whatever T::T(const T&) throws. + \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). + \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 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). + \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 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). + \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). + \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). + \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). + \note Basically there is no difference between erase(iterator, iterator) and this method. It is + implemented only for consistency with the base + circular_buffer. + \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 + + //! Adjust the amount of allocated memory. + 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(); + } + + //! Ensure the reserve for possible growth up. + size_type ensure_reserve(size_type new_capacity, size_type size) const { + if (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; + } + + //! Check for low capacity. + /* + \post If the capacity is low it will be increased. + */ + 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 +# if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006)) + this->invalidate_iterators_except(end()); +# else + invalidate_iterators_except(end()); +# endif +#endif + } + + //! Check for high capacity. + /* + \post If the capacity is high it will be decreased. + */ + 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 +# if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006)) + this->invalidate_iterators_except(end()); +# else + invalidate_iterators_except(end()); +# endif +#endif + } + + //! Specialized method for reducing the capacity. + void reduce_capacity(const true_type&) { + circular_buffer::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size())); + } + + //! Specialized method for reducing the capacity. + void reduce_capacity(const false_type&) {} + + //! Determine the initial capacity. + 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); + } + + //! Specialized method for determining the initial capacity. + template + static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType item, + const true_type&) { + return init_capacity(capacity_ctrl, static_cast(n)); + } + + //! Specialized method for determining the initial capacity. + 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(__BORLANDC__, BOOST_TESTED_AT(0x581)) + return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY::type()); +#else + return init_capacity( + capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY::type()); +#endif + } + + //! Specialized method for determining the initial capacity. + template + static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator first, InputIterator last, + const std::input_iterator_tag&) { + return capacity_ctrl.capacity(); + } + + //! Specialized method for determining the initial capacity. + 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)))); + } + + //! Specialized insert method. + template + void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + insert(pos, static_cast(n), static_cast(item)); + } + + //! Specialized insert method. + 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); + } + + //! Specialized rinsert method. + template + void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) { + rinsert(pos, static_cast(n), static_cast(item)); + } + + //! Specialized rinsert method. + 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) { + 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/thirdparty/boost/circular_buffer_fwd.hpp b/thirdparty/boost/circular_buffer_fwd.hpp new file mode 100644 index 0000000..2b87bfd --- /dev/null +++ b/thirdparty/boost/circular_buffer_fwd.hpp @@ -0,0 +1,43 @@ +// Forward declaration of the circular buffer and its adaptor. + +// Copyright (c) 2003-2007 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) && _MSC_VER >= 1200 + #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/thirdparty/boost/compatibility/cpp_c_headers/cassert b/thirdparty/boost/compatibility/cpp_c_headers/cassert new file mode 100644 index 0000000..5bc7329 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cassert @@ -0,0 +1,10 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CASSERT_HEADER +#define __CASSERT_HEADER + +#include + +#endif // CASSERT_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cctype b/thirdparty/boost/compatibility/cpp_c_headers/cctype new file mode 100644 index 0000000..1ad03cb --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cctype @@ -0,0 +1,26 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CCTYPE_HEADER +#define __CCTYPE_HEADER + +#include + +namespace std { + using ::isalnum; + using ::isdigit; + using ::isprint; + using ::isupper; + using ::tolower; + using ::isalpha; + using ::isgraph; + using ::ispunct; + using ::isxdigit; + using ::toupper; + using ::iscntrl; + using ::islower; + using ::isspace; +} + +#endif // CCTYPE_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cerrno b/thirdparty/boost/compatibility/cpp_c_headers/cerrno new file mode 100644 index 0000000..4d57b80 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cerrno @@ -0,0 +1,10 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CERRNO_HEADER +#define __CERRNO_HEADER + +#include + +#endif // CERRNO_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cfloat b/thirdparty/boost/compatibility/cpp_c_headers/cfloat new file mode 100644 index 0000000..9d3d533 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cfloat @@ -0,0 +1,10 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CFLOAT_HEADER +#define __CFLOAT_HEADER + +#include + +#endif // CFLOAT_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/climits b/thirdparty/boost/compatibility/cpp_c_headers/climits new file mode 100644 index 0000000..b71b7f5 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/climits @@ -0,0 +1,10 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CLIMITS_HEADER +#define __CLIMITS_HEADER + +#include + +#endif // CLIMITS_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/clocale b/thirdparty/boost/compatibility/cpp_c_headers/clocale new file mode 100644 index 0000000..b3ba3c8 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/clocale @@ -0,0 +1,16 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CLOCALE_HEADER +#define __CLOCALE_HEADER + +#include + +namespace std { + using ::lconv; + using ::localeconv; + using ::setlocale; +} + +#endif // CLOCALE_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cmath b/thirdparty/boost/compatibility/cpp_c_headers/cmath new file mode 100644 index 0000000..70dc884 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cmath @@ -0,0 +1,35 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CMATH_HEADER +#define __CMATH_HEADER + +#include + +namespace std { + using ::acos; + using ::cos; + using ::fmod; + using ::modf; + using ::tan; + using ::asin; + using ::cosh; + using ::frexp; + using ::pow; + using ::tanh; + using ::atan; + using ::exp; + using ::ldexp; + using ::sin; + using ::atan2; + using ::fabs; + using ::log; + using ::sinh; + using ::ceil; + using ::floor; + using ::log10; + using ::sqrt; +} + +#endif // CMATH_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/csetjmp b/thirdparty/boost/compatibility/cpp_c_headers/csetjmp new file mode 100644 index 0000000..aa6a019 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/csetjmp @@ -0,0 +1,15 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSETJMP_HEADER +#define __CSETJMP_HEADER + +#include + +namespace std { + using ::jmp_buf; + using ::longjmp; +} + +#endif // CSETJMP_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/csignal b/thirdparty/boost/compatibility/cpp_c_headers/csignal new file mode 100644 index 0000000..37e11d9 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/csignal @@ -0,0 +1,16 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSIGNAL_HEADER +#define __CSIGNAL_HEADER + +#include + +namespace std { + using ::sig_atomic_t; + using ::raise; + using ::signal; +} + +#endif // CSIGNAL_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cstdarg b/thirdparty/boost/compatibility/cpp_c_headers/cstdarg new file mode 100644 index 0000000..5e1dd74 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cstdarg @@ -0,0 +1,14 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSTDARG_HEADER +#define __CSTDARG_HEADER + +#include + +namespace std { + using ::va_list; +} + +#endif // CSTDARG_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cstddef b/thirdparty/boost/compatibility/cpp_c_headers/cstddef new file mode 100644 index 0000000..c00a55c --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cstddef @@ -0,0 +1,15 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSTDDEF_HEADER +#define __CSTDDEF_HEADER + +#include + +namespace std { + using ::ptrdiff_t; + using ::size_t; +} + +#endif // CSTDDEF_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cstdio b/thirdparty/boost/compatibility/cpp_c_headers/cstdio new file mode 100644 index 0000000..8a48077 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cstdio @@ -0,0 +1,57 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSTDIO_HEADER +#define __CSTDIO_HEADER + +#include + +namespace std { + using ::FILE; + using ::fpos_t; + using ::size_t; + using ::clearerr; + using ::fgets; + using ::fscanf; + using ::gets; + using ::rename; + using ::tmpfile; + using ::fclose; + using ::fopen; + using ::fseek; + using ::perror; + using ::rewind; + using ::tmpnam; + using ::feof; + using ::fprintf; + using ::fsetpos; + using ::printf; + using ::scanf; + using ::ungetc; + using ::ferror; + using ::fputc; + using ::ftell; + using ::putc; + using ::setbuf; + using ::vfprintf; + using ::fflush; + using ::fputs; + using ::fwrite; + using ::putchar; + using ::setvbuf; + using ::vprintf; + using ::fgetc; + using ::fread; + using ::getc; + using ::puts; + using ::sprintf; + using ::vsprintf; + using ::fgetpos; + using ::freopen; + using ::getchar; + using ::remove; + using ::sscanf; +} + +#endif // CSTDIO_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cstdlib b/thirdparty/boost/compatibility/cpp_c_headers/cstdlib new file mode 100644 index 0000000..7592ffc --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cstdlib @@ -0,0 +1,43 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSTDLIB_HEADER +#define __CSTDLIB_HEADER + +#include + +namespace std { + using ::abort; + using ::atexit; + using ::exit; + using ::getenv; + using ::system; + using ::calloc; + using ::malloc; + using ::free; + using ::realloc; + using ::atol; + using ::mblen; + using ::strtod; + using ::wctomb; + using ::atof; + using ::mbstowcs; + using ::strtol; + using ::wcstombs; + using ::atoi; + using ::mbtowc; + using ::strtoul; + using ::bsearch; + using ::qsort; + using ::div_t; + using ::ldiv_t; + using ::abs; + using ::labs; + using ::srand; + using ::div; + using ::ldiv; + using ::rand; +} + +#endif // CSTDLIB_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cstring b/thirdparty/boost/compatibility/cpp_c_headers/cstring new file mode 100644 index 0000000..e913597 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cstring @@ -0,0 +1,36 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CSTRING_HEADER +#define __CSTRING_HEADER + +#include + +namespace std { + using ::size_t; + using ::memchr; + using ::strcat; + using ::strcspn; + using ::strncpy; + using ::strtok; + using ::memcmp; + using ::strchr; + using ::strerror; + using ::strpbrk; + using ::strxfrm; + using ::memcpy; + using ::strcmp; + using ::strlen; + using ::strrchr; + using ::memmove; + using ::strcoll; + using ::strncat; + using ::strspn; + using ::memset; + using ::strcpy; + using ::strncmp; + using ::strstr; +} + +#endif // CSTRING_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/ctime b/thirdparty/boost/compatibility/cpp_c_headers/ctime new file mode 100644 index 0000000..0c8ac9a --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/ctime @@ -0,0 +1,26 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CTIME_HEADER +#define __CTIME_HEADER + +#include + +namespace std { + using ::size_t; + using ::clock_t; + using ::time_t; + using ::tm; + using ::asctime; + using ::clock; + using ::difftime; + using ::localtime; + using ::strftime; + using ::ctime; + using ::gmtime; + using ::mktime; + using ::time; +} + +#endif // CTIME_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cwchar b/thirdparty/boost/compatibility/cpp_c_headers/cwchar new file mode 100644 index 0000000..f9fbd30 --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cwchar @@ -0,0 +1,156 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CWCHAR_HEADER +#define __CWCHAR_HEADER + +#include + +namespace std { + using ::mbstate_t; + using ::wint_t; + using ::size_t; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::btowc; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::getwchar; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::ungetwc; +#endif + using ::wcscpy; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wcsrtombs; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wmemchr; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::fgetwc; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::mbrlen; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::vfwprintf; +#endif +#endif + using ::wcscspn; + using ::wcsspn; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wmemcmp; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::fgetws; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::mbrtowc; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::vswprintf; +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::wcsftime; +#endif + using ::wcsstr; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wmemcpy; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::fputwc; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::mbsinit; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::vwprintf; +#endif +#endif + using ::wcslen; + using ::wcstod; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wmemmove; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::fputws; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::mbsrtowcs; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wcrtomb; +#endif + using ::wcsncat; + using ::wcstok; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wmemset; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) +#if !(defined(__DECCXX_VER) && __DECCXX_VER <= 60290024) + using ::fwide; +#endif +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::putwc; +#endif + using ::wcscat; + using ::wcsncmp; + using ::wcstol; +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wprintf; +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::fwprintf; +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::putwchar; +#endif + using ::wcschr; + using ::wcsncpy; + using ::wcstoul; +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wscanf; +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::fwscanf; +#endif +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::swprintf; +#endif +#endif + using ::wcscmp; + using ::wcspbrk; + using ::wcsxfrm; +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) + using ::getwc; +#endif +#if !(defined(__linux) && defined(__DECCXX_VER) && __DECCXX_VER <= 60390005) +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::swscanf; +#endif +#endif + using ::wcscoll; + using ::wcsrchr; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wctob; +#endif +} + +#endif // CWCHAR_HEADER diff --git a/thirdparty/boost/compatibility/cpp_c_headers/cwctype b/thirdparty/boost/compatibility/cpp_c_headers/cwctype new file mode 100644 index 0000000..cf8f07b --- /dev/null +++ b/thirdparty/boost/compatibility/cpp_c_headers/cwctype @@ -0,0 +1,39 @@ +// This file is automatically generated. Do not edit. +// ['../../libs/compatibility/generate_cpp_c_headers.py'] +// Wed Jul 23 12:11:19 2003 ('GMTST', 'GMTST') + +#ifndef __CWCTYPE_HEADER +#define __CWCTYPE_HEADER + +#include + +namespace std { +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wctrans_t; +#endif + using ::wctype_t; + using ::wint_t; + using ::iswalnum; + using ::iswctype; + using ::iswlower; + using ::iswspace; +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::towctrans; +#endif +#if !(defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 740) + using ::wctrans; +#endif + using ::iswalpha; + using ::iswdigit; + using ::iswprint; + using ::iswupper; + using ::towlower; + using ::wctype; + using ::iswcntrl; + using ::iswgraph; + using ::iswpunct; + using ::iswxdigit; + using ::towupper; +} + +#endif // CWCTYPE_HEADER diff --git a/thirdparty/boost/compressed_pair.hpp b/thirdparty/boost/compressed_pair.hpp new file mode 100644 index 0000000..512c2a0 --- /dev/null +++ b/thirdparty/boost/compressed_pair.hpp @@ -0,0 +1,24 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp +// for full copyright notices. + +#ifndef BOOST_COMPRESSED_PAIR_HPP +#define BOOST_COMPRESSED_PAIR_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#include +#else +#include +#endif + +#endif // BOOST_COMPRESSED_PAIR_HPP diff --git a/thirdparty/boost/concept/assert.hpp b/thirdparty/boost/concept/assert.hpp new file mode 100644 index 0000000..11c86cc --- /dev/null +++ b/thirdparty/boost/concept/assert.hpp @@ -0,0 +1,46 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP +# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP + +# include +# include + +// The old protocol used a constraints() member function in concept +// checking classes. If the compiler supports SFINAE, we can detect +// that function and seamlessly support the old concept checking +// classes. In this release, backward compatibility with the old +// concept checking classes is enabled by default, where available. +// The old protocol is deprecated, though, and backward compatibility +// will no longer be the default in the next release. + +# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \ + && !defined(BOOST_NO_SFINAE) \ + \ + && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) \ + && !(BOOST_WORKAROUND(__GNUC__, == 2)) + +// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to +// check for the presence of particularmember functions. + +# define BOOST_OLD_CONCEPT_SUPPORT + +# endif + +# ifdef BOOST_MSVC +# include +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +# else +# include +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); + // +# define BOOST_CONCEPT_ASSERT(ModelInParens) \ + BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens) + +#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP diff --git a/thirdparty/boost/concept/detail/borland.hpp b/thirdparty/boost/concept/detail/borland.hpp new file mode 100644 index 0000000..cbc2ee0 --- /dev/null +++ b/thirdparty/boost/concept/detail/borland.hpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP + +# include + +namespace boost { namespace concept { + +template +struct require; + +template +struct require +{ + enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concept::require::instantiate \ + } + +}} // namespace boost::concept + +#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP diff --git a/thirdparty/boost/concept/detail/concept_def.hpp b/thirdparty/boost/concept/detail/concept_def.hpp new file mode 100644 index 0000000..f2474a8 --- /dev/null +++ b/thirdparty/boost/concept/detail/concept_def.hpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# include +# include +# include +# include +#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP + +// BOOST_concept(SomeName, (p1)(p2)...(pN)) +// +// Expands to "template struct SomeName" +// +// Also defines an equivalent SomeNameConcept for backward compatibility. +// Maybe in the next release we can kill off the "Concept" suffix for good. +#if BOOST_WORKAROUND(__GNUC__, <= 3) +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + /* at least 2.96 and 3.4.3 both need this */ \ + BOOST_PP_CAT(name,Concept)(); \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name +#else +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name +#endif + +// Helper for BOOST_concept, above. +# define BOOST_CONCEPT_typename(r, ignored, index, t) \ + BOOST_PP_COMMA_IF(index) typename t + diff --git a/thirdparty/boost/concept/detail/concept_undef.hpp b/thirdparty/boost/concept/detail/concept_undef.hpp new file mode 100644 index 0000000..fa36abd --- /dev/null +++ b/thirdparty/boost/concept/detail/concept_undef.hpp @@ -0,0 +1,5 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# undef BOOST_concept_typename +# undef BOOST_concept diff --git a/thirdparty/boost/concept/detail/general.hpp b/thirdparty/boost/concept/detail/general.hpp new file mode 100644 index 0000000..859a880 --- /dev/null +++ b/thirdparty/boost/concept/detail/general.hpp @@ -0,0 +1,66 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP + +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + +// This implementation works on Comeau and GCC, all the way back to +// 2.95 +namespace boost { namespace concept { + +template +struct requirement_; + +namespace detail +{ + template struct instantiate {}; +} + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +template +struct constraint +{ + static void failed() { ((Model*)0)->constraints(); } +}; + +template +struct requirement_ + : mpl::if_< + concept::not_satisfied + , constraint + , requirement + >::type +{}; + +# else + +// For GCC-2.x, these can't have exactly the same name +template +struct requirement_ + : requirement +{}; + +# endif + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + typedef ::boost::concept::detail::instantiate< \ + &::boost::concept::requirement_::failed> \ + BOOST_PP_CAT(boost_concept_check,__LINE__) + +}} + +#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP diff --git a/thirdparty/boost/concept/detail/has_constraints.hpp b/thirdparty/boost/concept/detail/has_constraints.hpp new file mode 100644 index 0000000..02c03e0 --- /dev/null +++ b/thirdparty/boost/concept/detail/has_constraints.hpp @@ -0,0 +1,48 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP + +# include +# include +namespace boost { namespace concept { + +namespace detail +{ + +// Here we implement the metafunction that detects whether a +// constraints metafunction exists + typedef char yes; + typedef char (&no)[2]; + + template + struct wrap_constraints {}; + +#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) + // Work around the following bogus error in Sun Studio 11, by + // turning off the has_constraints function entirely: + // Error: complex expression not allowed in dependent template + // argument expression + inline no has_constraints_(...); +#else + template + inline yes has_constraints_(Model*, wrap_constraints* = 0); + inline no has_constraints_(...); +#endif +} + +// This would be called "detail::has_constraints," but it has a strong +// tendency to show up in error messages. +template +struct not_satisfied +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) ); + typedef mpl::bool_ type; +}; + +}} // namespace boost::concept::detail + +#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/thirdparty/boost/concept/detail/msvc.hpp b/thirdparty/boost/concept/detail/msvc.hpp new file mode 100644 index 0000000..c19d0a5 --- /dev/null +++ b/thirdparty/boost/concept/detail/msvc.hpp @@ -0,0 +1,92 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +namespace boost { namespace concept { + +template +struct check +{ + virtual void failed(Model* x) + { + x->~Model(); + } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +namespace detail +{ + // No need for a virtual function here, since evaluating + // not_satisfied below will have already instantiated the + // constraints() member. + struct constraint {}; +} + +template +struct require + : mpl::if_c< + not_satisfied::value + , detail::constraint + , check + >::type +{}; + +# else + +template +struct require + : check +{}; + +# endif + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + +// +// The iterator library sees some really strange errors unless we +// do things this way. +// +template +struct require +{ + virtual void failed(Model*) + { + require(); + } +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept::require) \ +} + +# else // Not vc-7.1 + +template +require +require_(void(*)(Model)); + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept::require_((ModelFnPtr)0)) \ +} + +# endif +}} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/thirdparty/boost/concept/requires.hpp b/thirdparty/boost/concept/requires.hpp new file mode 100644 index 0000000..a060dd7 --- /dev/null +++ b/thirdparty/boost/concept/requires.hpp @@ -0,0 +1,78 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP +# define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP + +# include +# include +# include +# include + +namespace boost { + +// Template for use in handwritten assertions +template +struct requires_ : More +{ +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename More::type type; +# endif + BOOST_CONCEPT_ASSERT((Model)); +}; + +// Template for use by macros, where models must be wrapped in parens. +// This isn't in namespace detail to keep extra cruft out of resulting +// error messages. +template +struct _requires_ +{ + enum { value = 0 }; + BOOST_CONCEPT_ASSERT_FN(ModelFn); +}; + +template +struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type +{ +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename ::boost::parameter::aux::unaryfunptr_arg_type::type type; +# endif +}; + +# if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010)) +# define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_::value) +# else +# define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_::value) +# endif + +#if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +# define BOOST_CONCEPT_REQUIRES(models, result) \ + typename ::boost::parameter::aux::unaryfunptr_arg_type::type + +#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +// Same thing as below without the initial typename +# define BOOST_CONCEPT_REQUIRES(models, result) \ + ::boost::Requires_< \ + (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ + ::boost::parameter::aux::unaryfunptr_arg_type \ + >::type + +#else + +// This just ICEs on MSVC6 :( +# define BOOST_CONCEPT_REQUIRES(models, result) \ + typename ::boost::Requires_< \ + (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ + void(*)result \ + >::type + +#endif + +// C++0x proposed syntax changed. This supports an older usage +#define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result) + +} // namespace boost::concept_check + +#endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP diff --git a/thirdparty/boost/concept/usage.hpp b/thirdparty/boost/concept/usage.hpp new file mode 100644 index 0000000..71b2da7 --- /dev/null +++ b/thirdparty/boost/concept/usage.hpp @@ -0,0 +1,43 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP +# define BOOST_CONCEPT_USAGE_DWA2006919_HPP + +# include +# include + +namespace boost { namespace concept { + +# if BOOST_WORKAROUND(__GNUC__, == 2) + +# define BOOST_CONCEPT_USAGE(model) ~model() + +# else + +template +struct usage_requirements +{ + ~usage_requirements() { ((Model*)0)->~Model(); } +}; + +# if BOOST_WORKAROUND(__GNUC__, <= 3) + +# define BOOST_CONCEPT_USAGE(model) \ + model(); /* at least 2.96 and 3.4.3 both need this :( */ \ + BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \ + ~model() + +# else + +# define BOOST_CONCEPT_USAGE(model) \ + BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \ + ~model() + +# endif + +# endif + +}} // namespace boost::concept + +#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP diff --git a/thirdparty/boost/concept_archetype.hpp b/thirdparty/boost/concept_archetype.hpp new file mode 100644 index 0000000..c69578b --- /dev/null +++ b/thirdparty/boost/concept_archetype.hpp @@ -0,0 +1,669 @@ +// +// (C) Copyright Jeremy Siek 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Revision History: +// +// 17 July 2001: Added const to some member functions. (Jeremy Siek) +// 05 May 2001: Removed static dummy_cons object. (Jeremy Siek) + +// See http://www.boost.org/libs/concept_check for documentation. + +#ifndef BOOST_CONCEPT_ARCHETYPES_HPP +#define BOOST_CONCEPT_ARCHETYPES_HPP + +#include +#include +#include +#include + +namespace boost { + + //=========================================================================== + // Basic Archetype Classes + + namespace detail { + class dummy_constructor { }; + } + + // A type that models no concept. The template parameter + // is only there so that null_archetype types can be created + // that have different type. + template + class null_archetype { + private: + null_archetype() { } + null_archetype(const null_archetype&) { } + null_archetype& operator=(const null_archetype&) { return *this; } + public: + null_archetype(detail::dummy_constructor) { } +#ifndef __MWERKS__ + template + friend void dummy_friend(); // just to avoid warnings +#endif + }; + + // This is a helper class that provides a way to get a reference to + // an object. The get() function will never be called at run-time + // (nothing in this file will) so this seemingly very bad function + // is really quite innocent. The name of this class needs to be + // changed. + template + class static_object + { + public: + static T& get() + { +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + return *reinterpret_cast(0); +#else + static char d[sizeof(T)]; + return *reinterpret_cast(d); +#endif + } + }; + + template > + class default_constructible_archetype : public Base { + public: + default_constructible_archetype() + : Base(static_object::get()) { } + default_constructible_archetype(detail::dummy_constructor x) : Base(x) { } + }; + + template > + class assignable_archetype : public Base { + assignable_archetype() { } + assignable_archetype(const assignable_archetype&) { } + public: + assignable_archetype& operator=(const assignable_archetype&) { + return *this; + } + assignable_archetype(detail::dummy_constructor x) : Base(x) { } + }; + + template > + class copy_constructible_archetype : public Base { + public: + copy_constructible_archetype() + : Base(static_object::get()) { } + copy_constructible_archetype(const copy_constructible_archetype&) + : Base(static_object::get()) { } + copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { } + }; + + template > + class sgi_assignable_archetype : public Base { + public: + sgi_assignable_archetype(const sgi_assignable_archetype&) + : Base(static_object::get()) { } + sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) { + return *this; + } + sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { } + }; + + struct default_archetype_base { + default_archetype_base(detail::dummy_constructor) { } + }; + + // Careful, don't use same type for T and Base. That results in the + // conversion operator being invalid. Since T is often + // null_archetype, can't use null_archetype for Base. + template + class convertible_to_archetype : public Base { + private: + convertible_to_archetype() { } + convertible_to_archetype(const convertible_to_archetype& ) { } + convertible_to_archetype& operator=(const convertible_to_archetype&) + { return *this; } + public: + convertible_to_archetype(detail::dummy_constructor x) : Base(x) { } + operator const T&() const { return static_object::get(); } + }; + + template + class convertible_from_archetype : public Base { + private: + convertible_from_archetype() { } + convertible_from_archetype(const convertible_from_archetype& ) { } + convertible_from_archetype& operator=(const convertible_from_archetype&) + { return *this; } + public: + convertible_from_archetype(detail::dummy_constructor x) : Base(x) { } + convertible_from_archetype(const T&) { } + convertible_from_archetype& operator=(const T&) + { return *this; } + }; + + class boolean_archetype { + public: + boolean_archetype(const boolean_archetype&) { } + operator bool() const { return true; } + boolean_archetype(detail::dummy_constructor) { } + private: + boolean_archetype() { } + boolean_archetype& operator=(const boolean_archetype&) { return *this; } + }; + + template > + class equality_comparable_archetype : public Base { + public: + equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { } + }; + template + boolean_archetype + operator==(const equality_comparable_archetype&, + const equality_comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + template + boolean_archetype + operator!=(const equality_comparable_archetype&, + const equality_comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + + + template > + class equality_comparable2_first_archetype : public Base { + public: + equality_comparable2_first_archetype(detail::dummy_constructor x) + : Base(x) { } + }; + template > + class equality_comparable2_second_archetype : public Base { + public: + equality_comparable2_second_archetype(detail::dummy_constructor x) + : Base(x) { } + }; + template + boolean_archetype + operator==(const equality_comparable2_first_archetype&, + const equality_comparable2_second_archetype&) + { + return boolean_archetype(static_object::get()); + } + template + boolean_archetype + operator!=(const equality_comparable2_first_archetype&, + const equality_comparable2_second_archetype&) + { + return boolean_archetype(static_object::get()); + } + + + template > + class less_than_comparable_archetype : public Base { + public: + less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { } + }; + template + boolean_archetype + operator<(const less_than_comparable_archetype&, + const less_than_comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + + + + template > + class comparable_archetype : public Base { + public: + comparable_archetype(detail::dummy_constructor x) : Base(x) { } + }; + template + boolean_archetype + operator<(const comparable_archetype&, + const comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + template + boolean_archetype + operator<=(const comparable_archetype&, + const comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + template + boolean_archetype + operator>(const comparable_archetype&, + const comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + template + boolean_archetype + operator>=(const comparable_archetype&, + const comparable_archetype&) + { + return boolean_archetype(static_object::get()); + } + + + // The purpose of the optags is so that one can specify + // exactly which types the operator< is defined between. + // This is useful for allowing the operations: + // + // A a; B b; + // a < b + // b < a + // + // without also allowing the combinations: + // + // a < a + // b < b + // + struct optag1 { }; + struct optag2 { }; + struct optag3 { }; + +#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \ + template , class Tag = optag1 > \ + class NAME##_first_archetype : public Base { \ + public: \ + NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \ + }; \ + \ + template , class Tag = optag1 > \ + class NAME##_second_archetype : public Base { \ + public: \ + NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \ + }; \ + \ + template \ + boolean_archetype \ + operator OP (const NAME##_first_archetype&, \ + const NAME##_second_archetype&) \ + { \ + return boolean_archetype(static_object::get()); \ + } + + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op) + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op) + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op) + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op) + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op) + BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op) + +#define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \ + template > \ + class NAME##_archetype : public Base { \ + public: \ + NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \ + NAME##_archetype(const NAME##_archetype&) \ + : Base(static_object::get()) { } \ + NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \ + }; \ + template \ + NAME##_archetype \ + operator OP (const NAME##_archetype&,\ + const NAME##_archetype&) \ + { \ + return \ + NAME##_archetype(static_object::get()); \ + } + + BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable) + BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable) + BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable) + BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable) + BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable) + + // As is, these are useless because of the return type. + // Need to invent a better way... +#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \ + template > \ + class NAME##_first_archetype : public Base { \ + public: \ + NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \ + }; \ + \ + template > \ + class NAME##_second_archetype : public Base { \ + public: \ + NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \ + }; \ + \ + template \ + Return \ + operator OP (const NAME##_first_archetype&, \ + const NAME##_second_archetype&) \ + { \ + return Return(static_object::get()); \ + } + + BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op) + BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op) + BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op) + BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op) + BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op) + + //=========================================================================== + // Function Object Archetype Classes + + template + class generator_archetype { + public: + const Return& operator()() { + return static_object::get(); + } + }; + + class void_generator_archetype { + public: + void operator()() { } + }; + + template + class unary_function_archetype { + private: + unary_function_archetype() { } + public: + unary_function_archetype(detail::dummy_constructor) { } + const Return& operator()(const Arg&) const { + return static_object::get(); + } + }; + + template + class binary_function_archetype { + private: + binary_function_archetype() { } + public: + binary_function_archetype(detail::dummy_constructor) { } + const Return& operator()(const Arg1&, const Arg2&) const { + return static_object::get(); + } + }; + + template + class unary_predicate_archetype { + typedef boolean_archetype Return; + unary_predicate_archetype() { } + public: + unary_predicate_archetype(detail::dummy_constructor) { } + const Return& operator()(const Arg&) const { + return static_object::get(); + } + }; + + template > + class binary_predicate_archetype { + typedef boolean_archetype Return; + binary_predicate_archetype() { } + public: + binary_predicate_archetype(detail::dummy_constructor) { } + const Return& operator()(const Arg1&, const Arg2&) const { + return static_object::get(); + } + }; + + //=========================================================================== + // Iterator Archetype Classes + + template + class input_iterator_archetype + { + private: + typedef input_iterator_archetype self; + public: + typedef std::input_iterator_tag iterator_category; + typedef T value_type; + struct reference { + operator const value_type&() const { return static_object::get(); } + }; + typedef const T* pointer; + typedef std::ptrdiff_t difference_type; + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return reference(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + }; + + template + class input_iterator_archetype_no_proxy + { + private: + typedef input_iterator_archetype_no_proxy self; + public: + typedef std::input_iterator_tag iterator_category; + typedef T value_type; + typedef const T& reference; + typedef const T* pointer; + typedef std::ptrdiff_t difference_type; + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + }; + + template + struct output_proxy { + output_proxy& operator=(const T&) { return *this; } + }; + + template + class output_iterator_archetype + { + public: + typedef output_iterator_archetype self; + public: + typedef std::output_iterator_tag iterator_category; + typedef output_proxy value_type; + typedef output_proxy reference; + typedef void pointer; + typedef void difference_type; + output_iterator_archetype(detail::dummy_constructor) { } + output_iterator_archetype(const self&) { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return output_proxy(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + private: + output_iterator_archetype() { } + }; + + template + class input_output_iterator_archetype + { + private: + typedef input_output_iterator_archetype self; + struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { }; + public: + typedef in_out_tag iterator_category; + typedef T value_type; + struct reference { + reference& operator=(const T&) { return *this; } + operator value_type() { return static_object::get(); } + }; + typedef const T* pointer; + typedef std::ptrdiff_t difference_type; + input_output_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return reference(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + }; + + template + class forward_iterator_archetype + { + public: + typedef forward_iterator_archetype self; + public: + typedef std::forward_iterator_tag iterator_category; + typedef T value_type; + typedef const T& reference; + typedef T const* pointer; + typedef std::ptrdiff_t difference_type; + forward_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + }; + + template + class mutable_forward_iterator_archetype + { + public: + typedef mutable_forward_iterator_archetype self; + public: + typedef std::forward_iterator_tag iterator_category; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + mutable_forward_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + }; + + template + class bidirectional_iterator_archetype + { + public: + typedef bidirectional_iterator_archetype self; + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef const T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + bidirectional_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + self& operator--() { return *this; } + self operator--(int) { return *this; } + }; + + template + class mutable_bidirectional_iterator_archetype + { + public: + typedef mutable_bidirectional_iterator_archetype self; + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + mutable_bidirectional_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + self& operator--() { return *this; } + self operator--(int) { return *this; } + }; + + template + class random_access_iterator_archetype + { + public: + typedef random_access_iterator_archetype self; + public: + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef const T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + random_access_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + self& operator--() { return *this; } + self operator--(int) { return *this; } + reference operator[](difference_type) const + { return static_object::get(); } + self& operator+=(difference_type) { return *this; } + self& operator-=(difference_type) { return *this; } + difference_type operator-(const self&) const + { return difference_type(); } + self operator+(difference_type) const { return *this; } + self operator-(difference_type) const { return *this; } + bool operator<(const self&) const { return true; } + bool operator<=(const self&) const { return true; } + bool operator>(const self&) const { return true; } + bool operator>=(const self&) const { return true; } + }; + template + random_access_iterator_archetype + operator+(typename random_access_iterator_archetype::difference_type, + const random_access_iterator_archetype& x) + { return x; } + + + template + class mutable_random_access_iterator_archetype + { + public: + typedef mutable_random_access_iterator_archetype self; + public: + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + mutable_random_access_iterator_archetype() { } + self& operator=(const self&) { return *this; } + bool operator==(const self&) const { return true; } + bool operator!=(const self&) const { return true; } + reference operator*() const { return static_object::get(); } + self& operator++() { return *this; } + self operator++(int) { return *this; } + self& operator--() { return *this; } + self operator--(int) { return *this; } + reference operator[](difference_type) const + { return static_object::get(); } + self& operator+=(difference_type) { return *this; } + self& operator-=(difference_type) { return *this; } + difference_type operator-(const self&) const + { return difference_type(); } + self operator+(difference_type) const { return *this; } + self operator-(difference_type) const { return *this; } + bool operator<(const self&) const { return true; } + bool operator<=(const self&) const { return true; } + bool operator>(const self&) const { return true; } + bool operator>=(const self&) const { return true; } + }; + template + mutable_random_access_iterator_archetype + operator+ + (typename mutable_random_access_iterator_archetype::difference_type, + const mutable_random_access_iterator_archetype& x) + { return x; } + +} // namespace boost + +#endif // BOOST_CONCEPT_ARCHETYPES_H diff --git a/thirdparty/boost/concept_check.hpp b/thirdparty/boost/concept_check.hpp new file mode 100644 index 0000000..daaf7cf --- /dev/null +++ b/thirdparty/boost/concept_check.hpp @@ -0,0 +1,988 @@ +// +// (C) Copyright Jeremy Siek 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Revision History: +// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) +// 02 April 2001: Removed limits header altogether. (Jeremy Siek) +// 01 April 2001: Modified to use new header. (JMaddock) +// + +// See http://www.boost.org/libs/concept_check for documentation. + +#ifndef BOOST_CONCEPT_CHECKS_HPP +# define BOOST_CONCEPT_CHECKS_HPP + +# include + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +namespace boost +{ + + // + // Backward compatibility + // + + template + inline void function_requires(Model* = 0) + { + BOOST_CONCEPT_ASSERT((Model)); + } + template inline void ignore_unused_variable_warning(T const&) {} + +# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + + + // + // Begin concept definitions + // + BOOST_concept(Integer, (T)) + { + BOOST_CONCEPT_USAGE(Integer) + { + x.error_type_must_be_an_integer_type(); + } + private: + T x; + }; + + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct Integer< ::boost::long_long_type> {}; + template <> struct Integer< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct Integer<__int64> {}; + template <> struct Integer {}; +# endif + + BOOST_concept(SignedInteger,(T)) { + BOOST_CONCEPT_USAGE(SignedInteger) { + x.error_type_must_be_a_signed_integer_type(); + } + private: + T x; + }; + template <> struct SignedInteger { }; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct SignedInteger< ::boost::long_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct SignedInteger<__int64> {}; +# endif + + BOOST_concept(UnsignedInteger,(T)) { + BOOST_CONCEPT_USAGE(UnsignedInteger) { + x.error_type_must_be_an_unsigned_integer_type(); + } + private: + T x; + }; + + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct UnsignedInteger {}; +# endif + + //=========================================================================== + // Basic Concepts + + BOOST_concept(DefaultConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(DefaultConstructible) { + TT a; // require default constructor + ignore_unused_variable_warning(a); + } + }; + + BOOST_concept(Assignable,(TT)) + { + BOOST_CONCEPT_USAGE(Assignable) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = a; // require assignment operator +#endif + const_constraints(a); + } + private: + void const_constraints(const TT& b) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // const required for argument to assignment +#endif + } + private: + TT a; + }; + + + BOOST_concept(CopyConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(CopyConstructible) { + TT a(b); // require copy constructor + TT* ptr = &a; // require address of operator + const_constraints(a); + ignore_unused_variable_warning(ptr); + } + private: + void const_constraints(const TT& a) { + TT c(a); // require const copy constructor + const TT* ptr = &a; // require const address of operator + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(ptr); + } + TT b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + BOOST_concept(SGIAssignable,(TT)) + { + BOOST_CONCEPT_USAGE(SGIAssignable) { + TT b(a); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = a; // require assignment operator +#endif + const_constraints(a); + ignore_unused_variable_warning(b); + } + private: + void const_constraints(const TT& b) { + TT c(b); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // const required for argument to assignment +#endif + ignore_unused_variable_warning(c); + } + TT a; + }; + + BOOST_concept(Convertible,(X)(Y)) + { + BOOST_CONCEPT_USAGE(Convertible) { + Y y = x; + ignore_unused_variable_warning(y); + } + private: + X x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template + void require_boolean_expr(const TT& t) { + bool x = t; + ignore_unused_variable_warning(x); + } + + BOOST_concept(EqualityComparable,(TT)) + { + BOOST_CONCEPT_USAGE(EqualityComparable) { + require_boolean_expr(a == b); + require_boolean_expr(a != b); + } + private: + TT a, b; + }; + + BOOST_concept(LessThanComparable,(TT)) + { + BOOST_CONCEPT_USAGE(LessThanComparable) { + require_boolean_expr(a < b); + } + private: + TT a, b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + BOOST_concept(Comparable,(TT)) + { + BOOST_CONCEPT_USAGE(Comparable) { + require_boolean_expr(a < b); + require_boolean_expr(a > b); + require_boolean_expr(a <= b); + require_boolean_expr(a >= b); + } + private: + TT a, b; + }; + +#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + bool constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + +#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (Ret)(First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + Ret constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp); + + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp); + + //=========================================================================== + // Function Object Concepts + + BOOST_concept(Generator,(Func)(Return)) + { + BOOST_CONCEPT_USAGE(Generator) { test(is_void()); } + + private: + void test(boost::mpl::false_) + { + // Do we really want a reference here? + const Return& r = f(); + ignore_unused_variable_warning(r); + } + + void test(boost::mpl::true_) + { + f(); + } + + Func f; + }; + + BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } + + private: + void test(boost::mpl::false_) + { + f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) + Return r = f(arg); + ignore_unused_variable_warning(r); + } + + void test(boost::mpl::true_) + { + f(arg); + } + + Func f; + Arg arg; + }; + + BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void()); } + private: + void test(boost::mpl::false_) + { + f(first,second); + Return r = f(first, second); // require operator() + (void)r; + } + + void test(boost::mpl::true_) + { + f(first,second); + } + + Func f; + First first; + Second second; + }; + + BOOST_concept(UnaryPredicate,(Func)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryPredicate) { + require_boolean_expr(f(arg)); // require operator() returning bool + } + private: + Func f; + Arg arg; + }; + + BOOST_concept(BinaryPredicate,(Func)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryPredicate) { + require_boolean_expr(f(a, b)); // require operator() returning bool + } + private: + Func f; + First a; + Second b; + }; + + // use this when functor is used inside a container class like std::set + BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + { + BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { + const_constraints(f); + } + private: + void const_constraints(const Func& fun) { + // operator() must be a const member function + require_boolean_expr(fun(a, b)); + } + Func f; + First a; + Second b; + }; + + BOOST_concept(AdaptableGenerator,(Func)(Return)) + : Generator + { + typedef typename Func::result_type result_type; + + BOOST_CONCEPT_USAGE(AdaptableGenerator) + { + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) + : UnaryFunction + { + typedef typename Func::argument_type argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableUnaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second)) + : BinaryFunction< + Func + , typename Func::result_type + , typename Func::first_argument_type + , typename Func::second_argument_type + > + { + typedef typename Func::first_argument_type first_argument_type; + typedef typename Func::second_argument_type second_argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableBinaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptablePredicate,(Func)(Arg)) + : UnaryPredicate + , AdaptableUnaryFunction + { + }; + + BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + , AdaptableBinaryFunction + { + }; + + //=========================================================================== + // Iterator Concepts + + BOOST_concept(InputIterator,(TT)) + : Assignable + , EqualityComparable + { + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef typename boost::detail::iterator_traits::difference_type difference_type; + typedef typename boost::detail::iterator_traits::reference reference; + typedef typename boost::detail::iterator_traits::pointer pointer; + typedef typename boost::detail::iterator_traits::iterator_category iterator_category; + + BOOST_CONCEPT_USAGE(InputIterator) + { + BOOST_CONCEPT_ASSERT((SignedInteger)); + BOOST_CONCEPT_ASSERT((Convertible)); + + TT j(i); + (void)*i; // require dereference operator + ++j; // require preincrement operator + i++; // require postincrement operator + } + private: + TT i; + }; + + BOOST_concept(OutputIterator,(TT)(ValueT)) + : Assignable + { + BOOST_CONCEPT_USAGE(OutputIterator) { + + ++i; // require preincrement operator + i++; // require postincrement operator + *i++ = t; // require postincrement and assignment + } + private: + TT i, j; + ValueT t; + }; + + BOOST_concept(ForwardIterator,(TT)) + : InputIterator + { + BOOST_CONCEPT_USAGE(ForwardIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category + , std::forward_iterator_tag + >)); + + typename InputIterator::reference r = *i; + ignore_unused_variable_warning(r); + } + + private: + TT i; + }; + + BOOST_concept(Mutable_ForwardIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { + *i++ = *i; // require postincrement and assignment + } + private: + TT i; + }; + + BOOST_concept(BidirectionalIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(BidirectionalIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::bidirectional_iterator_tag + >)); + + --i; // require predecrement operator + i--; // require postdecrement operator + } + private: + TT i; + }; + + BOOST_concept(Mutable_BidirectionalIterator,(TT)) + : BidirectionalIterator + , Mutable_ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) + { + *i-- = *i; // require postdecrement and assignment + } + private: + TT i; + }; + + BOOST_concept(RandomAccessIterator,(TT)) + : BidirectionalIterator + , Comparable + { + BOOST_CONCEPT_USAGE(RandomAccessIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::random_access_iterator_tag + >)); + + i += n; // require assignment addition operator + i = i + n; i = n + i; // require addition with difference type + i -= n; // require assignment subtraction operator + i = i - n; // require subtraction with difference type + n = i - j; // require difference operator + (void)i[n]; // require element access operator + } + + private: + TT a, b; + TT i, j; + typename boost::detail::iterator_traits::difference_type n; + }; + + BOOST_concept(Mutable_RandomAccessIterator,(TT)) + : RandomAccessIterator + , Mutable_BidirectionalIterator + { + BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator) + { + i[n] = *i; // require element access and assignment + } + private: + TT i; + typename boost::detail::iterator_traits::difference_type n; + }; + + //=========================================================================== + // Container s + + BOOST_concept(Container,(C)) + : Assignable + { + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + typedef typename C::const_pointer const_pointer; + typedef typename C::const_iterator const_iterator; + + BOOST_CONCEPT_USAGE(Container) + { + BOOST_CONCEPT_ASSERT((InputIterator)); + const_constraints(c); + } + + private: + void const_constraints(const C& cc) { + i = cc.begin(); + i = cc.end(); + n = cc.size(); + n = cc.max_size(); + b = cc.empty(); + } + C c; + bool b; + const_iterator i; + size_type n; + }; + + BOOST_concept(Mutable_Container,(C)) + : Container + { + typedef typename C::reference reference; + typedef typename C::iterator iterator; + typedef typename C::pointer pointer; + + BOOST_CONCEPT_USAGE(Mutable_Container) + { + BOOST_CONCEPT_ASSERT(( + Assignable)); + + BOOST_CONCEPT_ASSERT((InputIterator)); + + i = c.begin(); + i = c.end(); + c.swap(c2); + } + + private: + iterator i; + C c, c2; + }; + + BOOST_concept(ForwardContainer,(C)) + : Container + { + BOOST_CONCEPT_USAGE(ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + ForwardIterator< + typename ForwardContainer::const_iterator + >)); + } + }; + + BOOST_concept(Mutable_ForwardContainer,(C)) + : ForwardContainer + , Mutable_Container + { + BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + Mutable_ForwardIterator< + typename Mutable_ForwardContainer::iterator + >)); + } + }; + + BOOST_concept(ReversibleContainer,(C)) + : ForwardContainer + { + typedef typename + C::const_reverse_iterator + const_reverse_iterator; + + BOOST_CONCEPT_USAGE(ReversibleContainer) + { + BOOST_CONCEPT_ASSERT(( + BidirectionalIterator< + typename ReversibleContainer::const_iterator>)); + + BOOST_CONCEPT_ASSERT((BidirectionalIterator)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reverse_iterator i = cc.rbegin(); + i = cc.rend(); + } + C c; + }; + + BOOST_concept(Mutable_ReversibleContainer,(C)) + : Mutable_ForwardContainer + , ReversibleContainer + { + typedef typename C::reverse_iterator reverse_iterator; + + BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) + { + typedef typename Mutable_ForwardContainer::iterator iterator; + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + + reverse_iterator i = c.rbegin(); + i = c.rend(); + } + private: + C c; + }; + + BOOST_concept(RandomAccessContainer,(C)) + : ReversibleContainer + { + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + + BOOST_CONCEPT_USAGE(RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT(( + RandomAccessIterator< + typename RandomAccessContainer::const_iterator + >)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reference r = cc[n]; + ignore_unused_variable_warning(r); + } + + C c; + size_type n; + }; + + BOOST_concept(Mutable_RandomAccessContainer,(C)) + : Mutable_ReversibleContainer + , RandomAccessContainer + { + private: + typedef Mutable_RandomAccessContainer self; + public: + BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + + typename self::reference r = c[i]; + ignore_unused_variable_warning(r); + } + + private: + typename Mutable_ReversibleContainer::size_type i; + C c; + }; + + // A Sequence is inherently mutable + BOOST_concept(Sequence,(S)) + : Mutable_ForwardContainer + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container --JGS + // ... so why aren't we following the standard? --DWA + , DefaultConstructible + { + BOOST_CONCEPT_USAGE(Sequence) + { + S + c(n), + c2(n, t), + c3(first, last); + + c.insert(p, t); + c.insert(p, n, t); + c.insert(p, first, last); + + c.erase(p); + c.erase(p, q); + + typename Sequence::reference r = c.front(); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(c3); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& c) { + typename Sequence::const_reference r = c.front(); + ignore_unused_variable_warning(r); + } + + typename S::value_type t; + typename S::size_type n; + typename S::value_type* first, *last; + typename S::iterator p, q; + }; + + BOOST_concept(FrontInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(FrontInsertionSequence) + { + c.push_front(t); + c.pop_front(); + } + private: + S c; + typename S::value_type t; + }; + + BOOST_concept(BackInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(BackInsertionSequence) + { + c.push_back(t); + c.pop_back(); + typename BackInsertionSequence::reference r = c.back(); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& cc) { + typename BackInsertionSequence::const_reference + r = cc.back(); + ignore_unused_variable_warning(r); + }; + S c; + typename S::value_type t; + }; + + BOOST_concept(AssociativeContainer,(C)) + : ForwardContainer + , DefaultConstructible + { + typedef typename C::key_type key_type; + typedef typename C::key_compare key_compare; + typedef typename C::value_compare value_compare; + typedef typename C::iterator iterator; + + BOOST_CONCEPT_USAGE(AssociativeContainer) + { + i = c.find(k); + r = c.equal_range(k); + c.erase(k); + c.erase(i); + c.erase(r.first, r.second); + const_constraints(c); + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + + typedef typename AssociativeContainer::value_type value_type_; + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + } + + // Redundant with the base concept, but it helps below. + typedef typename C::const_iterator const_iterator; + private: + void const_constraints(const C& cc) + { + ci = cc.find(k); + n = cc.count(k); + cr = cc.equal_range(k); + } + + C c; + iterator i; + std::pair r; + const_iterator ci; + std::pair cr; + typename C::key_type k; + typename C::size_type n; + }; + + BOOST_concept(UniqueAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) + { + C c(first, last); + + pos_flag = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + } + private: + std::pair pos_flag; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(MultipleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) + { + C c(first, last); + + pos = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(pos); + } + private: + typename C::iterator pos; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(SimpleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(PairAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(PairAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + typedef typename C::mapped_type mapped_type; + typedef std::pair required_value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(SortedAssociativeContainer,(C)) + : AssociativeContainer + , ReversibleContainer + { + BOOST_CONCEPT_USAGE(SortedAssociativeContainer) + { + C + c(kc), + c2(first, last), + c3(first, last, kc); + + p = c.upper_bound(k); + p = c.lower_bound(k); + r = c.equal_range(k); + + c.insert(p, t); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(c3); + const_constraints(c); + } + + void const_constraints(const C& c) + { + kc = c.key_comp(); + vc = c.value_comp(); + + cp = c.upper_bound(k); + cp = c.lower_bound(k); + cr = c.equal_range(k); + } + + private: + typename C::key_compare kc; + typename C::value_compare vc; + typename C::value_type t; + typename C::key_type k; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + + typedef SortedAssociativeContainer self; + iterator p; + const_iterator cp; + std::pair r; + std::pair cr; + typename C::value_type* first, *last; + }; + + // HashedAssociativeContainer + +} // namespace boost + +# include + +#endif // BOOST_CONCEPT_CHECKS_HPP + diff --git a/thirdparty/boost/concept_check/borland.hpp b/thirdparty/boost/concept_check/borland.hpp new file mode 100644 index 0000000..dbb0166 --- /dev/null +++ b/thirdparty/boost/concept_check/borland.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP + +namespace boost { + +template +struct concept_check; + +template +struct concept_check +{ + enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; +}; + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concept_check::instantiate \ + } + +} // namespace boost::concept_checking + +#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP diff --git a/thirdparty/boost/concept_check/general.hpp b/thirdparty/boost/concept_check/general.hpp new file mode 100644 index 0000000..06c3b82 --- /dev/null +++ b/thirdparty/boost/concept_check/general.hpp @@ -0,0 +1,82 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +// This implementation works on GCC and Comeau, but has actually been +// fairly carefully tuned to work on GCC versions starting with +// gcc-2.95.x. If you're trying to get an additional compiler to pass +// the tests you might consider breaking out a separate gcc.hpp and +// starting over on the general case. +namespace boost +{ + namespace concept_checking + { + template struct instantiate {}; + } + + template struct concept_check_; + + template + void concept_check_failed() + { + ((Model*)0)->~Model(); + } + + template + struct concept_check + { + concept_checking::instantiate > x; + enum { instantiate = 1 }; + }; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + template + void constraint_check_failed() + { + ((Model*)0)->constraints(); + } + + template + struct constraint_check + { + concept_checking::instantiate > x; + enum { instantiate = 1 }; + }; + + template + struct concept_check_ + : mpl::if_c< + concept_checking::has_constraints::value + , constraint_check + , concept_check + >::type + {}; + +# else + + template + struct concept_check_ + : concept_check + {}; + +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + ::boost::concept_check_::instantiate \ + } +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/thirdparty/boost/concept_check/has_constraints.hpp b/thirdparty/boost/concept_check/has_constraints.hpp new file mode 100644 index 0000000..571b181 --- /dev/null +++ b/thirdparty/boost/concept_check/has_constraints.hpp @@ -0,0 +1,31 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP + +namespace boost { namespace concept_checking { + +// Here we implement the "metafunction" that detects whether a +// constraints metafunction exists +typedef char yes; +typedef char (&no)[2]; + +template +struct wrap_constraints {}; + +template +inline yes has_constraints_(Model*, wrap_constraints* = 0); +inline no has_constraints_(...); + +template +struct has_constraints +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( concept_checking::has_constraints_((Model*)0) ) == 1 ); +}; + +}} // namespace boost::concept_checking + +#endif // BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/thirdparty/boost/concept_check/msvc.hpp b/thirdparty/boost/concept_check/msvc.hpp new file mode 100644 index 0000000..513f7bb --- /dev/null +++ b/thirdparty/boost/concept_check/msvc.hpp @@ -0,0 +1,90 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + + +namespace boost +{ + namespace concept_checking + { + template + struct concept_check_ + { + virtual void failed(Model* x) + { + x->~Model(); + } + }; + } + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + + namespace concept_checking + { + template + struct constraint_check + { + virtual void failed(Model* x) + { + x->constraints(); + } + }; + } + + template + struct concept_check + : mpl::if_c< + concept_checking::has_constraints::value + , concept_checking::constraint_check + , concept_checking::concept_check_ + >::type + {}; + +# else + + template + struct concept_check + : concept_checking::concept_check_ + {}; + +# endif + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + + // + // The iterator library sees some really strange errors unless we + // use partial specialization to extract the model type with + // msvc-7.1 + // + template + struct concept_check + : concept_check + { }; + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check) \ + } + +# else + + template + concept_check + concept_check_(void(*)(Model)); + +# define BOOST_CONCEPT_ASSERT( ModelInParens ) \ + enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \ + } + +# endif +} + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/thirdparty/boost/config.hpp b/thirdparty/boost/config.hpp new file mode 100644 index 0000000..cb5037a --- /dev/null +++ b/thirdparty/boost/config.hpp @@ -0,0 +1,70 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#endif // BOOST_CONFIG_HPP + + + + + + + + + + + diff --git a/thirdparty/boost/config/abi/borland_prefix.hpp b/thirdparty/boost/config/abi/borland_prefix.hpp new file mode 100644 index 0000000..6148195 --- /dev/null +++ b/thirdparty/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// for C++ Builder the following options effect the ABI: +// +// -b (on or off - effect emum sizes) +// -Vx (on or off - empty members) +// -Ve (on or off - empty base classes) +// -aX (alignment - 5 options). +// -pX (Calling convention - 4 options) +// -VmX (member pointer size and layout - 5 options) +// -VC (on or off, changes name mangling) +// -Vl (on or off, changes struct layout). + +// In addition the following warnings are sufficiently annoying (and +// unfixable) to have them turned off by default: +// +// 8027 - functions containing [for|while] loops are not expanded inline +// 8026 - functions taking class by value arguments are not expanded inline + +#pragma nopushoptwarn +# pragma option push -Vx -Ve -a8 -b -pc -Vmv -VC- -Vl- -w-8027 -w-8026 + + + diff --git a/thirdparty/boost/config/abi/borland_suffix.hpp b/thirdparty/boost/config/abi/borland_suffix.hpp new file mode 100644 index 0000000..110b3c3 --- /dev/null +++ b/thirdparty/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,12 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# pragma option pop +#pragma nopushoptwarn + + + + + diff --git a/thirdparty/boost/config/abi/msvc_prefix.hpp b/thirdparty/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 0000000..7f80cc9 --- /dev/null +++ b/thirdparty/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma pack(push,8) + + diff --git a/thirdparty/boost/config/abi/msvc_suffix.hpp b/thirdparty/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 0000000..8c1edd0 --- /dev/null +++ b/thirdparty/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma pack(pop) + + diff --git a/thirdparty/boost/config/abi_prefix.hpp b/thirdparty/boost/config/abi_prefix.hpp new file mode 100644 index 0000000..548d2ce --- /dev/null +++ b/thirdparty/boost/config/abi_prefix.hpp @@ -0,0 +1,25 @@ +// abi_prefix header -------------------------------------------------------// + +// © Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# define BOOST_CONFIG_ABI_PREFIX_HPP +#else +# error double inclusion of header boost/config/abi_prefix.hpp is an error +#endif + +#include + +// this must occur after all other includes and before any code appears: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/thirdparty/boost/config/abi_suffix.hpp b/thirdparty/boost/config/abi_suffix.hpp new file mode 100644 index 0000000..1f944f8 --- /dev/null +++ b/thirdparty/boost/config/abi_suffix.hpp @@ -0,0 +1,26 @@ +// abi_sufffix header -------------------------------------------------------// + +// © Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +// This header should be #included AFTER code that was preceded by a #include +// . + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# error Header boost/config/abi_prefix.hpp must only be used after boost/config/abi_prefix.hpp +#else +# undef BOOST_CONFIG_ABI_PREFIX_HPP +#endif + +// the suffix header occurs after all of our code: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/thirdparty/boost/config/auto_link.hpp b/thirdparty/boost/config/auto_link.hpp new file mode 100644 index 0000000..c340a34 --- /dev/null +++ b/thirdparty/boost/config/auto_link.hpp @@ -0,0 +1,368 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + "-" + + BOOST_LIB_VERSION + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hiphen: + + s static runtime (dynamic if not present). + d debug build (release if not present). + g debug/diagnostic runtime (release if not present). + p STLPort Build. + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(__BORLANDC__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +// Note: no compilers before 1200 are supported +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // vc6: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1310) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1400) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1500) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +#elif defined(__BORLANDC__) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +#elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +#elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +#elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +#endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(__BORLANDC__) + +// +// figure out whether we want the debug builds or not: +// +#if __BORLANDC__ > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLPort-debug form" +#endif + +# ifdef _RTLDLL + +# ifdef BOOST_BORLAND_DEBUG +# define BOOST_LIB_RT_OPT "-d" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# ifdef BOOST_BORLAND_DEBUG +# define BOOST_LIB_RT_OPT "-sd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_VERSION) + +#ifndef BOOST_AUTO_LINK_NOMANGLE +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# endif +#else +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif +#if defined(BOOST_AUTO_LINK_NOMANGLE) +# undef BOOST_AUTO_LINK_NOMANGLE +#endif + + + + + + + + + + + diff --git a/thirdparty/boost/config/compiler/borland.hpp b/thirdparty/boost/config/compiler/borland.hpp new file mode 100644 index 0000000..6e2461c --- /dev/null +++ b/thirdparty/boost/config/compiler/borland.hpp @@ -0,0 +1,209 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Borland C++ compiler setup: + +// +// versions check: +// we don't support Borland prior to version 5.4: +#if __BORLANDC__ < 0x540 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// last known and checked version is 0x600 (Builder X preview) +// or 0x593 (CodeGear C++ Builder 2007 December 2007 update): +#if (__BORLANDC__ > 0x593) && (__BORLANDC__ != 0x600) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message( "Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + +// +// Support macros to help with standard library detection +#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) +# define BOOST_BCB_WITH_ROGUE_WAVE +#elif __BORLANDC__ < 0x570 +# define BOOST_BCB_WITH_STLPORT +#else +# define BOOST_BCB_WITH_DINKUMWARE +#endif + +// +// Version 5.0 and below: +# if __BORLANDC__ <= 0x0550 +// Borland C++Builder 4 and 5: +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# if __BORLANDC__ == 0x0550 +// Borland C++Builder 5, command-line compiler 5.5: +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif +# endif + +// Version 5.51 and below: +#if (__BORLANDC__ <= 0x551) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_DEDUCED_TYPENAME +// workaround for missing WCHAR_MAX/WCHAR_MIN: +#include +#include +#ifndef WCHAR_MAX +# define WCHAR_MAX 0xffff +#endif +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#endif + +// Borland C++ Builder 6 and below: +#if (__BORLANDC__ <= 0x564) +# define BOOST_NO_INTEGRAL_INT64_T + +# ifdef NDEBUG + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// +// new bug in 5.61: +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) + // this seems to be needed by the command line compiler, but not the IDE: +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +// Borland C++ Builder 2006 Update 2 and below: +#if (__BORLANDC__ <= 0x582) +# define BOOST_NO_SFINAE +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# define BOOST_NO_TEMPLATE_TEMPLATES + +# define BOOST_NO_PRIVATE_IN_AGGREGATE + +# ifdef _WIN32 +# define BOOST_NO_SWPRINTF +# elif defined(linux) || defined(__linux__) || defined(__linux) + // we should really be able to do without this + // but the wcs* functions aren't imported into std:: +# define BOOST_NO_STDC_NAMESPACE + // _CPPUNWIND doesn't get automatically set for some reason: +# pragma defineonoption BOOST_CPPUNWIND -x +# endif +#endif + +// Borland C++ Builder 2007 December 2007 Update and below: +#if (__BORLANDC__ <= 0x593) +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +// Temporary workaround +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +#endif + +#if __BORLANDC__ >= 0x590 +# define BOOST_HAS_TR1_HASH + +# define BOOST_HAS_MACRO_USE_FACET +#endif + +// +// Post 0x561 we have long long and stdint.h: +#if __BORLANDC__ >= 0x561 +# ifndef __NO_LONG_LONG +# define BOOST_HAS_LONG_LONG +# endif + // On non-Win32 platforms let the platform config figure this out: +# ifdef _WIN32 +# define BOOST_HAS_STDINT_H +# endif +#endif + +// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is +// defined, then we have 0x560 or greater with the Rogue Wave implementation +// which presumably has the std::DBL_MAX bug. +#if defined( BOOST_BCB_WITH_ROGUE_WAVE ) +// is partly broken, some macros define symbols that are really in +// namespace std, so you end up having to use illegal constructs like +// std::DBL_MAX, as a fix we'll just include float.h and have done with: +#include +#endif +// +// __int64: +// +#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DECLSPEC +#endif +// +// ABI fixing headers: +// +#if __BORLANDC__ < 0x600 // not implemented for version 6 compiler yet +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +#endif +// +// Disable Win32 support in ANSI mode: +// +#if __BORLANDC__ < 0x600 +# pragma defineonoption BOOST_DISABLE_WIN32 -A +#elif defined(__STRICT_ANSI__) +# define BOOST_DISABLE_WIN32 +#endif +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) + + diff --git a/thirdparty/boost/config/compiler/comeau.hpp b/thirdparty/boost/config/compiler/comeau.hpp new file mode 100644 index 0000000..c2cb68c --- /dev/null +++ b/thirdparty/boost/config/compiler/comeau.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Douglas Gregor 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau C++ compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +#if (__COMO_VERSION__ <= 4245) + +# if defined(_MSC_VER) && _MSC_VER <= 1300 +# if _MSC_VER > 100 + // only set this in non-strict mode: +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# endif +# endif + +// Void returns don't work when emulating VC 6 (Peter Dimov) +// TODO: look up if this doesn't apply to the whole 12xx range +# if defined(_MSC_VER) && (_MSC_VER < 1300) +# define BOOST_NO_VOID_RETURNS +# endif + +#endif // version 4245 + +// +// enable __int64 support in VC emulation mode +// +# if defined(_MSC_VER) && (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +# endif + +#define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) + +// +// versions check: +// we don't know Comeau prior to version 4245: +#if __COMO_VERSION__ < 4245 +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4245: +#if (__COMO_VERSION__ > 4245) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/thirdparty/boost/config/compiler/common_edg.hpp b/thirdparty/boost/config/compiler/common_edg.hpp new file mode 100644 index 0000000..0a1fdf4 --- /dev/null +++ b/thirdparty/boost/config/compiler/common_edg.hpp @@ -0,0 +1,62 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright Markus Schoepflin 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// +// Options common to all edg based compilers. +// +// This is included from within the individual compiler mini-configs. + +#ifndef __EDG_VERSION__ +# error This file requires that __EDG_VERSION__ be defined. +#endif + +#if (__EDG_VERSION__ <= 238) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_SFINAE +#endif + +#if (__EDG_VERSION__ <= 240) +# define BOOST_NO_VOID_RETURNS +#endif + +#if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +#endif + +#if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) +# define BOOST_NO_IS_ABSTRACT +#endif + +#if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// See also kai.hpp which checks a Kai-specific symbol for EH +# if !defined(__KCC) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +# if !defined(__NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +# endif + +#ifdef c_plusplus +// EDG has "long long" in non-strict mode +// However, some libraries have insufficient "long long" support +// #define BOOST_HAS_LONG_LONG +#endif + + + diff --git a/thirdparty/boost/config/compiler/compaq_cxx.hpp b/thirdparty/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 0000000..8fb73fb --- /dev/null +++ b/thirdparty/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,19 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Tru64 C++ compiler setup (now HP): + +#define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) + +#include "boost/config/compiler/common_edg.hpp" + +// +// versions check: +// Nothing to do here? + + + diff --git a/thirdparty/boost/config/compiler/digitalmars.hpp b/thirdparty/boost/config/compiler/digitalmars.hpp new file mode 100644 index 0000000..41f49a8 --- /dev/null +++ b/thirdparty/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,67 @@ +// Copyright (C) Christof Meerwald 2003 +// Copyright (C) Dan Watkins 2003 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Digital Mars C++ compiler setup: +#define BOOST_COMPILER __DMC_VERSION_STRING__ + +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_PRAGMA_ONCE + +#if (__DMC__ <= 0x833) +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TEMPLATE_TEMPLATES +#define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING +#define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +#endif +#if (__DMC__ <= 0x840) || !defined(BOOST_STRICT_CONFIG) +#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_NO_OPERATORS_IN_NAMESPACE +#define BOOST_NO_UNREACHABLE_RETURN_DETECTION +#define BOOST_NO_SFINAE +#define BOOST_NO_USING_TEMPLATE +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// has macros: +#if (__DMC__ >= 0x840) +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_WINTHREADS +#endif + +#if (__DMC__ >= 0x847) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// +// Is this really the best way to detect whether the std lib is in namespace std? +// +#include +#if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) +# define BOOST_NO_STDC_NAMESPACE +#endif + + +// check for exception handling support: +#ifndef _CPPUNWIND +# define BOOST_NO_EXCEPTIONS +#endif + +#if __DMC__ < 0x800 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is ...: +#if (__DMC__ > 0x848) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/thirdparty/boost/config/compiler/gcc.hpp b/thirdparty/boost/config/compiler/gcc.hpp new file mode 100644 index 0000000..c71870f --- /dev/null +++ b/thirdparty/boost/config/compiler/gcc.hpp @@ -0,0 +1,149 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GNU C++ compiler setup: + +#if __GNUC__ < 3 +# if __GNUC_MINOR__ == 91 + // egcs 1.1 won't parse shared_ptr.hpp without this: +# define BOOST_NO_AUTO_PTR +# endif +# if __GNUC_MINOR__ < 95 + // + // Prior to gcc 2.95 member templates only partly + // work - define BOOST_MSVC6_MEMBER_TEMPLATES + // instead since inline member templates mostly work. + // +# define BOOST_NO_MEMBER_TEMPLATES +# if __GNUC_MINOR__ >= 9 +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif +# endif + +# if __GNUC_MINOR__ < 96 +# define BOOST_NO_SFINAE +# endif + +# if __GNUC_MINOR__ <= 97 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif + +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_IS_ABSTRACT +#elif __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + // + // gcc-3.x problems: + // + // Bug specific to gcc 3.1 and 3.2: + // +# if ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2)) +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# endif +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#ifndef __EXCEPTIONS +# define BOOST_NO_EXCEPTIONS +#endif + + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +// +// gcc implements the named return value optimization since version 3.1 +// +#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) +#define BOOST_HAS_NRVO +#endif + +// +// C++0x features +// +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_DECLTYPE +# endif +#endif + +// +// Potential C++0x features +// + +// Variadic templates compiler: +// http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html +#ifdef __VARIADIC_TEMPLATES +# define BOOST_HAS_VARIADIC_TMPL +#endif + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "GNU C++ version " __VERSION__ +#endif + +// +// versions check: +// we don't know gcc prior to version 2.90: +#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 90) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4.3 (Pre-release): +#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 3)) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/thirdparty/boost/config/compiler/gcc_xml.hpp b/thirdparty/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 0000000..76954a9 --- /dev/null +++ b/thirdparty/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,30 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GCC-XML C++ compiler setup: + +# if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ + + diff --git a/thirdparty/boost/config/compiler/greenhills.hpp b/thirdparty/boost/config/compiler/greenhills.hpp new file mode 100644 index 0000000..1dd89d1 --- /dev/null +++ b/thirdparty/boost/config/compiler/greenhills.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Greenhills C++ compiler setup: + +#define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) + +#include "boost/config/compiler/common_edg.hpp" + +// +// versions check: +// we don't support Greenhills prior to version 0: +#if __ghs < 0 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0: +#if (__ghs > 0) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/thirdparty/boost/config/compiler/hp_acc.hpp b/thirdparty/boost/config/compiler/hp_acc.hpp new file mode 100644 index 0000000..a0798d7 --- /dev/null +++ b/thirdparty/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// HP aCC C++ compiler setup: + +#if defined(__EDG__) +#include "boost/config/compiler/common_edg.hpp" +#endif + +#if (__HP_aCC <= 33100) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# if !defined(_NAMESPACE_STD) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +# endif +#endif + +#if (__HP_aCC <= 33300) +// member templates are sufficiently broken that we disable them for now +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +#endif + +#if (__HP_aCC <= 38000) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (__HP_aCC > 50000) && (__HP_aCC < 60000) +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SWPRINTF +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +// optional features rather than defects: +#if (__HP_aCC >= 33900) +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +#if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +// This macro should not be defined when compiling in strict ansi +// mode, but, currently, we don't have the ability to determine +// what standard mode we are compiling with. Some future version +// of aCC6 compiler will provide predefined macros reflecting the +// compilation options, including the standard mode. +#if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) + +// +// versions check: +// we don't support HP aCC prior to version 33000: +#if __HP_aCC < 33000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// +// Extended checks for supporting aCC on PA-RISC +#if __HP_aCC > 30000 && __HP_aCC < 50000 +# if __HP_aCC < 38000 + // versions prior to version A.03.80 not supported +# error "Compiler version not supported - version A.03.80 or higher is required" +# elif !defined(__hpxstd98) + // must compile using the option +hpxstd98 with version A.03.80 and above +# error "Compiler option '+hpxstd98' is required for proper support" +# endif //PA-RISC +#endif + +// +// last known and checked version for HP-UX/ia64 is 61300 +// last known and checked version for PA-RISC is 38000 +#if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/thirdparty/boost/config/compiler/intel.hpp b/thirdparty/boost/config/compiler/intel.hpp new file mode 100644 index 0000000..7f238f3 --- /dev/null +++ b/thirdparty/boost/config/compiler/intel.hpp @@ -0,0 +1,162 @@ +// (C) Copyright John Maddock 2001-8. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright Guillaume Melquiond 2002 - 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Martin Wille 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Intel compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +#if defined(__INTEL_COMPILER) +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +#define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 500) && defined(_MSC_VER) +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 600) + +# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) + +// Boost libraries assume strong standard conformance unless otherwise +// indicated by a config macro. As configured by Intel, the EDG front-end +// requires certain compiler options be set to achieve that strong conformance. +// Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) +// and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for +// details as they apply to particular versions of the compiler. When the +// compiler does not predefine a macro indicating if an option has been set, +// this config file simply assumes the option has been set. +// Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if +// the compiler option is not enabled. + +# define BOOST_NO_SWPRINTF +# endif + +// Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 +#if BOOST_INTEL_CXX_VERSION < 600 +# define BOOST_NO_INTRINSIC_WCHAR_T +#else +// We should test the macro _WCHAR_T_DEFINED to check if the compiler +// supports wchar_t natively. *BUT* there is a problem here: the standard +// headers define this macro if they typedef wchar_t. Anyway, we're lucky +// because they define it without a value, while Intel C++ defines it +// to 1. So we can check its value to see if the macro was defined natively +// or not. +// Under UNIX, the situation is exactly the same, but the macro _WCHAR_T +// is used instead. +# if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) +# define BOOST_NO_INTRINSIC_WCHAR_T +# endif +#endif + +#if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +// +// Figure out when Intel is emulating this gcc bug +// (All Intel versions prior to 9.0.26, and versions +// later than that if they are set up to emulate gcc 3.2 +// or earlier): +// +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# endif +#endif +#if (defined(__GNUC__) && (__GNUC__ < 4)) || defined(_WIN32) +// GCC or VC emulation: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif +// +// Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T +// set correctly, if we don't do this now, we will get errors later +// in type_traits code among other things, getting this correct +// for the Intel compiler is actually remarkably fragile and tricky: +// +#if defined(BOOST_NO_INTRINSIC_WCHAR_T) +#include +template< typename T > struct assert_no_intrinsic_wchar_t; +template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; +// if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T +// where it is defined above: +typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; +#else +template< typename T > struct assert_intrinsic_wchar_t; +template<> struct assert_intrinsic_wchar_t {}; +// if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: +template<> struct assert_intrinsic_wchar_t {}; +#endif + +#if _MSC_VER+0 >= 1000 +# if _MSC_VER >= 1200 +# define BOOST_HAS_MS_INT64 +# endif +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#elif defined(_WIN32) +# define BOOST_DISABLE_WIN32 +#endif + +// I checked version 6.0 build 020312Z, it implements the NRVO. +// Correct this as you find out which version of the compiler +// implemented the NRVO first. (Daniel Frey) +#if (BOOST_INTEL_CXX_VERSION >= 600) +# define BOOST_HAS_NRVO +#endif + +// +// versions check: +// we don't support Intel prior to version 5.0: +#if BOOST_INTEL_CXX_VERSION < 500 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (BOOST_INTEL_CXX_VERSION > 1010) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# elif defined(_MSC_VER) +// +// We don't emit this warning any more, since we have so few +// defect macros set anyway (just the one). +// +//# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/thirdparty/boost/config/compiler/kai.hpp b/thirdparty/boost/config/compiler/kai.hpp new file mode 100644 index 0000000..839341c --- /dev/null +++ b/thirdparty/boost/config/compiler/kai.hpp @@ -0,0 +1,35 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Kai C++ compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +# if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) + // at least on Sun, the contents of is not in namespace std +# define BOOST_NO_STDC_NAMESPACE +# endif + +// see also common_edg.hpp which needs a special check for __KCC +# if !defined(_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +#define BOOST_COMPILER "Kai C++ version " BOOST_STRINGIZE(__KCC_VERSION) + +// +// last known and checked version is 4001: +#if (__KCC_VERSION > 4001) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/thirdparty/boost/config/compiler/metrowerks.hpp b/thirdparty/boost/config/compiler/metrowerks.hpp new file mode 100644 index 0000000..0f27b77 --- /dev/null +++ b/thirdparty/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,111 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks C++ compiler setup: + +// locale support is disabled when linking with the dynamic runtime +# ifdef _MSL_NO_LOCALE +# define BOOST_NO_STD_LOCALE +# endif + +# if __MWERKS__ <= 0x2301 // 5.3 +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_POINTER_TO_MEMBER_CONST +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# endif + +# if __MWERKS__ <= 0x2401 // 6.2 +//# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if(__MWERKS__ <= 0x2407) // 7.x +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# endif + +# if(__MWERKS__ <= 0x3003) // 8.x +# define BOOST_NO_SFINAE +# endif + +// the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last +// tested version *only*: +# if(__MWERKS__ <= 0x3206) || !defined(BOOST_STRICT_CONFIG) // 9.5 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_IS_ABSTRACT +# endif + +#if !__option(wchar_type) +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if !__option(exceptions) +# define BOOST_NO_EXCEPTIONS +#endif + +#if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) +# if __MWERKS__ == 0x3000 +# define BOOST_COMPILER_VERSION 8.0 +# elif __MWERKS__ == 0x3001 +# define BOOST_COMPILER_VERSION 8.1 +# elif __MWERKS__ == 0x3002 +# define BOOST_COMPILER_VERSION 8.2 +# elif __MWERKS__ == 0x3003 +# define BOOST_COMPILER_VERSION 8.3 +# elif __MWERKS__ == 0x3200 +# define BOOST_COMPILER_VERSION 9.0 +# elif __MWERKS__ == 0x3201 +# define BOOST_COMPILER_VERSION 9.1 +# elif __MWERKS__ == 0x3202 +# define BOOST_COMPILER_VERSION 9.2 +# elif __MWERKS__ == 0x3204 +# define BOOST_COMPILER_VERSION 9.3 +# elif __MWERKS__ == 0x3205 +# define BOOST_COMPILER_VERSION 9.4 +# elif __MWERKS__ == 0x3206 +# define BOOST_COMPILER_VERSION 9.5 +# else +# define BOOST_COMPILER_VERSION __MWERKS__ +# endif +#else +# define BOOST_COMPILER_VERSION __MWERKS__ +#endif + +// +// C++0x features +// +#if __MWERKS__ > 0x3206 && __option(rvalue_refs) +# define BOOST_HAS_RVALUE_REFS +#endif + +#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Metrowerks prior to version 5.3: +#if __MWERKS__ < 0x2301 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__MWERKS__ > 0x3205) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/thirdparty/boost/config/compiler/mpw.hpp b/thirdparty/boost/config/compiler/mpw.hpp new file mode 100644 index 0000000..fc211f8 --- /dev/null +++ b/thirdparty/boost/config/compiler/mpw.hpp @@ -0,0 +1,51 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// MPW C++ compilers setup: + +# if defined(__SC__) +# define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) +# elif defined(__MRC__) +# define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) +# else +# error "Using MPW compiler configuration by mistake. Please update." +# endif + +// +// MPW 8.90: +// +#if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_USING_TEMPLATE + +# define BOOST_NO_CWCHAR +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ +#endif + +// +// versions check: +// we don't support MPW prior to version 8.9: +#if MPW_CPLUS < 0x890 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x890: +#if (MPW_CPLUS > 0x890) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/thirdparty/boost/config/compiler/pgi.hpp b/thirdparty/boost/config/compiler/pgi.hpp new file mode 100644 index 0000000..62303aa --- /dev/null +++ b/thirdparty/boost/config/compiler/pgi.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Noel Belcourt 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// PGI C++ compiler setup: + +#define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// + +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_SWPRINTF + +// +// version check: +// probably nothing to do here? + diff --git a/thirdparty/boost/config/compiler/sgi_mipspro.hpp b/thirdparty/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 0000000..9139c05 --- /dev/null +++ b/thirdparty/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// SGI C++ compiler setup: + +#define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +#include "boost/config/compiler/common_edg.hpp" + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// +#define BOOST_HAS_THREADS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#undef BOOST_NO_SWPRINTF +#undef BOOST_DEDUCED_TYPENAME +// +// version check: +// probably nothing to do here? + + diff --git a/thirdparty/boost/config/compiler/sunpro_cc.hpp b/thirdparty/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 0000000..6d52602 --- /dev/null +++ b/thirdparty/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,98 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Sun C++ compiler setup: + +# if __SUNPRO_CC <= 0x500 +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if (__SUNPRO_CC <= 0x520) + // + // Sunpro 5.2 and earler: + // + // although sunpro 5.2 supports the syntax for + // inline initialization it often gets the value + // wrong, especially where the value is computed + // from other constants (J Maddock 6th May 2001) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // Although sunpro 5.2 supports the syntax for + // partial specialization, it often seems to + // bind to the wrong specialization. Better + // to disable it until suppport becomes more stable + // (J Maddock 6th May 2001). +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# endif + +# if (__SUNPRO_CC <= 0x530) + // Requesting debug info (-g) with Boost.Python results + // in an internal compiler error for "static const" + // initialized in-class. + // >> Assertion: (../links/dbg_cstabs.cc, line 611) + // while processing ../test.cpp at line 0. + // (Jens Maurer according to Gottfried Ganßauge 04 Mar 2002) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // SunPro 5.3 has better support for partial specialization, + // but breaks when compiling std::less > + // (Jens Maurer 4 Nov 2001). + + // std::less specialization fixed as reported by George + // Heintzelman; partial specialization re-enabled + // (Peter Dimov 17 Jan 2002) + +//# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // integral constant expressions with 64 bit numbers fail +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +# if (__SUNPRO_CC < 0x570) +# define BOOST_NO_TEMPLATE_TEMPLATES + // see http://lists.boost.org/MailArchives/boost/msg47184.php + // and http://lists.boost.org/MailArchives/boost/msg47220.php +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_SFINAE +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif +# if (__SUNPRO_CC <= 0x580) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Issues that effect all known versions: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + + +#define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) + +// +// versions check: +// we don't support sunpro prior to version 4: +#if __SUNPRO_CC < 0x400 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x590: +#if (__SUNPRO_CC > 0x590) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + diff --git a/thirdparty/boost/config/compiler/vacpp.hpp b/thirdparty/boost/config/compiler/vacpp.hpp new file mode 100644 index 0000000..5680aca --- /dev/null +++ b/thirdparty/boost/config/compiler/vacpp.hpp @@ -0,0 +1,60 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schöpflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Visual Age (IBM) C++ compiler setup: + +#if __IBMCPP__ <= 501 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +#if (__IBMCPP__ <= 502) +// Actually the compiler supports inclass member initialization but it +// requires a definition for the class member and it doesn't recognize +// it as an integral constant expression when used as a template argument. +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +#if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// +// On AIX thread support seems to be indicated by _THREAD_SAFE: +// +#ifdef _THREAD_SAFE +# define BOOST_HAS_THREADS +#endif + +#define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) + +// +// versions check: +// we don't support Visual age prior to version 5: +#if __IBMCPP__ < 500 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 600: +#if (__IBMCPP__ > 600) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +// Some versions of the compiler have issues with default arguments on partial specializations +#define BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS + + + + diff --git a/thirdparty/boost/config/compiler/visualc.hpp b/thirdparty/boost/config/compiler/visualc.hpp new file mode 100644 index 0000000..ff67549 --- /dev/null +++ b/thirdparty/boost/config/compiler/visualc.hpp @@ -0,0 +1,191 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Microsoft Visual C++ compiler setup: + +#define BOOST_MSVC _MSC_VER + +// turn off the warnings before we #include anything +#pragma warning( disable : 4503 ) // warning: decorated name length exceeded + +#if _MSC_VER < 1300 // 1200 == VC++ 6.0, 1200-1202 == eVC++4 +# pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_EXCEPTION_STD_NAMESPACE + // disable min/max macro defines on vc6: + // +#endif + +#if (_MSC_VER <= 1300) // 1300 == VC++ 7.0 + +# if !defined(_MSC_EXTENSIONS) && !defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) // VC7 bug with /Za +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# endif + +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEDUCED_TYPENAME +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + +// VC++ 6/7 has member templates but they have numerous problems including +// cases of silent failure, so for safety we define: +# define BOOST_NO_MEMBER_TEMPLATES +// For VC++ experts wishing to attempt workarounds, we define: +# define BOOST_MSVC6_MEMBER_TEMPLATES + +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SFINAE +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +// TODO: what version is meant here? Have there really been any fixes in cl 12.01 (as e.g. shipped with eVC4)? +# if (_MSC_VER > 1200) +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# endif + +#endif + +#if _MSC_VER < 1400 +// although a conforming signature for swprint exists in VC7.1 +// it appears not to actually work: +# define BOOST_NO_SWPRINTF +#endif + +#if defined(UNDER_CE) +// Windows CE does not have a conforming signature for swprintf +# define BOOST_NO_SWPRINTF +#endif + +#if _MSC_VER <= 1400 // 1400 == VC++ 8.0 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +#if _MSC_VER <= 1500 // 1500 == VC++ 9.0 +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#ifndef _NATIVE_WCHAR_T_DEFINED +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if defined(_WIN32_WCE) || defined(UNDER_CE) +# define BOOST_NO_THREADEX +# define BOOST_NO_GETSYSTEMTIMEASFILETIME +# define BOOST_NO_SWPRINTF +#endif + +// +// check for exception handling support: +#ifndef _CPPUNWIND +# define BOOST_NO_EXCEPTIONS +#endif + +// +// __int64 support: +// +#if (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +#endif +#if (_MSC_VER >= 1310) && defined(_MSC_EXTENSIONS) +# define BOOST_HAS_LONG_LONG +#endif +#if (_MSC_VER >= 1400) && !defined(_DEBUG) +# define BOOST_HAS_NRVO +#endif +// +// disable Win32 API's if compiler extentions are +// turned off: +// +#ifndef _MSC_EXTENSIONS +# define BOOST_DISABLE_WIN32 +#endif + +// +// all versions support __declspec: +// +#define BOOST_HAS_DECLSPEC +// +// prefix and suffix headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" +#endif + +// TODO: +// these things are mostly bogus. 1200 means version 12.0 of the compiler. The +// artificial versions assigned to them only refer to the versions of some IDE +// these compilers have been shipped with, and even that is not all of it. Some +// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. +// IOW, you can't use these 'versions' in any sensible way. Sorry. +# if defined(UNDER_CE) +# if _MSC_VER < 1200 + // Note: these are so far off, they are not really supported +# elif _MSC_VER < 1300 // eVC++ 4 comes with 1200-1202 +# define BOOST_COMPILER_VERSION evc4.0 +# elif _MSC_VER == 1400 +# define BOOST_COMPILER_VERSION evc8 +# else +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1200 + // Note: these are so far off, they are not really supported +# define BOOST_COMPILER_VERSION 5.0 +# elif _MSC_VER < 1300 +# define BOOST_COMPILER_VERSION 6.0 +# elif _MSC_VER == 1300 +# define BOOST_COMPILER_VERSION 7.0 +# elif _MSC_VER == 1310 +# define BOOST_COMPILER_VERSION 7.1 +# elif _MSC_VER == 1400 +# define BOOST_COMPILER_VERSION 8.0 +# elif _MSC_VER == 1500 +# define BOOST_COMPILER_VERSION 9.0 +# else +# define BOOST_COMPILER_VERSION _MSC_VER +# endif +# endif + +#define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Visual C++ prior to version 6: +#if _MSC_VER < 1200 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 1400 (VC8): +#if (_MSC_VER > 1500) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif diff --git a/thirdparty/boost/config/no_tr1/complex.hpp b/thirdparty/boost/config/no_tr1/complex.hpp new file mode 100644 index 0000000..c6f4254 --- /dev/null +++ b/thirdparty/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/thirdparty/boost/config/no_tr1/functional.hpp b/thirdparty/boost/config/no_tr1/functional.hpp new file mode 100644 index 0000000..08d46fc --- /dev/null +++ b/thirdparty/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/thirdparty/boost/config/no_tr1/memory.hpp b/thirdparty/boost/config/no_tr1/memory.hpp new file mode 100644 index 0000000..d998a54 --- /dev/null +++ b/thirdparty/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/thirdparty/boost/config/no_tr1/utility.hpp b/thirdparty/boost/config/no_tr1/utility.hpp new file mode 100644 index 0000000..40f2234 --- /dev/null +++ b/thirdparty/boost/config/no_tr1/utility.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/utility is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_UTILITY +# define BOOST_CONFIG_UTILITY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +#endif diff --git a/thirdparty/boost/config/platform/aix.hpp b/thirdparty/boost/config/platform/aix.hpp new file mode 100644 index 0000000..36b6ab2 --- /dev/null +++ b/thirdparty/boost/config/platform/aix.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// IBM/Aix specific config options: + +#define BOOST_PLATFORM "IBM Aix" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME + +// This needs support in "boost/cstdint.hpp" exactly like FreeBSD. +// This platform has header named which includes all +// the things needed. +#define BOOST_HAS_STDINT_H + +// Threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_DELAY_NP +#define BOOST_HAS_SCHED_YIELD +//#define BOOST_HAS_PTHREAD_YIELD + +// boilerplate code: +#include + + + + diff --git a/thirdparty/boost/config/platform/amigaos.hpp b/thirdparty/boost/config/platform/amigaos.hpp new file mode 100644 index 0000000..fe22635 --- /dev/null +++ b/thirdparty/boost/config/platform/amigaos.hpp @@ -0,0 +1,15 @@ +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#define BOOST_PLATFORM "AmigaOS" + +#define BOOST_DISABLE_THREADS +#define BOOST_NO_CWCHAR +#define BOOST_NO_STD_WSTRING +#define BOOST_NO_INTRINSIC_WCHAR_T + + diff --git a/thirdparty/boost/config/platform/beos.hpp b/thirdparty/boost/config/platform/beos.hpp new file mode 100644 index 0000000..507ef82 --- /dev/null +++ b/thirdparty/boost/config/platform/beos.hpp @@ -0,0 +1,26 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// BeOS specific config options: + +#define BOOST_PLATFORM "BeOS" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_CWCTYPE +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_BETHREADS + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +// boilerplate code: +#include + + + diff --git a/thirdparty/boost/config/platform/bsd.hpp b/thirdparty/boost/config/platform/bsd.hpp new file mode 100644 index 0000000..b027d83 --- /dev/null +++ b/thirdparty/boost/config/platform/bsd.hpp @@ -0,0 +1,73 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Douglas Gregor 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic BSD config options: + +#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) +#error "This platform is not BSD" +#endif + +#ifdef __FreeBSD__ +#define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) +#elif defined(__NetBSD__) +#define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) +#elif defined(__OpenBSD__) +#define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) +#elif defined(__DragonFly__) +#define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) +#endif + +// +// is this the correct version check? +// FreeBSD has but does not +// advertise the fact in : +// +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__) +# define BOOST_HAS_NL_TYPES_H +#endif + +// +// FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in +// and not in +// +#if (defined(__FreeBSD__) && (__FreeBSD__ <= 3)) || defined(__OpenBSD__) +# define BOOST_HAS_PTHREADS +#endif + +// +// No wide character support in the BSD header files: +// +#if !(defined(__FreeBSD__) && (__FreeBSD__ >= 5)) +# define BOOST_NO_CWCHAR +#endif +// +// The BSD has macros only, no functions: +// +#if !defined(__OpenBSD__) +# define BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_SIGACTION + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + + + + diff --git a/thirdparty/boost/config/platform/cygwin.hpp b/thirdparty/boost/config/platform/cygwin.hpp new file mode 100644 index 0000000..514ad25 --- /dev/null +++ b/thirdparty/boost/config/platform/cygwin.hpp @@ -0,0 +1,51 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// cygwin specific config options: + +#define BOOST_PLATFORM "Cygwin" +#define BOOST_NO_CWCTYPE +#define BOOST_NO_CWCHAR +#define BOOST_NO_SWPRINTF +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + +// +// Threading API: +// See if we have POSIX threads, if we do use them, otherwise +// revert to native Win threads. +#define BOOST_HAS_UNISTD_H +#include +#if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_SIGACTION +#else +# if !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_WINTHREADS +# endif +# define BOOST_HAS_FTIME +#endif + +// +// find out if we have a stdint.h, there should be a better way to do this: +// +#include +#ifdef _STDINT_H +#define BOOST_HAS_STDINT_H +#endif + +// boilerplate code: +#include + + + + + diff --git a/thirdparty/boost/config/platform/hpux.hpp b/thirdparty/boost/config/platform/hpux.hpp new file mode 100644 index 0000000..ff331c1 --- /dev/null +++ b/thirdparty/boost/config/platform/hpux.hpp @@ -0,0 +1,84 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// hpux specific config options: + +#define BOOST_PLATFORM "HP-UX" + +// In principle, HP-UX has a nice under the name +// However, it has the following problem: +// Use of UINT32_C(0) results in "0u l" for the preprocessed source +// (verifyable with gcc 2.95.3) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) +# define BOOST_HAS_STDINT_H +#endif + +#if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) +# define BOOST_NO_SWPRINTF +# define BOOST_NO_CWCTYPE +#endif + +#if defined(__GNUC__) +# if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) + // GNU C on HP-UX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +# elif !defined(BOOST_DISABLE_THREADS) + // threads supported from gcc-3.3 onwards: +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# endif +#elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_HAS_PTHREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// the following are always available: +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +#endif +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#endif +#ifndef BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NL_TYPES_H +#endif +#ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +#endif +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +#endif +#ifndef BOOST_HAS_CLOCK_GETTIME +# define BOOST_HAS_CLOCK_GETTIME +#endif +#ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +#endif +#ifndef BOOST_HAS_NRVO +# ifndef __parisc +# define BOOST_HAS_NRVO +# endif +#endif +#ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +#endif +#ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +#endif diff --git a/thirdparty/boost/config/platform/irix.hpp b/thirdparty/boost/config/platform/irix.hpp new file mode 100644 index 0000000..e0691a4 --- /dev/null +++ b/thirdparty/boost/config/platform/irix.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "SGI Irix" + +#define BOOST_NO_SWPRINTF +// +// these are not auto detected by POSIX feature tests: +// +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#ifdef __GNUC__ + // GNU C on IRIX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/thirdparty/boost/config/platform/linux.hpp b/thirdparty/boost/config/platform/linux.hpp new file mode 100644 index 0000000..b87db79 --- /dev/null +++ b/thirdparty/boost/config/platform/linux.hpp @@ -0,0 +1,98 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#include + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. +# if defined __GNUC__ +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/thirdparty/boost/config/platform/macos.hpp b/thirdparty/boost/config/platform/macos.hpp new file mode 100644 index 0000000..1984c57 --- /dev/null +++ b/thirdparty/boost/config/platform/macos.hpp @@ -0,0 +1,78 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Bill Kempf 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Mac OS specific config options: + +#define BOOST_PLATFORM "Mac OS" + +#if __MACH__ && !defined(_MSL_USING_MSL_C) + +// Using the Mac OS X system BSD-style C library. + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif +// +// Begin by including our boilerplate code for POSIX +// feature detection, this is safe even when using +// the MSL as Metrowerks supply their own +// to replace the platform-native BSD one. G++ users +// should also always be able to do this on MaxOS X. +// +# include +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif + +// +// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, +// of these only pthreads are advertised in , so set the +// other options explicitly: +// +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_SIGACTION + +# if (__GNUC__ < 3) && !defined( __APPLE_CC__) + +// GCC strange "ignore std" mode works better if you pretend everything +// is in the std namespace, for the most part. + +# define BOOST_NO_STDC_NAMESPACE +# endif + +#else + +// Using the MSL C library. + +// We will eventually support threads in non-Carbon builds, but we do +// not support this yet. +# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) + +# if !defined(BOOST_HAS_PTHREADS) +# define BOOST_HAS_MPTASKS +# elif ( __dest_os == __mac_os_x ) +// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the +// gettimeofday and no posix. +# define BOOST_HAS_GETTIMEOFDAY +# endif + +// The MP task implementation of Boost Threads aims to replace MP-unsafe +// parts of the MSL, so we turn on threads unconditionally. +# define BOOST_HAS_THREADS + +// The remote call manager depends on this. +# define BOOST_BIND_ENABLE_PASCAL + +# endif + +#endif + + + diff --git a/thirdparty/boost/config/platform/qnxnto.hpp b/thirdparty/boost/config/platform/qnxnto.hpp new file mode 100644 index 0000000..102f27c --- /dev/null +++ b/thirdparty/boost/config/platform/qnxnto.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jim Douglas 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// QNX specific config options: + +#define BOOST_PLATFORM "QNX" + +#define BOOST_HAS_UNISTD_H +#include + +// QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h +// or log1p and expm1: +#undef BOOST_HAS_NL_TYPES_H +#undef BOOST_HAS_LOG1P +#undef BOOST_HAS_EXPM1 + +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_NANOSLEEP + + + + + diff --git a/thirdparty/boost/config/platform/solaris.hpp b/thirdparty/boost/config/platform/solaris.hpp new file mode 100644 index 0000000..8a8478d --- /dev/null +++ b/thirdparty/boost/config/platform/solaris.hpp @@ -0,0 +1,21 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// sun specific config options: + +#define BOOST_PLATFORM "Sun Solaris" + +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + + diff --git a/thirdparty/boost/config/platform/win32.hpp b/thirdparty/boost/config/platform/win32.hpp new file mode 100644 index 0000000..d18b689 --- /dev/null +++ b/thirdparty/boost/config/platform/win32.hpp @@ -0,0 +1,58 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Bill Kempf 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Rene Rivera 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Win32 specific config options: + +#define BOOST_PLATFORM "Win32" + +// Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. +#if defined(__MINGW32__) +# include <_mingw.h> +#endif + +#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +#endif + +#if !defined(__GNUC__) && !defined(BOOST_HAS_DECLSPEC) +# define BOOST_HAS_DECLSPEC +#endif + +#if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) +# define BOOST_HAS_STDINT_H +# define __STDC_LIMIT_MACROS +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_UNISTD_H +#endif + +// +// Win32 will normally be using native Win32 threads, +// but there is a pthread library avaliable as an option, +// we used to disable this when BOOST_DISABLE_WIN32 was +// defined but no longer - this should allow some +// files to be compiled in strict mode - while maintaining +// a consistent setting of BOOST_HAS_THREADS across +// all translation units (needed for shared_ptr etc). +// + +#ifdef _WIN32_WCE +# define BOOST_NO_ANSI_APIS +#endif + +#ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_WINTHREADS +#endif + +#ifndef BOOST_DISABLE_WIN32 +// WEK: Added +#define BOOST_HAS_FTIME +#define BOOST_WINDOWS 1 + +#endif diff --git a/thirdparty/boost/config/posix_features.hpp b/thirdparty/boost/config/posix_features.hpp new file mode 100644 index 0000000..bc3921c --- /dev/null +++ b/thirdparty/boost/config/posix_features.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/thirdparty/boost/config/requires_threads.hpp b/thirdparty/boost/config/requires_threads.hpp new file mode 100644 index 0000000..b79723b --- /dev/null +++ b/thirdparty/boost/config/requires_threads.hpp @@ -0,0 +1,92 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP +#define BOOST_CONFIG_REQUIRES_THREADS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_DISABLE_THREADS) + +// +// special case to handle versions of gcc which don't currently support threads: +// +#if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) +// +// this is checked up to gcc 3.3: +// +#if defined(__sgi) || defined(__hpux) +# error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" +#endif + +#endif + +# error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" + +#elif !defined(BOOST_HAS_THREADS) + +# if defined __COMO__ +// Comeau C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +#ifdef _WIN32 +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" +#else +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" +#endif + +# elif defined __GNUC__ +// GNU C++: +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + +#elif defined __sgi +// SGI MIPSpro C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" + +#elif defined __BORLANDC__ +// Borland +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined __HP_aCC +// HP aCC +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" + +#else + +# error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" + +#endif // compilers + +#endif // BOOST_HAS_THREADS + +#endif // BOOST_CONFIG_REQUIRES_THREADS_HPP diff --git a/thirdparty/boost/config/select_compiler_config.hpp b/thirdparty/boost/config/select_compiler_config.hpp new file mode 100644 index 0000000..0605fef --- /dev/null +++ b/thirdparty/boost/config/select_compiler_config.hpp @@ -0,0 +1,115 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + + +// one identification macro for each of the +// compilers we support: + +# define BOOST_CXX_GCCXML 0 +# define BOOST_CXX_COMO 0 +# define BOOST_CXX_DMC 0 +# define BOOST_CXX_INTEL 0 +# define BOOST_CXX_GNUC 0 +# define BOOST_CXX_KCC 0 +# define BOOST_CXX_SGI 0 +# define BOOST_CXX_TRU64 0 +# define BOOST_CXX_GHS 0 +# define BOOST_CXX_BORLAND 0 +# define BOOST_CXX_CW 0 +# define BOOST_CXX_SUNPRO 0 +# define BOOST_CXX_HPACC 0 +# define BOOST_CXX_MPW 0 +# define BOOST_CXX_IBMCPP 0 +# define BOOST_CXX_MSVC 0 +# define BOOST_CXX_PGI 0 + + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +# elif defined __GNUC__ +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif diff --git a/thirdparty/boost/config/select_platform_config.hpp b/thirdparty/boost/config/select_platform_config.hpp new file mode 100644 index 0000000..3d3a69d --- /dev/null +++ b/thirdparty/boost/config/select_platform_config.hpp @@ -0,0 +1,90 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if defined(linux) || defined(__linux) || defined(__linux__) +// linux: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#else + +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + + + diff --git a/thirdparty/boost/config/select_stdlib_config.hpp b/thirdparty/boost/config/select_stdlib_config.hpp new file mode 100644 index 0000000..7c094fc --- /dev/null +++ b/thirdparty/boost/config/select_stdlib_config.hpp @@ -0,0 +1,68 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// we need to include a std lib header here in order to detect which +// library is in use, use as it's about the smallest +// of the std lib headers - do not rely on this header being included - +// users can short-circuit this header if they know whose std lib +// they are using. + +#include + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#elif defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + + + diff --git a/thirdparty/boost/config/stdlib/dinkumware.hpp b/thirdparty/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 0000000..fb6e101 --- /dev/null +++ b/thirdparty/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,106 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Guillaume Melquiond 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Dinkumware standard library config: + +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#error This is not the Dinkumware lib! +#endif +#endif + + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) + // full dinkumware 3.06 and above + // fully conforming provided the compiler supports it: +# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(__BORLANDC__) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h +# define BOOST_NO_STDC_NAMESPACE +# endif +# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) +# define BOOST_NO_STD_ALLOCATOR +# endif +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + // if this lib version is set up for vc6 then there is no std::use_facet: +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET + // C lib functions aren't in namespace std either: +# define BOOST_NO_STDC_NAMESPACE + // and nor is +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +// There's no numeric_limits support unless _LONGLONG is defined: +# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +// 3.06 appears to have (non-sgi versions of) & , +// and no at all +#else +# define BOOST_MSVC_STD_ITERATOR 1 +# define BOOST_NO_STD_ITERATOR +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_STD_USE_FACET +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# define BOOST_HAS_MACRO_USE_FACET +# ifndef _CPPLIB_VER + // Updated Dinkum library defines this, and provides + // its own min and max definitions. +# define BOOST_NO_STD_MIN_MAX +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +#endif + +// +// std extension namespace is stdext for vc7.1 and later, +// the same applies to other compilers that sit on top +// of vc7.1 (Intel and Comeau): +// +#if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(__BORLANDC__) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(__BORLANDC__)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) + // if we're using a dinkum lib that's + // been configured for VC6/7 then there is + // no iterator traits (true even for icl) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +#if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) +// Intel C++ chokes over any non-trivial use of +// this may be an overly restrictive define, but regex fails without it: +# define BOOST_NO_STD_LOCALE +#endif + +#ifdef _CPPLIB_VER +# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER +#else +# define BOOST_DINKUMWARE_STDLIB 1 +#endif + +#ifdef _CPPLIB_VER +# define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) +#else +# define BOOST_STDLIB "Dinkumware standard library version 1.x" +#endif + + + + + + + + + diff --git a/thirdparty/boost/config/stdlib/libcomo.hpp b/thirdparty/boost/config/stdlib/libcomo.hpp new file mode 100644 index 0000000..74cbb8c --- /dev/null +++ b/thirdparty/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,46 @@ +// (C) Copyright John Maddock 2002 - 2003. +// (C) Copyright Jens Maurer 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau STL: + +#if !defined(__LIBCOMO__) +# include +# if !defined(__LIBCOMO__) +# error "This is not the Comeau STL!" +# endif +#endif + +// +// std::streambuf is non-standard +// NOTE: versions of libcomo prior to beta28 have octal version numbering, +// e.g. version 25 is 21 (dec) +#if __LIBCOMO_VERSION__ <= 22 +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) +#define BOOST_NO_SWPRINTF +#endif + +#if __LIBCOMO_VERSION__ >= 31 +# define BOOST_HAS_HASH +# define BOOST_HAS_SLIST +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) + + diff --git a/thirdparty/boost/config/stdlib/libstdcpp3.hpp b/thirdparty/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 0000000..87eda3c --- /dev/null +++ b/thirdparty/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,73 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// config for libstdc++ v3 +// not much to go in here: + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +#endif diff --git a/thirdparty/boost/config/stdlib/modena.hpp b/thirdparty/boost/config/stdlib/modena.hpp new file mode 100644 index 0000000..40b851e --- /dev/null +++ b/thirdparty/boost/config/stdlib/modena.hpp @@ -0,0 +1,30 @@ +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Modena C++ standard library (comes with KAI C++) + +#if !defined(MSIPL_COMPILE_H) +# include +# if !defined(__MSIPL_COMPILE_H) +# error "This is not the Modena C++ library!" +# endif +#endif + +#ifndef MSIPL_NL_TYPES +#define BOOST_NO_STD_MESSAGES +#endif + +#ifndef MSIPL_WCHART +#define BOOST_NO_STD_WSTRING +#endif + +#define BOOST_STDLIB "Modena C++ standard library" + + + + + diff --git a/thirdparty/boost/config/stdlib/msl.hpp b/thirdparty/boost/config/stdlib/msl.hpp new file mode 100644 index 0000000..d6ccdd2 --- /dev/null +++ b/thirdparty/boost/config/stdlib/msl.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks standard library: + +#ifndef __MSL_CPP__ +# include +# ifndef __MSL_CPP__ +# error This is not the MSL standard library! +# endif +#endif + +#if __MSL_CPP__ >= 0x6000 // Pro 6 +# define BOOST_HAS_HASH +# define BOOST_STD_EXTENSION_NAMESPACE Metrowerks +#endif +#define BOOST_HAS_SLIST + +#if __MSL_CPP__ < 0x6209 +# define BOOST_NO_STD_MESSAGES +#endif + +// check C lib version for +#include + +#if defined(__MSL__) && (__MSL__ >= 0x5000) +# define BOOST_HAS_STDINT_H +# if !defined(__PALMOS_TRAPS__) +# define BOOST_HAS_UNISTD_H +# endif + // boilerplate code: +# include +#endif + +#if defined(_MWMT) || _MSL_THREADSAFE +# define BOOST_HAS_THREADS +#endif + +#ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + + +#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) + + + + + + + + + diff --git a/thirdparty/boost/config/stdlib/roguewave.hpp b/thirdparty/boost/config/stdlib/roguewave.hpp new file mode 100644 index 0000000..524742a --- /dev/null +++ b/thirdparty/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,153 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Boris Gubenko 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Rogue Wave std lib: + +#if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# include +# if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# error This is not the Rogue Wave standard library +# endif +#endif +// +// figure out a consistent version number: +// +#ifndef _RWSTD_VER +# define BOOST_RWSTD_VER 0x010000 +#elif _RWSTD_VER < 0x010000 +# define BOOST_RWSTD_VER (_RWSTD_VER << 8) +#else +# define BOOST_RWSTD_VER _RWSTD_VER +#endif + +#ifndef _RWSTD_VER +# define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" +#elif _RWSTD_VER < 0x04010200 + # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) +#else +# ifdef _RWSTD_VER_STR +# define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR +# else +# define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) +# endif +#endif + +// +// Prior to version 2.2.0 the primary template for std::numeric_limits +// does not have compile time constants, even though specializations of that +// template do: +// +#if BOOST_RWSTD_VER < 0x020200 +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the +// library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): +#if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// Borland version of numeric_limits lacks __int64 specialisation: +// +#ifdef __BORLANDC__ +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// No std::iterator if it can't figure out default template args: +// +#if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// No iterator traits without partial specialization: +// +#if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// Prior to version 2.0, std::auto_ptr was buggy, and there were no +// new-style iostreams, and no conformant std::allocator: +// +#if (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_STRINGSTREAM +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STD_LOCALE +#endif + +// +// No template iterator constructors without member template support: +// +#if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +#endif + +// +// RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use +// (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR +// on HP aCC systems even though the allocator is in fact broken): +// +#if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If we have a std::locale, we still may not have std::use_facet: +// +#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// +// There's no std::distance prior to version 2, or without +// partial specialization support: +// +#if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + #define BOOST_NO_STD_DISTANCE +#endif + +// +// Some versions of the rogue wave library don't have assignable +// OutputIterators: +// +#if BOOST_RWSTD_VER < 0x020100 +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +#endif + +// +// Disable BOOST_HAS_LONG_LONG when the library has no support for it. +// +#if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) +# undef BOOST_HAS_LONG_LONG +#endif + +// +// check that on HP-UX, the proper RW library is used +// +#if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) +# error "Boost requires Standard RW library. Please compile and link with -AA" +#endif + +// +// Define macros specific to RW V2.2 on HP-UX +// +#if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) +# ifndef __HP_TC1_MAKE_PAIR +# define __HP_TC1_MAKE_PAIR +# endif +# ifndef _HP_INSTANTIATE_STD2_VL +# define _HP_INSTANTIATE_STD2_VL +# endif +#endif diff --git a/thirdparty/boost/config/stdlib/sgi.hpp b/thirdparty/boost/config/stdlib/sgi.hpp new file mode 100644 index 0000000..6e9c55b --- /dev/null +++ b/thirdparty/boost/config/stdlib/sgi.hpp @@ -0,0 +1,111 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic SGI STL: + +#if !defined(__STL_CONFIG_H) +# include +# if !defined(__STL_CONFIG_H) +# error "This is not the SGI STL!" +# endif +#endif + +// +// No std::iterator traits without partial specialisation: +// +#if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No std::stringstream with gcc < 3 +// +#if defined(__GNUC__) && (__GNUC__ < 3) && \ + ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ + !defined(__STL_USE_NEW_IOSTREAMS) || \ + defined(__APPLE_CC__) + // Note that we only set this for GNU C++ prior to 2.95 since the + // latest patches for that release do contain a minimal + // If you are running a 2.95 release prior to 2.95.3 then this will need + // setting, but there is no way to detect that automatically (other + // than by running the configure script). + // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't + // have . +# define BOOST_NO_STRINGSTREAM +#endif + +// +// Assume no std::locale without own iostreams (this may be an +// incorrect assumption in some cases): +// +#if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// Original native SGI streams have non-standard std::messages facet: +// +#if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// SGI's new iostreams have missing "const" in messages<>::open +// +#if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_MESSAGES +#endif + +// +// No template iterator constructors, or std::allocator +// without member templates: +// +#if !defined(__STL_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// If this is GNU libstdc++2, then no and no std::wstring: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) +# include +# if defined(__BASTRING__) +# define BOOST_NO_LIMITS +// Note: will provide compile-time constants +# undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_STD_WSTRING +# endif +#endif + +// +// There is no standard iterator unless we have namespace support: +// +#if !defined(__STL_USE_NAMESPACES) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "SGI standard library" + + + diff --git a/thirdparty/boost/config/stdlib/stlport.hpp b/thirdparty/boost/config/stdlib/stlport.hpp new file mode 100644 index 0000000..c2cb8d4 --- /dev/null +++ b/thirdparty/boost/config/stdlib/stlport.hpp @@ -0,0 +1,201 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// STLPort standard library config: + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# include +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# error "This is not STLPort!" +# endif +#endif + +// +// __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// for versions prior to 4.1(beta) +// +#if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// +// If STLport thinks that there is no partial specialisation, then there is no +// std::iterator traits: +// +#if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No new style iostreams on GCC without STLport's iostreams enabled: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) +# define BOOST_NO_STRINGSTREAM +#endif + +// +// No new iostreams implies no std::locale, and no std::stringstream: +// +#if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +#endif + +// +// If the streams are not native, and we have a "using ::x" compiler bug +// then the io stream facets are not available in namespace std:: +// +#ifdef _STLPORT_VERSION +# if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#endif + +// +// Without member template support enabled, their are no template +// iterate constructors, and no std::allocator: +// +#if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif +// +// however we always have at least a partial allocator: +// +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR + +#if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) +# define BOOST_NO_STD_ALLOCATOR +#endif + +#if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If STLport thinks there is no wchar_t at all, then we have to disable +// the support for the relevant specilazations of std:: templates. +// +#if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) +# ifndef BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTRING +# endif +# ifndef BOOST_NO_STD_WSTREAMBUF +# define BOOST_NO_STD_WSTREAMBUF +# endif +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// STLport does a good job of importing names into namespace std::, +// but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our +// workaround does not conflict with STLports: +// +// +// Harold Howe says: +// Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with +// BCB6 does cause problems. If we detect C++ Builder, then don't define +// BOOST_NO_STDC_NAMESPACE +// +#if !defined(__BORLANDC__) && !defined(__DMC__) +// +// If STLport is using it's own namespace, and the real names are in +// the global namespace, then we duplicate STLport's using declarations +// (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't +// necessarily import all the names we need into namespace std:: +// +# if (defined(__STL_IMPORT_VENDOR_CSTD) \ + || defined(__STL_USE_OWN_NAMESPACE) \ + || defined(_STLP_IMPORT_VENDOR_CSTD) \ + || defined(_STLP_USE_OWN_NAMESPACE)) \ + && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +#elif defined(__BORLANDC__) && __BORLANDC__ < 0x560 +// STLport doesn't import std::abs correctly: +#include +namespace std { using ::abs; } +// and strcmp/strcpy don't get imported either ('cos they are macros) +#include +#ifdef strcpy +# undef strcpy +#endif +#ifdef strcmp +# undef strcmp +#endif +#ifdef _STLP_VENDOR_CSTD +namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } +#endif +#endif + +// +// std::use_facet may be non-standard, uses a class instead: +// +#if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_STLP_USE_FACET +#endif + +// +// If STLport thinks there are no wide functions, etc. is not working; but +// only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import +// into std:: ourselves). +// +#if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +#endif + +// +// If STLport for some reason was configured so that it thinks that wchar_t +// is not an intrinsic type, then we have to disable the support for it as +// well (we would be missing required specializations otherwise). +// +#if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) +# undef BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// Borland ships a version of STLport with C++ Builder 6 that lacks +// hashtables and the like: +// +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x560) +# undef BOOST_HAS_HASH +#endif + +// +// gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max +// +#if defined(__GNUC__) && (__GNUC__ < 3) +# include // for std::min and std::max +# define BOOST_USING_STD_MIN() ((void)0) +# define BOOST_USING_STD_MAX() ((void)0) +namespace boost { using std::min; using std::max; } +#endif + +#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) + + + + + + + + diff --git a/thirdparty/boost/config/stdlib/vacpp.hpp b/thirdparty/boost/config/stdlib/vacpp.hpp new file mode 100644 index 0000000..1e2c8b3 --- /dev/null +++ b/thirdparty/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,18 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#if __IBMCPP__ <= 501 +# define BOOST_NO_STD_ALLOCATOR +#endif + +#define BOOST_HAS_MACRO_USE_FACET +#define BOOST_NO_STD_MESSAGES + +#define BOOST_STDLIB "Visual Age default standard library" + + + diff --git a/thirdparty/boost/config/suffix.hpp b/thirdparty/boost/config/suffix.hpp new file mode 100644 index 0000000..2d7dcbd --- /dev/null +++ b/thirdparty/boost/config/suffix.hpp @@ -0,0 +1,566 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Bill Kempf 2002. +// (C) Copyright Jens Maurer 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Gennaro Prota 2003. +// (C) Copyright Eric Friedman 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +// +// look for long long by looking for the appropriate macros in . +// Note that we use limits.h rather than climits for maximal portability, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(__BORLANDC__) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS)) && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# ifndef BOOST_HAS_SLIST +# define BOOST_NO_SLIST +# endif + +# ifndef BOOST_HAS_HASH +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# ifdef BOOST_NO_STDC_NAMESPACE +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# ifdef BOOST_NO_STD_MIN_MAX + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analagous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +#else +# define BOOST_UNREACHABLE_RETURN(x) +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +// long long workaround ------------------------------------------// +// On gcc (and maybe other compilers?) long long is alway supported +// but it's use may generate either warnings (with -ansi), or errors +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// +// +// Some compilers have problems with function templates whose +// template parameters don't appear in the function parameter +// list (basically they just link one instantiation of the +// template in the final executable). These macros provide a +// uniform way to cope with the problem with no effects on the +// calling syntax. + +// Example: +// +// #include +// #include +// #include +// +// template +// void f() { std::cout << n << ' '; } +// +// template +// void g() { std::cout << typeid(T).name() << ' '; } +// +// int main() { +// f<1>(); +// f<2>(); +// +// g(); +// g(); +// } +// +// With VC++ 6.0 the output is: +// +// 2 2 double double +// +// To fix it, write +// +// template +// void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... } +// +// template +// void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... } +// + + +#if defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS + +# include "boost/type.hpp" +# include "boost/non_type.hpp" + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) boost::type* = 0 +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type* +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type* = 0 +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type* + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ + , BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ + , BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ + , BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ + , BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +#else + +// no workaround needed: expand to nothing + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + + +#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS + + +// ---------------------------------------------------------------------------// + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) +#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2( X, Y ) X##Y + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +#endif + + diff --git a/thirdparty/boost/config/user.hpp b/thirdparty/boost/config/user.hpp new file mode 100644 index 0000000..3b998d1 --- /dev/null +++ b/thirdparty/boost/config/user.hpp @@ -0,0 +1,124 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be statically linked (Boost.Test for example) and others which may only +// be dynamically linked (Boost.Threads for example), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only be statically linked +// (Boost.Test for example) and others which may only be dynamically linked +// (Boost.Threads for example), in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + + + diff --git a/thirdparty/boost/crc.hpp b/thirdparty/boost/crc.hpp new file mode 100644 index 0000000..5824812 --- /dev/null +++ b/thirdparty/boost/crc.hpp @@ -0,0 +1,1106 @@ +// Boost CRC library crc.hpp header file -----------------------------------// + +// Copyright 2001, 2004 Daryle Walker. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_CRC_HPP +#define BOOST_CRC_HPP + +#include // for BOOST_STATIC_CONSTANT, etc. +#include // for boost::uint_t + +#include // for CHAR_BIT, etc. +#include // for std::size_t + +#include // for std::numeric_limits + + +// The type of CRC parameters that can go in a template should be related +// on the CRC's bit count. This macro expresses that type in a compact +// form, but also allows an alternate type for compilers that don't support +// dependent types (in template value-parameters). +#if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || (defined(BOOST_MSVC) && (BOOST_MSVC <= 1300))) +#define BOOST_CRC_PARM_TYPE typename ::boost::uint_t::fast +#else +#define BOOST_CRC_PARM_TYPE unsigned long +#endif + +// Some compilers [MS VC++ 6] cannot correctly set up several versions of a +// function template unless every template argument can be unambiguously +// deduced from the function arguments. (The bug is hidden if only one version +// is needed.) Since all of the CRC function templates have this problem, the +// workaround is to make up a dummy function argument that encodes the template +// arguments. Calls to such template functions need all their template +// arguments explicitly specified. At least one compiler that needs this +// workaround also needs the default value for the dummy argument to be +// specified in the definition. +#if defined(__GNUC__) || !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) +#define BOOST_CRC_DUMMY_PARM_TYPE +#define BOOST_CRC_DUMMY_INIT +#define BOOST_ACRC_DUMMY_PARM_TYPE +#define BOOST_ACRC_DUMMY_INIT +#else +namespace boost { namespace detail { + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > + struct dummy_crc_argument { }; +} } +#define BOOST_CRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument *p_ +#define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0 +#define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument *p_ +#define BOOST_ACRC_DUMMY_INIT BOOST_ACRC_DUMMY_PARM_TYPE = 0 +#endif + + +namespace boost +{ + + +// Forward declarations ----------------------------------------------------// + +template < std::size_t Bits > + class crc_basic; + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u, + BOOST_CRC_PARM_TYPE InitRem = 0u, + BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false, + bool ReflectRem = false > + class crc_optimal; + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > + typename uint_t::fast crc( void const *buffer, + std::size_t byte_count + BOOST_CRC_DUMMY_PARM_TYPE ); + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > + typename uint_t::fast augmented_crc( void const *buffer, + std::size_t byte_count, typename uint_t::fast initial_remainder + BOOST_ACRC_DUMMY_PARM_TYPE ); + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > + typename uint_t::fast augmented_crc( void const *buffer, + std::size_t byte_count + BOOST_ACRC_DUMMY_PARM_TYPE ); + +typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type; +typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_type; +typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type; + +typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> + crc_32_type; + + +// Forward declarations for implementation detail stuff --------------------// +// (Just for the stuff that will be needed for the next two sections) + +namespace detail +{ + template < std::size_t Bits > + struct mask_uint_t; + + template < > + struct mask_uint_t< std::numeric_limits::digits >; + + #if USHRT_MAX > UCHAR_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits >; + #endif + + #if UINT_MAX > USHRT_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits >; + #endif + + #if ULONG_MAX > UINT_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits >; + #endif + + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > + struct crc_table_t; + + template < std::size_t Bits, bool DoReflect > + class crc_helper; + + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template < std::size_t Bits > + class crc_helper< Bits, false >; + #endif + +} // namespace detail + + +// Simple cyclic redundancy code (CRC) class declaration -------------------// + +template < std::size_t Bits > +class crc_basic +{ + // Implementation type + typedef detail::mask_uint_t masking_type; + +public: + // Type + typedef typename masking_type::least value_type; + + // Constant for the template parameter + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); + + // Constructor + explicit crc_basic( value_type truncated_polynominal, + value_type initial_remainder = 0, value_type final_xor_value = 0, + bool reflect_input = false, bool reflect_remainder = false ); + + // Internal Operations + value_type get_truncated_polynominal() const; + value_type get_initial_remainder() const; + value_type get_final_xor_value() const; + bool get_reflect_input() const; + bool get_reflect_remainder() const; + + value_type get_interim_remainder() const; + void reset( value_type new_rem ); + void reset(); + + // External Operations + void process_bit( bool bit ); + void process_bits( unsigned char bits, std::size_t bit_count ); + void process_byte( unsigned char byte ); + void process_block( void const *bytes_begin, void const *bytes_end ); + void process_bytes( void const *buffer, std::size_t byte_count ); + + value_type checksum() const; + +private: + // Member data + value_type rem_; + value_type poly_, init_, final_; // non-const to allow assignability + bool rft_in_, rft_out_; // non-const to allow assignability + +}; // boost::crc_basic + + +// Optimized cyclic redundancy code (CRC) class declaration ----------------// + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +class crc_optimal +{ + // Implementation type + typedef detail::mask_uint_t masking_type; + +public: + // Type + typedef typename masking_type::fast value_type; + + // Constants for the template parameters + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); + BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly ); + BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem ); + BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor ); + BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn ); + BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem ); + + // Constructor + explicit crc_optimal( value_type init_rem = InitRem ); + + // Internal Operations + value_type get_truncated_polynominal() const; + value_type get_initial_remainder() const; + value_type get_final_xor_value() const; + bool get_reflect_input() const; + bool get_reflect_remainder() const; + + value_type get_interim_remainder() const; + void reset( value_type new_rem = InitRem ); + + // External Operations + void process_byte( unsigned char byte ); + void process_block( void const *bytes_begin, void const *bytes_end ); + void process_bytes( void const *buffer, std::size_t byte_count ); + + value_type checksum() const; + + // Operators + void operator ()( unsigned char byte ); + value_type operator ()() const; + +private: + // The implementation of output reflection depends on both reflect states. + BOOST_STATIC_CONSTANT( bool, reflect_output = (ReflectRem != ReflectIn) ); + + #ifndef __BORLANDC__ + #define BOOST_CRC_REF_OUT_VAL reflect_output + #else + typedef crc_optimal self_type; + #define BOOST_CRC_REF_OUT_VAL (self_type::reflect_output) + #endif + + // More implementation types + typedef detail::crc_table_t crc_table_type; + typedef detail::crc_helper helper_type; + typedef detail::crc_helper reflect_out_type; + + #undef BOOST_CRC_REF_OUT_VAL + + // Member data + value_type rem_; + +}; // boost::crc_optimal + + +// Implementation detail stuff ---------------------------------------------// + +namespace detail +{ + // Forward declarations for more implementation details + template < std::size_t Bits > + struct high_uint_t; + + template < std::size_t Bits > + struct reflector; + + + // Traits class for mask; given the bit number + // (1-based), get the mask for that bit by itself. + template < std::size_t Bits > + struct high_uint_t + : boost::uint_t< Bits > + { + typedef boost::uint_t base_type; + typedef typename base_type::least least; + typedef typename base_type::fast fast; + +#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 + static const least high_bit = 1ul << ( Bits - 1u ); + static const fast high_bit_fast = 1ul << ( Bits - 1u ); +#else + BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << ( Bits + - 1u )) ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << ( Bits + - 1u )) ); +#endif + + }; // boost::detail::high_uint_t + + + // Reflection routine class wrapper + // (since MS VC++ 6 couldn't handle the unwrapped version) + template < std::size_t Bits > + struct reflector + { + typedef typename boost::uint_t::fast value_type; + + static value_type reflect( value_type x ); + + }; // boost::detail::reflector + + // Function that reflects its argument + template < std::size_t Bits > + typename reflector::value_type + reflector::reflect + ( + typename reflector::value_type x + ) + { + value_type reflection = 0; + value_type const one = 1; + + for ( std::size_t i = 0 ; i < Bits ; ++i, x >>= 1 ) + { + if ( x & one ) + { + reflection |= ( one << (Bits - 1u - i) ); + } + } + + return reflection; + } + + + // Traits class for masks; given the bit number (1-based), + // get the mask for that bit and its lower bits. + template < std::size_t Bits > + struct mask_uint_t + : high_uint_t< Bits > + { + typedef high_uint_t base_type; + typedef typename base_type::least least; + typedef typename base_type::fast fast; + + #ifndef __BORLANDC__ + using base_type::high_bit; + using base_type::high_bit_fast; + #else + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); + #endif + +#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 + static const least sig_bits = (~( ~( 0ul ) << Bits )) ; +#else + BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) ); +#endif +#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 + // Work around a weird bug that ICEs the compiler in build_c_cast + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = static_cast(sig_bits) ); +#else + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); +#endif + }; // boost::detail::mask_uint_t + + template < > + struct mask_uint_t< std::numeric_limits::digits > + : high_uint_t< std::numeric_limits::digits > + { + typedef high_uint_t::digits> + base_type; + typedef base_type::least least; + typedef base_type::fast fast; + + #ifndef __BORLANDC__ + using base_type::high_bit; + using base_type::high_bit_fast; + #else + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); + #endif + + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); + + }; // boost::detail::mask_uint_t + + #if USHRT_MAX > UCHAR_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits > + : high_uint_t< std::numeric_limits::digits > + { + typedef high_uint_t::digits> + base_type; + typedef base_type::least least; + typedef base_type::fast fast; + + #ifndef __BORLANDC__ + using base_type::high_bit; + using base_type::high_bit_fast; + #else + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); + #endif + + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); + + }; // boost::detail::mask_uint_t + #endif + + #if UINT_MAX > USHRT_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits > + : high_uint_t< std::numeric_limits::digits > + { + typedef high_uint_t::digits> + base_type; + typedef base_type::least least; + typedef base_type::fast fast; + + #ifndef __BORLANDC__ + using base_type::high_bit; + using base_type::high_bit_fast; + #else + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); + #endif + + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); + + }; // boost::detail::mask_uint_t + #endif + + #if ULONG_MAX > UINT_MAX + template < > + struct mask_uint_t< std::numeric_limits::digits > + : high_uint_t< std::numeric_limits::digits > + { + typedef high_uint_t::digits> + base_type; + typedef base_type::least least; + typedef base_type::fast fast; + + #ifndef __BORLANDC__ + using base_type::high_bit; + using base_type::high_bit_fast; + #else + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); + #endif + + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); + + }; // boost::detail::mask_uint_t + #endif + + + // CRC table generator + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > + struct crc_table_t + { + BOOST_STATIC_CONSTANT( std::size_t, byte_combos = (1ul << CHAR_BIT) ); + + typedef mask_uint_t masking_type; + typedef typename masking_type::fast value_type; +#if defined(__BORLANDC__) && defined(_M_IX86) && (__BORLANDC__ == 0x560) + // for some reason Borland's command line compiler (version 0x560) + // chokes over this unless we do the calculation for it: + typedef value_type table_type[ 0x100 ]; +#else + typedef value_type table_type[ byte_combos ]; +#endif + + static void init_table(); + + static table_type table_; + + }; // boost::detail::crc_table_t + + // CRC table generator static data member definition + // (Some compilers [Borland C++] require the initializer to be present.) + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > + typename crc_table_t::table_type + crc_table_t::table_ + = { 0 }; + + // Populate CRC lookup table + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > + void + crc_table_t::init_table + ( + ) + { + // compute table only on the first run + static bool did_init = false; + if ( did_init ) return; + + // factor-out constants to avoid recalculation + value_type const fast_hi_bit = masking_type::high_bit_fast; + unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u); + + // loop over every possible dividend value + unsigned char dividend = 0; + do + { + value_type remainder = 0; + + // go through all the dividend's bits + for ( unsigned char mask = byte_hi_bit ; mask ; mask >>= 1 ) + { + // check if divisor fits + if ( dividend & mask ) + { + remainder ^= fast_hi_bit; + } + + // do polynominal division + if ( remainder & fast_hi_bit ) + { + remainder <<= 1; + remainder ^= TruncPoly; + } + else + { + remainder <<= 1; + } + } + + table_[ crc_helper::reflect(dividend) ] + = crc_helper::reflect( remainder ); + } + while ( ++dividend ); + + did_init = true; + } + + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Align the msb of the remainder to a byte + template < std::size_t Bits, bool RightShift > + class remainder + { + public: + typedef typename uint_t::fast value_type; + + static unsigned char align_msb( value_type rem ) + { return rem >> (Bits - CHAR_BIT); } + }; + + // Specialization for the case that the remainder has less + // bits than a byte: align the remainder msb to the byte msb + template < std::size_t Bits > + class remainder< Bits, false > + { + public: + typedef typename uint_t::fast value_type; + + static unsigned char align_msb( value_type rem ) + { return rem << (CHAR_BIT - Bits); } + }; + #endif + + // CRC helper routines + template < std::size_t Bits, bool DoReflect > + class crc_helper + { + public: + // Type + typedef typename uint_t::fast value_type; + + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Possibly reflect a remainder + static value_type reflect( value_type x ) + { return detail::reflector::reflect( x ); } + + // Compare a byte to the remainder's highest byte + static unsigned char index( value_type rem, unsigned char x ) + { return x ^ rem; } + + // Shift out the remainder's highest byte + static value_type shift( value_type rem ) + { return rem >> CHAR_BIT; } + #else + // Possibly reflect a remainder + static value_type reflect( value_type x ) + { return DoReflect ? detail::reflector::reflect( x ) : x; } + + // Compare a byte to the remainder's highest byte + static unsigned char index( value_type rem, unsigned char x ) + { return x ^ ( DoReflect ? rem : + ((Bits>CHAR_BIT)?( rem >> (Bits - CHAR_BIT) ) : + ( rem << (CHAR_BIT - Bits) ))); } + + // Shift out the remainder's highest byte + static value_type shift( value_type rem ) + { return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT; } + #endif + + }; // boost::detail::crc_helper + + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template < std::size_t Bits > + class crc_helper + { + public: + // Type + typedef typename uint_t::fast value_type; + + // Possibly reflect a remainder + static value_type reflect( value_type x ) + { return x; } + + // Compare a byte to the remainder's highest byte + static unsigned char index( value_type rem, unsigned char x ) + { return x ^ remainderCHAR_BIT)>::align_msb( rem ); } + + // Shift out the remainder's highest byte + static value_type shift( value_type rem ) + { return rem << CHAR_BIT; } + + }; // boost::detail::crc_helper + #endif + + +} // namespace detail + + +// Simple CRC class function definitions -----------------------------------// + +template < std::size_t Bits > +inline +crc_basic::crc_basic +( + typename crc_basic::value_type truncated_polynominal, + typename crc_basic::value_type initial_remainder, // = 0 + typename crc_basic::value_type final_xor_value, // = 0 + bool reflect_input, // = false + bool reflect_remainder // = false +) + : rem_( initial_remainder ), poly_( truncated_polynominal ) + , init_( initial_remainder ), final_( final_xor_value ) + , rft_in_( reflect_input ), rft_out_( reflect_remainder ) +{ +} + +template < std::size_t Bits > +inline +typename crc_basic::value_type +crc_basic::get_truncated_polynominal +( +) const +{ + return poly_; +} + +template < std::size_t Bits > +inline +typename crc_basic::value_type +crc_basic::get_initial_remainder +( +) const +{ + return init_; +} + +template < std::size_t Bits > +inline +typename crc_basic::value_type +crc_basic::get_final_xor_value +( +) const +{ + return final_; +} + +template < std::size_t Bits > +inline +bool +crc_basic::get_reflect_input +( +) const +{ + return rft_in_; +} + +template < std::size_t Bits > +inline +bool +crc_basic::get_reflect_remainder +( +) const +{ + return rft_out_; +} + +template < std::size_t Bits > +inline +typename crc_basic::value_type +crc_basic::get_interim_remainder +( +) const +{ + return rem_ & masking_type::sig_bits; +} + +template < std::size_t Bits > +inline +void +crc_basic::reset +( + typename crc_basic::value_type new_rem +) +{ + rem_ = new_rem; +} + +template < std::size_t Bits > +inline +void +crc_basic::reset +( +) +{ + this->reset( this->get_initial_remainder() ); +} + +template < std::size_t Bits > +inline +void +crc_basic::process_bit +( + bool bit +) +{ + value_type const high_bit_mask = masking_type::high_bit; + + // compare the new bit with the remainder's highest + rem_ ^= ( bit ? high_bit_mask : 0u ); + + // a full polynominal division step is done when the highest bit is one + bool const do_poly_div = static_cast( rem_ & high_bit_mask ); + + // shift out the highest bit + rem_ <<= 1; + + // carry out the division, if needed + if ( do_poly_div ) + { + rem_ ^= poly_; + } +} + +template < std::size_t Bits > +void +crc_basic::process_bits +( + unsigned char bits, + std::size_t bit_count +) +{ + // ignore the bits above the ones we want + bits <<= CHAR_BIT - bit_count; + + // compute the CRC for each bit, starting with the upper ones + unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u ); + for ( std::size_t i = bit_count ; i > 0u ; --i, bits <<= 1u ) + { + process_bit( static_cast(bits & high_bit_mask) ); + } +} + +template < std::size_t Bits > +inline +void +crc_basic::process_byte +( + unsigned char byte +) +{ + process_bits( (rft_in_ ? detail::reflector::reflect(byte) + : byte), CHAR_BIT ); +} + +template < std::size_t Bits > +void +crc_basic::process_block +( + void const * bytes_begin, + void const * bytes_end +) +{ + for ( unsigned char const * p + = static_cast(bytes_begin) ; p < bytes_end ; ++p ) + { + process_byte( *p ); + } +} + +template < std::size_t Bits > +inline +void +crc_basic::process_bytes +( + void const * buffer, + std::size_t byte_count +) +{ + unsigned char const * const b = static_cast( + buffer ); + + process_block( b, b + byte_count ); +} + +template < std::size_t Bits > +inline +typename crc_basic::value_type +crc_basic::checksum +( +) const +{ + return ( (rft_out_ ? detail::reflector::reflect( rem_ ) : rem_) + ^ final_ ) & masking_type::sig_bits; +} + + +// Optimized CRC class function definitions --------------------------------// + +// Macro to compact code +#define BOOST_CRC_OPTIMAL_NAME crc_optimal + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +BOOST_CRC_OPTIMAL_NAME::crc_optimal +( + typename BOOST_CRC_OPTIMAL_NAME::value_type init_rem // = InitRem +) + : rem_( helper_type::reflect(init_rem) ) +{ + crc_table_type::init_table(); +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal +( +) const +{ + return TruncPoly; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::get_initial_remainder +( +) const +{ + return InitRem; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::get_final_xor_value +( +) const +{ + return FinalXor; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +bool +BOOST_CRC_OPTIMAL_NAME::get_reflect_input +( +) const +{ + return ReflectIn; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +bool +BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder +( +) const +{ + return ReflectRem; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::get_interim_remainder +( +) const +{ + // Interim remainder should be _un_-reflected, so we have to undo it. + return helper_type::reflect( rem_ ) & masking_type::sig_bits_fast; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +void +BOOST_CRC_OPTIMAL_NAME::reset +( + typename BOOST_CRC_OPTIMAL_NAME::value_type new_rem // = InitRem +) +{ + rem_ = helper_type::reflect( new_rem ); +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +void +BOOST_CRC_OPTIMAL_NAME::process_byte +( + unsigned char byte +) +{ + process_bytes( &byte, sizeof(byte) ); +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +void +BOOST_CRC_OPTIMAL_NAME::process_block +( + void const * bytes_begin, + void const * bytes_end +) +{ + // Recompute the CRC for each byte passed + for ( unsigned char const * p + = static_cast(bytes_begin) ; p < bytes_end ; ++p ) + { + // Compare the new byte with the remainder's higher bits to + // get the new bits, shift out the remainder's current higher + // bits, and update the remainder with the polynominal division + // of the new bits. + unsigned char const byte_index = helper_type::index( rem_, *p ); + rem_ = helper_type::shift( rem_ ); + rem_ ^= crc_table_type::table_[ byte_index ]; + } +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +void +BOOST_CRC_OPTIMAL_NAME::process_bytes +( + void const * buffer, + std::size_t byte_count +) +{ + unsigned char const * const b = static_cast( + buffer ); + process_block( b, b + byte_count ); +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::checksum +( +) const +{ + return ( reflect_out_type::reflect(rem_) ^ get_final_xor_value() ) + & masking_type::sig_bits_fast; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +void +BOOST_CRC_OPTIMAL_NAME::operator () +( + unsigned char byte +) +{ + process_byte( byte ); +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename BOOST_CRC_OPTIMAL_NAME::value_type +BOOST_CRC_OPTIMAL_NAME::operator () +( +) const +{ + return checksum(); +} + + +// CRC computation function definition -------------------------------------// + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, + bool ReflectIn, bool ReflectRem > +inline +typename uint_t::fast +crc +( + void const * buffer, + std::size_t byte_count + BOOST_CRC_DUMMY_INIT +) +{ + BOOST_CRC_OPTIMAL_NAME computer; + computer.process_bytes( buffer, byte_count ); + return computer.checksum(); +} + + +// Augmented-message CRC computation function definitions ------------------// + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > +typename uint_t::fast +augmented_crc +( + void const * buffer, + std::size_t byte_count, + typename uint_t::fast initial_remainder + BOOST_ACRC_DUMMY_INIT +) +{ + typedef unsigned char byte_type; + typedef detail::mask_uint_t masking_type; + typedef detail::crc_table_t crc_table_type; + + typename masking_type::fast rem = initial_remainder; + byte_type const * const b = static_cast( buffer ); + byte_type const * const e = b + byte_count; + + crc_table_type::init_table(); + for ( byte_type const * p = b ; p < e ; ++p ) + { + // Use the current top byte as the table index to the next + // "partial product." Shift out that top byte, shifting in + // the next augmented-message byte. Complete the division. + byte_type const byte_index = rem >> ( Bits - CHAR_BIT ); + rem <<= CHAR_BIT; + rem |= *p; + rem ^= crc_table_type::table_[ byte_index ]; + } + + return rem & masking_type::sig_bits_fast; +} + +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > +inline +typename uint_t::fast +augmented_crc +( + void const * buffer, + std::size_t byte_count + BOOST_ACRC_DUMMY_INIT +) +{ + // The last function argument has its type specified so the other version of + // augmented_crc will be called. If the cast wasn't in place, and the + // BOOST_ACRC_DUMMY_INIT added a third argument (for a workaround), the "0" + // would match as that third argument, leading to infinite recursion. + return augmented_crc( buffer, byte_count, + static_cast::fast>(0) ); +} + + +} // namespace boost + + +// Undo header-private macros +#undef BOOST_CRC_OPTIMAL_NAME +#undef BOOST_ACRC_DUMMY_INIT +#undef BOOST_ACRC_DUMMY_PARM_TYPE +#undef BOOST_CRC_DUMMY_INIT +#undef BOOST_CRC_DUMMY_PARM_TYPE +#undef BOOST_CRC_PARM_TYPE + + +#endif // BOOST_CRC_HPP + diff --git a/thirdparty/boost/cregex.hpp b/thirdparty/boost/cregex.hpp new file mode 100644 index 0000000..81d0343 --- /dev/null +++ b/thirdparty/boost/cregex.hpp @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org/libs/regex for most recent version. + * FILE cregex.cpp + * VERSION see + * DESCRIPTION: Declares POSIX API functions + * + boost::RegEx high level wrapper. + */ + +#ifndef BOOST_RE_CREGEX_HPP +#define BOOST_RE_CREGEX_HPP + +#ifndef BOOST_REGEX_CONFIG_HPP +#include +#endif + +#include + +#endif /* include guard */ + + + + + + + + + + diff --git a/thirdparty/boost/cstdint.hpp b/thirdparty/boost/cstdint.hpp new file mode 100644 index 0000000..b3bb269 --- /dev/null +++ b/thirdparty/boost/cstdint.hpp @@ -0,0 +1,446 @@ +// boost cstdint.hpp header file ------------------------------------------// + +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 2001 +// Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) +// 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) +// 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) +// 12 Nov 00 Merged (Jens Maurer) +// 23 Sep 00 Added INTXX_C macro support (John Maddock). +// 22 Sep 00 Better 64-bit support (John Maddock) +// 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost +// 8 Aug 99 Initial version (Beman Dawes) + + +#ifndef BOOST_CSTDINT_HPP +#define BOOST_CSTDINT_HPP + +#include + + +#ifdef BOOST_HAS_STDINT_H + +// The following #include is an implementation artifact; not part of interface. +# ifdef __hpux +// HP-UX has a vaguely nice in a non-standard location +# include +# ifdef __STDC_32_MODE__ + // this is triggered with GCC, because it defines __cplusplus < 199707L +# define BOOST_NO_INT64_T +# endif +# elif defined(__FreeBSD__) || defined(__IBMCPP__) +# include +# else +# include + +// There is a bug in Cygwin two _C macros +# if defined(__STDC_CONSTANT_MACROS) && defined(__CYGWIN__) +# undef INTMAX_C +# undef UINTMAX_C +# define INTMAX_C(c) c##LL +# define UINTMAX_C(c) c##ULL +# endif + +# endif + +#ifdef __QNX__ + +// QNX (Dinkumware stdlib) defines these as non-standard names. +// Reflect to the standard names. + +typedef ::intleast8_t int_least8_t; +typedef ::intfast8_t int_fast8_t; +typedef ::uintleast8_t uint_least8_t; +typedef ::uintfast8_t uint_fast8_t; + +typedef ::intleast16_t int_least16_t; +typedef ::intfast16_t int_fast16_t; +typedef ::uintleast16_t uint_least16_t; +typedef ::uintfast16_t uint_fast16_t; + +typedef ::intleast32_t int_least32_t; +typedef ::intfast32_t int_fast32_t; +typedef ::uintleast32_t uint_least32_t; +typedef ::uintfast32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + +typedef ::intleast64_t int_least64_t; +typedef ::intfast64_t int_fast64_t; +typedef ::uintleast64_t uint_least64_t; +typedef ::uintfast64_t uint_fast64_t; + +# endif + +#endif + +namespace boost +{ + + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + +# endif + + using ::intmax_t; + using ::uintmax_t; + +} // namespace boost + +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) +// FreeBSD and Tru64 have an that contains much of what we need. +# include + +namespace boost { + + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; + + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; + + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; + +# else + + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; + +# endif + +} // namespace boost + +#else // BOOST_HAS_STDINT_H + +# include // implementation artifact; not part of interface +# include // needed for limits macros + + +namespace boost +{ + +// These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit +// platforms. For other systems, they will have to be hand tailored. +// +// Because the fast types are assumed to be the same as the undecorated types, +// it may be possible to hand tailor a more efficient implementation. Such +// an optimization may be illusionary; on the Intel x86-family 386 on, for +// example, byte arithmetic and load/stores are as fast as "int" sized ones. + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff + typedef signed char int8_t; + typedef signed char int_least8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint8_t; + typedef unsigned char uint_least8_t; + typedef unsigned char uint_fast8_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# if defined(__crayx1) + // The Cray X1 has a 16-bit short, however it is not recommend + // for use in performance critical code. + typedef short int16_t; + typedef short int_least16_t; + typedef int int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned int uint_fast16_t; +# else + typedef short int16_t; + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# endif +# elif (USHRT_MAX == 0xffffffff) && defined(CRAY) + // no 16-bit types on Cray: + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 32-bit types -----------------------------------------------------------// + +# if ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; +# elif UINT_MAX == 0xffffffff + typedef int int32_t; + typedef int int_least32_t; + typedef int int_fast32_t; + typedef unsigned int uint32_t; + typedef unsigned int uint_least32_t; + typedef unsigned int uint_fast32_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + !defined(BOOST_MSVC) && !defined(__BORLANDC__) && \ + (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) + // 2**64 - 1 +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + + typedef ::boost::long_long_type intmax_t; + typedef ::boost::ulong_long_type uintmax_t; + typedef ::boost::long_long_type int64_t; + typedef ::boost::long_long_type int_least64_t; + typedef ::boost::long_long_type int_fast64_t; + typedef ::boost::ulong_long_type uint64_t; + typedef ::boost::ulong_long_type uint_least64_t; + typedef ::boost::ulong_long_type uint_fast64_t; + +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 + typedef long intmax_t; + typedef unsigned long uintmax_t; + typedef long int64_t; + typedef long int_least64_t; + typedef long int_fast64_t; + typedef unsigned long uint64_t; + typedef unsigned long uint_least64_t; + typedef unsigned long uint_fast64_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) + __extension__ typedef long long intmax_t; + __extension__ typedef unsigned long long uintmax_t; + __extension__ typedef long long int64_t; + __extension__ typedef long long int_least64_t; + __extension__ typedef long long int_fast64_t; + __extension__ typedef unsigned long long uint64_t; + __extension__ typedef unsigned long long uint_least64_t; + __extension__ typedef unsigned long long uint_fast64_t; +# elif defined(BOOST_HAS_MS_INT64) + // + // we have Borland/Intel/Microsoft __int64: + // + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; + typedef __int64 int64_t; + typedef __int64 int_least64_t; + typedef __int64 int_fast64_t; + typedef unsigned __int64 uint64_t; + typedef unsigned __int64 uint_least64_t; + typedef unsigned __int64 uint_fast64_t; +# else // assume no 64-bit integers +# define BOOST_NO_INT64_T + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# endif + +} // namespace boost + + +#endif // BOOST_HAS_STDINT_H + +#endif // BOOST_CSTDINT_HPP + + +/**************************************************** + +Macro definition section: + +Define various INTXX_C macros only if +__STDC_CONSTANT_MACROS is defined. + +Undefine the macros if __STDC_CONSTANT_MACROS is +not defined and the macros are (cf ). + +Added 23rd September 2000 (John Maddock). +Modified 11th September 2001 to be excluded when +BOOST_HAS_STDINT_H is defined (John Maddock). + +******************************************************/ + +#if defined(__STDC_CONSTANT_MACROS) && !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && !defined(BOOST_HAS_STDINT_H) +# define BOOST__STDC_CONSTANT_MACROS_DEFINED +# if defined(BOOST_HAS_MS_INT64) +// +// Borland/Intel/Microsoft compilers have width specific suffixes: +// +# define INT8_C(value) value##i8 +# define INT16_C(value) value##i16 +# define INT32_C(value) value##i32 +# define INT64_C(value) value##i64 +# ifdef __BORLANDC__ + // Borland bug: appending ui8 makes the type a signed char +# define UINT8_C(value) static_cast(value##u) +# else +# define UINT8_C(value) value##ui8 +# endif +# define UINT16_C(value) value##ui16 +# define UINT32_C(value) value##ui32 +# define UINT64_C(value) value##ui64 +# define INTMAX_C(value) value##i64 +# define UINTMAX_C(value) value##ui64 + +# else +// do it the old fashioned way: + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff +# define INT8_C(value) static_cast(value) +# define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# define INT16_C(value) static_cast(value) +# define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types -----------------------------------------------------------// + +# if UINT_MAX == 0xffffffff +# define INT32_C(value) value +# define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +# define INT32_C(value) value##L +# define UINT32_C(value) value##uL +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) + +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615U) || \ + (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615U) || \ + (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615U) + +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 +# define INT64_C(value) value##L +# define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# endif + +# ifdef BOOST_NO_INT64_T +# define INTMAX_C(value) INT32_C(value) +# define UINTMAX_C(value) UINT32_C(value) +# else +# define INTMAX_C(value) INT64_C(value) +# define UINTMAX_C(value) UINT64_C(value) +# endif + +# endif // Borland/Microsoft specific width suffixes + + +#elif defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && !defined(__STDC_CONSTANT_MACROS) && !defined(BOOST_HAS_STDINT_H) +// +// undef all the macros: +// +# undef INT8_C +# undef INT16_C +# undef INT32_C +# undef INT64_C +# undef UINT8_C +# undef UINT16_C +# undef UINT32_C +# undef UINT64_C +# undef INTMAX_C +# undef UINTMAX_C + +#endif // __STDC_CONSTANT_MACROS_DEFINED etc. + + + + diff --git a/thirdparty/boost/cstdlib.hpp b/thirdparty/boost/cstdlib.hpp new file mode 100644 index 0000000..9f43030 --- /dev/null +++ b/thirdparty/boost/cstdlib.hpp @@ -0,0 +1,41 @@ +// boost/cstdlib.hpp header ------------------------------------------------// + +// Copyright Beman Dawes 2001. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/utility/cstdlib.html for documentation. + +// Revision History +// 26 Feb 01 Initial version (Beman Dawes) + +#ifndef BOOST_CSTDLIB_HPP +#define BOOST_CSTDLIB_HPP + +#include + +namespace boost +{ + // The intent is to propose the following for addition to namespace std + // in the C++ Standard Library, and to then deprecate EXIT_SUCCESS and + // EXIT_FAILURE. As an implementation detail, this header defines the + // new constants in terms of EXIT_SUCCESS and EXIT_FAILURE. In a new + // standard, the constants would be implementation-defined, although it + // might be worthwhile to "suggest" (which a standard is allowed to do) + // values of 0 and 1 respectively. + + // Rationale for having multiple failure values: some environments may + // wish to distinguish between different classes of errors. + // Rationale for choice of values: programs often use values < 100 for + // their own error reporting. Values > 255 are sometimes reserved for + // system detected errors. 200/201 were suggested to minimize conflict. + + const int exit_success = EXIT_SUCCESS; // implementation-defined value + const int exit_failure = EXIT_FAILURE; // implementation-defined value + const int exit_exception_failure = 200; // otherwise uncaught exception + const int exit_test_failure = 201; // report_error or + // report_critical_error called. +} + +#endif + diff --git a/thirdparty/boost/current_function.hpp b/thirdparty/boost/current_function.hpp new file mode 100644 index 0000000..3714e9e --- /dev/null +++ b/thirdparty/boost/current_function.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/utility/current_function.html +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/thirdparty/boost/date_time.hpp b/thirdparty/boost/date_time.hpp new file mode 100644 index 0000000..6cb1ec3 --- /dev/null +++ b/thirdparty/boost/date_time.hpp @@ -0,0 +1,17 @@ +#ifndef BOOST_DATE_TIME_ALL_HPP___ +#define BOOST_DATE_TIME_ALL_HPP___ + +/* Copyright (c) 2006 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + // See www.boost.org/libs/date_time for documentation. + +//gregorian and posix time included by indirectly +#include "boost/date_time/local_time/local_time.hpp" + +#endif // BOOST_DATE_TIME_ALL_HPP___ diff --git a/thirdparty/boost/date_time/adjust_functors.hpp b/thirdparty/boost/date_time/adjust_functors.hpp new file mode 100644 index 0000000..960c831 --- /dev/null +++ b/thirdparty/boost/date_time/adjust_functors.hpp @@ -0,0 +1,178 @@ +#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___ +#define _DATE_TIME_ADJUST_FUNCTORS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/wrapping_int.hpp" + +namespace boost { +namespace date_time { + + + //! Functor to iterate a fixed number of days + template + class day_functor + { + public: + typedef typename date_type::duration_type duration_type; + day_functor(int f) : f_(f) {} + duration_type get_offset(const date_type& d) const + { + // why is 'd' a parameter??? + // fix compiler warnings + d.year(); + return duration_type(f_); + } + duration_type get_neg_offset(const date_type& d) const + { + // fix compiler warnings + d.year(); + return duration_type(-f_); + } + private: + int f_; + }; + + + //! Provides calculation to find next nth month given a date + /*! This adjustment function provides the logic for 'month-based' + * advancement on a ymd based calendar. The policy it uses + * to handle the non existant end of month days is to back + * up to the last day of the month. Also, if the starting + * date is the last day of a month, this functor will attempt + * to adjust to the end of the month. + + */ + template + class month_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type cal_type; + typedef typename cal_type::ymd_type ymd_type; + typedef typename cal_type::day_type day_type; + + month_functor(int f) : f_(f), origDayOfMonth_(0) {} + duration_type get_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + typedef typename wrap_int2::int_type int_type; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + int_type year = wi.add(static_cast(f_)); + year = static_cast(year + ymd.year); //calculate resulting year +// std::cout << "trace wi: " << wi.as_int() << std::endl; +// std::cout << "trace year: " << year << std::endl; + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + //! Returns a negative duration_type + duration_type get_neg_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + typedef typename wrap_int2::int_type int_type; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + int_type year = wi.subtract(static_cast(f_)); + year = static_cast(year + ymd.year); //calculate resulting year + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + private: + int f_; + mutable short origDayOfMonth_; + }; + + + //! Functor to iterate a over weeks + template + class week_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type calendar_type; + week_functor(int f) : f_(f) {} + duration_type get_offset(const date_type& d) const + { + // why is 'd' a parameter??? + // fix compiler warnings + d.year(); + return duration_type(f_*calendar_type::days_in_week()); + } + duration_type get_neg_offset(const date_type& d) const + { + // fix compiler warnings + d.year(); + return duration_type(-f_*calendar_type::days_in_week()); + } + private: + int f_; + }; + + //! Functor to iterate by a year adjusting for leap years + template + class year_functor + { + public: + //typedef typename date_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + year_functor(int f) : _mf(f * 12) {} + duration_type get_offset(const date_type& d) const + { + return _mf.get_offset(d); + } + duration_type get_neg_offset(const date_type& d) const + { + return _mf.get_neg_offset(d); + } + private: + month_functor _mf; + }; + + +} }//namespace date_time + + +#endif + diff --git a/thirdparty/boost/date_time/c_local_time_adjustor.hpp b/thirdparty/boost/date_time/c_local_time_adjustor.hpp new file mode 100644 index 0000000..093a56d --- /dev/null +++ b/thirdparty/boost/date_time/c_local_time_adjustor.hpp @@ -0,0 +1,64 @@ +#ifndef DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__ +#define DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file c_local_time_adjustor.hpp + Time adjustment calculations based on machine +*/ + +#include +#include "boost/date_time/c_time.hpp" + +namespace boost { +namespace date_time { + + //! Adjust to / from utc using the C API + /*! Warning!!! This class assumes that timezone settings of the + * machine are correct. This can be a very dangerous assumption. + */ + template + class c_local_adjustor { + public: + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_type::date_type date_type; + typedef typename date_type::duration_type date_duration_type; + //! Convert a utc time to local time + static time_type utc_to_local(const time_type& t) + { + date_type time_t_start_day(1970,1,1); + time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0)); + if (t < time_t_start_time) { + throw std::out_of_range("Cannot convert dates prior to Jan 1, 1970"); + } + date_duration_type dd = t.date() - time_t_start_day; + time_duration_type td = t.time_of_day(); + std::time_t t2 = dd.days()*86400 + td.hours()*3600 + td.minutes()*60 + td.seconds(); + std::tm tms, *tms_ptr; + tms_ptr = c_time::localtime(&t2, &tms); + //tms_ptr = std::localtime(&t2); + date_type d(static_cast(tms_ptr->tm_year + 1900), + static_cast(tms_ptr->tm_mon + 1), + static_cast(tms_ptr->tm_mday)); + time_duration_type td2(tms_ptr->tm_hour, + tms_ptr->tm_min, + tms_ptr->tm_sec, + t.time_of_day().fractional_seconds()); + + return time_type(d,td2); + } + }; + + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/c_time.hpp b/thirdparty/boost/date_time/c_time.hpp new file mode 100644 index 0000000..f76c637 --- /dev/null +++ b/thirdparty/boost/date_time/c_time.hpp @@ -0,0 +1,91 @@ +#ifndef DATE_TIME_C_TIME_HPP___ +#define DATE_TIME_C_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +/*! @file c_time.hpp + Provide workarounds related to the ctime header +*/ + +#include "boost/date_time/compiler_config.hpp" +#include +//Work around libraries that don't put time_t and time in namespace std + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::time_t; using ::time; using ::localtime; + using ::tm; using ::gmtime; } +#endif // BOOST_NO_STDC_NAMESPACE + +//The following is used to support high precision time clocks +#ifdef BOOST_HAS_GETTIMEOFDAY +#include +#endif + +#ifdef BOOST_HAS_FTIME +#include +#endif + +namespace boost { +namespace date_time { + //! Provides a uniform interface to some 'ctime' functions + /*! Provides a uniform interface to some ctime functions and + * their '_r' counterparts. The '_r' functions require a pointer to a + * user created std::tm struct whereas the regular functions use a + * staticly created struct and return a pointer to that. These wrapper + * functions require the user to create a std::tm struct and send in a + * pointer to it. A pointer to the user created struct will be returned. */ + struct c_time { + public: +#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS) + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + // localtime_r() not in namespace std??? + result = localtime_r(t, result); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + // gmtime_r() not in namespace std??? + result = gmtime_r(t, result); + return result; + } +#else // BOOST_HAS_THREADS + +#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(push) // preserve warning settings +#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8 +#endif // _MSC_VER >= 1400 + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + result = std::localtime(t); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + result = std::gmtime(t); + return result; + } +#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(pop) // restore warnings to previous state +#endif // _MSC_VER >= 1400 + +#endif // BOOST_HAS_THREADS + }; +}} // namespaces + +#endif // DATE_TIME_C_TIME_HPP___ diff --git a/thirdparty/boost/date_time/compiler_config.hpp b/thirdparty/boost/date_time/compiler_config.hpp new file mode 100644 index 0000000..4fbebba --- /dev/null +++ b/thirdparty/boost/date_time/compiler_config.hpp @@ -0,0 +1,149 @@ +#ifndef DATE_TIME_COMPILER_CONFIG_HPP___ +#define DATE_TIME_COMPILER_CONFIG_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + #include "boost/detail/workaround.hpp" + +// With boost release 1.33, date_time will be using a different, +// more flexible, IO system. This new system is not compatible with +// old compilers. The original date_time IO system remains for those +// compilers. They must define this macro to use the legacy IO. +// (defined(__BORLANDC__) && (__BORLANDC__ <= 0x0581) ) ) && + #if( BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) \ + || BOOST_WORKAROUND( __GNUC__, < 3) \ + || (BOOST_WORKAROUND( _MSC_VER, <= 1300) ) \ + ) \ + && !defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +# define USE_DATE_TIME_PRE_1_33_FACET_IO +#endif + + +// This file performs some local compiler configurations + +#include "boost/date_time/locale_config.hpp" //set up locale configurations + +//Set up a configuration parameter for platforms that have +//GetTimeOfDay +#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME) +#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK +#endif + +// To Force no default constructors for date & ptime, un-comment following +//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR + +// Include extensions to date_duration - comment out to remove this feature +#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +// these extensions are known to cause problems with gcc295 +#if defined(__GNUC__) && (__GNUC__ < 3) +#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +#endif + +#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) ) +#define BOOST_DATE_TIME_NO_MEMBER_INIT +#endif + +// include these types before we try to re-define them +#include "boost/cstdint.hpp" + +//Define INT64_C for compilers that don't have it +#if (!defined(INT64_C)) +#define INT64_C(value) int64_t(value) +#endif + + +/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */ +#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_RW_LIB) +#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR +#endif + + +// Borland v5.64 does not have the following in std namespace; v5.5.1 does +#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT) +#include +namespace std { + using stlport::tolower; + using stlport::ctype; + using stlport::use_facet; +} +#endif + +// workaround for errors associated with output for date classes +// modifications and input streaming for time classes. +// Compilers affected are: +// gcc295, msvc (neither with STLPort), any borland +// +#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \ + (defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \ + !defined(_STLP_OWN_IOSTREAMS) ) || \ + BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) +#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS +#endif + +/* The following handles the definition of the necessary macros + * for dll building on Win32 platforms. + * + * For code that will be placed in the date_time .dll, + * it must be properly prefixed with BOOST_DATE_TIME_DECL. + * The corresponding .cpp file must have BOOST_DATE_TIME_SOURCES + * defined before including its header. For examples see: + * greg_month.hpp & greg_month.cpp + * + */ + +#ifdef BOOST_HAS_DECLSPEC // defined in config system + // we need to import/export our code only if the user has specifically + // asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost + // libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK + // if they want just this one to be dynamically liked: +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) + // export if this is our own source, otherwise import: +# ifdef BOOST_DATE_TIME_SOURCE +# define BOOST_DATE_TIME_DECL __declspec(dllexport) +# else +# define BOOST_DATE_TIME_DECL __declspec(dllimport) +# endif // BOOST_DATE_TIME_SOURCE +# endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_WHATEVER_DECL isn't defined yet define it now: +#ifndef BOOST_DATE_TIME_DECL +# define BOOST_DATE_TIME_DECL +#endif + +// +// Automatically link to the correct build variant where possible. +// +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_date_time +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#if defined(BOOST_HAS_THREADS) +# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__) + //no reentrant posix functions (eg: localtime_r) +# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) +# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS +# endif +#endif + + +#endif diff --git a/thirdparty/boost/date_time/constrained_value.hpp b/thirdparty/boost/date_time/constrained_value.hpp new file mode 100644 index 0000000..c5c3cf8 --- /dev/null +++ b/thirdparty/boost/date_time/constrained_value.hpp @@ -0,0 +1,98 @@ +#ifndef CONSTRAINED_VALUE_HPP___ +#define CONSTRAINED_VALUE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include + +namespace boost { + +//! Namespace containing constrained_value template and types +namespace CV { + //! Represent a min or max violation type + enum violation_enum {min_violation, max_violation}; + + //! A template to specify a constrained basic value type + /*! This template provides a quick way to generate + * an integer type with a constrained range. The type + * provides for the ability to specify the min, max, and + * and error handling policy. + * + * value policies + * A class that provides the range limits via the min and + * max functions as well as a function on_error that + * determines how errors are handled. A common strategy + * would be to assert or throw and exception. The on_error + * is passed both the current value and the new value that + * is in error. + * + */ + template + class constrained_value { + public: + typedef typename value_policies::value_type value_type; + // typedef except_type exception_type; + constrained_value(value_type value) + { + assign(value); + }; + constrained_value& operator=(value_type v) + { + assign(v); + return *this; + } + //! Return the max allowed value (traits method) + static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}; + //! Return the min allowed value (traits method) + static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}; + //! Coerce into the representation type + operator value_type() const {return value_;}; + protected: + value_type value_; + private: + void assign(value_type value) + { + //adding 1 below gets rid of a compiler warning which occurs when the + //min_value is 0 and the type is unsigned.... + if (value+1 < (min)()+1) { + value_policies::on_error(value_, value, min_violation); + return; + } + if (value > (max)()) { + value_policies::on_error(value_, value, max_violation); + return; + } + value_ = value; + + } +}; + + //! Template to shortcut the constrained_value policy creation process + template + class simple_exception_policy + { + public: + typedef rep_type value_type; + static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }; + static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value;}; + static void on_error(rep_type, rep_type, violation_enum) + { + throw exception_type(); + } + }; + + + +} } //namespace CV + + + + +#endif diff --git a/thirdparty/boost/date_time/date.hpp b/thirdparty/boost/date_time/date.hpp new file mode 100644 index 0000000..c96ce6f --- /dev/null +++ b/thirdparty/boost/date_time/date.hpp @@ -0,0 +1,197 @@ +#ifndef DATE_TIME_DATE_HPP___ +#define DATE_TIME_DATE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/year_month_day.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/operators.hpp" + +namespace boost { +namespace date_time { + + //!Representation of timepoint at the one day level resolution. + /*! + The date template represents an interface shell for a date class + that is based on a year-month-day system such as the gregorian + or iso systems. It provides basic operations to enable calculation + and comparisons. + + Theory + + This date representation fundamentally departs from the C tm struct + approach. The goal for this type is to provide efficient date + operations (add, subtract) and storage (minimize space to represent) + in a concrete class. Thus, the date uses a count internally to + represent a particular date. The calendar parameter defines + the policies for converting the the year-month-day and internal + counted form here. Applications that need to perform heavy + formatting of the same date repeatedly will perform better + by using the year-month-day representation. + + Internally the date uses a day number to represent the date. + This is a monotonic time representation. This representation + allows for fast comparison as well as simplifying + the creation of writing numeric operations. Essentially, the + internal day number is like adjusted julian day. The adjustment + is determined by the Epoch date which is represented as day 1 of + the calendar. Day 0 is reserved for negative infinity so that + any actual date is automatically greater than negative infinity. + When a date is constructed from a date or formatted for output, + the appropriate conversions are applied to create the year, month, + day representations. + */ + + + template + class date : private + boost::less_than_comparable > + { + public: + typedef T date_type; + typedef calendar calendar_type; + typedef typename calendar::date_traits_type traits_type; + typedef duration_type_ duration_type; + typedef typename calendar::year_type year_type; + typedef typename calendar::month_type month_type; + typedef typename calendar::day_type day_type; + typedef typename calendar::ymd_type ymd_type; + typedef typename calendar::date_rep_type date_rep_type; + typedef typename calendar::date_int_type date_int_type; + typedef typename calendar::day_of_week_type day_of_week_type; + date(year_type y, month_type m, day_type d) + : days_(calendar::day_number(ymd_type(y, m, d))) + {} + date(const ymd_type& ymd) + : days_(calendar::day_number(ymd)) + {} + //let the compiler write copy, assignment, and destructor + year_type year() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.year; + } + month_type month() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.month; + } + day_type day() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.day; + } + day_of_week_type day_of_week() const + { + ymd_type ymd = calendar::from_day_number(days_); + return calendar::day_of_week(ymd); + } + ymd_type year_month_day() const + { + return calendar::from_day_number(days_); + } + bool operator<(const date_type& rhs) const + { + return days_ < rhs.days_; + } + bool operator==(const date_type& rhs) const + { + return days_ == rhs.days_; + } + //! check to see if date is a special value + bool is_special()const + { + return(is_not_a_date() || is_infinity()); + } + //! check to see if date is not a value + bool is_not_a_date() const + { + return traits_type::is_not_a_number(days_); + } + //! check to see if date is one of the infinity values + bool is_infinity() const + { + return traits_type::is_inf(days_); + } + //! check to see if date is greater than all possible dates + bool is_pos_infinity() const + { + return traits_type::is_pos_inf(days_); + } + //! check to see if date is greater than all possible dates + bool is_neg_infinity() const + { + return traits_type::is_neg_inf(days_); + } + //! return as a special value or a not_special if a normal date + special_values as_special() const + { + return traits_type::to_special(days_); + } + duration_type operator-(const date_type& d) const + { + date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); + return duration_type(val.as_number()); + } + + date_type operator-(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) - dd.get_rep()); + } + return date_type(date_rep_type(days_) - dd.days()); + } + date_type operator-=(const duration_type& dd) + { + *this = *this - dd; + return date_type(days_); + } + date_rep_type day_count() const + { + return days_; + }; + //allow internal access from operators + date_type operator+(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) + dd.get_rep()); + } + return date_type(date_rep_type(days_) + dd.days()); + } + date_type operator+=(const duration_type& dd) + { + *this = *this + dd; + return date_type(days_); + } + + //see reference + protected: + /*! This is a private constructor which allows for the creation of new + dates. It is not exposed to users since that would require class + users to understand the inner workings of the date class. + */ + explicit date(date_int_type days) : days_(days) {}; + explicit date(date_rep_type days) : days_(days.as_number()) {}; + date_int_type days_; + + }; + + + + +} } // namespace date_time + + + + +#endif diff --git a/thirdparty/boost/date_time/date_clock_device.hpp b/thirdparty/boost/date_time/date_clock_device.hpp new file mode 100644 index 0000000..407d41a --- /dev/null +++ b/thirdparty/boost/date_time/date_clock_device.hpp @@ -0,0 +1,77 @@ +#ifndef DATE_CLOCK_DEVICE_HPP___ +#define DATE_CLOCK_DEVICE_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/c_time.hpp" + + +namespace boost { +namespace date_time { + + //! A clock providing day level services based on C time_t capabilities + /*! This clock uses Posix interfaces as its implementation and hence + * uses the timezone settings of the operating system. Incorrect + * user settings will result in incorrect results for the calls + * to local_day. + */ + template + class day_clock + { + public: + typedef typename date_type::ymd_type ymd_type; + //! Get the local day as a date type + static date_type local_day() + { + return date_type(local_day_ymd()); + } + //! Get the local day as a ymd_type + static typename date_type::ymd_type local_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_local_time(result); + return ymd_type(curr->tm_year + 1900, + curr->tm_mon + 1, + curr->tm_mday); + } + //! Get the current day in universal date as a ymd_type + static typename date_type::ymd_type universal_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_universal_time(result); + return ymd_type(curr->tm_year + 1900, + curr->tm_mon + 1, + curr->tm_mday); + } + //! Get the UTC day as a date type + static date_type universal_day() + { + return date_type(universal_day_ymd()); + } + + private: + static ::std::tm* get_local_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::localtime(&t, &result); + } + static ::std::tm* get_universal_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::gmtime(&t, &result); + } + + }; + +} } //namespace date_time + + +#endif diff --git a/thirdparty/boost/date_time/date_defs.hpp b/thirdparty/boost/date_time/date_defs.hpp new file mode 100644 index 0000000..b3b623b --- /dev/null +++ b/thirdparty/boost/date_time/date_defs.hpp @@ -0,0 +1,26 @@ +#ifndef DATE_TIME_DATE_DEFS_HPP +#define DATE_TIME_DATE_DEFS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +namespace boost { +namespace date_time { + + //! An enumeration of weekday names + enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; + + //! Simple enum to allow for nice programming with Jan, Feb, etc + enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths}; + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/date_duration.hpp b/thirdparty/boost/date_time/date_duration.hpp new file mode 100644 index 0000000..063a960 --- /dev/null +++ b/thirdparty/boost/date_time/date_duration.hpp @@ -0,0 +1,147 @@ +#ifndef DATE_TIME_DATE_DURATION__ +#define DATE_TIME_DATE_DURATION__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include + +namespace boost { +namespace date_time { + + + //! Duration type with date level resolution + template + class date_duration : private + boost::less_than_comparable + , boost::equality_comparable< date_duration< duration_rep_traits> + , boost::addable< date_duration< duration_rep_traits> + , boost::subtractable< date_duration< duration_rep_traits> + > > > > + { + public: + typedef typename duration_rep_traits::int_type duration_rep_type; + typedef typename duration_rep_traits::impl_type duration_rep; + + //! Construct from a day count + explicit date_duration(duration_rep day_count) : days_(day_count) {}; + + /*! construct from special_values - only works when + * instantiated with duration_traits_adapted */ + date_duration(special_values sv) : + days_(duration_rep::from_special(sv)) + {} + + // copy constructor required for addable<> & subtractable<> + //! Construct from another date_duration (Copy Constructor) + date_duration(const date_duration& other) : + days_(other.days_) + {} + + //! returns days_ as it's instantiated type - used for streaming + duration_rep get_rep()const + { + return days_; + } + bool is_special()const + { + return days_.is_special(); + } + //! returns days as value, not object. + duration_rep_type days() const + { + return duration_rep_traits::as_number(days_); + } + //! Returns the smallest duration -- used by to calculate 'end' + static date_duration unit() + { + return date_duration(1); + } + //! Equality + bool operator==(const date_duration& rhs) const + { + return days_ == rhs.days_; + } + //! Less + bool operator<(const date_duration& rhs) const + { + return days_ < rhs.days_; + } + + /* For shortcut operators (+=, -=, etc) simply using + * "days_ += days_" may not work. If instantiated with + * an int_adapter, shortcut operators are not present, + * so this will not compile */ + + //! Subtract another duration -- result is signed + date_duration operator-=(const date_duration& rhs) + { + //days_ -= rhs.days_; + days_ = days_ - rhs.days_; + return *this; + } + //! Add a duration -- result is signed + date_duration operator+=(const date_duration& rhs) + { + days_ = days_ + rhs.days_; + return *this; + } + + //! unary- Allows for dd = -date_duration(2); -> dd == -2 + date_duration operator-()const + { + return date_duration(get_rep() * (-1)); + } + //! Division operations on a duration with an integer. + date_duration operator/=(int divisor) + { + days_ = days_ / divisor; + return *this; + } + date_duration operator/(int divisor) + { + return date_duration(days_ / divisor); + } + + //! return sign information + bool is_negative() const + { + return days_ < 0; + } + private: + duration_rep days_; + }; + + + /*! Struct for instantiating date_duration with NO special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct duration_traits_long + { + typedef long int_type; + typedef long impl_type; + static int_type as_number(impl_type i) { return i; }; + }; + + /*! Struct for instantiating date_duration WITH special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct duration_traits_adapted + { + typedef long int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i) { return i.as_number(); }; + }; + + +} } //namspace date_time + + +#endif + diff --git a/thirdparty/boost/date_time/date_duration_types.hpp b/thirdparty/boost/date_time/date_duration_types.hpp new file mode 100644 index 0000000..1309b48 --- /dev/null +++ b/thirdparty/boost/date_time/date_duration_types.hpp @@ -0,0 +1,269 @@ +#ifndef DATE_DURATION_TYPES_HPP___ +#define DATE_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Additional duration type that represents a number of n*7 days + template + class weeks_duration : public date_duration { + public: + weeks_duration(typename duration_config::impl_type w) + : date_duration(w * 7) {} + weeks_duration(special_values sv) + : date_duration(sv) {} + }; + + // predeclare + template + class years_duration; + + //! additional duration type that represents a logical month + /*! A logical month enables things like: "date(2002,Mar,2) + months(2) -> + * 2002-May2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month. + */ + template + class months_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef months_duration months_type; + typedef years_duration years_type; + public: + months_duration(int_rep num) : _m(num) {} + months_duration(special_values sv) : _m(sv) + { + _m = int_rep::from_special(sv); + } + int_rep number_of_months() const { return _m; } + //! returns a negative duration + duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_neg_offset(d)); + } + duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_offset(d)); + } + bool operator==(const months_type& rhs) const + { + return(_m == rhs._m); + } + bool operator!=(const months_type& rhs) const + { + return(_m != rhs._m); + } + months_type operator+(const months_type& rhs)const + { + return months_type(_m + rhs._m); + } + months_type& operator+=(const months_type& rhs) + { + _m = _m + rhs._m; + return *this; + } + months_type operator-(const months_type& rhs)const + { + return months_type(_m - rhs._m); + } + months_type& operator-=(const months_type& rhs) + { + _m = _m - rhs._m; + return *this; + } + months_type operator*(const int_type rhs)const + { + return months_type(_m * rhs); + } + months_type& operator*=(const int_type rhs) + { + _m = _m * rhs; + return *this; + } + months_type operator/(const int_type rhs)const + { + return months_type(_m / rhs); + } + months_type& operator/=(const int_type rhs) + { + _m = _m / rhs; + return *this; + } + months_type operator+(const years_type& y)const + { + return months_type(y.number_of_years() * 12 + _m); + } + months_type& operator+=(const years_type& y) + { + _m = y.number_of_years() * 12 + _m; + return *this; + } + months_type operator-(const years_type& y) const + { + return months_type(_m - y.number_of_years() * 12); + } + months_type& operator-=(const years_type& y) + { + _m = _m - y.number_of_years() * 12; + return *this; + } + + // + friend date_type operator+(const date_type& d, const months_type& m) + { + return d + m.get_offset(d); + } + friend date_type operator+=(date_type& d, const months_type& m) + { + return d += m.get_offset(d); + } + friend date_type operator-(const date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d + m.get_neg_offset(d); + } + friend date_type operator-=(date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d += m.get_neg_offset(d); + } + + private: + int_rep _m; + }; + + //! additional duration type that represents a logical year + /*! A logical year enables things like: "date(2002,Mar,2) + years(2) -> + * 2004-Mar-2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) -> + * 2004-Feb-29). + */ + template + class years_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef years_duration years_type; + typedef months_duration months_type; + public: + years_duration(int_rep num) : _y(num) {} + years_duration(special_values sv) : _y(sv) + { + _y = int_rep::from_special(sv); + } + int_rep number_of_years() const { return _y; } + //! returns a negative duration + duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_neg_offset(d)); + } + duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_offset(d)); + } + bool operator==(const years_type& rhs) const + { + return(_y == rhs._y); + } + bool operator!=(const years_type& rhs) const + { + return(_y != rhs._y); + } + years_type operator+(const years_type& rhs)const + { + return years_type(_y + rhs._y); + } + years_type& operator+=(const years_type& rhs) + { + _y = _y + rhs._y; + return *this; + } + years_type operator-(const years_type& rhs)const + { + return years_type(_y - rhs._y); + } + years_type& operator-=(const years_type& rhs) + { + _y = _y - rhs._y; + return *this; + } + years_type operator*(const int_type rhs)const + { + return years_type(_y * rhs); + } + years_type& operator*=(const int_type rhs) + { + _y = _y * rhs; + return *this; + } + years_type operator/(const int_type rhs)const + { + return years_type(_y / rhs); + } + years_type& operator/=(const int_type rhs) + { + _y = _y / rhs; + return *this; + } + months_type operator+(const months_type& m) const + { + return(months_type(_y * 12 + m.number_of_months())); + } + months_type operator-(const months_type& m) const + { + return(months_type(_y * 12 - m.number_of_months())); + } + + // + friend date_type operator+(const date_type& d, const years_type& y) + { + return d + y.get_offset(d); + } + friend date_type operator+=(date_type& d, const years_type& y) + { + return d += y.get_offset(d); + } + friend date_type operator-(const date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d + y.get_neg_offset(d); + } + friend date_type operator-=(date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d += y.get_neg_offset(d); + } + + private: + int_rep _y; + }; + +}} // namespace boost::date_time + +#endif // DATE_DURATION_TYPES_HPP___ diff --git a/thirdparty/boost/date_time/date_facet.hpp b/thirdparty/boost/date_time/date_facet.hpp new file mode 100644 index 0000000..06bda95 --- /dev/null +++ b/thirdparty/boost/date_time/date_facet.hpp @@ -0,0 +1,775 @@ +#ifndef _DATE_TIME_DATE_FACET__HPP___ +#define _DATE_TIME_DATE_FACET__HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Martin Andrian, Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/algorithm/string/replace.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/special_values_formatter.hpp" +#include "boost/date_time/period_formatter.hpp" +#include "boost/date_time/period_parser.hpp" +#include "boost/date_time/date_generator_formatter.hpp" +#include "boost/date_time/date_generator_parser.hpp" +#include "boost/date_time/format_date_parser.hpp" +#include +#include + +namespace boost { namespace date_time { + + + /*! Class that provides format based I/O facet for date types. + * + * This class allows the formatting of dates by using format string. + * Format strings are: + * + * - %A => long_weekday_format - Full name Ex: Tuesday + * - %a => short_weekday_format - Three letter abbreviation Ex: Tue + * - %B => long_month_format - Full name Ex: October + * - %b => short_month_format - Three letter abbreviation Ex: Oct + * - %x => standard_format_specifier - defined by the locale + * - %Y-%b-%d => default_date_format - YYYY-Mon-dd + * + * Default month format == %b + * Default weekday format == %a + */ + template > > + class date_facet : public std::locale::facet { + public: + typedef typename date_type::duration_type duration_type; + // greg_weekday is gregorian_calendar::day_of_week_type + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::month_type month_type; + typedef boost::date_time::period period_type; + typedef std::basic_string string_type; + typedef CharT char_type; + typedef boost::date_time::period_formatter period_formatter_type; + typedef boost::date_time::special_values_formatter special_values_formatter_type; + typedef std::vector > input_collection_type; + // used for the output of the date_generators + typedef date_generator_formatter date_gen_formatter_type; + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + static const char_type long_weekday_format[3]; + static const char_type short_weekday_format[3]; + static const char_type long_month_format[3]; + static const char_type short_month_format[3]; + static const char_type default_period_separator[4]; + static const char_type standard_format_specifier[3]; + static const char_type iso_format_specifier[7]; + static const char_type iso_format_extended_specifier[9]; + static const char_type default_date_format[9]; // YYYY-Mon-DD + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + explicit date_facet(::size_t a_ref = 0) + : std::locale::facet(a_ref), + //m_format(standard_format_specifier) + m_format(default_date_format), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format) + {} + + explicit date_facet(const char_type* format_str, + const input_collection_type& short_names, + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_month_short_names(short_names) + {} + + + explicit date_facet(const char_type* format_str, + period_formatter_type per_formatter = period_formatter_type(), + special_values_formatter_type sv_formatter = special_values_formatter_type(), + date_gen_formatter_type dg_formatter = date_gen_formatter_type(), + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_period_formatter(per_formatter), + m_date_gen_formatter(dg_formatter), + m_special_values_formatter(sv_formatter) + {} + void format(const char_type* const format_str) { + m_format = format_str; + } + virtual void set_iso_format() + { + m_format = iso_format_specifier; + } + virtual void set_iso_extended_format() + { + m_format = iso_format_extended_specifier; + } + void month_format(const char_type* const format_str) { + m_month_format = format_str; + } + void weekday_format(const char_type* const format_str) { + m_weekday_format = format_str; + } + + void period_formatter(period_formatter_type per_formatter) { + m_period_formatter= per_formatter; + } + void special_values_formatter(const special_values_formatter_type& svf) + { + m_special_values_formatter = svf; + } + void short_weekday_names(const input_collection_type& short_names) + { + m_weekday_short_names = short_names; + } + void long_weekday_names(const input_collection_type& long_names) + { + m_weekday_long_names = long_names; + } + + void short_month_names(const input_collection_type& short_names) + { + m_month_short_names = short_names; + } + + void long_month_names(const input_collection_type& long_names) + { + m_month_long_names = long_names; + } + + void date_gen_phrase_strings(const input_collection_type& new_strings, + typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first) + { + m_date_gen_formatter.elements(new_strings, beg_pos); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const date_type& d) const + { + if (d.is_special()) { + return do_put_special(next, a_ios, fill_char, d.as_special()); + } + //The following line of code required the date to support a to_tm function + return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const duration_type& dd) const + { + if (dd.is_special()) { + return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special()); + } + + typedef std::num_put num_put; + if (std::has_facet(a_ios.getloc())) { + return std::use_facet(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number()); + } + else { + num_put* f = new num_put(); + std::locale l = std::locale(a_ios.getloc(), f); + a_ios.imbue(l); + return f->put(next, a_ios, fill_char, dd.get_rep().as_number()); + } + + } + + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const month_type& m) const + { + //if (d.is_special()) { + // return do_put_special(next, a_ios, fill_char, d.as_special()); + //} + //The following line of code required the date to support a to_tm function + tm dtm; + init_tm(dtm); + dtm.tm_mon = m -1; + return do_put_tm(next, a_ios, fill_char, dtm, m_month_format); + } + + //! puts the day of month + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const day_type& day) const + { + tm dtm; + init_tm(dtm); + dtm.tm_mday = day.as_number(); + char_type tmp[3] = {'%','d'}; + string_type temp_format(tmp); + return do_put_tm(next, a_ios, fill_char, dtm, temp_format); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const day_of_week_type& dow) const + { + //if (d.is_special()) { + // return do_put_special(next, a_ios, fill_char, d.as_special()); + //} + //The following line of code required the date to support a to_tm function + tm dtm; + init_tm(dtm); + dtm.tm_wday = dow; + return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format); + } + + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const period_type& p) const + { + return m_period_formatter.put_period(next, a_ios, fill_char, p, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const partial_date_type& pd) const + { + return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const nth_kday_type& nkd) const + { + return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const first_kday_type& fkd) const + { + return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const last_kday_type& lkd) const + { + return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const kday_before_type& fkb) const + { + return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const kday_after_type& fka) const + { + return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this); + } + + protected: + //! Helper function to initialize all fields in a tm struct + tm init_tm(tm& tm_value) const + { + tm_value.tm_sec = 0; /* seconds */ + tm_value.tm_min = 0; /* minutes */ + tm_value.tm_hour = 0; /* hours */ + tm_value.tm_mday = 0; /* day of the month */ + tm_value.tm_mon = 0; /* month */ + tm_value.tm_year = 0; /* year */ + tm_value.tm_wday = 0; /* day of the week */ + tm_value.tm_yday = 0; /* day in the year */ + tm_value.tm_isdst = 0; /* daylight saving time */ + return tm_value; + } + virtual OutItrT do_put_special(OutItrT next, + std::ios_base& /*a_ios*/, + char_type /*fill_char*/, + const boost::date_time::special_values sv) const + { + m_special_values_formatter.put_special(next, sv); + return next; + } + virtual OutItrT do_put_tm(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const tm& tm_value, + string_type a_format) const + { + // update format string with custom names + if (m_weekday_long_names.size()) { + boost::algorithm::replace_all(a_format, + long_weekday_format, + m_weekday_long_names[tm_value.tm_wday]); + } + if (m_weekday_short_names.size()) { + boost::algorithm::replace_all(a_format, + short_weekday_format, + m_weekday_short_names[tm_value.tm_wday]); + + } + if (m_month_long_names.size()) { + boost::algorithm::replace_all(a_format, + long_month_format, + m_month_long_names[tm_value.tm_mon]); + } + if (m_month_short_names.size()) { + boost::algorithm::replace_all(a_format, + short_month_format, + m_month_short_names[tm_value.tm_mon]); + } + // use time_put facet to create final string + return std::use_facet >(a_ios.getloc()).put(next, a_ios, + fill_char, + &tm_value, + &*a_format.begin(), + &*a_format.begin()+a_format.size()); + } + protected: + string_type m_format; + string_type m_month_format; + string_type m_weekday_format; + period_formatter_type m_period_formatter; + date_gen_formatter_type m_date_gen_formatter; + special_values_formatter_type m_special_values_formatter; + input_collection_type m_month_short_names; + input_collection_type m_month_long_names; + input_collection_type m_weekday_short_names; + input_collection_type m_weekday_long_names; + private: + }; + + template + std::locale::id date_facet::id; + + template + const typename date_facet::char_type + date_facet::long_weekday_format[3] = {'%','A'}; + + template + const typename date_facet::char_type + date_facet::short_weekday_format[3] = {'%','a'}; + + template + const typename date_facet::char_type + date_facet::long_month_format[3] = {'%','B'}; + + template + const typename date_facet::char_type + date_facet::short_month_format[3] = {'%','b'}; + + template + const typename date_facet::char_type + date_facet::default_period_separator[4] = { ' ', '/', ' '}; + + template + const typename date_facet::char_type + date_facet::standard_format_specifier[3] = + {'%', 'x' }; + + template + const typename date_facet::char_type + date_facet::iso_format_specifier[7] = + {'%', 'Y', '%', 'm', '%', 'd' }; + + template + const typename date_facet::char_type + date_facet::iso_format_extended_specifier[9] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd' }; + + template + const typename date_facet::char_type + date_facet::default_date_format[9] = + {'%','Y','-','%','b','-','%','d'}; + + + + //! Input facet + template > > + class date_input_facet : public std::locale::facet { + public: + typedef typename date_type::duration_type duration_type; + // greg_weekday is gregorian_calendar::day_of_week_type + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::year_type year_type; + typedef boost::date_time::period period_type; + typedef std::basic_string string_type; + typedef CharT char_type; + typedef boost::date_time::period_parser period_parser_type; + typedef boost::date_time::special_values_parser special_values_parser_type; + typedef std::vector > input_collection_type; + typedef format_date_parser format_date_parser_type; + // date_generators stuff goes here + typedef date_generator_parser date_gen_parser_type; + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + static const char_type long_weekday_format[3]; + static const char_type short_weekday_format[3]; + static const char_type long_month_format[3]; + static const char_type short_month_format[3]; + static const char_type four_digit_year_format[3]; + static const char_type two_digit_year_format[3]; + static const char_type default_period_separator[4]; + static const char_type standard_format_specifier[3]; + static const char_type iso_format_specifier[7]; + static const char_type iso_format_extended_specifier[9]; + static const char_type default_date_format[9]; // YYYY-Mon-DD + static std::locale::id id; + + explicit date_input_facet(::size_t a_ref = 0) + : std::locale::facet(a_ref), + m_format(default_date_format), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(m_format, std::locale::classic()) + // default period_parser & special_values_parser used + {} + + explicit date_input_facet(const string_type& format_str, + ::size_t a_ref = 0) + : std::locale::facet(a_ref), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(m_format, std::locale::classic()) + // default period_parser & special_values_parser used + {} + + explicit date_input_facet(const string_type& format_str, + const format_date_parser_type& date_parser, + const special_values_parser_type& sv_parser, + const period_parser_type& per_parser, + const date_gen_parser_type& date_gen_parser, + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(date_parser), + m_date_gen_parser(date_gen_parser), + m_period_parser(per_parser), + m_sv_parser(sv_parser) + {} + + + void format(const char_type* const format_str) { + m_format = format_str; + } + virtual void set_iso_format() + { + m_format = iso_format_specifier; + } + virtual void set_iso_extended_format() + { + m_format = iso_format_extended_specifier; + } + void month_format(const char_type* const format_str) { + m_month_format = format_str; + } + void weekday_format(const char_type* const format_str) { + m_weekday_format = format_str; + } + void year_format(const char_type* const format_str) { + m_year_format = format_str; + } + + void period_parser(period_parser_type per_parser) { + m_period_parser = per_parser; + } + void short_weekday_names(const input_collection_type& weekday_names) + { + m_parser.short_weekday_names(weekday_names); + } + void long_weekday_names(const input_collection_type& weekday_names) + { + m_parser.long_weekday_names(weekday_names); + } + + void short_month_names(const input_collection_type& month_names) + { + m_parser.short_month_names(month_names); + } + + void long_month_names(const input_collection_type& month_names) + { + m_parser.long_month_names(month_names); + } + + void date_gen_element_strings(const input_collection_type& col) + { + m_date_gen_parser.element_strings(col); + } + void date_gen_element_strings(const string_type& first, + const string_type& second, + const string_type& third, + const string_type& fourth, + const string_type& fifth, + const string_type& last, + const string_type& before, + const string_type& after, + const string_type& of) + + { + m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of); + } + + void special_values_parser(special_values_parser_type sv_parser) + { + m_sv_parser = sv_parser; + } + + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + date_type& d) const + { + d = m_parser.parse_date(from, to, m_format, m_sv_parser); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + month_type& m) const + { + m = m_parser.parse_month(from, to, m_month_format); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + day_of_week_type& wd) const + { + wd = m_parser.parse_weekday(from, to, m_weekday_format); + return from; + } + //! Expects 1 or 2 digit day range: 1-31 + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + day_type& d) const + { + d = m_parser.parse_var_day_of_month(from, to); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + year_type& y) const + { + y = m_parser.parse_year(from, to, m_year_format); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + duration_type& dd) const + { + // skip leading whitespace + while(std::isspace(*from) && from != to) { ++from; } + + /* num_get.get() will always consume the first character if it + * is a sign indicator (+/-). Special value strings may begin + * with one of these signs so we'll need a copy of it + * in case num_get.get() fails. */ + char_type c = '\0'; + // TODO Are these characters somewhere in the locale? + if(*from == '-' || *from == '+') { + c = *from; + } + typedef std::num_get num_get; + typename duration_type::duration_rep_type val = 0; + std::ios_base::iostate err = std::ios_base::goodbit; + + if (std::has_facet(a_ios.getloc())) { + from = std::use_facet(a_ios.getloc()).get(from, to, a_ios, err, val); + } + else { + num_get* ng = new num_get(); + std::locale l = std::locale(a_ios.getloc(), ng); + a_ios.imbue(l); + from = ng->get(from, to, a_ios, err, val); + } + if(err & std::ios_base::failbit){ + typedef typename special_values_parser_type::match_results match_results; + match_results mr; + if(c == '-' || c == '+') { // was the first character consumed? + mr.cache += c; + } + m_sv_parser.match(from, to, mr); + if(mr.current_match == match_results::PARSE_ERROR) { + throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"); + } + dd = duration_type(static_cast(mr.current_match)); + } + else { + dd = duration_type(val); + } + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + period_type& p) const + { + p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + nth_kday_type& nkd) const + { + nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + partial_date_type& pd) const + { + + pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + first_kday_type& fkd) const + { + fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + last_kday_type& lkd) const + { + lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + kday_before_type& fkb) const + { + fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + kday_after_type& fka) const + { + fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this); + return from; + } + + protected: + string_type m_format; + string_type m_month_format; + string_type m_weekday_format; + string_type m_year_format; + format_date_parser_type m_parser; + date_gen_parser_type m_date_gen_parser; + period_parser_type m_period_parser; + special_values_parser_type m_sv_parser; + private: + }; + + + template + std::locale::id date_input_facet::id; + + template + const typename date_input_facet::char_type + date_input_facet::long_weekday_format[3] = {'%','A'}; + + template + const typename date_input_facet::char_type + date_input_facet::short_weekday_format[3] = {'%','a'}; + + template + const typename date_input_facet::char_type + date_input_facet::long_month_format[3] = {'%','B'}; + + template + const typename date_input_facet::char_type + date_input_facet::short_month_format[3] = {'%','b'}; + + template + const typename date_input_facet::char_type + date_input_facet::four_digit_year_format[3] = {'%','Y'}; + + template + const typename date_input_facet::char_type + date_input_facet::two_digit_year_format[3] = {'%','y'}; + + template + const typename date_input_facet::char_type + date_input_facet::default_period_separator[4] = { ' ', '/', ' '}; + + template + const typename date_input_facet::char_type + date_input_facet::standard_format_specifier[3] = + {'%', 'x' }; + + template + const typename date_input_facet::char_type + date_input_facet::iso_format_specifier[7] = + {'%', 'Y', '%', 'm', '%', 'd' }; + + template + const typename date_input_facet::char_type + date_input_facet::iso_format_extended_specifier[9] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd' }; + + template + const typename date_input_facet::char_type + date_input_facet::default_date_format[9] = + {'%','Y','-','%','b','-','%','d'}; + +} } // namespaces + + +#endif diff --git a/thirdparty/boost/date_time/date_format_simple.hpp b/thirdparty/boost/date_time/date_format_simple.hpp new file mode 100644 index 0000000..d1fa8f1 --- /dev/null +++ b/thirdparty/boost/date_time/date_format_simple.hpp @@ -0,0 +1,159 @@ +#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___ +#define DATE_TIME_SIMPLE_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide simple basic formatting rules +template +class simple_format { +public: + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static charT year_sep_char() + { + return '-'; + } + //! char between year-month + static charT month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static charT day_sep_char() + { + return '-'; + } + //! char between date-hours + static charT hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Specialization of formmating rules for wchar_t +template<> +class simple_format { +public: + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static wchar_t year_sep_char() + { + return '-'; + } + //! char between year-month + static wchar_t month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static wchar_t day_sep_char() + { + return '-'; + } + //! char between date-hours + static wchar_t hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING +} } //namespace date_time + + + + +#endif diff --git a/thirdparty/boost/date_time/date_formatting.hpp b/thirdparty/boost/date_time/date_formatting.hpp new file mode 100644 index 0000000..65ab39f --- /dev/null +++ b/thirdparty/boost/date_time/date_formatting.hpp @@ -0,0 +1,127 @@ +#ifndef DATE_TIME_DATE_FORMATTING_HPP___ +#define DATE_TIME_DATE_FORMATTING_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include + +/* NOTE: "formatter" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * date_formatting_limited.hpp + */ + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class month_formatter + { + typedef std::basic_ostream ostream_type; + public: + //! Formats a month as as string into an ostream + /*! This function demands that month_type provide + * functions for converting to short and long strings + * if that capability is used. + */ + static ostream_type& format_month(const month_type& month, + ostream_type &os) + { + switch (format_type::month_format()) + { + case month_as_short_string: + { + os << month.as_short_string(); + break; + } + case month_as_long_string: + { + os << month.as_long_string(); + break; + } + case month_as_integer: + { + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); + break; + } + + } + return os; + } // format_month + }; + + + //! Convert ymd to a standard string formatting policies + template + class ymd_formatter + { + public: + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + static std::basic_string ymd_to_string(ymd_type ymd) + { + typedef typename ymd_type::month_type month_type; + std::basic_ostringstream ss; + ss << ymd.year; + if (format_type::has_date_sep_chars()) { + ss << format_type::month_sep_char(); + } + //this name is a bit ugly, oh well.... + month_formatter::format_month(ymd.month, ss); + if (format_type::has_date_sep_chars()) { + ss << format_type::day_sep_char(); + } + ss << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + }; + + + //! Convert a date to string using format policies + template + class date_formatter + { + public: + typedef std::basic_string string_type; + //! Convert to a date to standard string using format policies + static string_type date_to_string(date_type d) + { + typedef typename date_type::ymd_type ymd_type; + if (d.is_not_a_date()) { + return string_type(format_type::not_a_date()); + } + if (d.is_neg_infinity()) { + return string_type(format_type::neg_infinity()); + } + if (d.is_pos_infinity()) { + return string_type(format_type::pos_infinity()); + } + ymd_type ymd = d.year_month_day(); + return ymd_formatter::ymd_to_string(ymd); + } + }; + + +} } //namespace date_time + + +#endif + diff --git a/thirdparty/boost/date_time/date_formatting_limited.hpp b/thirdparty/boost/date_time/date_formatting_limited.hpp new file mode 100644 index 0000000..91a2f04 --- /dev/null +++ b/thirdparty/boost/date_time/date_formatting_limited.hpp @@ -0,0 +1,121 @@ +#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___ +#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class month_formatter + { + public: + //! Formats a month as as string into an ostream + /*! This function demands that month_type provide + * functions for converting to short and long strings + * if that capability is used. + */ + static std::ostream& format_month(const month_type& month, + std::ostream& os) + { + switch (format_type::month_format()) + { + case month_as_short_string: + { + os << month.as_short_string(); + break; + } + case month_as_long_string: + { + os << month.as_long_string(); + break; + } + case month_as_integer: + { + os << std::setw(2) << std::setfill('0') << month.as_number(); + break; + } + + } + return os; + } // format_month + }; + + + //! Convert ymd to a standard string formatting policies + template + class ymd_formatter + { + public: + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + static std::string ymd_to_string(ymd_type ymd) + { + typedef typename ymd_type::month_type month_type; + std::ostringstream ss; + ss << ymd.year; + if (format_type::has_date_sep_chars()) { + ss << format_type::month_sep_char(); + } + //this name is a bit ugly, oh well.... + month_formatter::format_month(ymd.month, ss); + if (format_type::has_date_sep_chars()) { + ss << format_type::day_sep_char(); + } + ss << std::setw(2) << std::setfill('0') + << ymd.day; + return ss.str(); + } + }; + + + //! Convert a date to string using format policies + template + class date_formatter + { + public: + //! Convert to a date to standard string using format policies + static std::string date_to_string(date_type d) + { + typedef typename date_type::ymd_type ymd_type; + if (d.is_not_a_date()) { + return format_type::not_a_date(); + } + if (d.is_neg_infinity()) { + return format_type::neg_infinity(); + } + if (d.is_pos_infinity()) { + return format_type::pos_infinity(); + } + ymd_type ymd = d.year_month_day(); + return ymd_formatter::ymd_to_string(ymd); + } + }; + + +} } //namespace date_time + + +#endif + diff --git a/thirdparty/boost/date_time/date_formatting_locales.hpp b/thirdparty/boost/date_time/date_formatting_locales.hpp new file mode 100644 index 0000000..84bd255 --- /dev/null +++ b/thirdparty/boost/date_time/date_formatting_locales.hpp @@ -0,0 +1,233 @@ +#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ +#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_names_put.hpp" +#include "boost/date_time/parse_format_base.hpp" +//#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class ostream_month_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_month(const month_type& month, + ostream_type& os, + const facet_type& f) + { + + switch (f.month_format()) + { + case month_as_short_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_short(oitr, month.as_enum()); + break; + } + case month_as_long_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_long(oitr, month.as_enum()); + break; + } + case month_as_integer: + { + charT fill_char = '0'; + os << std::setw(2) << std::setfill(fill_char) << month.as_number(); + break; + } + + } + } // format_month + + }; + + + //! Formats a weekday + template + class ostream_weekday_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_weekday(const weekday_type& wd, + ostream_type& os, + const facet_type& f, + bool as_long_string) + { + + std::ostreambuf_iterator oitr(os); + if (as_long_string) { + f.put_weekday_long(oitr, wd.as_enum()); + } + else { + f.put_weekday_short(oitr, wd.as_enum()); + } + + } // format_weekday + + }; + + + //! Convert ymd to a standard string formatting policies + template + class ostream_ymd_formatter + { + public: + typedef typename ymd_type::month_type month_type; + typedef ostream_month_formatter month_formatter_type; + typedef std::basic_ostream ostream_type; + typedef std::basic_string foo_type; + + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + // static string_type ymd_to_string(ymd_type ymd) +// { +// std::ostringstream ss; +// facet_type dnp; +// ymd_put(ymd, ss, dnp); +// return ss.str(); +// } + + + // Put ymd to ostream -- part of ostream refactor + static void ymd_put(ymd_type ymd, + ostream_type& os, + const facet_type& f) + { + std::ostreambuf_iterator oitr(os); + charT fill_char = '0'; + switch (f.date_order()) { + case ymd_order_iso: { + os << ymd.year; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(fill_char) + << ymd.day; + break; + } + case ymd_order_us: { + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(fill_char) + << ymd.day; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + case ymd_order_dmy: { + os << std::setw(2) << std::setfill(fill_char) + << ymd.day; + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + } + } + }; + + + //! Convert a date to string using format policies + template + class ostream_date_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename date_type::ymd_type ymd_type; + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os, + const facet_type& f) + { + special_values sv = d.as_special(); + if (sv == not_special) { + ymd_type ymd = d.year_month_day(); + ostream_ymd_formatter::ymd_put(ymd, os, f); + } + else { // output a special value + std::ostreambuf_iterator coi(os); + f.put_special_value(coi, sv); + } + } + + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os) + { + //retrieve the local from the ostream + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_type& f = std::use_facet(locale); + date_put(d, os, f); + } + else { + //default to something sensible if no facet installed + facet_type default_facet; + date_put(d, os, default_facet); + } + } // date_to_ostream + }; //class date_formatter + + +} } //namespace date_time + +#endif + +#endif + diff --git a/thirdparty/boost/date_time/date_generator_formatter.hpp b/thirdparty/boost/date_time/date_generator_formatter.hpp new file mode 100644 index 0000000..b4f9e7e --- /dev/null +++ b/thirdparty/boost/date_time/date_generator_formatter.hpp @@ -0,0 +1,263 @@ +#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ +#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include +#include +#include +#include "boost/date_time/date_generators.hpp" + +namespace boost { +namespace date_time { + + //! Formats date_generators for output + /*! Formatting of date_generators follows specific orders for the + * various types of date_generators. + * - partial_date => "dd Month" + * - nth_day_of_the_week_in_month => "nth weekday of month" + * - first_day_of_the_week_in_month => "first weekday of month" + * - last_day_of_the_week_in_month => "last weekday of month" + * - first_day_of_the_week_after => "weekday after" + * - first_day_of_the_week_before => "weekday before" + * While the order of the elements in these phrases cannot be changed, + * the elements themselves can be. Weekday and Month get their formats + * and names from the date_facet. The remaining elements are stored in + * the date_generator_formatter and can be customized upon construction + * or via a member function. The default elements are those shown in the + * examples above. + */ + template > > + class date_generator_formatter { + public: + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + typedef CharT char_type; + typedef std::basic_string string_type; + typedef std::vector collection_type; + static const char_type first_string[6]; + static const char_type second_string[7]; + static const char_type third_string[6]; + static const char_type fourth_string[7]; + static const char_type fifth_string[6]; + static const char_type last_string[5]; + static const char_type before_string[8]; + static const char_type after_string[6]; + static const char_type of_string[3]; + + enum phrase_elements {first=0, second, third, fourth, fifth, last, + before, after, of, number_of_phrase_elements}; + + //! Default format elements used + date_generator_formatter() + { + phrase_strings.push_back(string_type(first_string)); + phrase_strings.push_back(string_type(second_string)); + phrase_strings.push_back(string_type(third_string)); + phrase_strings.push_back(string_type(fourth_string)); + phrase_strings.push_back(string_type(fifth_string)); + phrase_strings.push_back(string_type(last_string)); + phrase_strings.push_back(string_type(before_string)); + phrase_strings.push_back(string_type(after_string)); + phrase_strings.push_back(string_type(of_string)); + } + + //! Constructor that allows for a custom set of phrase elements + date_generator_formatter(const string_type& first, + const string_type& second, + const string_type& third, + const string_type& fourth, + const string_type& fifth, + const string_type& last, + const string_type& before, + const string_type& after, + const string_type& of) + { + phrase_strings.push_back(string_type(first_string)); + phrase_strings.push_back(string_type(second_string)); + phrase_strings.push_back(string_type(third_string)); + phrase_strings.push_back(string_type(fourth_string)); + phrase_strings.push_back(string_type(fifth_string)); + phrase_strings.push_back(string_type(last_string)); + phrase_strings.push_back(string_type(before_string)); + phrase_strings.push_back(string_type(after_string)); + phrase_strings.push_back(string_type(of_string)); + } + + //! Replace the set of phrase elements with those contained in new_strings + /*! The order of the strings in the given collection is important. + * They must follow: + * - first, second, third, fourth, fifth, last, before, after, of. + * + * It is not necessary to send in a complete set if only a few + * elements are to be replaced as long as the correct beg_pos is used. + * + * Ex: To keep the default first through fifth elements, but replace + * the rest with a collection of: + * - "final", "prior", "following", "in". + * The beg_pos of date_generator_formatter::last would be used. + */ + void elements(const collection_type& new_strings, + phrase_elements beg_pos=first) + { + if(beg_pos < number_of_phrase_elements) { + typename collection_type::iterator itr = phrase_strings.begin(); + itr += beg_pos; + std::copy(new_strings.begin(), new_strings.end(), + itr); + //phrase_strings.begin()); + } + } + + //!Put a partial_date => "dd Month" + template + OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const partial_date_type& pd, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, pd.day()); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, pd.month()); + return next; + } + + //! Put an nth_day_of_the_week_in_month => "nth weekday of month" + template + OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const nth_kday_type& nkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[nkd.nth_week() -1]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, nkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, nkd.month()); + return next; + } + + //! Put a first_day_of_the_week_in_month => "first weekday of month" + template + OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const first_kday_type& fkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[first]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, fkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, fkd.month()); + return next; + } + + //! Put a last_day_of_the_week_in_month => "last weekday of month" + template + OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const last_kday_type& lkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[last]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, lkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, lkd.month()); + return next; + } + + //! Put a first_day_of_the_week_before => "weekday before" + template + OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const kday_before_type& fkb, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, fkb.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, phrase_strings[before]); + return next; + } + + //! Put a first_day_of_the_week_after => "weekday after" + template + OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const kday_after_type& fka, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, fka.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, phrase_strings[after]); + return next; + } + + + private: + collection_type phrase_strings; + + //! helper function to put the various member string into stream + OutItrT put_string(OutItrT next, const string_type& str) const + { + typename string_type::const_iterator itr = str.begin(); + while(itr != str.end()) { + *next = *itr; + ++itr; + ++next; + } + return next; + } + }; + + template + const typename date_generator_formatter::char_type + date_generator_formatter::first_string[6] = + {'f','i','r','s','t'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::second_string[7] = + {'s','e','c','o','n','d'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::third_string[6] = + {'t','h','i','r','d'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::fourth_string[7] = + {'f','o','u','r','t','h'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::fifth_string[6] = + {'f','i','f','t','h'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::last_string[5] = + {'l','a','s','t'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::before_string[8] = + {'b','e','f','o','r','e'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::after_string[6] = + {'a','f','t','e','r'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::of_string[3] = + {'o','f'}; +} } // namespaces + +#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ diff --git a/thirdparty/boost/date_time/date_generator_parser.hpp b/thirdparty/boost/date_time/date_generator_parser.hpp new file mode 100644 index 0000000..fc198db --- /dev/null +++ b/thirdparty/boost/date_time/date_generator_parser.hpp @@ -0,0 +1,329 @@ + +#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__ +#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/format_date_parser.hpp" +#include +#include + +namespace boost { namespace date_time { + + //! Class for date_generator parsing + /*! The elements of a date_generator "phrase" are parsed from the input stream in a + * particular order. All elements are required and the order in which they appear + * cannot change, however, the elements themselves can be changed. The default + * elements and their order are as follows: + * + * - partial_date => "dd Month" + * - nth_day_of_the_week_in_month => "nth weekday of month" + * - first_day_of_the_week_in_month => "first weekday of month" + * - last_day_of_the_week_in_month => "last weekday of month" + * - first_day_of_the_week_after => "weekday after" + * - first_day_of_the_week_before => "weekday before" + * + * Weekday and Month names and formats are handled via the date_input_facet. + * + */ + template + class date_generator_parser + { + public: + typedef std::basic_string string_type; + typedef std::istreambuf_iterator stream_itr_type; + + typedef typename date_type::month_type month_type; + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + typedef charT char_type; + static const char_type first_string[6]; + static const char_type second_string[7]; + static const char_type third_string[6]; + static const char_type fourth_string[7]; + static const char_type fifth_string[6]; + static const char_type last_string[5]; + static const char_type before_string[8]; + static const char_type after_string[6]; + static const char_type of_string[3]; + + enum phrase_elements {first=0, second, third, fourth, fifth, last, + before, after, of, number_of_phrase_elements}; + + //! Creates a date_generator_parser with the default set of "element_strings" + date_generator_parser() + { + element_strings(string_type(first_string), + string_type(second_string), + string_type(third_string), + string_type(fourth_string), + string_type(fifth_string), + string_type(last_string), + string_type(before_string), + string_type(after_string), + string_type(of_string)); + } + + //! Creates a date_generator_parser using a user defined set of element strings + date_generator_parser(const string_type& first_str, + const string_type& second_str, + const string_type& third_str, + const string_type& fourth_str, + const string_type& fifth_str, + const string_type& last_str, + const string_type& before_str, + const string_type& after_str, + const string_type& of_str) + { + element_strings(first_str, second_str, third_str, fourth_str, fifth_str, + last_str, before_str, after_str, of_str); + } + + //! Replace strings that determine nth week for generator + void element_strings(const string_type& first_str, + const string_type& second_str, + const string_type& third_str, + const string_type& fourth_str, + const string_type& fifth_str, + const string_type& last_str, + const string_type& before_str, + const string_type& after_str, + const string_type& of_str) + { + collection_type phrases; + phrases.push_back(first_str); + phrases.push_back(second_str); + phrases.push_back(third_str); + phrases.push_back(fourth_str); + phrases.push_back(fifth_str); + phrases.push_back(last_str); + phrases.push_back(before_str); + phrases.push_back(after_str); + phrases.push_back(of_str); + m_element_strings = parse_tree_type(phrases, this->first); // enum first + } + + void element_strings(const collection_type& col) + { + m_element_strings = parse_tree_type(col, this->first); // enum first + } + + + //! returns partial_date parsed from stream + template + partial_date_type + get_partial_date_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_type d(1); + month_type m(1); + facet.get(sitr, stream_end, a_ios, d); + facet.get(sitr, stream_end, a_ios, m); + + return partial_date_type(d,m); + } + + //! returns nth_kday_of_week parsed from stream + template + nth_kday_type + get_nth_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + typename nth_kday_type::week_num wn; + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + match_results mr = m_element_strings.match(sitr, stream_end); + switch(mr.current_match) { + case first : { wn = nth_kday_type::first; break; } + case second : { wn = nth_kday_type::second; break; } + case third : { wn = nth_kday_type::third; break; } + case fourth : { wn = nth_kday_type::fourth; break; } + case fifth : { wn = nth_kday_type::fifth; break; } + default: + { + throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"); + break; + } + } // week num + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + return nth_kday_type(wn, wd, m); + } + + //! returns first_kday_of_week parsed from stream + template + first_kday_type + get_first_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + extract_element(sitr, stream_end, first); // "first" element + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + + return first_kday_type(wd, m); + } + + //! returns last_kday_of_week parsed from stream + template + last_kday_type + get_last_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + extract_element(sitr, stream_end, last); // "last" element + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + + return last_kday_type(wd, m); + } + + //! returns first_kday_of_week parsed from stream + template + kday_before_type + get_kday_before_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, before);// "before" element + + return kday_before_type(wd); + } + + //! returns first_kday_of_week parsed from stream + template + kday_after_type + get_kday_after_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, after); // "after" element + + return kday_after_type(wd); + } + + private: + parse_tree_type m_element_strings; + + //! Extracts phrase element from input. Throws ios_base::failure on error. + void extract_element(stream_itr_type& sitr, + stream_itr_type& stream_end, + typename date_generator_parser::phrase_elements ele) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + match_results mr = m_element_strings.match(sitr, stream_end); + if(mr.current_match != ele) { + throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"); + } + } + + }; + + template + const typename date_generator_parser::char_type + date_generator_parser::first_string[6] = + {'f','i','r','s','t'}; + template + const typename date_generator_parser::char_type + date_generator_parser::second_string[7] = + {'s','e','c','o','n','d'}; + template + const typename date_generator_parser::char_type + date_generator_parser::third_string[6] = + {'t','h','i','r','d'}; + template + const typename date_generator_parser::char_type + date_generator_parser::fourth_string[7] = + {'f','o','u','r','t','h'}; + template + const typename date_generator_parser::char_type + date_generator_parser::fifth_string[6] = + {'f','i','f','t','h'}; + template + const typename date_generator_parser::char_type + date_generator_parser::last_string[5] = + {'l','a','s','t'}; + template + const typename date_generator_parser::char_type + date_generator_parser::before_string[8] = + {'b','e','f','o','r','e'}; + template + const typename date_generator_parser::char_type + date_generator_parser::after_string[6] = + {'a','f','t','e','r'}; + template + const typename date_generator_parser::char_type + date_generator_parser::of_string[3] = + {'o','f'}; + +} } //namespace + +#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__ + diff --git a/thirdparty/boost/date_time/date_generators.hpp b/thirdparty/boost/date_time/date_generators.hpp new file mode 100644 index 0000000..fc82b4d --- /dev/null +++ b/thirdparty/boost/date_time/date_generators.hpp @@ -0,0 +1,509 @@ +#ifndef DATE_TIME_DATE_GENERATORS_HPP__ +#define DATE_TIME_DATE_GENERATORS_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file date_generators.hpp + Definition and implementation of date algorithm templates +*/ +#include +#include +#include "boost/date_time/date.hpp" +#include "boost/date_time/compiler_config.hpp" + +namespace boost { +namespace date_time { + + //! Base class for all generators that take a year and produce a date. + /*! This class is a base class for polymorphic function objects that take + a year and produce a concrete date. + @param date_type The type representing a date. This type must + export a calender_type which defines a year_type. + */ + template + class year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::year_type year_type; + year_based_generator() {}; + virtual ~year_based_generator() {}; + virtual date_type get_date(year_type y) const = 0; + //! Returns a string for use in a POSIX time_zone string + virtual std::string to_string() const =0; + }; + + //! Generates a date by applying the year to the given month and day. + /*! + Example usage: + @code + partial_date pd(1, Jan); + partial_date pd2(70); + date d = pd.get_date(2002); //2002-Jan-01 + date d2 = pd2.get_date(2002); //2002-Mar-10 + @endcode + \ingroup date_alg + */ + template + class partial_date : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_type day_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + typedef typename duration_type::duration_rep duration_rep; + partial_date(day_type d, month_type m) : + day_(d), + month_(m) + {} + //! Partial date created from number of days into year. Range 1-366 + /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument + * exceeds range, partial_date will be created with closest in-range value. + * 60 will always be Feb29, if get_date() is called with a non-leap year + * an exception will be thrown */ + partial_date(duration_rep days) : + day_(1), // default values + month_(1) + { + date_type d1(2000,1,1); + if(days > 1) { + if(days > 366) // prevents wrapping + { + days = 366; + } + days = days - 1; + duration_type dd(days); + d1 = d1 + dd; + } + day_ = d1.day(); + month_ = d1.month(); + } + //! Return a concrete date when provided with a year specific year. + /*! Will throw an 'invalid_argument' exception if a partial_date object, + * instantiated with Feb-29, has get_date called with a non-leap year. + * Example: + * @code + * partial_date pd(29, Feb); + * pd.get_date(2003); // throws invalid_argument exception + * pg.get_date(2000); // returns 2000-2-29 + * @endcode + */ + date_type get_date(year_type y) const + { + if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) { + std::stringstream ss(""); + ss << "No Feb 29th in given year of " << y << "."; + throw std::invalid_argument(ss.str()); + //return date_type(1,1,1); // should never reach + } else { + return date_type(y, month_, day_); + } + } + date_type operator()(year_type y) const + { + return get_date(y); + //return date_type(y, month_, day_); + } + bool operator==(const partial_date& rhs) const + { + return (month_ == rhs.month_) && (day_ == rhs.day_); + } + bool operator<(const partial_date& rhs) const + { + if (month_ < rhs.month_) return true; + if (month_ > rhs.month_) return false; + //months are equal + return (day_ < rhs.day_); + } + + // added for streaming purposes + month_type month() const + { + return month_; + } + day_type day() const + { + return day_; + } + + //! Returns string suitable for use in POSIX time zone string + /*! Returns string formatted with up to 3 digits: + * Jan-01 == "0" + * Feb-29 == "58" + * Dec-31 == "365" */ + virtual std::string to_string() const + { + std::stringstream ss; + date_type d(2004, month_, day_); + unsigned short c = d.day_of_year(); + c--; // numbered 0-365 while day_of_year is 1 based... + ss << c; + return ss.str(); + } + private: + day_type day_; + month_type month_; + }; + + + //! Useful generator functor for finding holidays + /*! Based on the idea in Cal. Calc. for finding holidays that are + * the 'first Monday of September'. When instantiated with + * 'fifth' kday of month, the result will be the last kday of month + * which can be the fourth or fifth depending on the structure of + * the month. + * + * The algorithm here basically guesses for the first + * day of the month. Then finds the first day of the correct + * type. That is, if the first of the month is a Tuesday + * and it needs Wenesday then we simply increment by a day + * and then we can add the length of a week until we get + * to the 'nth kday'. There are probably more efficient + * algorithms based on using a mod 7, but this one works + * reasonably well for basic applications. + * \ingroup date_alg + */ + template + class nth_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + enum week_num {first=1, second, third, fourth, fifth}; + nth_kday_of_month(week_num week_no, + day_of_week_type dow, + month_type m) : + month_(m), + wn_(week_no), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type y) const + { + date_type d(y, month_, 1); //first day of month + duration_type one_day(1); + duration_type one_week(7); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + int week = 1; + while (week < wn_) { + d = d + one_week; + week++; + } + // remove wrapping to next month behavior + if(d.month() != month_) { + d = d - one_week; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + week_num nth_week() const + { + return wn_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + const char* nth_week_as_str() const + { + return nth_as_str(wn_); + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */ + virtual std::string to_string() const + { + std::stringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << static_cast(wn_) << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + week_num wn_; + day_of_week_type dow_; + }; + + //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5. + BOOST_DATE_TIME_DECL const char* nth_as_str(int n); + + //! Useful generator functor for finding holidays and daylight savings + /*! Similar to nth_kday_of_month, but requires less paramters + * \ingroup date_alg + */ + template + class first_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the first 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + first_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const + { + date_type d(year, month_,1); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */ + virtual std::string to_string() const + { + std::stringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 1 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + + //! Calculate something like Last Sunday of January + /*! Useful generator functor for finding holidays and daylight savings + * Get the last day of the month and then calculate the difference + * to the last previous day. + * @param date_type A date class that exports day_of_week, month_type, etc. + * \ingroup date_alg + */ + template + class last_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the date spec like last 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + last_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const + { + date_type d(year, month_, calendar_type::end_of_month_day(year,month_)); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */ + virtual std::string to_string() const + { + std::stringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 5 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + //! Calculate something like "First Sunday after Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_after firstkdayafter; + firstkdayafter fkaf(Monday); + fkaf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_after + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_after(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day + one_day; + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculate something like "First Sunday before Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_before firstkdaybefore; + firstkdaybefore fkbf(Monday); + fkbf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_before + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_before(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day - one_day; + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculates the number of days until the next weekday + /*! Calculates the number of days until the next weekday. + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 2 days */ + template + inline + typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.is_negative()){ + wks = duration_type(7); + } + return dd + wks; + } + + //! Calculates the number of days since the previous weekday + /*! Calculates the number of days since the previous weekday + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 5 days. The answer will be a positive + * number because Tuesday is 5 days before Sunday, not -5 days before. */ + template + inline + typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.days() > 0){ + wks = duration_type(7); + } + // we want a number of days, not an offset. The value returned must + // be zero or larger. + return (-dd + wks); + } + + //! Generates a date object representing the date of the following weekday from the given date + /*! Generates a date object representing the date of the following + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-11. */ + template + inline + date_type next_weekday(const date_type& d, const weekday_type& wd) + { + return d + days_until_weekday(d, wd); + } + + //! Generates a date object representing the date of the previous weekday from the given date + /*! Generates a date object representing the date of the previous + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-4. */ + template + inline + date_type previous_weekday(const date_type& d, const weekday_type& wd) + { + return d - days_before_weekday(d, wd); + } + +} } //namespace date_time + + + + +#endif + diff --git a/thirdparty/boost/date_time/date_iterator.hpp b/thirdparty/boost/date_time/date_iterator.hpp new file mode 100644 index 0000000..8b55e14 --- /dev/null +++ b/thirdparty/boost/date_time/date_iterator.hpp @@ -0,0 +1,101 @@ +#ifndef DATE_ITERATOR_HPP___ +#define DATE_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include + +namespace boost { +namespace date_time { + //! An iterator over dates with varying resolution (day, week, month, year, etc) + enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions}; + + //! Base date iterator type + /*! This class provides the skeleton for the creation of iterators. + * New and interesting interators can be created by plugging in a new + * function that derives the next value from the current state. + * generation of various types of -based information. + * + * Template Parameters + * + * date_type + * + * The date_type is a concrete date_type. The date_type must + * define a duration_type and a calendar_type. + */ + template + class date_itr_base { + // works, but benefit unclear at the moment + // class date_itr_base : public std::iterator{ + public: + typedef typename date_type::duration_type duration_type; + typedef date_type value_type; + typedef std::input_iterator_tag iterator_category; + + date_itr_base(date_type d) : current_(d) {} + virtual ~date_itr_base() {}; + date_itr_base& operator++() + { + current_ = current_ + get_offset(current_); + return *this; + } + date_itr_base& operator--() + { + current_ = current_ + get_neg_offset(current_); + return *this; + } + virtual duration_type get_offset(const date_type& current) const=0; + virtual duration_type get_neg_offset(const date_type& current) const=0; + date_type operator*() {return current_;}; + date_type* operator->() {return ¤t_;}; + bool operator< (const date_type& d) {return current_ < d;} + bool operator<= (const date_type& d) {return current_ <= d;} + bool operator> (const date_type& d) {return current_ > d;} + bool operator>= (const date_type& d) {return current_ >= d;} + bool operator== (const date_type& d) {return current_ == d;} + bool operator!= (const date_type& d) {return current_ != d;} + private: + date_type current_; + }; + + //! Overrides the base date iterator providing hook for functors + /* + * offset_functor + * + * The offset functor must define a get_offset function that takes the + * current point in time and calculates and offset. + * + */ + template + class date_itr : public date_itr_base { + public: + typedef typename date_type::duration_type duration_type; + date_itr(date_type d, int factor=1) : + date_itr_base(d), + of_(factor) + {} + private: + virtual duration_type get_offset(const date_type& current) const + { + return of_.get_offset(current); + } + virtual duration_type get_neg_offset(const date_type& current) const + { + return of_.get_neg_offset(current); + } + offset_functor of_; + }; + + + +} } //namespace date_time + + +#endif diff --git a/thirdparty/boost/date_time/date_names_put.hpp b/thirdparty/boost/date_time/date_names_put.hpp new file mode 100644 index 0000000..f0f6a92 --- /dev/null +++ b/thirdparty/boost/date_time/date_names_put.hpp @@ -0,0 +1,320 @@ +#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___ +#define DATE_TIME_DATE_NAMES_PUT_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/date_defs.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include "boost/lexical_cast.hpp" +#include + + +namespace boost { +namespace date_time { + + //! Output facet base class for gregorian dates. + /*! This class is a base class for date facets used to localize the + * names of months and the names of days in the week. + * + * Requirements of Config + * - define an enumeration month_enum that enumerates the months. + * The enumeration should be '1' based eg: Jan==1 + * - define as_short_string and as_long_string + * + * (see langer & kreft p334). + * + */ + template > + class date_names_put : public std::locale::facet + { + public: + date_names_put() {}; + typedef OutputIterator iter_type; + typedef typename Config::month_type month_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + //typedef typename Config::format_type format_type; + typedef std::basic_string string_type; + typedef charT char_type; + static const char_type default_special_value_names[3][17]; + static const char_type separator[2]; + + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + void put_special_value(iter_type& oitr, special_value_enum sv) const + { + do_put_special_value(oitr, sv); + } + void put_month_short(iter_type& oitr, month_enum moy) const + { + do_put_month_short(oitr, moy); + } + void put_month_long(iter_type& oitr, month_enum moy) const + { + do_put_month_long(oitr, moy); + } + void put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_short(oitr, wd); + } + void put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_long(oitr, wd); + } + bool has_date_sep_chars() const + { + return do_has_date_sep_chars(); + } + void year_sep_char(iter_type& oitr) const + { + do_year_sep_char(oitr); + } + //! char between year-month + void month_sep_char(iter_type& oitr) const + { + do_month_sep_char(oitr); + } + //! Char to separate month-day + void day_sep_char(iter_type& oitr) const + { + do_day_sep_char(oitr); + } + //! Determines the order to put the date elements + ymd_order_spec date_order() const + { + return do_date_order(); + } + //! Determines if month is displayed as integer, short or long string + month_format_spec month_format() const + { + return do_month_format(); + } + + protected: + //! Default facet implementation uses month_type defaults + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_short_string(c)); + } + //! Default facet implementation uses month_type defaults + virtual void do_put_month_long(iter_type& oitr, + month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_long_string(c)); + } + //! Default facet implementation for special value types + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin + string_type s(default_special_value_names[sv]); + put_string(oitr, s); + } + } + virtual void do_put_weekday_short(iter_type&, weekday_enum) const + { + } + virtual void do_put_weekday_long(iter_type&, weekday_enum) const + { + } + virtual bool do_has_date_sep_chars() const + { + return true; + } + virtual void do_year_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + string_type s(separator); //put in '-' + put_string(oitr, s); + } + //! Default for date order + virtual ymd_order_spec do_date_order() const + { + return ymd_order_iso; + } + //! Default month format + virtual month_format_spec do_month_format() const + { + return month_as_short_string; + } + void put_string(iter_type& oi, const charT* const s) const + { + string_type s1(boost::lexical_cast(s)); + typename string_type::iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + void put_string(iter_type& oi, const string_type& s1) const + { + typename string_type::const_iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + }; + + template + const typename date_names_put::char_type + date_names_put::default_special_value_names[3][17] = { + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}, + {'-','i','n','f','i','n','i','t','y'}, + {'+','i','n','f','i','n','i','t','y'} }; + + template + const typename date_names_put::char_type + date_names_put::separator[2] = + {'-', '\0'} ; + + + //! Generate storage location for a std::locale::id + template + std::locale::id date_names_put::id; + + //! A date name output facet that takes an array of char* to define strings + template > + class all_date_names_put : public date_names_put + { + public: + all_date_names_put(const charT* const month_short_names[], + const charT* const month_long_names[], + const charT* const special_value_names[], + const charT* const weekday_short_names[], + const charT* const weekday_long_names[], + charT separator_char = '-', + ymd_order_spec order_spec = ymd_order_iso, + month_format_spec month_format = month_as_short_string) : + month_short_names_(month_short_names), + month_long_names_(month_long_names), + special_value_names_(special_value_names), + weekday_short_names_(weekday_short_names), + weekday_long_names_(weekday_long_names), + order_spec_(order_spec), + month_format_spec_(month_format) + { + separator_char_[0] = separator_char; + separator_char_[1] = '\0'; + + }; + typedef OutputIterator iter_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + + const charT* const* get_short_month_names() const + { + return month_short_names_; + } + const charT* const* get_long_month_names() const + { + return month_long_names_; + } + const charT* const* get_special_value_names() const + { + return special_value_names_; + } + const charT* const* get_short_weekday_names()const + { + return weekday_short_names_; + } + const charT* const* get_long_weekday_names()const + { + return weekday_long_names_; + } + + protected: + //! Generic facet that takes array of chars + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_short_names_[moy-1]); + } + //! Long month names + virtual void do_put_month_long(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_long_names_[moy-1]); + } + //! Special values names + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + this->put_string(oitr, special_value_names_[sv]); + } + virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_short_names_[wd]); + } + virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_long_names_[wd]); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Set the date ordering + virtual ymd_order_spec do_date_order() const + { + return order_spec_; + } + //! Set the date ordering + virtual month_format_spec do_month_format() const + { + return month_format_spec_; + } + + private: + const charT* const* month_short_names_; + const charT* const* month_long_names_; + const charT* const* special_value_names_; + const charT* const* weekday_short_names_; + const charT* const* weekday_long_names_; + charT separator_char_[2]; + ymd_order_spec order_spec_; + month_format_spec month_format_spec_; + }; + +} } //namespace boost::date_time + +#endif //BOOST_NO_STD_LOCALE + +#endif diff --git a/thirdparty/boost/date_time/date_parsing.hpp b/thirdparty/boost/date_time/date_parsing.hpp new file mode 100644 index 0000000..5db3062 --- /dev/null +++ b/thirdparty/boost/date_time/date_parsing.hpp @@ -0,0 +1,299 @@ +#ifndef _DATE_TIME_DATE_PARSING_HPP___ +#define _DATE_TIME_DATE_PARSING_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/tokenizer.hpp" +#include "boost/lexical_cast.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include +#include +#include + +#if defined(BOOST_NO_STD_LOCALE) +#include // ::tolower(int) +#else +#include // std::tolower(char, locale) +#endif + +namespace boost { +namespace date_time { + + //! A function to replace the std::transform( , , ,tolower) construct + /*! This function simply takes a string, and changes all the characters + * in that string to lowercase (according to the default system locale). + * In the event that a compiler does not support locales, the old + * C style tolower() is used. + */ + inline + std::string + convert_to_lower(const std::string& inp) { + std::string tmp; + unsigned i = 0; +#if defined(BOOST_NO_STD_LOCALE) + while(i < inp.length()) { + tmp += static_cast(std::tolower(inp.at(i++))); +#else + static const std::locale loc(std::locale::classic()); + while(i < inp.length()) { + // tolower and others were brought in to std for borland >= v564 + // in compiler_config.hpp + std::string::value_type c(inp.at(i++)); + tmp += std::tolower(c, loc); +#endif + + } + return tmp; + } + + //! Helper function for parse_date. + /* Used by-value parameter because we change the string and may + * want to preserve the original argument */ + template + unsigned short + month_str_to_ushort(std::string s) { + if((s.at(0) >= '0') && (s.at(0) <= '9')) { + return boost::lexical_cast(s); + } + else { + s = convert_to_lower(s); + typename month_type::month_map_ptr_type ptr = month_type::get_month_map_ptr(); + typename month_type::month_map_type::iterator iter = ptr->find(s); + if(iter != ptr->end()) { // required for STLport + return iter->second; + } + } + return 13; // intentionally out of range - name not found + } + + //! Find index of a string in either of 2 arrays + /*! find_match searches both arrays for a match to 's'. Indexing of the + * arrays is from 0 to 'limit'. The index of the match is returned. + * Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2. + * 'limit' can be sent in with: greg_month::max(), + * greg_weekday::max() or date_time::NumSpecialValues */ + template + short find_match(const charT* const* short_names, + const charT* const* long_names, + short limit, + const std::basic_string& s) { + for(short i = 0; i <= limit; ++i){ + if(short_names[i] == s || long_names[i] == s){ + return i; + } + } + return static_cast(limit + 1); // not-found, return a value out of range + } + + //! Generic function to parse a delimited date (eg: 2002-02-10) + /*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or + * "2003-Feburary-10" + * The order in which the Month, Day, & Year appear in the argument + * string can be accomodated by passing in the appropriate ymd_order_spec + */ + template + date_type + parse_date(const std::string& s, int order_spec = ymd_order_iso) { + std::string spec_str(""); + if(order_spec == ymd_order_iso) { + spec_str = "ymd"; + } + else if(order_spec == ymd_order_dmy) { + spec_str = "dmy"; + } + else { // (order_spec == ymd_order_us) + spec_str = "mdy"; + } + + typedef typename date_type::year_type year_type; + typedef typename date_type::month_type month_type; + unsigned pos = 0; + unsigned short year(0), month(0), day(0); + typedef typename std::basic_string::traits_type traits_type; + typedef boost::char_separator char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + // may need more delimiters, these work for the regression tests + const char sep_char[] = {',','-','.',' ','/','\0'}; + char_separator_type sep(sep_char); + tokenizer tok(s,sep); + for(tokenizer_iterator beg=tok.begin(); + beg!=tok.end() && pos < spec_str.size(); + ++beg, ++pos) { + switch(spec_str.at(pos)) { + case 'y': + { + year = boost::lexical_cast(*beg); + break; + } + case 'm': + { + month = month_str_to_ushort(*beg); + break; + } + case 'd': + { + day = boost::lexical_cast(*beg); + break; + } + } //switch + } + return date_type(year, month, day); + } + + //! Generic function to parse undelimited date (eg: 20020201) + template + date_type + parse_undelimited_date(const std::string& s) { + int offsets[] = {4,2,2}; + int pos = 0; + typedef typename date_type::year_type year_type; + //typename date_type::ymd_type ymd((year_type::min)(),1,1); + unsigned short y = 0, m = 0, d = 0; + + /* The two bool arguments state that parsing will not wrap + * (only the first 8 characters will be parsed) and partial + * strings will not be parsed. + * Ex: + * "2005121" will parse 2005 & 12, but not the "1" */ + boost::offset_separator osf(offsets, offsets+3, false, false); + + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer_type; + tokenizer_type tok(s, osf); + for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) { + unsigned short i = boost::lexical_cast(*ti); + switch(pos) { + case 0: y = i; break; + case 1: m = i; break; + case 2: d = i; break; + } + pos++; + } + return date_type(y,m,d); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a char[] or string. All elements are + * used in output string */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type& end, + char) + { + std::stringstream ss(""); + while(beg != end) { + ss << *beg++; + } + return parse_date(ss.str()); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Returns the first string found in the stream referenced by the + * begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type& end, + std::string) + { + return parse_date(*beg); + } + + /* I believe the wchar stuff would be best elsewhere, perhaps in + * parse_date<>()? In the mean time this gets us started... */ + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a wstring. All elements are + * used in output string */ + template + inline + date_type from_stream_type(iterator_type& beg, + iterator_type& end, + wchar_t) + { + std::stringstream ss(""); + while(beg != end) { +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + ss << std::use_facet >(std::locale()).narrow(*beg++, 'X'); // 'X' will cause exception to be thrown +#else + ss << ss.narrow(*beg++, 'X'); +#endif + } + return parse_date(ss.str()); + } +#ifndef BOOST_NO_STD_WSTRING + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the first wstring found in the stream + * referenced by the begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type& end, + std::wstring) { + std::wstring ws = *beg; + std::stringstream ss(""); + std::wstring::iterator wsb = ws.begin(), wse = ws.end(); + while(wsb != wse) { +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + ss << std::use_facet >(std::locale()).narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown +#else + ss << ss.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown +#endif + } + return parse_date(ss.str()); + } +#endif // BOOST_NO_STD_WSTRING +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! function called by wrapper functions: date_period_from_(w)string() + template + period + from_simple_string_type(const std::basic_string& s){ + typedef typename std::basic_string::traits_type traits_type; + typedef typename boost::char_separator char_separator; + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + const charT sep_list[4] = {'[','/',']','\0'}; + char_separator sep(sep_list); + tokenizer tokens(s, sep); + typename tokenizer::iterator tok_it = tokens.begin(); + std::basic_string date_string = *tok_it; + // get 2 string iterators and generate a date from them + typename std::basic_string::iterator date_string_start = date_string.begin(), + date_string_end = date_string.end(); + typedef typename std::iterator_traits::iterator>::value_type value_type; + date_type d1 = from_stream_type(date_string_start, date_string_end, value_type()); + date_string = *(++tok_it); // next token + date_string_start = date_string.begin(), date_string_end = date_string.end(); + date_type d2 = from_stream_type(date_string_start, date_string_end, value_type()); + return period(d1, d2); + } +#endif + +} } //namespace date_time + + + + +#endif + diff --git a/thirdparty/boost/date_time/dst_rules.hpp b/thirdparty/boost/date_time/dst_rules.hpp new file mode 100644 index 0000000..f837140 --- /dev/null +++ b/thirdparty/boost/date_time/dst_rules.hpp @@ -0,0 +1,391 @@ +#ifndef DATE_TIME_DST_RULES_HPP__ +#define DATE_TIME_DST_RULES_HPP__ + +/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file dst_rules.hpp + Contains template class to provide static dst rule calculations +*/ + +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/date_defs.hpp" +#include + +namespace boost { + namespace date_time { + + enum time_is_dst_result {is_not_in_dst, is_in_dst, + ambiguous, invalid_time_label}; + + + //! Dynamic class used to caluclate dst transition information + template + class dst_calculator + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + //! Check the local time offset when on dst start day + /*! On this dst transition, the time label between + * the transition boundary and the boudary + the offset + * are invalid times. If before the boundary then still + * not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_start_offset_minutes Local day offset for start of dst + *@param dst_length_minutes Number of minutes to adjust clock forward + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_start_day(const time_duration_type& time_of_day, + unsigned int dst_start_offset_minutes, + long dst_length_minutes) + { + //std::cout << "here" << std::endl; + if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) { + return is_not_in_dst; + } + long offset = dst_start_offset_minutes + dst_length_minutes; + if (time_of_day >= time_duration_type(0,offset,0)) { + return is_in_dst; + } + return invalid_time_label; + } + + //! Check the local time offset when on the last day of dst + /*! This is the calculation for the DST end day. On that day times + * prior to the conversion time - dst_length (1 am in US) are still + * in dst. Times between the above and the switch time are + * ambiguous. Times after the start_offset are not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_end_offset_minutes Local time of day for end of dst + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_end_day(const time_duration_type& time_of_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in US this will be 60 so offset in day is 1,0,0 + int offset = dst_end_offset_minutes-dst_length_minutes; + if (time_of_day < time_duration_type(0,offset,0)) { + return is_in_dst; + } + if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) { + return is_not_in_dst; + } + return ambiguous; + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset Time offset within day for dst boundary + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset Time offset within day given in dst for dst boundary + * @param dst_length lenght of dst adjusment + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + const time_duration_type& dst_start_offset, + const date_type& dst_end_day, + const time_duration_type& dst_end_offset, + const time_duration_type& dst_length_minutes) + { + unsigned int start_minutes = + dst_start_offset.hours() * 60 + dst_start_offset.minutes(); + unsigned int end_minutes = + dst_end_offset.hours() * 60 + dst_end_offset.minutes(); + long length_minutes = + dst_length_minutes.hours() * 60 + dst_length_minutes.minutes(); + + return local_is_dst(current_day, time_of_day, + dst_start_day, start_minutes, + dst_end_day, end_minutes, + length_minutes); + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset_minutes Offset within day for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset_minutes Offset within day given in dst for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_length_minutes Length of dst adjusment (eg: 60 for US) + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + unsigned int dst_start_offset_minutes, + const date_type& dst_end_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in northern hemisphere dst is in the middle of the year + if (dst_start_day < dst_end_day) { + if ((current_day > dst_start_day) && (current_day < dst_end_day)) { + return is_in_dst; + } + if ((current_day < dst_start_day) || (current_day > dst_end_day)) { + return is_not_in_dst; + } + } + else {//southern hemisphere dst is at begining /end of year + if ((current_day < dst_start_day) && (current_day > dst_end_day)) { + return is_not_in_dst; + } + if ((current_day > dst_start_day) || (current_day < dst_end_day)) { + return is_in_dst; + } + } + + if (current_day == dst_start_day) { + return process_local_dst_start_day(time_of_day, + dst_start_offset_minutes, + dst_length_minutes); + } + + if (current_day == dst_end_day) { + return process_local_dst_end_day(time_of_day, + dst_end_offset_minutes, + dst_length_minutes); + } + //you should never reach this statement + return invalid_time_label; + } + + }; + + + //! Compile-time configurable daylight savings time calculation engine + /* This template provides the ability to configure a daylight savings + * calculation at compile time covering all the cases. Unfortunately + * because of the number of dimensions related to daylight savings + * calculation the number of parameters is high. In addition, the + * start and end transition rules are complex types that specify + * an algorithm for calculation of the starting day and ending + * day of daylight savings time including the month and day + * specifications (eg: last sunday in October). + * + * @param date_type A type that represents dates, typically gregorian::date + * @param time_duration_type Used for the offset in the day calculations + * @param dst_traits A set of traits that define the rules of dst + * calculation. The dst_trait must include the following: + * start_rule_functor - Rule to calculate the starting date of a + * dst transition (eg: last_kday_of_month). + * start_day - static function that returns month of dst start for + * start_rule_functor + * start_month -static function that returns day or day of week for + * dst start of dst + * end_rule_functor - Rule to calculate the end of dst day. + * end_day - static fucntion that returns end day for end_rule_functor + * end_month - static function that returns end month for end_rule_functor + * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U. + * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U. + * dst_length_minutes - number of minutes that dst shifts clock + */ + template + class dst_calc_engine + { + public: + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start, + dst_traits::dst_start_offset_minutes(), + dst_end, + dst_traits::dst_end_offset_minutes(), + dst_traits::dst_shift_length_minutes()); + + } + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00) + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0); + } + + static date_type local_dst_start_day(year_type year) + { + return dst_traits::local_dst_start_day(year); + } + + static date_type local_dst_end_day(year_type year) + { + return dst_traits::local_dst_end_day(year); + } + + + }; + + //! Depricated: Class to calculate dst boundaries for US time zones + /* Use dst_calc_engine instead. + * In 2007 US/Canada DST rules changed + * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time). + */ + template //1 hour == 60 min in US + class us_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef date_time::last_kday_of_month lkday; + typedef date_time::first_kday_of_month fkday; + typedef date_time::nth_kday_of_month nkday; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start,dst_start_offset_minutes, + dst_end, dst_start_offset_minutes, + dst_length_minutes); + + } + + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + static date_type local_dst_start_day(year_type year) + { + if (year >= year_type(2007)) { + //second sunday in march + nkday ssim(nkday::second, Sunday, gregorian::Mar); + return ssim.get_date(year); + } else { + //first sunday in april + fkday fsia(Sunday, gregorian::Apr); + return fsia.get_date(year); + } + } + + static date_type local_dst_end_day(year_type year) + { + if (year >= year_type(2007)) { + //first sunday in november + fkday fsin(Sunday, gregorian::Nov); + return fsin.get_date(year); + } else { + //last sunday in october + lkday lsio(Sunday, gregorian::Oct); + return lsio.get_date(year); + } + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_length_minutes,0); + } + + private: + + + }; + + //! Used for local time adjustments in places that don't use dst + template + class null_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + + //! Calculates if the given local time is dst or not + /*! @retval Always is_not_in_dst since this is for zones without dst + */ + static time_is_dst_result local_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + //! Calculates if the given utc time is in dst + static time_is_dst_result utc_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + static bool is_dst_boundary_day(date_type d) + { + return false; + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,0,0); + } + + }; + + + } } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/dst_transition_generators.hpp b/thirdparty/boost/date_time/dst_transition_generators.hpp new file mode 100644 index 0000000..d583112 --- /dev/null +++ b/thirdparty/boost/date_time/dst_transition_generators.hpp @@ -0,0 +1,75 @@ +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + */ +#ifndef DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__ +#define DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__ + + + +namespace boost { +namespace date_time { + + //! Defines base interface for calculating start and end date of daylight savings + template + class dst_day_calc_rule + { + public: + typedef typename date_type::year_type year_type; + virtual ~dst_day_calc_rule() {}; + virtual date_type start_day(year_type y) const=0; + virtual std::string start_rule_as_string() const=0; + virtual date_type end_day(year_type y) const=0; + virtual std::string end_rule_as_string() const=0; + + }; + + //! Canonical form for a class that provides day rule calculation + /*! This class is used to generate specific sets of dst rules + * + *@param spec Provides a specifiction of the function object types used + * to generate start and end days of daylight savings as well + * as the date type. + */ + template + class day_calc_dst_rule : public dst_day_calc_rule + { + public: + typedef typename spec::date_type date_type; + typedef typename date_type::year_type year_type; + typedef typename spec::start_rule start_rule; + typedef typename spec::end_rule end_rule; + day_calc_dst_rule(start_rule dst_start, + end_rule dst_end) : + dst_start_(dst_start), + dst_end_(dst_end) + {} + virtual date_type start_day(year_type y) const + { + return dst_start_.get_date(y); + } + virtual std::string start_rule_as_string() const + { + return dst_start_.to_string(); + } + virtual date_type end_day(year_type y) const + { + return dst_end_.get_date(y); + } + virtual std::string end_rule_as_string() const + { + return dst_end_.to_string(); + } + private: + start_rule dst_start_; + end_rule dst_end_; + }; + + +} }//namespace + + + +#endif diff --git a/thirdparty/boost/date_time/filetime_functions.hpp b/thirdparty/boost/date_time/filetime_functions.hpp new file mode 100644 index 0000000..24178e1 --- /dev/null +++ b/thirdparty/boost/date_time/filetime_functions.hpp @@ -0,0 +1,78 @@ +#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__ +#define DATE_TIME_FILETIME_FUNCTIONS_HPP__ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file filetime_functions.hpp + * Function(s) for converting between a FILETIME structure and a + * time object. This file is only available on systems that have + * BOOST_HAS_FTIME defined. + */ + +#include +#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME +#include +#include +#include + + +namespace boost { +namespace date_time { + + + //! Create a time object from an initialized FILETIME struct. + /*! Create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the FILETIME's sub second value + * will be truncated. Nanosecond resolution has no truncation. */ + template + inline + time_type time_from_ftime(const FILETIME& ft){ + typedef typename time_type::date_type date_type; + typedef typename time_type::date_duration_type date_duration_type; + typedef typename time_type::time_duration_type time_duration_type; + + /* OFFSET is difference between 1970-Jan-01 & 1601-Jan-01 + * in 100-nanosecond intervals */ + uint64_t c1 = 27111902UL; + uint64_t c2 = 3577643008UL; // issues warning without 'UL' + const uint64_t OFFSET = (c1 << 32) + c2; + const long sec_pr_day = 86400; // seconds per day + + uint64_t filetime = ft.dwHighDateTime; + filetime <<= 32; + filetime += ft.dwLowDateTime; + filetime -= OFFSET; // filetime is now 100-nanos since 1970-Jan-01 + + uint64_t sec = filetime / 10000000; +#if defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG) + uint64_t sub_sec = (filetime % 10000000) * 100; // nanoseconds +#else + uint64_t sub_sec = (filetime % 10000000) / 10; // truncate to microseconds +#endif + + // split sec into usable chunks: days, hours, minutes, & seconds + long _d = sec / sec_pr_day; + long tmp = sec % sec_pr_day; + long _h = tmp / 3600; // sec_pr_hour + tmp %= 3600; + long _m = tmp / 60; // sec_pr_min + tmp %= 60; + long _s = tmp; // seconds + + date_duration_type dd(_d); + date_type d = date_type(1970, Jan, 01) + dd; + return time_type(d, time_duration_type(_h, _m, _s, sub_sec)); + } + +}} // boost::date_time + +#endif // BOOST_HAS_FTIME + +#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__ diff --git a/thirdparty/boost/date_time/format_date_parser.hpp b/thirdparty/boost/date_time/format_date_parser.hpp new file mode 100644 index 0000000..9e292a8 --- /dev/null +++ b/thirdparty/boost/date_time/format_date_parser.hpp @@ -0,0 +1,731 @@ + +#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__ +#define DATE_TIME_FORMAT_DATE_PARSER_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/lexical_cast.hpp" +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/strings_from_facet.hpp" +#include "boost/date_time/special_values_parser.hpp" +#include +#include + +namespace boost { namespace date_time { + +//! Helper function for parsing fixed length strings into integers +/*! Will consume 'length' number of characters from stream. Consumed + * character are transfered to parse_match_result struct. + * Returns '-1' if no number can be parsed or incorrect number of + * digits in stream. */ +template +inline +int_type +fixed_string_to_int(std::istreambuf_iterator& itr, + std::istreambuf_iterator& stream_end, + parse_match_result& mr, + unsigned int length, + const charT& fill_char) +{ + //typedef std::basic_string string_type; + unsigned int j = 0; + //string_type s; + while (j < length && itr != stream_end && + (std::isdigit(*itr) || *itr == fill_char)) { + if(*itr == fill_char) { + /* Since a fill_char can be anything, we convert it to a zero. + * lexical_cast will behave predictably when zero is used as fill. */ + mr.cache += ('0'); + } + else { + mr.cache += (*itr); + } + itr++; + j++; + } + int_type i = -1; + // mr.cache will hold leading zeros. size() tells us when input is too short. + if(mr.cache.size() < length) { + return i; + } + try { + i = boost::lexical_cast(mr.cache); + }catch(bad_lexical_cast blc){ + // we want to return -1 if the cast fails so nothing to do here + } + return i; +} + +//! Helper function for parsing fixed length strings into integers +/*! Will consume 'length' number of characters from stream. Consumed + * character are transfered to parse_match_result struct. + * Returns '-1' if no number can be parsed or incorrect number of + * digits in stream. */ +template +inline +int_type +fixed_string_to_int(std::istreambuf_iterator& itr, + std::istreambuf_iterator& stream_end, + parse_match_result& mr, + unsigned int length) +{ + return fixed_string_to_int(itr, stream_end, mr, length, '0'); +} + +//! Helper function for parsing varied length strings into integers +/*! Will consume 'max_length' characters from stream only if those + * characters are digits. Returns '-1' if no number can be parsed. + * Will not parse a number preceeded by a '+' or '-'. */ +template +inline +int_type +var_string_to_int(std::istreambuf_iterator& itr, + std::istreambuf_iterator& /* stream_end */, + unsigned int max_length) +{ + typedef std::basic_string string_type; + unsigned int j = 0; + string_type s; + while ((j < max_length) && std::isdigit(*itr)) { + s += (*itr); + itr++; + j++; + } + int_type i = -1; + if(s.length() != 0) { + i = boost::lexical_cast(s); + } + return i; +} + + +//! Class with generic date parsing using a format string +/*! The following is the set of recognized format specifiers + - %a - Short weekday name + - %A - Long weekday name + - %b - Abbreviated month name + - %B - Full month name + - %d - Day of the month as decimal 01 to 31 + - %j - Day of year as decimal from 001 to 366 + - %m - Month name as a decimal 01 to 12 + - %U - Week number 00 to 53 with first Sunday as the first day of week 1? + - %w - Weekday as decimal number 0 to 6 where Sunday == 0 + - %W - Week number 00 to 53 where Monday is first day of week 1 + - %x - facet default date representation + - %y - Year without the century - eg: 04 for 2004 + - %Y - Year with century + + The weekday specifiers (%a and %A) do not add to the date construction, + but they provide a way to skip over the weekday names for formats that + provide them. + + todo -- Another interesting feature that this approach could provide is + an option to fill in any missing fields with the current values + from the clock. So if you have %m-%d the parser would detect + the missing year value and fill it in using the clock. + + todo -- What to do with the %x. %x in the classic facet is just bad... + + */ +template +class format_date_parser +{ + public: + typedef std::basic_string string_type; + typedef std::basic_ostringstream stringstream_type; + typedef std::istreambuf_iterator stream_itr_type; + typedef typename string_type::const_iterator const_itr; + typedef typename date_type::year_type year_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::duration_type duration_type; + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_of_year_type day_of_year_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > input_collection_type; + + // TODO sv_parser uses its default constructor - write the others + + format_date_parser(const string_type& format_str, + const input_collection_type& month_short_names, + const input_collection_type& month_long_names, + const input_collection_type& weekday_short_names, + const input_collection_type& weekday_long_names) : + m_format(format_str), + m_month_short_names(month_short_names, 1), + m_month_long_names(month_long_names, 1), + m_weekday_short_names(weekday_short_names), + m_weekday_long_names(weekday_long_names) + {} + + format_date_parser(const string_type& format_str, + const std::locale& locale) : + m_format(format_str), + m_month_short_names(gather_month_strings(locale), 1), + m_month_long_names(gather_month_strings(locale, false), 1), + m_weekday_short_names(gather_weekday_strings(locale)), + m_weekday_long_names(gather_weekday_strings(locale, false)) + {} + + format_date_parser(const format_date_parser& fdp) + { + this->m_format = fdp.m_format; + this->m_month_short_names = fdp.m_month_short_names; + this->m_month_long_names = fdp.m_month_long_names; + this->m_weekday_short_names = fdp.m_weekday_short_names; + this->m_weekday_long_names = fdp.m_weekday_long_names; + } + + string_type format() const + { + return m_format; + } + + void format(string_type format_str) + { + m_format = format_str; + } + + void short_month_names(const input_collection_type& month_names) + { + m_month_short_names = parse_tree_type(month_names, 1); + } + void long_month_names(const input_collection_type& month_names) + { + m_month_long_names = parse_tree_type(month_names, 1); + } + void short_weekday_names(const input_collection_type& weekday_names) + { + m_weekday_short_names = parse_tree_type(weekday_names); + } + void long_weekday_names(const input_collection_type& weekday_names) + { + m_weekday_long_names = parse_tree_type(weekday_names); + } + + date_type + parse_date(const string_type& value, + const string_type& format_str, + const special_values_parser& sv_parser) const + { + stringstream_type ss; + ss << value; + stream_itr_type sitr(ss); + stream_itr_type stream_end; + return parse_date(sitr, stream_end, format_str, sv_parser); + } + + date_type + parse_date(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + const special_values_parser& sv_parser) const + { + return parse_date(sitr, stream_end, m_format, sv_parser); + } + + /*! Of all the objects that the format_date_parser can parse, only a + * date can be a special value. Therefore, only parse_date checks + * for special_values. */ + date_type + parse_date(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + const special_values_parser& sv_parser) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + charT current_char = *sitr; + + short year(0), month(0), day(0), day_of_year(0);// wkday(0); + /* Initialized the following to their minimum values. These intermediate + * objects are used so we get specific exceptions when part of the input + * is unparsable. + * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/ + year_type t_year(1400); + month_type t_month(1); + day_type t_day(1); + day_of_week_type wkday(0); + + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + switch(*itr) { + case 'a': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + match_results mr = m_weekday_short_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + wkday = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'A': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + match_results mr = m_weekday_long_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + wkday = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'b': + { + match_results mr = m_month_short_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(mr.current_match); + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'B': + { + match_results mr = m_month_long_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(mr.current_match); + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'd': + { + match_results mr; + day = fixed_string_to_int(sitr, stream_end, mr, 2); + if(day == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_day = day_type(day); + break; + } + case 'e': + { + match_results mr; + day = fixed_string_to_int(sitr, stream_end, mr, 2, ' '); + if(day == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_day = day_type(day); + break; + } + case 'j': + { + match_results mr; + day_of_year = fixed_string_to_int(sitr, stream_end, mr, 3); + if(day_of_year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + // these next two lines are so we get an exception with bad input + day_of_year_type t_day_of_year(1); + t_day_of_year = day_of_year_type(day_of_year); + break; + } + case 'm': + { + match_results mr; + month = fixed_string_to_int(sitr, stream_end, mr, 2); + if(month == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(month); + break; + } + case 'Y': + { + match_results mr; + year = fixed_string_to_int(sitr, stream_end, mr, 4); + if(year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_year = year_type(year); + break; + } + case 'y': + { + match_results mr; + year = fixed_string_to_int(sitr, stream_end, mr, 2); + if(year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + year += 2000; //make 2 digit years in this century + t_year = year_type(year); + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + current_char = *sitr; + } + else { + sitr++; + } + } + } + + if (day_of_year > 0) { + date_type d(static_cast(year-1),12,31); //end of prior year + return d + duration_type(day_of_year); + } + + return date_type(t_year, t_month, t_day); // exceptions were thrown earlier + // if input was no good + } + + //! Throws bad_month if unable to parse + month_type + parse_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_month(sitr, stream_end, format_str, mr); + } + + //! Throws bad_month if unable to parse + month_type + parse_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + charT current_char = *sitr; + + short month(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + switch(*itr) { + case 'b': + { + mr = m_month_short_names.match(sitr, stream_end); + month = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'B': + { + mr = m_month_long_names.match(sitr, stream_end); + month = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'm': + { + month = var_string_to_int(sitr, stream_end, 2); + // var_string_to_int returns -1 if parse failed. That will + // cause a bad_month exception to be thrown so we do nothing here + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + current_char = *sitr; + } + else { + sitr++; + } + } + } + + return month_type(month); // throws bad_month exception when values are zero + } + + //! Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse + day_type + parse_var_day_of_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + return day_type(var_string_to_int(sitr, stream_end, 2)); + } + //! Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse + day_type + parse_day_of_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + //return day_type(var_string_to_int(sitr, stream_end, 2)); + match_results mr; + return day_type(fixed_string_to_int(sitr, stream_end, mr, 2)); + } + + day_of_week_type + parse_weekday(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_weekday(sitr, stream_end, format_str, mr); + } + day_of_week_type + parse_weekday(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + charT current_char = *sitr; + + short wkday(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + switch(*itr) { + case 'a': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + mr = m_weekday_short_names.match(sitr, stream_end); + wkday = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'A': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + mr = m_weekday_long_names.match(sitr, stream_end); + wkday = mr.current_match; + if (mr.has_remaining()) { + current_char = mr.last_char(); + use_current_char = true; + } + break; + } + case 'w': + { + // weekday as number 0-6, Sunday == 0 + wkday = var_string_to_int(sitr, stream_end, 2); + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + current_char = *sitr; + } + else { + sitr++; + } + } + } + + return day_of_week_type(wkday); // throws bad_day_of_month exception + // when values are zero + } + + //! throws bad_year if unable to parse + year_type + parse_year(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_year(sitr, stream_end, format_str, mr); + } + + //! throws bad_year if unable to parse + year_type + parse_year(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + charT current_char = *sitr; + + unsigned short year(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + //match_results mr; + switch(*itr) { + case 'Y': + { + // year from 4 digit string + year = fixed_string_to_int(sitr, stream_end, mr, 4); + break; + } + case 'y': + { + // year from 2 digit string (no century) + year = fixed_string_to_int(sitr, stream_end, mr, 2); + year += 2000; //make 2 digit years in this century + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + current_char = *sitr; + } + else { + sitr++; + } + } + } + + return year_type(year); // throws bad_year exception when values are zero + } + + + private: + string_type m_format; + parse_tree_type m_month_short_names; + parse_tree_type m_month_long_names; + parse_tree_type m_weekday_short_names; + parse_tree_type m_weekday_long_names; + +}; + +} } //namespace + +#endif + + + diff --git a/thirdparty/boost/date_time/gregorian/conversion.hpp b/thirdparty/boost/date_time/gregorian/conversion.hpp new file mode 100644 index 0000000..62543f2 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/conversion.hpp @@ -0,0 +1,73 @@ +#ifndef _GREGORIAN__CONVERSION_HPP___ +#define _GREGORIAN__CONVERSION_HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/c_time.hpp" +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +# if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +# include "boost/date_time/gregorian/formatters_limited.hpp" +# else +# include "boost/date_time/gregorian/formatters.hpp" +# endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS +#else +# include +# include "boost/date_time/gregorian/gregorian_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + +namespace boost { + +namespace gregorian { + + + //! Converts a date to a tm struct. Throws out_of_range exception if date is a special value + inline + std::tm to_tm(const date& d) + { + if(d.is_pos_infinity() || d.is_neg_infinity() || d.is_not_a_date()){ +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) + std::string s("tm unable to handle date value of " + to_simple_string(d)); + throw std::out_of_range(s); +#else + std::stringstream ss; + ss << "tm unable to handle date value of " << d; + throw std::out_of_range(ss.str()); +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + } + std::tm datetm; + boost::gregorian::date::ymd_type ymd = d.year_month_day(); + datetm.tm_year = ymd.year-1900; + datetm.tm_mon = ymd.month-1; + datetm.tm_mday = ymd.day; + datetm.tm_wday = d.day_of_week(); + datetm.tm_yday = d.day_of_year()-1; + datetm.tm_hour = datetm.tm_min = datetm.tm_sec = 0; + datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst + return datetm; + } + + //! Converts a tm structure into a date dropping the any time values. + inline + date date_from_tm(const std::tm& datetm) + { + return date(static_cast(datetm.tm_year+1900), + static_cast(datetm.tm_mon+1), + static_cast(datetm.tm_mday)); + } + + +} } //namespace boost::gregorian + + + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/formatters.hpp b/thirdparty/boost/date_time/gregorian/formatters.hpp new file mode 100644 index 0000000..0e14098 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/formatters.hpp @@ -0,0 +1,162 @@ +#ifndef GREGORIAN_FORMATTERS_HPP___ +#define GREGORIAN_FORMATTERS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/date_formatting_limited.hpp" +#else +#include "boost/date_time/date_formatting.hpp" +#endif +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" + +/* NOTE: "to_*_string" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * formatters_limited.hpp + */ + +namespace boost { +namespace gregorian { + + // wrapper function for to_simple_(w)string(date) + template + inline + std::basic_string to_simple_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date& d) { + return to_simple_string_type(d); + } + + + // wrapper function for to_simple_(w)string(date_period) + template + inline std::basic_string to_simple_string_type(const date_period& d) { + typedef std::basic_string string_type; + charT b = '[', m = '/', e=']'; + + string_type d1(date_time::date_formatter,charT>::date_to_string(d.begin())); + string_type d2(date_time::date_formatter,charT>::date_to_string(d.last())); + return string_type(b + d1 + m + d2 + e); + } + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date_period& d) { + return to_simple_string_type(d); + } + + // wrapper function for to_iso_(w)string(date_period) + template + inline std::basic_string to_iso_string_type(const date_period& d) { + charT sep = '/'; + std::basic_string s(date_time::date_formatter,charT>::date_to_string(d.begin())); + return s + sep + date_time::date_formatter,charT>::date_to_string(d.last()); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date_period& d) { + return to_iso_string_type(d); + } + + + // wrapper function for to_iso_extended_(w)string(date) + template + inline std::basic_string to_iso_extended_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::string to_iso_extended_string(const date& d) { + return to_iso_extended_string_type(d); + } + + // wrapper function for to_iso_(w)string(date) + template + inline std::basic_string to_iso_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date& d) { + return to_iso_string_type(d); + } + + + + + // wrapper function for to_sql_(w)string(date) + template + inline std::basic_string to_sql_string_type(const date& d) + { + date::ymd_type ymd = d.year_month_day(); + std::basic_ostringstream ss; + ss << ymd.year << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.month.as_number() //solves problem with gcc 3.1 hanging + << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + inline std::string to_sql_string(const date& d) { + return to_sql_string_type(d); + } + + +#if !defined(BOOST_NO_STD_WSTRING) + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date_period& d) { + return to_simple_string_type(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date& d) { + return to_simple_string_type(d); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date_period& d) { + return to_iso_string_type(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::wstring to_iso_extended_wstring(const date& d) { + return to_iso_extended_string_type(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date& d) { + return to_iso_string_type(d); + } + inline std::wstring to_sql_wstring(const date& d) { + return to_sql_string_type(d); + } +#endif // BOOST_NO_STD_WSTRING + +} } //namespace gregorian + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/formatters_limited.hpp b/thirdparty/boost/date_time/gregorian/formatters_limited.hpp new file mode 100644 index 0000000..12dc6ab --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/formatters_limited.hpp @@ -0,0 +1,81 @@ +#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___ +#define GREGORIAN_FORMATTERS_LIMITED_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/date_formatting_limited.hpp" +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" +#include "boost/date_time/compiler_config.hpp" + +namespace boost { +namespace gregorian { + + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date_period& d) { + std::string s("["); + std::string d1(date_time::date_formatter >::date_to_string(d.begin())); + std::string d2(date_time::date_formatter >::date_to_string(d.last())); + return std::string("[" + d1 + "/" + d2 + "]"); + } + + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date_period& d) { + std::string s(date_time::date_formatter >::date_to_string(d.begin())); + return s + "/" + date_time::date_formatter >::date_to_string(d.last()); + } + + + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::string to_iso_extended_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + + + inline std::string to_sql_string(const date& d) + { + date::ymd_type ymd = d.year_month_day(); + std::ostringstream ss; + ss << ymd.year << "-" + << std::setw(2) << std::setfill('0') + << ymd.month.as_number() //solves problem with gcc 3.1 hanging + << "-" + << std::setw(2) << std::setfill('0') + << ymd.day; + return ss.str(); + } + + +} } //namespace gregorian + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/greg_calendar.hpp b/thirdparty/boost/date_time/gregorian/greg_calendar.hpp new file mode 100644 index 0000000..554f27b --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_calendar.hpp @@ -0,0 +1,47 @@ +#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__ +#define GREGORIAN_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/greg_weekday.hpp" +#include "boost/date_time/gregorian/greg_day_of_year.hpp" +#include "boost/date_time/gregorian_calendar.hpp" +#include "boost/date_time/gregorian/greg_ymd.hpp" +#include "boost/date_time/int_adapter.hpp" + +namespace boost { +namespace gregorian { + + //!An internal date representation that includes infinities, not a date + typedef date_time::int_adapter fancy_date_rep; + + //! Gregorian calendar for this implementation, hard work in the base + class gregorian_calendar : + public date_time::gregorian_calendar_base { + public: + //! Type to hold a weekday (eg: Sunday, Monday,...) + typedef greg_weekday day_of_week_type; + //! Counter type from 1 to 366 for gregorian dates. + typedef greg_day_of_year_rep day_of_year_type; + //! Internal date representation that handles infinity, not a date + typedef fancy_date_rep date_rep_type; + //! Date rep implements the traits stuff as well + typedef fancy_date_rep date_traits_type; + + + private: + }; + +} } //namespace gregorian + + + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/greg_date.hpp b/thirdparty/boost/date_time/gregorian/greg_date.hpp new file mode 100644 index 0000000..f3622ab --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_date.hpp @@ -0,0 +1,135 @@ +#ifndef GREG_DATE_HPP___ +#define GREG_DATE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/gregorian/greg_calendar.hpp" +#include "boost/date_time/gregorian/greg_duration.hpp" + +namespace boost { +namespace gregorian { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! A date type based on gregorian_calendar + /*! This class is the primary interface for programming with + greogorian dates. The is a lightweight type that can be + freely passed by value. All comparison operators are + supported. + \ingroup date_basics + */ + class date : public date_time::date + { + public: + typedef gregorian_calendar::year_type year_type; + typedef gregorian_calendar::month_type month_type; + typedef gregorian_calendar::day_type day_type; + typedef gregorian_calendar::day_of_year_type day_of_year_type; + typedef gregorian_calendar::ymd_type ymd_type; + typedef gregorian_calendar::date_rep_type date_rep_type; + typedef gregorian_calendar::date_int_type date_int_type; + typedef date_duration duration_type; +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + //! Default constructor constructs with not_a_date_time + date(): + date_time::date(date_rep_type::from_special(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + //! Main constructor with year, month, day + date(year_type y, month_type m, day_type d) + : date_time::date(y, m, d) + { + if (gregorian_calendar::end_of_month_day(y, m) < d) { + throw bad_day_of_month(std::string("Day of month is not valid for year")); + } + } + //! Constructor from a ymd_type structure + explicit date(const ymd_type& ymd) + : date_time::date(ymd) + {} + //! Needed copy constructor + explicit date(const date_int_type& rhs): + date_time::date(rhs) + {} + //! Needed copy constructor + explicit date(date_rep_type rhs): + date_time::date(rhs) + {} + //! Constructor for infinities, not a date, max and min date + explicit date(special_values sv): + date_time::date(date_rep_type::from_special(sv)) + { + if (sv == min_date_time) + { + *this = date(1400, 1, 1); + } + if (sv == max_date_time) + { + *this = date(9999, 12, 31); + } + + } + //!Return the Julian Day number for the date. + date_int_type julian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::julian_day_number(ymd); + } + //!Return the day of year 1..365 or 1..366 (for leap year) + day_of_year_type day_of_year() const + { + date start_of_year(year(), 1, 1); + unsigned short doy = static_cast((*this-start_of_year).days() + 1); + return day_of_year_type(doy); + } + //!Return the Modified Julian Day number for the date. + long modjulian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::modjulian_day_number(ymd); + } + //!Return the iso 8601 week number 1..53 + int week_number() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::week_number(ymd); + } + //! Return the day number from the calendar + date_int_type day_number() const + { + return days_; + } + //! Return the last day of the current month + date end_of_month() const + { + ymd_type ymd = year_month_day(); + short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month); + return date(ymd.year, ymd.month, eom_day); + } + + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_day.hpp b/thirdparty/boost/date_time/gregorian/greg_day.hpp new file mode 100644 index 0000000..fede067 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_day.hpp @@ -0,0 +1,57 @@ +#ifndef GREG_DAY_HPP___ +#define GREG_DAY_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/constrained_value.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian day of month (1..31) + struct bad_day_of_month : public std::out_of_range + { + bad_day_of_month() : + std::out_of_range(std::string("Day of month value is out of range 1..31")) + {} + //! Allow other classes to throw with unique string for bad day like Feb 29 + bad_day_of_month(const std::string& s) : + std::out_of_range(s) + {} + }; + //! Policy class that declares error handling and day of month ranges + typedef CV::simple_exception_policy greg_day_policies; + + //! Generated represetation for gregorian day of month + typedef CV::constrained_value greg_day_rep; + + //! Represent a day of the month (range 1 - 31) + /*! This small class allows for simple conversion an integer value into + a day of the month for a standard gregorian calendar. The type + is automatically range checked so values outside of the range 1-31 + will cause a bad_day_of_month exception + */ + class greg_day : public greg_day_rep { + public: + greg_day(unsigned short day_of_month) : greg_day_rep(day_of_month) {} + unsigned short as_number() const {return value_;} + operator unsigned short() const {return value_;} + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_day_of_year.hpp b/thirdparty/boost/date_time/gregorian/greg_day_of_year.hpp new file mode 100644 index 0000000..b0057a3 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_day_of_year.hpp @@ -0,0 +1,38 @@ +#ifndef GREG_DAY_OF_YEAR_HPP___ +#define GREG_DAY_OF_YEAR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/constrained_value.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for day of year (1..366) + struct bad_day_of_year : public std::out_of_range + { + bad_day_of_year() : + std::out_of_range(std::string("Day of year value is out of range 1..366")) + {} + }; + + //! A day of the year range (1..366) + typedef CV::simple_exception_policy greg_day_of_year_policies; + + //! Define a range representation type for the day of the year 1..366 + typedef CV::constrained_value greg_day_of_year_rep; + + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_duration.hpp b/thirdparty/boost/date_time/gregorian/greg_duration.hpp new file mode 100644 index 0000000..2c53d10 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_duration.hpp @@ -0,0 +1,38 @@ +#ifndef GREG_DURATION_HPP___ +#define GREG_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/date_duration.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/date_duration_types.hpp" +#endif +#include "boost/date_time/int_adapter.hpp" + + +namespace boost { +namespace gregorian { + + + //!An internal date representation that includes infinities, not a date + typedef boost::date_time::duration_traits_adapted date_duration_rep; + + //! Durations in days for gregorian system + /*! \ingroup date_basics + */ + typedef date_time::date_duration date_duration; + + //! Shorthand for date_duration + typedef date_duration days; + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_duration_types.hpp b/thirdparty/boost/date_time/gregorian/greg_duration_types.hpp new file mode 100644 index 0000000..fa3654d --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_duration_types.hpp @@ -0,0 +1,34 @@ +#ifndef GREG_DURATION_TYPES_HPP___ +#define GREG_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/gregorian/greg_date.hpp" +#include "boost/date_time/int_adapter.hpp" +#include "boost/date_time/adjust_functors.hpp" +#include "boost/date_time/date_duration.hpp" +#include "boost/date_time/date_duration_types.hpp" + +namespace boost { +namespace gregorian { + + //! config struct for additional duration types (ie months_duration<> & years_duration<>) + struct greg_durations_config { + typedef date date_type; + typedef date_time::int_adapter int_rep; + typedef date_time::month_functor month_adjustor_type; + }; + + typedef date_time::months_duration months; + typedef date_time::years_duration years; + typedef date_time::weeks_duration weeks; + +}} // namespace boost::gregorian + +#endif // GREG_DURATION_TYPES_HPP___ diff --git a/thirdparty/boost/date_time/gregorian/greg_facet.hpp b/thirdparty/boost/date_time/gregorian/greg_facet.hpp new file mode 100644 index 0000000..daee3ad --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_facet.hpp @@ -0,0 +1,351 @@ +#ifndef GREGORIAN_FACET_HPP___ +#define GREGORIAN_FACET_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/date_formatting_locales.hpp" // sets BOOST_DATE_TIME_NO_LOCALE +#include "boost/date_time/gregorian/parsers.hpp" +#include +#include + +//This file is basically commented out if locales are not supported +#ifndef BOOST_DATE_TIME_NO_LOCALE + + +namespace boost { +namespace gregorian { + + //! Configuration of the output facet template + struct greg_facet_config + { + typedef boost::gregorian::greg_month month_type; + typedef boost::date_time::special_values special_value_enum; + typedef boost::gregorian::months_of_year month_enum; + typedef boost::date_time::weekdays weekday_enum; + }; + +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) + //! Create the base facet type for gregorian::date + typedef boost::date_time::date_names_put greg_base_facet; + + //! ostream operator for gregorian::date + /*! Uses the date facet to determine various output parameters including: + * - string values for the month (eg: Jan, Feb, Mar) (default: English) + * - string values for special values (eg: not-a-date-time) (default: English) + * - selection of long, short strings, or numerical month representation (default: short string) + * - month day year order (default yyyy-mmm-dd) + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date& d) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_date_formatter greg_ostream_formatter; + greg_ostream_formatter::date_put(d, os); + return os; + } + + //! operator<< for gregorian::greg_month typically streaming: Jan, Feb, Mar... + /*! Uses the date facet to determine output string as well as selection of long or short strings. + * Default if no facet is installed is to output a 2 wide numeric value for the month + * eg: 01 == Jan, 02 == Feb, ... 12 == Dec. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const greg_month& m) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_month_formatter greg_month_formatter; + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_def& f = std::use_facet(locale); + greg_month_formatter::format_month(m, os, f); + + } + else { //default to numeric + charT fill_char = '0'; + os << std::setw(2) << std::setfill(fill_char) << m.as_number(); + } + + return os; + } + + //! operator<< for gregorian::greg_weekday typically streaming: Sun, Mon, Tue, ... + /*! Uses the date facet to determine output string as well as selection of long or short string. + * Default if no facet is installed is to output a 3 char english string for the + * day of the week. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const greg_weekday& wd) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_weekday_formatter greg_weekday_formatter; + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_def& f = std::use_facet(locale); + greg_weekday_formatter::format_weekday(wd.as_enum(), os, f, true); + } + else { //default to short English string eg: Sun, Mon, Tue, Wed... + os << wd.as_short_string(); + } + + return os; + } + + //! operator<< for gregorian::date_period typical output: [2002-Jan-01/2002-Jan-31] + /*! Uses the date facet to determine output string as well as selection of long + * or short string fr dates. + * Default if no facet is installed is to output a 3 char english string for the + * day of the week. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date_period& dp) + { + os << '['; //TODO: facet or manipulator for periods? + os << dp.begin(); + os << '/'; //TODO: facet or manipulator for periods? + os << dp.last(); + os << ']'; + return os; + } + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date_duration& dd) + { + //os << dd.days(); + os << dd.get_rep(); + return os; + } + + //! operator<< for gregorian::partial_date. Output: "Jan 1" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const partial_date& pd) + { + os << std::setw(2) << std::setfill('0') << pd.day() << ' ' + << pd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::nth_kday_of_month. Output: "first Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const nth_kday_of_month& nkd) + { + os << nkd.nth_week_as_str() << ' ' + << nkd.day_of_week() << " of " + << nkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::first_kday_of_month. Output: "first Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_of_month& fkd) + { + os << "first " << fkd.day_of_week() << " of " + << fkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::last_kday_of_month. Output: "last Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const last_kday_of_month& lkd) + { + os << "last " << lkd.day_of_week() << " of " + << lkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::first_kday_after. Output: "first Mon after" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_after& fka) + { + os << fka.day_of_week() << " after"; + return os; + } + + //! operator<< for gregorian::first_kday_before. Output: "first Mon before" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_before& fkb) + { + os << fkb.day_of_week() << " before"; + return os; + } +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + /**************** Input Streaming ******************/ + +#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) + //! operator>> for gregorian::date + template + inline + std::basic_istream& operator>>(std::basic_istream& is, date& d) + { + std::istream_iterator, charT> beg(is), eos; + + typedef boost::date_time::all_date_names_put facet_def; + d = from_stream(beg, eos); + return is; + } +#endif // BOOST_NO_STD_ITERATOR_TRAITS + + //! operator>> for gregorian::date_duration + template + inline + std::basic_istream& operator>>(std::basic_istream& is, + date_duration& dd) + { + long v; + is >> v; + dd = date_duration(v); + return is; + } + + //! operator>> for gregorian::date_period + template + inline + std::basic_istream& operator>>(std::basic_istream& is, + date_period& dp) + { + std::basic_string s; + is >> s; + dp = date_time::from_simple_string_type(s); + return is; + } + + //! generates a locale with the set of gregorian name-strings of type char* + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char type); + + //! Returns a pointer to a facet with a default set of names (English) + /* Necessary in the event an exception is thrown from op>> for + * weekday or month. See comments in those functions for more info */ + BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put* create_facet_def(char type); + +#ifndef BOOST_NO_STD_WSTRING + //! generates a locale with the set of gregorian name-strings of type wchar_t* + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t type); + //! Returns a pointer to a facet with a default set of names (English) + /* Necessary in the event an exception is thrown from op>> for + * weekday or month. See comments in those functions for more info */ + BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put* create_facet_def(wchar_t type); +#endif // BOOST_NO_STD_WSTRING + + //! operator>> for gregorian::greg_month - throws exception if invalid month given + template + inline + std::basic_istream& operator>>(std::basic_istream& is,greg_month& m) + { + typedef boost::date_time::all_date_names_put facet_def; + + std::basic_string s; + is >> s; + + if(!std::has_facet(is.getloc())) { + std::locale loc = is.getloc(); + charT a = '\0'; + is.imbue(generate_locale(loc, a)); + } + + short num = 0; + + try{ + const facet_def& f = std::use_facet(is.getloc()); + num = date_time::find_match(f.get_short_month_names(), + f.get_long_month_names(), + (greg_month::max)(), s); + } + /* bad_cast will be thrown if the desired facet is not accessible + * so we can generate the facet. This has the drawback of using english + * names as a default. */ + catch(std::bad_cast bc){ + std::cout << "Month exception caught" << std::endl; + charT a = '\0'; + const facet_def* f = create_facet_def(a); + num = date_time::find_match(f->get_short_month_names(), + f->get_long_month_names(), + (greg_month::max)(), s); + delete(f); + } + + num += 1; // months numbered 1-12 + m = greg_month(num); + + return is; + } + + //! operator>> for gregorian::greg_weekday - throws exception if invalid weekday given + template + inline + std::basic_istream& operator>>(std::basic_istream& is,greg_weekday& wd) + { + typedef boost::date_time::all_date_names_put facet_def; + + std::basic_string s; + is >> s; + + if(!std::has_facet(is.getloc())) { + std::locale loc = is.getloc(); + charT a = '\0'; + is.imbue(generate_locale(loc, a)); + } + + short num = 0; + try{ + const facet_def& f = std::use_facet(is.getloc()); + num = date_time::find_match(f.get_short_weekday_names(), + f.get_long_weekday_names(), + (greg_weekday::max)(), s); + } + /* bad_cast will be thrown if the desired facet is not accessible + * so we can generate the facet. This has the drawback of using english + * names as a default. */ + catch(std::bad_cast bc){ + //std::cout << "Weekday exception caught" << std::endl; + charT a = '\0'; + const facet_def* f = create_facet_def(a); + num = date_time::find_match(f->get_short_weekday_names(), + f->get_long_weekday_names(), + (greg_weekday::max)(), s); + delete(f); + } + + wd = greg_weekday(num); // weekdays numbered 0-6 + return is; + } + +} } //namespace gregorian + +#endif + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/greg_month.hpp b/thirdparty/boost/date_time/gregorian/greg_month.hpp new file mode 100644 index 0000000..0a07a8d --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_month.hpp @@ -0,0 +1,105 @@ +#ifndef GREG_MONTH_HPP___ +#define GREG_MONTH_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/constrained_value.hpp" +#include "boost/date_time/date_defs.hpp" +#include "boost/shared_ptr.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + typedef date_time::months_of_year months_of_year; + + //bring enum values into the namespace + using date_time::Jan; + using date_time::Feb; + using date_time::Mar; + using date_time::Apr; + using date_time::May; + using date_time::Jun; + using date_time::Jul; + using date_time::Aug; + using date_time::Sep; + using date_time::Oct; + using date_time::Nov; + using date_time::Dec; + using date_time::NotAMonth; + using date_time::NumMonths; + + //! Exception thrown if a greg_month is constructed with a value out of range + struct bad_month : public std::out_of_range + { + bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {} + }; + //! Build a policy class for the greg_month_rep + typedef CV::simple_exception_policy greg_month_policies; + //! A constrained range that implements the gregorian_month rules + typedef CV::constrained_value greg_month_rep; + + + //! Wrapper class to represent months in gregorian based calendar + class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep { + public: + typedef date_time::months_of_year month_enum; + typedef std::map month_map_type; + typedef boost::shared_ptr month_map_ptr_type; + //! Construct a month from the months_of_year enumeration + greg_month(month_enum theMonth) : + greg_month_rep(static_cast(theMonth)) {} + //! Construct from a short value + greg_month(unsigned short theMonth) : greg_month_rep(theMonth) {} + //! Convert the value back to a short + operator unsigned short() const {return value_;} + //! Returns month as number from 1 to 12 + unsigned short as_number() const {return value_;} + month_enum as_enum() const {return static_cast(value_);} + const char* as_short_string() const; + const char* as_long_string() const; +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_wstring() const; + const wchar_t* as_long_wstring() const; +#endif // BOOST_NO_STD_WSTRING + //! Shared pointer to a map of Month strings (Names & Abbrev) & numbers + static month_map_ptr_type get_month_map_ptr(); + + /* parameterized as_*_string functions are intended to be called + * from a template function: "... as_short_string(charT c='\0');" */ + const char* as_short_string(char) const + { + return as_short_string(); + } + const char* as_long_string(char) const + { + return as_long_string(); + } +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_string(wchar_t) const + { + return as_short_wstring(); + } + const wchar_t* as_long_string(wchar_t) const + { + return as_long_wstring(); + } +#endif // BOOST_NO_STD_WSTRING + }; + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_serialize.hpp b/thirdparty/boost/date_time/gregorian/greg_serialize.hpp new file mode 100644 index 0000000..6d660c9 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_serialize.hpp @@ -0,0 +1,489 @@ +#ifndef GREGORIAN_SERIALIZE_HPP___ +#define GREGORIAN_SERIALIZE_HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/gregorian/parsers.hpp" +#include "boost/serialization/split_free.hpp" + + +// macros to split serialize functions into save & load functions +// An expanded version is below for gregorian::date +// NOTE: these macros define template functions in the boost::serialization namespace. +// They must be expanded *outside* of any namespace +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_period) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before) +BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after) + +namespace boost { +namespace serialization { + +/*! Method that does serialization for gregorian::date -- splits to load/save + */ +template +inline void serialize(Archive & ar, + ::boost::gregorian::date & d, + const unsigned int file_version) +{ + split_free(ar, d, file_version); +} + +//! Function to save gregorian::date objects using serialization lib +/*! Dates are serialized into a string for transport and storage. + * While it would be more efficient to store the internal + * integer used to manipulate the dates, it is an unstable solution. + */ +template +void save(Archive & ar, + const ::boost::gregorian::date & d, + unsigned int /* version */) +{ + std::string ds = to_iso_string(d); + ar & make_nvp("date", ds); +} + +//! Function to load gregorian::date objects using serialization lib +/*! Dates are serialized into a string for transport and storage. + * While it would be more efficient to store the internal + * integer used to manipulate the dates, it is an unstable solution. + */ +template +void load(Archive & ar, + ::boost::gregorian::date & d, + unsigned int /*version*/) +{ + std::string ds; + ar & make_nvp("date", ds); + try{ + d = ::boost::gregorian::from_undelimited_string(ds); + }catch(bad_lexical_cast be) { + gregorian::special_values sv = gregorian::special_value_from_string(ds); + if(sv == gregorian::not_special) { + throw(be); // no match found, rethrow original exception + } + else { + d = gregorian::date(sv); + } + } +} + + +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + ::boost::gregorian::date* dp, + const unsigned int /*file_version*/) +{ + // retrieve data from archive required to construct new + // invoke inplace constructor to initialize instance of date + ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time); +} + +/**** date_duration ****/ + +//! Function to save gregorian::date_duration objects using serialization lib +template +void save(Archive & ar, const gregorian::date_duration & dd, + unsigned int /*version*/) +{ + typename gregorian::date_duration::duration_rep dr = dd.get_rep(); + ar & make_nvp("date_duration", dr); +} +//! Function to load gregorian::date_duration objects using serialization lib +template +void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/) +{ + typename gregorian::date_duration::duration_rep dr(0); + ar & make_nvp("date_duration", dr); + dd = gregorian::date_duration(dr); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::date_duration* dd, + const unsigned int /*file_version*/) +{ + ::new(dd) gregorian::date_duration(gregorian::not_a_date_time); +} + +/**** date_duration::duration_rep (most likely int_adapter) ****/ + +//! helper unction to save date_duration objects using serialization lib +template +void save(Archive & ar, const gregorian::date_duration::duration_rep & dr, + unsigned int /*version*/) +{ + typename gregorian::date_duration::duration_rep::int_type it = dr.as_number(); + ar & make_nvp("date_duration_duration_rep", it); +} +//! helper function to load date_duration objects using serialization lib +template +void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/) +{ + typename gregorian::date_duration::duration_rep::int_type it(0); + ar & make_nvp("date_duration_duration_rep", it); + dr = gregorian::date_duration::duration_rep::int_type(it); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::date_duration::duration_rep* dr, + const unsigned int /*file_version*/) +{ + ::new(dr) gregorian::date_duration::duration_rep(0); +} + +/**** date_period ****/ + +//! Function to save gregorian::date_period objects using serialization lib +/*! date_period objects are broken down into 2 parts for serialization: + * the begining date object and the end date object + */ +template +void save(Archive & ar, const gregorian::date_period& dp, + unsigned int /*version*/) +{ + gregorian::date d1 = dp.begin(); + gregorian::date d2 = dp.end(); + ar & make_nvp("date_period_begin_date", d1); + ar & make_nvp("date_period_end_date", d2); +} +//! Function to load gregorian::date_period objects using serialization lib +/*! date_period objects are broken down into 2 parts for serialization: + * the begining date object and the end date object + */ +template +void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/) +{ + gregorian::date d1(gregorian::not_a_date_time); + gregorian::date d2(gregorian::not_a_date_time); + ar & make_nvp("date_period_begin_date", d1); + ar & make_nvp("date_period_end_date", d2); + dp = gregorian::date_period(d1,d2); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::date_period* dp, + const unsigned int /*file_version*/) +{ + gregorian::date d(gregorian::not_a_date_time); + gregorian::date_duration dd(1); + ::new(dp) gregorian::date_period(d,dd); +} + +/**** greg_month ****/ + +//! Function to save gregorian::greg_month objects using serialization lib +template +void save(Archive & ar, const gregorian::greg_month& gm, + unsigned int /*version*/) +{ + unsigned short us = gm.as_number(); + ar & make_nvp("greg_month", us); +} +//! Function to load gregorian::greg_month objects using serialization lib +template +void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/) +{ + unsigned short us; + ar & make_nvp("greg_month", us); + gm = gregorian::greg_month(us); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::greg_month* gm, + const unsigned int /*file_version*/) +{ + ::new(gm) gregorian::greg_month(1); +} + +/**** greg_day ****/ + +//! Function to save gregorian::greg_day objects using serialization lib +template +void save(Archive & ar, const gregorian::greg_day& gd, + unsigned int /*version*/) +{ + unsigned short us = gd.as_number(); + ar & make_nvp("greg_day", us); +} +//! Function to load gregorian::greg_day objects using serialization lib +template +void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/) +{ + unsigned short us; + ar & make_nvp("greg_day", us); + gd = gregorian::greg_day(us); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::greg_day* gd, + const unsigned int /*file_version*/) +{ + ::new(gd) gregorian::greg_day(1); +} + +/**** greg_weekday ****/ + +//! Function to save gregorian::greg_weekday objects using serialization lib +template +void save(Archive & ar, const gregorian::greg_weekday& gd, + unsigned int /*version*/) +{ + unsigned short us = gd.as_number(); + ar & make_nvp("greg_weekday", us); +} +//! Function to load gregorian::greg_weekday objects using serialization lib +template +void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/) +{ + unsigned short us; + ar & make_nvp("greg_weekday", us); + gd = gregorian::greg_weekday(us); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::greg_weekday* gd, + const unsigned int /*file_version*/) +{ + ::new(gd) gregorian::greg_weekday(1); +} + +/**** date_generators ****/ + +/**** partial_date ****/ + +//! Function to save gregorian::partial_date objects using serialization lib +/*! partial_date objects are broken down into 2 parts for serialization: + * the day (typically greg_day) and month (typically greg_month) objects + */ +template +void save(Archive & ar, const gregorian::partial_date& pd, + unsigned int /*version*/) +{ + gregorian::greg_day gd(pd.day()); + gregorian::greg_month gm(pd.month().as_number()); + ar & make_nvp("partial_date_day", gd); + ar & make_nvp("partial_date_month", gm); +} +//! Function to load gregorian::partial_date objects using serialization lib +/*! partial_date objects are broken down into 2 parts for serialization: + * the day (greg_day) and month (greg_month) objects + */ +template +void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/) +{ + gregorian::greg_day gd(1); + gregorian::greg_month gm(1); + ar & make_nvp("partial_date_day", gd); + ar & make_nvp("partial_date_month", gm); + pd = gregorian::partial_date(gd,gm); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, gregorian::partial_date* pd, + const unsigned int /*file_version*/) +{ + gregorian::greg_month gm(1); + gregorian::greg_day gd(1); + ::new(pd) gregorian::partial_date(gd,gm); +} + +/**** nth_kday_of_month ****/ + +//! Function to save nth_day_of_the_week_in_month objects using serialization lib +/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for + * serialization: the week number, the day of the week, and the month + */ +template +void save(Archive & ar, const gregorian::nth_kday_of_month& nkd, + unsigned int /*version*/) +{ + typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week()); + typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number()); + typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number()); + ar & make_nvp("nth_kday_of_month_week_num", wn); + ar & make_nvp("nth_kday_of_month_day_of_week", d); + ar & make_nvp("nth_kday_of_month_month", m); +} +//! Function to load nth_day_of_the_week_in_month objects using serialization lib +/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for + * serialization: the week number, the day of the week, and the month + */ +template +void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/) +{ + typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first); + typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday); + typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan); + ar & make_nvp("nth_kday_of_month_week_num", wn); + ar & make_nvp("nth_kday_of_month_day_of_week", d); + ar & make_nvp("nth_kday_of_month_month", m); + + nkd = gregorian::nth_kday_of_month(wn,d,m); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + gregorian::nth_kday_of_month* nkd, + const unsigned int /*file_version*/) +{ + // values used are not significant + ::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first, + gregorian::Monday,gregorian::Jan); +} + +/**** first_kday_of_month ****/ + +//! Function to save first_day_of_the_week_in_month objects using serialization lib +/*! first_day_of_the_week_in_month objects are broken down into 2 parts for + * serialization: the day of the week, and the month + */ +template +void save(Archive & ar, const gregorian::first_kday_of_month& fkd, + unsigned int /*version*/) +{ + typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number()); + typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number()); + ar & make_nvp("first_kday_of_month_day_of_week", d); + ar & make_nvp("first_kday_of_month_month", m); +} +//! Function to load first_day_of_the_week_in_month objects using serialization lib +/*! first_day_of_the_week_in_month objects are broken down into 2 parts for + * serialization: the day of the week, and the month + */ +template +void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/) +{ + typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday); + typename gregorian::first_kday_of_month::month_type m(gregorian::Jan); + ar & make_nvp("first_kday_of_month_day_of_week", d); + ar & make_nvp("first_kday_of_month_month", m); + + fkd = gregorian::first_kday_of_month(d,m); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + gregorian::first_kday_of_month* fkd, + const unsigned int /*file_version*/) +{ + // values used are not significant + ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan); +} + +/**** last_kday_of_month ****/ + +//! Function to save last_day_of_the_week_in_month objects using serialization lib +/*! last_day_of_the_week_in_month objects are broken down into 2 parts for + * serialization: the day of the week, and the month + */ +template +void save(Archive & ar, const gregorian::last_kday_of_month& lkd, + unsigned int /*version*/) +{ + typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number()); + typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number()); + ar & make_nvp("last_kday_of_month_day_of_week", d); + ar & make_nvp("last_kday_of_month_month", m); +} +//! Function to load last_day_of_the_week_in_month objects using serialization lib +/*! last_day_of_the_week_in_month objects are broken down into 2 parts for + * serialization: the day of the week, and the month + */ +template +void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/) +{ + typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday); + typename gregorian::last_kday_of_month::month_type m(gregorian::Jan); + ar & make_nvp("last_kday_of_month_day_of_week", d); + ar & make_nvp("last_kday_of_month_month", m); + + lkd = gregorian::last_kday_of_month(d,m); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + gregorian::last_kday_of_month* lkd, + const unsigned int /*file_version*/) +{ + // values used are not significant + ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan); +} + +/**** first_kday_before ****/ + +//! Function to save first_day_of_the_week_before objects using serialization lib +template +void save(Archive & ar, const gregorian::first_kday_before& fkdb, + unsigned int /*version*/) +{ + typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number()); + ar & make_nvp("first_kday_before_day_of_week", d); +} +//! Function to load first_day_of_the_week_before objects using serialization lib +template +void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/) +{ + typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday); + ar & make_nvp("first_kday_before_day_of_week", d); + + fkdb = gregorian::first_kday_before(d); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + gregorian::first_kday_before* fkdb, + const unsigned int /*file_version*/) +{ + // values used are not significant + ::new(fkdb) gregorian::first_kday_before(gregorian::Monday); +} + +/**** first_kday_after ****/ + +//! Function to save first_day_of_the_week_after objects using serialization lib +template +void save(Archive & ar, const gregorian::first_kday_after& fkda, + unsigned int /*version*/) +{ + typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number()); + ar & make_nvp("first_kday_after_day_of_week", d); +} +//! Function to load first_day_of_the_week_after objects using serialization lib +template +void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/) +{ + typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday); + ar & make_nvp("first_kday_after_day_of_week", d); + + fkda = gregorian::first_kday_after(d); +} +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + gregorian::first_kday_after* fkda, + const unsigned int /*file_version*/) +{ + // values used are not significant + ::new(fkda) gregorian::first_kday_after(gregorian::Monday); +} + +} // namespace serialization +} // namespace boost + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_weekday.hpp b/thirdparty/boost/date_time/gregorian/greg_weekday.hpp new file mode 100644 index 0000000..01058c2 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_weekday.hpp @@ -0,0 +1,66 @@ +#ifndef GREG_WEEKDAY_HPP___ +#define GREG_WEEKDAY_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/constrained_value.hpp" +#include "boost/date_time/date_defs.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //bring enum values into the namespace + using date_time::Sunday; + using date_time::Monday; + using date_time::Tuesday; + using date_time::Wednesday; + using date_time::Thursday; + using date_time::Friday; + using date_time::Saturday; + + + //! Exception that flags that a weekday number is incorrect + struct bad_weekday : public std::out_of_range + { + bad_weekday() : std::out_of_range(std::string("Weekday os out of range 0..6")) {} + }; + typedef CV::simple_exception_policy greg_weekday_policies; + typedef CV::constrained_value greg_weekday_rep; + + + //! Represent a day within a week (range 0==Sun to 6==Sat) + class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep { + public: + typedef boost::date_time::weekdays weekday_enum; + greg_weekday(unsigned short day_of_week_num) : + greg_weekday_rep(day_of_week_num) + {} + + unsigned short as_number() const {return value_;} + const char* as_short_string() const; + const char* as_long_string() const; +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_wstring() const; + const wchar_t* as_long_wstring() const; +#endif // BOOST_NO_STD_WSTRING + weekday_enum as_enum() const {return static_cast(value_);} + + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_year.hpp b/thirdparty/boost/date_time/gregorian/greg_year.hpp new file mode 100644 index 0000000..ca028d3 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_year.hpp @@ -0,0 +1,53 @@ +#ifndef GREG_YEAR_HPP___ +#define GREG_YEAR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/constrained_value.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian year + struct bad_year : public std::out_of_range + { + bad_year() : + std::out_of_range(std::string("Year is out of valid range: 1400..10000")) + {} + }; + //! Policy class that declares error handling gregorian year type + typedef CV::simple_exception_policy greg_year_policies; + + //! Generated representation for gregorian year + typedef CV::constrained_value greg_year_rep; + + //! Represent a day of the month (range 1900 - 10000) + /*! This small class allows for simple conversion an integer value into + a year for the gregorian calendar. This currently only allows a + range of 1900 to 10000. Both ends of the range are a bit arbitrary + at the moment, but they are the limits of current testing of the + library. As such they may be increased in the future. + */ + class greg_year : public greg_year_rep { + public: + greg_year(unsigned short year) : greg_year_rep(year) {} + operator unsigned short() const {return value_;} + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/greg_ymd.hpp b/thirdparty/boost/date_time/gregorian/greg_ymd.hpp new file mode 100644 index 0000000..21d5571 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/greg_ymd.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_GREG_YMD_HPP__ +#define DATE_TIME_GREG_YMD_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/year_month_day.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/gregorian/greg_day.hpp" +#include "boost/date_time/gregorian/greg_year.hpp" +#include "boost/date_time/gregorian/greg_month.hpp" + +namespace boost { +namespace gregorian { + + typedef date_time::year_month_day_base greg_year_month_day; + + + +} } //namespace gregorian + + + + +#endif + diff --git a/thirdparty/boost/date_time/gregorian/gregorian.hpp b/thirdparty/boost/date_time/gregorian/gregorian.hpp new file mode 100644 index 0000000..4131004 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/gregorian.hpp @@ -0,0 +1,38 @@ +#ifndef GREGORIAN_HPP__ +#define GREGORIAN_HPP__ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file gregorian.hpp + Single file header that provides overall include for all elements of + the gregorian date-time system. This includes the various types + defined, but also other functions for formatting and parsing. +*/ + + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/gregorian/conversion.hpp" +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/gregorian/formatters_limited.hpp" +#else +#include "boost/date_time/gregorian/formatters.hpp" +#endif + +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +#include "boost/date_time/gregorian/greg_facet.hpp" +#else +#include "boost/date_time/gregorian/gregorian_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + +#include "boost/date_time/gregorian/parsers.hpp" + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/gregorian_io.hpp b/thirdparty/boost/date_time/gregorian/gregorian_io.hpp new file mode 100644 index 0000000..288737c --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/gregorian_io.hpp @@ -0,0 +1,777 @@ +#ifndef DATE_TIME_GREGORIAN_IO_HPP__ +#define DATE_TIME_GREGORIAN_IO_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/date_facet.hpp" +#include "boost/io/ios_state.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + + typedef boost::date_time::period_formatter wperiod_formatter; + typedef boost::date_time::period_formatter period_formatter; + + typedef boost::date_time::date_facet wdate_facet; + typedef boost::date_time::date_facet date_facet; + + typedef boost::date_time::period_parser period_parser; + typedef boost::date_time::period_parser wperiod_parser; + + typedef boost::date_time::special_values_formatter special_values_formatter; + typedef boost::date_time::special_values_formatter wspecial_values_formatter; + + typedef boost::date_time::special_values_parser special_values_parser; + typedef boost::date_time::special_values_parser wspecial_values_parser; + + typedef boost::date_time::date_input_facet date_input_facet; + typedef boost::date_time::date_input_facet wdate_input_facet; + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date& d) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), d); + else { + //instantiate a custom facet for dealing with dates since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every date + //if the locale did not already exist. Of course this will be overridden + //if the user imbues at some later point. With the default settings + //for the facet the resulting format will be the same as the + //std::time_facet settings. + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), d); + } + return os; + } + + //! input operator for date + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date& d) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, d); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, d); + } + } + catch(...) { + // mask tells us what exceptions are turned on + std::ios_base::iostate exception_mask = is.exceptions(); + // if the user wants exceptions on failbit, we'll rethrow our + // date_time exception & set the failbit + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} // ignore this one + throw; // rethrow original exception + } + else { + // if the user want's to fail quietly, we simply set the failbit + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date_duration& dd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), dd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), dd); + + } + return os; + } + + //! input operator for date_duration + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date_duration& dd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, dd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, dd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date_period& dp) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), dp); + else { + //instantiate a custom facet for dealing with date periods since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the local did not already exist. Of course this will be overridden + //if the user imbues at some later point. With the default settings + //for the facet the resulting format will be the same as the + //std::time_facet settings. + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), dp); + + } + return os; + } + + //! input operator for date_period + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date_period& dp) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, dp); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, dp); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + /********** small gregorian types **********/ + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::greg_month& gm) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), gm); + else { + custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...) + //custom_date_facet* f = new custom_date_facet("%B"); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), gm); + } + return os; + } + + //! input operator for greg_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_month& m) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, m); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, m); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::greg_weekday& gw) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), gw); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), gw); + } + return os; + } + + //! input operator for greg_weekday + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_weekday& wd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, wd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, wd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + //NOTE: output operator for greg_day was not necessary + + //! input operator for greg_day + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_day& gd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, gd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, gd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + //NOTE: output operator for greg_year was not necessary + + //! input operator for greg_year + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_year& gy) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, gy); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, gy); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + /********** date generator types **********/ + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::partial_date& pd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), pd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), pd); + } + return os; + } + + //! input operator for partial_date + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, partial_date& pd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, pd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, pd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), nkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), nkd); + } + return os; + } + + //! input operator for nth_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + nth_day_of_the_week_in_month& nday) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, nday); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, nday); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fkd); + } + return os; + } + + //! input operator for first_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_in_month& fkd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fkd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fkd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), lkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), lkd); + } + return os; + } + + //! input operator for last_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + last_day_of_the_week_in_month& lkd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, lkd); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, lkd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_after& fda) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fda); + } + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fda); + } + return os; + } + + //! input operator for first_day_of_the_week_after + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_after& fka) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fka); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fka); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_before& fdb) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fdb); + } + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fdb); + } + return os; + } + + //! input operator for first_day_of_the_week_before + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_before& fkb) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fkb); + } + else { + date_input_facet* f = new date_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fkb); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + +} } // namespaces + +#endif // DATE_TIME_GREGORIAN_IO_HPP__ diff --git a/thirdparty/boost/date_time/gregorian/gregorian_types.hpp b/thirdparty/boost/date_time/gregorian/gregorian_types.hpp new file mode 100644 index 0000000..32b6e62 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/gregorian_types.hpp @@ -0,0 +1,109 @@ +#ifndef _GREGORIAN_TYPES_HPP__ +#define _GREGORIAN_TYPES_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file gregorian_types.hpp + Single file header that defines most of the types for the gregorian + date-time system. +*/ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/gregorian/greg_calendar.hpp" +#include "boost/date_time/gregorian/greg_duration.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#endif +#include "boost/date_time/gregorian/greg_date.hpp" +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/date_clock_device.hpp" +#include "boost/date_time/date_iterator.hpp" +#include "boost/date_time/adjust_functors.hpp" + +namespace boost { + +//! Gregorian date system based on date_time components +/*! This date system defines a full complement of types including + * a date, date_duration, date_period, day_clock, and a + * day_iterator. + */ +namespace gregorian { + //! Date periods for the gregorian system + /*!\ingroup date_basics + */ + typedef date_time::period date_period; + + //! A unifying date_generator base type + /*! A unifying date_generator base type for: + * partial_date, nth_day_of_the_week_in_month, + * first_day_of_the_week_in_month, and last_day_of_the_week_in_month + */ + typedef date_time::year_based_generator year_based_generator; + + //! A date generation object type + typedef date_time::partial_date partial_date; + + typedef date_time::nth_kday_of_month nth_kday_of_month; + typedef nth_kday_of_month nth_day_of_the_week_in_month; + + typedef date_time::first_kday_of_month first_kday_of_month; + typedef first_kday_of_month first_day_of_the_week_in_month; + + typedef date_time::last_kday_of_month last_kday_of_month; + typedef last_kday_of_month last_day_of_the_week_in_month; + + typedef date_time::first_kday_after first_kday_after; + typedef first_kday_after first_day_of_the_week_after; + + typedef date_time::first_kday_before first_kday_before; + typedef first_kday_before first_day_of_the_week_before; + + //! A clock to get the current day from the local computer + /*!\ingroup date_basics + */ + typedef date_time::day_clock day_clock; + + //! Base date_iterator type for gregorian types. + /*!\ingroup date_basics + */ + typedef date_time::date_itr_base date_iterator; + + //! A day level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> day_iterator; + //! A week level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> week_iterator; + //! A month level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> month_iterator; + //! A year level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> year_iterator; + + // bring in these date_generator functions from date_time namespace + using date_time::days_until_weekday; + using date_time::days_before_weekday; + using date_time::next_weekday; + using date_time::previous_weekday; + +} } //namespace gregorian + + + +#endif diff --git a/thirdparty/boost/date_time/gregorian/parsers.hpp b/thirdparty/boost/date_time/gregorian/parsers.hpp new file mode 100644 index 0000000..0bf936f --- /dev/null +++ b/thirdparty/boost/date_time/gregorian/parsers.hpp @@ -0,0 +1,91 @@ +#ifndef GREGORIAN_PARSERS_HPP___ +#define GREGORIAN_PARSERS_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/date_parsing.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //! Return special_value from string argument + /*! Return special_value from string argument. If argument is + * not one of the special value names (defined in src/gregorian/names.hpp), + * return 'not_special' */ + BOOST_DATE_TIME_DECL special_values special_value_from_string(const std::string& s); + + //! Deprecated: Use from_simple_string + inline date from_string(std::string s) { + return date_time::parse_date(s); + } + + //! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted) + inline date from_simple_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_iso); + } + + //! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted) + inline date from_us_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_us); + } + + //! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted) + inline date from_uk_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_dmy); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date from_undelimited_string(std::string s) { + return date_time::parse_undelimited_date(s); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date date_from_iso_string(const std::string& s) { + return date_time::parse_undelimited_date(s); + } + +#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS)) + //! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted + /* Arguments passed in by-value for convertability of char[] + * to iterator_type. Calls to from_stream_type are by-reference + * since conversion is already done */ + template + inline date from_stream(iterator_type beg, iterator_type end) { + if(beg == end) + { + return date(not_a_date_time); + } + typedef typename std::iterator_traits::value_type value_type; + return date_time::from_stream_type(beg, end, value_type()); + } +#endif //BOOST_NO_STD_ITERATOR_TRAITS + +#if (defined(_MSC_VER) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_string(const std::string& s){ + return date_time::from_simple_string_type(s); + } +# if !defined(BOOST_NO_STD_WSTRING) + //! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_wstring(const std::wstring& s){ + return date_time::from_simple_string_type(s); + } +# endif // BOOST_NO_STD_WSTRING +#endif + +} } //namespace gregorian + +#endif diff --git a/thirdparty/boost/date_time/gregorian_calendar.hpp b/thirdparty/boost/date_time/gregorian_calendar.hpp new file mode 100644 index 0000000..b249851 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian_calendar.hpp @@ -0,0 +1,70 @@ +#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__ +#define DATE_TIME_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +namespace boost { +namespace date_time { + + + //! An implementation of the Gregorian calendar + /*! This is a parameterized implementation of a proleptic Gregorian Calendar that + can be used in the creation of date systems or just to perform calculations. + All the methods of this class are static functions, so the intent is to + never create instances of this class. + @param ymd_type_ Struct type representing the year, month, day. The ymd_type must + define a of types for the year, month, and day. These types need to be + arithmetic types. + @param date_int_type_ Underlying type for the date count. Must be an arithmetic type. + */ + template + class gregorian_calendar_base { + public: + //! define a type a date split into components + typedef ymd_type_ ymd_type; + //! define a type for representing months + typedef typename ymd_type::month_type month_type; + //! define a type for representing days + typedef typename ymd_type::day_type day_type; + //! Type to hold a stand alone year value (eg: 2002) + typedef typename ymd_type::year_type year_type; + //! Define the integer type to use for internal calculations + typedef date_int_type_ date_int_type; + + + static unsigned short day_of_week(const ymd_type& ymd); + static int week_number(const ymd_type&ymd); + //static unsigned short day_of_year(date_int_type); + static date_int_type day_number(const ymd_type& ymd); + static date_int_type julian_day_number(const ymd_type& ymd); + static long modjulian_day_number(const ymd_type& ymd); + static ymd_type from_day_number(date_int_type); + static ymd_type from_julian_day_number(date_int_type); + static ymd_type from_modjulian_day_number(long); + static bool is_leap_year(year_type); + static unsigned short end_of_month_day(year_type y, month_type m); + static ymd_type epoch(); + static unsigned short days_in_week(); + + }; + + + +} } //namespace + +#ifndef NO_BOOST_DATE_TIME_INLINE +#include "boost/date_time/gregorian_calendar.ipp" +#endif + + + +#endif + + diff --git a/thirdparty/boost/date_time/gregorian_calendar.ipp b/thirdparty/boost/date_time/gregorian_calendar.ipp new file mode 100644 index 0000000..9118c44 --- /dev/null +++ b/thirdparty/boost/date_time/gregorian_calendar.ipp @@ -0,0 +1,219 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#ifndef NO_BOOST_DATE_TIME_INLINE + #undef BOOST_DATE_TIME_INLINE + #define BOOST_DATE_TIME_INLINE inline +#endif + +namespace boost { +namespace date_time { + //! Return the day of the week (0==Sunday, 1==Monday, etc) + /*! Converts a the year-month-day into a day of the week number + */ + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::day_of_week(const ymd_type& ymd) { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year - a); + unsigned short m = static_cast(ymd.month + 12*a - 2); + unsigned short d = static_cast((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7); + //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n"; + return d; + } + + //!Return the iso week number for the date + /*!Implements the rules associated with the iso 8601 week number. + Basically the rule is that Week 1 of the year is the week that contains + January 4th or the week that contains the first Thursday in January. + Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000. + */ + template + BOOST_DATE_TIME_INLINE + int + gregorian_calendar_base::week_number(const ymd_type& ymd) { + unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1)); + unsigned long juliantoday = julian_day_number(ymd); + unsigned long day = (julianbegin + 3) % 7; + unsigned long week = (juliantoday + day - julianbegin + 4)/7; + + if ((week >= 1) && (week <= 52)) { + return week; + } + + if ((week == 53)) { + if((day==6) ||(day == 5 && is_leap_year(ymd.year))) { + return week; //under these circumstances week == 53. + } else { + return 1; //monday - wednesday is in week 1 of next year + } + } + //if the week is not in current year recalculate using the previous year as the beginning year + else if (week == 0) { + julianbegin = julian_day_number(ymd_type(static_cast(ymd.year-1),1,1)); + juliantoday = julian_day_number(ymd); + day = (julianbegin + 3) % 7; + week = (juliantoday + day - julianbegin + 4)/7; + return week; + } + + return week; //not reachable -- well except if day == 5 and is_leap_year != true + + } + + //! Convert a ymd_type into a day number + /*! The day number is an absolute number of days since the start of count + */ + template + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base::day_number(const ymd_type& ymd) + { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year + 4800 - a); + unsigned short m = static_cast(ymd.month + 12*a - 3); + unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045; + return d; + } + + //! Convert a year-month-day into the julian day number + /*! Since this implementation uses julian day internally, this is the same as the day_number. + */ + template + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base::julian_day_number(const ymd_type& ymd) + { + return day_number(ymd); + } + + //! Convert year-month-day into a modified julian day number + /*! The day number is an absolute number of days. + * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC + */ + template + BOOST_DATE_TIME_INLINE + long + gregorian_calendar_base::modjulian_day_number(const ymd_type& ymd) + { + return julian_day_number(ymd)-2400001; //prerounded + } + + //! Change a day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a + 3)/146097; + date_int_type c = a-((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - (1461*d)/4; + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(static_cast(year),month,day); + } + + //! Change a day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_julian_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a+3)/146097; + date_int_type c = a - ((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - ((1461*d)/4); + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(year,month,day); + } + + //! Change a modified julian day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_modjulian_day_number(long dayNumber) { + date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded + return from_julian_day_number(jd); + } + + //! Determine if the provided year is a leap year + /*! + *@return true if year is a leap year, false otherwise + */ + template + BOOST_DATE_TIME_INLINE + bool + gregorian_calendar_base::is_leap_year(year_type year) + { + //divisible by 4, not if divisible by 100, but true if divisible by 400 + return (!(year % 4)) && ((year % 100) || (!(year % 400))); + } + + //! Calculate the last day of the month + /*! Find the day which is the end of the month given year and month + * No error checking is performed. + */ + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::end_of_month_day(year_type year, + month_type month) + { + switch (month) { + case 2: + if (is_leap_year(year)) { + return 29; + } else { + return 28; + }; + case 4: + case 6: + case 9: + case 11: + return 30; + default: + return 31; + }; + + } + + //! Provide the ymd_type specification for the calandar start + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::epoch() + { + return ymd_type(1400,1,1); + } + + //! Defines length of a week for week calculations + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::days_in_week() + { + return 7; + } + + +} } //namespace gregorian + + diff --git a/thirdparty/boost/date_time/int_adapter.hpp b/thirdparty/boost/date_time/int_adapter.hpp new file mode 100644 index 0000000..7c9e809 --- /dev/null +++ b/thirdparty/boost/date_time/int_adapter.hpp @@ -0,0 +1,507 @@ +#ifndef _DATE_TIME_INT_ADAPTER_HPP__ +#define _DATE_TIME_INT_ADAPTER_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/config.hpp" +#include "boost/limits.hpp" //work around compilers without limits +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/locale_config.hpp" +#include + +namespace boost { +namespace date_time { + + +//! Adapter to create integer types with +-infinity, and not a value +/*! This class is used internally in counted date/time representations. + * It adds the floating point like features of infinities and + * not a number. It also provides mathmatical operations with + * consideration to special values following these rules: + *@code + * +infinity - infinity == Not A Number (NAN) + * infinity * non-zero == infinity + * infinity * zero == NAN + * +infinity * -integer == -infinity + * infinity / infinity == NAN + * infinity * infinity == infinity + *@endcode + */ +template +class int_adapter { +public: + typedef int_type_ int_type; + int_adapter(int_type v) : + value_(v) + {} + static bool has_infinity() + { + return true; + } + static const int_adapter pos_infinity() + { + return (::std::numeric_limits::max)(); + } + static const int_adapter neg_infinity() + { + return (::std::numeric_limits::min)(); + } + static const int_adapter not_a_number() + { + return (::std::numeric_limits::max)()-1; + } + static int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::max)()-2; + } + static int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::min)()+1; + } + static int_adapter from_special(special_values sv) + { + switch (sv) { + case not_a_date_time: return not_a_number(); + case neg_infin: return neg_infinity(); + case pos_infin: return pos_infinity(); + case max_date_time: return (max)(); + case min_date_time: return (min)(); + default: return not_a_number(); + } + } + static bool is_inf(int_type v) + { + return (v == neg_infinity().as_number() || + v == pos_infinity().as_number()); + } + static bool is_neg_inf(int_type v) + { + return (v == neg_infinity().as_number()); + } + static bool is_pos_inf(int_type v) + { + return (v == pos_infinity().as_number()); + } + static bool is_not_a_number(int_type v) + { + return (v == not_a_number().as_number()); + } + //! Returns either special value type or is_not_special + static special_values to_special(int_type v) + { + if (is_not_a_number(v)) return not_a_date_time; + if (is_neg_inf(v)) return neg_infin; + if (is_pos_inf(v)) return pos_infin; + return not_special; + } + + //-3 leaves room for representations of infinity and not a date + static int_type maxcount() + { + return (::std::numeric_limits::max)()-3; + } + bool is_infinity() const + { + return (value_ == neg_infinity().as_number() || + value_ == pos_infinity().as_number()); + } + bool is_pos_infinity()const + { + return(value_ == pos_infinity().as_number()); + } + bool is_neg_infinity()const + { + return(value_ == neg_infinity().as_number()); + } + bool is_nan() const + { + return (value_ == not_a_number().as_number()); + } + bool is_special() const + { + return(is_infinity() || is_nan()); + } + bool operator==(const int_adapter& rhs) const + { + return (compare(rhs) == 0); + } + bool operator==(const int& rhs) const + { + // quiets compiler warnings + bool is_signed = std::numeric_limits::is_signed; + if(!is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return false; + } + } + return (compare(rhs) == 0); + } + bool operator!=(const int_adapter& rhs) const + { + return (compare(rhs) != 0); + } + bool operator!=(const int& rhs) const + { + // quiets compiler warnings + bool is_signed = std::numeric_limits::is_signed; + if(!is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) != 0); + } + bool operator<(const int_adapter& rhs) const + { + return (compare(rhs) == -1); + } + bool operator<(const int& rhs) const + { + // quiets compiler warnings + bool is_signed = std::numeric_limits::is_signed; + if(!is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) == -1); + } + bool operator>(const int_adapter& rhs) const + { + return (compare(rhs) == 1); + } + int_type as_number() const + { + return value_; + } + //! Returns either special value type or is_not_special + special_values as_special() const + { + return int_adapter::to_special(value_); + } + //creates nasty ambiguities +// operator int_type() const +// { +// return value_; +// } + + /*! Operator allows for adding dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + inline + int_adapter operator+(const int_adapter& rhs) const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + } + return int_adapter(value_ + rhs.as_number()); + } + + int_adapter operator+(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ + rhs); + } + + /*! Operator allows for subtracting dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + inline + int_adapter operator-(const int_adapter& rhs)const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + } + return int_adapter(value_ - rhs.as_number()); + } + int_adapter operator-(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ - rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator*(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator*(const int rhs) const + { + if(is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator/(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ / rhs.value_); + } + } + return int_adapter(value_ / rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator/(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ / rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator%(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ % rhs.value_); + } + } + return int_adapter(value_ % rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator%(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ % rhs); + } +private: + int_type value_; + + //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs + int compare(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(this->is_nan() || rhs.is_nan()) { + if(this->is_nan() && rhs.is_nan()) { + return 0; // equal + } + else { + return 2; // nan + } + } + if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) || + (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) ) + { + return -1; // less than + } + if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) || + (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) { + return 1; // greater than + } + } + if(value_ < rhs.value_) return -1; + if(value_ > rhs.value_) return 1; + // implied-> if(value_ == rhs.value_) + return 0; + } + /* When multiplying and dividing with at least 1 special value + * very simmilar rules apply. In those cases where the rules + * are different, they are handled in the respective operator + * function. */ + //! Assumes at least 'this' or 'rhs' is a special value + int_adapter mult_div_specials(const int_adapter& rhs)const + { + int min_value; + // quiets compiler warnings + bool is_signed = std::numeric_limits::is_signed; + if(is_signed) { + min_value = 0; + } + else { + min_value = 1;// there is no zero with unsigned + } + if(this->is_nan() || rhs.is_nan()) { + return int_adapter(not_a_number()); + } + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + /* Overloaded function necessary because of special + * situation where int_adapter is instantiated with + * 'unsigned' and func is called with negative int. + * It would produce incorrect results since 'unsigned' + * wraps around when initialized with a negative value */ + //! Assumes 'this' is a special value + int_adapter mult_div_specials(const int& rhs) const + { + int min_value; + // quiets compiler warnings + bool is_signed = std::numeric_limits::is_signed; + if(is_signed) { + min_value = 0; + } + else { + min_value = 1;// there is no zero with unsigned + } + if(this->is_nan()) { + return int_adapter(not_a_number()); + } + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + +}; + +#ifndef BOOST_DATE_TIME_NO_LOCALE + /*! Expected output is either a numeric representation + * or a special values representation.
+ * Ex. "12", "+infinity", "not-a-number", etc. */ + //template, typename int_type> + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const int_adapter& ia) + { + if(ia.is_special()) { + // switch copied from date_names_put.hpp + switch(ia.as_special()) + { + case not_a_date_time: + os << "not-a-number"; + break; + case pos_infin: + os << "+infinity"; + break; + case neg_infin: + os << "-infinity"; + break; + default: + os << ""; + } + } + else { + os << ia.as_number(); + } + return os; + } +#endif + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/iso_format.hpp b/thirdparty/boost/date_time/iso_format.hpp new file mode 100644 index 0000000..ae01f48 --- /dev/null +++ b/thirdparty/boost/date_time/iso_format.hpp @@ -0,0 +1,303 @@ +#ifndef ISO_FORMAT_HPP___ +#define ISO_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide common iso formatting spec +template +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + + //! ISO char for a year -- used in durations + static charT year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static charT month_sep_char() + { + return '-'; + } + //! ISO char for a day + static charT day_sep_char() + { + return '-'; + } + //! char for minute + static charT hour_sep_char() + { + return ':'; + } + //! char for minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + //! ISO char for a period + static charT period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static charT time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static charT week_start_char() + { + return 'W'; + } + + //! Separators for periods + static charT period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static charT time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static charT fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(charT sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(charT sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(charT sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static charT element_sep_char() + { + return '-'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Class to provide common iso formatting spec +template<> +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + + //! ISO char for a year -- used in durations + static wchar_t year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static wchar_t month_sep_char() + { + return '-'; + } + //! ISO char for a day + static wchar_t day_sep_char() + { + return '-'; + } + //! char for minute + static wchar_t hour_sep_char() + { + return ':'; + } + //! char for minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + //! ISO char for a period + static wchar_t period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static wchar_t time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static wchar_t week_start_char() + { + return 'W'; + } + + //! Separators for periods + static wchar_t period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static wchar_t time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static wchar_t fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(wchar_t sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(wchar_t sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(wchar_t sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static wchar_t element_sep_char() + { + return '-'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING + +//! Format description for iso normal YYYYMMDD +template +class iso_format : public iso_format_base { +public: + //! The ios standard format doesn't use char separators + static bool has_date_sep_chars() + { + return false; + } +}; + +//! Extended format uses seperators YYYY-MM-DD +template +class iso_extended_format : public iso_format_base { +public: + //! Extended format needs char separators + static bool has_date_sep_chars() + { + return true; + } + +}; + +} } //namespace date_time + + + + +#endif diff --git a/thirdparty/boost/date_time/local_time/conversion.hpp b/thirdparty/boost/date_time/local_time/conversion.hpp new file mode 100644 index 0000000..afa3d04 --- /dev/null +++ b/thirdparty/boost/date_time/local_time/conversion.hpp @@ -0,0 +1,35 @@ +#ifndef DATE_TIME_LOCAL_TIME_CONVERSION_HPP__ +#define DATE_TIME_LOCAL_TIME_CONVERSION_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/posix_time/conversion.hpp" +#include "boost/date_time/c_time.hpp" +#include "boost/date_time/local_time/local_date_time.hpp" + +namespace boost { +namespace local_time { + +//! Function that creates a tm struct from a local_date_time +inline +tm to_tm(const local_date_time& lt) { + tm lt_tm; + lt_tm = posix_time::to_tm(lt.local_time()); + if(lt.is_dst()){ + lt_tm.tm_isdst = 1; + } + else{ + lt_tm.tm_isdst = 0; + } + return lt_tm; +} + + +}} // namespaces +#endif // DATE_TIME_LOCAL_TIME_CONVERSION_HPP__ diff --git a/thirdparty/boost/date_time/local_time/custom_time_zone.hpp b/thirdparty/boost/date_time/local_time/custom_time_zone.hpp new file mode 100644 index 0000000..7ddd876 --- /dev/null +++ b/thirdparty/boost/date_time/local_time/custom_time_zone.hpp @@ -0,0 +1,169 @@ +#ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__ +#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__ + +/* Copyright (c) 2003-2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/time_zone_base.hpp" +#include "boost/date_time/time_zone_names.hpp" +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/date_time/local_time/dst_transition_day_rules.hpp" +#include "boost/date_time/string_convert.hpp" +//#include "boost/date_time/special_defs.hpp" +#include "boost/shared_ptr.hpp" + +namespace boost { +namespace local_time { + + //typedef boost::date_time::time_zone_names time_zone_names; + typedef boost::date_time::dst_adjustment_offsets dst_adjustment_offsets; + //typedef boost::date_time::time_zone_base time_zone; + typedef boost::shared_ptr dst_calc_rule_ptr; + + //! A real time zone + template + class custom_time_zone_base : public date_time::time_zone_base { + public: + typedef boost::posix_time::time_duration time_duration_type; + typedef date_time::time_zone_base base_type; + typedef typename base_type::string_type string_type; + typedef typename base_type::stringstream_type stringstream_type; + typedef date_time::time_zone_names_base time_zone_names; + typedef CharT char_type; + + custom_time_zone_base(const time_zone_names& zone_names, + const time_duration_type& utc_offset, + const dst_adjustment_offsets& dst_shift, + boost::shared_ptr calc_rule) : + zone_names_(zone_names), + base_utc_offset_(utc_offset), + dst_offsets_(dst_shift), + dst_calc_rules_(calc_rule) + {}; + virtual ~custom_time_zone_base() {}; + virtual string_type dst_zone_abbrev() const + { + return zone_names_.dst_zone_abbrev(); + } + virtual string_type std_zone_abbrev() const + { + return zone_names_.std_zone_abbrev(); + } + virtual string_type dst_zone_name() const + { + return zone_names_.dst_zone_name(); + } + virtual string_type std_zone_name() const + { + return zone_names_.std_zone_name(); + } + //! True if zone uses daylight savings adjustments + virtual bool has_dst() const + { + return (dst_calc_rules_); //if calc_rule is set the tz has dst + } + //! Local time that DST starts -- NADT if has_dst is false + virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const + { + gregorian::date d(gregorian::not_a_date_time); + if (dst_calc_rules_) { + d = dst_calc_rules_->start_day(y); + } + return posix_time::ptime(d, dst_offsets_.dst_start_offset_); + } + //! Local time that DST ends -- NADT if has_dst is false + virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const + { + gregorian::date d(gregorian::not_a_date_time); + if (dst_calc_rules_) { + d = dst_calc_rules_->end_day(y); + } + return posix_time::ptime(d, dst_offsets_.dst_end_offset_); + } + //! Base offset from UTC for zone (eg: -07:30:00) + virtual time_duration_type base_utc_offset() const + { + return base_utc_offset_; + } + //! Adjustment forward or back made while DST is in effect + virtual time_duration_type dst_offset() const + { + return dst_offsets_.dst_adjust_; + } + //! Returns a POSIX time_zone string for this object + virtual string_type to_posix_string() const + { + // std offset dst [offset],start[/time],end[/time] - w/o spaces + stringstream_type ss; + ss.fill('0'); + boost::shared_ptr no_rules; + // std + ss << std_zone_abbrev(); + // offset + if(base_utc_offset().is_negative()) { + // inverting the sign guarantees we get two digits + ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours(); + } + else { + ss << '+' << std::setw(2) << base_utc_offset().hours(); + } + if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) { + ss << ':' << std::setw(2) << base_utc_offset().minutes(); + if(base_utc_offset().seconds() != 0) { + ss << ':' << std::setw(2) << base_utc_offset().seconds(); + } + } + if(dst_calc_rules_ != no_rules) { + // dst + ss << dst_zone_abbrev(); + // dst offset + if(dst_offset().is_negative()) { + // inverting the sign guarantees we get two digits + ss << '-' << std::setw(2) << dst_offset().invert_sign().hours(); + } + else { + ss << '+' << std::setw(2) << dst_offset().hours(); + } + if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) { + ss << ':' << std::setw(2) << dst_offset().minutes(); + if(dst_offset().seconds() != 0) { + ss << ':' << std::setw(2) << dst_offset().seconds(); + } + } + // start/time + ss << ',' << date_time::convert_string_type(dst_calc_rules_->start_rule_as_string()) << '/' + << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':' + << std::setw(2) << dst_offsets_.dst_start_offset_.minutes(); + if(dst_offsets_.dst_start_offset_.seconds() != 0) { + ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds(); + } + // end/time + ss << ',' << date_time::convert_string_type(dst_calc_rules_->end_rule_as_string()) << '/' + << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':' + << std::setw(2) << dst_offsets_.dst_end_offset_.minutes(); + if(dst_offsets_.dst_end_offset_.seconds() != 0) { + ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds(); + } + } + + return ss.str(); + } + private: + time_zone_names zone_names_; + bool has_dst_; + time_duration_type base_utc_offset_; + dst_adjustment_offsets dst_offsets_; + boost::shared_ptr dst_calc_rules_; + }; + + typedef custom_time_zone_base custom_time_zone; + +} }//namespace + + + +#endif diff --git a/thirdparty/boost/date_time/local_time/date_duration_operators.hpp b/thirdparty/boost/date_time/local_time/date_duration_operators.hpp new file mode 100644 index 0000000..8facb0b --- /dev/null +++ b/thirdparty/boost/date_time/local_time/date_duration_operators.hpp @@ -0,0 +1,115 @@ +#ifndef LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___ +#define LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#include "boost/date_time/local_time/local_date_time.hpp" + +namespace boost { +namespace local_time { + + /*!@file date_duration_operators.hpp Operators for local_date_time and + * optional gregorian types. Operators use snap-to-end-of-month behavior. + * Further details on this behavior can be found in reference for + * date_time/date_duration_types.hpp and documentation for + * month and year iterators. + */ + + + /*! Adds a months object and a local_date_time. Result will be same + * day-of-month as local_date_time unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + local_date_time + operator+(const local_date_time& t, const boost::gregorian::months& m) + { + return t + m.get_offset(t.utc_time().date()); + } + + /*! Adds a months object to a local_date_time. Result will be same + * day-of-month as local_date_time unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + local_date_time + operator+=(local_date_time& t, const boost::gregorian::months& m) + { + return t += m.get_offset(t.utc_time().date()); + } + + /*! Subtracts a months object and a local_date_time. Result will be same + * day-of-month as local_date_time unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + local_date_time + operator-(const local_date_time& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t + m.get_neg_offset(t.utc_time().date()); + } + + /*! Subtracts a months object from a local_date_time. Result will be same + * day-of-month as local_date_time unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + local_date_time + operator-=(local_date_time& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t += m.get_neg_offset(t.utc_time().date()); + } + + // local_date_time & years + + /*! Adds a years object and a local_date_time. Result will be same + * month and day-of-month as local_date_time unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + local_date_time + operator+(const local_date_time& t, const boost::gregorian::years& y) + { + return t + y.get_offset(t.utc_time().date()); + } + + /*! Adds a years object to a local_date_time. Result will be same + * month and day-of-month as local_date_time unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + local_date_time + operator+=(local_date_time& t, const boost::gregorian::years& y) + { + return t += y.get_offset(t.utc_time().date()); + } + + /*! Subtracts a years object and a local_date_time. Result will be same + * month and day-of-month as local_date_time unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + local_date_time + operator-(const local_date_time& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t + y.get_neg_offset(t.utc_time().date()); + } + + /*! Subtracts a years object from a local_date_time. Result will be same + * month and day-of-month as local_date_time unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + local_date_time + operator-=(local_date_time& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t += y.get_neg_offset(t.utc_time().date()); + } + + +}} // namespaces + +#endif // LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___ diff --git a/thirdparty/boost/date_time/local_time/dst_transition_day_rules.hpp b/thirdparty/boost/date_time/local_time/dst_transition_day_rules.hpp new file mode 100644 index 0000000..e4e2545 --- /dev/null +++ b/thirdparty/boost/date_time/local_time/dst_transition_day_rules.hpp @@ -0,0 +1,77 @@ +#ifndef LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__ +#define LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/dst_transition_generators.hpp" + +namespace boost { +namespace local_time { + + //! Provides rule of the form starting Apr 30 ending Oct 21 + typedef date_time::dst_day_calc_rule dst_calc_rule; + + struct partial_date_rule_spec + { + typedef gregorian::date date_type; + typedef gregorian::partial_date start_rule; + typedef gregorian::partial_date end_rule; + }; + + //! Provides rule of the form first Sunday in April, last Saturday in Oct + typedef date_time::day_calc_dst_rule partial_date_dst_rule; + + struct first_last_rule_spec + { + typedef gregorian::date date_type; + typedef gregorian::first_kday_of_month start_rule; + typedef gregorian::last_kday_of_month end_rule; + }; + + //! Provides rule of the form first Sunday in April, last Saturday in Oct + typedef date_time::day_calc_dst_rule first_last_dst_rule; + + struct last_last_rule_spec + { + typedef gregorian::date date_type; + typedef gregorian::last_kday_of_month start_rule; + typedef gregorian::last_kday_of_month end_rule; + }; + + //! Provides rule of the form last Sunday in April, last Saturday in Oct + typedef date_time::day_calc_dst_rule last_last_dst_rule; + + struct nth_last_rule_spec + { + typedef gregorian::date date_type; + typedef gregorian::nth_kday_of_month start_rule; + typedef gregorian::last_kday_of_month end_rule; + }; + + //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April, last Sunday in Oct + typedef date_time::day_calc_dst_rule nth_last_dst_rule; + + struct nth_kday_rule_spec + { + typedef gregorian::date date_type; + typedef gregorian::nth_kday_of_month start_rule; + typedef gregorian::nth_kday_of_month end_rule; + }; + + //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October + typedef date_time::day_calc_dst_rule nth_kday_dst_rule; + //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October + typedef date_time::day_calc_dst_rule nth_day_of_the_week_in_month_dst_rule; + + +} }//namespace + + +#endif diff --git a/thirdparty/boost/date_time/local_time/local_date_time.hpp b/thirdparty/boost/date_time/local_time/local_date_time.hpp new file mode 100644 index 0000000..e606c2a --- /dev/null +++ b/thirdparty/boost/date_time/local_time/local_date_time.hpp @@ -0,0 +1,525 @@ +#ifndef LOCAL_TIME_LOCAL_DATE_TIME_HPP__ +#define LOCAL_TIME_LOCAL_DATE_TIME_HPP__ + +/* Copyright (c) 2003-2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/time.hpp" +#include "boost/date_time/posix_time/posix_time.hpp" //todo remove? +#include "boost/shared_ptr.hpp" +#include "boost/date_time/dst_rules.hpp" +#include "boost/date_time/time_zone_base.hpp" +#include "boost/date_time/special_defs.hpp" +#include +#include + +namespace boost { +namespace local_time { + + //! simple exception for reporting when STD or DST cannot be determined + struct ambiguous_result : public std::logic_error + { + ambiguous_result (std::string _msg="") : + std::logic_error(std::string("Daylight Savings Results are ambiguous: " + _msg)) {} + }; + //! simple exception for when time label given cannot exist + struct time_label_invalid : public std::logic_error + { + time_label_invalid (std::string _msg="") : + std::logic_error(std::string("Time label given is invalid: " + _msg)) {} + }; + struct dst_not_valid: public std::logic_error + { + dst_not_valid(std::string _msg="") : + std::logic_error(std::string("is_dst flag does not match resulting dst for time label given: " + _msg)) {} + }; + + //TODO: I think these should be in local_date_time_base and not + // necessarily brought into the namespace + using date_time::time_is_dst_result; + using date_time::is_in_dst; + using date_time::is_not_in_dst; + using date_time::ambiguous; + using date_time::invalid_time_label; + + //! Representation of "wall-clock" time in a particular time zone + /*! Representation of "wall-clock" time in a particular time zone + * Local_date_time_base holds a time value (date and time offset from 00:00) + * along with a time zone. The time value is stored as UTC and conversions + * to wall clock time are made as needed. This approach allows for + * operations between wall-clock times in different time zones, and + * daylight savings time considerations, to be made. Time zones are + * required to be in the form of a boost::shared_ptr. + */ + template > + class local_date_time_base : public date_time::base_time { + public: + typedef utc_time_ utc_time_type; + typedef typename utc_time_type::time_duration_type time_duration_type; + typedef typename utc_time_type::date_type date_type; + typedef typename date_type::duration_type date_duration_type; + typedef typename utc_time_type::time_system_type time_system_type; + /*! This constructor interprets the passed time as a UTC time. + * So, for example, if the passed timezone is UTC-5 then the + * time will be adjusted back 5 hours. The time zone allows for + * automatic calculation of whether the particular time is adjusted for + * daylight savings, etc. + * If the time zone shared pointer is null then time stays unadjusted. + *@param t A UTC time + *@param tz Timezone for to adjust the UTC time to. + */ + local_date_time_base(utc_time_type t, + boost::shared_ptr tz) : + date_time::base_time(t), + zone_(tz) + { + // param was already utc so nothing more to do + } + + /*! This constructs a local time -- the passed time information + * understood to be in the passed tz. The DST flag must be passed + * to indicate whether the time is in daylight savings or not. + * @throws -- time_label_invalid if the time passed does not exist in + * the given locale. The non-existent case occurs typically + * during the shift-back from daylight savings time. When + * the clock is shifted forward a range of times + * (2 am to 3 am in the US) is skipped and hence is invalid. + * @throws -- dst_not_valid if the DST flag is passed for a period + * where DST is not active. + */ + local_date_time_base(date_type d, + time_duration_type td, + boost::shared_ptr tz, + bool dst_flag) : //necessary for constr_adj() + date_time::base_time(construction_adjustment(utc_time_type(d, td), tz, dst_flag)), + zone_(tz) + { + if(tz != boost::shared_ptr() && tz->has_dst()){ + + // d & td are already local so we use them + time_is_dst_result result = check_dst(d, td, tz); + bool in_dst = (result == is_in_dst); // less processing than is_dst() + + // ambig occurs at end, invalid at start + if(result == invalid_time_label){ + // Ex: 2:15am local on trans-in day in nyc, dst_flag irrelevant + std::stringstream ss; + ss << "time given: " << d << ' ' << td; + throw time_label_invalid(ss.str()); + } + else if(result != ambiguous && in_dst != dst_flag){ + // is dst_flag accurate? + // Ex: false flag in NYC in June + std::stringstream ss; + ss << "flag given: " << (dst_flag ? "dst=true" : "dst=false") + << ", dst calculated: " << (in_dst ? "dst=true" : "dst=false"); + throw dst_not_valid(ss.str()); + } + + // everything checks out and conversion to utc already done + } + } + + //TODO maybe not the right set...Ignore the last 2 for now... + enum DST_CALC_OPTIONS { EXCEPTION_ON_ERROR, NOT_DATE_TIME_ON_ERROR }; + //ASSUME_DST_ON_ERROR, ASSUME_NOT_DST_ON_ERROR }; + + /*! This constructs a local time -- the passed time information + * understood to be in the passed tz. The DST flag is calculated + * according to the specified rule. + */ + local_date_time_base(date_type d, + time_duration_type td, + boost::shared_ptr tz, + DST_CALC_OPTIONS calc_option) : + // dummy value - time_ is set in constructor code + date_time::base_time(utc_time_type(d,td)), + zone_(tz) + { + time_is_dst_result result = check_dst(d, td, tz); + if(result == ambiguous) { + if(calc_option == EXCEPTION_ON_ERROR){ + std::stringstream ss; + ss << "time given: " << d << ' ' << td; + throw ambiguous_result(ss.str()); + } + else{ // NADT on error + this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time)); + } + } + else if(result == invalid_time_label){ + if(calc_option == EXCEPTION_ON_ERROR){ + std::stringstream ss; + ss << "time given: " << d << ' ' << td; + throw time_label_invalid(ss.str()); + } + else{ // NADT on error + this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time)); + } + } + else if(result == is_in_dst){ + utc_time_type t = + construction_adjustment(utc_time_type(d, td), tz, true); + this->time_ = posix_time::posix_time_system::get_time_rep(t.date(), + t.time_of_day()); + } + else{ + utc_time_type t = + construction_adjustment(utc_time_type(d, td), tz, false); + this->time_ = posix_time::posix_time_system::get_time_rep(t.date(), + t.time_of_day()); + } + } + + + //! Determines if given time label is in daylight savings for given zone + /*! Determines if given time label is in daylight savings for given zone. + * Takes a date and time_duration representing a local time, along + * with time zone, and returns a time_is_dst_result object as result. + */ + static time_is_dst_result check_dst(date_type d, + time_duration_type td, + boost::shared_ptr tz) + { + if(tz != boost::shared_ptr() && tz->has_dst()) { + typedef typename date_time::dst_calculator dst_calculator; + return dst_calculator::local_is_dst( + d, td, + tz->dst_local_start_time(d.year()).date(), + tz->dst_local_start_time(d.year()).time_of_day(), + tz->dst_local_end_time(d.year()).date(), + tz->dst_local_end_time(d.year()).time_of_day(), + tz->dst_offset() + ); + } + else{ + return is_not_in_dst; + } + } + + //! Simple destructor, releases time zone if last referrer + ~local_date_time_base() {}; + + //! Copy constructor + local_date_time_base(const local_date_time_base& rhs) : + date_time::base_time(rhs), + zone_(rhs.zone_) + {} + + //! Special values constructor + explicit local_date_time_base(const boost::date_time::special_values sv, + boost::shared_ptr tz = boost::shared_ptr()) : + date_time::base_time(utc_time_type(sv)), + zone_(tz) + {} + + //! returns time zone associated with calling instance + boost::shared_ptr zone() const + { + return zone_; + } + //! returns false is time_zone is NULL and if time value is a special_value + bool is_dst() const + { + if(zone_ != boost::shared_ptr() && zone_->has_dst() && !this->is_special()) { + // check_dst takes a local time, *this is utc + utc_time_type lt(this->time_); + lt += zone_->base_utc_offset(); + // dst_offset only needs to be considered with ambiguous time labels + // make that adjustment there + + switch(check_dst(lt.date(), lt.time_of_day(), zone_)){ + case is_not_in_dst: + return false; + case is_in_dst: + return true; + case ambiguous: + if(lt + zone_->dst_offset() < zone_->dst_local_end_time(lt.date().year())) { + return true; + } + break; + case invalid_time_label: + if(lt >= zone_->dst_local_start_time(lt.date().year())) { + return true; + } + break; + } + } + return false; + } + //! Returns object's time value as a utc representation + utc_time_type utc_time() const + { + return utc_time_type(this->time_); + } + //! Returns object's time value as a local representation + utc_time_type local_time() const + { + if(zone_ != boost::shared_ptr()){ + utc_time_type lt = this->utc_time() + zone_->base_utc_offset(); + if (is_dst()) { + lt += zone_->dst_offset(); + } + return lt; + } + return utc_time_type(this->time_); + } + //! Returns string in the form "2003-Aug-20 05:00:00 EDT" + /*! Returns string in the form "2003-Aug-20 05:00:00 EDT". If + * time_zone is NULL the time zone abbreviation will be "UTC". The time + * zone abbrev will not be included if calling object is a special_value*/ + std::string to_string() const + { + //TODO is this a temporary function ??? + std::stringstream ss; + if(this->is_special()){ + ss << utc_time(); + return ss.str(); + } + if(zone_ == boost::shared_ptr()) { + ss << utc_time() << " UTC"; + return ss.str(); + } + bool is_dst_ = is_dst(); + utc_time_type lt = this->utc_time() + zone_->base_utc_offset(); + if (is_dst_) { + lt += zone_->dst_offset(); + } + ss << local_time() << " "; + if (is_dst()) { + ss << zone_->dst_zone_abbrev(); + } + else { + ss << zone_->std_zone_abbrev(); + } + return ss.str(); + } + /*! returns a local_date_time_base in the given time zone with the + * optional time_duration added. */ + local_date_time_base local_time_in(boost::shared_ptr new_tz, + time_duration_type td=time_duration_type(0,0,0)) const + { + return local_date_time_base(utc_time_type(this->time_) + td, new_tz); + } + + //! Returns name of associated time zone or "Coordinated Universal Time". + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00" extended iso format). Empty string is returned for + * classes that do not use a time_zone */ + std::string zone_name(bool as_offset=false) const + { + if(zone_ == boost::shared_ptr()) { + if(as_offset) { + return std::string("Z"); + } + else { + return std::string("Coordinated Universal Time"); + } + } + if (is_dst()) { + if(as_offset) { + time_duration_type td = zone_->base_utc_offset(); + td += zone_->dst_offset(); + return zone_as_offset(td, ":"); + } + else { + return zone_->dst_zone_name(); + } + } + else { + if(as_offset) { + time_duration_type td = zone_->base_utc_offset(); + return zone_as_offset(td, ":"); + } + else { + return zone_->std_zone_name(); + } + } + } + //! Returns abbreviation of associated time zone or "UTC". + /*! Optional bool parameter will return time zone as an offset + * (ie "+0700" iso format). Empty string is returned for classes + * that do not use a time_zone */ + std::string zone_abbrev(bool as_offset=false) const + { + if(zone_ == boost::shared_ptr()) { + if(as_offset) { + return std::string("Z"); + } + else { + return std::string("UTC"); + } + } + if (is_dst()) { + if(as_offset) { + time_duration_type td = zone_->base_utc_offset(); + td += zone_->dst_offset(); + return zone_as_offset(td, ""); + } + else { + return zone_->dst_zone_abbrev(); + } + } + else { + if(as_offset) { + time_duration_type td = zone_->base_utc_offset(); + return zone_as_offset(td, ""); + } + else { + return zone_->std_zone_abbrev(); + } + } + } + + //! returns a posix_time_zone string for the associated time_zone. If no time_zone, "UTC+00" is returned. + std::string zone_as_posix_string() const + { + if(zone_ == shared_ptr()) { + return std::string("UTC+00"); + } + return zone_->to_posix_string(); + } + + //! Equality comparison operator + /*bool operator==(const date_time::base_time& rhs) const + { // fails due to rhs.time_ being protected + return date_time::base_time::operator==(rhs); + //return this->time_ == rhs.time_; + }*/ + //! Equality comparison operator + bool operator==(const local_date_time_base& rhs) const + { + return time_system_type::is_equal(this->time_, rhs.time_); + } + //! Non-Equality comparison operator + bool operator!=(const local_date_time_base& rhs) const + { + return !(*this == rhs); + } + //! Less than comparison operator + bool operator<(const local_date_time_base& rhs) const + { + return time_system_type::is_less(this->time_, rhs.time_); + } + //! Less than or equal to comparison operator + bool operator<=(const local_date_time_base& rhs) const + { + return (*this < rhs || *this == rhs); + } + //! Greater than comparison operator + bool operator>(const local_date_time_base& rhs) const + { + return !(*this <= rhs); + } + //! Greater than or equal to comparison operator + bool operator>=(const local_date_time_base& rhs) const + { + return (*this > rhs || *this == rhs); + } + + //! Local_date_time + date_duration + local_date_time_base operator+(const date_duration_type& dd) const + { + return local_date_time_base(time_system_type::add_days(this->time_,dd), zone_); + } + //! Local_date_time += date_duration + local_date_time_base operator+=(const date_duration_type& dd) + { + this->time_ = time_system_type::add_days(this->time_,dd); + return *this; + } + //! Local_date_time - date_duration + local_date_time_base operator-(const date_duration_type& dd) const + { + return local_date_time_base(time_system_type::subtract_days(this->time_,dd), zone_); + } + //! Local_date_time -= date_duration + local_date_time_base operator-=(const date_duration_type& dd) + { + this->time_ = time_system_type::subtract_days(this->time_,dd); + return *this; + } + //! Local_date_time + time_duration + local_date_time_base operator+(const time_duration_type& td) const + { + return local_date_time_base(time_system_type::add_time_duration(this->time_,td), zone_); + } + //! Local_date_time += time_duration + local_date_time_base operator+=(const time_duration_type& td) + { + this->time_ = time_system_type::add_time_duration(this->time_,td); + return *this; + } + //! Local_date_time - time_duration + local_date_time_base operator-(const time_duration_type& td) const + { + return local_date_time_base(time_system_type::subtract_time_duration(this->time_,td), zone_); + } + //! Local_date_time -= time_duration + local_date_time_base operator-=(const time_duration_type& td) + { + this->time_ = time_system_type::subtract_time_duration(this->time_,td); + return *this; + } + //! local_date_time -= local_date_time --> time_duration_type + time_duration_type operator-(const local_date_time_base& rhs) const + { + return utc_time_type(this->time_) - utc_time_type(rhs.time_); + } + private: + boost::shared_ptr zone_; + //bool is_dst_; + + /*! Adjust the passed in time to UTC? + */ + utc_time_type construction_adjustment(utc_time_type t, + boost::shared_ptr z, + bool dst_flag) + { + if(z != boost::shared_ptr()) { + if(dst_flag && z->has_dst()) { + t -= z->dst_offset(); + } // else no adjust + t -= z->base_utc_offset(); + } + return t; + } + + /*! Simple formatting code -- todo remove this? + */ + std::string zone_as_offset(const time_duration_type& td, + const std::string& separator) const + { + std::stringstream ss; + if(td.is_negative()) { + // a negative duration is represented as "-[h]h:mm" + // we require two digits for the hour. A positive duration + // with the %H flag will always give two digits + ss << "-"; + } + else { + ss << "+"; + } + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.hours()) + << separator + << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.minutes()); + return ss.str(); + } + }; + + //!Use the default parameters to define local_date_time + typedef local_date_time_base<> local_date_time; + +} } + + +#endif diff --git a/thirdparty/boost/date_time/local_time/local_time.hpp b/thirdparty/boost/date_time/local_time/local_time.hpp new file mode 100644 index 0000000..978ea4a --- /dev/null +++ b/thirdparty/boost/date_time/local_time/local_time.hpp @@ -0,0 +1,24 @@ +#ifndef LOCAL_TIME_LOCAL_TIME_HPP__ +#define LOCAL_TIME_LOCAL_TIME_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/date_time/local_time/local_date_time.hpp" +#include "boost/date_time/local_time/local_time_types.hpp" +#if !defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +#include "boost/date_time/local_time/local_time_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO +#include "boost/date_time/local_time/posix_time_zone.hpp" +#include "boost/date_time/local_time/custom_time_zone.hpp" +#include "boost/date_time/local_time/tz_database.hpp" +#include "boost/date_time/local_time/conversion.hpp" +#include "boost/date_time/time_zone_base.hpp" + + +#endif diff --git a/thirdparty/boost/date_time/local_time/local_time_io.hpp b/thirdparty/boost/date_time/local_time/local_time_io.hpp new file mode 100644 index 0000000..717def9 --- /dev/null +++ b/thirdparty/boost/date_time/local_time/local_time_io.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__ +#define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include "boost/date_time/local_time/local_date_time.hpp" +#include "boost/date_time/local_time/posix_time_zone.hpp" +#include "boost/date_time/time_facet.hpp" +#include "boost/date_time/string_convert.hpp" +#include "boost/io/ios_state.hpp" + +namespace boost { +namespace local_time { + + typedef boost::date_time::time_facet wlocal_time_facet; + typedef boost::date_time::time_facet local_time_facet; + + typedef boost::date_time::time_input_facet wlocal_time_input_facet; + typedef boost::date_time::time_input_facet local_time_input_facet; + + //! operator<< for local_date_time - see local_time docs for formatting details + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const local_date_time& ldt) + { + boost::io::ios_flags_saver iflags(os); + typedef local_date_time time_type;//::utc_time_type typename + typedef date_time::time_facet custom_time_facet; + typedef std::time_put std_time_facet; + std::ostreambuf_iterator oitr(os); + + if(std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(oitr, + os, + os.fill(), + ldt); + } + else { + custom_time_facet* f = new custom_time_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), ldt); + } + + return os; + } + + + //! input operator for local_date_time + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, local_date_time& ldt) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename local_date_time::utc_time_type utc_time_type; + typedef typename date_time::time_input_facet time_input_facet; + + // intermediate objects + std::basic_string tz_str; + utc_time_type pt(not_a_date_time); + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get_local_time(sit, str_end, is, pt, tz_str); + } + else { + time_input_facet* f = new time_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get_local_time(sit, str_end, is, pt, tz_str); + } + if(tz_str.empty()) { + time_zone_ptr null_ptr; + // a null time_zone_ptr creates a local_date_time that is UTC + ldt = local_date_time(pt, null_ptr); + } + else { + time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type(tz_str))); + // the "date & time" constructor expects the time label to *not* be utc. + // a posix_tz_string also expects the time label to *not* be utc. + ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR); + } + } + catch(...) { + // mask tells us what exceptions are turned on + std::ios_base::iostate exception_mask = is.exceptions(); + // if the user wants exceptions on failbit, we'll rethrow our + // date_time exception & set the failbit + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} // ignore this one + throw; // rethrow original exception + } + else { + // if the user want's to fail quietly, we simply set the failbit + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + +} } // namespaces + +#endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__ diff --git a/thirdparty/boost/date_time/local_time/local_time_types.hpp b/thirdparty/boost/date_time/local_time/local_time_types.hpp new file mode 100644 index 0000000..84d852f --- /dev/null +++ b/thirdparty/boost/date_time/local_time/local_time_types.hpp @@ -0,0 +1,52 @@ +#ifndef LOCAL_TIME_LOCAL_TIME_TYPES_HPP__ +#define LOCAL_TIME_LOCAL_TIME_TYPES_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/local_time/local_date_time.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/time_iterator.hpp" +#include "boost/date_time/compiler_config.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/local_time/date_duration_operators.hpp" +#endif //BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +#include "boost/date_time/local_time/custom_time_zone.hpp" + +namespace boost { +namespace local_time { + + typedef boost::date_time::period local_time_period; + + typedef date_time::time_itr local_time_iterator; + + typedef date_time::second_clock local_sec_clock; + typedef date_time::microsec_clock local_microsec_clock; + + typedef date_time::time_zone_base time_zone; + typedef date_time::time_zone_base wtime_zone; + + //! Shared Pointer for custom_time_zone and posix_time_zone objects + typedef boost::shared_ptr time_zone_ptr; + typedef boost::shared_ptr wtime_zone_ptr; + + typedef date_time::time_zone_names_base time_zone_names; + typedef date_time::time_zone_names_base wtime_zone_names; + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + +}} // namespaces + +#endif // LOCAL_TIME_LOCAL_TIME_TYPES_HPP__ diff --git a/thirdparty/boost/date_time/local_time/posix_time_zone.hpp b/thirdparty/boost/date_time/local_time/posix_time_zone.hpp new file mode 100644 index 0000000..fcc56cc --- /dev/null +++ b/thirdparty/boost/date_time/local_time/posix_time_zone.hpp @@ -0,0 +1,443 @@ +#ifndef _DATE_TIME_POSIX_TIME_ZONE__ +#define _DATE_TIME_POSIX_TIME_ZONE__ + +/* Copyright (c) 2003-2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/time_zone_names.hpp" +#include "boost/date_time/time_zone_base.hpp" +#include "boost/date_time/local_time/dst_transition_day_rules.hpp" +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/date_time/string_convert.hpp" +#include "boost/date_time/time_parsing.hpp" +#include "boost/tokenizer.hpp" +#include + +namespace boost{ +namespace local_time{ + + //! simple exception for UTC and Daylight savings start/end offsets + struct bad_offset : public std::out_of_range + { + bad_offset(std::string _msg="") : std::out_of_range(std::string("Offset out of range: " + _msg)) {} + }; + //! simple exception for UTC daylight savings adjustment + struct bad_adjustment : public std::out_of_range + { + bad_adjustment(std::string _msg="") : std::out_of_range(std::string("Adjustment out of range: " + _msg)) {} + }; + + typedef boost::date_time::dst_adjustment_offsets dst_adjustment_offsets; + + //! A time zone class constructed from a POSIX time zone string + /*! A POSIX time zone string takes the form of:
+ * "std offset dst [offset],start[/time],end[/time]" (w/no spaces) + * 'std' specifies the abbrev of the time zone.
+ * 'offset' is the offset from UTC.
+ * 'dst' specifies the abbrev of the time zone during daylight savings time.
+ * The second offset is how many hours changed during DST. Default=1
+ * 'start' and'end' are the dates when DST goes into (and out of) effect.
+ * 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}
+ * 'time' and 'offset' take the same form. Time defaults=02:00:00
+ * 'start' and 'end' can be one of three forms:
+ * Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}
+ * Jn {n=1-365 Feb29 is never counted}
+ * n {n=0-365 Feb29 is counted in leap years}
+ * Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00" + *
+ * Exceptions will be thrown under these conditions:
+ * An invalid date spec (see date class)
+ * A boost::local_time::bad_offset exception will be thrown for:
+ * A DST start or end offset that is negative or more than 24 hours
+ * A UTC zone that is greater than +12 or less than -12 hours
+ * A boost::local_time::bad_adjustment exception will be thrown for:
+ * A DST adjustment that is 24 hours or more (positive or negative)
+ */ + template + class posix_time_zone_base : public date_time::time_zone_base { + public: + typedef boost::posix_time::time_duration time_duration_type; + typedef date_time::time_zone_names_base time_zone_names; + typedef date_time::time_zone_base base_type; + typedef typename base_type::string_type string_type; + typedef CharT char_type; + typedef typename base_type::stringstream_type stringstream_type; + typedef boost::char_separator > char_separator_type; + typedef boost::tokenizer tokenizer_type; + typedef typename boost::tokenizer::iterator tokenizer_iterator_type; + + //! Construct from a POSIX time zone string + posix_time_zone_base(const string_type& s) : + //zone_names_("std_name","std_abbrev","no-dst","no-dst"), + zone_names_(), + has_dst_(false), + base_utc_offset_(posix_time::hours(0)), + dst_offsets_(posix_time::hours(0),posix_time::hours(0),posix_time::hours(0)), + dst_calc_rules_() + { + const char_type sep_chars[2] = {','}; + char_separator_type sep(sep_chars); + tokenizer_type tokens(s, sep); + tokenizer_iterator_type it = tokens.begin(); + calc_zone(*it++); + if(has_dst_){ + string_type tmp_str = *it++; + calc_rules(tmp_str, *it); + } + } + virtual ~posix_time_zone_base() {}; + //!String for the zone when not in daylight savings (eg: EST) + virtual string_type std_zone_abbrev()const + { + return zone_names_.std_zone_abbrev(); + } + //!String for the timezone when in daylight savings (eg: EDT) + /*! For those time zones that have no DST, an empty string is used */ + virtual string_type dst_zone_abbrev() const + { + return zone_names_.dst_zone_abbrev(); + } + //!String for the zone when not in daylight savings (eg: Eastern Standard Time) + /*! The full STD name is not extracted from the posix time zone string. + * Therefore, the STD abbreviation is used in it's place */ + virtual string_type std_zone_name()const + { + return zone_names_.std_zone_name(); + } + //!String for the timezone when in daylight savings (eg: Eastern Daylight Time) + /*! The full DST name is not extracted from the posix time zone string. + * Therefore, the STD abbreviation is used in it's place. For time zones + * that have no DST, an empty string is used */ + virtual string_type dst_zone_name()const + { + return zone_names_.dst_zone_name(); + } + //! True if zone uses daylight savings adjustments otherwise false + virtual bool has_dst()const + { + return has_dst_; + } + //! Local time that DST starts -- NADT if has_dst is false + virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const + { + gregorian::date d(gregorian::not_a_date_time); + if(has_dst_) + { + d = dst_calc_rules_->start_day(y); + } + return posix_time::ptime(d, dst_offsets_.dst_start_offset_); + } + //! Local time that DST ends -- NADT if has_dst is false + virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const + { + gregorian::date d(gregorian::not_a_date_time); + if(has_dst_) + { + d = dst_calc_rules_->end_day(y); + } + return posix_time::ptime(d, dst_offsets_.dst_end_offset_); + } + //! Base offset from UTC for zone (eg: -07:30:00) + virtual time_duration_type base_utc_offset()const + { + return base_utc_offset_; + } + //! Adjustment forward or back made while DST is in effect + virtual time_duration_type dst_offset()const + { + return dst_offsets_.dst_adjust_; + } + + //! Returns a POSIX time_zone string for this object + virtual string_type to_posix_string() const + { + // std offset dst [offset],start[/time],end[/time] - w/o spaces + stringstream_type ss; + ss.fill('0'); + boost::shared_ptr no_rules; + // std + ss << std_zone_abbrev(); + // offset + if(base_utc_offset().is_negative()) { + // inverting the sign guarantees we get two digits + ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours(); + } + else { + ss << '+' << std::setw(2) << base_utc_offset().hours(); + } + if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) { + ss << ':' << std::setw(2) << base_utc_offset().minutes(); + if(base_utc_offset().seconds() != 0) { + ss << ':' << std::setw(2) << base_utc_offset().seconds(); + } + } + if(dst_calc_rules_ != no_rules) { + // dst + ss << dst_zone_abbrev(); + // dst offset + if(dst_offset().is_negative()) { + // inverting the sign guarantees we get two digits + ss << '-' << std::setw(2) << dst_offset().invert_sign().hours(); + } + else { + ss << '+' << std::setw(2) << dst_offset().hours(); + } + if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) { + ss << ':' << std::setw(2) << dst_offset().minutes(); + if(dst_offset().seconds() != 0) { + ss << ':' << std::setw(2) << dst_offset().seconds(); + } + } + // start/time + ss << ',' << date_time::convert_string_type(dst_calc_rules_->start_rule_as_string()) << '/' + << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':' + << std::setw(2) << dst_offsets_.dst_start_offset_.minutes(); + if(dst_offsets_.dst_start_offset_.seconds() != 0) { + ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds(); + } + // end/time + ss << ',' << date_time::convert_string_type(dst_calc_rules_->end_rule_as_string()) << '/' + << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':' + << std::setw(2) << dst_offsets_.dst_end_offset_.minutes(); + if(dst_offsets_.dst_end_offset_.seconds() != 0) { + ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds(); + } + } + + return ss.str(); + } + private: + time_zone_names zone_names_; + bool has_dst_; + time_duration_type base_utc_offset_; + dst_adjustment_offsets dst_offsets_; + boost::shared_ptr dst_calc_rules_; + + /*! Extract time zone abbreviations for STD & DST as well + * as the offsets for the time shift that occurs and how + * much of a shift. At this time full time zone names are + * NOT extracted so the abbreviations are used in their place */ + void calc_zone(const string_type& obj){ + const char_type empty_string[2] = {'\0'}; + stringstream_type ss(empty_string); + typename string_type::const_iterator sit = obj.begin(); + string_type l_std_zone_abbrev, l_dst_zone_abbrev; + + // get 'std' name/abbrev + while(std::isalpha(*sit)){ + ss << *sit++; + } + l_std_zone_abbrev = ss.str(); + ss.str(empty_string); + + // get UTC offset + if(sit != obj.end()){ + // get duration + while(sit != obj.end() && !std::isalpha(*sit)){ + ss << *sit++; + } + base_utc_offset_ = date_time::str_from_delimited_time_duration(ss.str()); + ss.str(empty_string); + + // base offset must be within range of -12 hours to +12 hours + if(base_utc_offset_ < time_duration_type(-12,0,0) || + base_utc_offset_ > time_duration_type(12,0,0)) + { + throw bad_offset(posix_time::to_simple_string(base_utc_offset_)); + } + } + + // get DST data if given + if(sit != obj.end()){ + has_dst_ = true; + + // get 'dst' name/abbrev + while(sit != obj.end() && std::isalpha(*sit)){ + ss << *sit++; + } + l_dst_zone_abbrev = ss.str(); + ss.str(empty_string); + + // get DST offset if given + if(sit != obj.end()){ + // get duration + while(sit != obj.end() && !std::isalpha(*sit)){ + ss << *sit++; + } + dst_offsets_.dst_adjust_ = date_time::str_from_delimited_time_duration(ss.str()); + ss.str(empty_string); + } + else{ // default DST offset + dst_offsets_.dst_adjust_ = posix_time::hours(1); + } + + // adjustment must be within +|- 1 day + if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) || + dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0)) + { + throw bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_)); + } + } + // full names not extracted so abbrevs used in their place + zone_names_ = time_zone_names(l_std_zone_abbrev, l_std_zone_abbrev, l_dst_zone_abbrev, l_dst_zone_abbrev); + } + + void calc_rules(const string_type& start, const string_type& end){ + const char_type sep_chars[2] = {'/'}; + char_separator_type sep(sep_chars); + tokenizer_type st_tok(start, sep); + tokenizer_type et_tok(end, sep); + tokenizer_iterator_type sit = st_tok.begin(); + tokenizer_iterator_type eit = et_tok.begin(); + + // generate date spec + char_type x = string_type(*sit).at(0); + if(x == 'M'){ + M_func(*sit, *eit); + } + else if(x == 'J'){ + julian_no_leap(*sit, *eit); + } + else{ + julian_day(*sit, *eit); + } + + ++sit; + ++eit; + // generate durations + // starting offset + if(sit != st_tok.end()){ + dst_offsets_.dst_start_offset_ = date_time::str_from_delimited_time_duration(*sit); + } + else{ + // default + dst_offsets_.dst_start_offset_ = posix_time::hours(2); + } + // start/end offsets must fall on given date + if(dst_offsets_.dst_start_offset_ < time_duration_type(0,0,0) || + dst_offsets_.dst_start_offset_ >= time_duration_type(24,0,0)) + { + throw bad_offset(posix_time::to_simple_string(dst_offsets_.dst_start_offset_)); + } + + // ending offset + if(eit != et_tok.end()){ + dst_offsets_.dst_end_offset_ = date_time::str_from_delimited_time_duration(*eit); + } + else{ + // default + dst_offsets_.dst_end_offset_ = posix_time::hours(2); + } + // start/end offsets must fall on given date + if(dst_offsets_.dst_end_offset_ < time_duration_type(0,0,0) || + dst_offsets_.dst_end_offset_ >= time_duration_type(24,0,0)) + { + throw bad_offset(posix_time::to_simple_string(dst_offsets_.dst_end_offset_)); + } + } + + /* Parses out a start/end date spec from a posix time zone string. + * Date specs come in three possible formats, this function handles + * the 'M' spec. Ex "M2.2.4" => 2nd month, 2nd week, 4th day . + */ + void M_func(const string_type& s, const string_type& e){ + typedef gregorian::nth_kday_of_month nkday; + unsigned short sm=0,sw=0,sd=0,em=0,ew=0,ed=0; // start/end month,week,day + const char_type sep_chars[3] = {'M','.'}; + char_separator_type sep(sep_chars); + tokenizer_type stok(s, sep), etok(e, sep); + + tokenizer_iterator_type it = stok.begin(); + sm = lexical_cast(*it++); + sw = lexical_cast(*it++); + sd = lexical_cast(*it); + + it = etok.begin(); + em = lexical_cast(*it++); + ew = lexical_cast(*it++); + ed = lexical_cast(*it); + + dst_calc_rules_ = shared_ptr( + new nth_kday_dst_rule( + nth_last_dst_rule::start_rule( + static_cast(sw),sd,sm), + nth_last_dst_rule::start_rule( + static_cast(ew),ed,em) + ) + ); + } + + //! Julian day. Feb29 is never counted, even in leap years + // expects range of 1-365 + void julian_no_leap(const string_type& s, const string_type& e){ + typedef gregorian::gregorian_calendar calendar; + const unsigned short year = 2001; // Non-leap year + unsigned short sm=1; + int sd=0; + sd = lexical_cast(s.substr(1)); // skip 'J' + while(sd >= calendar::end_of_month_day(year,sm)){ + sd -= calendar::end_of_month_day(year,sm++); + } + unsigned short em=1; + int ed=0; + ed = lexical_cast(e.substr(1)); // skip 'J' + while(ed > calendar::end_of_month_day(year,em)){ + ed -= calendar::end_of_month_day(year,em++); + } + + dst_calc_rules_ = shared_ptr( + new partial_date_dst_rule( + partial_date_dst_rule::start_rule( + sd, static_cast(sm)), + partial_date_dst_rule::end_rule( + ed, static_cast(em)) + ) + ); + } + + //! Julian day. Feb29 is always counted, but exception thrown in non-leap years + // expects range of 0-365 + void julian_day(const string_type& s, const string_type& e){ + int sd=0, ed=0; + sd = lexical_cast(s); + ed = lexical_cast(e); + dst_calc_rules_ = shared_ptr( + new partial_date_dst_rule( + partial_date_dst_rule::start_rule(++sd),// args are 0-365 + partial_date_dst_rule::end_rule(++ed) // pd expects 1-366 + ) + ); + } + + //! helper function used when throwing exceptions + static std::string td_as_string(const time_duration_type& td) + { + std::string s; +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) + s = posix_time::to_simple_string(td); +#else + std::stringstream ss; + ss << td; + s = ss.str(); +#endif + return s; + } + }; + + typedef posix_time_zone_base posix_time_zone; + +} } // namespace boost::local_time + + +#endif // _DATE_TIME_POSIX_TIME_ZONE__ diff --git a/thirdparty/boost/date_time/local_time/tz_database.hpp b/thirdparty/boost/date_time/local_time/tz_database.hpp new file mode 100644 index 0000000..2fe8457 --- /dev/null +++ b/thirdparty/boost/date_time/local_time/tz_database.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_DATE_TIME_TZ_DATABASE_HPP__ +#define BOOST_DATE_TIME_TZ_DATABASE_HPP__ + +/* Copyright (c) 2003-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include "boost/date_time/local_time/custom_time_zone.hpp" +#include "boost/date_time/local_time/dst_transition_day_rules.hpp" +#include "boost/date_time/tz_db_base.hpp" + + +namespace boost { +namespace local_time { + + using date_time::data_not_accessible; + using date_time::bad_field_count; + + //! Object populated with boost::shared_ptr objects + /*! Object populated with boost::shared_ptr objects + * Database is populated from specs stored in external csv file. See + * date_time::tz_db_base for greater detail */ + typedef date_time::tz_db_base tz_database; + +}} // namespace + +#endif // BOOST_DATE_TIME_TZ_DATABASE_HPP__ + diff --git a/thirdparty/boost/date_time/local_time_adjustor.hpp b/thirdparty/boost/date_time/local_time_adjustor.hpp new file mode 100644 index 0000000..2e8e331 --- /dev/null +++ b/thirdparty/boost/date_time/local_time_adjustor.hpp @@ -0,0 +1,213 @@ +#ifndef DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__ +#define DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file local_time_adjustor.hpp + Time adjustment calculations for local times +*/ + +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/dst_rules.hpp" +#include + +namespace boost { + namespace date_time { + + + //! Provides a base offset adjustment from utc + template + class utc_adjustment + { + public: + static time_duration_type local_to_utc_base_offset() + { + time_duration_type td(hours,minutes,0); + return td.invert_sign(); + } + static time_duration_type utc_to_local_base_offset() + { + return time_duration_type(hours,minutes,0); + } + }; + + + + //! Allow sliding utc adjustment with fixed dst rules + template + class dynamic_local_time_adjustor : public dst_rules + { + public: + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_type::date_type date_type; + + dynamic_local_time_adjustor(time_duration_type utc_offset) : + utc_offset_(utc_offset) + {} + + //! Presumes local time + time_duration_type utc_offset(bool is_dst) + { + if (is_dst) { + return utc_offset_ + this->dst_offset(); + } + else { + return utc_offset_; + } + + } + private: + time_duration_type utc_offset_; + + }; + + + + //! Embed the rules for local time adjustments at compile time + template + class static_local_time_adjustor: public dst_rules, public utc_offset_rules + { + public: + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_type::date_type date_type; + + //! Calculates the offset from a utc time to local based on dst and utc offset + /*! @param t UTC time to calculate offset to local time + * This adjustment depends on the following observations about the + * workings of the DST boundary offset. Since UTC time labels are + * monotonically increasing we can determine if a given local time + * is in DST or not and therefore adjust the offset appropriately. + * + * The logic is as follows. Starting with UTC time use the offset to + * create a label for an non-dst adjusted local time. Then call + * dst_rules::local_is_dst with the non adjust local time. The + * results of this function will either unabiguously decide that + * the initial local time is in dst or return an illegal or + * ambiguous result. An illegal result only occurs at the end + * of dst (where labels are skipped) and indicates that dst has + * ended. An ambiguous result means that we need to recheck by + * making a dst adjustment and then rechecking. If the dst offset + * is added to the utc time and the recheck proves non-ambiguous + * then we are past the boundary. If it is still ambiguous then + * we are ahead of the boundary and dst is still in effect. + * + * TODO -- check if all dst offsets are positive. If not then + * the algorithm needs to check for this and reverse the + * illegal/ambiguous logic. + */ + static time_duration_type utc_to_local_offset(const time_type& t) + { + //get initial local time guess by applying utc offset + time_type initial = t + utc_offset_rules::utc_to_local_base_offset(); + time_is_dst_result dst_flag = + dst_rules::local_is_dst(initial.date(), initial.time_of_day()); + switch(dst_flag) { + case is_in_dst: return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset(); + case is_not_in_dst: return utc_offset_rules::utc_to_local_base_offset(); + case invalid_time_label:return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset(); + case ambiguous: { + time_type retry = initial + dst_rules::dst_offset(); + dst_flag = dst_rules::local_is_dst(retry.date(), retry.time_of_day()); + //if still ambibuous then the utc time still translates to a dst time + if (dst_flag == ambiguous) { + return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset(); + } + // we are past the dst boundary + else { + return utc_offset_rules::utc_to_local_base_offset(); + } + } + }//case + //TODO better excpetion type + throw std::out_of_range("Unreachable case"); + + } + + //! Get the offset to UTC given a local time + static time_duration_type local_to_utc_offset(const time_type& t, + date_time::dst_flags dst=date_time::calculate) + { + switch (dst) { + case is_dst: + return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset(); + case not_dst: + return utc_offset_rules::local_to_utc_base_offset(); + case calculate: + time_is_dst_result res = + dst_rules::local_is_dst(t.date(), t.time_of_day()); + switch(res) { + case is_in_dst: return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset(); + case is_not_in_dst: return utc_offset_rules::local_to_utc_base_offset(); + case ambiguous: return utc_offset_rules::local_to_utc_base_offset(); + case invalid_time_label: throw std::out_of_range("Time label invalid"); + } + } + throw std::out_of_range("Time label invalid"); + } + + + private: + + }; + + void dummy_to_prevent_msvc6_ice(); //why ask why? + + //! Template that simplifies the creation of local time calculator + /*! Use this template to create the timezone to utc convertors as required. + * + * This class will also work for other regions that don't use dst and + * have a utc offset which is an integral number of hours. + * + * Template Parameters + * -time_type -- Time class to use + * -utc_offset -- Number hours local time is adjust from utc + * -use_dst -- true (default) if region uses dst, false otherwise + * For example: + * @code + * //eastern timezone is utc-5 + typedef date_time::local_adjustor us_eastern; + typedef date_time::local_adjustor us_central; + typedef date_time::local_adjustor us_mountain; + typedef date_time::local_adjustor us_pacific; + typedef date_time::local_adjustor us_arizona; + @endcode + + */ + template + class local_adjustor + { + public: + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_type::date_type date_type; + typedef static_local_time_adjustor > dst_adjustor; + //! Convert a utc time to local time + static time_type utc_to_local(const time_type& t) + { + time_duration_type td = dst_adjustor::utc_to_local_offset(t); + return t + td; + } + //! Convert a local time to utc + static time_type local_to_utc(const time_type& t, + date_time::dst_flags dst=date_time::calculate) + { + time_duration_type td = dst_adjustor::local_to_utc_offset(t, dst); + return t + td; + } + }; + + + } } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/local_timezone_defs.hpp b/thirdparty/boost/date_time/local_timezone_defs.hpp new file mode 100644 index 0000000..d58197a --- /dev/null +++ b/thirdparty/boost/date_time/local_timezone_defs.hpp @@ -0,0 +1,193 @@ +#ifndef DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__ +#define DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/dst_rules.hpp" + +namespace boost { + namespace date_time { + + // Configurations for common dst rules cases: + // See http://www.wharton.co.uk/Support/sup_dst.htm for more + // information on how various locales use dst rules + + //! Specification for daylight savings start rules in US + /*! This class is used to configure dst_calc_engine template typically + as follows: + @code + using namespace boost::gregorian; + using namespace boost::posix_time; + typedef us_dst_trait us_dst_traits; + typedef boost::date_time::dst_calc_engine + us_dst_calc; + //calculate the 2002 transition day of USA April 7 2002 + date dst_start = us_dst_calc::local_dst_start_day(2002); + + //calculate the 2002 transition day of USA Oct 27 2002 + date dst_end = us_dst_calc::local_dst_end_day(2002); + + //check if a local time is in dst or not -- posible answers + //are yes, no, invalid time label, ambiguous + ptime t(...some time...); + if (us_dst::local_is_dst(t.date(), t.time_of_day()) + == boost::date_time::is_not_in_dst) + { + + } + + @endcode + This generates a type suitable for the calculation of dst + transitions for the United States. Of course other templates + can be used for other locales. + + */ + + template + struct us_dst_trait + { + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::year_type year_type; + typedef date_time::nth_kday_of_month start_rule_functor; + typedef date_time::first_kday_of_month end_rule_functor; + typedef date_time::first_kday_of_month start_rule_functor_pre2007; + typedef date_time::last_kday_of_month end_rule_functor_pre2007; + static day_of_week_type start_day(year_type) {return Sunday;} + static month_type start_month(year_type y) + { + if (y < 2007) return Apr; + return Mar; + } + static day_of_week_type end_day(year_type y) {return Sunday;} + static month_type end_month(year_type y) + { + if (y < 2007) return Oct; + return Nov; + } + static date_type local_dst_start_day(year_type year) + { + if (year < 2007) { + start_rule_functor_pre2007 start1(start_day(year), + start_month(year)); + return start1.get_date(year); + } + start_rule_functor start(start_rule_functor::second, + start_day(year), + start_month(year)); + return start.get_date(year); + + } + static date_type local_dst_end_day(year_type year) + { + if (year < 2007) { + end_rule_functor_pre2007 end_rule(end_day(year), + end_month(year)); + return end_rule.get_date(year); + } + end_rule_functor end(end_day(year), + end_month(year)); + return end.get_date(year); + } + static int dst_start_offset_minutes() { return 120;} + static int dst_end_offset_minutes() { return 120; } + static int dst_shift_length_minutes() { return 60; } + }; + + //!Rules for daylight savings start in the EU (Last Sun in Mar) + /*!These amount to the following: + - Start of dst day is last Sunday in March + - End day of dst is last Sunday in Oct + - Going forward switch time is 2:00 am (offset 120 minutes) + - Going back switch time is 3:00 am (off set 180 minutes) + - Shift duration is one hour (60 minutes) + */ + template + struct eu_dst_trait + { + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::year_type year_type; + typedef date_time::last_kday_of_month start_rule_functor; + typedef date_time::last_kday_of_month end_rule_functor; + static day_of_week_type start_day(year_type) {return Sunday;} + static month_type start_month(year_type) {return Mar;} + static day_of_week_type end_day(year_type) {return Sunday;} + static month_type end_month(year_type) {return Oct;} + static int dst_start_offset_minutes() { return 120;} + static int dst_end_offset_minutes() { return 180; } + static int dst_shift_length_minutes() { return 60; } + static date_type local_dst_start_day(year_type year) + { + start_rule_functor start(start_day(year), + start_month(year)); + return start.get_date(year); + } + static date_type local_dst_end_day(year_type year) + { + end_rule_functor end(end_day(year), + end_month(year)); + return end.get_date(year); + } + }; + + //! Alternative dst traits for some parts of the United Kingdom + /* Several places in the UK use EU start and end rules for the + day, but different local conversion times (eg: forward change at 1:00 + am local and backward change at 2:00 am dst instead of 2:00am + forward and 3:00am back for the EU). + */ + template + struct uk_dst_trait : public eu_dst_trait + { + static int dst_start_offset_minutes() { return 60;} + static int dst_end_offset_minutes() { return 120; } + static int dst_shift_length_minutes() { return 60; } + }; + + //Rules for Adelaide Australia + template + struct acst_dst_trait + { + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::year_type year_type; + typedef date_time::last_kday_of_month start_rule_functor; + typedef date_time::last_kday_of_month end_rule_functor; + static day_of_week_type start_day(year_type) {return Sunday;} + static month_type start_month(year_type) {return Oct;} + static day_of_week_type end_day(year_type) {return Sunday;} + static month_type end_month(year_type) {return Mar;} + static int dst_start_offset_minutes() { return 120;} + static int dst_end_offset_minutes() { return 180; } + static int dst_shift_length_minutes() { return 60; } + static date_type local_dst_start_day(year_type year) + { + start_rule_functor start(start_day(year), + start_month(year)); + return start.get_date(year); + } + static date_type local_dst_end_day(year_type year) + { + end_rule_functor end(end_day(year), + end_month(year)); + return end.get_date(year); + } + }; + + + + + + +} } //namespace boost::date_time + + +#endif diff --git a/thirdparty/boost/date_time/locale_config.hpp b/thirdparty/boost/date_time/locale_config.hpp new file mode 100644 index 0000000..003d841 --- /dev/null +++ b/thirdparty/boost/date_time/locale_config.hpp @@ -0,0 +1,31 @@ +#ifndef DATE_TIME_LOCALE_CONFIG_HPP___ +#define DATE_TIME_LOCALE_CONFIG_HPP___ + +/* Copyright (c) 2002-2006 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +// This file configures whether the library will support locales and hence +// iostream based i/o. Even if a compiler has some support for locales, +// any failure to be compatible gets the compiler on the exclusion list. +// +// At the moment this is defined for MSVC 6 and any compiler that +// defines BOOST_NO_STD_LOCALE (gcc 2.95.x) + +#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE +#include "boost/detail/workaround.hpp" + +//This file basically becomes a noop if locales are not properly supported +#if (defined(BOOST_NO_STD_LOCALE) \ + || (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \ + || (BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 )) ) ) +#define BOOST_DATE_TIME_NO_LOCALE +#endif + + +#endif + diff --git a/thirdparty/boost/date_time/microsec_time_clock.hpp b/thirdparty/boost/date_time/microsec_time_clock.hpp new file mode 100644 index 0000000..ce25563 --- /dev/null +++ b/thirdparty/boost/date_time/microsec_time_clock.hpp @@ -0,0 +1,205 @@ +#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ +#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +/*! @file microsec_time_clock.hpp + This file contains a high resolution time clock implementation. +*/ + +#include +#include "boost/date_time/c_time.hpp" +#include "boost/date_time/time_clock.hpp" +#include "boost/cstdint.hpp" +#include "boost/shared_ptr.hpp" + +#ifdef BOOST_HAS_FTIME +#include +#endif + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + +namespace boost { +namespace date_time { + + + //! A clock providing microsecond level resolution + /*! A high precision clock that measures the local time + * at a resolution up to microseconds and adjusts to the + * resolution of the time system. For example, for the + * a library configuration with nano second resolution, + * the last 3 places of the fractional seconds will always + * be 000 since there are 1000 nano-seconds in a micro second. + */ + template + class microsec_clock + { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_duration_type::rep_type resolution_traits_type; + + //! return a local time object for the given zone, based on computer clock + //JKG -- looks like we could rewrite this against universal_time + template + static time_type local_time(shared_ptr tz_ptr) { + typedef typename time_type::utc_time_type utc_time_type; + typedef second_clock second_clock; + // we'll need to know the utc_offset this machine has + // in order to get a utc_time_type set to utc + utc_time_type utc_time = second_clock::universal_time(); + time_duration_type utc_offset = second_clock::local_time() - utc_time; + // use micro clock to get a local time with sub seconds + // and adjust it to get a true utc time reading with sub seconds + utc_time = microsec_clock::local_time() - utc_offset; + return time_type(utc_time, tz_ptr); + } + + + private: + // we want this enum available for both platforms yet still private + enum TZ_FOR_CREATE { LOCAL, GMT }; + + public: + +#ifdef BOOST_HAS_GETTIMEOFDAY + //! Return the local time based on computer clock settings + static time_type local_time() { + return create_time(LOCAL); + } + + //! Get the current day in universal date as a ymd_type + static time_type universal_time() + { + return create_time(GMT); + } + + private: + static time_type create_time(TZ_FOR_CREATE tz) { + timeval tv; + gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux. + std::time_t t = tv.tv_sec; + boost::uint32_t fs = tv.tv_usec; + std::tm curr, *curr_ptr = 0; + if (tz == LOCAL) { + curr_ptr = c_time::localtime(&t, &curr); + } else { + curr_ptr = c_time::gmtime(&t, &curr); + } + date_type d(curr_ptr->tm_year + 1900, + curr_ptr->tm_mon + 1, + curr_ptr->tm_mday); + //The following line will adjusts the fractional second tick in terms + //of the current time system. For example, if the time system + //doesn't support fractional seconds then res_adjust returns 0 + //and all the fractional seconds return 0. + int adjust = resolution_traits_type::res_adjust()/1000000; + + time_duration_type td(curr_ptr->tm_hour, + curr_ptr->tm_min, + curr_ptr->tm_sec, + fs*adjust); + return time_type(d,td); + + } +#endif // BOOST_HAS_GETTIMEOFDAY + +#ifdef BOOST_HAS_FTIME + //! Return the local time based on computer clock settings + static time_type local_time() { + FILETIME ft; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + // Some runtime library implementations expect local times as the norm for ctime. + FILETIME ft_utc; + GetSystemTimeAsFileTime(&ft_utc); + FileTimeToLocalFileTime(&ft_utc,&ft); + #elif defined(BOOST_NO_GETSYSTEMTIMEASFILETIME) + SYSTEMTIME st; + GetSystemTime( &st ); + SystemTimeToFileTime( &st, &ft ); + #else + GetSystemTimeAsFileTime(&ft); + #endif + return create_time(ft, LOCAL); + } + + //! Return the UTC time based on computer settings + static time_type universal_time() { + FILETIME ft; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + // Some runtime library implementations expect local times as the norm for ctime. + FILETIME ft_utc; + GetSystemTimeAsFileTime(&ft_utc); + FileTimeToLocalFileTime(&ft_utc,&ft); + #elif defined(BOOST_NO_GETSYSTEMTIMEASFILETIME) + SYSTEMTIME st; + GetSystemTime( &st ); + SystemTimeToFileTime( &st, &ft ); + #else + GetSystemTimeAsFileTime(&ft); + #endif + return create_time(ft, GMT); + } + + private: + static time_type create_time(FILETIME& ft, TZ_FOR_CREATE tz) { + // offset is difference (in 100-nanoseconds) from + // 1970-Jan-01 to 1601-Jan-01 + boost::uint64_t c1 = 27111902; + boost::uint64_t c2 = 3577643008UL; // 'UL' removes compiler warnings + const boost::uint64_t OFFSET = (c1 << 32) + c2; + + boost::uint64_t filetime = ft.dwHighDateTime; + filetime = filetime << 32; + filetime += ft.dwLowDateTime; + filetime -= OFFSET; + // filetime now holds 100-nanoseconds since 1970-Jan-01 + + // microseconds -- static casts supress warnings + boost::uint32_t sub_sec = static_cast((filetime % 10000000) / 10); + + std::time_t t = static_cast(filetime / 10000000); // seconds since epoch + + std::tm curr, *curr_ptr = 0; + if (tz == LOCAL) { + curr_ptr = c_time::localtime(&t, &curr); + } + else { + curr_ptr = c_time::gmtime(&t, &curr); + } + date_type d(curr_ptr->tm_year + 1900, + curr_ptr->tm_mon + 1, + curr_ptr->tm_mday); + + //The following line will adjusts the fractional second tick in terms + //of the current time system. For example, if the time system + //doesn't support fractional seconds then res_adjust returns 0 + //and all the fractional seconds return 0. + int adjust = static_cast(resolution_traits_type::res_adjust()/1000000); + + time_duration_type td(curr_ptr->tm_hour, + curr_ptr->tm_min, + curr_ptr->tm_sec, + sub_sec * adjust); + //st.wMilliseconds * adjust); + return time_type(d,td); + + } +#endif // BOOST_HAS_FTIME + }; + + +} } //namespace date_time + +#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + + +#endif + diff --git a/thirdparty/boost/date_time/parse_format_base.hpp b/thirdparty/boost/date_time/parse_format_base.hpp new file mode 100644 index 0000000..317151a --- /dev/null +++ b/thirdparty/boost/date_time/parse_format_base.hpp @@ -0,0 +1,29 @@ +#ifndef DATE_TIME_PARSE_FORMAT_BASE__ +#define DATE_TIME_PARSE_FORMAT_BASE__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +namespace boost { +namespace date_time { + + //! Enum for distinguishing parsing and formatting options + enum month_format_spec {month_as_integer, month_as_short_string, + month_as_long_string}; + + //! Enum for distinguishing the order of Month, Day, & Year. + /*! Enum for distinguishing the order in which Month, Day, & Year + * will appear in a date string */ + enum ymd_order_spec {ymd_order_iso, //order is year-month-day + ymd_order_dmy, //day-month-year + ymd_order_us}; //order is month-day-year + + +} }//namespace date_time + +#endif diff --git a/thirdparty/boost/date_time/period.hpp b/thirdparty/boost/date_time/period.hpp new file mode 100644 index 0000000..f54a963 --- /dev/null +++ b/thirdparty/boost/date_time/period.hpp @@ -0,0 +1,377 @@ +#ifndef DATE_TIME_PERIOD_HPP___ +#define DATE_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! \file period.hpp + This file contain the implementation of the period abstraction. This is + basically the same idea as a range. Although this class is intended for + use in the time library, it is pretty close to general enough for other + numeric uses. + +*/ + +#include "boost/operators.hpp" + + +namespace boost { +namespace date_time { + //!Provides generalized period type useful in date-time systems + /*!This template uses a class to represent a time point within the period + and another class to represent a duration. As a result, this class is + not appropriate for use when the number and duration representation + are the same (eg: in the regular number domain). + + A period can be specified by providing either the begining point and + a duration or the begining point and the end point( end is NOT part + of the period but 1 unit past it. A period will be "invalid" if either + end_point <= begin_point or the given duration is <= 0. Any valid period + will return false for is_null(). + + Zero length periods are also considered invalid. Zero length periods are + periods where the begining and end points are the same, or, the given + duration is zero. For a zero length period, the last point will be one + unit less than the begining point. + + In the case that the begin and last are the same, the period has a + length of one unit. + + The best way to handle periods is usually to provide a begining point and + a duration. So, day1 + 7 days is a week period which includes all of the + first day and 6 more days (eg: Sun to Sat). + + */ + template + class period : private + boost::less_than_comparable + , boost::equality_comparable< period + > > + { + public: + typedef point_rep point_type; + typedef duration_rep duration_type; + + period(point_rep first_point, point_rep end_point); + period(point_rep first_point, duration_rep len); + point_rep begin() const; + point_rep end() const; + point_rep last() const; + duration_rep length() const; + bool is_null() const; + bool operator==(const period& rhs) const; + bool operator<(const period& rhs) const; + void shift(const duration_rep& d); + void expand(const duration_rep& d); + bool contains(const point_rep& point) const; + bool contains(const period& other) const; + bool intersects(const period& other) const; + bool is_adjacent(const period& other) const; + bool is_before(const point_rep& point) const; + bool is_after(const point_rep& point) const; + period intersection(const period& other) const; + period merge(const period& other) const; + period span(const period& other) const; + private: + point_rep begin_; + point_rep last_; + }; + + //! create a period from begin to last eg: [begin,end) + /*! If end <= begin then the period will be invalid + */ + template + inline + period::period(point_rep first_point, + point_rep end_point) : + begin_(first_point), + last_(end_point - duration_rep::unit()) + {} + + //! create a period as [begin, begin+len) + /*! If len is <= 0 then the period will be invalid + */ + template + inline + period::period(point_rep first_point, duration_rep len) : + begin_(first_point), + last_(first_point + len-duration_rep::unit()) + { } + + + //! Return the first element in the period + template + inline + point_rep period::begin() const + { + return begin_; + } + + //! Return one past the last element + template + inline + point_rep period::end() const + { + return last_ + duration_rep::unit(); + } + + //! Return the last item in the period + template + inline + point_rep period::last() const + { + return last_; + } + + //! True if period is ill formed (length is zero or less) + template + inline + bool period::is_null() const + { + return end() <= begin_; + } + + //! Return the length of the period + template + inline + duration_rep period::length() const + { + if(last_ < begin_){ // invalid period + return last_+duration_rep::unit() - begin_; + } + else{ + return end() - begin_; // normal case + } + } + + //! Equality operator + template + inline + bool period::operator==(const period& rhs) const + { + return ((begin_ == rhs.begin_) && + (last_ == rhs.last_)); + } + + //! Strict as defined by rhs.last <= lhs.last + template + inline + bool period::operator<(const period& rhs) const + { + return (last_ < rhs.begin_); + } + + + //! Shift the start and end by the specified amount + template + inline + void period::shift(const duration_rep& d) + { + begin_ = begin_ + d; + last_ = last_ + d; + } + + /** Expands the size of the period by the duration on both ends. + * + *So before expand + *@code + * + * [-------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + * After expand(2) + *@code + * + * [----------------------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + */ + template + inline + void period::expand(const duration_rep& d) + { + begin_ = begin_ - d; + last_ = last_ + d; + } + + //! True if the point is inside the period, zero length periods contain no points + template + inline + bool period::contains(const point_rep& point) const + { + return ((point >= begin_) && + (point <= last_)); + } + + + //! True if this period fully contains (or equals) the other period + template + inline + bool period::contains(const period& other) const + { + return ((begin_ <= other.begin_) && (last_ >= other.last_)); + } + + + //! True if periods are next to each other without a gap. + /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent + * with either of p1 or p2. + *@code + * [-p1-) + * [-p2-) + * [-p3-) + *@endcode + */ + template + inline + bool + period::is_adjacent(const period& other) const + { + return (other.begin() == end() || + begin_ == other.end()); + } + + + //! True if all of the period is prior or t < start + /* In the example below only point 1 would evaluate to true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline + bool + period::is_after(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't after + } + + return t < begin_; + } + + //! True if all of the period is prior to the passed point or end <= t + /* In the example below points 4 and 5 return true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline + bool + period::is_before(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't before anything + } + + return last_ < t; + } + + + //! True if the periods overlap in any way + /* In the example below p1 intersects with p2, p4, and p6. + *@code + * [---p1---) + * [---p2---) + * [---p3---) + * [---p4---) + * [-p5-) + * [-p6-) + *@endcode + */ + template + inline + bool period::intersects(const period& other) const + { + return ( contains(other.begin_) || + other.contains(begin_) || + ((other.begin_ < begin_) && (other.last_ >= begin_))); + } + + //! Returns the period of intersection or invalid range no intersection + template + inline + period + period::intersection(const period& other) const + { + if (begin_ > other.begin_) { + if (last_ <= other.last_) { //case2 + return *this; + } + //case 1 + return period(begin_, other.end()); + } + else { + if (last_ <= other.last_) { //case3 + return period(other.begin_, this->end()); + } + //case4 + return other; + } + //unreachable + } + + //! Returns the union of intersecting periods -- or null period + /*! + */ + template + inline + period + period::merge(const period& other) const + { + if (this->intersects(other)) { + if (begin_ < other.begin_) { + return period(begin_, last_ > other.last_ ? this->end() : other.end()); + } + + return period(other.begin_, last_ > other.last_ ? this->end() : other.end()); + + } + return period(begin_,begin_); // no intersect return null + } + + //! Combine two periods with earliest start and latest end. + /*! Combines two periods and any gap between them such that + * start = min(p1.start, p2.start) + * end = max(p1.end , p2.end) + *@code + * [---p1---) + * [---p2---) + * result: + * [-----------p3----------) + *@endcode + */ + template + inline + period + period::span(const period& other) const + { + point_rep start((begin_ < other.begin_) ? begin() : other.begin()); + point_rep newend((last_ < other.last_) ? other.end() : this->end()); + return period(start, newend); + } + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/period_formatter.hpp b/thirdparty/boost/date_time/period_formatter.hpp new file mode 100644 index 0000000..63d4bce --- /dev/null +++ b/thirdparty/boost/date_time/period_formatter.hpp @@ -0,0 +1,196 @@ + +#ifndef DATETIME_PERIOD_FORMATTER_HPP___ +#define DATETIME_PERIOD_FORMATTER_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + + +namespace boost { namespace date_time { + + + //! Not a facet, but a class used to specify and control period formats + /*! Provides settings for the following: + * - period_separator -- default '/' + * - period_open_start_delimeter -- default '[' + * - period_open_range_end_delimeter -- default ')' + * - period_closed_range_end_delimeter -- default ']' + * - display_as_open_range, display_as_closed_range -- default closed_range + * + * Thus the default formatting for a period is as follows: + *@code + * [period.start()/period.last()] + *@endcode + * So for a typical date_period this would be + *@code + * [2004-Jan-04/2004-Feb-01] + *@endcode + * where the date formatting is controlled by the date facet + */ + template > > + class period_formatter { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + typedef typename std::basic_string::const_iterator const_itr_type; + typedef std::vector > collection_type; + + static const char_type default_period_separator[2]; + static const char_type default_period_start_delimeter[2]; + static const char_type default_period_open_range_end_delimeter[2]; + static const char_type default_period_closed_range_end_delimeter[2]; + + enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE }; + + //! Constructor that sets up period formatter options -- default should suffice most cases. + period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE, + const char_type* const period_separator = default_period_separator, + const char_type* const period_start_delimeter = default_period_start_delimeter, + const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter, + const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) : + m_range_option(range_option_in), + m_period_separator(period_separator), + m_period_start_delimeter(period_start_delimeter), + m_open_range_end_delimeter(period_open_range_end_delimeter), + m_closed_range_end_delimeter(period_closed_range_end_delimeter) + {} + + //! Puts the characters between period elements into stream -- default is / + OutItrT put_period_separator(OutItrT& oitr) const + { + const_itr_type ci = m_period_separator.begin(); + while (ci != m_period_separator.end()) { + *oitr = *ci; + ci++; + } + return oitr; + } + + //! Puts the period start characters into stream -- default is [ + OutItrT put_period_start_delimeter(OutItrT& oitr) const + { + const_itr_type ci = m_period_start_delimeter.begin(); + while (ci != m_period_start_delimeter.end()) { + *oitr = *ci; + ci++; + } + return oitr; + } + + //! Puts the period end characters into stream as controled by open/closed range setting. + OutItrT put_period_end_delimeter(OutItrT& oitr) const + { + + const_itr_type ci, end; + if (m_range_option == AS_OPEN_RANGE) { + ci = m_open_range_end_delimeter.begin(); + end = m_open_range_end_delimeter.end(); + } + else { + ci = m_closed_range_end_delimeter.begin(); + end = m_closed_range_end_delimeter.end(); + } + while (ci != end) { + *oitr = *ci; + ci++; + } + return oitr; + } + + range_display_options range_option() const + { + return m_range_option; + } + + //! Reset the range_option control + void + range_option(range_display_options option) const + { + m_range_option = option; + } + void delimiter_strings(const string_type& separator, + const string_type& start_delim, + const string_type& open_end_delim, + const string_type& closed_end_delim) + { + m_period_separator; + m_period_start_delimeter; + m_open_range_end_delimeter; + m_closed_range_end_delimeter; + } + + + //! Generic code to output a period -- no matter the period type. + /*! This generic code will output any period using a facet to + * to output the 'elements'. For example, in the case of a date_period + * the elements will be instances of a date which will be formatted + * according the to setup in the passed facet parameter. + * + * The steps for formatting a period are always the same: + * - put the start delimiter + * - put start element + * - put the separator + * - put either last or end element depending on range settings + * - put end delimeter depending on range settings + * + * Thus for a typical date period the result might look like this: + *@code + * + * [March 01, 2004/June 07, 2004] <-- closed range + * [March 01, 2004/June 08, 2004) <-- open range + * + *@endcode + */ + template + OutItrT put_period(OutItrT next, + std::ios_base& a_ios, + char_type a_fill, + const period_type& p, + const facet_type& facet) const { + put_period_start_delimeter(next); + next = facet.put(next, a_ios, a_fill, p.begin()); + put_period_separator(next); + if (m_range_option == AS_CLOSED_RANGE) { + facet.put(next, a_ios, a_fill, p.last()); + } + else { + facet.put(next, a_ios, a_fill, p.end()); + } + put_period_end_delimeter(next); + return next; + } + + + private: + range_display_options m_range_option; + string_type m_period_separator; + string_type m_period_start_delimeter; + string_type m_open_range_end_delimeter; + string_type m_closed_range_end_delimeter; + }; + + template + const typename period_formatter::char_type + period_formatter::default_period_separator[2] = {'/'}; + + template + const typename period_formatter::char_type + period_formatter::default_period_start_delimeter[2] = {'['}; + + template + const typename period_formatter::char_type + period_formatter::default_period_open_range_end_delimeter[2] = {')'}; + + template + const typename period_formatter::char_type + period_formatter::default_period_closed_range_end_delimeter[2] = {']'}; + + } } //namespace boost::date_time + +#endif diff --git a/thirdparty/boost/date_time/period_parser.hpp b/thirdparty/boost/date_time/period_parser.hpp new file mode 100644 index 0000000..57623e1 --- /dev/null +++ b/thirdparty/boost/date_time/period_parser.hpp @@ -0,0 +1,196 @@ + +#ifndef DATETIME_PERIOD_PARSER_HPP___ +#define DATETIME_PERIOD_PARSER_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/string_convert.hpp" + + +namespace boost { namespace date_time { + + + //! Not a facet, but a class used to specify and control period parsing + /*! Provides settings for the following: + * - period_separator -- default '/' + * - period_open_start_delimeter -- default '[' + * - period_open_range_end_delimeter -- default ')' + * - period_closed_range_end_delimeter -- default ']' + * - display_as_open_range, display_as_closed_range -- default closed_range + * + * For a typical date_period, the contents of the input stream would be + *@code + * [2004-Jan-04/2004-Feb-01] + *@endcode + * where the date format is controlled by the date facet + */ + template + class period_parser { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + //typedef typename std::basic_string::const_iterator const_itr_type; + typedef std::istreambuf_iterator stream_itr_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + static const char_type default_period_separator[2]; + static const char_type default_period_start_delimeter[2]; + static const char_type default_period_open_range_end_delimeter[2]; + static const char_type default_period_closed_range_end_delimeter[2]; + + enum period_range_option { AS_OPEN_RANGE, AS_CLOSED_RANGE }; + + //! Constructor that sets up period parser options + period_parser(period_range_option range_option = AS_CLOSED_RANGE, + const char_type* const period_separator = default_period_separator, + const char_type* const period_start_delimeter = default_period_start_delimeter, + const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter, + const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) + : m_range_option(range_option) + { + delimiters.push_back(string_type(period_separator)); + delimiters.push_back(string_type(period_start_delimeter)); + delimiters.push_back(string_type(period_open_range_end_delimeter)); + delimiters.push_back(string_type(period_closed_range_end_delimeter)); + } + + period_parser(const period_parser& p_parser) + { + this->delimiters = p_parser.delimiters; + this->m_range_option = p_parser.m_range_option; + } + + period_range_option range_option() const + { + return m_range_option; + } + void range_option(period_range_option option) + { + m_range_option = option; + } + collection_type delimiter_strings() const + { + return delimiters; + } + void delimiter_strings(const string_type& separator, + const string_type& start_delim, + const string_type& open_end_delim, + const string_type& closed_end_delim) + { + delimiters.clear(); + delimiters.push_back(separator); + delimiters.push_back(start_delim); + delimiters.push_back(open_end_delim); + delimiters.push_back(closed_end_delim); + } + + //! Generic code to parse a period -- no matter the period type. + /*! This generic code will parse any period using a facet to + * to get the 'elements'. For example, in the case of a date_period + * the elements will be instances of a date which will be parsed + * according the to setup in the passed facet parameter. + * + * The steps for parsing a period are always the same: + * - consume the start delimiter + * - get start element + * - consume the separator + * - get either last or end element depending on range settings + * - consume the end delimeter depending on range settings + * + * Thus for a typical date period the contents of the input stream + * might look like this: + *@code + * + * [March 01, 2004/June 07, 2004] <-- closed range + * [March 01, 2004/June 08, 2004) <-- open range + * + *@endcode + */ + template + period_type get_period(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const period_type& p, + const duration_type& dur_unit, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + typedef typename period_type::point_type point_type; + point_type p1(not_a_date_time), p2(not_a_date_time); + + + consume_delim(sitr, stream_end, delimiters[START]); // start delim + facet.get(sitr, stream_end, a_ios, p1); // first point + consume_delim(sitr, stream_end, delimiters[SEPARATOR]); // separator + facet.get(sitr, stream_end, a_ios, p2); // second point + + // period construction parameters are always open range [begin, end) + if (m_range_option == AS_CLOSED_RANGE) { + consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim + // add 1 duration unit to p2 to make range open + p2 += dur_unit; + } + else { + consume_delim(sitr, stream_end, delimiters[OPEN_END]); // end delim + } + + return period_type(p1, p2); + } + + private: + collection_type delimiters; + period_range_option m_range_option; + + enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END }; + + //! throws ios_base::failure if delimiter and parsed data do not match + void consume_delim(stream_itr_type& sitr, + stream_itr_type& stream_end, + const string_type& delim) const + { + /* string_parse_tree will not parse a string of punctuation characters + * without knowing exactly how many characters to process + * Ex [2000. Will not parse out the '[' string without knowing + * to process only one character. By using length of the delimiter + * string we can safely iterate past it. */ + string_type s; + for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) { + s += *sitr; + ++sitr; + } + if(s != delim) { + throw std::ios_base::failure("Parse failed. Expected '" + convert_string_type(delim) + "' but found '" + convert_string_type(s) + "'"); + } + } + }; + + template + const typename period_parser::char_type + period_parser::default_period_separator[2] = {'/'}; + + template + const typename period_parser::char_type + period_parser::default_period_start_delimeter[2] = {'['}; + + template + const typename period_parser::char_type + period_parser::default_period_open_range_end_delimeter[2] = {')'}; + + template + const typename period_parser::char_type + period_parser::default_period_closed_range_end_delimeter[2] = {']'}; + + } } //namespace boost::date_time + +#endif // DATETIME_PERIOD_PARSER_HPP___ diff --git a/thirdparty/boost/date_time/posix_time/conversion.hpp b/thirdparty/boost/date_time/posix_time/conversion.hpp new file mode 100644 index 0000000..78c3299 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/conversion.hpp @@ -0,0 +1,93 @@ +#ifndef POSIX_TIME_CONVERSION_HPP___ +#define POSIX_TIME_CONVERSION_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/posix_time/ptime.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/filetime_functions.hpp" +#include "boost/date_time/c_time.hpp" +#include "boost/date_time/gregorian/conversion.hpp" + +namespace boost { + +namespace posix_time { + + + //! Function that converts a time_t into a ptime. + inline + ptime from_time_t(std::time_t t) + { + ptime start(gregorian::date(1970,1,1)); + return start + seconds(static_cast(t)); + } + + //! Convert a time to a tm structure truncating any fractional seconds + inline + std::tm to_tm(const boost::posix_time::ptime& t) { + std::tm timetm = boost::gregorian::to_tm(t.date()); + boost::posix_time::time_duration td = t.time_of_day(); + timetm.tm_hour = td.hours(); + timetm.tm_min = td.minutes(); + timetm.tm_sec = td.seconds(); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + //! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components + inline + std::tm to_tm(const boost::posix_time::time_duration& td) { + std::tm timetm; + timetm.tm_year = 0; + timetm.tm_mon = 0; + timetm.tm_mday = 0; + timetm.tm_wday = 0; + timetm.tm_yday = 0; + + timetm.tm_hour = date_time::absolute_value(td.hours()); + timetm.tm_min = date_time::absolute_value(td.minutes()); + timetm.tm_sec = date_time::absolute_value(td.seconds()); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + + //! Convert a tm struct to a ptime ignoring is_dst flag + inline + ptime ptime_from_tm(const std::tm& timetm) { + boost::gregorian::date d = boost::gregorian::date_from_tm(timetm); + return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec)); + } + + +#if defined(BOOST_HAS_FTIME) + + //! Function to create a time object from an initialized FILETIME struct. + /*! Function to create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the FILETIME's sub second value + * will be truncated. Nanosecond resolution has no truncation. + * + * Note ftime is part of the Win32 API, so it is not portable to non-windows + * platforms. + */ + template + inline + time_type from_ftime(const FILETIME& ft) + { + return boost::date_time::time_from_ftime(ft); + } + +#endif // BOOST_HAS_FTIME + +} } //namespace boost::posix_time + + + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/date_duration_operators.hpp b/thirdparty/boost/date_time/posix_time/date_duration_operators.hpp new file mode 100644 index 0000000..24f80cf --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/date_duration_operators.hpp @@ -0,0 +1,114 @@ +#ifndef DATE_DURATION_OPERATORS_HPP___ +#define DATE_DURATION_OPERATORS_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + /*!@file date_duration_operators.hpp Operators for ptime and + * optional gregorian types. Operators use snap-to-end-of-month behavior. + * Further details on this behavior can be found in reference for + * date_time/date_duration_types.hpp and documentation for + * month and year iterators. + */ + + + /*! Adds a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator+(const ptime& t, const boost::gregorian::months& m) + { + return t + m.get_offset(t.date()); + } + + /*! Adds a months object to a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator+=(ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t += m.get_offset(t.date()); + } + + /*! Subtracts a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator-(const ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t + m.get_neg_offset(t.date()); + } + + /*! Subtracts a months object from a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator-=(ptime& t, const boost::gregorian::months& m) + { + return t += m.get_neg_offset(t.date()); + } + + // ptime & years + + /*! Adds a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator+(const ptime& t, const boost::gregorian::years& y) + { + return t + y.get_offset(t.date()); + } + + /*! Adds a years object to a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator+=(ptime& t, const boost::gregorian::years& y) + { + return t += y.get_offset(t.date()); + } + + /*! Subtracts a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator-(const ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t + y.get_neg_offset(t.date()); + } + + /*! Subtracts a years object from a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator-=(ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t += y.get_neg_offset(t.date()); + } + +}} // namespaces + +#endif // DATE_DURATION_OPERATORS_HPP___ diff --git a/thirdparty/boost/date_time/posix_time/posix_time.hpp b/thirdparty/boost/date_time/posix_time/posix_time.hpp new file mode 100644 index 0000000..8e61953 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time.hpp @@ -0,0 +1,39 @@ +#ifndef POSIX_TIME_HPP___ +#define POSIX_TIME_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ +/*!@file posix_time.hpp Global header file to get all of posix time types + */ + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/posix_time/date_duration_operators.hpp" +#endif + +// output functions +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/posix_time/time_formatters_limited.hpp" +#else +#include "boost/date_time/posix_time/time_formatters.hpp" +#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS + +// streaming operators +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +#include "boost/date_time/posix_time/posix_time_legacy_io.hpp" +#else +#include "boost/date_time/posix_time/posix_time_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + +#include "boost/date_time/posix_time/time_parsers.hpp" +#include "boost/date_time/posix_time/conversion.hpp" + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/posix_time_config.hpp b/thirdparty/boost/date_time/posix_time/posix_time_config.hpp new file mode 100644 index 0000000..0441ae1 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_config.hpp @@ -0,0 +1,178 @@ +#ifndef POSIX_TIME_CONFIG_HPP___ +#define POSIX_TIME_CONFIG_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/time_duration.hpp" +#include "boost/date_time/time_resolution_traits.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/wrapping_int.hpp" +#include "boost/limits.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/cstdint.hpp" +#include +#include //for MCW 7.2 std::abs(long long) + +namespace boost { +namespace posix_time { + +//Remove the following line if you want 64 bit millisecond resolution time +//#define BOOST_GDTL_POSIX_TIME_STD_CONFIG + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + // set up conditional test compilations +#define BOOST_DATE_TIME_HAS_MILLISECONDS +#define BOOST_DATE_TIME_HAS_MICROSECONDS +#define BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits time_res_traits; +#else + // set up conditional test compilations +#define BOOST_DATE_TIME_HAS_MILLISECONDS +#define BOOST_DATE_TIME_HAS_MICROSECONDS +#undef BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits< + boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro, + 1000000, 6 > time_res_traits; + + +// #undef BOOST_DATE_TIME_HAS_MILLISECONDS +// #undef BOOST_DATE_TIME_HAS_MICROSECONDS +// #undef BOOST_DATE_TIME_HAS_NANOSECONDS +// typedef date_time::time_resolution_traits time_res_traits; + +#endif + + + //! Base time duration type + /*! \ingroup time_basics + */ + class time_duration : + public date_time::time_duration + { + public: + typedef time_res_traits rep_type; + typedef time_res_traits::day_type day_type; + typedef time_res_traits::hour_type hour_type; + typedef time_res_traits::min_type min_type; + typedef time_res_traits::sec_type sec_type; + typedef time_res_traits::fractional_seconds_type fractional_seconds_type; + typedef time_res_traits::tick_type tick_type; + typedef time_res_traits::impl_type impl_type; + time_duration(hour_type hour, + min_type min, + sec_type sec, + fractional_seconds_type fs=0) : + date_time::time_duration(hour,min,sec,fs) + {} + time_duration() : + date_time::time_duration(0,0,0) + {} + //! Construct from special_values + time_duration(boost::date_time::special_values sv) : + date_time::time_duration(sv) + {} + //Give duration access to ticks constructor -- hide from users + friend class date_time::time_duration; + private: + explicit time_duration(impl_type ticks) : + date_time::time_duration(ticks) + {} + }; + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + + //! Simple implementation for the time rep + struct simple_time_rep + { + typedef gregorian::date date_type; + typedef time_duration time_duration_type; + simple_time_rep(date_type d, time_duration_type tod) : + day(d), + time_of_day(tod) + { + // make sure we have sane values for date & time + if(!day.is_special() && !time_of_day.is_special()){ + if(time_of_day >= time_duration_type(24,0,0)) { + while(time_of_day >= time_duration_type(24,0,0)) { + day += date_type::duration_type(1); + time_of_day -= time_duration_type(24,0,0); + } + } + else if(time_of_day.is_negative()) { + while(time_of_day.is_negative()) { + day -= date_type::duration_type(1); + time_of_day += time_duration_type(24,0,0); + } + } + } + } + date_type day; + time_duration_type time_of_day; + bool is_special()const + { + return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time()); + } + bool is_pos_infinity()const + { + return(day.is_pos_infinity() || time_of_day.is_pos_infinity()); + } + bool is_neg_infinity()const + { + return(day.is_neg_infinity() || time_of_day.is_neg_infinity()); + } + bool is_not_a_date_time()const + { + return(day.is_not_a_date() || time_of_day.is_not_a_date_time()); + } + }; + + class posix_time_system_config + { + public: + typedef simple_time_rep time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000); +#endif + }; + +#else + + class millisec_posix_time_system_config + { + public: + typedef boost::int64_t time_rep_type; + //typedef time_res_traits::tick_type time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits::impl_type impl_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000); +#endif + }; + +#endif + +} }//namespace posix_time + + +#endif + + diff --git a/thirdparty/boost/date_time/posix_time/posix_time_duration.hpp b/thirdparty/boost/date_time/posix_time/posix_time_duration.hpp new file mode 100644 index 0000000..0ec4600 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_duration.hpp @@ -0,0 +1,82 @@ +#ifndef POSIX_TIME_DURATION_HPP___ +#define POSIX_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/posix_time/posix_time_config.hpp" + +namespace boost { +namespace posix_time { + + //! Allows expression of durations as an hour count + /*! \ingroup time_basics + */ + class hours : public time_duration + { + public: + explicit hours(long h) : + time_duration(h,0,0) + {} + }; + + //! Allows expression of durations as a minute count + /*! \ingroup time_basics + */ + class minutes : public time_duration + { + public: + explicit minutes(long m) : + time_duration(0,m,0) + {} + }; + + //! Allows expression of durations as a seconds count + /*! \ingroup time_basics + */ + class seconds : public time_duration + { + public: + explicit seconds(long s) : + time_duration(0,0,s) + {} + }; + + + //! Allows expression of durations as milli seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration millisec; + typedef date_time::subsecond_duration milliseconds; + + //! Allows expression of durations as micro seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration microsec; + typedef date_time::subsecond_duration microseconds; + + //This is probably not needed anymore... +#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS) + + //! Allows expression of durations as nano seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration nanosec; + typedef date_time::subsecond_duration nanoseconds; + + +#endif + + + + +} }//namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/posix_time_io.hpp b/thirdparty/boost/date_time/posix_time/posix_time_io.hpp new file mode 100644 index 0000000..5946e9e --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_io.hpp @@ -0,0 +1,246 @@ +#ifndef DATE_TIME_POSIX_TIME_IO_HPP__ +#define DATE_TIME_POSIX_TIME_IO_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/time_facet.hpp" +#include "boost/date_time/period_formatter.hpp" +#include "boost/date_time/posix_time/time_period.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +//#include "boost/date_time/gregorian/gregorian_io.hpp" +#include "boost/io/ios_state.hpp" +#include +#include + +namespace boost { +namespace posix_time { + + + //! wptime_facet is depricated and will be phased out. use wtime_facet instead + //typedef boost::date_time::time_facet wptime_facet; + //! ptime_facet is depricated and will be phased out. use time_facet instead + //typedef boost::date_time::time_facet ptime_facet; + + //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead + //typedef boost::date_time::time_input_facet wptime_input_facet; + //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead + //typedef boost::date_time::time_input_facet ptime_input_facet; + + typedef boost::date_time::time_facet wtime_facet; + typedef boost::date_time::time_facet time_facet; + + typedef boost::date_time::time_input_facet wtime_input_facet; + typedef boost::date_time::time_input_facet time_input_facet; + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const ptime& p) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + typedef std::time_put std_ptime_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(oitr, os, os.fill(), p); + else { + //instantiate a custom facet for dealing with times since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the locale did not already exist. Of course this will be overridden + //if the user imbues as some later point. + std::ostreambuf_iterator oitr(os); + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), p); + } + return os; + } + + //! input operator for ptime + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, ptime& pt) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, pt); + } + else { + time_input_facet* f = new time_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, pt); + } + } + catch(...) { + // mask tells us what exceptions are turned on + std::ios_base::iostate exception_mask = is.exceptions(); + // if the user wants exceptions on failbit, we'll rethrow our + // date_time exception & set the failbit + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} // ignore this one + throw; // rethrow original exception + } + else { + // if the user want's to fail quietly, we simply set the failbit + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const boost::posix_time::time_period& p) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + typedef std::time_put std_time_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(oitr, os, os.fill(), p); + } + else { + //instantiate a custom facet for dealing with periods since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the local did not already exist. Of course this will be overridden + //if the user imbues as some later point. + std::ostreambuf_iterator oitr(os); + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), p); + } + return os; + } + + //! input operator for time_period + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, time_period& tp) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, tp); + } + else { + time_input_facet* f = new time_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, tp); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + //! ostream operator for posix_time::time_duration + // todo fix to use facet -- place holder for now... + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_duration& td) + { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + typedef std::time_put std_ptime_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(oitr, os, os.fill(), td); + else { + //instantiate a custom facet for dealing with times since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the locale did not already exist. Of course this will be overridden + //if the user imbues as some later point. + std::ostreambuf_iterator oitr(os); + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), td); + } + return os; + } + + //! input operator for time_duration + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, time_duration& td) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, td); + } + else { + time_input_facet* f = new time_input_facet(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, td); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + +} } // namespaces +#endif // DATE_TIME_POSIX_TIME_IO_HPP__ diff --git a/thirdparty/boost/date_time/posix_time/posix_time_legacy_io.hpp b/thirdparty/boost/date_time/posix_time/posix_time_legacy_io.hpp new file mode 100644 index 0000000..ef71875 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_legacy_io.hpp @@ -0,0 +1,153 @@ +#ifndef POSIX_TIME_PRE133_OPERATORS_HPP___ +#define POSIX_TIME_PRE133_OPERATORS_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file posix_time_pre133_operators.hpp + * These input and output operators are for use with the + * pre 1.33 version of the date_time libraries io facet code. + * The operators used in version 1.33 and later can be found + * in posix_time_io.hpp */ + +#include +#include +#include +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#include "boost/date_time/posix_time/time_period.hpp" +#include "boost/date_time/time_parsing.hpp" + +namespace boost { +namespace posix_time { + + +//The following code is removed for configurations with poor std::locale support (eg: MSVC6, gcc 2.9x) +#ifndef BOOST_DATE_TIME_NO_LOCALE +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) + //! ostream operator for posix_time::time_duration + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_duration& td) + { + typedef boost::date_time::ostream_time_duration_formatter duration_formatter; + duration_formatter::duration_put(td, os); + return os; + } + + //! ostream operator for posix_time::ptime + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const ptime& t) + { + typedef boost::date_time::ostream_time_formatter time_formatter; + time_formatter::time_put(t, os); + return os; + } + + //! ostream operator for posix_time::time_period + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_period& tp) + { + typedef boost::date_time::ostream_time_period_formatter period_formatter; + period_formatter::period_put(tp, os); + return os; + } +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO +/******** input streaming ********/ + template + inline + std::basic_istream& operator>>(std::basic_istream& is, time_duration& td) + { + // need to create a std::string and parse it + std::basic_string inp_s; + std::stringstream out_ss; + is >> inp_s; + typename std::basic_string::iterator b = inp_s.begin(); + // need to use both iterators because there is no requirement + // for the data held by a std::basic_string<> be terminated with + // any marker (such as '\0'). + typename std::basic_string::iterator e = inp_s.end(); + while(b != e){ + out_ss << out_ss.narrow(*b, 0); + ++b; + } + + td = date_time::parse_delimited_time_duration(out_ss.str()); + return is; + } + + template + inline + std::basic_istream& operator>>(std::basic_istream& is, ptime& pt) + { + gregorian::date d(not_a_date_time); + time_duration td(0,0,0); + is >> d >> td; + pt = ptime(d, td); + + return is; + } + + /** operator>> for time_period. time_period must be in + * "[date time_duration/date time_duration]" format. */ + template + inline + std::basic_istream& operator>>(std::basic_istream& is, time_period& tp) + { + gregorian::date d(not_a_date_time); + time_duration td(0,0,0); + ptime beg(d, td); + ptime end(beg); + std::basic_string s; + // get first date string and remove leading '[' + is >> s; + { + std::basic_stringstream ss; + ss << s.substr(s.find('[')+1); + ss >> d; + } + // get first time_duration & second date string, remove the '/' + // and split into 2 strings + is >> s; + { + std::basic_stringstream ss; + ss << s.substr(0, s.find('/')); + ss >> td; + } + beg = ptime(d, td); + { + std::basic_stringstream ss; + ss << s.substr(s.find('/')+1); + ss >> d; + } + // get last time_duration and remove the trailing ']' + is >> s; + { + std::basic_stringstream ss; + ss << s.substr(0, s.find(']')); + ss >> td; + } + end = ptime(d, td); + + tp = time_period(beg,end); + return is; + } + + +#endif //BOOST_DATE_TIME_NO_LOCALE + +} } // namespaces + +#endif // POSIX_TIME_PRE133_OPERATORS_HPP___ diff --git a/thirdparty/boost/date_time/posix_time/posix_time_system.hpp b/thirdparty/boost/date_time/posix_time/posix_time_system.hpp new file mode 100644 index 0000000..e0cf1e9 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_system.hpp @@ -0,0 +1,68 @@ +#ifndef POSIX_TIME_SYSTEM_HPP___ +#define POSIX_TIME_SYSTEM_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/posix_time/posix_time_config.hpp" +#include "boost/date_time/time_system_split.hpp" +#include "boost/date_time/time_system_counted.hpp" +#include "boost/date_time/compiler_config.hpp" + + +namespace boost { +namespace posix_time { + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers + typedef date_time::split_timedate_system posix_time_system; +#else + typedef date_time::split_timedate_system posix_time_system; +#endif + +#else + + typedef date_time::counted_time_rep int64_time_rep; + typedef date_time::counted_time_system posix_time_system; + +#endif + +} }//namespace posix_time + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/boost/date_time/posix_time/posix_time_types.hpp b/thirdparty/boost/date_time/posix_time/posix_time_types.hpp new file mode 100644 index 0000000..ec1ad2e --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/posix_time_types.hpp @@ -0,0 +1,55 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + */ +#ifndef POSIX_TIME_TYPES_HPP___ +#define POSIX_TIME_TYPES_HPP___ + +#include "boost/date_time/time_clock.hpp" +#include "boost/date_time/microsec_time_clock.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/posix_time/date_duration_operators.hpp" +#endif +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/posix_time_system.hpp" +#include "boost/date_time/posix_time/time_period.hpp" +#include "boost/date_time/time_iterator.hpp" +#include "boost/date_time/dst_rules.hpp" + +namespace boost { + +//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties +namespace posix_time { + + //! Iterator over a defined time duration + /*! \ingroup time_basics + */ + typedef date_time::time_itr time_iterator; + //! A time clock that has a resolution of one second + /*! \ingroup time_basics + */ + typedef date_time::second_clock second_clock; + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + //! A time clock that has a resolution of one microsecond + /*! \ingroup time_basics + */ + typedef date_time::microsec_clock microsec_clock; +#endif + + //! Define a dst null dst rule for the posix_time system + typedef date_time::null_dst_rules no_dst; + //! Define US dst rule calculator for the posix_time system + typedef date_time::us_dst_rules us_dst; + + +} } //namespace posix_time + + + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/ptime.hpp b/thirdparty/boost/date_time/posix_time/ptime.hpp new file mode 100644 index 0000000..48132c9 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/ptime.hpp @@ -0,0 +1,65 @@ +#ifndef POSIX_PTIME_HPP___ +#define POSIX_PTIME_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/posix_time/posix_time_system.hpp" +#include "boost/date_time/time.hpp" + +namespace boost { + +namespace posix_time { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! Time type with no timezone or other adjustments + /*! \ingroup time_basics + */ + class ptime : public date_time::base_time + { + public: + typedef posix_time_system time_system_type; + typedef time_system_type::time_rep_type time_rep_type; + typedef time_system_type::time_duration_type time_duration_type; + typedef ptime time_type; + //! Construct with date and offset in day + ptime(gregorian::date d,time_duration_type td) : date_time::base_time(d,td) + {} + //! Construct a time at start of the given day (midnight) + explicit ptime(gregorian::date d) : date_time::base_time(d,time_duration_type(0,0,0)) + {} + //! Copy from time_rep + ptime(const time_rep_type& rhs): + date_time::base_time(rhs) + {} + //! Construct from special value + ptime(const special_values sv) : date_time::base_time(sv) + {} +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + // Default constructor constructs to not_a_date_time + ptime() : date_time::base_time(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + + }; + + + +} }//namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/time_formatters.hpp b/thirdparty/boost/date_time/posix_time/time_formatters.hpp new file mode 100644 index 0000000..2dfe978 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/time_formatters.hpp @@ -0,0 +1,289 @@ +#ifndef POSIXTIME_FORMATTERS_HPP___ +#define POSIXTIME_FORMATTERS_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" +#include "boost/date_time/time_formatting_streams.hpp" + +#include "boost/date_time/time_parsing.hpp" + +/* NOTE: The "to_*_string" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * formatters_limited.hpp + */ + +namespace boost { + +namespace posix_time { + + // template function called by wrapper functions: + // to_*_string(time_duration) & to_*_wstring(time_duration) + template + inline std::basic_string to_simple_string_type(time_duration td) { + std::basic_ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) + { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.hours()) << ":"; + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.minutes()) << ":"; + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + charT buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill(fill_char) + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456 + /*!\ingroup time_format + */ + inline std::string to_simple_string(time_duration td) { + return to_simple_string_type(td); + } + + + // template function called by wrapper functions: + // to_*_string(time_duration) & to_*_wstring(time_duration) + template + inline std::basic_string to_iso_string_type(time_duration td) + { + std::basic_ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.hours()); + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.minutes()); + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + charT buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill(fill_char) + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 + /*!\ingroup time_format + */ + inline std::string to_iso_string(time_duration td){ + return to_iso_string_type(td); + } + + //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff + /*!\ingroup time_format + */ + template + inline std::basic_string to_simple_string_type(ptime t) + { + // can't use this w/gcc295, no to_simple_string_type<>(td) available + std::basic_string ts = gregorian::to_simple_string_type(t.date());// + " "; + if(!t.time_of_day().is_special()) { + charT space = ' '; + return ts + space + to_simple_string_type(t.time_of_day()); + } + else { + return ts; + } + } + inline std::string to_simple_string(ptime t){ + return to_simple_string_type(t); + } + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_simple_string_type(time_period tp) + { + charT beg = '[', mid = '/', end = ']'; + std::basic_string d1(to_simple_string_type(tp.begin())); + std::basic_string d2(to_simple_string_type(tp.last())); + return std::basic_string(beg + d1 + mid + d2 + end); + } + //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff] + /*!\ingroup time_format + */ + inline std::string to_simple_string(time_period tp){ + return to_simple_string_type(tp); + } + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_iso_string_type(ptime t) + { + std::basic_string ts = gregorian::to_iso_string_type(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + charT sep = 'T'; + return ts + sep + to_iso_string_type(t.time_of_day()); + } + else { + return ts; + } + } + //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::string to_iso_string(ptime t){ + return to_iso_string_type(t); + } + + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_iso_extended_string_type(ptime t) + { + std::basic_string ts = gregorian::to_iso_extended_string_type(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + charT sep = 'T'; + return ts + sep + to_simple_string_type(t.time_of_day()); + } + else { + return ts; + } + } + //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::string to_iso_extended_string(ptime t){ + return to_iso_extended_string_type(t); + } + +#if !defined(BOOST_NO_STD_WSTRING) + //! Time duration to wstring -hh::mm::ss.fffffff. Example: 10:09:03.0123456 + /*!\ingroup time_format + */ + inline std::wstring to_simple_wstring(time_duration td) { + return to_simple_string_type(td); + } + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 + /*!\ingroup time_format + */ + inline std::wstring to_iso_wstring(time_duration td){ + return to_iso_string_type(td); + } + inline std::wstring to_simple_wstring(ptime t){ + return to_simple_string_type(t); + } + //! Convert to wstring of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff] + /*!\ingroup time_format + */ + inline std::wstring to_simple_wstring(time_period tp){ + return to_simple_string_type(tp); + } + //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::wstring to_iso_wstring(ptime t){ + return to_iso_string_type(t); + } + //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::wstring to_iso_extended_wstring(ptime t){ + return to_iso_extended_string_type(t); + } + +#endif // BOOST_NO_STD_WSTRING + + +} } //namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/time_formatters_limited.hpp b/thirdparty/boost/date_time/posix_time/time_formatters_limited.hpp new file mode 100644 index 0000000..0c67080 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/time_formatters_limited.hpp @@ -0,0 +1,211 @@ +#ifndef POSIXTIME_FORMATTERS_LIMITED_HPP___ +#define POSIXTIME_FORMATTERS_LIMITED_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" +#include "boost/date_time/time_formatting_streams.hpp" + +namespace boost { + +namespace posix_time { + + //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456 + /*!\ingroup time_format + */ + inline std::string to_simple_string(time_duration td) { + std::ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) + { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.hours()) << ":"; + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.minutes()) << ":"; + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + char buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill('0') + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 + /*!\ingroup time_format + */ + inline + std::string + to_iso_string(time_duration td) + { + std::ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.hours()); + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.minutes()); + ss << std::setw(2) << std::setfill('0') + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + char buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill('0') + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + + //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff + /*!\ingroup time_format + */ + inline + std::string + to_simple_string(ptime t) + { + std::string ts = gregorian::to_simple_string(t.date());// + " "; + if(!t.time_of_day().is_special()) { + return ts + " " + to_simple_string(t.time_of_day()); + } + else { + return ts; + } + } + + //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff] + /*!\ingroup time_format + */ + inline + std::string + to_simple_string(time_period tp) + { + std::string d1(to_simple_string(tp.begin())); + std::string d2(to_simple_string(tp.last())); + return std::string("[" + d1 + "/" + d2 +"]"); + } + + //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator + /*!\ingroup time_format + */ + inline + std::string to_iso_string(ptime t) + { + std::string ts = gregorian::to_iso_string(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + return ts + "T" + to_iso_string(t.time_of_day()); + } + else { + return ts; + } + } + + //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator + /*!\ingroup time_format + */ + inline + std::string + to_iso_extended_string(ptime t) + { + std::string ts = gregorian::to_iso_extended_string(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + return ts + "T" + to_simple_string(t.time_of_day()); + } + else { + return ts; + } + } + + +} } //namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/time_parsers.hpp b/thirdparty/boost/date_time/posix_time/time_parsers.hpp new file mode 100644 index 0000000..d40270c --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/time_parsers.hpp @@ -0,0 +1,44 @@ +#ifndef POSIXTIME_PARSERS_HPP___ +#define POSIXTIME_PARSERS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/time_parsing.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" + + +namespace boost { + +namespace posix_time { + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". */ + inline time_duration duration_from_string(const std::string& s) { + return date_time::parse_delimited_time_duration(s); + } + + inline ptime time_from_string(const std::string& s) { + return date_time::parse_delimited_time(s, ' '); + } + + inline ptime from_iso_string(const std::string& s) { + return date_time::parse_iso_time(s, 'T'); + } + + + +} } //namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/time_period.hpp b/thirdparty/boost/date_time/posix_time/time_period.hpp new file mode 100644 index 0000000..96ca091 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/time_period.hpp @@ -0,0 +1,29 @@ +#ifndef POSIX_TIME_PERIOD_HPP___ +#define POSIX_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/period.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + //! Time period type + /*! \ingroup time_basics + */ + typedef date_time::period time_period; + + +} }//namespace posix_time + + +#endif + diff --git a/thirdparty/boost/date_time/posix_time/time_serialize.hpp b/thirdparty/boost/date_time/posix_time/time_serialize.hpp new file mode 100644 index 0000000..f338da1 --- /dev/null +++ b/thirdparty/boost/date_time/posix_time/time_serialize.hpp @@ -0,0 +1,200 @@ +#ifndef POSIX_TIME_SERIALIZE_HPP___ +#define POSIX_TIME_SERIALIZE_HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/date_time/gregorian/greg_serialize.hpp" +#include "boost/serialization/split_free.hpp" + + +// macros to split serialize functions into save & load functions +// NOTE: these macros define template functions in the boost::serialization namespace. +// They must be expanded *outside* of any namespace +BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime) +BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration) +BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period) + +namespace boost { +namespace serialization { + + +/*** time_duration ***/ + +//! Function to save posix_time::time_duration objects using serialization lib +/*! time_duration objects are broken down into 4 parts for serialization: + * types are hour_type, min_type, sec_type, and fractional_seconds_type + * as defined in the time_duration class + */ +template +void save(Archive & ar, + const posix_time::time_duration& td, + unsigned int /*version*/) +{ + // serialize a bool so we know how to read this back in later + bool is_special = td.is_special(); + ar & make_nvp("is_special", is_special); + if(is_special) { + std::string s = to_simple_string(td); + ar & make_nvp("sv_time_duration", s); + } + else { + typename posix_time::time_duration::hour_type h = td.hours(); + typename posix_time::time_duration::min_type m = td.minutes(); + typename posix_time::time_duration::sec_type s = td.seconds(); + typename posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds(); + ar & make_nvp("time_duration_hours", h); + ar & make_nvp("time_duration_minutes", m); + ar & make_nvp("time_duration_seconds", s); + ar & make_nvp("time_duration_fractional_seconds", fs); + } +} + +//! Function to load posix_time::time_duration objects using serialization lib +/*! time_duration objects are broken down into 4 parts for serialization: + * types are hour_type, min_type, sec_type, and fractional_seconds_type + * as defined in the time_duration class + */ +template +void load(Archive & ar, + posix_time::time_duration & td, + unsigned int /*version*/) +{ + bool is_special = false; + ar & make_nvp("is_special", is_special); + if(is_special) { + std::string s; + ar & make_nvp("sv_time_duration", s); + posix_time::special_values sv = gregorian::special_value_from_string(s); + td = posix_time::time_duration(sv); + } + else { + typename posix_time::time_duration::hour_type h(0); + typename posix_time::time_duration::min_type m(0); + typename posix_time::time_duration::sec_type s(0); + typename posix_time::time_duration::fractional_seconds_type fs(0); + ar & make_nvp("time_duration_hours", h); + ar & make_nvp("time_duration_minutes", m); + ar & make_nvp("time_duration_seconds", s); + ar & make_nvp("time_duration_fractional_seconds", fs); + td = posix_time::time_duration(h,m,s,fs); + } +} + +// no load_construct_data function provided as time_duration provides a +// default constructor + +/*** ptime ***/ + +//! Function to save posix_time::ptime objects using serialization lib +/*! ptime objects are broken down into 2 parts for serialization: + * a date object and a time_duration onject + */ +template +void save(Archive & ar, + const posix_time::ptime& pt, + unsigned int /*version*/) +{ + // from_iso_string does not include fractional seconds + // therefore date and time_duration are used + typename posix_time::ptime::date_type d = pt.date(); + ar & make_nvp("ptime_date", d); + if(!pt.is_special()) { + typename posix_time::ptime::time_duration_type td = pt.time_of_day(); + ar & make_nvp("ptime_time_duration", td); + } +} + +//! Function to load posix_time::ptime objects using serialization lib +/*! ptime objects are broken down into 2 parts for serialization: + * a date object and a time_duration onject + */ +template +void load(Archive & ar, + posix_time::ptime & pt, + unsigned int /*version*/) +{ + // from_iso_string does not include fractional seconds + // therefore date and time_duration are used + typename posix_time::ptime::date_type d(posix_time::not_a_date_time); + typename posix_time::ptime::time_duration_type td; + ar & make_nvp("ptime_date", d); + if(!d.is_special()) { + ar & make_nvp("ptime_time_duration", td); + pt = boost::posix_time::ptime(d,td); + } + else { + pt = boost::posix_time::ptime(d.as_special()); + } + +} + +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + posix_time::ptime* pt, + const unsigned int /*file_version*/) +{ + // retrieve data from archive required to construct new + // invoke inplace constructor to initialize instance of date + new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time); +} + +/*** time_period ***/ + +//! Function to save posix_time::time_period objects using serialization lib +/*! time_period objects are broken down into 2 parts for serialization: + * a begining ptime object and an ending ptime object + */ +template +void save(Archive & ar, + const posix_time::time_period& tp, + unsigned int /*version*/) +{ + posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day()); + posix_time::ptime end(tp.end().date(), tp.end().time_of_day()); + ar & make_nvp("time_period_begin", beg); + ar & make_nvp("time_period_end", end); +} + +//! Function to load posix_time::time_period objects using serialization lib +/*! time_period objects are broken down into 2 parts for serialization: + * a begining ptime object and an ending ptime object + */ +template +void load(Archive & ar, + boost::posix_time::time_period & tp, + unsigned int /*version*/) +{ + posix_time::time_duration td(1,0,0); + gregorian::date d(gregorian::not_a_date_time); + posix_time::ptime beg(d,td); + posix_time::ptime end(d,td); + ar & make_nvp("time_period_begin", beg); + ar & make_nvp("time_period_end", end); + tp = boost::posix_time::time_period(beg, end); +} + +//!override needed b/c no default constructor +template +inline void load_construct_data(Archive & ar, + boost::posix_time::time_period* tp, + const unsigned int /*file_version*/) +{ + posix_time::time_duration td(1,0,0); + gregorian::date d(gregorian::not_a_date_time); + posix_time::ptime beg(d,td); + posix_time::ptime end(d,td); + new(tp) boost::posix_time::time_period(beg,end); +} + +} // namespace serialization +} // namespace boost + +#endif diff --git a/thirdparty/boost/date_time/special_defs.hpp b/thirdparty/boost/date_time/special_defs.hpp new file mode 100644 index 0000000..2d1c123 --- /dev/null +++ b/thirdparty/boost/date_time/special_defs.hpp @@ -0,0 +1,25 @@ +#ifndef DATE_TIME_SPECIAL_DEFS_HPP__ +#define DATE_TIME_SPECIAL_DEFS_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +namespace boost { +namespace date_time { + + enum special_values {not_a_date_time, + neg_infin, pos_infin, + min_date_time, max_date_time, + not_special, NumSpecialValues}; + + +} } //namespace date_time + + +#endif + diff --git a/thirdparty/boost/date_time/special_values_formatter.hpp b/thirdparty/boost/date_time/special_values_formatter.hpp new file mode 100644 index 0000000..e3b13e5 --- /dev/null +++ b/thirdparty/boost/date_time/special_values_formatter.hpp @@ -0,0 +1,96 @@ + +#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___ +#define DATETIME_SPECIAL_VALUE_FORMATTER_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include +#include "boost/date_time/special_defs.hpp" + +namespace boost { namespace date_time { + + + //! Class that provides generic formmatting ostream formatting for special values + /*! This class provides for the formmating of special values to an output stream. + * In particular, it produces strings for the values of negative and positive + * infinity as well as not_a_date_time. + * + * While not a facet, this class is used by the date and time facets for formatting + * special value types. + * + */ + template > > + class special_values_formatter + { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + typedef std::vector collection_type; + static const char_type default_special_value_names[3][17]; + + //! Construct special values formatter using default strings. + /*! Default strings are not-a-date-time -infinity +infinity + */ + special_values_formatter() + { + std::copy(&default_special_value_names[0], + &default_special_value_names[3], + std::back_inserter(m_special_value_names)); + } + + //! Construct special values formatter from array of strings + /*! This constructor will take pair of iterators from an array of strings + * that represent the special values and copy them for use in formatting + * special values. + *@code + * const char* const special_value_names[]={"nadt","-inf","+inf" }; + * + * special_value_formatter svf(&special_value_names[0], &special_value_names[3]); + *@endcode + */ + special_values_formatter(const char_type* const* begin, const char_type* const* end) + { + std::copy(begin, end, std::back_inserter(m_special_value_names)); + } + special_values_formatter(typename collection_type::iterator beg, typename collection_type::iterator end) + { + std::copy(beg, end, std::back_inserter(m_special_value_names)); + } + + OutItrT put_special(OutItrT next, + const boost::date_time::special_values& value) const + { + + unsigned int index = value; + if (index < m_special_value_names.size()) { + std::copy(m_special_value_names[index].begin(), + m_special_value_names[index].end(), + next); + } + return next; + } + protected: + collection_type m_special_value_names; + }; + + //! Storage for the strings used to indicate special values + /* using c_strings to initialize these worked fine in testing, however, + * a project that compiled its objects separately, then linked in a separate + * step wound up with redefinition errors for the values in this array. + * Initializing individual characters eliminated this problem */ + template + const typename special_values_formatter::char_type special_values_formatter::default_special_value_names[3][17] = { + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}, + {'-','i','n','f','i','n','i','t','y'}, + {'+','i','n','f','i','n','i','t','y'} }; + + } } //namespace boost::date_time + +#endif diff --git a/thirdparty/boost/date_time/special_values_parser.hpp b/thirdparty/boost/date_time/special_values_parser.hpp new file mode 100644 index 0000000..7ad0375 --- /dev/null +++ b/thirdparty/boost/date_time/special_values_parser.hpp @@ -0,0 +1,159 @@ + +#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ +#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: + */ + + +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/special_defs.hpp" +#include +#include + +namespace boost { namespace date_time { + + //! Class for special_value parsing + /*! + * TODO: add doc-comments for which elements can be changed + * Parses input stream for strings representing special_values. + * Special values parsed are: + * - not_a_date_time + * - neg_infin + * - pod_infin + * - min_date_time + * - max_date_time + */ + template + class special_values_parser + { + public: + typedef std::basic_string string_type; + //typedef std::basic_stringstream stringstream_type; + typedef std::istreambuf_iterator stream_itr_type; + //typedef typename string_type::const_iterator const_itr; + //typedef typename date_type::year_type year_type; + //typedef typename date_type::month_type month_type; + typedef typename date_type::duration_type duration_type; + //typedef typename date_type::day_of_week_type day_of_week_type; + //typedef typename date_type::day_type day_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + typedef charT char_type; + static const char_type nadt_string[16]; + static const char_type neg_inf_string[10]; + static const char_type pos_inf_string[10]; + static const char_type min_date_time_string[18]; + static const char_type max_date_time_string[18]; + + //! Creates a special_values_parser with the default set of "sv_strings" + special_values_parser() + { + sv_strings(string_type(nadt_string), + string_type(neg_inf_string), + string_type(pos_inf_string), + string_type(min_date_time_string), + string_type(max_date_time_string)); + } + + //! Creates a special_values_parser using a user defined set of element strings + special_values_parser(const string_type& nadt_str, + const string_type& neg_inf_str, + const string_type& pos_inf_str, + const string_type& min_dt_str, + const string_type& max_dt_str) + { + sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str); + } + + special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end) + { + collection_type phrases; + std::copy(beg, end, std::back_inserter(phrases)); + m_sv_strings = parse_tree_type(phrases, static_cast(not_a_date_time)); + } + + special_values_parser(const special_values_parser& svp) + { + this->m_sv_strings = svp.m_sv_strings; + } + + //! Replace special value strings + void sv_strings(const string_type& nadt_str, + const string_type& neg_inf_str, + const string_type& pos_inf_str, + const string_type& min_dt_str, + const string_type& max_dt_str) + { + collection_type phrases; + phrases.push_back(nadt_str); + phrases.push_back(neg_inf_str); + phrases.push_back(pos_inf_str); + phrases.push_back(min_dt_str); + phrases.push_back(max_dt_str); + m_sv_strings = parse_tree_type(phrases, static_cast(not_a_date_time)); + } + + /* Does not return a special_value because if the parsing fails, + * the return value will always be not_a_date_time + * (mr.current_match retains its default value of -1 on a failed + * parse and that casts to not_a_date_time). */ + //! Sets match_results.current_match to the corresponding special_value or -1 + bool match(stream_itr_type& sitr, + stream_itr_type& str_end, + match_results& mr) const + { + unsigned int level = 0; + m_sv_strings.match(sitr, str_end, mr, level); + return (mr.current_match != match_results::PARSE_ERROR); + } + /*special_values match(stream_itr_type& sitr, + stream_itr_type& str_end, + match_results& mr) const + { + unsigned int level = 0; + m_sv_strings.match(sitr, str_end, mr, level); + if(mr.current_match == match_results::PARSE_ERROR) { + throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"); + } + return static_cast(mr.current_match); + }*/ + + + private: + parse_tree_type m_sv_strings; + + }; + + template + const typename special_values_parser::char_type + special_values_parser::nadt_string[16] = + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}; + template + const typename special_values_parser::char_type + special_values_parser::neg_inf_string[10] = + {'-','i','n','f','i','n','i','t','y'}; + template + const typename special_values_parser::char_type + special_values_parser::pos_inf_string[10] = + {'+','i','n','f','i','n','i','t','y'}; + template + const typename special_values_parser::char_type + special_values_parser::min_date_time_string[18] = + {'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'}; + template + const typename special_values_parser::char_type + special_values_parser::max_date_time_string[18] = + {'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'}; + +} } //namespace + +#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ + diff --git a/thirdparty/boost/date_time/string_convert.hpp b/thirdparty/boost/date_time/string_convert.hpp new file mode 100644 index 0000000..e5190a9 --- /dev/null +++ b/thirdparty/boost/date_time/string_convert.hpp @@ -0,0 +1,33 @@ +#ifndef _STRING_CONVERT_HPP___ +#define _STRING_CONVERT_HPP___ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/compiler_config.hpp" +#include + +namespace boost { +namespace date_time { + + //! Converts a string from one value_type to another + /*! Converts a wstring to a string (or a string to wstring). If both template parameters + * are of same type, a copy of the input string is returned. */ + template + inline + std::basic_string convert_string_type(const std::basic_string& inp_str) + { + typedef std::basic_string input_type; + typedef std::basic_string output_type; + output_type result; + result.insert(result.begin(), inp_str.begin(), inp_str.end()); + return result; + } + +}} // namespace boost::date_time + +#endif // _STRING_CONVERT_HPP___ diff --git a/thirdparty/boost/date_time/string_parse_tree.hpp b/thirdparty/boost/date_time/string_parse_tree.hpp new file mode 100644 index 0000000..fc357cf --- /dev/null +++ b/thirdparty/boost/date_time/string_parse_tree.hpp @@ -0,0 +1,278 @@ +#ifndef BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__ +#define BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/lexical_cast.hpp" //error without? +#include "boost/algorithm/string/case_conv.hpp" +#include +#include +#include +#include + +namespace boost { namespace date_time { + + +template +struct parse_match_result +{ + parse_match_result() : + match_depth(0), + current_match(-1)// -1 is match_not-found value + {} + typedef std::basic_string string_type; + string_type remaining() const + { + if (match_depth == cache.size()) { + return string_type(); + } + if (current_match == -1) { + return cache; + } + //some of the cache was used return the rest + return string_type(cache, match_depth); + } + charT last_char() const + { + return cache[cache.size()-1]; + } + //! Returns true if more characters were parsed than was necessary + /*! Should be used in conjunction with last_char() + * to get the remaining character. + */ + bool has_remaining() const + { + return (cache.size() > match_depth); + } + + // cache will hold characters that have been read from the stream + string_type cache; + unsigned short match_depth; + short current_match; + enum PARSE_STATE { PARSE_ERROR= -1 }; +}; + + //for debug -- really only char streams... +template +std::basic_ostream& +operator<<(std::basic_ostream& os, parse_match_result& mr) +{ + os << "cm: " << mr.current_match + << " C: '" << mr.cache + << "' md: " << mr.match_depth + << " R: " << mr.remaining(); + return os; +} + + + +//! Recursive data structure to allow efficient parsing of various strings +/*! This class provides a quick lookup by building what amounts to a + * tree data structure. It also features a match function which can + * can handle nasty input interators by caching values as it recurses + * the tree so that it can backtrack as needed. + */ +template +struct string_parse_tree +{ +#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) + typedef std::multimap > ptree_coll; +#else + typedef std::multimap ptree_coll; +#endif + typedef typename ptree_coll::value_type value_type; + typedef typename ptree_coll::iterator iterator; + typedef typename ptree_coll::const_iterator const_iterator; + typedef std::basic_string string_type; + typedef std::vector > collection_type; + typedef parse_match_result parse_match_result_type; + + /*! Parameter "starting_point" desingates where the numbering begins. + * A starting_point of zero will start the numbering at zero + * (Sun=0, Mon=1, ...) were a starting_point of one starts the + * numbering at one (Jan=1, Feb=2, ...). The default is zero, + * negative vaules are not allowed */ + string_parse_tree(collection_type names, unsigned int starting_point=0) + { + // iterate thru all the elements and build the tree + unsigned short index = 0; + while (index != names.size() ) { + string_type s = boost::algorithm::to_lower_copy(names[index]); + insert(s, static_cast(index + starting_point)); + index++; + } + //set the last tree node = index+1 indicating a value + index++; + } + + + string_parse_tree(short value = -1) : + m_value(value) + {} + ptree_coll m_next_chars; + short m_value; + + void insert(const string_type& s, unsigned short value) + { + unsigned int i = 0; + iterator ti; + while(i < s.size()) { + if (i==0) { + if (i == (s.size()-1)) { + ti = m_next_chars.insert(value_type(s[i], + string_parse_tree(value))); + } + else { + ti = m_next_chars.insert(value_type(s[i], + string_parse_tree())); + } + } + else { + if (i == (s.size()-1)) { + ti = ti->second.m_next_chars.insert(value_type(s[i], + string_parse_tree(value))); + } + + else { + ti = ti->second.m_next_chars.insert(value_type(s[i], + string_parse_tree())); + } + + } + i++; + } + } + + + //! Recursive function that finds a matching string in the tree. + /*! Must check match_results::has_remaining() after match() is + * called. This is required so the user can determine if + * stream iterator is already pointing to the expected + * character or not (match() might advance sitr to next char in stream). + * + * A parse_match_result that has been returned from a failed match + * attempt can be sent in to the match function of a different + * string_parse_tree to attempt a match there. Use the iterators + * for the partially consumed stream, the parse_match_result object, + * and '0' for the level parameter. */ + short + match(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + parse_match_result_type& result, + unsigned int& level) const + { + + level++; + charT c; + // if we conditionally advance sitr, we won't have + // to consume the next character past the input + bool adv_itr = true; + if (level > result.cache.size()) { + if (sitr == stream_end) return 0; //bail - input exhausted + c = static_cast(std::tolower(*sitr)); + //result.cache += c; + //sitr++; + } + else { + // if we're looking for characters from the cache, + // we don't want to increment sitr + adv_itr = false; + c = static_cast(std::tolower(result.cache[level-1])); + } + const_iterator litr = m_next_chars.lower_bound(c); + const_iterator uitr = m_next_chars.upper_bound(c); + while (litr != uitr) { // equal if not found + if(adv_itr) { + sitr++; + result.cache += c; + } + if (litr->second.m_value != -1) { // -1 is default value + if (result.match_depth < level) { + result.current_match = litr->second.m_value; + result.match_depth = static_cast(level); + } + litr->second.match(sitr, stream_end, + result, level); + level--; + } + else { + litr->second.match(sitr, stream_end, + result, level); + level--; + } + + if(level <= result.cache.size()) { + adv_itr = false; + } + + litr++; + } + return result.current_match; + + } + + /*! Must check match_results::has_remaining() after match() is + * called. This is required so the user can determine if + * stream iterator is already pointing to the expected + * character or not (match() might advance sitr to next char in stream). + */ + parse_match_result_type + match(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // lookup to_lower of char in tree. + unsigned int level = 0; + // string_type cache; + parse_match_result_type result; + match(sitr, stream_end, result, level); + return result; + } + + void printme(std::ostream& os, int& level) + { + level++; + iterator itr = m_next_chars.begin(); + iterator end = m_next_chars.end(); + // os << "starting level: " << level << std::endl; + while (itr != end) { + os << "level: " << level + << " node: " << itr->first + << " value: " << itr->second.m_value + << std::endl; + itr->second.printme(os, level); + itr++; + } + level--; + } + + void print(std::ostream& os) + { + int level = 0; + printme(os, level); + } + + void printmatch(std::ostream& os, charT c) + { + iterator litr = m_next_chars.lower_bound(c); + iterator uitr = m_next_chars.upper_bound(c); + os << "matches for: " << c << std::endl; + while (litr != uitr) { + os << " node: " << litr->first + << " value: " << litr->second.m_value + << std::endl; + litr++; + } + } + +}; + + +} } //namespace +#endif diff --git a/thirdparty/boost/date_time/strings_from_facet.hpp b/thirdparty/boost/date_time/strings_from_facet.hpp new file mode 100644 index 0000000..11155d7 --- /dev/null +++ b/thirdparty/boost/date_time/strings_from_facet.hpp @@ -0,0 +1,123 @@ +#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___ +#define DATE_TIME_STRINGS_FROM_FACET__HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include +#include +#include +#include + +namespace boost { namespace date_time { + +//! This function gathers up all the month strings from a std::locale +/*! Using the time_put facet, this function creates a collection of + * all the month strings from a locale. This is handy when building + * custom date parsers or formatters that need to be localized. + * + *@param charT The type of char to use when gathering typically char + * or wchar_t. + *@param locale The locale to use when gathering the strings + *@param short_strings True(default) to gather short strings, + * false for long strings. + *@return A vector of strings containing the strings in order. eg: + * Jan, Feb, Mar, etc. + */ +template +std::vector > +gather_month_strings(const std::locale& locale, bool short_strings=true) +{ + typedef std::basic_string string_type; + typedef std::vector collection_type; + typedef std::basic_ostringstream ostream_type; + typedef std::ostreambuf_iterator ostream_iter_type; + typedef std::basic_ostringstream stringstream_type; + typedef std::time_put time_put_facet_type; + charT short_fmt[3] = { '%', 'b' }; + charT long_fmt[3] = { '%', 'B' }; + collection_type months; + string_type outfmt(short_fmt); + if (!short_strings) { + outfmt = long_fmt; + } + { + //grab the needed strings by using the locale to + //output each month + for (int m=0; m < 12; m++) { + tm tm_value; + tm_value.tm_mon = m; + stringstream_type ss; + ostream_iter_type oitr(ss); + std::use_facet(locale).put(oitr, ss, ss.fill(), + &tm_value, + &*outfmt.begin(), + &*outfmt.begin()+outfmt.size()); + months.push_back(ss.str()); + } + } + return months; +} + +//! This function gathers up all the weekday strings from a std::locale +/*! Using the time_put facet, this function creates a collection of + * all the weekday strings from a locale starting with the string for + * 'Sunday'. This is handy when building custom date parsers or + * formatters that need to be localized. + * + *@param charT The type of char to use when gathering typically char + * or wchar_t. + *@param locale The locale to use when gathering the strings + *@param short_strings True(default) to gather short strings, + * false for long strings. + *@return A vector of strings containing the weekdays in order. eg: + * Sun, Mon, Tue, Wed, Thu, Fri, Sat + */ +template +std::vector > +gather_weekday_strings(const std::locale& locale, bool short_strings=true) +{ + typedef std::basic_string string_type; + typedef std::vector collection_type; + typedef std::basic_ostringstream ostream_type; + typedef std::ostreambuf_iterator ostream_iter_type; + typedef std::basic_ostringstream stringstream_type; + typedef std::time_put time_put_facet_type; + charT short_fmt[3] = { '%', 'a' }; + charT long_fmt[3] = { '%', 'A' }; + + collection_type weekdays; + + + string_type outfmt(short_fmt); + if (!short_strings) { + outfmt = long_fmt; + } + { + //grab the needed strings by using the locale to + //output each month / weekday + for (int i=0; i < 7; i++) { + tm tm_value; + tm_value.tm_wday = i; + stringstream_type ss; + ostream_iter_type oitr(ss); + std::use_facet(locale).put(oitr, ss, ss.fill(), + &tm_value, + &*outfmt.begin(), + &*outfmt.begin()+outfmt.size()); + + weekdays.push_back(ss.str()); + } + } + return weekdays; +} + +} } //namespace + + +#endif diff --git a/thirdparty/boost/date_time/testfrmwk.hpp b/thirdparty/boost/date_time/testfrmwk.hpp new file mode 100644 index 0000000..6450ecf --- /dev/null +++ b/thirdparty/boost/date_time/testfrmwk.hpp @@ -0,0 +1,66 @@ + +#ifndef TEST_FRMWK_HPP___ +#define TEST_FRMWK_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * $Date: 2008-03-26 17:16:15 -0400 (Wed, 26 Mar 2008) $ + */ + + +#include +#include + +//! Really simple test framework for counting and printing +class TestStats +{ +public: + static TestStats& instance() {static TestStats ts; return ts;} + void addPassingTest() {testcount_++; passcount_++;} + void addFailingTest() {testcount_++;} + unsigned int testcount() const {return testcount_;} + unsigned int passcount() const {return passcount_;} + void print(std::ostream& out = std::cout) const + { + out << testcount_ << " Tests Executed: " ; + if (passcount() != testcount()) { + out << (testcount() - passcount()) << " FAILURES"; + } + else { + out << "All Succeeded" << std::endl; + } + out << std::endl; + } +private: + TestStats() : testcount_(0), passcount_(0) {} + unsigned int testcount_; + unsigned int passcount_; +}; + + +bool check(const std::string& testname, bool testcond) +{ + TestStats& stat = TestStats::instance(); + if (testcond) { + std::cout << "Pass :: " << testname << " " << std::endl; + stat.addPassingTest(); + return true; + } + else { + stat.addFailingTest(); + std::cout << "FAIL :: " << testname << " " << std::endl; + return false; + } +} + + +int printTestStats() +{ + TestStats& stat = TestStats::instance(); + stat.print(); + return stat.testcount() - stat.passcount(); +} + +#endif diff --git a/thirdparty/boost/date_time/time.hpp b/thirdparty/boost/date_time/time.hpp new file mode 100644 index 0000000..512a1e5 --- /dev/null +++ b/thirdparty/boost/date_time/time.hpp @@ -0,0 +1,190 @@ +#ifndef DATE_TIME_TIME_HPP___ +#define DATE_TIME_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +/*! @file time.hpp + This file contains the interface for the time associated classes. +*/ +#include "boost/date_time/time_defs.hpp" +#include "boost/operators.hpp" +#include + +namespace boost { +namespace date_time { + + //! Representation of a precise moment in time, including the date. + /*! + This class is a skeleton for the interface of a temporal type + with a resolution that is higher than a day. It is intended that + this class be the base class and that the actual time + class be derived using the BN pattern. In this way, the derived + class can make decisions such as 'should there be a default constructor' + and what should it set its value to, should there be optional constructors + say allowing only an time_durations that generate a time from a clock,etc. + So, in fact multiple time types can be created for a time_system with + different construction policies, and all of them can perform basic + operations by only writing a copy constructor. Finally, compiler + errors are also shorter. + + The real behavior of the time class is provided by the time_system + template parameter. This class must provide all the logic + for addition, subtraction, as well as define all the interface + types. + + */ + + template + class base_time : private + boost::less_than_comparable > + { + public: + typedef T time_type; + typedef typename time_system::time_rep_type time_rep_type; + typedef typename time_system::date_type date_type; + typedef typename time_system::date_duration_type date_duration_type; + typedef typename time_system::time_duration_type time_duration_type; + //typedef typename time_system::hms_type hms_type; + + base_time(const date_type& day, + const time_duration_type& td, + dst_flags dst=not_dst) : + time_(time_system::get_time_rep(day, td, dst)) + {} + base_time(special_values sv) : + time_(time_system::get_time_rep(sv)) + {} + base_time(const time_rep_type& rhs) : + time_(rhs) + {} + date_type date() const + { + return time_system::get_date(time_); + } + time_duration_type time_of_day() const + { + return time_system::get_time_of_day(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_name(bool as_offset=false) const + { + return time_system::zone_name(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_abbrev(bool as_offset=false) const + { + return time_system::zone_name(time_); + } + //! An empty string is returned for classes that do not use a time_zone + std::string zone_as_posix_string() const + { + return std::string(""); + } + + //! check to see if date is not a value + bool is_not_a_date_time() const + { + return time_.is_not_a_date_time(); + } + //! check to see if date is one of the infinity values + bool is_infinity() const + { + return (is_pos_infinity() || is_neg_infinity()); + } + //! check to see if date is greater than all possible dates + bool is_pos_infinity() const + { + return time_.is_pos_infinity(); + } + //! check to see if date is greater than all possible dates + bool is_neg_infinity() const + { + return time_.is_neg_infinity(); + } + //! check to see if time is a special value + bool is_special() const + { + return(is_not_a_date_time() || is_infinity()); + } + //!Equality operator -- others generated by boost::equality_comparable + bool operator==(const time_type& rhs) const + { + return time_system::is_equal(time_,rhs.time_); + } + //!Equality operator -- others generated by boost::less_than_comparable + bool operator<(const time_type& rhs) const + { + return time_system::is_less(time_,rhs.time_); + } + //! difference between two times + time_duration_type operator-(const time_type& rhs) const + { + return time_system::subtract_times(time_, rhs.time_); + } + //! add date durations + time_type operator+(const date_duration_type& dd) const + { + return time_system::add_days(time_, dd); + } + time_type operator+=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() + dd, time_of_day())); + return time_type(time_); + } + //! subtract date durations + time_type operator-(const date_duration_type& dd) const + { + return time_system::subtract_days(time_, dd); + } + time_type operator-=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() - dd, time_of_day())); + return time_type(time_); + } + //! add time durations + time_type operator+(const time_duration_type& td) const + { + return time_type(time_system::add_time_duration(time_, td)); + } + time_type operator+=(const time_duration_type& td) + { + time_ = (time_system::get_time_rep(date(), time_of_day() + td)); + return time_type(time_); + } + //! subtract time durations + time_type operator-(const time_duration_type& rhs) const + { + return time_system::subtract_time_duration(time_, rhs); + } + time_type operator-=(const time_duration_type& td) + { + time_ = (time_system::get_time_rep(date(), time_of_day() - td)); + return time_type(time_); + } + + protected: + time_rep_type time_; + }; + + + + + +} } //namespace date_time::boost + + +#endif + diff --git a/thirdparty/boost/date_time/time_clock.hpp b/thirdparty/boost/date_time/time_clock.hpp new file mode 100644 index 0000000..38f17d9 --- /dev/null +++ b/thirdparty/boost/date_time/time_clock.hpp @@ -0,0 +1,83 @@ +#ifndef DATE_TIME_TIME_CLOCK_HPP___ +#define DATE_TIME_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +/*! @file time_clock.hpp + This file contains the interface for clock devices. +*/ + +#include "boost/date_time/c_time.hpp" +#include "boost/shared_ptr.hpp" + +namespace boost { +namespace date_time { + + + //! A clock providing time level services based on C time_t capabilities + /*! This clock provides resolution to the 1 second level + */ + template + class second_clock + { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + + static time_type local_time() + { + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::localtime(&t); + curr_ptr = c_time::localtime(&t, &curr); + return create_time(curr_ptr); + } + + + //! Get the current day in universal date as a ymd_type + static time_type universal_time() + { + + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::gmtime(&t); + curr_ptr = c_time::gmtime(&t, &curr); + return create_time(curr_ptr); + } + + template + static time_type local_time(boost::shared_ptr tz_ptr) + { + typedef typename time_type::utc_time_type utc_time_type; + utc_time_type utc_time = second_clock::universal_time(); + return time_type(utc_time, tz_ptr); + } + + + private: + static time_type create_time(::std::tm* current) + { + date_type d(static_cast(current->tm_year + 1900), + static_cast(current->tm_mon + 1), + static_cast(current->tm_mday)); + time_duration_type td(current->tm_hour, + current->tm_min, + current->tm_sec); + return time_type(d,td); + } + + }; + + +} } //namespace date_time + + +#endif diff --git a/thirdparty/boost/date_time/time_defs.hpp b/thirdparty/boost/date_time/time_defs.hpp new file mode 100644 index 0000000..f33b7e5 --- /dev/null +++ b/thirdparty/boost/date_time/time_defs.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP +#define DATE_TIME_TIME_PRECISION_LIMITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + + +/*! \file time_defs.hpp + This file contains nice definitions for handling the resoluion of various time + reprsentations. +*/ + +namespace boost { +namespace date_time { + + //!Defines some nice types for handling time level resolutions + enum time_resolutions {sec, tenth, hundreth, milli, ten_thousandth, micro, nano, NumResolutions }; + + //! Flags for daylight savings or summer time + enum dst_flags {not_dst, is_dst, calculate}; + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/time_duration.hpp b/thirdparty/boost/date_time/time_duration.hpp new file mode 100644 index 0000000..eba1ef3 --- /dev/null +++ b/thirdparty/boost/date_time/time_duration.hpp @@ -0,0 +1,281 @@ +#ifndef DATE_TIME_TIME_DURATION_HPP___ +#define DATE_TIME_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/operators.hpp" +#include "boost/date_time/time_defs.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/compiler_config.hpp" + +namespace boost { +namespace date_time { + + + //! Represents some amount of elapsed time measure to a given resolution + /*! This class represents a standard set of capabilities for all + counted time durations. Time duration implementations should derive + from this class passing their type as the first template parameter. + This design allows the subclass duration types to provide custom + construction policies or other custom features not provided here. + + @param T The subclass type + @param rep_type The time resolution traits for this duration type. + */ + template + class time_duration : private + boost::less_than_comparable > + /* dividable, addable, and subtractable operator templates + * won't work with this class (MSVC++ 6.0). return type + * from '+=' is different than expected return type + * from '+'. multipliable probably wont work + * either (haven't tried) */ + { + public: + typedef T duration_type; //the subclass + typedef rep_type traits_type; + typedef typename rep_type::day_type day_type; + typedef typename rep_type::hour_type hour_type; + typedef typename rep_type::min_type min_type; + typedef typename rep_type::sec_type sec_type; + typedef typename rep_type::fractional_seconds_type fractional_seconds_type; + typedef typename rep_type::tick_type tick_type; + typedef typename rep_type::impl_type impl_type; + + time_duration() : ticks_(0) {} + time_duration(hour_type hours_in, + min_type minutes_in, + sec_type seconds_in=0, + fractional_seconds_type frac_sec_in = 0) : + ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in)) + {} + // copy constructor required for dividable<> + //! Construct from another time_duration (Copy constructor) + time_duration(const time_duration& other) + : ticks_(other.ticks_) + {} + //! Construct from special_values + time_duration(special_values sv) : ticks_(impl_type::from_special(sv)) + {} + //! Returns smallest representable duration + static duration_type unit() + { + return duration_type(0,0,0,1); + } + //! Return the number of ticks in a second + static tick_type ticks_per_second() + { + return rep_type::res_adjust(); + } + //! Provide the resolution of this duration type + static time_resolutions resolution() + { + return rep_type::resolution(); + } + //! Returns number of hours in the duration + hour_type hours() const + { + return static_cast(ticks() / (3600*ticks_per_second())); + } + //! Returns normalized number of minutes + min_type minutes() const + { + return static_cast((ticks() / (60*ticks_per_second())) % 60); + } + //! Returns normalized number of seconds (0..60) + sec_type seconds() const + { + return static_cast((ticks()/ticks_per_second()) % 60); + } + //! Returns total number of seconds truncating any fractional seconds + sec_type total_seconds() const + { + return static_cast(ticks() / ticks_per_second()); + } + //! Returns total number of milliseconds truncating any fractional seconds + tick_type total_milliseconds() const + { + if (ticks_per_second() < 1000) { + return ticks() * (static_cast(1000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000)) ; + } + //! Returns total number of nanoseconds truncating any sub millisecond values + tick_type total_nanoseconds() const + { + if (ticks_per_second() < 1000000000) { + return ticks() * (static_cast(1000000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000000)) ; + } + //! Returns total number of microseconds truncating any sub microsecond values + tick_type total_microseconds() const + { + if (ticks_per_second() < 1000000) { + return ticks() * (static_cast(1000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000)) ; + } + //! Returns count of fractional seconds at given resolution + fractional_seconds_type fractional_seconds() const + { + return (ticks() % ticks_per_second()); + } + //! Returns number of possible digits in fractional seconds + static unsigned short num_fractional_digits() + { + return rep_type::num_fractional_digits(); + } + duration_type invert_sign() const + { + return duration_type(ticks_ * (-1)); + } + bool is_negative() const + { + return ticks_ < 0; + } + bool operator<(const time_duration& rhs) const + { + return ticks_ < rhs.ticks_; + } + bool operator==(const time_duration& rhs) const + { + return ticks_ == rhs.ticks_; + } + //! unary- Allows for time_duration td = -td1 + duration_type operator-()const + { + return duration_type(ticks_ * (-1)); + } + duration_type operator-(const duration_type& d) const + { + return duration_type(ticks_ - d.ticks_); + } + duration_type operator+(const duration_type& d) const + { + return duration_type(ticks_ + d.ticks_); + } + duration_type operator/(int divisor) const + { + return duration_type(ticks_ / divisor); + } + duration_type operator-=(const duration_type& d) + { + ticks_ = ticks_ - d.ticks_; + return duration_type(ticks_); + } + duration_type operator+=(const duration_type& d) + { + ticks_ = ticks_ + d.ticks_; + return duration_type(ticks_); + } + //! Division operations on a duration with an integer. + duration_type operator/=(int divisor) + { + ticks_ = ticks_ / divisor; + return duration_type(ticks_); + } + //! Multiplication operations an a duration with an integer + duration_type operator*(int rhs) const + { + return duration_type(ticks_ * rhs); + } + duration_type operator*=(int divisor) + { + ticks_ = ticks_ * divisor; + return duration_type(ticks_); + } + tick_type ticks() const + { + return traits_type::as_number(ticks_); + } + + //! Is ticks_ a special value? + bool is_special()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_special(); + } + else{ + return false; + } + } + //! Is duration pos-infinity + bool is_pos_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_pos_infinity(); + } + else{ + return false; + } + } + //! Is duration neg-infinity + bool is_neg_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_neg_infinity(); + } + else{ + return false; + } + } + //! Is duration not-a-date-time + bool is_not_a_date_time()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_nan(); + } + else{ + return false; + } + } + + //! Used for special_values output + impl_type get_rep()const + { + return ticks_; + } + + protected: + explicit time_duration(impl_type in) : ticks_(in) {}; + impl_type ticks_; + }; + + + + //! Template for instantiating derived adjusting durations + /* These templates are designed to work with multiples of + * 10 for frac_of_second and resoultion adjustment + */ + template + class subsecond_duration : public base_duration + { + public: + typedef typename base_duration::traits_type traits_type; + explicit subsecond_duration(boost::int64_t ss) : + base_duration(0,0,0,ss*traits_type::res_adjust()/frac_of_second) + {} + }; + + + +} } //namespace date_time + + + + +#endif + diff --git a/thirdparty/boost/date_time/time_facet.hpp b/thirdparty/boost/date_time/time_facet.hpp new file mode 100644 index 0000000..3ade78b --- /dev/null +++ b/thirdparty/boost/date_time/time_facet.hpp @@ -0,0 +1,1263 @@ + +#ifndef _DATE_TIME_FACET__HPP__ +#define _DATE_TIME_FACET__HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Martin Andrian, Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/date_time/date_facet.hpp" +#include "boost/date_time/string_convert.hpp" +#include "boost/algorithm/string/erase.hpp" +#include +#include +#include + +namespace boost { +namespace date_time { + + template + struct time_formats { + public: + typedef CharT char_type; + static const char_type fractional_seconds_format[3]; // f + static const char_type fractional_seconds_or_none_format[3]; // F + static const char_type seconds_with_fractional_seconds_format[3]; // s + static const char_type seconds_format[3]; // S + static const char_type standard_format[9]; // x X + static const char_type zone_abbrev_format[3]; // z + static const char_type zone_name_format[3]; // Z + static const char_type zone_iso_format[3]; // q + static const char_type zone_iso_extended_format[3]; // Q + static const char_type posix_zone_string_format[4]; // ZP + static const char_type duration_sign_negative_only[3]; // - + static const char_type duration_sign_always[3]; // + + static const char_type duration_seperator[2]; + static const char_type negative_sign[2]; //- + static const char_type positive_sign[2]; //+ + static const char_type iso_time_format_specifier[18]; + static const char_type iso_time_format_extended_specifier[22]; + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + static const char_type default_time_format[23]; + // default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev + static const char_type default_time_input_format[24]; + //default time_duration format is HH:MM:SS[.fff...] + static const char_type default_time_duration_format[11]; + }; + + template + const typename time_formats::char_type + time_formats::fractional_seconds_format[3] = {'%','f'}; + + template + const typename time_formats::char_type + time_formats::fractional_seconds_or_none_format[3] = {'%','F'}; + + template + const typename time_formats::char_type + time_formats::seconds_with_fractional_seconds_format[3] = + {'%','s'}; + + template + const typename time_formats::char_type + time_formats::seconds_format[3] = {'%','S'}; + + template + const typename time_formats::char_type + //time_formats::standard_format[5] = {'%','c',' ','%','z'}; + time_formats::standard_format[9] = {'%','x',' ','%','X',' ','%','z'}; + + template + const typename time_formats::char_type + time_formats::zone_abbrev_format[3] = {'%','z'}; + + template + const typename time_formats::char_type + time_formats::zone_name_format[3] = {'%','Z'}; + + template + const typename time_formats::char_type + time_formats::zone_iso_format[3] = {'%','q'}; + + template + const typename time_formats::char_type + time_formats::zone_iso_extended_format[3] ={'%','Q'}; + + template + const typename time_formats::char_type + time_formats::posix_zone_string_format[4] ={'%','Z','P'}; + + template + const typename time_formats::char_type + time_formats::duration_seperator[2] = {':'}; + + template + const typename time_formats::char_type + time_formats::negative_sign[2] = {'-'}; + + template + const typename time_formats::char_type + time_formats::positive_sign[2] = {'+'}; + + template + const typename time_formats::char_type + time_formats::duration_sign_negative_only[3] ={'%','-'}; + + template + const typename time_formats::char_type + time_formats::duration_sign_always[3] ={'%','+'}; + + template + const typename time_formats::char_type + time_formats::iso_time_format_specifier[18] = + {'%', 'Y', '%', 'm', '%', 'd', 'T', + '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' }; + + template + const typename time_formats::char_type + time_formats::iso_time_format_extended_specifier[22] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', + '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'}; + + template + const typename time_formats::char_type + time_formats::default_time_format[23] = + {'%','Y','-','%','b','-','%','d',' ', + '%','H',':','%','M',':','%','S','%','F',' ','%','z'}; + + template + const typename time_formats::char_type + time_formats::default_time_input_format[24] = + {'%','Y','-','%','b','-','%','d',' ', + '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'}; + + template + const typename time_formats::char_type + time_formats::default_time_duration_format[11] = + {'%','H',':','%','M',':','%','S','%','F'}; + + + + /*! Facet used for format-based output of time types + * This class provides for the use of format strings to output times. In addition + * to the flags for formatting date elements, the following are the allowed format flags: + * - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z") + * - %f => fractional seconds ".123456" + * - %F => fractional seconds or none: like frac sec but empty if frac sec == 0 + * - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f) + * - %S => seconds "02" + * - %z => abbreviated time zone "EDT" + * - %Z => full time zone name "Eastern Daylight Time" + */ + template > > + class time_facet : + public boost::date_time::date_facet { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef boost::date_time::period period_type; + typedef boost::date_time::date_facet base_type; + typedef typename base_type::string_type string_type; + typedef typename base_type::char_type char_type; + typedef typename base_type::period_formatter_type period_formatter_type; + typedef typename base_type::special_values_formatter_type special_values_formatter_type; + typedef typename base_type::date_gen_formatter_type date_gen_formatter_type; + static const char_type* fractional_seconds_format; // %f + static const char_type* fractional_seconds_or_none_format; // %F + static const char_type* seconds_with_fractional_seconds_format; // %s + static const char_type* seconds_format; // %S + static const char_type* standard_format; // %x X + static const char_type* zone_abbrev_format; // %z + static const char_type* zone_name_format; // %Z + static const char_type* zone_iso_format; // %q + static const char_type* zone_iso_extended_format; // %Q + static const char_type* posix_zone_string_format; // %ZP + static const char_type* duration_seperator; + static const char_type* duration_sign_always; // %+ + static const char_type* duration_sign_negative_only; // %- + static const char_type* negative_sign; //- + static const char_type* positive_sign; //+ + static const char_type* iso_time_format_specifier; + static const char_type* iso_time_format_extended_specifier; + + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + static const char_type* default_time_format; + //default time_duration format is HH:MM:SS[.fff...] + static const char_type* default_time_duration_format; + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + //! sets default formats for ptime, local_date_time, and time_duration + explicit time_facet(::size_t /* a_ref */ = 0) + //: base_type(standard_format), + : base_type(default_time_format), + m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) + {} + + //! Construct the facet with an explicitly specified format + explicit time_facet(const char_type* a_format, + period_formatter_type period_formatter = period_formatter_type(), + const special_values_formatter_type& special_value_formatter = special_values_formatter_type(), + date_gen_formatter_type dg_formatter = date_gen_formatter_type(), + ::size_t a_ref = 0) + : base_type(a_format, + period_formatter, + special_value_formatter, + dg_formatter, + a_ref), + m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) + {} + + //! Changes format for time_duration + void time_duration_format(const char_type* const format) + { + m_time_duration_format = format; + } + + virtual void set_iso_format() + { + this->m_format = iso_time_format_specifier; + } + virtual void set_iso_extended_format() + { + this->m_format = iso_time_format_extended_specifier; + } + + OutItrT put(OutItrT a_next, + std::ios_base& a_ios, + char_type a_fill, + const time_type& a_time) const + { + if (a_time.is_special()) { + return this->do_put_special(a_next, a_ios, a_fill, + a_time.date().as_special()); + } + string_type format(this->m_format); + string_type frac_str; + if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { + // replace %s with %S.nnn + frac_str = + fractional_seconds_as_string(a_time.time_of_day(), false); + char_type sep = std::use_facet >(a_ios.getloc()).decimal_point(); + + string_type replace_string(seconds_format); + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + seconds_with_fractional_seconds_format, + replace_string); + } + /* NOTE: replacing posix_zone_string_format must be done BEFORE + * zone_name_format: "%ZP" & "%Z", if Z is checked first it will + * incorrectly replace a zone_name where a posix_string should go */ + if (format.find(posix_zone_string_format) != string_type::npos) { + if(a_time.zone_abbrev().empty()) { + // if zone_abbrev() returns an empty string, we want to + // erase posix_zone_string_format from format + boost::algorithm::replace_all(format, + posix_zone_string_format, + ""); + } + else{ + boost::algorithm::replace_all(format, + posix_zone_string_format, + a_time.zone_as_posix_string()); + } + } + if (format.find(zone_name_format) != string_type::npos) { + if(a_time.zone_name().empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_name() returns an empty string, we want to + // erase zone_name_format & one preceeding space + std::basic_ostringstream ss; + ss << ' ' << zone_name_format; + boost::algorithm::replace_all(format, + ss.str(), + ""); + } + else{ + boost::algorithm::replace_all(format, + zone_name_format, + a_time.zone_name()); + } + } + if (format.find(zone_abbrev_format) != string_type::npos) { + if(a_time.zone_abbrev(false).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_abbrev() returns an empty string, we want to + // erase zone_abbrev_format & one preceeding space + std::basic_ostringstream ss; + ss << ' ' << zone_abbrev_format; + boost::algorithm::replace_all(format, + ss.str(), + ""); + } + else{ + boost::algorithm::replace_all(format, + zone_abbrev_format, + a_time.zone_abbrev(false)); + } + } + if (format.find(zone_iso_extended_format) != string_type::npos) { + if(a_time.zone_name(true).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_name() returns an empty string, we want to + // erase zone_iso_extended_format from format + boost::algorithm::replace_all(format, + zone_iso_extended_format, + ""); + } + else{ + boost::algorithm::replace_all(format, + zone_iso_extended_format, + a_time.zone_name(true)); + } + } + + if (format.find(zone_iso_format) != string_type::npos) { + if(a_time.zone_abbrev(true).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_abbrev() returns an empty string, we want to + // erase zone_iso_format from format + boost::algorithm::replace_all(format, + zone_iso_format, + ""); + } + else{ + boost::algorithm::replace_all(format, + zone_iso_format, + a_time.zone_abbrev(true)); + } + } + if (format.find(fractional_seconds_format) != string_type::npos) { + // replace %f with nnnnnnn + if (!frac_str.size()) { + frac_str = fractional_seconds_as_string(a_time.time_of_day(), false); + } + boost::algorithm::replace_all(format, + fractional_seconds_format, + frac_str); + } + + if (format.find(fractional_seconds_or_none_format) != string_type::npos) { + // replace %F with nnnnnnn or nothing if fs == 0 + frac_str = + fractional_seconds_as_string(a_time.time_of_day(), true); + if (frac_str.size()) { + char_type sep = std::use_facet >(a_ios.getloc()).decimal_point(); + string_type replace_string; + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + fractional_seconds_or_none_format, + replace_string); + } + else { + boost::algorithm::erase_all(format, + fractional_seconds_or_none_format); + } + } + + return this->do_put_tm(a_next, a_ios, a_fill, + to_tm(a_time), format); + } + + //! put function for time_duration + OutItrT put(OutItrT a_next, + std::ios_base& a_ios, + char_type a_fill, + const time_duration_type& a_time_dur) const + { + if (a_time_dur.is_special()) { + return this->do_put_special(a_next, a_ios, a_fill, + a_time_dur.get_rep().as_special()); + } + + string_type format(m_time_duration_format); + if (a_time_dur.is_negative()) { + // replace %- with minus sign. Should we use the numpunct facet? + boost::algorithm::replace_all(format, + duration_sign_negative_only, + negative_sign); + // remove all the %+ in the string with '-' + boost::algorithm::replace_all(format, + duration_sign_always, + negative_sign); + } + else { //duration is positive + // remove all the %- combos from the string + boost::algorithm::replace_all(format, + duration_sign_negative_only, + ""); + // remove all the %+ in the string with '+' + boost::algorithm::replace_all(format, + duration_sign_always, + positive_sign); + } + + string_type frac_str; + if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { + // replace %s with %S.nnn + frac_str = + fractional_seconds_as_string(a_time_dur, false); + char_type sep = std::use_facet >(a_ios.getloc()).decimal_point(); + + string_type replace_string(seconds_format); + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + seconds_with_fractional_seconds_format, + replace_string); + } + if (format.find(fractional_seconds_format) != string_type::npos) { + // replace %f with nnnnnnn + if (!frac_str.size()) { + frac_str = fractional_seconds_as_string(a_time_dur, false); + } + boost::algorithm::replace_all(format, + fractional_seconds_format, + frac_str); + } + + if (format.find(fractional_seconds_or_none_format) != string_type::npos) { + // replace %F with nnnnnnn or nothing if fs == 0 + frac_str = + fractional_seconds_as_string(a_time_dur, true); + if (frac_str.size()) { + char_type sep = std::use_facet >(a_ios.getloc()).decimal_point(); + string_type replace_string; + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + fractional_seconds_or_none_format, + replace_string); + } + else { + boost::algorithm::erase_all(format, + fractional_seconds_or_none_format); + } + } + + return this->do_put_tm(a_next, a_ios, a_fill, + to_tm(a_time_dur), format); + } + + OutItrT put(OutItrT next, std::ios_base& a_ios, + char_type fill, const period_type& p) const + { + return this->m_period_formatter.put_period(next, a_ios, fill,p,*this); + } + + + protected: + + static + string_type + fractional_seconds_as_string(const time_duration_type& a_time, + bool null_when_zero) + { + typename time_duration_type::fractional_seconds_type frac_sec = + a_time.fractional_seconds(); + + if (null_when_zero && (frac_sec == 0)) { + return string_type(); + } + + //make sure there is no sign + frac_sec = date_time::absolute_value(frac_sec); + std::basic_ostringstream ss; + ss.imbue(std::locale::classic()); // don't want any formatting + ss << std::setw(time_duration_type::num_fractional_digits()) + << std::setfill(static_cast('0')); +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // JDG [7/6/02 VC++ compatibility] + char_type buff[34]; + ss << _i64toa(static_cast(frac_sec), buff, 10); +#else + ss << frac_sec; +#endif + return ss.str(); + } + + private: + string_type m_time_duration_format; + + }; + + template + std::locale::id time_facet::id; + + template + const typename time_facet::char_type* + time_facet::fractional_seconds_format = time_formats::fractional_seconds_format; + + template + const typename time_facet::char_type* + time_facet::fractional_seconds_or_none_format = time_formats::fractional_seconds_or_none_format; + + template + const typename time_facet::char_type* + time_facet::seconds_with_fractional_seconds_format = + time_formats::seconds_with_fractional_seconds_format; + + + template + const typename time_facet::char_type* + time_facet::zone_name_format = time_formats::zone_name_format; + + template + const typename time_facet::char_type* + time_facet::zone_abbrev_format = time_formats::zone_abbrev_format; + + template + const typename time_facet::char_type* + time_facet::zone_iso_extended_format =time_formats::zone_iso_extended_format; + + template + const typename time_facet::char_type* + time_facet::posix_zone_string_format =time_formats::posix_zone_string_format; + + template + const typename time_facet::char_type* + time_facet::zone_iso_format = time_formats::zone_iso_format; + + template + const typename time_facet::char_type* + time_facet::seconds_format = time_formats::seconds_format; + + template + const typename time_facet::char_type* + time_facet::standard_format = time_formats::standard_format; + + template + const typename time_facet::char_type* + time_facet::duration_seperator = time_formats::duration_seperator; + + template + const typename time_facet::char_type* + time_facet::negative_sign = time_formats::negative_sign; + + template + const typename time_facet::char_type* + time_facet::positive_sign = time_formats::positive_sign; + + template + const typename time_facet::char_type* + time_facet::duration_sign_negative_only = time_formats::duration_sign_negative_only; + + template + const typename time_facet::char_type* + time_facet::duration_sign_always = time_formats::duration_sign_always; + + template + const typename time_facet::char_type* + time_facet::iso_time_format_specifier = time_formats::iso_time_format_specifier; + + template + const typename time_facet::char_type* + time_facet::iso_time_format_extended_specifier = time_formats::iso_time_format_extended_specifier; + + template + const typename time_facet::char_type* + time_facet::default_time_format = + time_formats::default_time_format; + + template + const typename time_facet::char_type* + time_facet::default_time_duration_format = + time_formats::default_time_duration_format; + + + //! Facet for format-based input. + /*! + */ + template > > + class time_input_facet : + public boost::date_time::date_input_facet { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type; + typedef boost::date_time::period period_type; + typedef boost::date_time::date_input_facet base_type; + typedef typename base_type::duration_type date_duration_type; + typedef typename base_type::year_type year_type; + typedef typename base_type::month_type month_type; + typedef typename base_type::day_type day_type; + typedef typename base_type::string_type string_type; + typedef typename string_type::const_iterator const_itr; + typedef typename base_type::char_type char_type; + typedef typename base_type::format_date_parser_type format_date_parser_type; + typedef typename base_type::period_parser_type period_parser_type; + typedef typename base_type::special_values_parser_type special_values_parser_type; + typedef typename base_type::date_gen_parser_type date_gen_parser_type; + typedef typename base_type::special_values_parser_type::match_results match_results; + + static const char_type* fractional_seconds_format; // f + static const char_type* fractional_seconds_or_none_format; // F + static const char_type* seconds_with_fractional_seconds_format; // s + static const char_type* seconds_format; // S + static const char_type* standard_format; // x X + static const char_type* zone_abbrev_format; // z + static const char_type* zone_name_format; // Z + static const char_type* zone_iso_format; // q + static const char_type* zone_iso_extended_format; // Q + static const char_type* duration_seperator; + static const char_type* iso_time_format_specifier; + static const char_type* iso_time_format_extended_specifier; + static const char_type* default_time_input_format; + static const char_type* default_time_duration_format; + static std::locale::id id; + + //! Constructor that takes a format string for a ptime + explicit time_input_facet(const string_type& format, ::size_t a_ref = 0) + : base_type(format, a_ref), + m_time_duration_format(default_time_duration_format) + { } + + explicit time_input_facet(const string_type& format, + const format_date_parser_type& date_parser, + const special_values_parser_type& sv_parser, + const period_parser_type& per_parser, + const date_gen_parser_type& date_gen_parser, + ::size_t a_ref = 0) + : base_type(format, + date_parser, + sv_parser, + per_parser, + date_gen_parser, + a_ref), + m_time_duration_format(default_time_duration_format) + {} + + //! sets default formats for ptime, local_date_time, and time_duration + explicit time_input_facet(::size_t a_ref = 0) + : base_type(default_time_input_format, a_ref), + m_time_duration_format(default_time_duration_format) + { } + + //! Set the format for time_duration + void time_duration_format(const char_type* const format) { + m_time_duration_format = format; + } + virtual void set_iso_format() + { + this->m_format = iso_time_format_specifier; + } + virtual void set_iso_extended_format() + { + this->m_format = iso_time_format_extended_specifier; + } + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& a_ios, + period_type& p) const + { + p = this->m_period_parser.get_period(sitr, + stream_end, + a_ios, + p, + time_duration_type::unit(), + *this); + return sitr; + } + + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + //default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...] + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& a_ios, + time_duration_type& td) const + { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + + bool use_current_char = false; + + // num_get will consume the +/-, we may need a copy if special_value + char_type c = '\0'; + if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { + c = *sitr; + } + + long hour = 0; + long min = 0; + long sec = 0; + typename time_duration_type::fractional_seconds_type frac(0); + + typedef std::num_get num_get; + if(!std::has_facet(a_ios.getloc())) { + num_get* ng = new num_get(); + std::locale loc = std::locale(a_ios.getloc(), ng); + a_ios.imbue(loc); + } + + const_itr itr(m_time_duration_format.begin()); + while (itr != m_time_duration_format.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + switch(*itr) { + case 'H': + { + match_results mr; + hour = fixed_string_to_int(sitr, stream_end, mr, 2); + if(hour == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'M': + { + match_results mr; + min = fixed_string_to_int(sitr, stream_end, mr, 2); + if(min == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'S': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 's': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, td, c); + } + // %s is the same as %S%f so we drop through into %f + //break; + } + case 'f': + { + // check for decimal, check special_values if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'F': + { + // check for decimal, skip if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + break; + } + default: + {} // ignore what we don't understand? + }// switch + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + // set use_current_char when sitr is already + // pointing at the next character to process + if (use_current_char) { + use_current_char = false; + } + else { + sitr++; + } + } + } + + td = time_duration_type(hour, min, sec, frac); + return sitr; + } + + + //! Parses a time object from the input stream + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& a_ios, + time_type& t) const + { + string_type tz_str; + return get(sitr, stream_end, a_ios, t, tz_str, false); + } + //! Expects a time_zone in the input stream + InItrT get_local_time(InItrT& sitr, + InItrT& stream_end, + std::ios_base& a_ios, + time_type& t, + string_type& tz_str) const + { + return get(sitr, stream_end, a_ios, t, tz_str, true); + } + + protected: + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& a_ios, + time_type& t, + string_type& tz_str, + bool time_is_local) const + { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + + bool use_current_char = false; + bool use_current_format_char = false; // used whith two character flags + + // num_get will consume the +/-, we may need a copy if special_value + char_type c = '\0'; + if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { + c = *sitr; + } + + // time elements + long hour = 0; + long min = 0; + long sec = 0; + typename time_duration_type::fractional_seconds_type frac(0); + // date elements + short day_of_year(0); + /* Initialized the following to their minimum values. These intermediate + * objects are used so we get specific exceptions when part of the input + * is unparsable. + * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/ + year_type t_year(1400); + month_type t_month(1); + day_type t_day(1); + + typedef std::num_get num_get; + if(!std::has_facet(a_ios.getloc())) { + num_get* ng = new num_get(); + std::locale loc = std::locale(a_ios.getloc(), ng); + a_ios.imbue(loc); + } + + const_itr itr(this->m_format.begin()); + while (itr != this->m_format.end() && (sitr != stream_end)) { + if (*itr == '%') { + itr++; + if (*itr != '%') { + // the cases are grouped by date & time flags - not alphabetical order + switch(*itr) { + // date flags + case 'Y': + case 'y': + { + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + try { + t_year = this->m_parser.parse_year(sitr, stream_end, s, mr); + } + catch(std::out_of_range bad_year) { // base class for bad_year exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_year + } + } + break; + } + case 'B': + case 'b': + case 'm': + { + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + try { + t_month = this->m_parser.parse_month(sitr, stream_end, s, mr); + } + catch(std::out_of_range bad_month) { // base class for bad_month exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_year + } + } + // did m_parser already advance sitr to next char? + if(mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'a': + case 'A': + case 'w': + { + // weekday is not used in construction but we need to get it out of the stream + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + typename date_type::day_of_week_type wd(0); + try { + wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr); + } + catch(std::out_of_range bad_weekday) { // base class for bad_weekday exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_weekday + } + } + // did m_parser already advance sitr to next char? + if(mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'j': + { + // code that gets julian day (from format_date_parser) + match_results mr; + day_of_year = fixed_string_to_int(sitr, stream_end, mr, 3); + if(day_of_year == -1) { + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + } + // these next two lines are so we get an exception with bad input + typedef typename time_type::date_type::day_of_year_type day_of_year_type; + day_of_year_type t_day_of_year(day_of_year); + break; + } + case 'd': + { + try { + t_day = this->m_parser.parse_day_of_month(sitr, stream_end); + } + catch(std::out_of_range bad_day_of_month) { // base class for exception + match_results mr; + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_year + } + } + break; + } + // time flags + case 'H': + { + match_results mr; + hour = fixed_string_to_int(sitr, stream_end, mr, 2); + if(hour == -1){ + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 'M': + { + match_results mr; + min = fixed_string_to_int(sitr, stream_end, mr, 2); + if(min == -1){ + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 'S': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 's': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, t, c); + } + // %s is the same as %S%f so we drop through into %f + //break; + } + case 'f': + { + // check for decimal, check SV if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 'F': + { + // check for decimal, skip if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + break; + } + // time_zone flags + //case 'q': + //case 'Q': + //case 'z': + case 'Z': + { + if(time_is_local) { // skip if 't' is a ptime + ++itr; + if(*itr == 'P') { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + // parse zone + while((sitr != stream_end) && (!std::isspace(*sitr))) { + tz_str += *sitr; + ++sitr; + } + } + else { + use_current_format_char = true; + } + + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + + break; + } + default: + {} // ignore what we don't understand? + }// switch + } + else { // itr == '%', second consecutive + sitr++; + } + + if(use_current_format_char) { + use_current_format_char = false; + } + else { + itr++; //advance past format specifier + } + + } + else { //skip past chars in format and in buffer + itr++; + // set use_current_char when sitr is already + // pointing at the next character to process + if (use_current_char) { + use_current_char = false; + } + else { + sitr++; + } + } + } + + date_type d(not_a_date_time); + if (day_of_year > 0) { + d = date_type(static_cast(t_year-1),12,31) + date_duration_type(day_of_year); + } + else { + d = date_type(t_year, t_month, t_day); + } + + time_duration_type td(hour, min, sec, frac); + t = time_type(d, td); + return sitr; + } + + //! Helper function to check for special_value + /*! First character may have been consumed during original parse + * attempt. Parameter 'c' should be a copy of that character. + * Throws ios_base::failure if parse fails. */ + template + inline + InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const + { + match_results mr; + if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed? + mr.cache += c; + } + this->m_sv_parser.match(sitr, stream_end, mr); + if(mr.current_match == match_results::PARSE_ERROR) { + std::string tmp = convert_string_type(mr.cache); + throw std::ios_base::failure("Parse failed. No match found for '" + tmp + "'"); + } + tt = temporal_type(static_cast(mr.current_match)); + return sitr; + } + + //! Helper function for parsing a fractional second type from the stream + void parse_frac_type(InItrT& sitr, + InItrT& stream_end, + fracional_seconds_type& frac) const + { + string_type cache; + while((sitr != stream_end) && std::isdigit(*sitr)) { + cache += *sitr; + ++sitr; + } + if(cache.size() > 0) { + unsigned short precision = time_duration_type::num_fractional_digits(); + // input may be only the first few decimal places + if(cache.size() < precision) { + frac = lexical_cast(cache); + frac = decimal_adjust(frac, static_cast(precision - cache.size())); + } + else { + // if input has too many decimal places, drop excess digits + frac = lexical_cast(cache.substr(0, precision)); + } + } + } + + private: + string_type m_time_duration_format; + + //! Helper function to adjust trailing zeros when parsing fractional digits + template + inline + int_type decimal_adjust(int_type val, const unsigned short places) const + { + unsigned long factor = 1; + for(int i = 0; i < places; ++i){ + factor *= 10; // shift decimal to the right + } + return val * factor; + } + + }; + +template + std::locale::id time_input_facet::id; + +template + const typename time_input_facet::char_type* + time_input_facet::fractional_seconds_format = time_formats::fractional_seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::fractional_seconds_or_none_format = time_formats::fractional_seconds_or_none_format; + + template + const typename time_input_facet::char_type* + time_input_facet::seconds_with_fractional_seconds_format = time_formats::seconds_with_fractional_seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::seconds_format = time_formats::seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::standard_format = time_formats::standard_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_abbrev_format = time_formats::zone_abbrev_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_name_format = time_formats::zone_name_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_iso_format = time_formats::zone_iso_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_iso_extended_format = time_formats::zone_iso_extended_format; + + template + const typename time_input_facet::char_type* + time_input_facet::duration_seperator = time_formats::duration_seperator; + + template + const typename time_input_facet::char_type* + time_input_facet::iso_time_format_specifier = time_formats::iso_time_format_specifier; + + template + const typename time_input_facet::char_type* + time_input_facet::iso_time_format_extended_specifier = time_formats::iso_time_format_extended_specifier; + + template + const typename time_input_facet::char_type* + time_input_facet::default_time_input_format = time_formats::default_time_input_format; + + template + const typename time_input_facet::char_type* + time_input_facet::default_time_duration_format = time_formats::default_time_duration_format; + + +} } // namespaces + + +#endif + diff --git a/thirdparty/boost/date_time/time_formatting_streams.hpp b/thirdparty/boost/date_time/time_formatting_streams.hpp new file mode 100644 index 0000000..0595f82 --- /dev/null +++ b/thirdparty/boost/date_time/time_formatting_streams.hpp @@ -0,0 +1,119 @@ +#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___ +#define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/date_formatting_locales.hpp" +#include "boost/date_time/time_resolution_traits.hpp" + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +namespace boost { +namespace date_time { + + + //! Put a time type into a stream using appropriate facets + template + class ostream_time_duration_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; + + //! Put time into an ostream + static void duration_put(const time_duration_type& td, + ostream_type& os) + { + if(td.is_special()) { + os << td.get_rep(); + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + os << '-'; + } + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.hours()) << ":"; + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.minutes()) << ":"; + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.seconds()); + fractional_seconds_type frac_sec = + absolute_value(td.fractional_seconds()); + if (frac_sec != 0) { + os << "." + << std::setw(time_duration_type::num_fractional_digits()) + << std::setfill(fill_char) + << frac_sec; + } + } // else + } // duration_put + }; //class ostream_time_duration_formatter + + //! Put a time type into a stream using appropriate facets + template + class ostream_time_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef ostream_time_duration_formatter duration_formatter; + + //! Put time into an ostream + static void time_put(const time_type& t, + ostream_type& os) + { + date_type d = t.date(); + os << d; + if(!d.is_infinity() && !d.is_not_a_date()) + { + os << " "; //TODO: fix the separator here. + duration_formatter::duration_put(t.time_of_day(), os); + } + + } // time_to_ostream + }; //class ostream_time_formatter + + + //! Put a time period into a stream using appropriate facets + template + class ostream_time_period_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_period_type::point_type time_type; + typedef ostream_time_formatter time_formatter; + + //! Put time into an ostream + static void period_put(const time_period_type& tp, + ostream_type& os) + { + os << '['; //TODO: facet or manipulator for periods? + time_formatter::time_put(tp.begin(), os); + os << '/'; //TODO: facet or manipulator for periods? + time_formatter::time_put(tp.last(), os); + os << ']'; + + } // period_put + + }; //class ostream_time_period_formatter + + + +} } //namespace date_time + +#endif //BOOST_DATE_TIME_NO_LOCALE + +#endif + diff --git a/thirdparty/boost/date_time/time_iterator.hpp b/thirdparty/boost/date_time/time_iterator.hpp new file mode 100644 index 0000000..37f7782 --- /dev/null +++ b/thirdparty/boost/date_time/time_iterator.hpp @@ -0,0 +1,52 @@ +#ifndef DATE_TIME_TIME_ITERATOR_HPP___ +#define DATE_TIME_TIME_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +namespace boost { +namespace date_time { + + + //! Simple time iterator skeleton class + template + class time_itr { + public: + typedef typename time_type::time_duration_type time_duration_type; + time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {}; + time_itr& operator++() + { + current_ = current_ + offset_; + return *this; + } + time_itr& operator--() + { + current_ = current_ - offset_; + return *this; + } + time_type operator*() {return current_;}; + time_type* operator->() {return ¤t_;}; + bool operator< (const time_type& t) {return current_ < t;}; + bool operator<= (const time_type& t) {return current_ <= t;}; + bool operator!= (const time_type& t) {return current_ != t;}; + bool operator== (const time_type& t) {return current_ == t;}; + bool operator> (const time_type& t) {return current_ > t;}; + bool operator>= (const time_type& t) {return current_ >= t;}; + + private: + time_type current_; + time_duration_type offset_; + }; + + + +} }//namespace date_time + + +#endif diff --git a/thirdparty/boost/date_time/time_parsing.hpp b/thirdparty/boost/date_time/time_parsing.hpp new file mode 100644 index 0000000..6d3954b --- /dev/null +++ b/thirdparty/boost/date_time/time_parsing.hpp @@ -0,0 +1,321 @@ +#ifndef _DATE_TIME_TIME_PARSING_HPP___ +#define _DATE_TIME_TIME_PARSING_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/tokenizer.hpp" +#include "boost/lexical_cast.hpp" +#include "boost/date_time/date_parsing.hpp" +#include "boost/cstdint.hpp" +#include + +namespace boost { +namespace date_time { + + //! computes exponential math like 2^8 => 256, only works with positive integers + //Not general purpose, but needed b/c std::pow is not available + //everywehere. Hasn't been tested with negatives and zeros + template + inline + int_type power(int_type base, int_type exponent) + { + int_type result = 1; + for(int i = 0; i < exponent; ++i){ + result *= base; + } + return result; + } + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * If the number of fractional digits provided is greater than the + * precision of the time duration type then the extra digits are + * truncated. + * + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". + */ + template + inline + time_duration + str_from_delimited_time_duration(const std::basic_string& s) + { + unsigned short min=0, sec =0; + int hour =0; + bool is_neg = (s.at(0) == '-'); + boost::int64_t fs=0; + int pos = 0; + + typedef typename std::basic_string::traits_type traits_type; + typedef boost::char_separator char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef typename boost::tokenizer::const_iterator, + typename std::basic_string >::iterator tokenizer_iterator; + + char_type sep_chars[5] = {'-',':',',','.'}; + char_separator_type sep(sep_chars); + tokenizer tok(s,sep); + for(tokenizer_iterator beg=tok.begin(); beg!=tok.end();++beg){ + switch(pos) { + case 0: { + hour = boost::lexical_cast(*beg); + break; + } + case 1: { + min = boost::lexical_cast(*beg); + break; + } + case 2: { + sec = boost::lexical_cast(*beg); + break; + }; + case 3: { + int digits = static_cast(beg->length()); + //Works around a bug in MSVC 6 library that does not support + //operator>> thus meaning lexical_cast will fail to compile. +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // msvc wouldn't compile 'time_duration::num_fractional_digits()' + // (required template argument list) as a workaround a temp + // time_duration object was used + time_duration td(hour,min,sec,fs); + int precision = td.num_fractional_digits(); + // _atoi64 is an MS specific function + if(digits >= precision) { + // drop excess digits + fs = _atoi64(beg->substr(0, precision).c_str()); + } + else { + fs = _atoi64(beg->c_str()); + } +#else + int precision = time_duration::num_fractional_digits(); + if(digits >= precision) { + // drop excess digits + fs = boost::lexical_cast(beg->substr(0, precision)); + } + else { + fs = boost::lexical_cast(*beg); + } +#endif + if(digits < precision){ + // trailing zeros get dropped from the string, + // "1:01:01.1" would yield .000001 instead of .100000 + // the power() compensates for the missing decimal places + fs *= power(10, precision - digits); + } + + break; + } + }//switch + pos++; + } + if(is_neg) { + return -time_duration(hour, min, sec, fs); + } + else { + return time_duration(hour, min, sec, fs); + } + } + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * If the number of fractional digits provided is greater than the + * precision of the time duration type then the extra digits are + * truncated. + * + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". + */ + template + inline + time_duration + parse_delimited_time_duration(const std::string& s) + { + return str_from_delimited_time_duration(s); + } + + //! Utility function to split appart string + inline + bool + split(const std::string& s, + char sep, + std::string& first, + std::string& second) + { + int sep_pos = static_cast(s.find(sep)); + first = s.substr(0,sep_pos); + second = s.substr(sep_pos+1); + return true; + } + + + template + inline + time_type + parse_delimited_time(const std::string& s, char sep) + { + typedef typename time_type::time_duration_type time_duration; + typedef typename time_type::date_type date_type; + + //split date/time on a unique delimiter char such as ' ' or 'T' + std::string date_string, tod_string; + split(s, sep, date_string, tod_string); + //call parse_date with first string + date_type d = parse_date(date_string); + //call parse_time_duration with remaining string + time_duration td = parse_delimited_time_duration(tod_string); + //construct a time + return time_type(d, td); + + } + + //! Parse time duration part of an iso time of form: [-]hhmmss[.fff...] (eg: 120259.123 is 12 hours, 2 min, 59 seconds, 123000 microseconds) + template + inline + time_duration + parse_undelimited_time_duration(const std::string& s) + { + int precision = 0; + { + // msvc wouldn't compile 'time_duration::num_fractional_digits()' + // (required template argument list) as a workaround, a temp + // time_duration object was used + time_duration tmp(0,0,0,1); + precision = tmp.num_fractional_digits(); + } + // 'precision+1' is so we grab all digits, plus the decimal + int offsets[] = {2,2,2, precision+1}; + int pos = 0, sign = 0; + int hours = 0; + short min=0, sec=0; + boost::int64_t fs=0; + // increment one position if the string was "signed" + if(s.at(sign) == '-') + { + ++sign; + } + // stlport choked when passing s.substr() to tokenizer + // using a new string fixed the error + std::string remain = s.substr(sign); + /* We do not want the offset_separator to wrap the offsets, we + * will never want to process more than: + * 2 char, 2 char, 2 char, frac_sec length. + * We *do* want the offset_separator to give us a partial for the + * last characters if there were not enough provided in the input string. */ + bool wrap_off = false; + bool ret_part = true; + boost::offset_separator osf(offsets, offsets+4, wrap_off, ret_part); + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + tokenizer tok(remain, osf); + for(tokenizer_iterator ti=tok.begin(); ti!=tok.end();++ti){ + switch(pos) { + case 0: + { + hours = boost::lexical_cast(*ti); + break; + } + case 1: + { + min = boost::lexical_cast(*ti); + break; + } + case 2: + { + sec = boost::lexical_cast(*ti); + break; + } + case 3: + { + std::string char_digits(ti->substr(1)); // digits w/no decimal + int digits = static_cast(char_digits.length()); + + //Works around a bug in MSVC 6 library that does not support + //operator>> thus meaning lexical_cast will fail to compile. +#if (defined(BOOST_MSVC) && (_MSC_VER <= 1200)) // 1200 == VC++ 6.0 + // _atoi64 is an MS specific function + if(digits >= precision) { + // drop excess digits + fs = _atoi64(char_digits.substr(0, precision).c_str()); + } + else if(digits == 0) { + fs = 0; // just in case _atoi64 doesn't like an empty string + } + else { + fs = _atoi64(char_digits.c_str()); + } +#else + if(digits >= precision) { + // drop excess digits + fs = boost::lexical_cast(char_digits.substr(0, precision)); + } + else if(digits == 0) { + fs = 0; // lexical_cast doesn't like empty strings + } + else { + fs = boost::lexical_cast(char_digits); + } +#endif + if(digits < precision){ + // trailing zeros get dropped from the string, + // "1:01:01.1" would yield .000001 instead of .100000 + // the power() compensates for the missing decimal places + fs *= power(10, precision - digits); + } + + break; + } + }; + pos++; + } + if(sign) { + return -time_duration(hours, min, sec, fs); + } + else { + return time_duration(hours, min, sec, fs); + } + } + + //! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time + template + inline + time_type + parse_iso_time(const std::string& s, char sep) + { + typedef typename time_type::time_duration_type time_duration; + typedef typename time_type::date_type date_type; + + //split date/time on a unique delimiter char such as ' ' or 'T' + std::string date_string, tod_string; + split(s, sep, date_string, tod_string); + //call parse_date with first string + date_type d = parse_undelimited_date(date_string); + //call parse_time_duration with remaining string + time_duration td = parse_undelimited_time_duration(tod_string); + //construct a time + return time_type(d, td); + } + + + +} }//namespace date_time + + + + +#endif diff --git a/thirdparty/boost/date_time/time_resolution_traits.hpp b/thirdparty/boost/date_time/time_resolution_traits.hpp new file mode 100644 index 0000000..6e72543 --- /dev/null +++ b/thirdparty/boost/date_time/time_resolution_traits.hpp @@ -0,0 +1,140 @@ +#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP +#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include "boost/date_time/time_defs.hpp" +#include "boost/date_time/int_adapter.hpp" +#include "boost/cstdint.hpp" + +namespace boost { +namespace date_time { + + //! Simple function to calculate absolute value of a numeric type + template + // JDG [7/6/02 made a template], + // moved here from time_duration.hpp 2003-Sept-4. + inline T absolute_value(T x) + { + return x < 0 ? -x : x; + } + + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi32_impl { + typedef boost::int32_t int_type; + typedef boost::int32_t impl_type; + static int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted32_impl { + typedef boost::int32_t int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return true;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi64_impl { + typedef boost::int64_t int_type; + typedef boost::int64_t impl_type; + static int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted64_impl { + typedef boost::int64_t int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return true;} + }; + + template + class time_resolution_traits { + public: + typedef typename frac_sec_type::int_type fractional_seconds_type; + typedef typename frac_sec_type::int_type tick_type; + typedef typename frac_sec_type::impl_type impl_type; + typedef v_type day_type; + typedef v_type hour_type; + typedef v_type min_type; + typedef v_type sec_type; + + // bring in function from frac_sec_type traits structs + static typename frac_sec_type::int_type as_number(typename frac_sec_type::impl_type i) + { + return frac_sec_type::as_number(i); + } + static bool is_adapted() + { + return frac_sec_type::is_adapted(); + } + + //Would like this to be frac_sec_type, but some compilers complain + BOOST_STATIC_CONSTANT(int, ticks_per_second = resolution_adjust); + // static const boost::int32_t ticks_per_second = resolution_adjust; + + static time_resolutions resolution() + { + return res; + } + static unsigned short num_fractional_digits() + { + return frac_digits; + } + static fractional_seconds_type res_adjust() + { + return resolution_adjust; + } + //! Any negative argument results in a negative tick_count + static tick_type to_tick_count(hour_type hours, + min_type minutes, + sec_type seconds, + fractional_seconds_type fs) + { + if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0) + { + hours = absolute_value(hours); + minutes = absolute_value(minutes); + seconds = absolute_value(seconds); + fs = absolute_value(fs); + return (((((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs) * -1); + } + + return (((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs; + } + + }; + + typedef time_resolution_traits milli_res; + typedef time_resolution_traits micro_res; + typedef time_resolution_traits nano_res; + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/time_system_counted.hpp b/thirdparty/boost/date_time/time_system_counted.hpp new file mode 100644 index 0000000..41a34c7 --- /dev/null +++ b/thirdparty/boost/date_time/time_system_counted.hpp @@ -0,0 +1,254 @@ +#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP +#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + + +#include "boost/date_time/time_defs.hpp" +#include + + +namespace boost { +namespace date_time { + + //! Time representation that uses a single integer count + template + struct counted_time_rep + { + typedef typename config::int_type int_type; + typedef typename config::date_type date_type; + typedef typename config::impl_type impl_type; + typedef typename date_type::duration_type date_duration_type; + typedef typename date_type::calendar_type calendar_type; + typedef typename date_type::ymd_type ymd_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::resolution_traits resolution_traits; + + counted_time_rep(const date_type& d, const time_duration_type& time_of_day) + : time_count_(1) + { + if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) { + time_count_ = time_of_day.get_rep() + d.day_count(); + //std::cout << time_count_ << std::endl; + } + else { + time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks(); + } + } + explicit counted_time_rep(int_type count) : + time_count_(count) + {} + explicit counted_time_rep(impl_type count) : + time_count_(count) + {} + date_type date() const + { + if(time_count_.is_special()) { + return date_type(time_count_.as_special()); + } + else { + typename calendar_type::date_int_type dc = day_count(); + //std::cout << "time_rep here:" << dc << std::endl; + ymd_type ymd = calendar_type::from_day_number(dc); + return date_type(ymd); + } + } + //int_type day_count() const + unsigned long day_count() const + { + /* resolution_traits::as_number returns a boost::int64_t & + * frac_sec_per_day is also a boost::int64_t so, naturally, + * the division operation returns a boost::int64_t. + * The static_cast to an unsigned long is ok (results in no data loss) + * because frac_sec_per_day is either the number of + * microseconds per day, or the number of nanoseconds per day. + * Worst case scenario: resolution_traits::as_number returns the + * maximum value an int64_t can hold and frac_sec_per_day + * is microseconds per day (lowest possible value). + * The division operation will then return a value of 106751991 - + * easily fitting in an unsigned long. + */ + return static_cast(resolution_traits::as_number(time_count_) / frac_sec_per_day()); + } + int_type time_count() const + { + return resolution_traits::as_number(time_count_); + } + int_type tod() const + { + return resolution_traits::as_number(time_count_) % frac_sec_per_day(); + } + static int_type frac_sec_per_day() + { + int_type seconds_per_day = 60*60*24; + int_type fractional_sec_per_sec(resolution_traits::res_adjust()); + return seconds_per_day*fractional_sec_per_sec; + } + bool is_pos_infinity()const + { + return impl_type::is_pos_inf(time_count_.as_number()); + } + bool is_neg_infinity()const + { + return impl_type::is_neg_inf(time_count_.as_number()); + } + bool is_not_a_date_time()const + { + return impl_type::is_not_a_number(time_count_.as_number()); + } + bool is_special()const + { + return time_count_.is_special(); + } + impl_type get_rep()const + { + return time_count_; + } + private: + impl_type time_count_; + }; + + //! An unadjusted time system implementation. + template + class counted_time_system + { + public: + typedef time_rep time_rep_type; + typedef typename time_rep_type::impl_type impl_type; + typedef typename time_rep_type::time_duration_type time_duration_type; + typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; + typedef typename time_rep_type::date_type date_type; + typedef typename time_rep_type::date_duration_type date_duration_type; + + + template static void unused_var(const T&) {} + + static time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags dst=not_dst) + { + unused_var(dst); + return time_rep_type(day, tod); + } + + static time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static date_type get_date(const time_rep_type& val) + { + return val.date(); + } + static time_duration_type get_time_of_day(const time_rep_type& val) + { + if(val.is_special()) { + return time_duration_type(val.get_rep().as_special()); + } + else{ + return time_duration_type(0,0,0,val.tod()); + } + } + static std::string zone_name(const time_rep_type&) + { + return ""; + } + static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() == rhs.time_count()); + } + static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() < rhs.time_count()); + } + static time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() + dd.get_rep())); + } + else { + return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() - dd.get_rep())); + } + else{ + return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() - td.get_rep())); + } + else { + return time_rep_type(base.time_count() - td.ticks()); + } + } + static time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() + td.get_rep())); + } + else { + return time_rep_type(base.time_count() + td.ticks()); + } + } + static time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + if(lhs.is_special() || rhs.is_special()) { + return(time_duration_type( + impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number()))); + } + else { + fractional_seconds_type fs = lhs.time_count() - rhs.time_count(); + return time_duration_type(0,0,0,fs); + } + } + + }; + + +} } //namespace date_time + + + +#endif + diff --git a/thirdparty/boost/date_time/time_system_split.hpp b/thirdparty/boost/date_time/time_system_split.hpp new file mode 100644 index 0000000..608c7ba --- /dev/null +++ b/thirdparty/boost/date_time/time_system_split.hpp @@ -0,0 +1,213 @@ +#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP +#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/special_defs.hpp" + +namespace boost { +namespace date_time { + + //! An unadjusted time system implementation. +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + template +#else + template +#endif + class split_timedate_system + { + public: + typedef typename config::time_rep_type time_rep_type; + typedef typename config::date_type date_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::date_duration_type date_duration_type; + typedef typename config::int_type int_type; + typedef typename config::resolution_traits resolution_traits; + + //86400 is number of seconds in a day... +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + typedef date_time::wrapping_int wrap_int_type; +#else + private: + BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second); + public: +# if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0X581) ) + typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type; +# else + typedef date_time::wrapping_int wrap_int_type; +#endif +#endif + + static time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags dst=not_dst) + { + if(day.is_special() || tod.is_special()) { + if(day.is_not_a_date() || tod.is_not_a_date_time()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else if(day.is_pos_infinity()) { + if(tod.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(pos_infin)); + } + } + else if(day.is_neg_infinity()) { + if(tod.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(neg_infin)); + } + } + else if(tod.is_pos_infinity()) { + if(day.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(pos_infin), tod); + } + } + else if(tod.is_neg_infinity()) { + if(day.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(neg_infin), tod); + } + } + } + return time_rep_type(day, tod); + } + static date_type get_date(const time_rep_type& val) + { + return date_type(val.day); + } + static time_duration_type get_time_of_day(const time_rep_type& val) + { + return time_duration_type(val.time_of_day); + } + static std::string zone_name(const time_rep_type&) + { + return ""; + } + static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day)); + } + static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + if (lhs.day < rhs.day) return true; + if (lhs.day > rhs.day) return false; + return (lhs.time_of_day < rhs.time_of_day); + } + static time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + return time_rep_type(base.day+dd, base.time_of_day); + } + static time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day); + } + static time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.day.is_special() || td.is_special()) + { + return split_timedate_system::get_time_rep(base.day, -td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return add_time_duration(base,td1); + } + + //std::cout << td.ticks() << std::endl; + wrap_int_type day_offset(base.time_of_day.ticks()); + date_duration_type day_overflow(static_cast(day_offset.subtract(td.ticks()))); +// std::cout << "sub: " << base.time_of_day.ticks() << "|" +// << day_offset.as_int() << "|" +// << day_overflow.days() << std::endl; + return time_rep_type(base.day-day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.day.is_special() || td.is_special()) { + return split_timedate_system::get_time_rep(base.day, td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return subtract_time_duration(base,td1); + } + wrap_int_type day_offset(base.time_of_day.ticks()); + typename date_duration_type::duration_rep_type doff = day_offset.add(td.ticks()); +// std::cout << "day overflow: " << doff << std::endl; +// std::cout << "ticks: " << td.ticks() << std::endl; + date_duration_type day_overflow(doff); +// std::cout << "base: " << to_simple_string(base.day) << std::endl; +// std::cout << "overflow " << day_overflow.days() << std::endl; + return time_rep_type(base.day+day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + date_duration_type dd = lhs.day - rhs.day; + time_duration_type td(dd.days()*24,0,0); //days * 24 hours + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + // return time_rep_type(base.day-dd, base.time_of_day); + } + + }; + +} } //namespace date_time + + +#endif diff --git a/thirdparty/boost/date_time/time_zone_base.hpp b/thirdparty/boost/date_time/time_zone_base.hpp new file mode 100644 index 0000000..801feed --- /dev/null +++ b/thirdparty/boost/date_time/time_zone_base.hpp @@ -0,0 +1,99 @@ +#ifndef _DATE_TIME_TIME_ZONE_BASE__ +#define _DATE_TIME_TIME_ZONE_BASE__ + +/* Copyright (c) 2003-2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +#include +#include + +namespace boost { +namespace date_time { + + + + //! Interface class for dynamic time zones. + /*! This class represents the base interface for all timezone + * representations. Subclasses may provide different systems + * for identifying a particular zone. For example some may + * provide a geographical based zone construction while others + * may specify the offset from GMT. Another possible implementation + * would be to convert from POSIX timezone strings. Regardless of + * the construction technique, this is the interface that these + * time zone types must provide. + * + * Note that this class is intended to be used as a shared + * resource (hence the derivation from boost::counted_base. + */ + template + class time_zone_base { + public: + typedef CharT char_type; + typedef std::basic_string string_type; + typedef std::basic_ostringstream stringstream_type; + typedef typename time_type::date_type::year_type year_type; + typedef typename time_type::time_duration_type time_duration_type; + + time_zone_base() {}; + virtual ~time_zone_base() {}; + //!String for the timezone when in daylight savings (eg: EDT) + virtual string_type dst_zone_abbrev() const=0; + //!String for the zone when not in daylight savings (eg: EST) + virtual string_type std_zone_abbrev() const=0; + //!String for the timezone when in daylight savings (eg: Eastern Daylight Time) + virtual string_type dst_zone_name() const=0; + //!String for the zone when not in daylight savings (eg: Eastern Standard Time) + virtual string_type std_zone_name() const=0; + //! True if zone uses daylight savings adjustments otherwise false + virtual bool has_dst() const=0; + //! Local time that DST starts -- undefined if has_dst is false + virtual time_type dst_local_start_time(year_type y) const=0; + //! Local time that DST ends -- undefined if has_dst is false + virtual time_type dst_local_end_time(year_type y) const=0; + //! Base offset from UTC for zone (eg: -07:30:00) + virtual time_duration_type base_utc_offset() const=0; + //! Adjustment forward or back made while DST is in effect + virtual time_duration_type dst_offset() const=0; + //! Returns a POSIX time_zone string for this object + virtual string_type to_posix_string() const =0; + + private: + + }; + + + //! Structure which holds the time offsets associated with daylight savings time + /*! + *@param time_duration_type A type used to represent the offset + */ + template + class dst_adjustment_offsets + { + public: + dst_adjustment_offsets(const time_duration_type& dst_adjust, + const time_duration_type& dst_start_offset, + const time_duration_type& dst_end_offset) : + dst_adjust_(dst_adjust), + dst_start_offset_(dst_start_offset), + dst_end_offset_(dst_end_offset) + {} + + //! Amount DST adjusts the clock eg: plus one hour + time_duration_type dst_adjust_; + //! Time past midnight on start transition day that dst starts + time_duration_type dst_start_offset_; + //! Time past midnight on end transition day that dst ends + time_duration_type dst_end_offset_; + }; + + +} } //namespace date_time + + + +#endif diff --git a/thirdparty/boost/date_time/time_zone_names.hpp b/thirdparty/boost/date_time/time_zone_names.hpp new file mode 100644 index 0000000..07f83b4 --- /dev/null +++ b/thirdparty/boost/date_time/time_zone_names.hpp @@ -0,0 +1,98 @@ +#ifndef DATE_TIME_TIME_ZONE_NAMES_HPP__ +#define DATE_TIME_TIME_ZONE_NAMES_HPP__ + +/* Copyright (c) 2002-2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include + +namespace boost { +namespace date_time { + + template + struct default_zone_names { + public: + typedef CharT char_type; + static const char_type standard_name[9]; + static const char_type standard_abbrev[11]; + static const char_type non_dst_identifier[7]; + }; + template + const typename default_zone_names::char_type + default_zone_names::standard_name[9] = + {'s','t','d','_','n','a','m','e'}; + + template + const typename default_zone_names::char_type + default_zone_names::standard_abbrev[11] = + {'s','t','d','_','a','b','b','r','e','v'}; + + template + const typename default_zone_names::char_type + default_zone_names::non_dst_identifier[7] = + {'n','o','-','d','s','t'}; + + //! Base type that holds various string names for timezone output. + /*! Class that holds various types of strings used for timezones. + * For example, for the western United States there is the full + * name: Pacific Standard Time and the abbreviated name: PST. + * During daylight savings there are additional names: + * Pacific Daylight Time and PDT. + *@parm CharT Allows class to support different character types + */ + template + class time_zone_names_base + { + public: + typedef std::basic_string string_type; + time_zone_names_base() : + std_zone_name_(default_zone_names::standard_name), + std_zone_abbrev_(default_zone_names::standard_abbrev), + dst_zone_name_(default_zone_names::non_dst_identifier), + dst_zone_abbrev_(default_zone_names::non_dst_identifier) + {} + time_zone_names_base(const string_type& std_zone_name_str, + const string_type& std_zone_abbrev_str, + const string_type& dst_zone_name_str, + const string_type& dst_zone_abbrev_str) : + std_zone_name_(std_zone_name_str), + std_zone_abbrev_(std_zone_abbrev_str), + dst_zone_name_(dst_zone_name_str), + dst_zone_abbrev_(dst_zone_abbrev_str) + {} + string_type dst_zone_abbrev() const + { + return dst_zone_abbrev_; + } + string_type std_zone_abbrev() const + { + return std_zone_abbrev_; + } + string_type dst_zone_name() const + { + return dst_zone_name_; + } + string_type std_zone_name() const + { + return std_zone_name_; + } + private: + string_type std_zone_name_; + string_type std_zone_abbrev_; + string_type dst_zone_name_; + string_type dst_zone_abbrev_; + + }; + + //! Specialization of timezone names for standard char. + //typedef time_zone_names_base time_zone_names; + +} } //namespace + + +#endif diff --git a/thirdparty/boost/date_time/tz_db_base.hpp b/thirdparty/boost/date_time/tz_db_base.hpp new file mode 100644 index 0000000..ae70689 --- /dev/null +++ b/thirdparty/boost/date_time/tz_db_base.hpp @@ -0,0 +1,376 @@ +#ifndef DATE_TIME_TZ_DB_BASE_HPP__ +#define DATE_TIME_TZ_DB_BASE_HPP__ + +/* Copyright (c) 2003-2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +#include "boost/shared_ptr.hpp" +#include "boost/date_time/time_zone_names.hpp" +#include "boost/date_time/time_zone_base.hpp" +#include "boost/date_time/time_parsing.hpp" +#include "boost/tokenizer.hpp" +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace date_time { + + //! Exception thrown when tz database cannot locate requested data file + class data_not_accessible : public std::logic_error + { + public: + data_not_accessible() : + std::logic_error(std::string("Unable to locate or access the required datafile.")) + {} + data_not_accessible(const std::string& filespec) : + std::logic_error(std::string("Unable to locate or access the required datafile. Filespec: " + filespec)) + {} + }; + + //! Exception thrown when tz database locates incorrect field structure in data file + class bad_field_count : public std::out_of_range + { + public: + bad_field_count(const std::string& s) : + std::out_of_range(s) + {} + }; + + //! Creates a database of time_zones from csv datafile + /*! The csv file containing the zone_specs used by the + * tz_db_base is intended to be customized by the + * library user. When customizing this file (or creating your own) the + * file must follow a specific format. + * + * This first line is expected to contain column headings and is therefore + * not processed by the tz_db_base. + * + * Each record (line) must have eleven fields. Some of those fields can + * be empty. Every field (even empty ones) must be enclosed in + * double-quotes. + * Ex: + * @code + * "America/Phoenix" <- string enclosed in quotes + * "" <- empty field + * @endcode + * + * Some fields represent a length of time. The format of these fields + * must be: + * @code + * "{+|-}hh:mm[:ss]" <- length-of-time format + * @endcode + * Where the plus or minus is mandatory and the seconds are optional. + * + * Since some time zones do not use daylight savings it is not always + * necessary for every field in a zone_spec to contain a value. All + * zone_specs must have at least ID and GMT offset. Zones that use + * daylight savings must have all fields filled except: + * STD ABBR, STD NAME, DST NAME. You should take note + * that DST ABBR is mandatory for zones that use daylight savings + * (see field descriptions for further details). + * + * ******* Fields and their description/details ********* + * + * ID: + * Contains the identifying string for the zone_spec. Any string will + * do as long as it's unique. No two ID's can be the same. + * + * STD ABBR: + * STD NAME: + * DST ABBR: + * DST NAME: + * These four are all the names and abbreviations used by the time + * zone being described. While any string will do in these fields, + * care should be taken. These fields hold the strings that will be + * used in the output of many of the local_time classes. + * Ex: + * @code + * time_zone nyc = tz_db.time_zone_from_region("America/New_York"); + * local_time ny_time(date(2004, Aug, 30), IS_DST, nyc); + * cout << ny_time.to_long_string() << endl; + * // 2004-Aug-30 00:00:00 Eastern Daylight Time + * cout << ny_time.to_short_string() << endl; + * // 2004-Aug-30 00:00:00 EDT + * @endcode + * + * NOTE: The exact format/function names may vary - see local_time + * documentation for further details. + * + * GMT offset: + * This is the number of hours added to utc to get the local time + * before any daylight savings adjustments are made. Some examples + * are: America/New_York offset -5 hours, & Africa/Cairo offset +2 hours. + * The format must follow the length-of-time format described above. + * + * DST adjustment: + * The amount of time added to gmt_offset when daylight savings is in + * effect. The format must follow the length-of-time format described + * above. + * + * DST Start Date rule: + * This is a specially formatted string that describes the day of year + * in which the transition take place. It holds three fields of it's own, + * separated by semicolons. + * The first field indicates the "nth" weekday of the month. The possible + * values are: 1 (first), 2 (second), 3 (third), 4 (fourth), 5 (fifth), + * and -1 (last). + * The second field indicates the day-of-week from 0-6 (Sun=0). + * The third field indicates the month from 1-12 (Jan=1). + * + * Examples are: "-1;5;9"="Last Friday of September", + * "2;1;3"="Second Monday of March" + * + * Start time: + * Start time is the number of hours past midnight, on the day of the + * start transition, the transition takes place. More simply put, the + * time of day the transition is made (in 24 hours format). The format + * must follow the length-of-time format described above with the + * exception that it must always be positive. + * + * DST End date rule: + * See DST Start date rule. The difference here is this is the day + * daylight savings ends (transition to STD). + * + * End time: + * Same as Start time. + */ + template + class tz_db_base { + public: + /* Having CharT as a template parameter created problems + * with posix_time::duration_from_string. Templatizing + * duration_from_string was not possible at this time, however, + * it should be possible in the future (when poor compilers get + * fixed or stop being used). + * Since this class was designed to use CharT as a parameter it + * is simply typedef'd here to ease converting in back to a + * parameter the future */ + typedef char char_type; + + typedef typename time_zone_type::base_type time_zone_base_type; + typedef typename time_zone_type::time_duration_type time_duration_type; + typedef time_zone_names_base time_zone_names; + typedef dst_adjustment_offsets dst_adjustment_offsets; + typedef std::basic_string string_type; + + //! Constructs an empty database + tz_db_base() {} + + //! Process csv data file, may throw exceptions + /*! May throw data_not_accessible, or bad_field_count exceptions */ + void load_from_file(const std::string& pathspec) + { + string_type in_str; + std::string buff; + + std::ifstream ifs(pathspec.c_str()); + if(!ifs){ + throw data_not_accessible(pathspec); + } + std::getline(ifs, buff); // first line is column headings + + while( std::getline(ifs, buff)) { + parse_string(buff); + } + } + + //! returns true if record successfully added to map + /*! Takes an id string in the form of "America/Phoenix", and a + * time_zone object for that region. The id string must be a unique + * name that does not already exist in the database. */ + bool add_record(const string_type& id, + boost::shared_ptr tz) + { + typename map_type::value_type p(id, tz); + return (m_zone_map.insert(p)).second; + } + + //! Returns a time_zone object built from the specs for the given region + /*! Returns a time_zone object built from the specs for the given + * region. If region does not exist a local_time::record_not_found + * exception will be thrown */ + boost::shared_ptr + time_zone_from_region(const string_type& region) const + { + // get the record + typename map_type::const_iterator record = m_zone_map.find(region); + if(record == m_zone_map.end()){ + return boost::shared_ptr(); //null pointer + } + return record->second; + } + + //! Returns a vector of strings holding the time zone regions in the database + std::vector region_list() const + { + typedef std::vector vector_type; + vector_type regions; + typename map_type::const_iterator itr = m_zone_map.begin(); + while(itr != m_zone_map.end()) { + regions.push_back(itr->first); + ++itr; + } + return regions; + } + + private: + typedef std::map > map_type; + map_type m_zone_map; + + // start and end rule are of the same type + typedef typename rule_type::start_rule::week_num week_num; + + /* TODO: mechanisms need to be put in place to handle different + * types of rule specs. parse_rules() only handles nth_kday + * rule types. */ + + //! parses rule specs for transition day rules + rule_type* parse_rules(const string_type& sr, const string_type& er) const + { + using namespace gregorian; + // start and end rule are of the same type, + // both are included here for readability + typedef typename rule_type::start_rule start_rule; + typedef typename rule_type::end_rule end_rule; + + // these are: [start|end] nth, day, month + int s_nth = 0, s_d = 0, s_m = 0; + int e_nth = 0, e_d = 0, e_m = 0; + split_rule_spec(s_nth, s_d, s_m, sr); + split_rule_spec(e_nth, e_d, e_m, er); + + typename start_rule::week_num s_wn, e_wn; + s_wn = get_week_num(s_nth); + e_wn = get_week_num(e_nth); + + + return new rule_type(start_rule(s_wn, s_d, s_m), + end_rule(e_wn, e_d, e_m)); + } + //! helper function for parse_rules() + week_num get_week_num(int nth) const + { + typedef typename rule_type::start_rule start_rule; + switch(nth){ + case 1: + return start_rule::first; + case 2: + return start_rule::second; + case 3: + return start_rule::third; + case 4: + return start_rule::fourth; + case 5: + case -1: + return start_rule::fifth; + default: + // shouldn't get here - add error handling later + break; + } + return start_rule::fifth; // silence warnings + } + + //! splits the [start|end]_date_rule string into 3 ints + void split_rule_spec(int& nth, int& d, int& m, string_type rule) const + { + typedef boost::char_separator > char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + + const char_type sep_char[] = { ';', '\0'}; + char_separator_type sep(sep_char); + tokenizer tokens(rule, sep); // 3 fields + + tokenizer_iterator tok_iter = tokens.begin(); + nth = std::atoi(tok_iter->c_str()); ++tok_iter; + d = std::atoi(tok_iter->c_str()); ++tok_iter; + m = std::atoi(tok_iter->c_str()); + } + + + //! Take a line from the csv, turn it into a time_zone_type. + /*! Take a line from the csv, turn it into a time_zone_type, + * and add it to the map. Zone_specs in csv file are expected to + * have eleven fields that describe the time zone. Returns true if + * zone_spec successfully added to database */ + bool parse_string(string_type& s) + { + + std::vector result; + typedef boost::token_iterator_generator, string_type::const_iterator, string_type >::type token_iter_type; + + token_iter_type i = boost::make_token_iterator(s.begin(), s.end(),boost::escaped_list_separator()); + + token_iter_type end; + while (i != end) { + result.push_back(*i); + i++; + } + + enum db_fields { ID, STDABBR, STDNAME, DSTABBR, DSTNAME, GMTOFFSET, + DSTADJUST, START_DATE_RULE, START_TIME, END_DATE_RULE, + END_TIME, FIELD_COUNT }; + + //take a shot at fixing gcc 4.x error + const unsigned int expected_fields = static_cast(FIELD_COUNT); + if (result.size() != expected_fields) { + std::stringstream msg; + msg << "Expecting " << FIELD_COUNT << " fields, got " + << result.size() << " fields in line: " << s; + throw bad_field_count(msg.str()); + } + + // initializations + bool has_dst = true; + if(result[DSTABBR] == std::string()){ + has_dst = false; + } + + + // start building components of a time_zone + time_zone_names names(result[STDNAME], result[STDABBR], + result[DSTNAME], result[DSTABBR]); + + time_duration_type utc_offset = + str_from_delimited_time_duration(result[GMTOFFSET]); + + dst_adjustment_offsets adjust(time_duration_type(0,0,0), + time_duration_type(0,0,0), + time_duration_type(0,0,0)); + + boost::shared_ptr rules; + + if(has_dst){ + adjust = dst_adjustment_offsets( + str_from_delimited_time_duration(result[DSTADJUST]), + str_from_delimited_time_duration(result[START_TIME]), + str_from_delimited_time_duration(result[END_TIME]) + ); + + rules = + boost::shared_ptr(parse_rules(result[START_DATE_RULE], + result[END_DATE_RULE])); + } + string_type id(result[ID]); + boost::shared_ptr zone(new time_zone_type(names, utc_offset, adjust, rules)); + return (add_record(id, zone)); + + } + + }; + +} } // namespace + +#endif // DATE_TIME_TZ_DB_BASE_HPP__ diff --git a/thirdparty/boost/date_time/wrapping_int.hpp b/thirdparty/boost/date_time/wrapping_int.hpp new file mode 100644 index 0000000..11be318 --- /dev/null +++ b/thirdparty/boost/date_time/wrapping_int.hpp @@ -0,0 +1,163 @@ +#ifndef _DATE_TIME_WRAPPING_INT_HPP__ +#define _DATE_TIME_WRAPPING_INT_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + + +namespace boost { +namespace date_time { + +//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type) +/*! In composite date and time types this type is used to + * wrap at the day boundary. + * Ex: + * A wrapping_int will roll over after nine, and + * roll under below zero. This gives a range of [0,9] + * + * NOTE: it is strongly recommended that wrapping_int2 be used + * instead of wrapping_int as wrapping_int is to be depricated + * at some point soon. + * + * Also Note that warnings will occur if instantiated with an + * unsigned type. Only a signed type should be used! + */ +template +class wrapping_int { +public: + typedef int_type_ int_type; + //typedef overflow_type_ overflow_type; + static int_type wrap_value() {return wrap_val;} + //!Add, return true if wrapped + wrapping_int(int_type v) : value_(v) {}; + //! Explicit converion method + int_type as_int() const {return value_;} + operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + int_type add(int_type v) + { + int_type remainder = static_cast(v % (wrap_val)); + int_type overflow = static_cast(v / (wrap_val)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went (positive indicates wrap under, negative indicates wrap over). + * Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a negative return value. If + * wrapping under took place, a positive value would be returned. */ + int_type subtract(int_type v) + { + int_type remainder = static_cast(v % (wrap_val)); + int_type underflow = static_cast(-(v / (wrap_val))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow) * -1; + } +private: + int_type value_; + + int_type calculate_wrap(int_type wrap) + { + if ((value_) >= wrap_val) + { + wrap++; + value_ -= (wrap_val); + } + else if(value_ < 0) + { + wrap--; + value_ += (wrap_val); + } + return wrap; + } + +}; + + +//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type) +/*! Bad name, quick impl to fix a bug -- fix later!! + * This allows the wrap to restart at a value other than 0. + */ +template +class wrapping_int2 { +public: + typedef int_type_ int_type; + static int_type wrap_value() {return wrap_max;} + static int_type min_value() {return wrap_min;} + /*! If initializing value is out of range of [wrap_min, wrap_max], + * value will be initialized to closest of min or max */ + wrapping_int2(int_type v) : value_(v) { + if(value_ < wrap_min) + { + value_ = wrap_min; + } + if(value_ > wrap_max) + { + value_ = wrap_max; + } + } + //! Explicit converion method + int_type as_int() const {return value_;} + operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + int_type add(int_type v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + int_type overflow = static_cast(v / (wrap_max - wrap_min + 1)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a positive return value. If + * wrapping under took place, a negative value would be returned */ + int_type subtract(int_type v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + int_type underflow = static_cast(-(v / (wrap_max - wrap_min + 1))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow); + } + +private: + int_type value_; + + int_type calculate_wrap(int_type wrap) + { + if ((value_) > wrap_max) + { + wrap++; + value_ -= (wrap_max - wrap_min + 1); + } + else if((value_) < wrap_min) + { + wrap--; + value_ += (wrap_max - wrap_min + 1); + } + return wrap; + } +}; + + + +} } //namespace date_time + + + +#endif + diff --git a/thirdparty/boost/date_time/year_month_day.hpp b/thirdparty/boost/date_time/year_month_day.hpp new file mode 100644 index 0000000..00cdbd4 --- /dev/null +++ b/thirdparty/boost/date_time/year_month_day.hpp @@ -0,0 +1,45 @@ +#ifndef YearMonthDayBase_HPP__ +#define YearMonthDayBase_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + */ + +namespace boost { +namespace date_time { + + //! Allow rapid creation of ymd triples of different types + template + struct year_month_day_base { + year_month_day_base(YearType year, + MonthType month, + DayType day); + YearType year; + MonthType month; + DayType day; + typedef YearType year_type; + typedef MonthType month_type; + typedef DayType day_type; + }; + + + //! A basic constructor + template + inline + year_month_day_base::year_month_day_base(YearType y, + MonthType m, + DayType d) : + year(y), + month(m), + day(d) + {} + +} }//namespace date_time + + +#endif + diff --git a/thirdparty/boost/detail/algorithm.hpp b/thirdparty/boost/detail/algorithm.hpp new file mode 100644 index 0000000..6f8fcda --- /dev/null +++ b/thirdparty/boost/detail/algorithm.hpp @@ -0,0 +1,222 @@ +// (C) Copyright Jeremy Siek 2001. +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef BOOST_ALGORITHM_HPP +# define BOOST_ALGORITHM_HPP +# include +// Algorithms on sequences +// +// The functions in this file have not yet gone through formal +// review, and are subject to change. This is a work in progress. +// They have been checked into the detail directory because +// there are some graph algorithms that use these functions. + +#include +#include + +namespace boost { + + template + Iter1 begin(const std::pair& p) { return p.first; } + + template + Iter2 end(const std::pair& p) { return p.second; } + + template + typename boost::detail::iterator_traits::difference_type + size(const std::pair& p) { + return std::distance(p.first, p.second); + } + +#if 0 + // These seem to interfere with the std::pair overloads :( + template + typename Container::iterator + begin(Container& c) { return c.begin(); } + + template + typename Container::const_iterator + begin(const Container& c) { return c.begin(); } + + template + typename Container::iterator + end(Container& c) { return c.end(); } + + template + typename Container::const_iterator + end(const Container& c) { return c.end(); } + + template + typename Container::size_type + size(const Container& c) { return c.size(); } +#else + template + typename std::vector::iterator + begin(std::vector& c) { return c.begin(); } + + template + typename std::vector::const_iterator + begin(const std::vector& c) { return c.begin(); } + + template + typename std::vector::iterator + end(std::vector& c) { return c.end(); } + + template + typename std::vector::const_iterator + end(const std::vector& c) { return c.end(); } + + template + typename std::vector::size_type + size(const std::vector& c) { return c.size(); } +#endif + + template + void iota(ForwardIterator first, ForwardIterator last, T value) + { + for (; first != last; ++first, ++value) + *first = value; + } + template + void iota(Container& c, const T& value) + { + iota(begin(c), end(c), value); + } + + // Also do version with 2nd container? + template + OutIter copy(const Container& c, OutIter result) { + return std::copy(begin(c), end(c), result); + } + + template + bool equal(const Container1& c1, const Container2& c2) + { + if (size(c1) != size(c2)) + return false; + return std::equal(begin(c1), end(c1), begin(c2)); + } + + template + void sort(Container& c) { std::sort(begin(c), end(c)); } + + template + void sort(Container& c, const Predicate& p) { + std::sort(begin(c), end(c), p); + } + + template + void stable_sort(Container& c) { std::stable_sort(begin(c), end(c)); } + + template + void stable_sort(Container& c, const Predicate& p) { + std::stable_sort(begin(c), end(c), p); + } + + template + bool any_if(InputIterator first, InputIterator last, Predicate p) + { + return std::find_if(first, last, p) != last; + } + template + bool any_if(const Container& c, Predicate p) + { + return any_if(begin(c), end(c), p); + } + + template + bool container_contains(InputIterator first, InputIterator last, T value) + { + return std::find(first, last, value) != last; + } + template + bool container_contains(const Container& c, const T& value) + { + return container_contains(begin(c), end(c), value); + } + + template + std::size_t count(const Container& c, const T& value) + { + return std::count(begin(c), end(c), value); + } + + template + std::size_t count_if(const Container& c, Predicate p) + { + return std::count_if(begin(c), end(c), p); + } + + template + bool is_sorted(ForwardIterator first, ForwardIterator last) + { + if (first == last) + return true; + + ForwardIterator next = first; + for (++next; next != last; first = next, ++next) { + if (*next < *first) + return false; + } + + return true; + } + + template + bool is_sorted(ForwardIterator first, ForwardIterator last, + StrictWeakOrdering comp) + { + if (first == last) + return true; + + ForwardIterator next = first; + for (++next; next != last; first = next, ++next) { + if (comp(*next, *first)) + return false; + } + + return true; + } + + template + bool is_sorted(const Container& c) + { + return is_sorted(begin(c), end(c)); + } + + template + bool is_sorted(const Container& c, StrictWeakOrdering comp) + { + return is_sorted(begin(c), end(c), comp); + } + +} // namespace boost + +#endif // BOOST_ALGORITHM_HPP diff --git a/thirdparty/boost/detail/allocator_utilities.hpp b/thirdparty/boost/detail/allocator_utilities.hpp new file mode 100644 index 0000000..91c44e9 --- /dev/null +++ b/thirdparty/boost/detail/allocator_utilities.hpp @@ -0,0 +1,193 @@ +/* Copyright 2003-2007 Joaquín M López Muñoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See Boost website at http://www.boost.org/ + */ + +#ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP +#define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace detail{ + +/* Allocator adaption layer. Some stdlibs provide allocators without rebind + * and template ctors. These facilities are simulated with the external + * template class rebind_to and the aid of partial_std_allocator_wrapper. + */ + +namespace allocator{ + +/* partial_std_allocator_wrapper inherits the functionality of a std + * allocator while providing a templatized ctor and other bits missing + * in some stdlib implementation or another. + */ + +template +class partial_std_allocator_wrapper:public std::allocator +{ +public: + /* Oddly enough, STLport does not define std::allocator::value_type + * when configured to work without partial template specialization. + * No harm in supplying the definition here unconditionally. + */ + + typedef Type value_type; + + partial_std_allocator_wrapper(){}; + + template + partial_std_allocator_wrapper(const partial_std_allocator_wrapper&){} + + partial_std_allocator_wrapper(const std::allocator& x): + std::allocator(x) + { + }; + +#if defined(BOOST_DINKUMWARE_STDLIB) + /* Dinkumware guys didn't provide a means to call allocate() without + * supplying a hint, in disagreement with the standard. + */ + + Type* allocate(std::size_t n,const void* hint=0) + { + std::allocator& a=*this; + return a.allocate(n,hint); + } +#endif + +}; + +/* Detects whether a given allocator belongs to a defective stdlib not + * having the required member templates. + * Note that it does not suffice to check the Boost.Config stdlib + * macros, as the user might have passed a custom, compliant allocator. + * The checks also considers partial_std_allocator_wrapper to be + * a standard defective allocator. + */ + +#if defined(BOOST_NO_STD_ALLOCATOR)&&\ + (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB)) + +template +struct is_partial_std_allocator +{ + BOOST_STATIC_CONSTANT(bool, + value= + (is_same< + std::allocator, + Allocator + >::value)|| + (is_same< + partial_std_allocator_wrapper< + BOOST_DEDUCED_TYPENAME Allocator::value_type>, + Allocator + >::value)); +}; + +#else + +template +struct is_partial_std_allocator +{ + BOOST_STATIC_CONSTANT(bool,value=false); +}; + +#endif + +/* rebind operations for defective std allocators */ + +template +struct partial_std_allocator_rebind_to +{ + typedef partial_std_allocator_wrapper type; +}; + +/* rebind operation in all other cases */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +/* Workaround for a problem in MSVC with dependent template typedefs + * when doing rebinding of allocators. + * Modeled after (thanks, Aleksey!) + */ + +template +struct rebinder +{ + template struct fake_allocator:Allocator{}; + template<> struct fake_allocator + { + template struct rebind{}; + }; + + template + struct result: + fake_allocator::value>:: + template rebind + { + }; +}; +#else +template +struct rebinder +{ + template + struct result + { + typedef typename Allocator::BOOST_NESTED_TEMPLATE + rebind::other other; + }; +}; +#endif + +template +struct compliant_allocator_rebind_to +{ + typedef typename rebinder:: + BOOST_NESTED_TEMPLATE result::other type; +}; + +/* rebind front-end */ + +template +struct rebind_to: + mpl::eval_if_c< + is_partial_std_allocator::value, + partial_std_allocator_rebind_to, + compliant_allocator_rebind_to + > +{ +}; + +/* allocator-independent versions of construct and destroy */ + +template +void construct(void* p,const Type& t) +{ + new (p) Type(t); +} + +template +void destroy(const Type* p) +{ + p->~Type(); +} + +} /* namespace boost::detail::allocator */ + +} /* namespace boost::detail */ + +} /* namespace boost */ + +#endif diff --git a/thirdparty/boost/detail/atomic_count.hpp b/thirdparty/boost/detail/atomic_count.hpp new file mode 100644 index 0000000..aa8527d --- /dev/null +++ b/thirdparty/boost/detail/atomic_count.hpp @@ -0,0 +1,124 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/atomic_count.hpp - thread/SMP safe reference counter +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// typedef boost::detail::atomic_count; +// +// atomic_count a(n); +// +// (n is convertible to long) +// +// Effects: Constructs an atomic_count with an initial value of n +// +// a; +// +// Returns: (long) the current value of a +// +// ++a; +// +// Effects: Atomically increments the value of a +// Returns: nothing +// +// --a; +// +// Effects: Atomically decrements the value of a +// Returns: (long) zero if the new value of a is zero, +// unspecified non-zero value otherwise (usually the new value) +// +// Important note: when --a returns zero, it must act as a +// read memory barrier (RMB); i.e. the calling thread must +// have a synchronized view of the memory +// +// On Intel IA-32 (x86) memory is always synchronized, so this +// is not a problem. +// +// On many architectures the atomic instructions already act as +// a memory barrier. +// +// This property is necessary for proper reference counting, since +// a thread can update the contents of a shared object, then +// release its reference, and another thread may immediately +// release the last reference causing object destruction. +// +// The destructor needs to have a synchronized view of the +// object to perform proper cleanup. +// +// Original example by Alexander Terekhov: +// +// Given: +// +// - a mutable shared object OBJ; +// - two threads THREAD1 and THREAD2 each holding +// a private smart_ptr object pointing to that OBJ. +// +// t1: THREAD1 updates OBJ (thread-safe via some synchronization) +// and a few cycles later (after "unlock") destroys smart_ptr; +// +// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization +// with respect to shared mutable object OBJ; OBJ destructors +// are called driven by smart_ptr interface... +// + +#include + +#ifndef BOOST_HAS_THREADS + +namespace boost +{ + +namespace detail +{ + +typedef long atomic_count; + +} + +} + +#elif defined(BOOST_AC_USE_PTHREADS) + +# include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + +# include + +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + +# include + +#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +# include + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) + +# include + +#elif defined(BOOST_HAS_PTHREADS) + +# define BOOST_AC_USE_PTHREADS +# include + +#else + +// Use #define BOOST_DISABLE_THREADS to avoid the error +#error Unrecognized threading platform + +#endif + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_gcc.hpp b/thirdparty/boost/detail/atomic_count_gcc.hpp new file mode 100644 index 0000000..ea1f6a4 --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_gcc.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED + +// +// boost/detail/atomic_count_gcc.hpp +// +// atomic_count for GNU libstdc++ v3 +// +// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2002 Lars Gullik Bjønnes +// Copyright 2003-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +#if defined(__GLIBCXX__) // g++ 3.4+ + +using __gnu_cxx::__atomic_add; +using __gnu_cxx::__exchange_and_add; + +#endif + +class atomic_count +{ +public: + + explicit atomic_count(long v) : value_(v) {} + + void operator++() + { + __atomic_add(&value_, 1); + } + + long operator--() + { + return __exchange_and_add(&value_, -1) - 1; + } + + operator long() const + { + return __exchange_and_add(&value_, 0); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable _Atomic_word value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_gcc_x86.hpp b/thirdparty/boost/detail/atomic_count_gcc_x86.hpp new file mode 100644 index 0000000..077a904 --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_gcc_x86.hpp @@ -0,0 +1,84 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED + +// +// boost/detail/atomic_count_gcc_x86.hpp +// +// atomic_count for g++ on 486+/AMD64 +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} + + void operator++() + { + __asm__ + ( + "lock\n\t" + "incl %0": + "+m"( value_ ): // output (%0) + : // inputs + "cc" // clobbers + ); + } + + long operator--() + { + return atomic_exchange_and_add( &value_, -1 ) - 1; + } + + operator long() const + { + return atomic_exchange_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable int value_; + +private: + + static int atomic_exchange_and_add( int * pw, int dv ) + { + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "+m"( *pw ), "=r"( r ): // outputs (%0, %1) + "1"( dv ): // inputs (%2 == %1) + "memory", "cc" // clobbers + ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_pthreads.hpp b/thirdparty/boost/detail/atomic_count_pthreads.hpp new file mode 100644 index 0000000..f3eb54d --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_pthreads.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED + +// +// boost/detail/atomic_count_pthreads.hpp +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +// +// The generic pthread_mutex-based implementation sometimes leads to +// inefficiencies. Example: a class with two atomic_count members +// can get away with a single mutex. +// +// Users can detect this situation by checking BOOST_AC_USE_PTHREADS. +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +private: + + class scoped_lock + { + public: + + scoped_lock(pthread_mutex_t & m): m_(m) + { + pthread_mutex_lock(&m_); + } + + ~scoped_lock() + { + pthread_mutex_unlock(&m_); + } + + private: + + pthread_mutex_t & m_; + }; + +public: + + explicit atomic_count(long v): value_(v) + { + pthread_mutex_init(&mutex_, 0); + } + + ~atomic_count() + { + pthread_mutex_destroy(&mutex_); + } + + void operator++() + { + scoped_lock lock(mutex_); + ++value_; + } + + long operator--() + { + scoped_lock lock(mutex_); + return --value_; + } + + operator long() const + { + scoped_lock lock(mutex_); + return value_; + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable pthread_mutex_t mutex_; + long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_solaris.hpp b/thirdparty/boost/detail/atomic_count_solaris.hpp new file mode 100644 index 0000000..99571d6 --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_solaris.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED + +// +// boost/detail/atomic_count_solaris.hpp +// based on: boost/detail/atomic_count_win32.hpp +// +// Copyright (c) 2001-2005 Peter Dimov +// Copyright (c) 2006 Michael van der Westhuizen +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( uint32_t v ): value_( v ) + { + } + + long operator++() + { + return atomic_inc_32_nv( &value_ ); + } + + long operator--() + { + return atomic_dec_32_nv( &value_ ); + } + + operator uint32_t() const + { + return static_cast( value_ ); + } + +private: + + atomic_count( atomic_count const & ); + atomic_count & operator=( atomic_count const & ); + + uint32_t value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_sync.hpp b/thirdparty/boost/detail/atomic_count_sync.hpp new file mode 100644 index 0000000..ed6ef40 --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_sync.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED + +// +// boost/detail/atomic_count_sync.hpp +// +// atomic_count for g++ 4.1+ +// +// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( v ) {} + + void operator++() + { + __sync_add_and_fetch( &value_, 1 ); + } + + long operator--() + { + return __sync_add_and_fetch( &value_, -1 ); + } + + operator long() const + { + return __sync_fetch_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/atomic_count_win32.hpp b/thirdparty/boost/detail/atomic_count_win32.hpp new file mode 100644 index 0000000..a9ac550 --- /dev/null +++ b/thirdparty/boost/detail/atomic_count_win32.hpp @@ -0,0 +1,63 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/atomic_count_win32.hpp +// +// Copyright (c) 2001-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ): value_( v ) + { + } + + long operator++() + { + return BOOST_INTERLOCKED_INCREMENT( &value_ ); + } + + long operator--() + { + return BOOST_INTERLOCKED_DECREMENT( &value_ ); + } + + operator long() const + { + return static_cast( value_ ); + } + +private: + + atomic_count( atomic_count const & ); + atomic_count & operator=( atomic_count const & ); + + long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED diff --git a/thirdparty/boost/detail/bad_weak_ptr.hpp b/thirdparty/boost/detail/bad_weak_ptr.hpp new file mode 100644 index 0000000..3bbca2b --- /dev/null +++ b/thirdparty/boost/detail/bad_weak_ptr.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED +#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/bad_weak_ptr.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#ifdef __BORLANDC__ +# pragma warn -8026 // Functions with excep. spec. are not expanded inline +#endif + +namespace boost +{ + +// The standard library that comes with Borland C++ 5.5.1, 5.6.4 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option push -pc +#endif + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "tr1::bad_weak_ptr"; + } +}; + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option pop +#endif + +} // namespace boost + +#ifdef __BORLANDC__ +# pragma warn .8026 // Functions with excep. spec. are not expanded inline +#endif + +#endif // #ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/detail/binary_search.hpp b/thirdparty/boost/detail/binary_search.hpp new file mode 100644 index 0000000..8242b70 --- /dev/null +++ b/thirdparty/boost/detail/binary_search.hpp @@ -0,0 +1,216 @@ +// Copyright (c) 2000 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) +// +// Copyright (c) 1994 +// Hewlett-Packard Company +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Hewlett-Packard Company makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +// Copyright (c) 1996 +// Silicon Graphics Computer Systems, Inc. +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Silicon Graphics makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +#ifndef BINARY_SEARCH_DWA_122600_H_ +# define BINARY_SEARCH_DWA_122600_H_ + +# include +# include + +namespace boost { namespace detail { + +template +ForwardIter lower_bound(ForwardIter first, ForwardIter last, + const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (*middle < val) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template +ForwardIter lower_bound(ForwardIter first, ForwardIter last, + const Tp& val, Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(*middle, val)) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template +ForwardIter upper_bound(ForwardIter first, ForwardIter last, + const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (val < *middle) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template +ForwardIter upper_bound(ForwardIter first, ForwardIter last, + const Tp& val, Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(val, *middle)) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template +std::pair +equal_range(ForwardIter first, ForwardIter last, const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (*middle < val) { + first = middle; + ++first; + len = len - half - 1; + } + else if (val < *middle) + len = half; + else { + left = boost::detail::lower_bound(first, middle, val); + std::advance(first, len); + right = boost::detail::upper_bound(++middle, first, val); + return std::pair(left, right); + } + } + return std::pair(first, first); +} + +template +std::pair +equal_range(ForwardIter first, ForwardIter last, const Tp& val, + Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(*middle, val)) { + first = middle; + ++first; + len = len - half - 1; + } + else if (comp(val, *middle)) + len = half; + else { + left = boost::detail::lower_bound(first, middle, val, comp); + std::advance(first, len); + right = boost::detail::upper_bound(++middle, first, val, comp); + return std::pair(left, right); + } + } + return std::pair(first, first); +} + +template +bool binary_search(ForwardIter first, ForwardIter last, + const Tp& val) { + ForwardIter i = boost::detail::lower_bound(first, last, val); + return i != last && !(val < *i); +} + +template +bool binary_search(ForwardIter first, ForwardIter last, + const Tp& val, + Compare comp) { + ForwardIter i = boost::detail::lower_bound(first, last, val, comp); + return i != last && !comp(val, *i); +} + +}} // namespace boost::detail + +#endif // BINARY_SEARCH_DWA_122600_H_ diff --git a/thirdparty/boost/detail/call_traits.hpp b/thirdparty/boost/detail/call_traits.hpp new file mode 100644 index 0000000..cd7dd10 --- /dev/null +++ b/thirdparty/boost/detail/call_traits.hpp @@ -0,0 +1,164 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// call_traits: defines typedefs for function usage +// (see libs/utility/call_traits.htm) + +/* Release notes: + 23rd July 2000: + Fixed array specialization. (JM) + Added Borland specific fixes for reference types + (issue raised by Steve Cleary). +*/ + +#ifndef BOOST_DETAIL_CALL_TRAITS_HPP +#define BOOST_DETAIL_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif +#include + +#include +#include +#include + +namespace boost{ + +namespace detail{ + +template +struct ct_imp2 +{ + typedef const T& param_type; +}; + +template +struct ct_imp2 +{ + typedef const T param_type; +}; + +template +struct ct_imp +{ + typedef const T& param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef const T param_type; +}; + +} + +template +struct call_traits +{ +public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + // + // C++ Builder workaround: we should be able to define a compile time + // constant and pass that as a single template parameter to ct_imp, + // however compiler bugs prevent this - instead pass three bool's to + // ct_imp and add an extra partial specialisation + // of ct_imp to handle the logic. (JM) + typedef typename boost::detail::ct_imp< + T, + ::boost::is_pointer::value, + ::boost::is_arithmetic::value + >::param_type param_type; +}; + +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 ) ) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +template +struct call_traits< T * > +{ + typedef T * value_type; + typedef T * & reference; + typedef T * const & const_reference; + typedef T * const param_type; // hh removed const +}; +#endif +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template +struct call_traits +{ +private: + typedef T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; + +template +struct call_traits +{ +private: + typedef const T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; +#endif + +} + +#endif // BOOST_DETAIL_CALL_TRAITS_HPP diff --git a/thirdparty/boost/detail/catch_exceptions.hpp b/thirdparty/boost/detail/catch_exceptions.hpp new file mode 100644 index 0000000..f06a117 --- /dev/null +++ b/thirdparty/boost/detail/catch_exceptions.hpp @@ -0,0 +1,146 @@ +// boost/catch_exceptions.hpp -----------------------------------------------// + +// Copyright Beman Dawes 1995-2001. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/test for documentation. + +// Revision History +// 13 Jun 01 report_exception() made inline. (John Maddock, Jesse Jones) +// 26 Feb 01 Numerous changes suggested during formal review. (Beman) +// 25 Jan 01 catch_exceptions.hpp code factored out of cpp_main.cpp. +// 22 Jan 01 Remove test_tools dependencies to reduce coupling. +// 5 Nov 00 Initial boost version (Beman Dawes) + +#ifndef BOOST_CATCH_EXCEPTIONS_HPP +#define BOOST_CATCH_EXCEPTIONS_HPP + +// header dependencies are deliberately restricted to the standard library +// to reduce coupling to other boost libraries. +#include // for string +#include // for bad_alloc +#include // for bad_cast, bad_typeid +#include // for exception, bad_exception +#include // for std exception hierarchy +#include // for exit codes +# if __GNUC__ != 2 || __GNUC_MINOR__ > 96 +# include // for ostream +# else +# include // workaround GNU missing ostream header +# endif + +# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x0551) +# define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT +# endif + +#if defined(MPW_CPLUS) && (MPW_CPLUS <= 0x890) +# define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT + namespace std { class bad_typeid { }; } +# endif + +namespace boost +{ + + namespace detail + { + // A separate reporting function was requested during formal review. + inline void report_exception( std::ostream & os, + const char * name, const char * info ) + { os << "\n** uncaught exception: " << name << " " << info << std::endl; } + } + + // catch_exceptions ------------------------------------------------------// + + template< class Generator > // Generator is function object returning int + int catch_exceptions( Generator function_object, + std::ostream & out, std::ostream & err ) + { + int result = 0; // quiet compiler warnings + bool exception_thrown = true; // avoid setting result for each excptn type + +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + result = function_object(); + exception_thrown = false; +#ifndef BOOST_NO_EXCEPTIONS + } + + // As a result of hard experience with strangely interleaved output + // under some compilers, there is a lot of use of endl in the code below + // where a simple '\n' might appear to do. + + // The rules for catch & arguments are a bit different from function + // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't + // required, but it doesn't hurt and some programmers ask for it. + + catch ( const char * ex ) + { detail::report_exception( out, "", ex ); } + catch ( const std::string & ex ) + { detail::report_exception( out, "", ex.c_str() ); } + + // std:: exceptions + catch ( const std::bad_alloc & ex ) + { detail::report_exception( out, "std::bad_alloc:", ex.what() ); } + +# ifndef BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT + catch ( const std::bad_cast & ex ) + { detail::report_exception( out, "std::bad_cast:", ex.what() ); } + catch ( const std::bad_typeid & ex ) + { detail::report_exception( out, "std::bad_typeid:", ex.what() ); } +# else + catch ( const std::bad_cast & ) + { detail::report_exception( out, "std::bad_cast", "" ); } + catch ( const std::bad_typeid & ) + { detail::report_exception( out, "std::bad_typeid", "" ); } +# endif + + catch ( const std::bad_exception & ex ) + { detail::report_exception( out, "std::bad_exception:", ex.what() ); } + catch ( const std::domain_error & ex ) + { detail::report_exception( out, "std::domain_error:", ex.what() ); } + catch ( const std::invalid_argument & ex ) + { detail::report_exception( out, "std::invalid_argument:", ex.what() ); } + catch ( const std::length_error & ex ) + { detail::report_exception( out, "std::length_error:", ex.what() ); } + catch ( const std::out_of_range & ex ) + { detail::report_exception( out, "std::out_of_range:", ex.what() ); } + catch ( const std::range_error & ex ) + { detail::report_exception( out, "std::range_error:", ex.what() ); } + catch ( const std::overflow_error & ex ) + { detail::report_exception( out, "std::overflow_error:", ex.what() ); } + catch ( const std::underflow_error & ex ) + { detail::report_exception( out, "std::underflow_error:", ex.what() ); } + catch ( const std::logic_error & ex ) + { detail::report_exception( out, "std::logic_error:", ex.what() ); } + catch ( const std::runtime_error & ex ) + { detail::report_exception( out, "std::runtime_error:", ex.what() ); } + catch ( const std::exception & ex ) + { detail::report_exception( out, "std::exception:", ex.what() ); } + + catch ( ... ) + { detail::report_exception( out, "unknown exception", "" ); } +#endif // BOOST_NO_EXCEPTIONS + + if ( exception_thrown ) result = boost::exit_exception_failure; + + if ( result != 0 && result != exit_success ) + { + out << std::endl << "**** returning with error code " + << result << std::endl; + err + << "********** errors detected; see stdout for details ***********" + << std::endl; + } +#if !defined(BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE) + else { out << std::flush << "no errors detected" << std::endl; } +#endif + return result; + } // catch_exceptions + +} // boost + +#endif // BOOST_CATCH_EXCEPTIONS_HPP + diff --git a/thirdparty/boost/detail/compressed_pair.hpp b/thirdparty/boost/detail/compressed_pair.hpp new file mode 100644 index 0000000..7d9c518 --- /dev/null +++ b/thirdparty/boost/detail/compressed_pair.hpp @@ -0,0 +1,443 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// compressed_pair: pair that "compresses" empty members +// (see libs/utility/compressed_pair.htm) +// +// JM changes 25 Jan 2004: +// For the case where T1 == T2 and both are empty, then first() and second() +// should return different objects. +// JM changes 25 Jan 2000: +// Removed default arguments from compressed_pair_switch to get +// C++ Builder 4 to accept them +// rewriten swap to get gcc and C++ builder to compile. +// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs. + +#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP +#define BOOST_DETAIL_COMPRESSED_PAIR_HPP + +#include + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4512) +#endif +namespace boost +{ + +template +class compressed_pair; + + +// compressed_pair + +namespace details +{ + // JM altered 26 Jan 2000: + template + struct compressed_pair_switch; + + template + struct compressed_pair_switch + {static const int value = 0;}; + + template + struct compressed_pair_switch + {static const int value = 3;}; + + template + struct compressed_pair_switch + {static const int value = 1;}; + + template + struct compressed_pair_switch + {static const int value = 2;}; + + template + struct compressed_pair_switch + {static const int value = 4;}; + + template + struct compressed_pair_switch + {static const int value = 5;}; + + template class compressed_pair_imp; + +#ifdef __GNUC__ + // workaround for GCC (JM): + using std::swap; +#endif + // + // can't call unqualified swap from within classname::swap + // as Koenig lookup rules will find only the classname::swap + // member function not the global declaration, so use cp_swap + // as a forwarding function (JM): + template + inline void cp_swap(T& t1, T& t2) + { +#ifndef __GNUC__ + using std::swap; +#endif + swap(t1, t2); + } + + // 0 derive from neither + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + + // 1 derive from T1 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(second_, y.second()); + } + private: + second_type second_; + }; + + // 2 derive from T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : second_type(y), first_(x) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(first_, y.first()); + } + + private: + first_type first_; + }; + + // 3 derive from T1 and T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type, + protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_type(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + // + // no need to swap empty bases: + void swap(::boost::compressed_pair&) {} + }; + + // JM + // 4 T1 == T2, T1 and T2 both empty + // Originally this did not store an instance of T2 at all + // but that led to problems beause it meant &x.first() == &x.second() + // which is not true for any other kind of pair, so now we store an instance + // of T2 just in case the user is relying on first() and second() returning + // different objects (albeit both empty). + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), m_second(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x), m_second(x) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return m_second;} + second_const_reference second() const {return m_second;} + + void swap(::boost::compressed_pair&) {} + private: + T2 m_second; + }; + + // 5 T1 == T2 and are not empty: //JM + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x), second_(x) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + +} // details + +template +class compressed_pair + : private ::boost::details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> base; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} + explicit compressed_pair(first_param_type x) : base(x) {} + explicit compressed_pair(second_param_type y) : base(y) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(compressed_pair& y) { base::swap(y); } +}; + +// JM +// Partial specialisation for case where T1 == T2: +// +template +class compressed_pair + : private details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> base; +public: + typedef T first_type; + typedef T second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} +#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) + explicit +#endif + compressed_pair(first_param_type x) : base(x) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(::boost::compressed_pair& y) { base::swap(y); } +}; + +template +inline +void +swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +} // boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP + diff --git a/thirdparty/boost/detail/dynamic_bitset.hpp b/thirdparty/boost/detail/dynamic_bitset.hpp new file mode 100644 index 0000000..fc30baf --- /dev/null +++ b/thirdparty/boost/detail/dynamic_bitset.hpp @@ -0,0 +1,176 @@ +// -------------------------------------------------- +// +// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. +// (C) Copyright Gennaro Prota 2003 - 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/dynamic_bitset/ for documentation. +// +// $Revision: 41316 $ $Date: 2007-11-23 12:03:14 -0500 (Fri, 23 Nov 2007) $ - $Name$ + +#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP +#define BOOST_DETAIL_DYNAMIC_BITSET_HPP + +#include // for std::size_t +#include "boost/config.hpp" +#include "boost/detail/workaround.hpp" + + +namespace boost { + + namespace detail { + + // Gives (read-)access to the object representation + // of an object of type T (3.9p4). CANNOT be used + // on a base sub-object + // + template + inline const unsigned char * object_representation (T* p) + { + return static_cast(static_cast(p)); + } + + template + struct shifter + { + static void left_shift(T & v) { + amount >= width ? (v = 0) + : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount)); + } + }; + + // ------- count function implementation -------------- + + namespace dynamic_bitset_count_impl { + + typedef unsigned char byte_type; + + enum mode { access_by_bytes, access_by_blocks }; + + template struct mode_to_type {}; + + // the table: wrapped in a class template, so + // that it is only instantiated if/when needed + // + template + struct count_table { static const byte_type table[]; }; + + template <> + struct count_table { /* no table */ }; + + + const unsigned int table_width = 8; + template + const byte_type count_table::table[] = + { + // Automatically generated by GPTableGen.exe v.1.0 + // + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + }; + + + // overload for access by bytes + // + + template + inline std::size_t do_count(Iterator first, std::size_t length, + int /*dummy param*/, + mode_to_type* ) + { + std::size_t num = 0; + if (length) + { + const byte_type * p = object_representation(&*first); + length *= sizeof(*first); + + do { + num += count_table<>::table[*p]; + ++p; + --length; + + } while (length); + } + + return num; + } + + + // overload for access by blocks + // + template + inline std::size_t do_count(Iterator first, std::size_t length, ValueType, + mode_to_type*) + { + std::size_t num = 0; + while (length){ + + ValueType value = *first; + while (value) { + num += count_table<>::table[value & ((1u<>= table_width; + } + + ++first; + --length; + } + + return num; + } + + + } // dynamic_bitset_count_impl + // ------------------------------------------------------- + + + // Some library implementations simply return a dummy + // value such as + // + // size_type(-1) / sizeof(T) + // + // from vector<>::max_size. This tries to get out more + // meaningful info. + // + template + typename T::size_type vector_max_size_workaround(const T & v) { + + typedef typename T::allocator_type allocator_type; + + const typename allocator_type::size_type alloc_max = + v.get_allocator().max_size(); + const typename T::size_type container_max = v.max_size(); + + return alloc_max < container_max? + alloc_max : + container_max; + } + + // for static_asserts + template + struct dynamic_bitset_allowed_block_type { + enum { value = T(-1) > 0 }; // ensure T has no sign + }; + + template <> + struct dynamic_bitset_allowed_block_type { + enum { value = false }; + }; + + + } // namespace detail + +} // namespace boost + +#endif // include guard + diff --git a/thirdparty/boost/detail/endian.hpp b/thirdparty/boost/detail/endian.hpp new file mode 100644 index 0000000..2b99be2 --- /dev/null +++ b/thirdparty/boost/detail/endian.hpp @@ -0,0 +1,73 @@ +// Copyright 2005 Caleb Epstein +// Copyright 2006 John Maddock +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* + * Copyright notice reproduced from , from + * which this code was originally taken. + * + * Modified by Caleb Epstein to use with GNU libc and to + * defined the BOOST_ENDIAN macro. + */ + +#ifndef BOOST_DETAIL_ENDIAN_HPP +#define BOOST_DETAIL_ENDIAN_HPP + +// GNU libc offers the helpful header which defines +// __BYTE_ORDER + +#if defined (__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define BOOST_LITTLE_ENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define BOOST_BIG_ENDIAN +# elif (__BYTE_ORDER == __PDP_ENDIAN) +# define BOOST_PDP_ENDIAN +# else +# error Unknown machine endianness detected. +# endif +# define BOOST_BYTE_ORDER __BYTE_ORDER +#elif defined(_BIG_ENDIAN) +# define BOOST_BIG_ENDIAN +# define BOOST_BYTE_ORDER 4321 +#elif defined(_LITTLE_ENDIAN) +# define BOOST_LITTLE_ENDIAN +# define BOOST_BYTE_ORDER 1234 +#elif defined(__sparc) || defined(__sparc__) \ + || defined(_POWER) || defined(__powerpc__) \ + || defined(__ppc__) || defined(__hpux) \ + || defined(_MIPSEB) || defined(_POWER) \ + || defined(__s390__) +# define BOOST_BIG_ENDIAN +# define BOOST_BYTE_ORDER 4321 +#elif defined(__i386__) || defined(__alpha__) \ + || defined(__ia64) || defined(__ia64__) \ + || defined(_M_IX86) || defined(_M_IA64) \ + || defined(_M_ALPHA) || defined(__amd64) \ + || defined(__amd64__) || defined(_M_AMD64) \ + || defined(__x86_64) || defined(__x86_64__) \ + || defined(_M_X64) + +# define BOOST_LITTLE_ENDIAN +# define BOOST_BYTE_ORDER 1234 +#else +# error The file boost/detail/endian.hpp needs to be set up for your CPU type. +#endif + + +#endif diff --git a/thirdparty/boost/detail/has_default_constructor.hpp b/thirdparty/boost/detail/has_default_constructor.hpp new file mode 100644 index 0000000..911a5e5 --- /dev/null +++ b/thirdparty/boost/detail/has_default_constructor.hpp @@ -0,0 +1,29 @@ + +// (C) Copyright Matthias Troyerk 2006. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED +#define BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED + +#include + +namespace boost { namespace detail { + +/// type trait to check for a default constructor +/// +/// The default implementation just checks for a trivial constructor. +/// Using some compiler magic it might be possible to provide a better default + +template +struct has_default_constructor + : public has_trivial_constructor +{}; + +} } // namespace boost::detail + + +#endif // BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED diff --git a/thirdparty/boost/detail/identifier.hpp b/thirdparty/boost/detail/identifier.hpp new file mode 100644 index 0000000..142a546 --- /dev/null +++ b/thirdparty/boost/detail/identifier.hpp @@ -0,0 +1,89 @@ +// boost/identifier.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 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 documentation at http://www.boost.org/libs/utility + +#ifndef BOOST_IDENTIFIER_HPP +#define BOOST_IDENTIFIER_HPP + +#include +#include +#include + +namespace boost +{ + namespace detail + { + // class template identifier ---------------------------------------------// + + // Always used as a base class so that different instantiations result in + // different class types even if instantiated with the same value type T. + + // Expected usage is that T is often an integer type, best passed by + // value. There is no reason why T can't be a possibly larger class such as + // std::string, best passed by const reference. + + // This implementation uses pass by value, based on expected common uses. + + template + class identifier + { + public: + typedef T value_type; + + const value_type value() const { return m_value; } + void assign( value_type v ) { m_value = v; } + + bool operator==( const D & rhs ) const { return m_value == rhs.m_value; } + bool operator!=( const D & rhs ) const { return m_value != rhs.m_value; } + bool operator< ( const D & rhs ) const { return m_value < rhs.m_value; } + bool operator<=( const D & rhs ) const { return m_value <= rhs.m_value; } + bool operator> ( const D & rhs ) const { return m_value > rhs.m_value; } + bool operator>=( const D & rhs ) const { return m_value >= rhs.m_value; } + + typedef void (*unspecified_bool_type)(D); // without the D, unspecified_bool_type + static void unspecified_bool_true(D){} // conversion allows relational operators + // between different identifier types + + operator unspecified_bool_type() const { return m_value == value_type() ? 0 : unspecified_bool_true; } + bool operator!() const { return m_value == value_type(); } + + // constructors are protected so that class can only be used as a base class + protected: + identifier() {} + explicit identifier( value_type v ) : m_value(v) {} + + #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // 1300 == VC++ 7.0 bug workaround + private: + #endif + T m_value; + }; + + //#ifndef BOOST_NO_SFINAE + + // template + // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, + // Ostream & >::type operator<<( Ostream & os, const Id & id ) + // { + // return os << id.value(); + // } + + // template + // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, + // Istream & >::type operator>>( Istream & is, Id & id ) + // { + // typename Id::value_type v; + // is >> v; + // id.value( v ); + // return is; + // } + //#endif + + } // namespace detail +} // namespace boost + +#endif // BOOST_IDENTIFIER_HPP diff --git a/thirdparty/boost/detail/indirect_traits.hpp b/thirdparty/boost/detail/indirect_traits.hpp new file mode 100644 index 0000000..a35b7cb --- /dev/null +++ b/thirdparty/boost/detail/indirect_traits.hpp @@ -0,0 +1,487 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef INDIRECT_TRAITS_DWA2002131_HPP +# define INDIRECT_TRAITS_DWA2002131_HPP +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +# include +# include +# include +# include +# include +# include + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# endif + +namespace boost { namespace detail { + +namespace indirect_traits { + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_reference_to_const : mpl::false_ +{ +}; + +template +struct is_reference_to_const : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_const : mpl::true_ +{ +}; +# endif + +template +struct is_reference_to_function : mpl::false_ +{ +}; + +template +struct is_reference_to_function : is_function +{ +}; + +template +struct is_pointer_to_function : mpl::false_ +{ +}; + +// There's no such thing as a pointer-to-cv-function, so we don't need +// specializations for those +template +struct is_pointer_to_function : is_function +{ +}; + +template +struct is_reference_to_member_function_pointer_impl : mpl::false_ +{ +}; + +template +struct is_reference_to_member_function_pointer_impl + : is_member_function_pointer::type> +{ +}; + + +template +struct is_reference_to_member_function_pointer + : is_reference_to_member_function_pointer_impl +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + +template +struct is_reference_to_function_pointer_aux + : mpl::and_< + is_reference + , is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those +}; + +template +struct is_reference_to_function_pointer + : mpl::if_< + is_reference_to_function + , mpl::false_ + , is_reference_to_function_pointer_aux + >::type +{ +}; + +template +struct is_reference_to_non_const + : mpl::and_< + is_reference + , mpl::not_< + is_reference_to_const + > + > +{ +}; + +template +struct is_reference_to_volatile : mpl::false_ +{ +}; + +template +struct is_reference_to_volatile : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_volatile : mpl::true_ +{ +}; +# endif + + +template +struct is_reference_to_pointer : mpl::false_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_class + : mpl::and_< + is_reference + , is_class< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) +}; + +template +struct is_pointer_to_class + : mpl::and_< + is_pointer + , is_class< + typename remove_cv< + typename remove_pointer::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) +}; + +# else + +using namespace boost::detail::is_function_ref_tester_; + +typedef char (&inner_yes_type)[3]; +typedef char (&inner_no_type)[2]; +typedef char (&outer_no_type)[1]; + +template +struct is_const_help +{ + typedef typename mpl::if_< + is_const + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_volatile_help +{ + typedef typename mpl::if_< + is_volatile + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_pointer_help +{ + typedef typename mpl::if_< + is_pointer + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_class_help +{ + typedef typename mpl::if_< + is_class + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_reference_to_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); + typedef mpl::bool_ type; + }; + +template +struct is_reference_to_function + : mpl::if_, is_reference_to_function_aux, mpl::bool_ >::type +{ +}; + +template +struct is_pointer_to_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); + typedef mpl::bool_ type; +}; + +template +struct is_pointer_to_function + : mpl::if_, is_pointer_to_function_aux, mpl::bool_ >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) +}; + +struct false_helper1 +{ + template + struct apply : mpl::false_ + { + }; +}; + +template +typename is_const_help::type reference_to_const_helper(V&); +outer_no_type +reference_to_const_helper(...); + +struct true_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; + }; +}; + +template +struct is_reference_to_const_helper1 : true_helper1 +{ +}; + +template <> +struct is_reference_to_const_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_const + : is_reference_to_const_helper1::value>::template apply +{ +}; + + +template +struct is_reference_to_non_const_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); + + typedef mpl::bool_ type; + }; +}; + +template <> +struct is_reference_to_non_const_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_non_const + : is_reference_to_non_const_helper1::value>::template apply +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_non_const,(T)) +}; + + +template +typename is_volatile_help::type reference_to_volatile_helper(V&); +outer_no_type +reference_to_volatile_helper(...); + +template +struct is_reference_to_volatile_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; + }; +}; + +template <> +struct is_reference_to_volatile_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_volatile + : is_reference_to_volatile_helper1::value>::template apply +{ +}; + +template +typename is_pointer_help::type reference_to_pointer_helper(V&); +outer_no_type reference_to_pointer_helper(...); + +template +struct reference_to_pointer_impl +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) + ); + + typedef mpl::bool_ type; +}; + +template +struct is_reference_to_pointer + : mpl::eval_if, reference_to_pointer_impl, mpl::false_>::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_pointer,(T)) +}; + +template +struct is_reference_to_function_pointer + : mpl::eval_if, is_pointer_to_function_aux, mpl::false_>::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) +}; + + +template +struct is_member_function_pointer_help + : mpl::if_, inner_yes_type, inner_no_type> +{}; + +template +typename is_member_function_pointer_help::type member_function_pointer_helper(V&); +outer_no_type member_function_pointer_helper(...); + +template +struct is_pointer_to_member_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; +}; + +template +struct is_reference_to_member_function_pointer + : mpl::if_< + is_reference + , is_pointer_to_member_function_aux + , mpl::bool_ + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + +template +typename is_class_help::type reference_to_class_helper(V const volatile&); +outer_no_type reference_to_class_helper(...); + +template +struct is_reference_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_reference::value + & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) + ); + typedef mpl::bool_ type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) +}; + +template +typename is_class_help::type pointer_to_class_helper(V const volatile*); +outer_no_type pointer_to_class_helper(...); + +template +struct is_pointer_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_pointer::value + && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type)) + ); + typedef mpl::bool_ type; +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +} + +using namespace indirect_traits; + +}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/thirdparty/boost/detail/interlocked.hpp b/thirdparty/boost/detail/interlocked.hpp new file mode 100644 index 0000000..608b864 --- /dev/null +++ b/thirdparty/boost/detail/interlocked.hpp @@ -0,0 +1,130 @@ +#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED +#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/interlocked.hpp +// +// Copyright 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer + +#elif defined(_WIN32_WCE) + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long); + +# pragma intrinsic( _InterlockedIncrement ) +# pragma intrinsic( _InterlockedDecrement ) +# pragma intrinsic( _InterlockedCompareExchange ) +# pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedExchangeAdd ) + +# if defined(_M_IA64) || defined(_M_AMD64) + +extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); + +# pragma intrinsic( _InterlockedCompareExchangePointer ) +# pragma intrinsic( _InterlockedExchangePointer ) + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED diff --git a/thirdparty/boost/detail/is_function_ref_tester.hpp b/thirdparty/boost/detail/is_function_ref_tester.hpp new file mode 100644 index 0000000..833cdf3 --- /dev/null +++ b/thirdparty/boost/detail/is_function_ref_tester.hpp @@ -0,0 +1,135 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED +#define BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +#include "boost/type_traits/detail/yes_no_type.hpp" +#include "boost/type_traits/config.hpp" + +#if defined(BOOST_TT_PREPROCESSING_MODE) +# include "boost/preprocessor/iterate.hpp" +# include "boost/preprocessor/enum_params.hpp" +# include "boost/preprocessor/comma_if.hpp" +#endif + +namespace boost { +namespace detail { +namespace is_function_ref_tester_ { + +template +boost::type_traits::no_type BOOST_TT_DECL is_function_ref_tester(T& ...); + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// preprocessor-generated part, don't edit by hand! + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24), int); + +#else + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_function_ref_tester.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace detail +} // namespace python +} // namespace boost + +#endif // BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +///// iteration + +#else +#define i BOOST_PP_FRAME_ITERATION(1) + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(BOOST_PP_ENUM_PARAMS(i,T)), int); + +#undef i +#endif // BOOST_PP_IS_ITERATING diff --git a/thirdparty/boost/detail/is_incrementable.hpp b/thirdparty/boost/detail/is_incrementable.hpp new file mode 100644 index 0000000..e64d2c5 --- /dev/null +++ b/thirdparty/boost/detail/is_incrementable.hpp @@ -0,0 +1,124 @@ +// Copyright David Abrahams 2004. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_INCREMENTABLE_DWA200415_HPP +# define IS_INCREMENTABLE_DWA200415_HPP + +# include +# include +# include +# include +# include + +// Must be the last include +# include + +namespace boost { namespace detail { + +// is_incrementable metafunction +// +// Requires: Given x of type T&, if the expression ++x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_incrementable_ +{ + // a type returned from operator++ when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator++ less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator++ for when none other is found +# if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 + +} + +namespace is_incrementable_2 +{ + is_incrementable_::tag operator++(is_incrementable_::any const&); + is_incrementable_::tag operator++(is_incrementable_::any const&,int); +} +using namespace is_incrementable_2; + +namespace is_incrementable_ +{ + +# else + + tag operator++(any const&); + tag operator++(any const&,int); + +# endif + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ + || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + + // two check overloads help us identify which operator++ was picked + char (& check(tag) )[2]; + + template + char check(T const&); + + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check(BOOST_comma(++x,0))) == 1 + ); + }; + + template + struct postfix_impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check(BOOST_comma(x++,0))) == 1 + ); + }; +} + +# undef BOOST_comma + +template +struct is_incrementable +BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl::value) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::impl::value) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T)) +}; + +template +struct is_postfix_incrementable +BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl::value) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::postfix_impl::value) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T)) +}; + +} // namespace detail + +BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_incrementable) +BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_postfix_incrementable) + +} // namespace boost + +# include + +#endif // IS_INCREMENTABLE_DWA200415_HPP diff --git a/thirdparty/boost/detail/is_xxx.hpp b/thirdparty/boost/detail/is_xxx.hpp new file mode 100644 index 0000000..60fd28b --- /dev/null +++ b/thirdparty/boost/detail/is_xxx.hpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2005. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_DETAIL_IS_XXX_DWA20051011_HPP +# define BOOST_DETAIL_IS_XXX_DWA20051011_HPP + +# include +# include +# include + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include +# include + +# define BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) \ +template \ +struct is_##name \ +{ \ + typedef char yes; \ + typedef char (&no)[2]; \ + \ + static typename add_reference::type dummy; \ + \ + struct helpers \ + { \ + template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ + static yes test( \ + qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \ + ); \ + \ + template \ + static no test(U&, ...); \ + }; \ + \ + BOOST_STATIC_CONSTANT( \ + bool, value \ + = !is_reference::value \ + & (sizeof(helpers::test(dummy, 0)) == sizeof(yes))); \ + \ + typedef mpl::bool_ type; \ +}; + +# else + +# define BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) \ +template \ +struct is_##name : mpl::false_ \ +{ \ +}; \ + \ +template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ +struct is_##name< \ + qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ +> \ + : mpl::true_ \ +{ \ +}; + +# endif + +#endif // BOOST_DETAIL_IS_XXX_DWA20051011_HPP diff --git a/thirdparty/boost/detail/iterator.hpp b/thirdparty/boost/detail/iterator.hpp new file mode 100644 index 0000000..48345e8 --- /dev/null +++ b/thirdparty/boost/detail/iterator.hpp @@ -0,0 +1,494 @@ +// (C) Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Boost versions of +// +// std::iterator_traits<>::iterator_category +// std::iterator_traits<>::difference_type +// std::distance() +// +// ...for all compilers and iterators +// +// Additionally, if X is a pointer +// std::iterator_traits::pointer + +// Otherwise, if partial specialization is supported or X is not a pointer +// std::iterator_traits::value_type +// std::iterator_traits::pointer +// std::iterator_traits::reference +// +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 04 Mar 2001 - More attempted fixes for Intel C++ (David Abrahams) +// 03 Mar 2001 - Put all implementation into namespace +// boost::detail::iterator_traits_. Some progress made on fixes +// for Intel compiler. (David Abrahams) +// 02 Mar 2001 - Changed BOOST_MSVC to BOOST_MSVC_STD_ITERATOR in a few +// places. (Jeremy Siek) +// 19 Feb 2001 - Improved workarounds for stock MSVC6; use yes_type and +// no_type from type_traits.hpp; stopped trying to remove_cv +// before detecting is_pointer, in honor of the new type_traits +// semantics. (David Abrahams) +// 13 Feb 2001 - Make it work with nearly all standard-conforming iterators +// under raw VC6. The one category remaining which will fail is +// that of iterators derived from std::iterator but not +// boost::iterator and which redefine difference_type. +// 11 Feb 2001 - Clean away code which can never be used (David Abrahams) +// 09 Feb 2001 - Always have a definition for each traits member, even if it +// can't be properly deduced. These will be incomplete types in +// some cases (undefined), but it helps suppress MSVC errors +// elsewhere (David Abrahams) +// 07 Feb 2001 - Support for more of the traits members where possible, making +// this useful as a replacement for std::iterator_traits when +// used as a default template parameter. +// 06 Feb 2001 - Removed useless #includes of standard library headers +// (David Abrahams) + +#ifndef ITERATOR_DWA122600_HPP_ +# define ITERATOR_DWA122600_HPP_ + +# include +# include + +// STLPort 4.0 and betas have a bug when debugging is enabled and there is no +// partial specialization: instead of an iterator_category typedef, the standard +// container iterators have _Iterator_category. +// +// Also, whether debugging is enabled or not, there is a broken specialization +// of std::iterator which has no +// typedefs but iterator_category. +# if defined(__SGI_STL_PORT) + +# if (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && defined(__STL_DEBUG) +# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# endif + +# define BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +# endif // STLPort <= 4.1b4 && no partial specialization + +# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \ + && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MSVC_STD_ITERATOR) + +namespace boost { namespace detail { + +// Define a new template so it can be specialized +template +struct iterator_traits + : std::iterator_traits +{}; +using std::distance; + +}} // namespace boost::detail + +# else + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MSVC_STD_ITERATOR) + +// This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS + +namespace boost { namespace detail { + +// Rogue Wave Standard Library fools itself into thinking partial +// specialization is missing on some platforms (e.g. Sun), so fails to +// supply iterator_traits! +template +struct iterator_traits +{ + typedef typename Iterator::value_type value_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct iterator_traits +{ + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; + +template +struct iterator_traits +{ + typedef T value_type; + typedef T const& reference; + typedef T const* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; + +}} // namespace boost::detail + +# else + +# include +# include +# include + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# include +# endif +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +# include +# endif + +# include +# include +# include + +// should be the last #include +# include "boost/type_traits/detail/bool_trait_def.hpp" + +namespace boost { namespace detail { + +BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) +BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer) +BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category) + +// is_mutable_iterator -- +// +// A metafunction returning true iff T is a mutable iterator type +// with a nested value_type. Will only work portably with iterators +// whose operator* returns a reference, but that seems to be OK for +// the iterators supplied by Dinkumware. Some input iterators may +// compile-time if they arrive here, and if the compiler is strict +// about not taking the address of an rvalue. + +// This one detects ordinary mutable iterators - the result of +// operator* is convertible to the value_type. +template +type_traits::yes_type is_mutable_iterator_helper(T const*, BOOST_DEDUCED_TYPENAME T::value_type*); + +// Since you can't take the address of an rvalue, the guts of +// is_mutable_iterator_impl will fail if we use &*t directly. This +// makes sure we can still work with non-lvalue iterators. +template T* mutable_iterator_lvalue_helper(T& x); +int mutable_iterator_lvalue_helper(...); + + +// This one detects output iterators such as ostream_iterator which +// return references to themselves. +template +type_traits::yes_type is_mutable_iterator_helper(T const*, T const*); + +type_traits::no_type is_mutable_iterator_helper(...); + +template +struct is_mutable_iterator_impl +{ + static T t; + + BOOST_STATIC_CONSTANT( + bool, value = sizeof( + detail::is_mutable_iterator_helper( + (T*)0 + , mutable_iterator_lvalue_helper(*t) // like &*t + )) + == sizeof(type_traits::yes_type) + ); +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl::value) + + +// is_full_iterator_traits -- +// +// A metafunction returning true iff T has all the requisite nested +// types to satisfy the requirements for a fully-conforming +// iterator_traits implementation. +template +struct is_full_iterator_traits_impl +{ + enum { value = + has_value_type::value + & has_reference::value + & has_pointer::value + & has_difference_type::value + & has_iterator_category::value + }; +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl::value) + + +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +BOOST_MPL_HAS_XXX_TRAIT_DEF(_Iterator_category) + +// is_stlport_40_debug_iterator -- +// +// A metafunction returning true iff T has all the requisite nested +// types to satisfy the requirements of an STLPort 4.0 debug iterator +// iterator_traits implementation. +template +struct is_stlport_40_debug_iterator_impl +{ + enum { value = + has_value_type::value + & has_reference::value + & has_pointer::value + & has_difference_type::value + & has__Iterator_category::value + }; +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl::value) + +template +struct stlport_40_debug_iterator_traits +{ + typedef typename T::value_type value_type; + typedef typename T::reference reference; + typedef typename T::pointer pointer; + typedef typename T::difference_type difference_type; + typedef typename T::_Iterator_category iterator_category; +}; +# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + +template struct pointer_iterator_traits; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct pointer_iterator_traits +{ + typedef typename remove_const::type value_type; + typedef T* pointer; + typedef T& reference; + typedef std::random_access_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; +}; +# else + +// In case of no template partial specialization, and if T is a +// pointer, iterator_traits::value_type can still be computed. For +// some basic types, remove_pointer is manually defined in +// type_traits/broken_compiler_spec.hpp. For others, do it yourself. + +template class please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee; + +template +struct pointer_value_type + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_const< + typename remove_pointer

::type + >::type + > +{ +}; + + +template +struct pointer_reference + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_pointer

::type& + > +{ +}; + +template +struct pointer_iterator_traits +{ + typedef T pointer; + typedef std::random_access_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + typedef typename pointer_value_type::type value_type; + typedef typename pointer_reference::type reference; +}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +// We'll sort iterator types into one of these classifications, from which we +// can determine the difference_type, pointer, reference, and value_type +template +struct standard_iterator_traits +{ + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct msvc_stdlib_mutable_traits + : std::iterator_traits +{ + typedef typename std::iterator_traits::distance_type difference_type; + typedef typename std::iterator_traits::value_type* pointer; + typedef typename std::iterator_traits::value_type& reference; +}; + +template +struct msvc_stdlib_const_traits + : std::iterator_traits +{ + typedef typename std::iterator_traits::distance_type difference_type; + typedef const typename std::iterator_traits::value_type* pointer; + typedef const typename std::iterator_traits::value_type& reference; +}; + +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +template +struct is_bad_output_iterator + : is_base_and_derived< + std::iterator + , Iterator> +{ +}; + +struct bad_output_iterator_traits +{ + typedef void value_type; + typedef void difference_type; + typedef std::output_iterator_tag iterator_category; + typedef void pointer; + typedef void reference; +}; +# endif + +// If we're looking at an MSVC6 (old Dinkumware) ``standard'' +// iterator, this will generate an appropriate traits class. +template +struct msvc_stdlib_iterator_traits + : mpl::if_< + is_mutable_iterator + , msvc_stdlib_mutable_traits + , msvc_stdlib_const_traits + >::type +{}; + +template +struct non_pointer_iterator_traits + : mpl::if_< + // if the iterator contains all the right nested types... + is_full_iterator_traits + // Use a standard iterator_traits implementation + , standard_iterator_traits +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + // Check for STLPort 4.0 broken _Iterator_category type + , mpl::if_< + is_stlport_40_debug_iterator + , stlport_40_debug_iterator_traits +# endif + // Otherwise, assume it's a Dinkum iterator + , msvc_stdlib_iterator_traits +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + >::type +# endif + >::type +{ +}; + +template +struct iterator_traits_aux + : mpl::if_< + is_pointer + , pointer_iterator_traits + , non_pointer_iterator_traits + >::type +{ +}; + +template +struct iterator_traits +{ + // Explicit forwarding from base class needed to keep MSVC6 happy + // under some circumstances. + private: +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + typedef + typename mpl::if_< + is_bad_output_iterator + , bad_output_iterator_traits + , iterator_traits_aux + >::type base; +# else + typedef iterator_traits_aux base; +# endif + public: + typedef typename base::value_type value_type; + typedef typename base::pointer pointer; + typedef typename base::reference reference; + typedef typename base::difference_type difference_type; + typedef typename base::iterator_category iterator_category; +}; + +// This specialization cuts off ETI (Early Template Instantiation) for MSVC. +template <> struct iterator_traits +{ + typedef int value_type; + typedef int pointer; + typedef int reference; + typedef int difference_type; + typedef int iterator_category; +}; + +}} // namespace boost::detail + +# endif // workarounds + +namespace boost { namespace detail { + +namespace iterator_traits_ +{ + template + struct distance_select + { + static Difference execute(Iterator i1, const Iterator i2, ...) + { + Difference result = 0; + while (i1 != i2) + { + ++i1; + ++result; + } + return result; + } + + static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*) + { + return i2 - i1; + } + }; +} // namespace boost::detail::iterator_traits_ + +template +inline typename iterator_traits::difference_type +distance(Iterator first, Iterator last) +{ + typedef typename iterator_traits::difference_type diff_t; + typedef typename ::boost::detail::iterator_traits::iterator_category iterator_category; + + return iterator_traits_::distance_select::execute( + first, last, (iterator_category*)0); +} + +}} + +# endif + + +# undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +#endif // ITERATOR_DWA122600_HPP_ diff --git a/thirdparty/boost/detail/lcast_precision.hpp b/thirdparty/boost/detail/lcast_precision.hpp new file mode 100644 index 0000000..895790e --- /dev/null +++ b/thirdparty/boost/detail/lcast_precision.hpp @@ -0,0 +1,184 @@ +// Copyright Alexander Nasonov & Paul A. Bristow 2006. + +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED +#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + +#include +#include +#include + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT +// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL +#include +#include +#endif + +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \ + (defined(BOOST_MSVC) && (BOOST_MSVC<1310)) + +#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#endif + +#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#include +#else +#include +#endif + +namespace boost { namespace detail { + +class lcast_abstract_stub {}; + +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +// Calculate an argument to pass to std::ios_base::precision from +// lexical_cast. See alternative implementation for broken standard +// libraries in lcast_get_precision below. Keep them in sync, please. +template +struct lcast_precision +{ +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + BOOST_STATIC_CONSTANT(bool, use_default_precision = + !limits::is_specialized || limits::is_exact + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_bin = + !use_default_precision && + limits::radix == 2 && limits::digits > 0 + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_dec = + !use_default_precision && + limits::radix == 10 && limits::digits10 > 0 + ); + + BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max = + boost::integer_traits::const_max + ); + + BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U); + + BOOST_STATIC_ASSERT(!is_specialized_dec || + precision_dec <= streamsize_max + 0UL + ); + + BOOST_STATIC_CONSTANT(unsigned long, precision_bin = + 2UL + limits::digits * 30103UL / 100000UL + ); + + BOOST_STATIC_ASSERT(!is_specialized_bin || + (limits::digits + 0UL < ULONG_MAX / 30103UL && + precision_bin > limits::digits10 + 0UL && + precision_bin <= streamsize_max + 0UL) + ); + + BOOST_STATIC_CONSTANT(std::streamsize, value = + is_specialized_bin ? precision_bin + : is_specialized_dec ? precision_dec : 6 + ); +}; +#endif + +template +inline std::streamsize lcast_get_precision(T* = 0) +{ +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION + return lcast_precision::value; +#else // Follow lcast_precision algorithm at run-time: + +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + bool const use_default_precision = + !limits::is_specialized || limits::is_exact; + + if(!use_default_precision) + { // Includes all built-in floating-point types, float, double ... + // and UDT types for which digits (significand bits) is defined (not zero) + + bool const is_specialized_bin = + limits::radix == 2 && limits::digits > 0; + bool const is_specialized_dec = + limits::radix == 10 && limits::digits10 > 0; + std::streamsize const streamsize_max = + (boost::integer_traits::max)(); + + if(is_specialized_bin) + { // Floating-point types with + // limits::digits defined by the specialization. + + unsigned long const digits = limits::digits; + unsigned long const precision = 2UL + digits * 30103UL / 100000UL; + // unsigned long is selected because it is at least 32-bits + // and thus ULONG_MAX / 30103UL is big enough for all types. + BOOST_ASSERT( + digits < ULONG_MAX / 30103UL && + precision > limits::digits10 + 0UL && + precision <= streamsize_max + 0UL + ); + return precision; + } + else if(is_specialized_dec) + { // Decimal Floating-point type, most likely a User Defined Type + // rather than a real floating-point hardware type. + unsigned int const precision = limits::digits10 + 1U; + BOOST_ASSERT(precision <= streamsize_max + 0UL); + return precision; + } + } + + // Integral type (for which precision has no effect) + // or type T for which limits is NOT specialized, + // so assume stream precision remains the default 6 decimal digits. + // Warning: if your User-defined Floating-point type T is NOT specialized, + // then you may lose accuracy by only using 6 decimal digits. + // To avoid this, you need to specialize T with either + // radix == 2 and digits == the number of significand bits, + // OR + // radix = 10 and digits10 == the number of decimal digits. + + return 6; +#endif +} + +template +inline void lcast_set_precision(std::ios_base& stream, T*) +{ + stream.precision(lcast_get_precision()); +} + +template +inline void lcast_set_precision(std::ios_base& stream, Source*, Target*) +{ + std::streamsize const s = lcast_get_precision((Source*)0); + std::streamsize const t = lcast_get_precision((Target*)0); + stream.precision(s > t ? s : t); +} + +}} + +#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + diff --git a/thirdparty/boost/detail/lightweight_mutex.hpp b/thirdparty/boost/detail/lightweight_mutex.hpp new file mode 100644 index 0000000..a6b7584 --- /dev/null +++ b/thirdparty/boost/detail/lightweight_mutex.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_mutex.hpp - lightweight mutex +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// typedef boost::detail::lightweight_mutex; +// +// boost::detail::lightweight_mutex is a header-only implementation of +// a subset of the Mutex concept requirements: +// +// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex +// +// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX. +// + +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# include +#else +// Use #define BOOST_DISABLE_THREADS to avoid the error +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED diff --git a/thirdparty/boost/detail/lightweight_test.hpp b/thirdparty/boost/detail/lightweight_test.hpp new file mode 100644 index 0000000..57292cb --- /dev/null +++ b/thirdparty/boost/detail/lightweight_test.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_test.hpp - lightweight test library +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// BOOST_TEST(expression) +// BOOST_ERROR(message) +// +// int boost::report_errors() +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline int & test_errors() +{ + static int x = 0; + return x; +} + +inline void test_failed_impl(char const * expr, char const * file, int line, char const * function) +{ + std::cerr << file << "(" << line << "): test '" << expr << "' failed in function '" << function << "'" << std::endl; + ++test_errors(); +} + +inline void error_impl(char const * msg, char const * file, int line, char const * function) +{ + std::cerr << file << "(" << line << "): " << msg << " in function '" << function << "'" << std::endl; + ++test_errors(); +} + +} // namespace detail + +inline int report_errors() +{ + int errors = detail::test_errors(); + + if(errors == 0) + { + std::cerr << "No errors detected." << std::endl; + return 0; + } + else + { + std::cerr << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; + return 1; + } +} + +} // namespace boost + +#define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) +#define BOOST_ERROR(msg) ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED diff --git a/thirdparty/boost/detail/limits.hpp b/thirdparty/boost/detail/limits.hpp new file mode 100644 index 0000000..4fc66d6 --- /dev/null +++ b/thirdparty/boost/detail/limits.hpp @@ -0,0 +1,449 @@ +// Copyright 2001 John Maddock +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is not portable code. Parts of numeric_limits<> are + * inherently machine-dependent, and this file is written for the MIPS + * architecture and the SGI MIPSpro C++ compiler. Parts of it (in + * particular, some of the characteristics of floating-point types) + * are almost certainly incorrect for any other platform. + */ + +/* The above comment is almost certainly out of date. This file works + * on systems other than SGI MIPSpro C++ now. + */ + +/* + * Revision history: + * 21 Sep 2001: + * Only include if BOOST_NO_CWCHAR is defined. (Darin Adler) + * 10 Aug 2001: + * Added MIPS (big endian) to the big endian family. (Jens Maurer) + * 13 Apr 2001: + * Added powerpc to the big endian family. (Jeremy Siek) + * 5 Apr 2001: + * Added sparc (big endian) processor support (John Maddock). + * Initial sub: + * Modified by Jens Maurer for gcc 2.95 on x86. + */ + +#ifndef BOOST_SGI_CPP_LIMITS +#define BOOST_SGI_CPP_LIMITS + +#include +#include +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include // for WCHAR_MIN and WCHAR_MAX +#endif + +namespace std { + +enum float_round_style { + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3 +}; + +enum float_denorm_style { + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 +}; + +// The C++ standard (section 18.2.1) requires that some of the members of +// numeric_limits be static const data members that are given constant- +// initializers within the class declaration. On compilers where the +// BOOST_NO_INCLASS_MEMBER_INITIALIZATION macro is defined, it is impossible to write +// a standard-conforming numeric_limits class. +// +// There are two possible workarounds: either initialize the data +// members outside the class, or change them from data members to +// enums. Neither workaround is satisfactory: the former makes it +// impossible to use the data members in constant-expressions, and the +// latter means they have the wrong type and that it is impossible to +// take their addresses. We choose the former workaround. + +#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + enum { __mem_name = __mem_value } +#else /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ +# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + static const __mem_type __mem_name = __mem_value +#endif /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ + +// Base class for all specializations of numeric_limits. +template +class _Numeric_limits_base { +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false); + + static __number min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } + static __number max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0); + + static __number epsilon() throw() { return __number(); } + static __number round_error() throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_absent); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + static __number infinity() throw() { return __number(); } + static __number quiet_NaN() throw() { return __number(); } + static __number signaling_NaN() throw() { return __number(); } + static __number denorm_min() throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, + round_style, + round_toward_zero); +}; + +// Base class for integers. + +template +class _Integer_limits : public _Numeric_limits_base<_Int> +{ +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + static _Int min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imin; } + static _Int max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imax; } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, + digits, + (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT) + - (__imin == 0 ? 0 : 1) + : __idigits); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000); + // log 2 = 0.301029995664... + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true); +}; + +#if defined(BOOST_BIG_ENDIAN) + + template + struct float_helper{ + static Number get_word() throw() { + // sizeof(long double) == 16 + const unsigned int _S_word[4] = { Word, 0, 0, 0 }; + return *reinterpret_cast(&_S_word); + } +}; + +#else + + template + struct float_helper{ + static Number get_word() throw() { + // sizeof(long double) == 12, but only 10 bytes significant + const unsigned int _S_word[4] = { 0, 0, 0, Word }; + return *reinterpret_cast( + reinterpret_cast(&_S_word)+16- + (sizeof(Number) == 12 ? 10 : sizeof(Number))); + } +}; + +#endif + +// Base class for floating-point numbers. +template +class _Floating_limits : public _Numeric_limits_base<__number> +{ +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_indeterminate); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + + static __number infinity() throw() { + return float_helper<__number, __InfinityWord>::get_word(); + } + static __number quiet_NaN() throw() { + return float_helper<__number,__QNaNWord>::get_word(); + } + static __number signaling_NaN() throw() { + return float_helper<__number,__SNaNWord>::get_word(); + } + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false /* was: true */ ); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle); +}; + +// Class numeric_limits + +// The unspecialized class. + +template +class numeric_limits : public _Numeric_limits_base {}; + +// Specializations for all built-in integral types. + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template<> +class numeric_limits +#if !defined(WCHAR_MAX) || !defined(WCHAR_MIN) +#if defined(_WIN32) || defined(__CYGWIN__) + : public _Integer_limits +#elif defined(__hppa) +// wchar_t has "unsigned int" as the underlying type + : public _Integer_limits +#else +// assume that wchar_t has "int" as the underlying type + : public _Integer_limits +#endif +#else +// we have WCHAR_MIN and WCHAR_MAX defined, so use it + : public _Integer_limits +#endif +{}; +#endif + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +#ifdef __GNUC__ + +// Some compilers have long long, but don't define the +// LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This +// assumes that long long is 64 bits. +#if !defined(LONGLONG_MAX) && !defined(ULONGLONG_MAX) + +# define ULONGLONG_MAX 0xffffffffffffffffLLU +# define LONGLONG_MAX 0x7fffffffffffffffLL + +#endif + +#if !defined(LONGLONG_MIN) +# define LONGLONG_MIN (-LONGLONG_MAX - 1) +#endif + + +#if !defined(ULONGLONG_MIN) +# define ULONGLONG_MIN 0 +#endif + +#endif /* __GNUC__ */ + +// Specializations for all built-in floating-point type. + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static float min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MIN; } + static float denorm_min() throw() { return FLT_MIN; } + static float max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MAX; } + static float epsilon() throw() { return FLT_EPSILON; } + static float round_error() throw() { return 0.5f; } // Units: ulps. +}; + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MIN; } + static double denorm_min() throw() { return DBL_MIN; } + static double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MAX; } + static double epsilon() throw() { return DBL_EPSILON; } + static double round_error() throw() { return 0.5; } // Units: ulps. +}; + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static long double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MIN; } + static long double denorm_min() throw() { return LDBL_MIN; } + static long double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MAX; } + static long double epsilon() throw() { return LDBL_EPSILON; } + static long double round_error() throw() { return 4; } // Units: ulps. +}; + +} // namespace std + +#endif /* BOOST_SGI_CPP_LIMITS */ + +// Local Variables: +// mode:C++ +// End: + + + diff --git a/thirdparty/boost/detail/lwm_nop.hpp b/thirdparty/boost/detail/lwm_nop.hpp new file mode 100644 index 0000000..21f5ed0 --- /dev/null +++ b/thirdparty/boost/detail/lwm_nop.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED +#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_nop.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +public: + + typedef lightweight_mutex scoped_lock; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED diff --git a/thirdparty/boost/detail/lwm_pthreads.hpp b/thirdparty/boost/detail/lwm_pthreads.hpp new file mode 100644 index 0000000..864d872 --- /dev/null +++ b/thirdparty/boost/detail/lwm_pthreads.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED +#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_pthreads.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +private: + + pthread_mutex_t m_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + pthread_mutex_init(&m_, pthread_mutexattr_default); +#else + pthread_mutex_init(&m_, 0); +#endif + } + + ~lightweight_mutex() + { + pthread_mutex_destroy(&m_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + pthread_mutex_t & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + scoped_lock(lightweight_mutex & m): m_(m.m_) + { + pthread_mutex_lock(&m_); + } + + ~scoped_lock() + { + pthread_mutex_unlock(&m_); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED diff --git a/thirdparty/boost/detail/lwm_win32_cs.hpp b/thirdparty/boost/detail/lwm_win32_cs.hpp new file mode 100644 index 0000000..7286f2a --- /dev/null +++ b/thirdparty/boost/detail/lwm_win32_cs.hpp @@ -0,0 +1,104 @@ +#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED +#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_win32_cs.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#ifdef BOOST_USE_WINDOWS_H +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#ifndef BOOST_USE_WINDOWS_H + +struct CRITICAL_SECTION +{ + struct critical_section_debug * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; +#if defined(_WIN64) + unsigned __int64 SpinCount; +#else + unsigned long SpinCount; +#endif +}; + +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *); + +#endif // #ifndef BOOST_USE_WINDOWS_H + +class lightweight_mutex +{ +private: + + CRITICAL_SECTION cs_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + InitializeCriticalSection(&cs_); + } + + ~lightweight_mutex() + { + DeleteCriticalSection(&cs_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + lightweight_mutex & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + explicit scoped_lock(lightweight_mutex & m): m_(m) + { + EnterCriticalSection(&m_.cs_); + } + + ~scoped_lock() + { + LeaveCriticalSection(&m_.cs_); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED diff --git a/thirdparty/boost/detail/named_template_params.hpp b/thirdparty/boost/detail/named_template_params.hpp new file mode 100644 index 0000000..0c2c947 --- /dev/null +++ b/thirdparty/boost/detail/named_template_params.hpp @@ -0,0 +1,177 @@ +// (C) Copyright Jeremy Siek 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) + +// Revision History: + +// 04 Oct 2001 David Abrahams +// Changed name of "bind" to "select" to avoid problems with MSVC. + +#ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP +#define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP + +#include +#include // for is_reference +#if defined(__BORLANDC__) +#include +#endif + +namespace boost { + namespace detail { + + struct default_argument { }; + + struct dummy_default_gen { + template + struct select { + typedef default_argument type; + }; + }; + + // This class template is a workaround for MSVC. + template struct default_generator { + typedef detail::dummy_default_gen type; + }; + + template struct is_default { + enum { value = false }; + typedef type_traits::no_type type; + }; + template <> struct is_default { + enum { value = true }; + typedef type_traits::yes_type type; + }; + + struct choose_default { + template + struct select { + typedef typename default_generator::type Gen; + typedef typename Gen::template select::type type; + }; + }; + struct choose_arg { + template + struct select { + typedef Arg type; + }; + }; + +#if defined(__BORLANDC__) + template + struct choose_arg_or_default { typedef choose_arg type; }; + template <> + struct choose_arg_or_default { + typedef choose_default type; + }; +#else + template + struct choose_arg_or_default { typedef choose_arg type; }; + template <> + struct choose_arg_or_default { + typedef choose_default type; + }; +#endif + + template + class resolve_default { +#if defined(__BORLANDC__) + typedef typename choose_arg_or_default::type>::type Selector; +#else + // This usually works for Borland, but I'm seeing weird errors in + // iterator_adaptor_test.cpp when using this method. + enum { is_def = is_default::value }; + typedef typename choose_arg_or_default::type Selector; +#endif + public: + typedef typename Selector + ::template select::type type; + }; + + // To differentiate an unnamed parameter from a traits generator + // we use is_convertible. + struct named_template_param_base { }; + + template + struct is_named_param_list { + enum { value = is_convertible::value }; + }; + + struct choose_named_params { + template struct select { typedef Prev type; }; + }; + struct choose_default_arg { + template struct select { + typedef detail::default_argument type; + }; + }; + + template struct choose_default_dispatch_; + template <> struct choose_default_dispatch_ { + typedef choose_named_params type; + }; + template <> struct choose_default_dispatch_ { + typedef choose_default_arg type; + }; + // The use of inheritance here is a Solaris Forte 6 workaround. + template struct choose_default_dispatch + : public choose_default_dispatch_ { }; + + template + struct choose_default_argument { + enum { is_named = is_named_param_list::value }; + typedef typename choose_default_dispatch::type Selector; + typedef typename Selector::template select::type type; + }; + + // This macro assumes that there is a class named default_##TYPE + // defined before the application of the macro. This class should + // have a single member class template named "select" with two + // template parameters: the type of the class being created (e.g., + // the iterator_adaptor type when creating iterator adaptors) and + // a traits class. The select class should have a single typedef + // named "type" that produces the default for TYPE. See + // boost/iterator_adaptors.hpp for an example usage. Also, + // applications of this macro must be placed in namespace + // boost::detail. + +#define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \ + struct get_##TYPE##_from_named { \ + template \ + struct select { \ + typedef typename NamedParams::traits NamedTraits; \ + typedef typename NamedTraits::TYPE TYPE; \ + typedef typename resolve_default::type type; \ + }; \ + }; \ + struct pass_thru_##TYPE { \ + template struct select { \ + typedef typename resolve_default::type type; \ + };\ + }; \ + template \ + struct get_##TYPE##_dispatch { }; \ + template <> struct get_##TYPE##_dispatch<1> { \ + typedef get_##TYPE##_from_named type; \ + }; \ + template <> struct get_##TYPE##_dispatch<0> { \ + typedef pass_thru_##TYPE type; \ + }; \ + template \ + class get_##TYPE { \ + enum { is_named = is_named_param_list::value }; \ + typedef typename get_##TYPE##_dispatch::type Selector; \ + public: \ + typedef typename Selector::template select::type type; \ + }; \ + template <> struct default_generator { \ + typedef default_##TYPE type; \ + } + + + } // namespace detail +} // namespace boost + +#endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP diff --git a/thirdparty/boost/detail/no_exceptions_support.hpp b/thirdparty/boost/detail/no_exceptions_support.hpp new file mode 100644 index 0000000..702407f --- /dev/null +++ b/thirdparty/boost/detail/no_exceptions_support.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_ +#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_ + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +//---------------------------------------------------------------------- +// (C) Copyright 2004 Pavel Vozenilek. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// +// This file contains helper macros used when exception support may be +// disabled (as indicated by macro BOOST_NO_EXCEPTIONS). +// +// Before picking up these macros you may consider using RAII techniques +// to deal with exceptions - their syntax can be always the same with +// or without exception support enabled. +// + +/* Example of use: + +void foo() { + BOOST_TRY { + ... + } BOOST_CATCH(const std::bad_alloc&) { + ... + BOOST_RETHROW + } BOOST_CATCH(const std::exception& e) { + ... + } + BOOST_CATCH_END +} + +With exception support enabled it will expand into: + +void foo() { + { try { + ... + } catch (const std::bad_alloc&) { + ... + throw; + } catch (const std::exception& e) { + ... + } + } +} + +With exception support disabled it will expand into: + +void foo() { + { if(true) { + ... + } else if (false) { + ... + } else if (false) { + ... + } + } +} +*/ +//---------------------------------------------------------------------- + +#include +#include + +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_TRY { try +# define BOOST_CATCH(x) catch(x) +# define BOOST_RETHROW throw; +# define BOOST_CATCH_END } +#else +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# define BOOST_TRY { if ("") +# define BOOST_CATCH(x) else if (!"") +# else +# define BOOST_TRY { if (true) +# define BOOST_CATCH(x) else if (false) +# endif +# define BOOST_RETHROW +# define BOOST_CATCH_END } +#endif + + +#endif diff --git a/thirdparty/boost/detail/none_t.hpp b/thirdparty/boost/detail/none_t.hpp new file mode 100644 index 0000000..e48bd36 --- /dev/null +++ b/thirdparty/boost/detail/none_t.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// fernando_cacciola@hotmail.com +// +#ifndef BOOST_DETAIL_NONE_T_17SEP2003_HPP +#define BOOST_DETAIL_NONE_T_17SEP2003_HPP + +namespace boost { + +namespace detail { + +struct none_helper{}; + +typedef int none_helper::*none_t ; + +} // namespace detail + +} // namespace boost + +#endif + diff --git a/thirdparty/boost/detail/numeric_traits.hpp b/thirdparty/boost/detail/numeric_traits.hpp new file mode 100644 index 0000000..a44db9e --- /dev/null +++ b/thirdparty/boost/detail/numeric_traits.hpp @@ -0,0 +1,191 @@ +// (C) Copyright David Abrahams 2001, Howard Hinnant 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) +// +// Template class numeric_traits -- +// +// Supplies: +// +// typedef difference_type -- a type used to represent the difference +// between any two values of Number. +// +// Support: +// 1. Not all specializations are supplied +// +// 2. Use of specializations that are not supplied will cause a +// compile-time error +// +// 3. Users are free to specialize numeric_traits for any type. +// +// 4. Right now, specializations are only supplied for integer types. +// +// 5. On implementations which do not supply compile-time constants in +// std::numeric_limits<>, only specializations for built-in integer types +// are supplied. +// +// 6. Handling of numbers whose range of representation is at least as +// great as boost::intmax_t can cause some differences to be +// unrepresentable in difference_type: +// +// Number difference_type +// ------ --------------- +// signed Number +// unsigned intmax_t +// +// template typename numeric_traits::difference_type +// numeric_distance(Number x, Number y) +// computes (y - x), attempting to avoid overflows. +// + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 11 Feb 2001 - Use BOOST_STATIC_CONSTANT (David Abrahams) +// 11 Feb 2001 - Rolled back ineffective Borland-specific code +// (David Abrahams) +// 10 Feb 2001 - Rolled in supposed Borland fixes from John Maddock, but +// not seeing any improvement yet (David Abrahams) +// 06 Feb 2001 - Factored if_true out into boost/detail/select_type.hpp +// (David Abrahams) +// 23 Jan 2001 - Fixed logic of difference_type selection, which was +// completely wack. In the process, added digit_traits<> +// to compute the number of digits in intmax_t even when +// not supplied by numeric_limits<>. (David Abrahams) +// 21 Jan 2001 - Created (David Abrahams) + +#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901 +# define BOOST_NUMERIC_TRAITS_HPP_DWA20001901 + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace detail { + + // Template class is_signed -- determine whether a numeric type is signed + // Requires that T is constructable from the literals -1 and 0. Compile-time + // error results if that requirement is not met (and thus signedness is not + // likely to have meaning for that type). + template + struct is_signed + { +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + BOOST_STATIC_CONSTANT(bool, value = (Number(-1) < Number(0))); +#else + BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits::is_signed); +#endif + }; + +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + // digit_traits - compute the number of digits in a built-in integer + // type. Needed for implementations on which numeric_limits is not specialized + // for intmax_t (e.g. VC6). + template struct digit_traits_select; + + // numeric_limits is specialized; just select that version of digits + template <> struct digit_traits_select + { + template struct traits + { + BOOST_STATIC_CONSTANT(int, digits = std::numeric_limits::digits); + }; + }; + + // numeric_limits is not specialized; compute digits from sizeof(T) + template <> struct digit_traits_select + { + template struct traits + { + BOOST_STATIC_CONSTANT(int, digits = ( + sizeof(T) * std::numeric_limits::digits + - (is_signed::value ? 1 : 0)) + ); + }; + }; + + // here's the "usable" template + template struct digit_traits + { + typedef digit_traits_select< + ::std::numeric_limits::is_specialized> selector; + typedef typename selector::template traits traits; + BOOST_STATIC_CONSTANT(int, digits = traits::digits); + }; +#endif + + // Template class integer_traits -- traits of various integer types + // This should probably be rolled into boost::integer_traits one day, but I + // need it to work without + template + struct integer_traits + { +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + private: + typedef Integer integer_type; + typedef std::numeric_limits x; +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // for some reason, MSVC asserts when it shouldn't unless we make these + // local definitions + BOOST_STATIC_CONSTANT(bool, is_integer = x::is_integer); + BOOST_STATIC_CONSTANT(bool, is_specialized = x::is_specialized); + + BOOST_STATIC_ASSERT(is_integer); + BOOST_STATIC_ASSERT(is_specialized); +# endif + public: + typedef typename + if_true<(int(x::is_signed) + && (!int(x::is_bounded) + // digits is the number of no-sign bits + || (int(x::digits) + 1 >= digit_traits::digits)))>::template then< + Integer, + + typename if_true<(int(x::digits) + 1 < digit_traits::digits)>::template then< + signed int, + + typename if_true<(int(x::digits) + 1 < digit_traits::digits)>::template then< + signed long, + + // else + intmax_t + >::type>::type>::type difference_type; +#else + BOOST_STATIC_ASSERT(boost::is_integral::value); + + typedef typename + if_true<(sizeof(Integer) >= sizeof(intmax_t))>::template then< + + typename if_true<(is_signed::value)>::template then< + Integer, + intmax_t + >::type, + + typename if_true<(sizeof(Integer) < sizeof(std::ptrdiff_t))>::template then< + std::ptrdiff_t, + intmax_t + >::type + >::type difference_type; +# endif + }; + + // Right now, only supports integers, but should be expanded. + template + struct numeric_traits + { + typedef typename integer_traits::difference_type difference_type; + }; + + template + typename numeric_traits::difference_type numeric_distance(Number x, Number y) + { + typedef typename numeric_traits::difference_type difference_type; + return difference_type(y) - difference_type(x); + } +}} + +#endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901 diff --git a/thirdparty/boost/detail/ob_call_traits.hpp b/thirdparty/boost/detail/ob_call_traits.hpp new file mode 100644 index 0000000..eaf9cbe --- /dev/null +++ b/thirdparty/boost/detail/ob_call_traits.hpp @@ -0,0 +1,168 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. +// +// Crippled version for crippled compilers: +// see libs/utility/call_traits.htm +// + +/* Release notes: + 01st October 2000: + Fixed call_traits on VC6, using "poor man's partial specialisation", + using ideas taken from "Generative programming" by Krzysztof Czarnecki + & Ulrich Eisenecker. +*/ + +#ifndef BOOST_OB_CALL_TRAITS_HPP +#define BOOST_OB_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP +#include +#endif + +namespace boost{ + +#ifdef BOOST_MSVC6_MEMBER_TEMPLATES +// +// use member templates to emulate +// partial specialisation: +// +namespace detail{ + +template +struct standard_call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T& param_type; +}; +template +struct simple_call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T param_type; +}; +template +struct reference_call_traits +{ + typedef T value_type; + typedef T reference; + typedef T const_reference; + typedef T param_type; +}; + +template +struct call_traits_chooser +{ + template + struct rebind + { + typedef standard_call_traits type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + typedef simple_call_traits type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + typedef reference_call_traits type; + }; +}; + +template +struct call_traits_sizeof_chooser2 +{ + template + struct small_rebind + { + typedef simple_call_traits small_type; + }; +}; + +template<> +struct call_traits_sizeof_chooser2 +{ + template + struct small_rebind + { + typedef standard_call_traits small_type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) }; + typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser; + typedef typename chooser::template small_rebind bound_type; + typedef typename bound_type::small_type type; + }; +}; + +} // namespace detail +template +struct call_traits +{ +private: + typedef detail::call_traits_chooser< + ::boost::is_pointer::value, + ::boost::is_arithmetic::value, + ::boost::is_reference::value + > chooser; + typedef typename chooser::template rebind bound_type; + typedef typename bound_type::type call_traits_type; +public: + typedef typename call_traits_type::value_type value_type; + typedef typename call_traits_type::reference reference; + typedef typename call_traits_type::const_reference const_reference; + typedef typename call_traits_type::param_type param_type; +}; + +#else +// +// sorry call_traits is completely non-functional +// blame your broken compiler: +// + +template +struct call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T& param_type; +}; + +#endif // member templates + +} + +#endif // BOOST_OB_CALL_TRAITS_HPP diff --git a/thirdparty/boost/detail/ob_compressed_pair.hpp b/thirdparty/boost/detail/ob_compressed_pair.hpp new file mode 100644 index 0000000..51346f7 --- /dev/null +++ b/thirdparty/boost/detail/ob_compressed_pair.hpp @@ -0,0 +1,510 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. +// see libs/utility/compressed_pair.hpp +// +/* Release notes: + 20 Jan 2001: + Fixed obvious bugs (David Abrahams) + 07 Oct 2000: + Added better single argument constructor support. + 03 Oct 2000: + Added VC6 support (JM). + 23rd July 2000: + Additional comments added. (JM) + Jan 2000: + Original version: this version crippled for use with crippled compilers + - John Maddock Jan 2000. +*/ + + +#ifndef BOOST_OB_COMPRESSED_PAIR_HPP +#define BOOST_OB_COMPRESSED_PAIR_HPP + +#include +#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_SAME_TRAITS_HPP +#include +#endif +#ifndef BOOST_CALL_TRAITS_HPP +#include +#endif + +namespace boost +{ +#ifdef BOOST_MSVC6_MEMBER_TEMPLATES +// +// use member templates to emulate +// partial specialisation. Note that due to +// problems with overload resolution with VC6 +// each of the compressed_pair versions that follow +// have one template single-argument constructor +// in place of two specific constructors: +// + +template +class compressed_pair; + +namespace detail{ + +template +struct best_conversion_traits +{ + typedef char one; + typedef char (&two)[2]; + static A a; + static one test(T1); + static two test(T2); + + enum { value = sizeof(test(a)) }; +}; + +template +struct init_one; + +template <> +struct init_one<1> +{ + template + static void init(const A& a, T1* p1, T2*) + { + *p1 = a; + } +}; + +template <> +struct init_one<2> +{ + template + static void init(const A& a, T1*, T2* p2) + { + *p2 = a; + } +}; + + +// T1 != T2, both non-empty +template +class compressed_pair_0 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_0() : _first(), _second() {} + compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {} + template + explicit compressed_pair_0(const A& val) + { + init_one::value>::init(val, &_first, &_second); + } + compressed_pair_0(const ::boost::compressed_pair& x) + : _first(x.first()), _second(x.second()) {} + +#if 0 + compressed_pair_0& operator=(const compressed_pair_0& x) { + cout << "assigning compressed pair 0" << endl; + _first = x._first; + _second = x._second; + cout << "finished assigning compressed pair 0" << endl; + return *this; + } +#endif + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_0& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +// T1 != T2, T2 empty +template +class compressed_pair_1 : T2 +{ +private: + T1 _first; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_1() : T2(), _first() {} + compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {} + + template + explicit compressed_pair_1(const A& val) + { + init_one::value>::init(val, &_first, static_cast(this)); + } + + compressed_pair_1(const ::boost::compressed_pair& x) + : T2(x.second()), _first(x.first()) {} + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // Total weirdness. If the assignment to _first is moved after + // the call to the inherited operator=, then this breaks graph/test/graph.cpp + // by way of iterator_adaptor. + compressed_pair_1& operator=(const compressed_pair_1& x) { + _first = x._first; + T2::operator=(x); + return *this; + } +#endif + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_1& y) + { + // no need to swap empty base class: + using std::swap; + swap(_first, y._first); + } +}; + +// T1 != T2, T1 empty +template +class compressed_pair_2 : T1 +{ +private: + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_2() : T1(), _second() {} + compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {} + template + explicit compressed_pair_2(const A& val) + { + init_one::value>::init(val, static_cast(this), &_second); + } + compressed_pair_2(const ::boost::compressed_pair& x) + : T1(x.first()), _second(x.second()) {} + +#if 0 + compressed_pair_2& operator=(const compressed_pair_2& x) { + cout << "assigning compressed pair 2" << endl; + T1::operator=(x); + _second = x._second; + cout << "finished assigning compressed pair 2" << endl; + return *this; + } +#endif + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_2& y) + { + // no need to swap empty base class: + using std::swap; + swap(_second, y._second); + } +}; + +// T1 != T2, both empty +template +class compressed_pair_3 : T1, T2 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_3() : T1(), T2() {} + compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {} + template + explicit compressed_pair_3(const A& val) + { + init_one::value>::init(val, static_cast(this), static_cast(this)); + } + compressed_pair_3(const ::boost::compressed_pair& x) + : T1(x.first()), T2(x.second()) {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_3& y) + { + // no need to swap empty base classes: + } +}; + +// T1 == T2, and empty +template +class compressed_pair_4 : T1 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_4() : T1() {} + compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {} + // only one single argument constructor since T1 == T2 + explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {} + compressed_pair_4(const ::boost::compressed_pair& x) + : T1(x.first()), m_second(x.second()) {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return m_second; } + second_const_reference second() const { return m_second; } + + void swap(compressed_pair_4& y) + { + // no need to swap empty base classes: + } +private: + T2 m_second; +}; + +// T1 == T2, not empty +template +class compressed_pair_5 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_5() : _first(), _second() {} + compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {} + // only one single argument constructor since T1 == T2 + explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {} + compressed_pair_5(const ::boost::compressed_pair& c) + : _first(c.first()), _second(c.second()) {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_5& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_0 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_1 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_2 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_3 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_4 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_5 type; + }; +}; + +template +struct compressed_pair_traits +{ +private: + typedef compressed_pair_chooser::value, is_empty::value, is_same::value> chooser; + typedef typename chooser::template rebind bound_type; +public: + typedef typename bound_type::type type; +}; + +} // namespace detail + +template +class compressed_pair : public detail::compressed_pair_traits::type +{ +private: + typedef typename detail::compressed_pair_traits::type base_type; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base_type() {} + compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {} + template + explicit compressed_pair(const A& x) : base_type(x){} + + first_reference first() { return base_type::first(); } + first_const_reference first() const { return base_type::first(); } + + second_reference second() { return base_type::second(); } + second_const_reference second() const { return base_type::second(); } +}; + +template +inline void swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +#else +// no partial specialisation, no member templates: + +template +class compressed_pair +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : _first(), _second() {} + compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {} + explicit compressed_pair(first_param_type x) : _first(x), _second() {} + // can't define this in case T1 == T2: + // explicit compressed_pair(second_param_type y) : _first(), _second(y) {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +inline void swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +#endif + +} // boost + +#endif // BOOST_OB_COMPRESSED_PAIR_HPP + + + diff --git a/thirdparty/boost/detail/quick_allocator.hpp b/thirdparty/boost/detail/quick_allocator.hpp new file mode 100644 index 0000000..de653a6 --- /dev/null +++ b/thirdparty/boost/detail/quick_allocator.hpp @@ -0,0 +1,198 @@ +#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/quick_allocator.hpp +// +// Copyright (c) 2003 David Abrahams +// Copyright (c) 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#include +#include +#include + +#include // ::operator new, ::operator delete +#include // std::size_t + +namespace boost +{ + +namespace detail +{ + +template union freeblock +{ + typedef typename boost::type_with_alignment::type aligner_type; + aligner_type aligner; + char bytes[size]; + freeblock * next; +}; + +template struct allocator_impl +{ + typedef freeblock block; + + // It may seem odd to use such small pages. + // + // However, on a typical Windows implementation that uses + // the OS allocator, "normal size" pages interact with the + // "ordinary" operator new, slowing it down dramatically. + // + // 512 byte pages are handled by the small object allocator, + // and don't interfere with ::new. + // + // The other alternative is to use much bigger pages (1M.) + // + // It is surprisingly easy to hit pathological behavior by + // varying the page size. g++ 2.96 on Red Hat Linux 7.2, + // for example, passionately dislikes 496. 512 seems OK. + +#if defined(BOOST_QA_PAGE_SIZE) + + enum { items_per_page = BOOST_QA_PAGE_SIZE / size }; + +#else + + enum { items_per_page = 512 / size }; // 1048560 / size + +#endif + +#ifdef BOOST_HAS_THREADS + + static lightweight_mutex & mutex() + { + static lightweight_mutex m; + return m; + } + + static lightweight_mutex * mutex_init; + +#endif + + static block * free; + static block * page; + static unsigned last; + + static inline void * alloc() + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + // "Listen to me carefully: there is no memory leak" + // -- Scott Meyers, Eff C++ 2nd Ed Item 10 + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + + static inline void * alloc(std::size_t n) + { + if(n != size) // class-specific new called for a derived object + { + return ::operator new(n); + } + else + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + } + + static inline void dealloc(void * pv) + { + if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } + + static inline void dealloc(void * pv, std::size_t n) + { + if(n != size) // class-specific delete called for a derived object + { + ::operator delete(pv); + } + else if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } +}; + +#ifdef BOOST_HAS_THREADS + +template + lightweight_mutex * allocator_impl::mutex_init = &allocator_impl::mutex(); + +#endif + +template + freeblock * allocator_impl::free = 0; + +template + freeblock * allocator_impl::page = 0; + +template + unsigned allocator_impl::last = allocator_impl::items_per_page; + +template +struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED diff --git a/thirdparty/boost/detail/reference_content.hpp b/thirdparty/boost/detail/reference_content.hpp new file mode 100644 index 0000000..eae9f04 --- /dev/null +++ b/thirdparty/boost/detail/reference_content.hpp @@ -0,0 +1,141 @@ +//----------------------------------------------------------------------------- +// boost detail/reference_content.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_REFERENCE_CONTENT_HPP +#define BOOST_DETAIL_REFERENCE_CONTENT_HPP + +#include "boost/config.hpp" + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include "boost/mpl/bool.hpp" +# include "boost/type_traits/has_nothrow_copy.hpp" +#else +# include "boost/mpl/if.hpp" +# include "boost/type_traits/is_reference.hpp" +#endif + +#include "boost/mpl/void.hpp" + +namespace boost { + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template reference_content +// +// Non-Assignable wrapper for references. +// +template +class reference_content +{ +private: // representation + + RefT content_; + +public: // structors + + ~reference_content() + { + } + + reference_content(RefT r) + : content_( r ) + { + } + + reference_content(const reference_content& operand) + : content_( operand.content_ ) + { + } + +private: // non-Assignable + + reference_content& operator=(const reference_content&); + +public: // queries + + RefT get() const + { + return content_; + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_reference_content +// +// Wraps with reference_content if specified type is reference. +// + +template struct make_reference_content; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_content +{ + typedef T type; +}; + +template +struct make_reference_content< T& > +{ + typedef reference_content type; +}; + +#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_content + : mpl::if_< + is_reference + , reference_content + , T + > +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround + +template <> +struct make_reference_content< mpl::void_ > +{ + template + struct apply + : make_reference_content + { + }; + + typedef mpl::void_ type; +}; + +} // namespace detail + +/////////////////////////////////////////////////////////////////////////////// +// reference_content type traits specializations +// + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct has_nothrow_copy< + ::boost::detail::reference_content< T& > + > + : mpl::true_ +{ +}; + +#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +} // namespace boost + +#endif // BOOST_DETAIL_REFERENCE_CONTENT_HPP diff --git a/thirdparty/boost/detail/select_type.hpp b/thirdparty/boost/detail/select_type.hpp new file mode 100644 index 0000000..01c9436 --- /dev/null +++ b/thirdparty/boost/detail/select_type.hpp @@ -0,0 +1,36 @@ +// (C) Copyright David Abrahams 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. + +// Revision History +// 09 Feb 01 Applied John Maddock's Borland patch Moving +// specialization to unspecialized template (David Abrahams) +// 06 Feb 01 Created (David Abrahams) + +#ifndef SELECT_TYPE_DWA20010206_HPP +# define SELECT_TYPE_DWA20010206_HPP + +namespace boost { namespace detail { + + // Template class if_true -- select among 2 types based on a bool constant expression + // Usage: + // typename if_true<(bool_const_expression)>::template then::type + + // HP aCC cannot deal with missing names for template value parameters + template struct if_true + { + template + struct then { typedef T type; }; + }; + + template <> + struct if_true + { + template + struct then { typedef F type; }; + }; +}} +#endif // SELECT_TYPE_DWA20010206_HPP diff --git a/thirdparty/boost/detail/shared_array_nmt.hpp b/thirdparty/boost/detail/shared_array_nmt.hpp new file mode 100644 index 0000000..3a80932 --- /dev/null +++ b/thirdparty/boost/detail/shared_array_nmt.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED + +// +// detail/shared_array_nmt.hpp - shared_array.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation. +// + +#include +#include +#include +#include + +#include // for std::ptrdiff_t +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_array +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + + explicit shared_array(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_array_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_array_delete(p); + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_array() + { + if(--*pn == 0) + { + boost::checked_array_delete(px); + delete pn; + } + } + + shared_array(shared_array const & r) : px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_array & operator=(shared_array const & r) + { + shared_array(r).swap(*this); + return *this; + } + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_array(p).swap(*this); + } + + T * get() const // never throws + { + return px; + } + + T & operator[](std::ptrdiff_t i) const // never throws + { + BOOST_ASSERT(px != 0); + BOOST_ASSERT(i >= 0); + return px[i]; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_array & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter + +}; // shared_array + +template inline bool operator==(shared_array const & a, shared_array const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_array const & a, shared_array const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_array const & a, shared_array const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_array & a, shared_array & b) +{ + a.swap(b); +} + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/shared_count.hpp b/thirdparty/boost/detail/shared_count.hpp new file mode 100644 index 0000000..55d0a37 --- /dev/null +++ b/thirdparty/boost/detail/shared_count.hpp @@ -0,0 +1,375 @@ +#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#ifdef __BORLANDC__ +# pragma warn -8027 // Functions containing try are not expanded inline +#endif + +#include +#include +#include +#include +#include +#include + +#include // std::auto_ptr +#include // std::less +#include // std::bad_alloc + +namespace boost +{ + +namespace detail +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +#endif + +class weak_count; + +class shared_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + + template explicit shared_count( Y * p ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_p( p ); + } + catch(...) + { + boost::checked_delete( p ); + throw; + } + +#else + + pi_ = new sp_counted_impl_p( p ); + + if( pi_ == 0 ) + { + boost::checked_delete( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + + template shared_count(P p, D d): pi_(0) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_pd(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + +#else + + pi_ = new sp_counted_impl_pd(p, d); + + if(pi_ == 0) + { + d(p); // delete p + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + template shared_count( P p, D d, A a ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef sp_counted_impl_pda impl_type; + typedef typename A::template rebind< impl_type >::other A2; + + A2 a2( a ); + +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + } + catch(...) + { + d( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + + if( pi_ != 0 ) + { + new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + } + else + { + d( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + +#ifndef BOOST_NO_AUTO_PTR + + // auto_ptr is special cased to provide the strong guarantee + + template + explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception(std::bad_alloc()); + } + +#endif + + r.release(); + } + +#endif + + ~shared_count() // nothrow + { + if( pi_ != 0 ) pi_->release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if( pi_ != 0 ) pi_->add_ref_copy(); + } + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if( tmp != 0 ) tmp->add_ref_copy(); + if( pi_ != 0 ) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()( a.pi_, b.pi_ ); + } + + void * get_deleter( sp_typeinfo const & ti ) const + { + return pi_? pi_->get_deleter( ti ): 0; + } +}; + + +class weak_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ == 0 || !pi_->add_ref_lock() ) + { + boost::throw_exception( boost::bad_weak_ptr() ); + } +} + +} // namespace detail + +} // namespace boost + +#ifdef __BORLANDC__ +# pragma warn .8027 // Functions containing try are not expanded inline +#endif + +#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/shared_ptr_nmt.hpp b/thirdparty/boost/detail/shared_ptr_nmt.hpp new file mode 100644 index 0000000..8907d61 --- /dev/null +++ b/thirdparty/boost/detail/shared_ptr_nmt.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED + +// +// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include +#include +#include +#include + +#ifndef BOOST_NO_AUTO_PTR +# include // for std::auto_ptr +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_ptr +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + typedef T value_type; + + explicit shared_ptr(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_delete(p); + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_ptr() + { + if(--*pn == 0) + { + boost::checked_delete(px); + delete pn; + } + } + + shared_ptr(shared_ptr const & r): px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_ptr & operator=(shared_ptr const & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit shared_ptr(std::auto_ptr & r) + { + pn = new count_type(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_ptr & operator=(std::auto_ptr & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#endif + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_ptr(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_ptr & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter +}; + +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_ptr & a, shared_ptr & b) +{ + a.swap(b); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr const & p) +{ + return p.get(); +} + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base.hpp b/thirdparty/boost/detail/sp_counted_base.hpp new file mode 100644 index 0000000..f7de1ec --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base.hpp @@ -0,0 +1,81 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base.hpp +// +// Copyright 2005, 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( BOOST_SP_DISABLE_THREADS ) + +# include + +#elif defined( BOOST_SP_USE_PTHREADS ) + +# include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + +# include + +//~ #elif defined( __MWERKS__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + +//~ # include + +#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) + +# include + +#elif defined(__HP_aCC) && defined(__ia64) + +# include + +#elif defined( __MWERKS__ ) && defined( __POWERPC__ ) + +# include + +#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) + +# include + +#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +# include + +#elif defined(__GNUC__) && ( defined( __sparcv8 ) || defined( __sparcv9 ) ) + +# include + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +# include + +#elif !defined( BOOST_HAS_THREADS ) + +# include + +#elif defined( BOOST_HAS_PTHREADS ) + +# include + +#else + +// Use #define BOOST_DISABLE_THREADS to avoid the error +# error Unrecognized threading platform + +#endif + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_acc_ia64.hpp b/thirdparty/boost/detail/sp_counted_base_acc_ia64.hpp new file mode 100644 index 0000000..7d145f8 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_acc_ia64.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64 +// +// Copyright 2007 Baruch Zilber +// Copyright 2007 Boris Gubenko +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include "sp_typeinfo.hpp" +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int r = static_cast(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE)); + if (1 == r) + { + _Asm_mf(); + } + + return r - 1; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int v = *pw; + + for (;;) + { + if (0 == v) + { + return 0; + } + + _Asm_mov_to_ar(_AREG_CCV, + v, + (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)); + int r = static_cast(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE)); + if (r == v) + { + return r + 1; + } + + v = r; + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_cw_ppc.hpp b/thirdparty/boost/detail/sp_counted_base_cw_ppc.hpp new file mode 100644 index 0000000..99e3b89 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_cw_ppc.hpp @@ -0,0 +1,170 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + addi a, a, 1 + stwcx. a, 0, pw + bne- loop + } +} + +inline long atomic_decrement( register long * pw ) +{ + register int a; + + asm + { + sync + +loop: + + lwarx a, 0, pw + addi a, a, -1 + stwcx. a, 0, pw + bne- loop + + isync + } + + return a; +} + +inline long atomic_conditional_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + cmpwi a, 0 + beq store + + addi a, a, 1 + +store: + + stwcx. a, 0, pw + bne- loop + } + + return a; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_cw_x86.hpp b/thirdparty/boost/detail/sp_counted_base_cw_x86.hpp new file mode 100644 index 0000000..9abb127 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_cw_x86.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+ +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2005 Rene Rivera +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + asm + { + mov esi, [pw] + mov eax, dv + lock xadd dword ptr [esi], eax + } +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + asm + { + mov esi, [pw] + lock inc dword ptr [esi] + } +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + asm + { + mov esi, [pw] + mov eax, dword ptr [esi] + L0: + test eax, eax + je L1 + mov ebx, eax + inc ebx + lock cmpxchg dword ptr [esi], ebx + jne L0 + L1: + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_gcc_ia64.hpp b/thirdparty/boost/detail/sp_counted_base_gcc_ia64.hpp new file mode 100644 index 0000000..357a9b4 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_gcc_ia64.hpp @@ -0,0 +1,157 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2006 Peter Dimov +// Copyright 2005 Ben Hutchings +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + // No barrier is required here but fetchadd always has an acquire or + // release barrier associated with it. We choose release as it should be + // cheaper. + __asm__ ("fetchadd4.rel %0=%1,1" : + "=r"(tmp), "=m"(*pw) : + "m"( *pw )); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n" + " cmp.eq p7,p0=1,%0 ;; \n" + "(p7) ld4.acq %0=%1 " : + "=&r"(rv), "=m"(*pw) : + "m"( *pw ) : + "p7"); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp, tmp2; + + __asm__ ("0: ld4 %0=%3 ;; \n" + " cmp.eq p7,p0=0,%0 ;; \n" + "(p7) br.cond.spnt 1f \n" + " mov ar.ccv=%0 \n" + " add %1=1,%0 ;; \n" + " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n" + " cmp.ne p7,p0=%0,%2 ;; \n" + "(p7) br.cond.spnt 0b \n" + " mov %0=%1 ;; \n" + "1:" : + "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) : + "m"( *pw ) : + "ar.ccv", "p7"); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_gcc_ppc.hpp b/thirdparty/boost/detail/sp_counted_base_gcc_ppc.hpp new file mode 100644 index 0000000..17d06bc --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_gcc_ppc.hpp @@ -0,0 +1,181 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, 1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( tmp ): + "r"( pw ), "m"( *pw ): + "cc" + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ __volatile__ + ( + "sync\n\t" + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, -1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b\n\t" + "isync": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "memory", "cc" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "cmpwi %1, 0\n\t" + "beq 1f\n\t" + "addi %1, %1, 1\n\t" + "1:\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "cc" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_gcc_sparc.hpp b/thirdparty/boost/detail/sp_counted_base_gcc_sparc.hpp new file mode 100644 index 0000000..9e57466 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_gcc_sparc.hpp @@ -0,0 +1,166 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ +// +// Copyright (c) 2006 Piotr Wyderski +// Copyright (c) 2006 Tomas Puverle +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Thanks to Michael van der Westhuizen + +#include "sp_typeinfo.hpp" +#include // int32_t + +namespace boost +{ + +namespace detail +{ + +inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) +{ + __asm__ __volatile__( "cas %0, %2, %1" + : "+m" (*dest_), "+r" (swap_) + : "r" (compare_) + : "memory" ); + + return swap_; +} + +inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv ) +{ + // long r = *pw; + // *pw += dv; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) + { + return r; + } + } +} + +inline void atomic_increment( int32_t * pw ) +{ + atomic_fetch_and_add( pw, 1 ); +} + +inline int32_t atomic_decrement( int32_t * pw ) +{ + return atomic_fetch_and_add( pw, -1 ); +} + +inline int32_t atomic_conditional_increment( int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( r == 0 ) + { + return r; + } + + if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int32_t use_count_; // #shared + int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_gcc_x86.hpp b/thirdparty/boost/detail/sp_counted_base_gcc_x86.hpp new file mode 100644 index 0000000..15fe9c7 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_gcc_x86.hpp @@ -0,0 +1,173 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "=m"( *pw ), "=r"( r ): // outputs (%0, %1) + "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) + "memory", "cc" // clobbers + ); + + return r; +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + __asm__ + ( + "lock\n\t" + "incl %0": + "=m"( *pw ): // output (%0) + "m"( *pw ): // input (%1) + "cc" // clobbers + ); +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + int rv, tmp; + + __asm__ + ( + "movl %0, %%eax\n\t" + "0:\n\t" + "test %%eax, %%eax\n\t" + "je 1f\n\t" + "movl %%eax, %2\n\t" + "incl %2\n\t" + "lock\n\t" + "cmpxchgl %2, %0\n\t" + "jne 0b\n\t" + "1:": + "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) + "m"( *pw ): // input (%3) + "cc" // clobbers + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_nt.hpp b/thirdparty/boost/detail/sp_counted_base_nt.hpp new file mode 100644 index 0000000..e68995a --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_nt.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_nt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + ++use_count_; + } + + bool add_ref_lock() // true on success + { + if( use_count_ == 0 ) return false; + ++use_count_; + return true; + } + + void release() // nothrow + { + if( --use_count_ == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + ++weak_count_; + } + + void weak_release() // nothrow + { + if( --weak_count_ == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return use_count_; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_pt.hpp b/thirdparty/boost/detail/sp_counted_base_pt.hpp new file mode 100644 index 0000000..bd7d712 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_pt.hpp @@ -0,0 +1,135 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_pt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include "sp_typeinfo.hpp" +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable pthread_mutex_t m_; + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + pthread_mutex_init( &m_, pthread_mutexattr_default ); +#else + pthread_mutex_init( &m_, 0 ); +#endif + } + + virtual ~sp_counted_base() // nothrow + { + pthread_mutex_destroy( &m_ ); + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + pthread_mutex_lock( &m_ ); + ++use_count_; + pthread_mutex_unlock( &m_ ); + } + + bool add_ref_lock() // true on success + { + pthread_mutex_lock( &m_ ); + bool r = use_count_ == 0? false: ( ++use_count_, true ); + pthread_mutex_unlock( &m_ ); + return r; + } + + void release() // nothrow + { + pthread_mutex_lock( &m_ ); + long new_use_count = --use_count_; + pthread_mutex_unlock( &m_ ); + + if( new_use_count == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + pthread_mutex_lock( &m_ ); + ++weak_count_; + pthread_mutex_unlock( &m_ ); + } + + void weak_release() // nothrow + { + pthread_mutex_lock( &m_ ); + long new_weak_count = --weak_count_; + pthread_mutex_unlock( &m_ ); + + if( new_weak_count == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + pthread_mutex_lock( &m_ ); + long r = use_count_; + pthread_mutex_unlock( &m_ ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_solaris.hpp b/thirdparty/boost/detail/sp_counted_base_solaris.hpp new file mode 100644 index 0000000..c206c34 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_solaris.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED + +// +// detail/sp_counted_base_solaris.hpp +// based on: detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Michael van der Westhuizen +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include "sp_typeinfo.hpp" +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + uint32_t use_count_; // #shared + uint32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_inc_32( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true; + } + } + + void release() // nothrow + { + if( atomic_dec_32_nv( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_inc_32( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_dec_32_nv( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_sync.hpp b/thirdparty/boost/detail/sp_counted_base_sync.hpp new file mode 100644 index 0000000..41a8d6d --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_sync.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics +// +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include "sp_typeinfo.hpp" +#include + +namespace boost +{ + +namespace detail +{ + +#if INT_MAX >= 2147483647 + +typedef int sp_int32_t; + +#else + +typedef long sp_int32_t; + +#endif + +inline void atomic_increment( sp_int32_t * pw ) +{ + __sync_fetch_and_add( pw, 1 ); +} + +inline sp_int32_t atomic_decrement( sp_int32_t * pw ) +{ + return __sync_fetch_and_add( pw, -1 ); +} + +inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + sp_int32_t r = *pw; + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 ); + + if( r2 == r ) + { + return r; + } + else + { + r = r2; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + sp_int32_t use_count_; // #shared + sp_int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< sp_int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_base_w32.hpp b/thirdparty/boost/detail/sp_counted_base_w32.hpp new file mode 100644 index 0000000..d77cfba --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_base_w32.hpp @@ -0,0 +1,130 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + BOOST_INTERLOCKED_INCREMENT( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + long tmp = static_cast< long const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) + + // work around a code generation bug + + long tmp2 = tmp + 1; + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; + +#else + + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; + +#endif + } + } + + void release() // nothrow + { + if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + BOOST_INTERLOCKED_INCREMENT( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_counted_impl.hpp b/thirdparty/boost/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..c3519a3 --- /dev/null +++ b/thirdparty/boost/detail/sp_counted_impl.hpp @@ -0,0 +1,231 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_impl.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) +#include // std::allocator +#endif + +#include // std::size_t + +namespace boost +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn ); +void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); + +#endif + +namespace detail +{ + +template class sp_counted_impl_p: public sp_counted_base +{ +private: + + X * px_; + + sp_counted_impl_p( sp_counted_impl_p const & ); + sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); + + typedef sp_counted_impl_p this_type; + +public: + + explicit sp_counted_impl_p( X * px ): px_( px ) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px, sizeof(X), this ); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); +#endif + boost::checked_delete( px_ ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ) + { + return 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_impl_pd: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); + + typedef sp_counted_impl_pd this_type; + +public: + + // pre: d(p) must not throw + + sp_counted_impl_pd( P p, D d ): ptr(p), del(d) + { + } + + virtual void dispose() // nothrow + { + del( ptr ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast( del ): 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +template class sp_counted_impl_pda: public sp_counted_base +{ +private: + + P p_; // copy constructor must not throw + D d_; // copy constructor must not throw + A a_; // copy constructor must not throw + + sp_counted_impl_pda( sp_counted_impl_pda const & ); + sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); + + typedef sp_counted_impl_pda this_type; + +public: + + // pre: d( p ) must not throw + + sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a ) + { + } + + virtual void dispose() // nothrow + { + d_( p_ ); + } + + virtual void destroy() // nothrow + { + typedef typename A::template rebind< this_type >::other A2; + + A2 a2( a_ ); + + this->~this_type(); + a2.deallocate( this, 1 ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast( d_ ): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED diff --git a/thirdparty/boost/detail/sp_typeinfo.hpp b/thirdparty/boost/detail/sp_typeinfo.hpp new file mode 100644 index 0000000..1db4614 --- /dev/null +++ b/thirdparty/boost/detail/sp_typeinfo.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED +#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_typeinfo.hpp +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if defined( BOOST_NO_TYPEID ) + +namespace boost +{ + +namespace detail +{ + +typedef void* sp_typeinfo; + +template struct sp_typeid_ +{ + static char v_; +}; + +template char sp_typeid_< T >::v_; + +template struct sp_typeid_< T const >: sp_typeid_< T > +{ +}; + +template struct sp_typeid_< T volatile >: sp_typeid_< T > +{ +}; + +template struct sp_typeid_< T const volatile >: sp_typeid_< T > +{ +}; + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_::v_) + +#else + +#include + +namespace boost +{ + +namespace detail +{ + +#if defined( BOOST_NO_STD_TYPEINFO ) + +typedef ::type_info sp_typeinfo; + +#else + +typedef std::type_info sp_typeinfo; + +#endif + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) typeid(T) + +#endif + +#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED diff --git a/thirdparty/boost/detail/templated_streams.hpp b/thirdparty/boost/detail/templated_streams.hpp new file mode 100644 index 0000000..a0527fe --- /dev/null +++ b/thirdparty/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/thirdparty/boost/detail/utf8_codecvt_facet.hpp b/thirdparty/boost/detail/utf8_codecvt_facet.hpp new file mode 100644 index 0000000..e6e62c7 --- /dev/null +++ b/thirdparty/boost/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,197 @@ +// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UTF8_CODECVT_FACET_HPP +#define BOOST_UTF8_CODECVT_FACET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// utf8_codecvt_facet.hpp + +// This header defines class utf8_codecvt_facet, derived fro +// std::codecvt, which can be used to convert utf8 data in +// files into wchar_t strings in the application. +// +// The header is NOT STANDALONE, and is not to be included by the USER. +// There are at least two libraries which want to use this functionality, and +// we want to avoid code duplication. It would be possible to create utf8 +// library, but: +// - this requires review process first +// - in the case, when linking the a library which uses utf8 +// (say 'program_options'), user should also link to the utf8 library. +// This seems inconvenient, and asking a user to link to an unrevieved +// library is strange. +// Until the above points are fixed, a library which wants to use utf8 must: +// - include this header from one of it's headers or sources +// - include the corresponding .cpp file from one of the sources +// - before including either file, the library must define +// - BOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used +// - BOOST_UTF8_END_NAMESPACE to the code to close the previous namespace +// - declaration. +// - BOOST_UTF8_DECL -- to the code which must be used for all 'exportable' +// symbols. +// +// For example, program_options library might contain: +// #define BOOST_UTF8_BEGIN_NAMESPACE +// namespace boost { namespace program_options { +// #define BOOST_UTF8_END_NAMESPACE }} +// #define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL +// #include "../../detail/utf8/utf8_codecvt.cpp" +// +// Essentially, each library will have its own copy of utf8 code, in +// different namespaces. + +// Note:(Robert Ramey). I have made the following alterations in the original +// code. +// a) Rendered utf8_codecvt with using templates +// b) Move longer functions outside class definition to prevent inlining +// and make code smaller +// c) added on a derived class to permit translation to/from current +// locale to utf8 + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters +// +// utf8_codecvt_facet +// This is an implementation of a std::codecvt facet for translating +// from UTF-8 externally to UCS-4. Note that this is not tied to +// any specific types in order to allow customization on platforms +// where wchar_t is not big enough. +// +// NOTES: The current implementation jumps through some unpleasant hoops in +// order to deal with signed character types. As a std::codecvt_base::result, +// it is necessary for the ExternType to be convertible to unsigned char. +// I chose not to tie the extern_type explicitly to char. But if any combination +// of types other than is used, then std::codecvt must be +// specialized on those types for this to work. + +#include +// for mbstate_t +#include +// for std::size_t +#include + +#include +#include + +namespace std { + #if defined(__LIBCOMO__) + using ::mbstate_t; + #elif defined(BOOST_DINKUMWARE_STDLIB) && !defined(__BORLANDC__) + using ::mbstate_t; + #elif defined(__SGI_STL_PORT) + #elif defined(BOOST_NO_STDC_NAMESPACE) + using ::mbstate_t; + using ::codecvt; + #endif +} // namespace std + +#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) + #define BOOST_CODECVT_DO_LENGTH_CONST const +#else + #define BOOST_CODECVT_DO_LENGTH_CONST +#endif + +// maximum lenght of a multibyte string +#define MB_LENGTH_MAX 8 + +BOOST_UTF8_BEGIN_NAMESPACE + +struct BOOST_UTF8_DECL utf8_codecvt_facet : + public std::codecvt +{ +public: + explicit utf8_codecvt_facet(std::size_t no_locale_manage=0) + : std::codecvt(no_locale_manage) + {} +protected: + virtual std::codecvt_base::result do_in( + std::mbstate_t& state, + const char * from, + const char * from_end, + const char * & from_next, + wchar_t * to, + wchar_t * to_end, + wchar_t*& to_next + ) const; + + virtual std::codecvt_base::result do_out( + std::mbstate_t & state, const wchar_t * from, + const wchar_t * from_end, const wchar_t* & from_next, + char * to, char * to_end, char * & to_next + ) const; + + bool invalid_continuing_octet(unsigned char octet_1) const { + return (octet_1 < 0x80|| 0xbf< octet_1); + } + + bool invalid_leading_octet(unsigned char octet_1) const { + return (0x7f < octet_1 && octet_1 < 0xc0) || + (octet_1 > 0xfd); + } + + // continuing octets = octets except for the leading octet + static unsigned int get_cont_octet_count(unsigned char lead_octet) { + return get_octet_count(lead_octet) - 1; + } + + static unsigned int get_octet_count(unsigned char lead_octet); + + // How many "continuing octets" will be needed for this word + // == total octets - 1. + int get_cont_octet_out_count(wchar_t word) const ; + + virtual bool do_always_noconv() const throw() { return false; } + + // UTF-8 isn't really stateful since we rewind on partial conversions + virtual std::codecvt_base::result do_unshift( + std::mbstate_t&, + char * from, + char * /*to*/, + char * & next + ) const + { + next = from; + return ok; + } + + virtual int do_encoding() const throw() { + const int variable_byte_external_encoding=0; + return variable_byte_external_encoding; + } + + // How many char objects can I process to get <= max_limit + // wchar_t objects? + virtual int do_length( + BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &, + const char * from, + const char * from_end, + std::size_t max_limit +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + ) const throw(); +#else + ) const; +#endif + + // Largest possible value do_length(state,from,from_end,1) could return. + virtual int do_max_length() const throw () { + return 6; // largest UTF-8 encoding of a UCS-4 character + } +}; + +BOOST_UTF8_END_NAMESPACE + +#endif // BOOST_UTF8_CODECVT_FACET_HPP diff --git a/thirdparty/boost/detail/workaround.hpp b/thirdparty/boost/detail/workaround.hpp new file mode 100644 index 0000000..91df358 --- /dev/null +++ b/thirdparty/boost/detail/workaround.hpp @@ -0,0 +1,202 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef WORKAROUND_DWA2002126_HPP +# define WORKAROUND_DWA2002126_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +# ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __MSC_VER +#define __MSC_VER_WORKAROUND_GUARD 1 +#else +#define __MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif + +#ifndef _RWSTD_VER +#define _RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WORKAROUND_GUARD 0 +#endif +// Always define to zero, if it's used it'll be defined my MPL: +#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 + +# define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +# else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +# endif + +# else + +# define BOOST_WORKAROUND(symbol, test) 0 + +# endif + +#endif // WORKAROUND_DWA2002126_HPP diff --git a/thirdparty/boost/dynamic_bitset.hpp b/thirdparty/boost/dynamic_bitset.hpp new file mode 100644 index 0000000..7c8caaa --- /dev/null +++ b/thirdparty/boost/dynamic_bitset.hpp @@ -0,0 +1,21 @@ +// -------------------------------------------------- +// +// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ----------------------------------------------------------- + +// See http://www.boost.org/libs/dynamic_bitset/ for documentation. +// +// $Revision: 41369 $ $Date: 2007-11-25 13:07:19 -0500 (Sun, 25 Nov 2007) $ - $Name$ + +#ifndef BOOST_DYNAMIC_BITSET_HPP +#define BOOST_DYNAMIC_BITSET_HPP + +#include "boost/dynamic_bitset/dynamic_bitset.hpp" + +#endif // include guard diff --git a/thirdparty/boost/dynamic_bitset/config.hpp b/thirdparty/boost/dynamic_bitset/config.hpp new file mode 100644 index 0000000..f710c69 --- /dev/null +++ b/thirdparty/boost/dynamic_bitset/config.hpp @@ -0,0 +1,82 @@ +// -------------------------------------------------- +// +// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. +// (C) Copyright Gennaro Prota 2003 - 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/dynamic_bitset/ for documentation. +// +// $Revision: 41369 $ $Date: 2007-11-25 13:07:19 -0500 (Sun, 25 Nov 2007) $ - $Name$ + +#ifndef BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424 +#define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424 + +#include "boost/config.hpp" +#include "boost/detail/workaround.hpp" + +// support for pre 3.0 libstdc++ - thanks Phil Edwards! +#if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS) +# define BOOST_OLD_IOSTREAMS +#endif + +// this should be in the config system some day +// see http://lists.boost.org/MailArchives/boost/msg62291.php +#define BOOST_DYNAMIC_BITSET_GNUC_VERSION ( __GNUC__ * 100 * 100 \ + + __GNUC_MINOR__ * 100) + +// no-op function to workaround gcc bug c++/8419 +// +namespace boost { namespace detail { + template T make_non_const(T t) { return t; } +}} + +#if defined(__GNUC__) && BOOST_WORKAROUND(BOOST_DYNAMIC_BITSET_GNUC_VERSION, \ + BOOST_TESTED_AT(30300)) +# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) \ + (boost::detail::make_non_const(expr)) +#else +# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) (expr) +#endif + +// +#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \ + || (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS) +#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS +#endif + +// if we can't use friends then we simply expose private members +// +#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS) +#define BOOST_DYNAMIC_BITSET_PRIVATE public +#else +#define BOOST_DYNAMIC_BITSET_PRIVATE private +#endif + +// A couple of macros to cope with libraries without locale +// support. The first macro must be used to declare a reference +// to a ctype facet. The second one to widen a char by using +// that ctype object. If facets and locales aren't available +// the first macro is a no-op and the second one just expands +// to its parameter c. +// +#if defined (BOOST_USE_FACET) + +#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) \ + const std::ctype & name = \ + BOOST_USE_FACET(std::ctype, loc) /**/ + +#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) \ + (fac.widen(c)) +#else + +#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) /**/ +#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) c + +#endif + +#endif // include guard diff --git a/thirdparty/boost/dynamic_bitset/dynamic_bitset.hpp b/thirdparty/boost/dynamic_bitset/dynamic_bitset.hpp new file mode 100644 index 0000000..5ed390b --- /dev/null +++ b/thirdparty/boost/dynamic_bitset/dynamic_bitset.hpp @@ -0,0 +1,1731 @@ +// -------------------------------------------------- +// +// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. +// (C) Copyright Gennaro Prota 2003 - 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/dynamic_bitset/ for documentation. +// +// $Revision: 41959 $ $Date: 2007-12-10 13:51:19 -0500 (Mon, 10 Dec 2007) $ - $Name$ + + +#ifndef BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP +#define BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP + +#include +#include +#include // for std::overflow_error +#include // for std::swap, min, copy, fill +#include +#include // for CHAR_BIT + +#include "boost/dynamic_bitset/config.hpp" + +#ifndef BOOST_NO_STD_LOCALE +# include +#endif + +#if defined(BOOST_OLD_IOSTREAMS) +# include +# include // for isspace +#else +# include +# include +#endif + +#include "boost/dynamic_bitset_fwd.hpp" +#include "boost/detail/dynamic_bitset.hpp" +#include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter) +#include "boost/static_assert.hpp" +#include "boost/limits.hpp" +#include "boost/pending/lowest_bit.hpp" // used by find_first/next + + +namespace boost { + +template + +#if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // 1300 == VC++ 7.0 + // VC++ (up to 7.0) wants the default arguments again + > +# else + +# endif + +class dynamic_bitset +{ + // Portability note: member function templates are defined inside + // this class definition to avoid problems with VC++. Similarly, + // with the member functions of nested classes. + + BOOST_STATIC_ASSERT(detail::dynamic_bitset_allowed_block_type::value); + +public: + typedef Block block_type; + typedef Allocator allocator_type; + typedef std::size_t size_type; + typedef int block_width_type; + + BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits::digits)); + BOOST_STATIC_CONSTANT(size_type, npos = static_cast(-1)); + + +public: + + // A proxy class to simulate lvalues of bit type. + // + class reference + { + friend class dynamic_bitset; + + + // the one and only non-copy ctor + reference(block_type & b, int pos) + :m_block(b), m_mask(block_type(1) << pos) + { assert(pos >= 0 && pos < bits_per_block); } + + void operator&(); // left undefined + + public: + + // copy constructor: compiler generated + + operator bool() const { return (m_block & m_mask) != 0; } + bool operator~() const { return (m_block & m_mask) == 0; } + + reference& flip() { do_flip(); return *this; } + + reference& operator=(bool x) { do_assign(x); return *this; } // for b[i] = x + reference& operator=(const reference& rhs) { do_assign(rhs); return *this; } // for b[i] = b[j] + + reference& operator|=(bool x) { if (x) do_set(); return *this; } + reference& operator&=(bool x) { if (!x) do_reset(); return *this; } + reference& operator^=(bool x) { if (x) do_flip(); return *this; } + reference& operator-=(bool x) { if (x) do_reset(); return *this; } + + private: + block_type & m_block; + const block_type m_mask; + + void do_set() { m_block |= m_mask; } + void do_reset() { m_block &= ~m_mask; } + void do_flip() { m_block ^= m_mask; } + void do_assign(bool x) { x? do_set() : do_reset(); } + }; + + typedef bool const_reference; + + // constructors, etc. + explicit + dynamic_bitset(const Allocator& alloc = Allocator()); + + explicit + dynamic_bitset(size_type num_bits, unsigned long value = 0, + const Allocator& alloc = Allocator()); + + + // WARNING: you should avoid using this constructor. + // + // A conversion from string is, in most cases, formatting, + // and should be performed by using operator>>. + // + // NOTE: + // Leave the parentheses around std::basic_string::npos. + // g++ 3.2 requires them and probably the standard will - see core issue 325 + // NOTE 2: + // split into two constructors because of bugs in MSVC 6.0sp5 with STLport + + template + dynamic_bitset(const std::basic_string& s, + typename std::basic_string::size_type pos, + typename std::basic_string::size_type n, + size_type num_bits = npos, + const Allocator& alloc = Allocator()) + + :m_bits(alloc), + m_num_bits(0) + { + init_from_string(s, pos, n, num_bits); + } + + template + explicit + dynamic_bitset(const std::basic_string& s, + typename std::basic_string::size_type pos = 0) + + :m_bits(Allocator()), + m_num_bits(0) + { + init_from_string(s, pos, (std::basic_string::npos), + npos); + } + + // The first bit in *first is the least significant bit, and the + // last bit in the block just before *last is the most significant bit. + template + dynamic_bitset(BlockInputIterator first, BlockInputIterator last, + const Allocator& alloc = Allocator()) + + :m_bits(first, last, alloc), + m_num_bits(m_bits.size() * bits_per_block) + {} + + + // copy constructor + dynamic_bitset(const dynamic_bitset& b); + + ~dynamic_bitset(); + + void swap(dynamic_bitset& b); + dynamic_bitset& operator=(const dynamic_bitset& b); + + allocator_type get_allocator() const; + + // size changing operations + void resize(size_type num_bits, bool value = false); + void clear(); + void push_back(bool bit); + void append(Block block); + + template + void m_append(BlockInputIterator first, BlockInputIterator last, std::input_iterator_tag) + { + std::vector v(first, last); + m_append(v.begin(), v.end(), std::random_access_iterator_tag()); + } + template + void m_append(BlockInputIterator first, BlockInputIterator last, std::forward_iterator_tag) + { + assert(first != last); + block_width_type r = count_extra_bits(); + std::size_t d = boost::detail::distance(first, last); + m_bits.reserve(num_blocks() + d); + if (r == 0) { + for( ; first != last; ++first) + m_bits.push_back(*first); // could use vector<>::insert() + } + else { + m_highest_block() |= (*first << r); + do { + Block b = *first >> (bits_per_block - r); + ++first; + m_bits.push_back(b | (first==last? 0 : *first << r)); + } while (first != last); + } + m_num_bits += bits_per_block * d; + } + template + void append(BlockInputIterator first, BlockInputIterator last) // strong guarantee + { + if (first != last) { + typename detail::iterator_traits::iterator_category cat; + m_append(first, last, cat); + } + } + + + // bitset operations + dynamic_bitset& operator&=(const dynamic_bitset& b); + dynamic_bitset& operator|=(const dynamic_bitset& b); + dynamic_bitset& operator^=(const dynamic_bitset& b); + dynamic_bitset& operator-=(const dynamic_bitset& b); + dynamic_bitset& operator<<=(size_type n); + dynamic_bitset& operator>>=(size_type n); + dynamic_bitset operator<<(size_type n) const; + dynamic_bitset operator>>(size_type n) const; + + // basic bit operations + dynamic_bitset& set(size_type n, bool val = true); + dynamic_bitset& set(); + dynamic_bitset& reset(size_type n); + dynamic_bitset& reset(); + dynamic_bitset& flip(size_type n); + dynamic_bitset& flip(); + bool test(size_type n) const; + bool any() const; + bool none() const; + dynamic_bitset operator~() const; + size_type count() const; + + // subscript + reference operator[](size_type pos) { + return reference(m_bits[block_index(pos)], bit_index(pos)); + } + bool operator[](size_type pos) const { return test(pos); } + + unsigned long to_ulong() const; + + size_type size() const; + size_type num_blocks() const; + size_type max_size() const; + bool empty() const; + + bool is_subset_of(const dynamic_bitset& a) const; + bool is_proper_subset_of(const dynamic_bitset& a) const; + bool intersects(const dynamic_bitset & a) const; + + // lookup + size_type find_first() const; + size_type find_next(size_type pos) const; + + +#if !defined BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS + // lexicographical comparison + template + friend bool operator==(const dynamic_bitset& a, + const dynamic_bitset& b); + + template + friend bool operator<(const dynamic_bitset& a, + const dynamic_bitset& b); + + + template + friend void to_block_range(const dynamic_bitset& b, + BlockOutputIterator result); + + template + friend void from_block_range(BlockIterator first, BlockIterator last, + dynamic_bitset& result); + + + template + friend std::basic_istream& operator>>(std::basic_istream& is, + dynamic_bitset& b); + + template + friend void to_string_helper(const dynamic_bitset & b, stringT & s, bool dump_all); + + +#endif + + +private: + BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits::digits); + typedef std::vector buffer_type; + + void m_zero_unused_bits(); + bool m_check_invariants() const; + + size_type m_do_find_from(size_type first_block) const; + + block_width_type count_extra_bits() const { return bit_index(size()); } + static size_type block_index(size_type pos) { return pos / bits_per_block; } + static block_width_type bit_index(size_type pos) { return static_cast(pos % bits_per_block); } + static Block bit_mask(size_type pos) { return Block(1) << bit_index(pos); } + + template + void init_from_string(const std::basic_string& s, + typename std::basic_string::size_type pos, + typename std::basic_string::size_type n, + size_type num_bits) + { + assert(pos <= s.size()); + + typedef typename std::basic_string StrT; + typedef typename StrT::traits_type Tr; + + const typename StrT::size_type rlen = (std::min)(n, s.size() - pos); + const size_type sz = ( num_bits != npos? num_bits : rlen); + m_bits.resize(calc_num_blocks(sz)); + m_num_bits = sz; + + + BOOST_DYNAMIC_BITSET_CTYPE_FACET(CharT, fac, std::locale()); + const CharT one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); + + const size_type m = num_bits < rlen ? num_bits : rlen; + typename StrT::size_type i = 0; + for( ; i < m; ++i) { + + const CharT c = s[(pos + m - 1) - i]; + + assert( Tr::eq(c, one) + || Tr::eq(c, BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0')) ); + + if (Tr::eq(c, one)) + set(i); + + } + + } + +BOOST_DYNAMIC_BITSET_PRIVATE: + + bool m_unchecked_test(size_type pos) const; + static size_type calc_num_blocks(size_type num_bits); + + Block& m_highest_block(); + const Block& m_highest_block() const; + + buffer_type m_bits; + size_type m_num_bits; + + + class bit_appender; + friend class bit_appender; + class bit_appender { + // helper for stream >> + // Supplies to the lack of an efficient append at the less + // significant end: bits are actually appended "at left" but + // rearranged in the destructor. From the perspective of + // client code everything works *as if* dynamic_bitset<> had + // an append_at_right() function (eventually throwing the same + // exceptions as push_back) except that the function is in fact + // called bit_appender::do_append(). + // + dynamic_bitset & bs; + size_type n; + Block mask; + Block * current; + public: + bit_appender(dynamic_bitset & r) : bs(r), n(0), mask(0), current(0) {} + ~bit_appender() { + // reverse the order of blocks, shift + // if needed, and then resize + // + std::reverse(bs.m_bits.begin(), bs.m_bits.end()); + const block_width_type offs = bit_index(n); + if (offs) + bs >>= (bits_per_block - offs); + bs.resize(n); // doesn't enlarge, so can't throw + assert(bs.m_check_invariants()); + } + inline void do_append(bool value) { + + if (mask == 0) { + bs.append(Block(0)); + current = &bs.m_highest_block(); + mask = Block(1) << (bits_per_block - 1); + } + + if(value) + *current |= mask; + + mask /= 2; + ++n; + } + size_type get_count() const { return n; } + }; + +}; + +#if defined(__IBMCPP__) && BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + +// Workaround for IBM's AIX platform. +// See http://comments.gmane.org/gmane.comp.lib.boost.user/15331 +// +// NOTE: +// The compiler is actually right, until core issue 454 will be settled: +// http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#454 +// +// It's arguable whether we want to mark this with BOOST_WORKAROUND or not. + + +template +dynamic_bitset::block_width_type const +dynamic_bitset::bits_per_block; + +template +dynamic_bitset::block_width_type const +dynamic_bitset::ulong_width; + +#endif + +// Global Functions: + +// comparison +template +bool operator!=(const dynamic_bitset& a, + const dynamic_bitset& b); + +template +bool operator<=(const dynamic_bitset& a, + const dynamic_bitset& b); + +template +bool operator>(const dynamic_bitset& a, + const dynamic_bitset& b); + +template +bool operator>=(const dynamic_bitset& a, + const dynamic_bitset& b); + +// stream operators +#ifdef BOOST_OLD_IOSTREAMS +template +std::ostream& operator<<(std::ostream& os, + const dynamic_bitset& b); + +template +std::istream& operator>>(std::istream& is, dynamic_bitset& b); +#else +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const dynamic_bitset& b); + +template +std::basic_istream& +operator>>(std::basic_istream& is, + dynamic_bitset& b); +#endif + +// bitset operations +template +dynamic_bitset +operator&(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +template +dynamic_bitset +operator|(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +template +dynamic_bitset +operator^(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +template +dynamic_bitset +operator-(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +// namespace scope swap +template +void swap(dynamic_bitset& b1, + dynamic_bitset& b2); + + +template +void +to_string(const dynamic_bitset& b, stringT & s); + +template +void +to_block_range(const dynamic_bitset& b, + BlockOutputIterator result); + + +template +inline void +from_block_range(BlockIterator first, BlockIterator last, + dynamic_bitset& result) +{ + // PRE: distance(first, last) <= numblocks() + std::copy (first, last, result.m_bits.begin()); +} + +//============================================================================= +// dynamic_bitset implementation + + +//----------------------------------------------------------------------------- +// constructors, etc. + +template +dynamic_bitset::dynamic_bitset(const Allocator& alloc) + : m_bits(alloc), m_num_bits(0) +{ + +} + +template +dynamic_bitset:: +dynamic_bitset(size_type num_bits, unsigned long value, const Allocator& alloc) + : m_bits(calc_num_blocks(num_bits), Block(0), alloc), + m_num_bits(num_bits) +{ + + typedef unsigned long num_type; + typedef boost::detail::shifter shifter; + + //if (num_bits == 0) + // return; + + // zero out all bits at pos >= num_bits, if any; + // note that: num_bits == 0 implies value == 0 + if (num_bits < static_cast(ulong_width)) { + const num_type mask = (num_type(1) << num_bits) - 1; + value &= mask; + } + + typename buffer_type::iterator it = m_bits.begin(); + for( ; value; shifter::left_shift(value), ++it) { + *it = static_cast(value); + } + +} + +// copy constructor +template +inline dynamic_bitset:: +dynamic_bitset(const dynamic_bitset& b) + : m_bits(b.m_bits), m_num_bits(b.m_num_bits) +{ + +} + +template +inline dynamic_bitset:: +~dynamic_bitset() +{ + assert(m_check_invariants()); +} + +template +inline void dynamic_bitset:: +swap(dynamic_bitset& b) // no throw +{ + std::swap(m_bits, b.m_bits); + std::swap(m_num_bits, b.m_num_bits); +} + +template +dynamic_bitset& dynamic_bitset:: +operator=(const dynamic_bitset& b) +{ + m_bits = b.m_bits; + m_num_bits = b.m_num_bits; + return *this; +} + +template +inline typename dynamic_bitset::allocator_type +dynamic_bitset::get_allocator() const +{ + return m_bits.get_allocator(); +} + +//----------------------------------------------------------------------------- +// size changing operations + +template +void dynamic_bitset:: +resize(size_type num_bits, bool value) // strong guarantee +{ + + const size_type old_num_blocks = num_blocks(); + const size_type required_blocks = calc_num_blocks(num_bits); + + const block_type v = value? ~Block(0) : Block(0); + + if (required_blocks != old_num_blocks) { + m_bits.resize(required_blocks, v); // s.g. (copy) + } + + + // At this point: + // + // - if the buffer was shrunk, we have nothing more to do, + // except a call to m_zero_unused_bits() + // + // - if it was enlarged, all the (used) bits in the new blocks have + // the correct value, but we have not yet touched those bits, if + // any, that were 'unused bits' before enlarging: if value == true, + // they must be set. + + if (value && (num_bits > m_num_bits)) { + + const size_type extra_bits = count_extra_bits(); + if (extra_bits) { + assert(old_num_blocks >= 1 && old_num_blocks <= m_bits.size()); + + // Set them. + m_bits[old_num_blocks - 1] |= (v << extra_bits); + } + + } + + m_num_bits = num_bits; + m_zero_unused_bits(); + +} + +template +void dynamic_bitset:: +clear() // no throw +{ + m_bits.clear(); + m_num_bits = 0; +} + + +template +void dynamic_bitset:: +push_back(bool bit) +{ + const size_type sz = size(); + resize(sz + 1); + set(sz, bit); +} + +template +void dynamic_bitset:: +append(Block value) // strong guarantee +{ + const block_width_type r = count_extra_bits(); + + if (r == 0) { + // the buffer is empty, or all blocks are filled + m_bits.push_back(value); + } + else { + m_bits.push_back(value >> (bits_per_block - r)); + m_bits[m_bits.size() - 2] |= (value << r); // m_bits.size() >= 2 + } + + m_num_bits += bits_per_block; + assert(m_check_invariants()); + +} + + +//----------------------------------------------------------------------------- +// bitset operations +template +dynamic_bitset& +dynamic_bitset::operator&=(const dynamic_bitset& rhs) +{ + assert(size() == rhs.size()); + for (size_type i = 0; i < num_blocks(); ++i) + m_bits[i] &= rhs.m_bits[i]; + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::operator|=(const dynamic_bitset& rhs) +{ + assert(size() == rhs.size()); + for (size_type i = 0; i < num_blocks(); ++i) + m_bits[i] |= rhs.m_bits[i]; + //m_zero_unused_bits(); + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::operator^=(const dynamic_bitset& rhs) +{ + assert(size() == rhs.size()); + for (size_type i = 0; i < this->num_blocks(); ++i) + m_bits[i] ^= rhs.m_bits[i]; + //m_zero_unused_bits(); + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::operator-=(const dynamic_bitset& rhs) +{ + assert(size() == rhs.size()); + for (size_type i = 0; i < num_blocks(); ++i) + m_bits[i] &= ~rhs.m_bits[i]; + //m_zero_unused_bits(); + return *this; +} + +// +// NOTE: +// Note that the 'if (r != 0)' is crucial to avoid undefined +// behavior when the left hand operand of >> isn't promoted to a +// wider type (because rs would be too large). +// +template +dynamic_bitset& +dynamic_bitset::operator<<=(size_type n) +{ + if (n >= m_num_bits) + return reset(); + //else + if (n > 0) { + + size_type const last = num_blocks() - 1; // num_blocks() is >= 1 + size_type const div = n / bits_per_block; // div is <= last + block_width_type const r = bit_index(n); + block_type * const b = &m_bits[0]; + + if (r != 0) { + + block_width_type const rs = bits_per_block - r; + + for (size_type i = last-div; i>0; --i) { + b[i+div] = (b[i] << r) | (b[i-1] >> rs); + } + b[div] = b[0] << r; + + } + else { + for (size_type i = last-div; i>0; --i) { + b[i+div] = b[i]; + } + b[div] = b[0]; + } + + // disable std::fill_n deprecated warning in MSVC++ 8.0 (warning C4996) + // This will only work in MSVC++ 8.0 SP1, which brings up the warning + // in the line of user code; otherwise, the warning will come up + // in the line in the header itself, so if the user includes stdlib + // headers before dynamic_bitset, he will still get the warning. +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#pragma warning(push) +#pragma warning(disable:4996) +#endif + + // zero out div blocks at the less significant end + std::fill_n(b, div, static_cast(0)); + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#pragma warning(pop) +#endif + + // zero out any 1 bit that flowed into the unused part + m_zero_unused_bits(); // thanks to Lester Gong + + + } + + return *this; + + +} + + +// +// NOTE: +// see the comments to operator <<= +// +template +dynamic_bitset & dynamic_bitset::operator>>=(size_type n) { + if (n >= m_num_bits) { + return reset(); + } + //else + if (n>0) { + + size_type const last = num_blocks() - 1; // num_blocks() is >= 1 + size_type const div = n / bits_per_block; // div is <= last + block_width_type const r = bit_index(n); + block_type * const b = &m_bits[0]; + + + if (r != 0) { + + block_width_type const ls = bits_per_block - r; + + for (size_type i = div; i < last; ++i) { + b[i-div] = (b[i] >> r) | (b[i+1] << ls); + } + // r bits go to zero + b[last-div] = b[last] >> r; + } + + else { + for (size_type i = div; i <= last; ++i) { + b[i-div] = b[i]; + } + // note the '<=': the last iteration 'absorbs' + // b[last-div] = b[last] >> 0; + } + + + + // div blocks are zero filled at the most significant end + std::fill_n(b + (num_blocks()-div), div, static_cast(0)); + } + + return *this; +} + + +template +dynamic_bitset +dynamic_bitset::operator<<(size_type n) const +{ + dynamic_bitset r(*this); + return r <<= n; +} + +template +dynamic_bitset +dynamic_bitset::operator>>(size_type n) const +{ + dynamic_bitset r(*this); + return r >>= n; +} + + +//----------------------------------------------------------------------------- +// basic bit operations + +template +dynamic_bitset& +dynamic_bitset::set(size_type pos, bool val) +{ + assert(pos < m_num_bits); + + if (val) + m_bits[block_index(pos)] |= bit_mask(pos); + else + reset(pos); + + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::set() +{ + std::fill(m_bits.begin(), m_bits.end(), ~Block(0)); + m_zero_unused_bits(); + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::reset(size_type pos) +{ + assert(pos < m_num_bits); +#if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x + // CodeWarrior 8 generates incorrect code when the &=~ is compiled, + // use the |^ variation instead.. + m_bits[block_index(pos)] |= bit_mask(pos); + m_bits[block_index(pos)] ^= bit_mask(pos); +#else + m_bits[block_index(pos)] &= ~bit_mask(pos); +#endif + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::reset() +{ + std::fill(m_bits.begin(), m_bits.end(), Block(0)); + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::flip(size_type pos) +{ + assert(pos < m_num_bits); + m_bits[block_index(pos)] ^= bit_mask(pos); + return *this; +} + +template +dynamic_bitset& +dynamic_bitset::flip() +{ + for (size_type i = 0; i < num_blocks(); ++i) + m_bits[i] = ~m_bits[i]; + m_zero_unused_bits(); + return *this; +} + +template +bool dynamic_bitset::m_unchecked_test(size_type pos) const +{ + return (m_bits[block_index(pos)] & bit_mask(pos)) != 0; +} + +template +bool dynamic_bitset::test(size_type pos) const +{ + assert(pos < m_num_bits); + return m_unchecked_test(pos); +} + +template +bool dynamic_bitset::any() const +{ + for (size_type i = 0; i < num_blocks(); ++i) + if (m_bits[i]) + return true; + return false; +} + +template +inline bool dynamic_bitset::none() const +{ + return !any(); +} + +template +dynamic_bitset +dynamic_bitset::operator~() const +{ + dynamic_bitset b(*this); + b.flip(); + return b; +} + + +template +typename dynamic_bitset::size_type +dynamic_bitset::count() const +{ + using namespace detail::dynamic_bitset_count_impl; + + const bool no_padding = bits_per_block == CHAR_BIT * sizeof(Block); + const bool enough_table_width = table_width >= CHAR_BIT; + + typedef mode_to_type< (no_padding && enough_table_width ? + access_by_bytes : access_by_blocks) > m; + + return do_count(m_bits.begin(), num_blocks(), Block(0), static_cast(0)); + +} + + +//----------------------------------------------------------------------------- +// conversions + + +template +void to_string_helper(const dynamic_bitset & b, stringT & s, + bool dump_all) +{ + typedef typename stringT::traits_type Tr; + typedef typename stringT::value_type Ch; + + BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, std::locale()); + const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); + const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); + + // Note that this function may access (when + // dump_all == true) bits beyond position size() - 1 + + typedef typename dynamic_bitset::size_type size_type; + + const size_type len = dump_all? + dynamic_bitset::bits_per_block * b.num_blocks(): + b.size(); + s.assign (len, zero); + + for (size_type i = 0; i < len; ++i) { + if (b.m_unchecked_test(i)) + Tr::assign(s[len - 1 - i], one); + + } + +} + + +// A comment similar to the one about the constructor from +// basic_string can be done here. Thanks to James Kanze for +// making me (Gennaro) realize this important separation of +// concerns issue, as well as many things about i18n. +// +template +inline void +to_string(const dynamic_bitset& b, stringT& s) +{ + to_string_helper(b, s, false); +} + + +// Differently from to_string this function dumps out +// every bit of the internal representation (may be +// useful for debugging purposes) +// +template +inline void +dump_to_string(const dynamic_bitset& b, stringT& s) +{ + to_string_helper(b, s, true /* =dump_all*/); +} + +template +inline void +to_block_range(const dynamic_bitset& b, + BlockOutputIterator result) +{ + // note how this copies *all* bits, including the + // unused ones in the last block (which are zero) + std::copy(b.m_bits.begin(), b.m_bits.end(), result); +} + +template +unsigned long dynamic_bitset:: +to_ulong() const +{ + + if (m_num_bits == 0) + return 0; // convention + + // Check for overflows. This may be a performance burden on very + // large bitsets but is required by the specification, sorry + if (find_next(ulong_width - 1) != npos) + throw std::overflow_error("boost::dynamic_bitset::to_ulong overflow"); + + + // Ok, from now on we can be sure there's no "on" bit + // beyond the "allowed" positions + typedef unsigned long result_type; + + /* + if find_next() did its job correctly we don't need the if + below, because all bits we care about are in the first block + + if (bits_per_block >= ulong_width) + return static_cast(m_bits[0]); + */ + + size_type last_block = block_index( + (std::min)( m_num_bits, (size_type)ulong_width ) - 1 ); + result_type result = 0; + for (size_type i = 0; i <= last_block; ++i) { + + assert((size_type)bits_per_block * i < (size_type)ulong_width); + + unsigned long piece = m_bits[i]; + result |= (piece << (bits_per_block * i)); + } + + return result; +} + + +template +inline typename dynamic_bitset::size_type +dynamic_bitset::size() const +{ + return m_num_bits; +} + +template +inline typename dynamic_bitset::size_type +dynamic_bitset::num_blocks() const +{ + return m_bits.size(); +} + +template +inline typename dynamic_bitset::size_type +dynamic_bitset::max_size() const +{ + // Semantics of vector<>::max_size() aren't very clear + // (see lib issue 197) and many library implementations + // simply return dummy values, _unrelated_ to the underlying + // allocator. + // + // Given these problems, I was tempted to not provide this + // function at all but the user could need it if he provides + // his own allocator. + // + + const size_type m = detail::vector_max_size_workaround(m_bits); + + return m <= (size_type(-1)/bits_per_block) ? + m * bits_per_block : + size_type(-1); +} + +template +inline bool dynamic_bitset::empty() const +{ + return size() == 0; +} + +template +bool dynamic_bitset:: +is_subset_of(const dynamic_bitset& a) const +{ + assert(size() == a.size()); + for (size_type i = 0; i < num_blocks(); ++i) + if (m_bits[i] & ~a.m_bits[i]) + return false; + return true; +} + +template +bool dynamic_bitset:: +is_proper_subset_of(const dynamic_bitset& a) const +{ + assert(size() == a.size()); + assert(num_blocks() == a.num_blocks()); + + bool proper = false; + for (size_type i = 0; i < num_blocks(); ++i) { + const Block & bt = m_bits[i]; + const Block & ba = a.m_bits[i]; + + if (bt & ~ba) + return false; // not a subset at all + if (ba & ~bt) + proper = true; + } + return proper; +} + +template +bool dynamic_bitset::intersects(const dynamic_bitset & b) const +{ + size_type common_blocks = num_blocks() < b.num_blocks() + ? num_blocks() : b.num_blocks(); + + for(size_type i = 0; i < common_blocks; ++i) { + if(m_bits[i] & b.m_bits[i]) + return true; + } + return false; +} + +// -------------------------------- +// lookup + + +// look for the first bit "on", starting +// from the block with index first_block +// +template +typename dynamic_bitset::size_type +dynamic_bitset::m_do_find_from(size_type first_block) const +{ + size_type i = first_block; + + // skip null blocks + while (i < num_blocks() && m_bits[i] == 0) + ++i; + + if (i >= num_blocks()) + return npos; // not found + + return i * bits_per_block + boost::lowest_bit(m_bits[i]); + +} + + +template +typename dynamic_bitset::size_type +dynamic_bitset::find_first() const +{ + return m_do_find_from(0); +} + + +template +typename dynamic_bitset::size_type +dynamic_bitset::find_next(size_type pos) const +{ + + const size_type sz = size(); + if (pos >= (sz-1) || sz == 0) + return npos; + + ++pos; + + const size_type blk = block_index(pos); + const block_width_type ind = bit_index(pos); + + // mask out bits before pos + const Block fore = m_bits[blk] & ( ~Block(0) << ind ); + + return fore? + blk * bits_per_block + lowest_bit(fore) + : + m_do_find_from(blk + 1); + +} + + + +//----------------------------------------------------------------------------- +// comparison + +template +bool operator==(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return (a.m_num_bits == b.m_num_bits) + && (a.m_bits == b.m_bits); +} + +template +inline bool operator!=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a == b); +} + +template +bool operator<(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + assert(a.size() == b.size()); + typedef typename dynamic_bitset::size_type size_type; + + //if (a.size() == 0) + // return false; + + // Since we are storing the most significant bit + // at pos == size() - 1, we need to do the comparisons in reverse. + // + for (size_type ii = a.num_blocks(); ii > 0; --ii) { + size_type i = ii-1; + if (a.m_bits[i] < b.m_bits[i]) + return true; + else if (a.m_bits[i] > b.m_bits[i]) + return false; + } + return false; +} + +template +inline bool operator<=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a > b); +} + +template +inline bool operator>(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return b < a; +} + +template +inline bool operator>=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a < b); +} + +//----------------------------------------------------------------------------- +// stream operations + +#ifdef BOOST_OLD_IOSTREAMS +template < typename Block, typename Alloc> +std::ostream& +operator<<(std::ostream& os, const dynamic_bitset& b) +{ + // NOTE: since this is aimed at "classic" iostreams, exception + // masks on the stream are not supported. The library that + // ships with gcc 2.95 has an exceptions() member function but + // nothing is actually implemented; not even the class ios::failure. + + using namespace std; + + const ios::iostate ok = ios::goodbit; + ios::iostate err = ok; + + if (os.opfx()) { + + //try + typedef typename dynamic_bitset::size_type bitsetsize_type; + + const bitsetsize_type sz = b.size(); + std::streambuf * buf = os.rdbuf(); + size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0) + || (bitsetsize_type) os.width() <= sz? 0 : os.width() - sz; + + const char fill_char = os.fill(); + const ios::fmtflags adjustfield = os.flags() & ios::adjustfield; + + // if needed fill at left; pad is decresed along the way + if (adjustfield != ios::left) { + for (; 0 < npad; --npad) + if (fill_char != buf->sputc(fill_char)) { + err |= ios::failbit; + break; + } + } + + if (err == ok) { + // output the bitset + for (bitsetsize_type i = b.size(); 0 < i; --i) { + const char dig = b.test(i-1)? '1' : '0'; + if (EOF == buf->sputc(dig)) { + err |= ios::failbit; + break; + } + } + } + + if (err == ok) { + // if needed fill at right + for (; 0 < npad; --npad) { + if (fill_char != buf->sputc(fill_char)) { + err |= ios::failbit; + break; + } + } + } + + os.osfx(); + os.width(0); + + } // if opfx + + if(err != ok) + os.setstate(err); // assume this does NOT throw + return os; + +} +#else + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const dynamic_bitset& b) +{ + + using namespace std; + + const ios_base::iostate ok = ios_base::goodbit; + ios_base::iostate err = ok; + + typename basic_ostream::sentry cerberos(os); + if (cerberos) { + + BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, os.getloc()); + const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); + const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); + + try { + + typedef typename dynamic_bitset::size_type bitsetsize_type; + typedef basic_streambuf buffer_type; + + buffer_type * buf = os.rdbuf(); + size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0) + || (bitsetsize_type) os.width() <= b.size()? 0 : os.width() - b.size(); + + const Ch fill_char = os.fill(); + const ios_base::fmtflags adjustfield = os.flags() & ios_base::adjustfield; + + // if needed fill at left; pad is decresed along the way + if (adjustfield != ios_base::left) { + for (; 0 < npad; --npad) + if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) { + err |= ios_base::failbit; + break; + } + } + + if (err == ok) { + // output the bitset + for (bitsetsize_type i = b.size(); 0 < i; --i) { + typename buffer_type::int_type + ret = buf->sputc(b.test(i-1)? one : zero); + if (Tr::eq_int_type(Tr::eof(), ret)) { + err |= ios_base::failbit; + break; + } + } + } + + if (err == ok) { + // if needed fill at right + for (; 0 < npad; --npad) { + if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) { + err |= ios_base::failbit; + break; + } + } + } + + + os.width(0); + + } catch (...) { // see std 27.6.1.1/4 + bool rethrow = false; + try { os.setstate(ios_base::failbit); } catch (...) { rethrow = true; } + + if (rethrow) + throw; + } + } + + if(err != ok) + os.setstate(err); // may throw exception + return os; + +} +#endif + + +#ifdef BOOST_OLD_IOSTREAMS + + // A sentry-like class that calls isfx in its destructor. + // "Necessary" because bit_appender::do_append may throw. + class pseudo_sentry { + std::istream & m_r; + const bool m_ok; + public: + explicit pseudo_sentry(std::istream & r) : m_r(r), m_ok(r.ipfx(0)) { } + ~pseudo_sentry() { m_r.isfx(); } + operator bool() const { return m_ok; } + }; + +template +std::istream& +operator>>(std::istream& is, dynamic_bitset& b) +{ + +// Extractor for classic IO streams (libstdc++ < 3.0) +// ----------------------------------------------------// +// It's assumed that the stream buffer functions, and +// the stream's setstate() _cannot_ throw. + + + typedef dynamic_bitset bitset_type; + typedef typename bitset_type::size_type size_type; + + std::ios::iostate err = std::ios::goodbit; + pseudo_sentry cerberos(is); // skips whitespaces + if(cerberos) { + + b.clear(); + + const std::streamsize w = is.width(); + const size_type limit = w > 0 && static_cast(w) < b.max_size() + ? w : b.max_size(); + typename bitset_type::bit_appender appender(b); + std::streambuf * buf = is.rdbuf(); + for(int c = buf->sgetc(); appender.get_count() < limit; c = buf->snextc() ) { + + if (c == EOF) { + err |= std::ios::eofbit; + break; + } + else if (char(c) != '0' && char(c) != '1') + break; // non digit character + + else { + try { + appender.do_append(char(c) == '1'); + } + catch(...) { + is.setstate(std::ios::failbit); // assume this can't throw + throw; + } + } + + } // for + } + + is.width(0); + if (b.size() == 0) + err |= std::ios::failbit; + if (err != std::ios::goodbit) + is.setstate (err); // may throw + + return is; +} + +#else // BOOST_OLD_IOSTREAMS + +template +std::basic_istream& +operator>>(std::basic_istream& is, dynamic_bitset& b) +{ + + using namespace std; + + typedef dynamic_bitset bitset_type; + typedef typename bitset_type::size_type size_type; + + const streamsize w = is.width(); + const size_type limit = 0 < w && static_cast(w) < b.max_size()? + w : b.max_size(); + + ios_base::iostate err = ios_base::goodbit; + typename basic_istream::sentry cerberos(is); // skips whitespaces + if(cerberos) { + + // in accordance with prop. resol. of lib DR 303 [last checked 4 Feb 2004] + BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, is.getloc()); + const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0'); + const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1'); + + b.clear(); + try { + typename bitset_type::bit_appender appender(b); + basic_streambuf * buf = is.rdbuf(); + typename Tr::int_type c = buf->sgetc(); + for( ; appender.get_count() < limit; c = buf->snextc() ) { + + if (Tr::eq_int_type(Tr::eof(), c)) { + err |= ios_base::eofbit; + break; + } + else { + const Ch to_c = Tr::to_char_type(c); + const bool is_one = Tr::eq(to_c, one); + + if (!is_one && !Tr::eq(to_c, zero)) + break; // non digit character + + appender.do_append(is_one); + + } + + } // for + } + catch (...) { + // catches from stream buf, or from vector: + // + // bits_stored bits have been extracted and stored, and + // either no further character is extractable or we can't + // append to the underlying vector (out of memory) + + bool rethrow = false; // see std 27.6.1.1/4 + try { is.setstate(ios_base::badbit); } + catch(...) { rethrow = true; } + + if (rethrow) + throw; + + } + } + + is.width(0); + if (b.size() == 0 /*|| !cerberos*/) + err |= ios_base::failbit; + if (err != ios_base::goodbit) + is.setstate (err); // may throw + + return is; + +} + + +#endif + + +//----------------------------------------------------------------------------- +// bitset operations + +template +dynamic_bitset +operator&(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b &= y; +} + +template +dynamic_bitset +operator|(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b |= y; +} + +template +dynamic_bitset +operator^(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b ^= y; +} + +template +dynamic_bitset +operator-(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b -= y; +} + +//----------------------------------------------------------------------------- +// namespace scope swap + +template +inline void +swap(dynamic_bitset& left, + dynamic_bitset& right) // no throw +{ + left.swap(right); +} + + +//----------------------------------------------------------------------------- +// private (on conforming compilers) member functions + + +template +inline typename dynamic_bitset::size_type +dynamic_bitset::calc_num_blocks(size_type num_bits) +{ + return num_bits / bits_per_block + + static_cast( num_bits % bits_per_block != 0 ); +} + +// gives a reference to the highest block +// +template +inline Block& dynamic_bitset::m_highest_block() +{ + return const_cast + (static_cast(this)->m_highest_block()); +} + +// gives a const-reference to the highest block +// +template +inline const Block& dynamic_bitset::m_highest_block() const +{ + assert(size() > 0 && num_blocks() > 0); + return m_bits.back(); +} + + +// If size() is not a multiple of bits_per_block +// then not all the bits in the last block are used. +// This function resets the unused bits (convenient +// for the implementation of many member functions) +// +template +inline void dynamic_bitset::m_zero_unused_bits() +{ + assert (num_blocks() == calc_num_blocks(m_num_bits)); + + // if != 0 this is the number of bits used in the last block + const block_width_type extra_bits = count_extra_bits(); + + if (extra_bits != 0) + m_highest_block() &= ~(~static_cast(0) << extra_bits); + +} + +// check class invariants +template +bool dynamic_bitset::m_check_invariants() const +{ + const block_width_type extra_bits = count_extra_bits(); + if (extra_bits > 0) { + block_type const mask = (~static_cast(0) << extra_bits); + if ((m_highest_block() & mask) != 0) + return false; + } + if (m_bits.size() > m_bits.capacity() || num_blocks() != calc_num_blocks(size())) + return false; + + return true; + +} + + +} // namespace boost + + +#undef BOOST_BITSET_CHAR + +#endif // include guard + diff --git a/thirdparty/boost/dynamic_bitset_fwd.hpp b/thirdparty/boost/dynamic_bitset_fwd.hpp new file mode 100644 index 0000000..5735876 --- /dev/null +++ b/thirdparty/boost/dynamic_bitset_fwd.hpp @@ -0,0 +1,29 @@ +// -------------------------------------------------- +// +// (C) Copyright Chuck Allison and Jeremy Siek 2001 - 2002. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ----------------------------------------------------------- + +// See http://www.boost.org/libs/dynamic_bitset/ for documentation. +// +// $Revision: 41369 $ $Date: 2007-11-25 13:07:19 -0500 (Sun, 25 Nov 2007) $ - $Name$ + +#ifndef BOOST_DYNAMIC_BITSET_FWD_HPP +#define BOOST_DYNAMIC_BITSET_FWD_HPP + +#include + +namespace boost { + +template > +class dynamic_bitset; + +} // namespace boost + +#endif // include guard diff --git a/thirdparty/boost/dynamic_property_map.hpp b/thirdparty/boost/dynamic_property_map.hpp new file mode 100644 index 0000000..021691e --- /dev/null +++ b/thirdparty/boost/dynamic_property_map.hpp @@ -0,0 +1,370 @@ +#ifndef DYNAMIC_PROPERTY_MAP_RG09302004_HPP +#define DYNAMIC_PROPERTY_MAP_RG09302004_HPP + +// Copyright 2004-5 The Trustees of Indiana University. + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// dynamic_property_map.hpp - +// Support for runtime-polymorphic property maps. This header is factored +// out of Doug Gregor's routines for reading GraphML files for use in reading +// GraphViz graph files. + +// Authors: Doug Gregor +// Ronald Garcia +// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace detail { + + // read_value - + // A wrapper around lexical_cast, which does not behave as + // desired for std::string types. + template + inline Value read_value(const std::string& value) + { return boost::lexical_cast(value); } + + template<> + inline std::string read_value(const std::string& value) + { return value; } + +} + + +// dynamic_property_map - +// This interface supports polymorphic manipulation of property maps. +class dynamic_property_map +{ +public: + virtual ~dynamic_property_map() { } + + virtual boost::any get(const any& key) = 0; + virtual std::string get_string(const any& key) = 0; + virtual void put(const any& key, const any& value) = 0; + virtual const std::type_info& key() const = 0; + virtual const std::type_info& value() const = 0; +}; + + +////////////////////////////////////////////////////////////////////// +// Property map exceptions +////////////////////////////////////////////////////////////////////// + +struct dynamic_property_exception : public std::exception { + virtual ~dynamic_property_exception() throw() {} + virtual const char* what() const throw() = 0; +}; + +struct property_not_found : public dynamic_property_exception { + std::string property; + mutable std::string statement; + property_not_found(const std::string& property) : property(property) {} + virtual ~property_not_found() throw() {} + + const char* what() const throw() { + if(statement.empty()) + statement = + std::string("Property not found: ") + property + "."; + + return statement.c_str(); + } +}; + +struct dynamic_get_failure : public dynamic_property_exception { + std::string property; + mutable std::string statement; + dynamic_get_failure(const std::string& property) : property(property) {} + virtual ~dynamic_get_failure() throw() {} + + const char* what() const throw() { + if(statement.empty()) + statement = + std::string( + "dynamic property get cannot retrieve value for property: ") + + property + "."; + + return statement.c_str(); + } +}; + +struct dynamic_const_put_error : public dynamic_property_exception { + virtual ~dynamic_const_put_error() throw() {} + + const char* what() const throw() { + return "Attempt to put a value into a const property map: "; + } +}; + + +namespace detail { + +// +// dynamic_property_map_adaptor - +// property-map adaptor to support runtime polymorphism. +template +class dynamic_property_map_adaptor : public dynamic_property_map +{ + typedef typename property_traits::key_type key_type; + typedef typename property_traits::value_type value_type; + typedef typename property_traits::category category; + + // do_put - overloaded dispatches from the put() member function. + // Attempts to "put" to a property map that does not model + // WritablePropertyMap result in a runtime exception. + + // in_value must either hold an object of value_type or a string that + // can be converted to value_type via iostreams. + void do_put(const any& in_key, const any& in_value, mpl::bool_) + { +#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95)) + using boost::put; +#endif + + key_type key = any_cast(in_key); + if (in_value.type() == typeid(value_type)) { +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) + boost::put(property_map, key, any_cast(in_value)); +#else + put(property_map, key, any_cast(in_value)); +#endif + } else { + // if in_value is an empty string, put a default constructed value_type. + std::string v = any_cast(in_value); + if (v.empty()) { +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) + boost::put(property_map, key, value_type()); +#else + put(property_map, key, value_type()); +#endif + } else { +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) + boost::put(property_map, key, detail::read_value(v)); +#else + put(property_map, key, detail::read_value(v)); +#endif + } + } + } + + void do_put(const any&, const any&, mpl::bool_) + { + throw dynamic_const_put_error(); + } + +public: + explicit dynamic_property_map_adaptor(const PropertyMap& property_map) + : property_map(property_map) { } + + virtual boost::any get(const any& key) + { +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) + return boost::get(property_map, any_cast(key)); +#else + using boost::get; + + return get(property_map, any_cast(key)); +#endif + } + + virtual std::string get_string(const any& key) + { +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) + std::ostringstream out; + out << boost::get(property_map, any_cast(key)); + return out.str(); +#else + using boost::get; + + std::ostringstream out; + out << get(property_map, any_cast(key)); + return out.str(); +#endif + } + + virtual void put(const any& in_key, const any& in_value) + { + do_put(in_key, in_value, + mpl::bool_<(is_convertible::value)>()); + } + + virtual const std::type_info& key() const { return typeid(key_type); } + virtual const std::type_info& value() const { return typeid(value_type); } + + PropertyMap& base() { return property_map; } + const PropertyMap& base() const { return property_map; } + +private: + PropertyMap property_map; +}; + +} // namespace detail + +// +// dynamic_properties - +// container for dynamic property maps +// +struct dynamic_properties +{ + typedef std::multimap + property_maps_type; + typedef boost::function3, + const std::string&, + const boost::any&, + const boost::any&> generate_fn_type; +public: + + typedef property_maps_type::iterator iterator; + typedef property_maps_type::const_iterator const_iterator; + + dynamic_properties() : generate_fn() { } + dynamic_properties(const generate_fn_type& g) : generate_fn(g) {} + + ~dynamic_properties() + { + for (property_maps_type::iterator i = property_maps.begin(); + i != property_maps.end(); ++i) { + delete i->second; + } + } + + template + dynamic_properties& + property(const std::string& name, PropertyMap property_map) + { + // Tbd: exception safety + std::auto_ptr pm( + new detail::dynamic_property_map_adaptor(property_map)); + property_maps_type::iterator i = + property_maps.insert(property_maps_type::value_type(name, 0)); + i->second = pm.release(); + + return *this; + } + + iterator begin() { return property_maps.begin(); } + const_iterator begin() const { return property_maps.begin(); } + iterator end() { return property_maps.end(); } + const_iterator end() const { return property_maps.end(); } + + iterator lower_bound(const std::string& name) + { return property_maps.lower_bound(name); } + + const_iterator lower_bound(const std::string& name) const + { return property_maps.lower_bound(name); } + + void + insert(const std::string& name, std::auto_ptr pm) + { + property_maps.insert(property_maps_type::value_type(name, pm.release())); + } + + template + std::auto_ptr + generate(const std::string& name, const Key& key, const Value& value) + { + if(!generate_fn) { + throw property_not_found(name); + } else { + return generate_fn(name,key,value); + } + } + +private: + property_maps_type property_maps; + generate_fn_type generate_fn; +}; + +template +bool +put(const std::string& name, dynamic_properties& dp, const Key& key, + const Value& value) +{ + for (dynamic_properties::iterator i = dp.lower_bound(name); + i != dp.end() && i->first == name; ++i) { + if (i->second->key() == typeid(key)) { + i->second->put(key, value); + return true; + } + } + + std::auto_ptr new_map = dp.generate(name, key, value); + if (new_map.get()) { + new_map->put(key, value); + dp.insert(name, new_map); + return true; + } else { + return false; + } +} + +#ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +template +Value +get(const std::string& name, const dynamic_properties& dp, const Key& key) +{ + for (dynamic_properties::const_iterator i = dp.lower_bound(name); + i != dp.end() && i->first == name; ++i) { + if (i->second->key() == typeid(key)) + return any_cast(i->second->get(key)); + } + + throw dynamic_get_failure(name); +} +#endif + +template +Value +get(const std::string& name, const dynamic_properties& dp, const Key& key, type) +{ + for (dynamic_properties::const_iterator i = dp.lower_bound(name); + i != dp.end() && i->first == name; ++i) { + if (i->second->key() == typeid(key)) + return any_cast(i->second->get(key)); + } + + throw dynamic_get_failure(name); +} + +template +std::string +get(const std::string& name, const dynamic_properties& dp, const Key& key) +{ + for (dynamic_properties::const_iterator i = dp.lower_bound(name); + i != dp.end() && i->first == name; ++i) { + if (i->second->key() == typeid(key)) + return i->second->get_string(key); + } + + throw dynamic_get_failure(name); +} + +// The easy way to ignore properties. +inline +std::auto_ptr +ignore_other_properties(const std::string&, + const boost::any&, + const boost::any&) { + return std::auto_ptr(0); +} + +} // namespace boost + +#endif // DYNAMIC_PROPERTY_MAP_RG09302004_HPP diff --git a/thirdparty/boost/enable_shared_from_this.hpp b/thirdparty/boost/enable_shared_from_this.hpp new file mode 100644 index 0000000..28042c8 --- /dev/null +++ b/thirdparty/boost/enable_shared_from_this.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +// +// enable_shared_from_this.hpp +// +// Copyright (c) 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +// + +#include +#include +#include +#include + +namespace boost +{ + +template class enable_shared_from_this +{ +protected: + + enable_shared_from_this() + { + } + + enable_shared_from_this(enable_shared_from_this const &) + { + } + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { + return *this; + } + + ~enable_shared_from_this() + { + } + +public: + + shared_ptr shared_from_this() + { + shared_ptr p(_internal_weak_this); + BOOST_ASSERT(p.get() == this); + return p; + } + + shared_ptr shared_from_this() const + { + shared_ptr p(_internal_weak_this); + BOOST_ASSERT(p.get() == this); + return p; + } + +// Note: No, you don't need to initialize _internal_weak_this +// +// Please read the documentation, not the code +// +// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html + + typedef T _internal_element_type; // for bcc 5.5.1 + mutable weak_ptr<_internal_element_type> _internal_weak_this; +}; + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED diff --git a/thirdparty/boost/filesystem.hpp b/thirdparty/boost/filesystem.hpp new file mode 100644 index 0000000..d89914a --- /dev/null +++ b/thirdparty/boost/filesystem.hpp @@ -0,0 +1,20 @@ +// boost/filesystem/filesystem.hpp -----------------------------------------// + +// Copyright Beman Dawes 2005 + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP +#define BOOST_FILESYSTEM_FILESYSTEM_HPP + +#include // includes path.hpp +#include + +#endif + diff --git a/thirdparty/boost/filesystem/config.hpp b/thirdparty/boost/filesystem/config.hpp new file mode 100644 index 0000000..b845cf1 --- /dev/null +++ b/thirdparty/boost/filesystem/config.hpp @@ -0,0 +1,113 @@ +// boost/filesystem/config.hpp ---------------------------------------------// + +// Copyright Beman Dawes 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 library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONFIG_HPP +#define BOOST_FILESYSTEM_CONFIG_HPP + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// ability to change namespace aids path_table.cpp ------------------------// +#ifndef BOOST_FILESYSTEM_NAMESPACE +# define BOOST_FILESYSTEM_NAMESPACE filesystem +#endif + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include +#include + +// determine platform ------------------------------------------------------// + +// BOOST_CYGWIN_PATH implies BOOST_WINDOWS_PATH and BOOST_POSIX_API + +# if defined(BOOST_CYGWIN_PATH) +# if defined(BOOST_POSIX_PATH) +# error BOOST_POSIX_PATH is invalid when BOOST_CYGWIN_PATH is defined +# endif +# if defined(BOOST_WINDOWS_API) +# error BOOST_WINDOWS_API is invalid when BOOST_CYGWIN_PATH is defined +# endif +# define BOOST_WINDOWS_PATH +# define BOOST_POSIX_API +# endif + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use + +# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) +# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined +# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define BOOST_WINDOWS_API +# else +# define BOOST_POSIX_API +# endif +# endif + +// BOOST_WINDOWS_PATH enables Windows path syntax recognition + +# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) +# define BOOST_WINDOWS_PATH +# endif + +// narrow support only for badly broken compilers or libraries -------------// + +# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) +# define BOOST_FILESYSTEM_NARROW_ONLY +# endif + +// enable dynamic linking on Windows ---------------------------------------// + +# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__) +# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead +# endif + +#ifdef BOOST_HAS_DECLSPEC // defined in config system +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_FILESYSTEM_SOURCE +# define BOOST_FILESYSTEM_DECL __declspec(dllexport) +#else +# define BOOST_FILESYSTEM_DECL __declspec(dllimport) +#endif // BOOST_FILESYSTEM_SOURCE +#endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_FILESYSTEM_DECL isn't defined yet define it now: +#ifndef BOOST_FILESYSTEM_DECL +#define BOOST_FILESYSTEM_DECL +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_filesystem +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // BOOST_FILESYSTEM_CONFIG_HPP diff --git a/thirdparty/boost/filesystem/convenience.hpp b/thirdparty/boost/filesystem/convenience.hpp new file mode 100644 index 0000000..bad9f92 --- /dev/null +++ b/thirdparty/boost/filesystem/convenience.hpp @@ -0,0 +1,286 @@ +// boost/filesystem/convenience.hpp ----------------------------------------// + +// Copyright Beman Dawes, 2002-2005 +// Copyright Vladimir Prus, 2002 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP +#define BOOST_FILESYSTEM_CONVENIENCE_HPP + +#include +#include +#include +#include + +#include // must be the last #include + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template typename boost::enable_if, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type) +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem::path Path; +# define BOOST_FS_FUNC_STRING inline std::string +# define BOOST_FS_TYPENAME +# endif + +namespace boost +{ + namespace filesystem + { + + BOOST_FS_FUNC(bool) create_directories(const Path& ph) + { + if (ph.empty() || exists(ph)) + { + if ( !ph.empty() && !is_directory(ph) ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::create_directories", ph, + make_error_code( boost::system::posix::file_exists ) ) ); + return false; + } + + // First create branch, by calling ourself recursively + create_directories(ph.branch_path()); + // Now that parent's path exists, create the directory + create_directory(ph); + return true; + } + + BOOST_FS_FUNC_STRING extension(const Path& ph) + { + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type leaf = ph.leaf(); + + BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.'); + if (n != string_type::npos) + return leaf.substr(n); + else + return string_type(); + } + + BOOST_FS_FUNC_STRING basename(const Path& ph) + { + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type leaf = ph.leaf(); + BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.'); + return leaf.substr(0, n); + } + + BOOST_FS_FUNC(Path) change_extension( const Path & ph, + const BOOST_FS_TYPENAME Path::string_type & new_extension ) + { return ph.branch_path() / (basename(ph) + new_extension); } + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline bool create_directories(const path& ph) + { return create_directories(ph); } + inline bool create_directories(const wpath& ph) + { return create_directories(ph); } + + inline std::string extension(const path& ph) + { return extension(ph); } + inline std::wstring extension(const wpath& ph) + { return extension(ph); } + + inline std::string basename(const path& ph) + { return basename( ph ); } + inline std::wstring basename(const wpath& ph) + { return basename( ph ); } + + inline path change_extension( const path & ph, const std::string& new_ex ) + { return change_extension( ph, new_ex ); } + inline wpath change_extension( const wpath & ph, const std::wstring& new_ex ) + { return change_extension( ph, new_ex ); } + +# endif + + + // basic_recursive_directory_iterator helpers --------------------------// + + namespace detail + { + template< class Path > + struct recur_dir_itr_imp + { + typedef basic_directory_iterator< Path > element_type; + std::stack< element_type, std::vector< element_type > > m_stack; + int m_level; + bool m_no_push; + bool m_no_throw; + + recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {} + }; + + } // namespace detail + + // basic_recursive_directory_iterator ----------------------------------// + + template< class Path > + class basic_recursive_directory_iterator + : public boost::iterator_facade< + basic_recursive_directory_iterator, + basic_directory_entry, + boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + + basic_recursive_directory_iterator(){} // creates the "end" iterator + + explicit basic_recursive_directory_iterator( const Path & dir_path ); + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ); + + int level() const { return m_imp->m_level; } + + void pop(); + void no_push() + { + BOOST_ASSERT( m_imp.get() && "attempt to no_push() on end iterator" ); + m_imp->m_no_push = true; + } + + file_status status() const + { + BOOST_ASSERT( m_imp.get() + && "attempt to call status() on end recursive_iterator" ); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT( m_imp.get() + && "attempt to call symlink_status() on end recursive_iterator" ); + return m_imp->m_stack.top()->symlink_status(); + } + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::recur_dir_itr_imp< Path > > m_imp; + + friend class boost::iterator_core_access; + + typename boost::iterator_facade< + basic_recursive_directory_iterator, + basic_directory_entry, + boost::single_pass_traversal_tag >::reference + dereference() const + { + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); + return *m_imp->m_stack.top(); + } + + void increment(); + + bool equal( const basic_recursive_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + }; + + typedef basic_recursive_directory_iterator recursive_directory_iterator; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_recursive_directory_iterator wrecursive_directory_iterator; +# endif + + // basic_recursive_directory_iterator implementation -------------------// + + // constructors + template + basic_recursive_directory_iterator:: + basic_recursive_directory_iterator( const Path & dir_path ) + : m_imp( new detail::recur_dir_itr_imp ) + { + m_imp->m_stack.push( basic_directory_iterator( dir_path ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator() ) + { m_imp.reset (); } + } + + template + basic_recursive_directory_iterator:: + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ) + : m_imp( new detail::recur_dir_itr_imp ) + { + m_imp->m_no_throw = true; + m_imp->m_stack.push( basic_directory_iterator( dir_path, ec ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator() ) + { m_imp.reset (); } + } + + // increment + template + void basic_recursive_directory_iterator::increment() + { + BOOST_ASSERT( m_imp.get() && "increment on end iterator" ); + + static const basic_directory_iterator end_itr; + + if ( m_imp->m_no_push ) + { m_imp->m_no_push = false; } + else if ( is_directory( m_imp->m_stack.top()->status() ) ) + { + system::error_code ec; + m_imp->m_stack.push( + m_imp->m_no_throw + ? basic_directory_iterator( *m_imp->m_stack.top(), ec ) + : basic_directory_iterator( *m_imp->m_stack.top() ) ); + if ( m_imp->m_stack.top() != end_itr ) + { + ++m_imp->m_level; + return; + } + m_imp->m_stack.pop(); + } + + while ( !m_imp->m_stack.empty() + && ++m_imp->m_stack.top() == end_itr ) + { + m_imp->m_stack.pop(); + --m_imp->m_level; + } + + if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator + } + + // pop + template + void basic_recursive_directory_iterator::pop() + { + BOOST_ASSERT( m_imp.get() && "pop on end iterator" ); + BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" ); + + static const basic_directory_iterator end_itr; + + do + { + m_imp->m_stack.pop(); + --m_imp->m_level; + } + while ( !m_imp->m_stack.empty() + && ++m_imp->m_stack.top() == end_itr ); + + if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator + } + + } // namespace filesystem +} // namespace boost + +#undef BOOST_FS_FUNC_STRING +#undef BOOST_FS_FUNC + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP diff --git a/thirdparty/boost/filesystem/exception.hpp b/thirdparty/boost/filesystem/exception.hpp new file mode 100644 index 0000000..0d7d383 --- /dev/null +++ b/thirdparty/boost/filesystem/exception.hpp @@ -0,0 +1,9 @@ +// boost/filesystem/exception.hpp -------------------------------------------// + +// Copyright Beman Dawes 2003 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This header is no long used. The contents have been moved to path.hpp. +// It is provided so that user code #includes do not have to be changed. diff --git a/thirdparty/boost/filesystem/fstream.hpp b/thirdparty/boost/filesystem/fstream.hpp new file mode 100644 index 0000000..642f733 --- /dev/null +++ b/thirdparty/boost/filesystem/fstream.hpp @@ -0,0 +1,584 @@ +// boost/filesystem/fstream.hpp --------------------------------------------// + +// Copyright Beman Dawes 2002. +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FSTREAM_HPP +#define BOOST_FILESYSTEM_FSTREAM_HPP + +#include // for 8.3 hack (see below) +#include +#include + +#include +#include + +#include // must be the last #include + +// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for +// various compiler problems. They have been removed to ease development of the +// basic i18n functionality. Once the new interface is stable, the workarounds +// will be reinstated for any compilers that otherwise can support the rest of +// the library after internationalization. + +namespace boost +{ + namespace filesystem + { + namespace detail + { +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) +# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405 + // The 8.3 hack: + // C++98 does not supply a wchar_t open, so try to get an equivalent + // narrow char name based on the short, so-called 8.3, name. + // Not needed for Dinkumware 405 and later as they do supply wchar_t open. + BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, + std::ios_base::openmode mode ); // true if succeeds + BOOST_FILESYSTEM_DECL std::string narrow_path_api( + const std::wstring & ph ); // return is empty if fails + + inline std::string path_proxy( const std::wstring & file_ph, + std::ios_base::openmode mode ) + // Return a non-existant path if cannot supply narrow short path. + // An empty path doesn't work because some Dinkumware versions + // assert the path is non-empty. + { + std::string narrow_ph; + bool created_file( false ); + if ( !exists( file_ph ) + && (mode & std::ios_base::out) != 0 + && create_file_api( file_ph, mode ) ) + { + created_file = true; + } + narrow_ph = narrow_path_api( file_ph ); + if ( narrow_ph.empty() ) + { + if ( created_file ) remove_api( file_ph ); + narrow_ph = "\x01"; + } + return narrow_ph; + } +# else + // Dinkumware 405 and later does supply wchar_t functions + inline const std::wstring & path_proxy( const std::wstring & file_ph, + std::ios_base::openmode ) + { return file_ph; } +# endif +# endif + + inline const std::string & path_proxy( const std::string & file_ph, + std::ios_base::openmode ) + { return file_ph; } + + } // namespace detail + + template < class charT, class traits = std::char_traits > + class basic_filebuf : public std::basic_filebuf + { + private: // disallow copying + basic_filebuf( const basic_filebuf & ); + const basic_filebuf & operator=( const basic_filebuf & ); + public: + basic_filebuf() {} + virtual ~basic_filebuf() {} + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template + typename boost::enable_if, + basic_filebuf *>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + basic_filebuf * + open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + basic_filebuf * + open( const path & file_ph, std::ios_base::openmode mode ); +# endif + }; + + template < class charT, class traits = std::char_traits > + class basic_ifstream : public std::basic_ifstream + { + private: // disallow copying + basic_ifstream( const basic_ifstream & ); + const basic_ifstream & operator=( const basic_ifstream & ); + public: + basic_ifstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template + explicit basic_ifstream( const Path & file_ph, + typename boost::enable_if >::type* dummy = 0 ); + + template + basic_ifstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if >::type* dummy = 0 ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + explicit basic_ifstream( const wpath & file_ph ); + basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + + explicit basic_ifstream( const path & file_ph ); + basic_ifstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ifstream() {} + }; + + template < class charT, class traits = std::char_traits > + class basic_ofstream : public std::basic_ofstream + { + private: // disallow copying + basic_ofstream( const basic_ofstream & ); + const basic_ofstream & operator=( const basic_ofstream & ); + public: + basic_ofstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + template + explicit basic_ofstream( const Path & file_ph, + typename boost::enable_if >::type* dummy = 0 ); + explicit basic_ofstream( const wpath & file_ph ); + + template + basic_ofstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if >::type* dummy = 0 ); + basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_ofstream( const path & file_ph ); + basic_ofstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ofstream() {} + }; + + template < class charT, class traits = std::char_traits > + class basic_fstream : public std::basic_fstream + { + private: // disallow copying + basic_fstream( const basic_fstream & ); + const basic_fstream & operator=( const basic_fstream & ); + public: + basic_fstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + template + explicit basic_fstream( const Path & file_ph, + typename boost::enable_if >::type* dummy = 0 ); + explicit basic_fstream( const wpath & file_ph ); + + template + basic_fstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if >::type* dummy = 0 ); + basic_fstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template + typename boost::enable_if, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_fstream( const path & file_ph ); + basic_fstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_fstream() {} + + }; + + typedef basic_filebuf filebuf; + typedef basic_ifstream ifstream; + typedef basic_ofstream ofstream; + typedef basic_fstream fstream; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_filebuf wfilebuf; + typedef basic_ifstream wifstream; + typedef basic_fstream wfstream; + typedef basic_ofstream wofstream; +# endif + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + +// basic_filebuf definitions -----------------------------------------------// + + template + template + typename boost::enable_if, + basic_filebuf *>::type + basic_filebuf::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + return (std::basic_filebuf::open( detail::path_proxy( + file_ph.external_file_string(), mode ).c_str(), mode ) + == 0) ? 0 : this; + } + + template + basic_filebuf * + basic_filebuf::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + return this->BOOST_NESTED_TEMPLATE open( file_ph, mode ); + } + +// basic_ifstream definitions ----------------------------------------------// + + template template + basic_ifstream::basic_ifstream(const Path & file_ph, + typename boost::enable_if >::type* ) + : std::basic_ifstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template + basic_ifstream::basic_ifstream( const wpath & file_ph ) + : std::basic_ifstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template template + basic_ifstream::basic_ifstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if >::type* ) + : std::basic_ifstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ) {} + + template + basic_ifstream::basic_ifstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ) {} + + template template + typename boost::enable_if, void>::type + basic_ifstream::open( const Path & file_ph ) + { + std::basic_ifstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template + void basic_ifstream::open( const wpath & file_ph ) + { + std::basic_ifstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template template + typename boost::enable_if, void>::type + basic_ifstream::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ); + } + + template + void basic_ifstream::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ); + } + +// basic_ofstream definitions ----------------------------------------------// + + template template + basic_ofstream::basic_ofstream(const Path & file_ph, + typename boost::enable_if >::type* ) + : std::basic_ofstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template + basic_ofstream::basic_ofstream( const wpath & file_ph ) + : std::basic_ofstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template template + basic_ofstream::basic_ofstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if >::type* ) + : std::basic_ofstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ) {} + + template + basic_ofstream::basic_ofstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ) {} + + template template + typename boost::enable_if, void>::type + basic_ofstream::open( const Path & file_ph ) + { + std::basic_ofstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template + void basic_ofstream::open( const wpath & file_ph ) + { + std::basic_ofstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template template + typename boost::enable_if, void>::type + basic_ofstream::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ); + } + + template + void basic_ofstream::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ); + } + +// basic_fstream definitions -----------------------------------------------// + + template template + basic_fstream::basic_fstream(const Path & file_ph, + typename boost::enable_if >::type* ) + : std::basic_fstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template + basic_fstream::basic_fstream( const wpath & file_ph ) + : std::basic_fstream( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template template + basic_fstream::basic_fstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if >::type* ) + : std::basic_fstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} + + template + basic_fstream::basic_fstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} + + template template + typename boost::enable_if, void>::type + basic_fstream::open( const Path & file_ph ) + { + std::basic_fstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template + void basic_fstream::open( const wpath & file_ph ) + { + std::basic_fstream::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template template + typename boost::enable_if, void>::type + basic_fstream::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); + } + + template + void basic_fstream::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); + } + +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template + basic_filebuf * + basic_filebuf::open( const path & file_ph, + std::ios_base::openmode mode ) + { + return std::basic_filebuf::open( + file_ph.file_string().c_str(), mode ) == 0 ? 0 : this; + } +# endif + + template + basic_ifstream::basic_ifstream( const path & file_ph ) + : std::basic_ifstream( + file_ph.file_string().c_str(), std::ios_base::in ) {} + + template + basic_ifstream::basic_ifstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template + void basic_ifstream::open( const path & file_ph ) + { + std::basic_ifstream::open( + file_ph.file_string().c_str(), std::ios_base::in ); + } + + template + void basic_ifstream::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template + basic_ofstream::basic_ofstream( const path & file_ph ) + : std::basic_ofstream( + file_ph.file_string().c_str(), std::ios_base::out ) {} + + template + basic_ofstream::basic_ofstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template + void basic_ofstream::open( const path & file_ph ) + { + std::basic_ofstream::open( + file_ph.file_string().c_str(), std::ios_base::out ); + } + + template + void basic_ofstream::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template + basic_fstream::basic_fstream( const path & file_ph ) + : std::basic_fstream( + file_ph.file_string().c_str(), + std::ios_base::in|std::ios_base::out ) {} + + + template + basic_fstream::basic_fstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template + void basic_fstream::open( const path & file_ph ) + { + std::basic_fstream::open( + file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out ); + } + + template + void basic_fstream::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream::open( + file_ph.file_string().c_str(), mode ); + } +# endif + } // namespace filesystem +} // namespace boost + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_FSTREAM_HPP diff --git a/thirdparty/boost/filesystem/operations.hpp b/thirdparty/boost/filesystem/operations.hpp new file mode 100644 index 0000000..3ffe181 --- /dev/null +++ b/thirdparty/boost/filesystem/operations.hpp @@ -0,0 +1,1119 @@ +// boost/filesystem/operations.hpp -----------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Copyright 2002 Jan Langer +// Copyright 2001 Dietmar Kuehl +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_OPERATIONS_HPP +#define BOOST_FILESYSTEM_OPERATIONS_HPP + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include // for pair +#include + +#ifdef BOOST_WINDOWS_API +# include +# if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500 +# define BOOST_FS_HARD_LINK // Default for Windows 2K or later +# endif +#endif + +#include // must be the last #include + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::time_t; } +# endif + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template typename boost::enable_if, \ + BOOST_FS_TYPE>::type +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \ + template inline typename boost::enable_if, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem::path Path; +# define BOOST_FS_TYPENAME +# endif + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + template class basic_directory_iterator; + + // BOOST_FILESYSTEM_NARROW_ONLY needs this: + typedef basic_directory_iterator directory_iterator; + + template class basic_directory_entry; + + enum file_type + { + status_unknown, + file_not_found, + regular_file, + directory_file, + // the following will never be reported by some operating or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + type_unknown // file does exist, but isn't one of the above types or + // we don't have strong enough permission to find its type + }; + + class file_status + { + public: + explicit file_status( file_type v = status_unknown ) : m_value(v) {} + + void type( file_type v ) { m_value = v; } + file_type type() const { return m_value; } + + private: + // the internal representation is unspecified so that additional state + // information such as permissions can be added in the future; this + // implementation just uses status_type as the internal representation + + file_type m_value; + }; + + inline bool status_known( file_status f ) { return f.type() != status_unknown; } + inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; } + inline bool is_regular( file_status f ) { return f.type() == regular_file; } + inline bool is_directory( file_status f ) { return f.type() == directory_file; } + inline bool is_symlink( file_status f ) { return f.type() == symlink_file; } + inline bool is_other( file_status f ) { return exists(f) && !is_regular(f) && !is_directory(f) && !is_symlink(f); } + + struct space_info + { + // all values are byte counts + boost::uintmax_t capacity; + boost::uintmax_t free; // <= capacity + boost::uintmax_t available; // <= free + }; + + namespace detail + { + typedef std::pair< system::error_code, bool > + query_pair; + + typedef std::pair< system::error_code, boost::uintmax_t > + uintmax_pair; + + typedef std::pair< system::error_code, std::time_t > + time_pair; + + typedef std::pair< system::error_code, space_info > + space_pair; + + template< class Path > + struct directory_pair + { + typedef std::pair< system::error_code, + typename Path::external_string_type > type; + }; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DECL bool + symbolic_link_exists_api( const std::string & ); // deprecated +# endif + + BOOST_FILESYSTEM_DECL file_status + status_api( const std::string & ph, system::error_code & ec ); +# ifndef BOOST_WINDOWS_API + BOOST_FILESYSTEM_DECL file_status + symlink_status_api( const std::string & ph, system::error_code & ec ); +# endif + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::string & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::string & from, const std::string & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::string & from, const std::string & to ); + +# if defined(BOOST_WINDOWS_API) + + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::string & ph, std::string & target ); + +# if !defined(BOOST_FILESYSTEM_NARROW_ONLY) + + BOOST_FILESYSTEM_DECL boost::filesystem::file_status + status_api( const std::wstring & ph, system::error_code & ec ); + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::wstring & ph, std::wstring & target ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::wstring & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::wstring & ph ); +# ifdef BOOST_FS_HARD_LINK + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::wstring & existing_ph, + const std::wstring & new_ph ); +# endif + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::wstring & to_ph, + const std::wstring & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::wstring & from, const std::wstring & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::wstring & from, const std::wstring & to ); + +# endif +# endif + + template + unsigned long remove_all_aux( const Path & ph ); + + } // namespace detail + +// operations functions ----------------------------------------------------// + + // The non-template overloads enable automatic conversion from std and + // C-style strings. See basic_path constructors. The enable_if for the + // templates implements the famous "do-the-right-thing" rule. + +// query functions ---------------------------------------------------------// + + BOOST_INLINE_FS_FUNC(file_status) + status( const Path & ph, system::error_code & ec ) + { return detail::status_api( ph.external_file_string(), ec ); } + + BOOST_FS_FUNC(file_status) + status( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::status", ph, ec ) ); + return result; + } + + BOOST_INLINE_FS_FUNC(file_status) + symlink_status( const Path & ph, system::error_code & ec ) +# ifdef BOOST_WINDOWS_API + { return detail::status_api( ph.external_file_string(), ec ); } +# else + { return detail::symlink_status_api( ph.external_file_string(), ec ); } +# endif + + BOOST_FS_FUNC(file_status) + symlink_status( const Path & ph ) + { + system::error_code ec; + file_status result( symlink_status( ph, ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::symlink_status", ph, ec ) ); + return result; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists( const path & ph ) + { return is_symlink( symlink_status(ph) ); } +#endif + + BOOST_FS_FUNC(bool) exists( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::exists", ph, ec ) ); + return exists( result ); + } + + BOOST_FS_FUNC(bool) is_directory( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::is_directory", ph, ec ) ); + return is_directory( result ); + } + + BOOST_FS_FUNC(bool) is_regular( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::is_regular", ph, ec ) ); + return is_regular( result ); + } + + BOOST_FS_FUNC(bool) is_other( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::is_other", ph, ec ) ); + return is_other( result ); + } + + BOOST_FS_FUNC(bool) is_symlink( +# ifdef BOOST_WINDOWS_API + const Path & ) + { + return false; +# else + const Path & ph) + { + system::error_code ec; + file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::is_symlink", ph, ec ) ); + return is_symlink( result ); +# endif + } + + // VC++ 7.0 and earlier has a serious namespace bug that causes a clash + // between boost::filesystem::is_empty and the unrelated type trait + // boost::is_empty. + +# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 + BOOST_FS_FUNC(bool) is_empty( const Path & ph ) +# else + BOOST_FS_FUNC(bool) _is_empty( const Path & ph ) +# endif + { + detail::query_pair result( + detail::is_empty_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::is_empty", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 ) + { + detail::query_pair result( detail::equivalent_api( + ph1.external_file_string(), ph2.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::equivalent", ph1, ph2, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph ) + { + detail::uintmax_pair result + ( detail::file_size_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::file_size", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(space_info) space( const Path & ph ) + { + detail::space_pair result + ( detail::space_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::space", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph ) + { + detail::time_pair result + ( detail::last_write_time_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::last_write_time", ph, result.first ) ); + return result.second; + } + + +// operations --------------------------------------------------------------// + + BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph ) + { + detail::query_pair result( + detail::create_directory_api( dir_ph.external_directory_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::create_directory", + dir_ph, result.first ) ); + return result.second; + } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + BOOST_FS_FUNC(void) + create_hard_link( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::create_hard_link", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_hard_link( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } +#endif + + BOOST_FS_FUNC(void) + create_symlink( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::create_symlink", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_symlink( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } + + BOOST_FS_FUNC(bool) remove( const Path & ph ) + { + if ( exists( ph ) + || is_symlink( ph ) ) // handle dangling symbolic links + // note that the POSIX behavior for symbolic links is what we want; + // the link rather than what it points to is deleted. Windows behavior + // doesn't matter; is_symlink() is always false on Windows. + { + system::error_code ec( detail::remove_api( ph.external_file_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::remove", ph, ec ) ); + return true; + } + return false; + } + + BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph ) + { + return exists( ph )|| is_symlink( ph ) + ? detail::remove_all_aux( ph ) : 0; + } + + BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::rename_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::rename", + from_path, to_path, ec ) ); + } + + BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::copy_file_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::copy_file", + from_path, to_path, ec ) ); + } + + template< class Path > + Path current_path() + { + typename Path::external_string_type ph; + system::error_code ec( detail::get_current_path_api( ph ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::current_path", ec ) ); + return Path( Path::traits_type::to_internal( ph ) ); + } + + BOOST_FS_FUNC(void) current_path( const Path & ph ) + { + system::error_code ec( detail::set_current_path_api( + ph.external_directory_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::current_path", ph, ec ) ); + } + + template< class Path > + const Path & initial_path() + { + static Path init_path; + if ( init_path.empty() ) init_path = current_path(); + return init_path; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // legacy support + inline path current_path() // overload supports pre-i18n apps + { return current_path(); } + inline const path & initial_path() // overload supports pre-i18n apps + { return initial_path(); } +# endif + + BOOST_FS_FUNC(Path) system_complete( const Path & ph ) + { +# ifdef BOOST_WINDOWS_API + if ( ph.empty() ) return ph; + BOOST_FS_TYPENAME Path::external_string_type sys_ph; + system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(), + sys_ph ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::system_complete", ph, ec ) ); + return Path( Path::traits_type::to_internal( sys_ph ) ); +# else + return (ph.empty() || ph.is_complete()) + ? ph : current_path() / ph; +# endif + } + + BOOST_FS_FUNC(Path) + complete( const Path & ph, + const Path & base/* = initial_path() */) + { + BOOST_ASSERT( base.is_complete() + && (ph.is_complete() || !ph.has_root_name()) + && "boost::filesystem::complete() precondition not met" ); +# ifdef BOOST_WINDOWS_PATH + if (ph.empty() || ph.is_complete()) return ph; + if ( !ph.has_root_name() ) + return ph.has_root_directory() + ? Path( base.root_name() ) / ph + : base / ph; + return base / ph; +# else + return (ph.empty() || ph.is_complete()) ? ph : base / ph; +# endif + } + + // VC++ 7.1 had trouble with default arguments, so separate one argument + // signatures are provided as workarounds; the effect is the same. + BOOST_FS_FUNC(Path) complete( const Path & ph ) + { return complete( ph, initial_path() ); } + + BOOST_FS_FUNC(void) + last_write_time( const Path & ph, const std::time_t new_time ) + { + system::error_code ec( detail::last_write_time_api( ph.external_file_string(), + new_time ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::last_write_time", ph, ec ) ); + } + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline file_status status( const path & ph ) + { return status( ph ); } + inline file_status status( const wpath & ph ) + { return status( ph ); } + + inline file_status status( const path & ph, system::error_code & ec ) + { return status( ph, ec ); } + inline file_status status( const wpath & ph, system::error_code & ec ) + { return status( ph, ec ); } + + inline file_status symlink_status( const path & ph ) + { return symlink_status( ph ); } + inline file_status symlink_status( const wpath & ph ) + { return symlink_status( ph ); } + + inline file_status symlink_status( const path & ph, system::error_code & ec ) + { return symlink_status( ph, ec ); } + inline file_status symlink_status( const wpath & ph, system::error_code & ec ) + { return symlink_status( ph, ec ); } + + inline bool exists( const path & ph ) { return exists( ph ); } + inline bool exists( const wpath & ph ) { return exists( ph ); } + + inline bool is_directory( const path & ph ) + { return is_directory( ph ); } + inline bool is_directory( const wpath & ph ) + { return is_directory( ph ); } + + inline bool is_regular( const path & ph ) + { return is_regular( ph ); } + inline bool is_regular( const wpath & ph ) + { return is_regular( ph ); } + + inline bool is_other( const path & ph ) + { return is_other( ph ); } + inline bool is_other( const wpath & ph ) + { return is_other( ph ); } + + inline bool is_symlink( const path & ph ) + { return is_symlink( ph ); } + inline bool is_symlink( const wpath & ph ) + { return is_symlink( ph ); } + + inline bool is_empty( const path & ph ) + { return is_empty( ph ); } + inline bool is_empty( const wpath & ph ) + { return is_empty( ph ); } + + inline bool equivalent( const path & ph1, const path & ph2 ) + { return equivalent( ph1, ph2 ); } + inline bool equivalent( const wpath & ph1, const wpath & ph2 ) + { return equivalent( ph1, ph2 ); } + + inline boost::uintmax_t file_size( const path & ph ) + { return file_size( ph ); } + inline boost::uintmax_t file_size( const wpath & ph ) + { return file_size( ph ); } + + inline space_info space( const path & ph ) + { return space( ph ); } + inline space_info space( const wpath & ph ) + { return space( ph ); } + + inline std::time_t last_write_time( const path & ph ) + { return last_write_time( ph ); } + inline std::time_t last_write_time( const wpath & ph ) + { return last_write_time( ph ); } + + inline bool create_directory( const path & dir_ph ) + { return create_directory( dir_ph ); } + inline bool create_directory( const wpath & dir_ph ) + { return create_directory( dir_ph ); } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + inline void create_hard_link( const path & to_ph, + const path & from_ph ) + { return create_hard_link( to_ph, from_ph ); } + inline void create_hard_link( const wpath & to_ph, + const wpath & from_ph ) + { return create_hard_link( to_ph, from_ph ); } + + inline system::error_code create_hard_link( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_hard_link( to_ph, from_ph, ec ); } + inline system::error_code create_hard_link( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_hard_link( to_ph, from_ph, ec ); } +#endif + + inline void create_symlink( const path & to_ph, + const path & from_ph ) + { return create_symlink( to_ph, from_ph ); } + inline void create_symlink( const wpath & to_ph, + const wpath & from_ph ) + { return create_symlink( to_ph, from_ph ); } + + inline system::error_code create_symlink( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_symlink( to_ph, from_ph, ec ); } + inline system::error_code create_symlink( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_symlink( to_ph, from_ph, ec ); } + + inline bool remove( const path & ph ) + { return remove( ph ); } + inline bool remove( const wpath & ph ) + { return remove( ph ); } + + inline unsigned long remove_all( const path & ph ) + { return remove_all( ph ); } + inline unsigned long remove_all( const wpath & ph ) + { return remove_all( ph ); } + + inline void rename( const path & from_path, const path & to_path ) + { return rename( from_path, to_path ); } + inline void rename( const wpath & from_path, const wpath & to_path ) + { return rename( from_path, to_path ); } + + inline void copy_file( const path & from_path, const path & to_path ) + { return copy_file( from_path, to_path ); } + inline void copy_file( const wpath & from_path, const wpath & to_path ) + { return copy_file( from_path, to_path ); } + + inline path system_complete( const path & ph ) + { return system_complete( ph ); } + inline wpath system_complete( const wpath & ph ) + { return system_complete( ph ); } + + inline path complete( const path & ph, + const path & base/* = initial_path()*/ ) + { return complete( ph, base ); } + inline wpath complete( const wpath & ph, + const wpath & base/* = initial_path()*/ ) + { return complete( ph, base ); } + + inline path complete( const path & ph ) + { return complete( ph, initial_path() ); } + inline wpath complete( const wpath & ph ) + { return complete( ph, initial_path() ); } + + inline void last_write_time( const path & ph, const std::time_t new_time ) + { last_write_time( ph, new_time ); } + inline void last_write_time( const wpath & ph, const std::time_t new_time ) + { last_write_time( ph, new_time ); } + + inline void current_path( const path & ph ) + { current_path( ph ); } + inline void current_path( const wpath & ph ) + { current_path( ph ); } + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + namespace detail + { + template + unsigned long remove_all_aux( const Path & ph ) + { + static const boost::filesystem::basic_directory_iterator end_itr; + unsigned long count = 1; + if ( !boost::filesystem::is_symlink( ph ) // don't recurse symbolic links + && boost::filesystem::is_directory( ph ) ) + { + for ( boost::filesystem::basic_directory_iterator itr( ph ); + itr != end_itr; ++itr ) + { + count += remove_all_aux( itr->path() ); + } + } + boost::filesystem::remove( ph ); + return count; + } + +// test helper -------------------------------------------------------------// + + // not part of the documented interface because false positives are possible; + // there is no law that says that an OS that has large stat.st_size + // actually supports large file sizes. + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + +// directory_iterator helpers ----------------------------------------------// + +// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class +// basic_directory_iterator, and so avoid iterator_facade DLL template +// problems. They also overload to the proper external path character type. + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + const std::string & dir_path, + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_close( void *& handle +#if defined(BOOST_POSIX_API) + , void *& buffer +#endif + ); + // Effects: none if handle==0, otherwise close handle, set handle=0 + +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, const std::wstring & ph, + std::wstring & target, file_status & fs, file_status & symlink_fs ); + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, std::wstring & target, + file_status & fs, file_status & symlink_fs ); +# endif + + template< class Path > + class dir_itr_imp + { + public: + basic_directory_entry m_directory_entry; + void * m_handle; +# ifdef BOOST_POSIX_API + void * m_buffer; // see dir_itr_increment implementation +# endif + dir_itr_imp() : m_handle(0) +# ifdef BOOST_POSIX_API + , m_buffer(0) +# endif + {} + + ~dir_itr_imp() { dir_itr_close( m_handle +#if defined(BOOST_POSIX_API) + , m_buffer +#endif + ); } + }; + + BOOST_FILESYSTEM_DECL system::error_code not_found_error(); + + } // namespace detail + +// basic_directory_iterator ------------------------------------------------// + + template< class Path > + class basic_directory_iterator + : public boost::iterator_facade< + basic_directory_iterator, + basic_directory_entry, + boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + + basic_directory_iterator(){} // creates the "end" iterator + + explicit basic_directory_iterator( const Path & dir_path ); + basic_directory_iterator( const Path & dir_path, system::error_code & ec ); + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp; + + friend class boost::iterator_core_access; + + typename boost::iterator_facade< + basic_directory_iterator, + basic_directory_entry, + boost::single_pass_traversal_tag >::reference dereference() const + { + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); + return m_imp->m_directory_entry; + } + + void increment(); + + bool equal( const basic_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + system::error_code m_init( const Path & dir_path ); + }; + + typedef basic_directory_iterator< path > directory_iterator; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_directory_iterator< wpath > wdirectory_iterator; +# endif + + // basic_directory_iterator implementation ---------------------------// + + template + system::error_code basic_directory_iterator::m_init( + const Path & dir_path ) + { + if ( dir_path.empty() ) + { + m_imp.reset(); + return detail::not_found_error(); + } + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec( detail::dir_itr_first( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + dir_path.external_directory_string(), + name, fs, symlink_fs ) ); + + if ( ec ) + { + m_imp.reset(); + return ec; + } + + if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator + else // not eof + { + m_imp->m_directory_entry.assign( dir_path + / Path::traits_type::to_internal( name ), fs, symlink_fs ); + if ( name[0] == dot::value // dot or dot-dot + && (name.size() == 1 + || (name[1] == dot::value + && name.size() == 2)) ) + { increment(); } + } + return boost::system::error_code(); + } + + template + basic_directory_iterator::basic_directory_iterator( + const Path & dir_path ) + : m_imp( new detail::dir_itr_imp ) + { + system::error_code ec( m_init(dir_path) ); + if ( ec ) + { + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::basic_directory_iterator constructor", + dir_path, ec ) ); + } + } + + template + basic_directory_iterator::basic_directory_iterator( + const Path & dir_path, system::error_code & ec ) + : m_imp( new detail::dir_itr_imp ) + { + ec = m_init(dir_path); + } + + template + void basic_directory_iterator::increment() + { + BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" ); + BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" ); + + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec; + + for (;;) + { + ec = detail::dir_itr_increment( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + name, fs, symlink_fs ); + if ( ec ) + { + boost::throw_exception( basic_filesystem_error( + "boost::filesystem::basic_directory_iterator increment", + m_imp->m_directory_entry.path().branch_path(), ec ) ); + } + if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end + if ( !(name[0] == dot::value // !(dot or dot-dot) + && (name.size() == 1 + || (name[1] == dot::value + && name.size() == 2))) ) + { + m_imp->m_directory_entry.replace_leaf( + Path::traits_type::to_internal( name ), fs, symlink_fs ); + return; + } + } + } + + // basic_directory_entry -----------------------------------------------// + + template + class basic_directory_entry + { + public: + typedef Path path_type; + typedef typename Path::string_type string_type; + + // compiler generated copy-ctor, copy assignment, and destructor apply + + basic_directory_entry() {} + explicit basic_directory_entry( const path_type & p, + file_status st = file_status(), file_status symlink_st=file_status() ) + : m_path(p), m_status(st), m_symlink_status(symlink_st) + {} + + void assign( const path_type & p, + file_status st, file_status symlink_st ) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_leaf( const string_type & s, + file_status st, file_status symlink_st ) + { + m_path.remove_leaf(); + m_path /= s; + m_status = st; + m_symlink_status = symlink_st; + } + + const Path & path() const { return m_path; } + file_status status() const; + file_status status( system::error_code & ec ) const; + file_status symlink_status() const; + file_status symlink_status( system::error_code & ec ) const; + + // conversion simplifies the most common use of basic_directory_entry + operator const path_type &() const { return m_path; } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // deprecated functions preserve common use cases in legacy code + typename Path::string_type leaf() const + { + return path().leaf(); + } + typename Path::string_type string() const + { + return path().string(); + } +# endif + + private: + path_type m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + // note: m_symlink_status is not used by Windows implementation + + }; // basic_directory_status + + typedef basic_directory_entry directory_entry; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_directory_entry wdirectory_entry; +# endif + + // basic_directory_entry implementation --------------------------------// + + template + file_status + basic_directory_entry::status() const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { m_status = m_symlink_status; } + else { m_status = boost::filesystem::status( m_path ); } +# else + m_status = boost::filesystem::status( m_path ); +# endif + } + return m_status; + } + + template + file_status + basic_directory_entry::status( system::error_code & ec ) const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { ec = boost::system::error_code();; m_status = m_symlink_status; } + else { m_status = boost::filesystem::status( m_path, ec ); } +# else + m_status = boost::filesystem::status( m_path, ec ); +# endif + } + else ec = boost::system::error_code();; + return m_status; + } + + template + file_status + basic_directory_entry::symlink_status() const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem::symlink_status( m_path ); } + return m_symlink_status; +# else + return status(); +# endif + } + + template + file_status + basic_directory_entry::symlink_status( system::error_code & ec ) const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); } + else ec = boost::system::error_code();; + return m_symlink_status; +# else + return status( ec ); +# endif + } + } // namespace filesystem +} // namespace boost + +#undef BOOST_FS_FUNC + + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_OPERATIONS_HPP diff --git a/thirdparty/boost/filesystem/path.hpp b/thirdparty/boost/filesystem/path.hpp new file mode 100644 index 0000000..d57d8fb --- /dev/null +++ b/thirdparty/boost/filesystem/path.hpp @@ -0,0 +1,1432 @@ +// boost/filesystem/path.hpp -----------------------------------------------// + +// Copyright Beman Dawes 2002-2005 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_PATH_HPP +#define BOOST_FILESYSTEM_PATH_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include // for lexicographical_compare +#include // needed by basic_path inserter and extractor +#include +#include + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# include +# endif + +#include // must be the last #include + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace BOOST_FILESYSTEM_NAMESPACE + { + template class basic_path; + + struct path_traits; + typedef basic_path< std::string, path_traits > path; + + struct path_traits + { + typedef std::string internal_string_type; + typedef std::string external_string_type; + static external_string_type to_external( const path &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } + }; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + struct BOOST_FILESYSTEM_DECL wpath_traits; + + typedef basic_path< std::wstring, wpath_traits > wpath; + + struct BOOST_FILESYSTEM_DECL wpath_traits + { + typedef std::wstring internal_string_type; +# ifdef BOOST_WINDOWS_API + typedef std::wstring external_string_type; + static external_string_type to_external( const wpath &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } +# else + typedef std::string external_string_type; + static external_string_type to_external( const wpath & ph, + const internal_string_type & src ); + static internal_string_type to_internal( + const external_string_type & src ); +# endif + static void imbue( const std::locale & loc ); + static bool imbue( const std::locale & loc, const std::nothrow_t & ); + }; + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // path traits ---------------------------------------------------------// + + template struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = false ); }; + template<> struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<> struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# endif + + // these only have to be specialized if Path::string_type::value_type + // is not convertible from char + template struct slash + { BOOST_STATIC_CONSTANT( char, value = '/' ); }; + + template struct dot + { BOOST_STATIC_CONSTANT( char, value = '.' ); }; + + template struct colon + { BOOST_STATIC_CONSTANT( char, value = ':' ); }; + +# ifdef BOOST_WINDOWS_PATH + template struct path_alt_separator + { BOOST_STATIC_CONSTANT( char, value = '\\' ); }; +# endif + + // workaround for VC++ 7.0 and earlier issues with nested classes + namespace detail + { + template + class iterator_helper + { + public: + typedef typename Path::iterator iterator; + static void do_increment( iterator & ph ); + static void do_decrement( iterator & ph ); + }; + } + + // basic_path ----------------------------------------------------------// + + template + class basic_path + { + // invariant: m_path valid according to the portable generic path grammar + + // validate template arguments +// TODO: get these working +// BOOST_STATIC_ASSERT( ::boost::is_same::value ); +// BOOST_STATIC_ASSERT( ::boost::is_same::value || ::boost::is_same::value ); + + public: + // compiler generates copy constructor and copy assignment + + typedef basic_path path_type; + typedef String string_type; + typedef typename String::value_type value_type; + typedef Traits traits_type; + typedef typename Traits::external_string_type external_string_type; + + // constructors/destructor + basic_path() {} + basic_path( const string_type & s ) { operator/=( s ); } + basic_path( const value_type * s ) { operator/=( s ); } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template + basic_path( InputIterator first, InputIterator last ) + { append( first, last ); } +# endif + ~basic_path() {} + + // assignments + basic_path & operator=( const string_type & s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } + basic_path & operator=( const value_type * s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template + basic_path & assign( InputIterator first, InputIterator last ) + { m_path.clear(); append( first, last ); return *this; } +# endif + + // modifiers + basic_path & operator/=( const basic_path & rhs ) { return operator /=( rhs.string().c_str() ); } + basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); } + basic_path & operator/=( const value_type * s ); +# ifndef BOOST_NO_MEMBER_TEMPLATES + template + basic_path & append( InputIterator first, InputIterator last ); +# endif + + void swap( basic_path & rhs ) + { + m_path.swap( rhs.m_path ); +# ifdef BOOST_CYGWIN_PATH + std::swap( m_cygwin_root, rhs.m_cygwin_root ); +# endif + } + + basic_path & remove_leaf(); + + // observers + const string_type & string() const { return m_path; } + const string_type file_string() const; + const string_type directory_string() const { return file_string(); } + + const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); } + const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); } + + basic_path root_path() const; + string_type root_name() const; + string_type root_directory() const; + basic_path relative_path() const; + string_type leaf() const; + basic_path branch_path() const; + + bool empty() const { return m_path.empty(); } // name consistent with std containers + bool is_complete() const; + bool has_root_path() const; + bool has_root_name() const; + bool has_root_directory() const; + bool has_relative_path() const { return !relative_path().empty(); } + bool has_leaf() const { return !m_path.empty(); } + bool has_branch_path() const { return !branch_path().empty(); } + + // iterators + class iterator : public boost::iterator_facade< + iterator, + string_type const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::BOOST_FILESYSTEM_NAMESPACE::basic_path; + + const string_type & dereference() const + { return m_name; } + bool equal( const iterator & rhs ) const + { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } + + friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper; + + void increment() + { + boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper::do_increment( + *this ); + } + void decrement() + { + boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper::do_decrement( + *this ); + } + + string_type m_name; // current element + const basic_path * m_path_ptr; // path being iterated over + typename string_type::size_type m_pos; // position of name in + // path_ptr->string(). The + // end() iterator is indicated by + // pos == path_ptr->m_path.size() + }; // iterator + + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + private: + // Note: This is an implementation for POSIX and Windows, where there + // are only minor differences between generic and native path grammars. + // Private members might be quite different in other implementations, + // particularly where there were wide differences between portable and + // native path formats, or between file_string() and + // directory_string() formats, or simply that the implementation + // was willing expend additional memory to achieve greater speed for + // some operations at the expense of other operations. + + string_type m_path; // invariant: portable path grammar + // on Windows, backslashes converted to slashes + +# ifdef BOOST_CYGWIN_PATH + bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization + // done by append +# endif + + void m_append_separator_if_needed(); + void m_append( value_type value ); // converts Windows alt_separator + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper; + + // Deprecated features ease transition for existing code. Don't use these + // in new code. +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + public: + typedef bool (*name_check)( const std::string & name ); + basic_path( const string_type & str, name_check ) { operator/=( str ); } + basic_path( const typename string_type::value_type * s, name_check ) + { operator/=( s );} + string_type native_file_string() const { return file_string(); } + string_type native_directory_string() const { return directory_string(); } + static bool default_name_check_writable() { return false; } + static void default_name_check( name_check ) {} + static name_check default_name_check() { return 0; } + basic_path & canonize(); + basic_path & normalize(); +# endif + }; + + // basic_path non-member functions ---------------------------------------// + + template< class String, class Traits > + inline void swap( basic_path & lhs, + basic_path & rhs ) { lhs.swap( rhs ); } + + template< class String, class Traits > + bool operator<( const basic_path & lhs, const basic_path & rhs ) + { + return std::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) + { + basic_path tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path::string_type & lhs, + const basic_path & rhs ) + { + basic_path tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { + basic_path tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { + basic_path tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + inline bool operator==( const basic_path & lhs, const basic_path & rhs ) + { + return !(lhs < rhs) && !(rhs < lhs); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) + { + basic_path tmp( lhs ); + return !(tmp < rhs) && !(rhs < tmp); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path::string_type & lhs, + const basic_path & rhs ) + { + basic_path tmp( lhs ); + return !(tmp < rhs) && !(rhs < tmp); + } + + template< class String, class Traits > + inline bool operator==( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { + basic_path tmp( rhs ); + return !(lhs < tmp) && !(tmp < lhs); + } + + template< class String, class Traits > + inline bool operator==( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { + basic_path tmp( rhs ); + return !(lhs < tmp) && !(tmp < lhs); + } + + template< class String, class Traits > + inline bool operator!=( const basic_path & lhs, const basic_path & rhs ) { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) { return !(basic_path(lhs) == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path::string_type & lhs, + const basic_path & rhs ) { return !(basic_path(lhs) == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { return !(lhs == basic_path(rhs)); } + + template< class String, class Traits > + inline bool operator!=( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { return !(lhs == basic_path(rhs)); } + + template< class String, class Traits > + inline bool operator>( const basic_path & lhs, const basic_path & rhs ) { return rhs < lhs; } + + template< class String, class Traits > + inline bool operator>( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) { return rhs < basic_path(lhs); } + + template< class String, class Traits > + inline bool operator>( const typename basic_path::string_type & lhs, + const basic_path & rhs ) { return rhs < basic_path(lhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { return basic_path(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator>( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { return basic_path(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator<=( const basic_path & lhs, const basic_path & rhs ) { return !(rhs < lhs); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) { return !(rhs < basic_path(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path::string_type & lhs, + const basic_path & rhs ) { return !(rhs < basic_path(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { return !(basic_path(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator<=( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { return !(basic_path(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path & lhs, const basic_path & rhs ) { return !(lhs < rhs); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path::string_type::value_type * lhs, + const basic_path & rhs ) { return !(lhs < basic_path(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path::string_type & lhs, + const basic_path & rhs ) { return !(lhs < basic_path(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { return !(basic_path(lhs) < rhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path & lhs, + const typename basic_path::string_type & rhs ) + { return !(basic_path(lhs) < rhs); } + + // operator / + + template< class String, class Traits > + inline basic_path operator/( + const basic_path & lhs, + const basic_path & rhs ) + { return basic_path( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path operator/( + const basic_path & lhs, + const typename String::value_type * rhs ) + { return basic_path( lhs ) /= + basic_path( rhs ); } + + template< class String, class Traits > + inline basic_path operator/( + const basic_path & lhs, const String & rhs ) + { return basic_path( lhs ) /= + basic_path( rhs ); } + + template< class String, class Traits > + inline basic_path operator/( + const typename String::value_type * lhs, + const basic_path & rhs ) + { return basic_path( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path operator/( + const String & lhs, const basic_path & rhs ) + { return basic_path( lhs ) /= rhs; } + + // inserters and extractors --------------------------------------------// + +// bypass VC++ 7.0 and earlier, and broken Borland compilers +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class Path > + std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator<< + ( std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& os, const Path & ph ) + { + os << ph.string(); + return os; + } + + template< class Path > + std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator>> + ( std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& is, Path & ph ) + { + typename Path::string_type str; + is >> str; + ph = str; + return is; + } +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class String, class Traits > + std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator<< + ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type >& os, + const basic_path< String, Traits > & ph ) + { + os << ph.string(); + return os; + } + + template< class String, class Traits > + std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator>> + ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type> & is, + basic_path< String, Traits > & ph ) + { + String str; + is >> str; + ph = str; + return is; + } +# endif + + // basic_filesystem_error helpers --------------------------------------// + + // Originally choice of implementation was done via specialization of + // basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.) + // couldn't handle that, so the choice is now accomplished by overloading. + + namespace detail + { + // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure! + inline + const char * what( const char * sys_err_what, + const path & path1, const path & path2, std::string & target ) + { + try + { + if ( target.empty() ) + { + target = sys_err_what; + if ( !path1.empty() ) + { + target += ": \""; + target += path1.file_string(); + target += "\""; + } + if ( !path2.empty() ) + { + target += ", \""; + target += path2.file_string(); + target += "\""; + } + } + return target.c_str(); + } + catch (...) + { + return sys_err_what; + } + } + + template + const char * what( const char * sys_err_what, + const Path & /*path1*/, const Path & /*path2*/, std::string & /*target*/ ) + { + return sys_err_what; + } + } + + // basic_filesystem_error ----------------------------------------------// + + template + class basic_filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + public: + // compiler generates copy constructor and copy assignment + + typedef Path path_type; + + basic_filesystem_error( const std::string & what, + system::error_code ec ); + + basic_filesystem_error( const std::string & what, + const path_type & path1, system::error_code ec ); + + basic_filesystem_error( const std::string & what, const path_type & path1, + const path_type & path2, system::error_code ec ); + + ~basic_filesystem_error() throw() {} + + const path_type & path1() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; + } + const path_type & path2() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; + } + + const char * what() const throw() + { + if ( !m_imp_ptr.get() ) + return system::system_error::what(); + return detail::what( system::system_error::what(), m_imp_ptr->m_path1, + m_imp_ptr->m_path2, m_imp_ptr->m_what ); + } + + private: + struct m_imp + { + path_type m_path1; // may be empty() + path_type m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr m_imp_ptr; + }; + + typedef basic_filesystem_error filesystem_error; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_filesystem_error wfilesystem_error; +# endif + + // path::name_checks -----------------------------------------------------// + + BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool native( const std::string & name ); + inline bool no_check( const std::string & ) + { return true; } + +// implementation -----------------------------------------------------------// + + namespace detail + { + + // is_separator helper ------------------------------------------------// + + template + inline bool is_separator( typename Path::string_type::value_type c ) + { + return c == slash::value +# ifdef BOOST_WINDOWS_PATH + || c == path_alt_separator::value +# endif + ; + } + + // leaf_pos helper ----------------------------------------------------// + + template + typename String::size_type leaf_pos( + const String & str, // precondition: portable generic path grammar + typename String::size_type end_pos ) // end_pos is past-the-end position + // return 0 if str itself is leaf (or empty) + { + typedef typename + boost::BOOST_FILESYSTEM_NAMESPACE::basic_path path_type; + + // case: "//" + if ( end_pos == 2 + && str[0] == slash::value + && str[1] == slash::value ) return 0; + + // case: ends in "/" + if ( end_pos && str[end_pos-1] == slash::value ) + return end_pos-1; + + // set pos to start of last element + typename String::size_type pos( + str.find_last_of( slash::value, end_pos-1 ) ); +# ifdef BOOST_WINDOWS_PATH + if ( pos == String::npos ) + pos = str.find_last_of( path_alt_separator::value, end_pos-1 ); + if ( pos == String::npos ) + pos = str.find_last_of( colon::value, end_pos-2 ); +# endif + + return ( pos == String::npos // path itself must be a leaf (or empty) + || (pos == 1 && str[0] == slash::value) ) // or net + ? 0 // so leaf is entire string + : pos + 1; // or starts after delimiter + } + + // first_element helper -----------------------------------------------// + // sets pos and len of first element, excluding extra separators + // if src.empty(), sets pos,len, to 0,0. + + template + void first_element( + const String & src, // precondition: portable generic path grammar + typename String::size_type & element_pos, + typename String::size_type & element_size, +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1 + typename String::size_type size = String::npos +# else + typename String::size_type size = -1 +# endif + ) + { + if ( size == String::npos ) size = src.size(); + element_pos = 0; + element_size = 0; + if ( src.empty() ) return; + + typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path path_type; + + typename String::size_type cur(0); + + // deal with // [network] + if ( size >= 2 && src[0] == slash::value + && src[1] == slash::value + && (size == 2 + || src[2] != slash::value) ) + { + cur += 2; + element_size += 2; + } + + // leading (not non-network) separator + else if ( src[0] == slash::value ) + { + ++element_size; + // bypass extra leading separators + while ( cur+1 < size + && src[cur+1] == slash::value ) + { + ++cur; + ++element_pos; + } + return; + } + + // at this point, we have either a plain name, a network name, + // or (on Windows only) a device name + + // find the end + while ( cur < size +# ifdef BOOST_WINDOWS_PATH + && src[cur] != colon::value +# endif + && src[cur] != slash::value ) + { + ++cur; + ++element_size; + } + +# ifdef BOOST_WINDOWS_PATH + if ( cur == size ) return; + // include device delimiter + if ( src[cur] == colon::value ) + { ++element_size; } +# endif + + return; + } + + // root_directory_start helper ----------------------------------------// + + template + typename String::size_type root_directory_start( + const String & s, // precondition: portable generic path grammar + typename String::size_type size ) + // return npos if no root_directory found + { + typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path path_type; + +# ifdef BOOST_WINDOWS_PATH + // case "c:/" + if ( size > 2 + && s[1] == colon::value + && s[2] == slash::value ) return 2; +# endif + + // case "//" + if ( size == 2 + && s[0] == slash::value + && s[1] == slash::value ) return String::npos; + + // case "//net {/}" + if ( size > 3 + && s[0] == slash::value + && s[1] == slash::value + && s[2] != slash::value ) + { + typename String::size_type pos( + s.find( slash::value, 2 ) ); + return pos < size ? pos : String::npos; + } + + // case "/" + if ( size > 0 && s[0] == slash::value ) return 0; + + return String::npos; + } + + // is_non_root_slash helper -------------------------------------------// + + template + bool is_non_root_slash( const String & str, + typename String::size_type pos ) // pos is position of the slash + { + typedef typename + boost::BOOST_FILESYSTEM_NAMESPACE::basic_path + path_type; + + assert( !str.empty() && str[pos] == slash::value + && "precondition violation" ); + + // subsequent logic expects pos to be for leftmost slash of a set + while ( pos > 0 && str[pos-1] == slash::value ) + --pos; + + return pos != 0 + && (pos <= 2 || str[1] != slash::value + || str.find( slash::value, 2 ) != pos) +# ifdef BOOST_WINDOWS_PATH + && (pos !=2 || str[1] != colon::value) +# endif + ; + } + } // namespace detail + + // decomposition functions ----------------------------------------------// + + template + String basic_path::leaf() const + { + typename String::size_type end_pos( + detail::leaf_pos( m_path, m_path.size() ) ); + return (m_path.size() + && end_pos + && m_path[end_pos] == slash::value + && detail::is_non_root_slash< String, Traits >(m_path, end_pos)) + ? String( 1, dot::value ) + : m_path.substr( end_pos ); + } + + template + basic_path basic_path::branch_path() const + { + typename String::size_type end_pos( + detail::leaf_pos( m_path, m_path.size() ) ); + + bool leaf_was_separator( m_path.size() + && m_path[end_pos] == slash::value ); + + // skip separators unless root directory + typename string_type::size_type root_dir_pos( detail::root_directory_start + ( m_path, end_pos ) ); + for ( ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && m_path[end_pos-1] == slash::value + ; + --end_pos ) {} + + return (end_pos == 1 && root_dir_pos == 0 && leaf_was_separator) + ? path_type() + : path_type( m_path.substr( 0, end_pos ) ); + } + + template + basic_path basic_path::relative_path() const + { + iterator itr( begin() ); + for ( ; itr.m_pos != m_path.size() + && (itr.m_name[0] == slash::value +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon::value +# endif + ); ++itr ) {} + + return basic_path( m_path.substr( itr.m_pos ) ); + } + + template + String basic_path::root_name() const + { + iterator itr( begin() ); + + return ( itr.m_pos != m_path.size() + && ( + ( itr.m_name.size() > 1 + && itr.m_name[0] == slash::value + && itr.m_name[1] == slash::value + ) +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon::value +# endif + ) ) + ? *itr + : String(); + } + + template + String basic_path::root_directory() const + { + typename string_type::size_type start( + detail::root_directory_start( m_path, m_path.size() ) ); + + return start == string_type::npos + ? string_type() + : m_path.substr( start, 1 ); + } + + template + basic_path basic_path::root_path() const + { + // even on POSIX, root_name() is non-empty() on network paths + return basic_path( root_name() ) /= root_directory(); + } + + // path query functions -------------------------------------------------// + + template + inline bool basic_path::is_complete() const + { +# ifdef BOOST_WINDOWS_PATH + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + + template + inline bool basic_path::has_root_path() const + { + return !root_path().empty(); + } + + template + inline bool basic_path::has_root_name() const + { + return !root_name().empty(); + } + + template + inline bool basic_path::has_root_directory() const + { + return !root_directory().empty(); + } + + // append ---------------------------------------------------------------// + + template + void basic_path::m_append_separator_if_needed() + // requires: !empty() + { + if ( +# ifdef BOOST_WINDOWS_PATH + *(m_path.end()-1) != colon::value && +# endif + *(m_path.end()-1) != slash::value ) + { + m_path += slash::value; + } + } + + template + void basic_path::m_append( value_type value ) + { +# ifdef BOOST_CYGWIN_PATH + if ( m_path.empty() ) m_cygwin_root = (value == slash::value); +# endif + +# ifdef BOOST_WINDOWS_PATH + // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/') + m_path += ( value == path_alt_separator::value + ? slash::value + : value ); +# else + m_path += value; +# endif + } + + // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers, + // the append() member template could replace this code. + template + basic_path & basic_path::operator /= + ( const value_type * next_p ) + { + // ignore escape sequence on POSIX or Windows + if ( *next_p == slash::value + && *(next_p+1) == slash::value + && *(next_p+2) == colon::value ) next_p += 3; + + // append slash::value if needed + if ( !empty() && *next_p != 0 + && !detail::is_separator( *next_p ) ) + { m_append_separator_if_needed(); } + + for ( ; *next_p != 0; ++next_p ) m_append( *next_p ); + return *this; + } + +# ifndef BOOST_NO_MEMBER_TEMPLATES + template template + basic_path & basic_path::append( + InputIterator first, InputIterator last ) + { + // append slash::value if needed + if ( !empty() && first != last + && !detail::is_separator( *first ) ) + { m_append_separator_if_needed(); } + + // song-and-dance to avoid violating InputIterator requirements + // (which prohibit lookahead) in detecting a possible escape sequence + // (escape sequences are simply ignored on POSIX and Windows) + bool was_escape_sequence(true); + std::size_t append_count(0); + typename String::size_type initial_pos( m_path.size() ); + + for ( ; first != last && *first; ++first ) + { + if ( append_count == 0 && *first != slash::value ) + was_escape_sequence = false; + if ( append_count == 1 && *first != slash::value ) + was_escape_sequence = false; + if ( append_count == 2 && *first != colon::value ) + was_escape_sequence = false; + m_append( *first ); + ++append_count; + } + + // erase escape sequence if any + if ( was_escape_sequence && append_count >= 3 ) + m_path.erase( initial_pos, 3 ); + + return *this; + } +# endif + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + // canonize ------------------------------------------------------------// + + template + basic_path & basic_path::canonize() + { + static const typename string_type::value_type dot_str[] + = { dot::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + + for ( iterator itr( begin() ); itr != end(); ++itr ) + { + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + + // normalize ------------------------------------------------------------// + + template + basic_path & basic_path::normalize() + { + static const typename string_type::value_type dot_str[] + = { dot::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + iterator start( begin() ); + iterator last( end() ); + iterator stop( last-- ); + for ( iterator itr( start ); itr != stop; ++itr ) + { + // ignore "." except at start and last + if ( itr->size() == 1 + && (*itr)[0] == dot::value + && itr != start + && itr != last ) continue; + + // ignore a name and following ".." + if ( !temp.empty() + && itr->size() == 2 + && (*itr)[0] == dot::value + && (*itr)[1] == dot::value ) // dot dot + { + string_type lf( temp.leaf() ); + if ( lf.size() > 0 + && (lf.size() != 1 + || (lf[0] != dot::value + && lf[0] != slash::value)) + && (lf.size() != 2 + || (lf[0] != dot::value + && lf[1] != dot::value +# ifdef BOOST_WINDOWS_PATH + && lf[1] != colon::value +# endif + ) + ) + ) + { + temp.remove_leaf(); + // if not root directory, must also remove "/" if any + if ( temp.m_path.size() > 0 + && temp.m_path[temp.m_path.size()-1] + == slash::value ) + { + typename string_type::size_type rds( + detail::root_directory_start( temp.m_path, + temp.m_path.size() ) ); + if ( rds == string_type::npos + || rds != temp.m_path.size()-1 ) + { temp.m_path.erase( temp.m_path.size()-1 ); } + } + + iterator next( itr ); + if ( temp.empty() && ++next != stop + && next == last && *last == dot_str ) temp /= dot_str; + continue; + } + } + + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + +# endif + + // remove_leaf ----------------------------------------------------------// + + template + basic_path & basic_path::remove_leaf() + { + m_path.erase( + detail::leaf_pos( m_path, m_path.size() ) ); + return *this; + } + + // path conversion functions --------------------------------------------// + + template + const String + basic_path::file_string() const + { +# ifdef BOOST_WINDOWS_PATH + // for Windows, use the alternate separator, and bypass extra + // root separators + + typename string_type::size_type root_dir_start( + detail::root_directory_start( m_path, m_path.size() ) ); + bool in_root( root_dir_start != string_type::npos ); + String s; + for ( typename string_type::size_type pos( 0 ); + pos != m_path.size(); ++pos ) + { + // special case // [net] + if ( pos == 0 && m_path.size() > 1 + && m_path[0] == slash::value + && m_path[1] == slash::value + && ( m_path.size() == 2 + || !detail::is_separator( m_path[2] ) + ) ) + { + ++pos; + s += path_alt_separator::value; + s += path_alt_separator::value; + continue; + } + + // bypass extra root separators + if ( in_root ) + { + if ( s.size() > 0 + && s[s.size()-1] == path_alt_separator::value + && m_path[pos] == slash::value + ) continue; + } + + if ( m_path[pos] == slash::value ) + s += path_alt_separator::value; + else + s += m_path[pos]; + + if ( pos > root_dir_start + && m_path[pos] == slash::value ) + { in_root = false; } + } +# ifdef BOOST_CYGWIN_PATH + if ( m_cygwin_root ) s[0] = slash::value; +# endif + return s; +# else + return m_path; +# endif + } + + // iterator functions ---------------------------------------------------// + + template + typename basic_path::iterator basic_path::begin() const + { + iterator itr; + itr.m_path_ptr = this; + typename string_type::size_type element_size; + detail::first_element( m_path, itr.m_pos, element_size ); + itr.m_name = m_path.substr( itr.m_pos, element_size ); + return itr; + } + + template + typename basic_path::iterator basic_path::end() const + { + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_path.size(); + return itr; + } + + namespace detail + { + // do_increment ------------------------------------------------------// + + template + void iterator_helper::do_increment( iterator & itr ) + { + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + assert( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" ); + + bool was_net( itr.m_name.size() > 2 + && itr.m_name[0] == slash::value + && itr.m_name[1] == slash::value + && itr.m_name[2] != slash::value ); + + // increment to position past current element + itr.m_pos += itr.m_name.size(); + + // if end reached, create end iterator + if ( itr.m_pos == itr.m_path_ptr->m_path.size() ) + { + itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() + return; + } + + // process separator (Windows drive spec is only case not a separator) + if ( itr.m_path_ptr->m_path[itr.m_pos] == slash::value ) + { + // detect root directory + if ( was_net + # ifdef BOOST_WINDOWS_PATH + // case "c:/" + || itr.m_name[itr.m_name.size()-1] == colon::value + # endif + ) + { + itr.m_name = slash::value; + return; + } + + // bypass separators + while ( itr.m_pos != itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path[itr.m_pos] == slash::value ) + { ++itr.m_pos; } + + // detect trailing separator, and treat it as ".", per POSIX spec + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) ) + { + --itr.m_pos; + itr.m_name = dot::value; + return; + } + } + + // get next element + typename string_type::size_type end_pos( + itr.m_path_ptr->m_path.find( slash::value, itr.m_pos ) ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + + // do_decrement ------------------------------------------------------// + + template + void iterator_helper::do_decrement( iterator & itr ) + { + assert( itr.m_pos && "basic_path::iterator decrement past begin()" ); + + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + typename string_type::size_type end_pos( itr.m_pos ); + + typename string_type::size_type root_dir_pos( + detail::root_directory_start( + itr.m_path_ptr->m_path, end_pos ) ); + + // if at end and there was a trailing non-root '/', return "." + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path.size() > 1 + && itr.m_path_ptr->m_path[itr.m_pos-1] == slash::value + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) + ) + { + --itr.m_pos; + itr.m_name = dot::value; + return; + } + + // skip separators unless root directory + for ( + ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && itr.m_path_ptr->m_path[end_pos-1] == slash::value + ; + --end_pos ) {} + + itr.m_pos = detail::leaf_pos + ( itr.m_path_ptr->m_path, end_pos ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + } // namespace detail + + // basic_filesystem_error implementation --------------------------------// + + template + basic_filesystem_error::basic_filesystem_error( + const std::string & what, system::error_code ec ) + : system::system_error(ec, what) + { + try + { + m_imp_ptr.reset( new m_imp ); + } + catch (...) { m_imp_ptr.reset(); } + } + + template + basic_filesystem_error::basic_filesystem_error( + const std::string & what, const path_type & path1, + system::error_code ec ) + : system::system_error(ec, what) + { + try + { + m_imp_ptr.reset( new m_imp ); + m_imp_ptr->m_path1 = path1; + } + catch (...) { m_imp_ptr.reset(); } + } + + template + basic_filesystem_error::basic_filesystem_error( + const std::string & what, const path_type & path1, + const path_type & path2, system::error_code ec ) + : system::system_error(ec, what) + { + try + { + m_imp_ptr.reset( new m_imp ); + m_imp_ptr->m_path1 = path1; + m_imp_ptr->m_path2 = path2; + } + catch (...) { m_imp_ptr.reset(); } + } + + } // namespace BOOST_FILESYSTEM_NAMESPACE +} // namespace boost + +#include // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/thirdparty/boost/foreach.hpp b/thirdparty/boost/foreach.hpp new file mode 100644 index 0000000..141eb78 --- /dev/null +++ b/thirdparty/boost/foreach.hpp @@ -0,0 +1,893 @@ +/////////////////////////////////////////////////////////////////////////////// +// foreach.hpp header file +// +// Copyright 2004 Eric Niebler. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// See http://www.boost.org/libs/foreach for documentation +// +// Credits: +// Anson Tsao - for the initial inspiration and several good suggestions. +// Thorsten Ottosen - for Boost.Range, and for suggesting a way to detect +// const-qualified rvalues at compile time on VC7.1+ +// Russell Hind - For help porting to Borland +// Alisdair Meredith - For help porting to Borland +// Stefan Slapeta - For help porting to Intel +// David Jenkins - For help finding a Microsoft Code Analysis bug + +#ifndef BOOST_FOREACH + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // for std::pair + +#include +#include + +// Some compilers let us detect even const-qualified rvalues at compile-time +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1310) && !defined(_PREFAST_) \ + || (BOOST_WORKAROUND(__GNUC__, >= 4) && !defined(BOOST_INTEL)) \ + || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ >= 4) && !defined(BOOST_INTEL)) +# define BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION +#else +// Some compilers allow temporaries to be bound to non-const references. +// These compilers make it impossible to for BOOST_FOREACH to detect +// temporaries and avoid reevaluation of the collection expression. +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ + || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) \ + || BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) +# define BOOST_FOREACH_NO_RVALUE_DETECTION +# endif +// Some compilers do not correctly implement the lvalue/rvalue conversion +// rules of the ternary conditional operator. +# if defined(BOOST_FOREACH_NO_RVALUE_DETECTION) \ + || defined(BOOST_NO_SFINAE) \ + || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ + || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 810) \ + || BOOST_WORKAROUND(__GNUC__, < 3) \ + || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ <= 2)) \ + || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ <= 3) && defined(__APPLE_CC__)) \ + || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ + || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) +# define BOOST_FOREACH_NO_CONST_RVALUE_DETECTION +# else +# define BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION +# include +# include +# include +# include +#endif + +// This must be at global scope, hence the uglified name +enum boost_foreach_argument_dependent_lookup_hack +{ + boost_foreach_argument_dependent_lookup_hack_value +}; + +namespace boost +{ + +// forward declarations for iterator_range +template +class iterator_range; + +// forward declarations for sub_range +template +class sub_range; + +namespace foreach +{ + /////////////////////////////////////////////////////////////////////////////// + // in_range + // + template + inline std::pair in_range(T begin, T end) + { + return std::make_pair(begin, end); + } + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::tag + // + typedef boost_foreach_argument_dependent_lookup_hack tag; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_lightweight_proxy + // Specialize this for user-defined collection types if they are inexpensive to copy. + // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. + template + struct is_lightweight_proxy + : boost::mpl::false_ + { + }; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_noncopyable + // Specialize this for user-defined collection types if they cannot be copied. + // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. + template + struct is_noncopyable + #if !defined(BOOST_BROKEN_IS_BASE_AND_DERIVED) && !defined(BOOST_NO_IS_ABSTRACT) + : boost::mpl::or_< + boost::is_abstract + , boost::is_base_and_derived + > + #elif !defined(BOOST_BROKEN_IS_BASE_AND_DERIVED) + : boost::is_base_and_derived + #elif !defined(BOOST_NO_IS_ABSTRACT) + : boost::is_abstract + #else + : boost::mpl::false_ + #endif + { + }; + +} // namespace foreach + +} // namespace boost + +// vc6/7 needs help ordering the following overloads +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_FOREACH_TAG_DEFAULT ... +#else +# define BOOST_FOREACH_TAG_DEFAULT boost::foreach::tag +#endif + +/////////////////////////////////////////////////////////////////////////////// +// boost_foreach_is_lightweight_proxy +// Another customization point for the is_lightweight_proxy optimization, +// this one works on legacy compilers. Overload boost_foreach_is_lightweight_proxy +// at the global namespace for your type. +template +inline boost::foreach::is_lightweight_proxy * +boost_foreach_is_lightweight_proxy(T *&, BOOST_FOREACH_TAG_DEFAULT) { return 0; } + +template +inline boost::mpl::true_ * +boost_foreach_is_lightweight_proxy(std::pair *&, boost::foreach::tag) { return 0; } + +template +inline boost::mpl::true_ * +boost_foreach_is_lightweight_proxy(boost::iterator_range *&, boost::foreach::tag) { return 0; } + +template +inline boost::mpl::true_ * +boost_foreach_is_lightweight_proxy(boost::sub_range *&, boost::foreach::tag) { return 0; } + +template +inline boost::mpl::true_ * +boost_foreach_is_lightweight_proxy(T **&, boost::foreach::tag) { return 0; } + +/////////////////////////////////////////////////////////////////////////////// +// boost_foreach_is_noncopyable +// Another customization point for the is_noncopyable trait, +// this one works on legacy compilers. Overload boost_foreach_is_noncopyable +// at the global namespace for your type. +template +inline boost::foreach::is_noncopyable * +boost_foreach_is_noncopyable(T *&, BOOST_FOREACH_TAG_DEFAULT) { return 0; } + +namespace boost +{ + +namespace foreach_detail_ +{ + +/////////////////////////////////////////////////////////////////////////////// +// Define some utilities for assessing the properties of expressions +// +typedef char yes_type; +typedef char (&no_type)[2]; +yes_type is_true(boost::mpl::true_ *); +no_type is_true(boost::mpl::false_ *); + +// Extracts the desired property from the expression without evaluating it +#define BOOST_FOREACH_PROTECT(expr) \ + (static_cast *>(0)) + +template +inline boost::mpl::and_ *and_(Bool1 *, Bool2 *) { return 0; } + +template +inline boost::mpl::and_ *and_(Bool1 *, Bool2 *, Bool3 *) { return 0; } + +template +inline boost::mpl::or_ *or_(Bool1 *, Bool2 *) { return 0; } + +template +inline boost::mpl::or_ *or_(Bool1 *, Bool2 *, Bool3 *) { return 0; } + +template +inline boost::mpl::not_ *not_(Bool *) { return 0; } + +template +inline boost::mpl::false_ *is_rvalue_(T &, int) { return 0; } + +template +inline boost::mpl::true_ *is_rvalue_(T const &, ...) { return 0; } + +template +inline boost::is_array *is_array_(T const &) { return 0; } + +template +inline boost::is_const *is_const_(T &) { return 0; } + +#ifndef BOOST_FOREACH_NO_RVALUE_DETECTION +template +inline boost::mpl::true_ *is_const_(T const &) { return 0; } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// auto_any_t/auto_any +// General utility for putting an object of any type into automatic storage +struct auto_any_base +{ + // auto_any_base must evaluate to false in boolean context so that + // they can be declared in if() statements. + operator bool() const + { + return false; + } +}; + +template +struct auto_any : auto_any_base +{ + auto_any(T const &t) + : item(t) + { + } + + // temporaries of type auto_any will be bound to const auto_any_base + // references, but we still want to be able to mutate the stored + // data, so declare it as mutable. + mutable T item; +}; + +typedef auto_any_base const &auto_any_t; + +template +inline BOOST_DEDUCED_TYPENAME boost::mpl::if_::type &auto_any_cast(auto_any_t a) +{ + return static_cast const &>(a).item; +} + +typedef boost::mpl::true_ const_; + +/////////////////////////////////////////////////////////////////////////////// +// type2type +// +template +struct type2type + : boost::mpl::if_ +{ +}; + +template +struct wrap_cstr +{ + typedef T type; +}; + +template<> +struct wrap_cstr +{ + typedef wrap_cstr type; + typedef char *iterator; + typedef char *const_iterator; +}; + +template<> +struct wrap_cstr +{ + typedef wrap_cstr type; + typedef char const *iterator; + typedef char const *const_iterator; +}; + +template<> +struct wrap_cstr +{ + typedef wrap_cstr type; + typedef wchar_t *iterator; + typedef wchar_t *const_iterator; +}; + +template<> +struct wrap_cstr +{ + typedef wrap_cstr type; + typedef wchar_t const *iterator; + typedef wchar_t const *const_iterator; +}; + +template +struct is_char_array + : mpl::and_< + is_array + , mpl::or_< + is_convertible + , is_convertible + > + > +{}; + +template +struct foreach_iterator +{ + // **** READ THIS IF YOUR COMPILE BREAKS HERE **** + // + // There is an ambiguity about how to iterate over arrays of char and wchar_t. + // Should the last array element be treated as a null terminator to be skipped, or + // is it just like any other element in the array? To fix the problem, you must + // say which behavior you want. + // + // To treat the container as a null-terminated string, merely cast it to a + // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... + // + // To treat the container as an array, use boost::as_array() in , + // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... + #if BOOST_MSVC > 1300 + BOOST_MPL_ASSERT_MSG( (!is_char_array::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T) ); + #endif + + // If the type is a pointer to a null terminated string (as opposed + // to an array type), there is no ambiguity. + typedef BOOST_DEDUCED_TYPENAME wrap_cstr::type container; + + typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< + C + , range_const_iterator + , range_mutable_iterator + >::type type; +}; + +template +struct foreach_reference + : iterator_reference::type> +{ +}; + +/////////////////////////////////////////////////////////////////////////////// +// encode_type +// +template +inline type2type *encode_type(T &, boost::mpl::false_ *) { return 0; } + +template +inline type2type *encode_type(T const &, boost::mpl::true_ *) { return 0; } + +/////////////////////////////////////////////////////////////////////////////// +// set_false +// +inline bool set_false(bool &b) { return b = false; } + +/////////////////////////////////////////////////////////////////////////////// +// to_ptr +// +template +inline T *&to_ptr(T const &) +{ + static T *t = 0; + return t; +} + +// Borland needs a little extra help with arrays +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +inline T (*&to_ptr(T (&)[N]))[N] +{ + static T (*t)[N] = 0; + return t; +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// derefof +// +template +inline T &derefof(T *t) +{ + // This is a work-around for a compiler bug in Borland. If T* is a pointer to array type U(*)[N], + // then dereferencing it results in a U* instead of U(&)[N]. The cast forces the issue. + return reinterpret_cast( + *const_cast( + reinterpret_cast(t) + ) + ); +} + +#ifdef BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION +/////////////////////////////////////////////////////////////////////////////// +// Detect at compile-time whether an expression yields an rvalue or +// an lvalue. This is rather non-standard, but some popular compilers +// accept it. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// rvalue_probe +// +template +struct rvalue_probe +{ + struct private_type_ {}; + // can't ever return an array by value + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::mpl::or_, boost::is_array >, private_type_, T + >::type value_type; + operator value_type(); + operator T &() const; +}; + +template +rvalue_probe const make_probe(T const &t); + +# define BOOST_FOREACH_IS_RVALUE(COL) \ + boost::foreach_detail_::and_( \ + boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(COL)) \ + , BOOST_FOREACH_PROTECT(boost::foreach_detail_::is_rvalue_( \ + (true ? boost::foreach_detail_::make_probe(COL) : (COL)), 0))) + +#elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) +/////////////////////////////////////////////////////////////////////////////// +// Detect at run-time whether an expression yields an rvalue +// or an lvalue. This is 100% standard C++, but not all compilers +// accept it. Also, it causes FOREACH to break when used with non- +// copyable collection types. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// rvalue_probe +// +template +struct rvalue_probe +{ + rvalue_probe(T &t, bool &b) + : value(t) + , is_rvalue(b) + { + } + + struct private_type_ {}; + // can't ever return an array or an abstract type by value + #ifdef BOOST_NO_IS_ABSTRACT + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_array, private_type_, T + >::type value_type; + #else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::mpl::or_, boost::is_array >, private_type_, T + >::type value_type; + #endif + + operator value_type() + { + this->is_rvalue = true; + return this->value; + } + + operator T &() const + { + return this->value; + } + +private: + T &value; + bool &is_rvalue; +}; + +template +rvalue_probe make_probe(T &t, bool &b) { return rvalue_probe(t, b); } + +template +rvalue_probe make_probe(T const &t, bool &b) { return rvalue_probe(t, b); } + +/////////////////////////////////////////////////////////////////////////////// +// simple_variant +// holds either a T or a T const* +template +struct simple_variant +{ + simple_variant(T const *t) + : is_rvalue(false) + { + *static_cast(this->data.address()) = t; + } + + simple_variant(T const &t) + : is_rvalue(true) + { + ::new(this->data.address()) T(t); + } + + simple_variant(simple_variant const &that) + : is_rvalue(that.is_rvalue) + { + if(this->is_rvalue) + ::new(this->data.address()) T(*that.get()); + else + *static_cast(this->data.address()) = that.get(); + } + + ~simple_variant() + { + if(this->is_rvalue) + this->get()->~T(); + } + + T const *get() const + { + if(this->is_rvalue) + return static_cast(this->data.address()); + else + return *static_cast(this->data.address()); + } + +private: + enum size_type { size = sizeof(T) > sizeof(T*) ? sizeof(T) : sizeof(T*) }; + simple_variant &operator =(simple_variant const &); + bool const is_rvalue; + aligned_storage data; +}; + +// If the collection is an array or is noncopyable, it must be an lvalue. +// If the collection is a lightweight proxy, treat it as an rvalue +// BUGBUG what about a noncopyable proxy? +template +inline BOOST_DEDUCED_TYPENAME boost::enable_if, IsProxy>::type * +should_copy_impl(LValue *, IsProxy *, bool *) +{ + return 0; +} + +// Otherwise, we must determine at runtime whether it's an lvalue or rvalue +inline bool * +should_copy_impl(boost::mpl::false_ *, boost::mpl::false_ *, bool *is_rvalue) +{ + return is_rvalue; +} + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// contain +// +template +inline auto_any contain(T const &t, boost::mpl::true_ *) // rvalue +{ + return t; +} + +template +inline auto_any contain(T &t, boost::mpl::false_ *) // lvalue +{ + // Cannot seem to get sunpro to handle addressof() with array types. + #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) + return &t; + #else + return boost::addressof(t); + #endif +} + +#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION +template +auto_any > +contain(T const &t, bool *rvalue) +{ + return *rvalue ? simple_variant(t) : simple_variant(&t); +} +#endif + +///////////////////////////////////////////////////////////////////////////// +// begin +// +template +inline auto_any::type> +begin(auto_any_t col, type2type *, boost::mpl::true_ *) // rvalue +{ + return boost::begin(auto_any_cast(col)); +} + +template +inline auto_any::type> +begin(auto_any_t col, type2type *, boost::mpl::false_ *) // lvalue +{ + typedef BOOST_DEDUCED_TYPENAME type2type::type type; + typedef BOOST_DEDUCED_TYPENAME foreach_iterator::type iterator; + return iterator(boost::begin(derefof(auto_any_cast(col)))); +} + +#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION +template +auto_any::type> +begin(auto_any_t col, type2type *, bool *) +{ + return boost::begin(*auto_any_cast, boost::mpl::false_>(col).get()); +} +#endif + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +template +inline auto_any +begin(auto_any_t col, type2type *, boost::mpl::true_ *) // null-terminated C-style strings +{ + return auto_any_cast(col); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// end +// +template +inline auto_any::type> +end(auto_any_t col, type2type *, boost::mpl::true_ *) // rvalue +{ + return boost::end(auto_any_cast(col)); +} + +template +inline auto_any::type> +end(auto_any_t col, type2type *, boost::mpl::false_ *) // lvalue +{ + typedef BOOST_DEDUCED_TYPENAME type2type::type type; + typedef BOOST_DEDUCED_TYPENAME foreach_iterator::type iterator; + return iterator(boost::end(derefof(auto_any_cast(col)))); +} + +#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION +template +auto_any::type> +end(auto_any_t col, type2type *, bool *) +{ + return boost::end(*auto_any_cast, boost::mpl::false_>(col).get()); +} +#endif + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +template +inline auto_any +end(auto_any_t col, type2type *, boost::mpl::true_ *) // null-terminated C-style strings +{ + return 0; // not used +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// done +// +template +inline bool done(auto_any_t cur, auto_any_t end, type2type *) +{ + typedef BOOST_DEDUCED_TYPENAME foreach_iterator::type iter_t; + return auto_any_cast(cur) == auto_any_cast(end); +} + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +template +inline bool done(auto_any_t cur, auto_any_t, type2type *) // null-terminated C-style strings +{ + return ! *auto_any_cast(cur); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// next +// +template +inline void next(auto_any_t cur, type2type *) +{ + typedef BOOST_DEDUCED_TYPENAME foreach_iterator::type iter_t; + ++auto_any_cast(cur); +} + +/////////////////////////////////////////////////////////////////////////////// +// deref +// +template +inline BOOST_DEDUCED_TYPENAME foreach_reference::type +deref(auto_any_t cur, type2type *) +{ + typedef BOOST_DEDUCED_TYPENAME foreach_iterator::type iter_t; + return *auto_any_cast(cur); +} + +} // namespace foreach_detail_ +} // namespace boost + +// A sneaky way to get the type of the collection without evaluating the expression +#define BOOST_FOREACH_TYPEOF(COL) \ + (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::is_const_(COL))) + +// returns true_* if the type is noncopyable +#define BOOST_FOREACH_IS_NONCOPYABLE(COL) \ + boost_foreach_is_noncopyable( \ + boost::foreach_detail_::to_ptr(COL) \ + , boost_foreach_argument_dependent_lookup_hack_value) + +// returns true_* if the type is a lightweight proxy (and is not noncopyable) +#define BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL) \ + boost::foreach_detail_::and_( \ + boost::foreach_detail_::not_(BOOST_FOREACH_IS_NONCOPYABLE(COL)) \ + , boost_foreach_is_lightweight_proxy( \ + boost::foreach_detail_::to_ptr(COL) \ + , boost_foreach_argument_dependent_lookup_hack_value)) + +#ifdef BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION +/////////////////////////////////////////////////////////////////////////////// +// R-values and const R-values supported here with zero runtime overhead +/////////////////////////////////////////////////////////////////////////////// + +// No variable is needed to track the rvalue-ness of the collection expression +# define BOOST_FOREACH_PREAMBLE() \ + /**/ + +// Evaluate the collection expression +# define BOOST_FOREACH_EVALUATE(COL) \ + (COL) + +# define BOOST_FOREACH_SHOULD_COPY(COL) \ + (true ? 0 : boost::foreach_detail_::or_( \ + BOOST_FOREACH_IS_RVALUE(COL) \ + , BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL))) + +#elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) +/////////////////////////////////////////////////////////////////////////////// +// R-values and const R-values supported here +/////////////////////////////////////////////////////////////////////////////// + +// Declare a variable to track the rvalue-ness of the collection expression +# define BOOST_FOREACH_PREAMBLE() \ + if (bool _foreach_is_rvalue = false) {} else + +// Evaluate the collection expression, and detect if it is an lvalue or and rvalue +# define BOOST_FOREACH_EVALUATE(COL) \ + (true ? boost::foreach_detail_::make_probe((COL), _foreach_is_rvalue) : (COL)) + +// The rvalue/lvalue-ness of the collection expression is determined dynamically, unless +// type type is an array or is noncopyable or is non-const, in which case we know it's an lvalue. +// If the type happens to be a lightweight proxy, always make a copy. +# define BOOST_FOREACH_SHOULD_COPY(COL) \ + (boost::foreach_detail_::should_copy_impl( \ + true ? 0 : boost::foreach_detail_::or_( \ + boost::foreach_detail_::is_array_(COL) \ + , BOOST_FOREACH_IS_NONCOPYABLE(COL) \ + , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(COL))) \ + , true ? 0 : BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL) \ + , &_foreach_is_rvalue)) + +#elif !defined(BOOST_FOREACH_NO_RVALUE_DETECTION) +/////////////////////////////////////////////////////////////////////////////// +// R-values supported here, const R-values NOT supported here +/////////////////////////////////////////////////////////////////////////////// + +// No variable is needed to track the rvalue-ness of the collection expression +# define BOOST_FOREACH_PREAMBLE() \ + /**/ + +// Evaluate the collection expression +# define BOOST_FOREACH_EVALUATE(COL) \ + (COL) + +// Determine whether the collection expression is an lvalue or an rvalue. +// NOTE: this gets the answer wrong for const rvalues. +# define BOOST_FOREACH_SHOULD_COPY(COL) \ + (true ? 0 : boost::foreach_detail_::or_( \ + boost::foreach_detail_::is_rvalue_((COL), 0) \ + , BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL))) + +#else +/////////////////////////////////////////////////////////////////////////////// +// R-values NOT supported here +/////////////////////////////////////////////////////////////////////////////// + +// No variable is needed to track the rvalue-ness of the collection expression +# define BOOST_FOREACH_PREAMBLE() \ + /**/ + +// Evaluate the collection expression +# define BOOST_FOREACH_EVALUATE(COL) \ + (COL) + +// Can't use rvalues with BOOST_FOREACH (unless they are lightweight proxies) +# define BOOST_FOREACH_SHOULD_COPY(COL) \ + (true ? 0 : BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL)) + +#endif + +#define BOOST_FOREACH_CONTAIN(COL) \ + boost::foreach_detail_::contain( \ + BOOST_FOREACH_EVALUATE(COL) \ + , BOOST_FOREACH_SHOULD_COPY(COL)) + +#define BOOST_FOREACH_BEGIN(COL) \ + boost::foreach_detail_::begin( \ + _foreach_col \ + , BOOST_FOREACH_TYPEOF(COL) \ + , BOOST_FOREACH_SHOULD_COPY(COL)) + +#define BOOST_FOREACH_END(COL) \ + boost::foreach_detail_::end( \ + _foreach_col \ + , BOOST_FOREACH_TYPEOF(COL) \ + , BOOST_FOREACH_SHOULD_COPY(COL)) + +#define BOOST_FOREACH_DONE(COL) \ + boost::foreach_detail_::done( \ + _foreach_cur \ + , _foreach_end \ + , BOOST_FOREACH_TYPEOF(COL)) + +#define BOOST_FOREACH_NEXT(COL) \ + boost::foreach_detail_::next( \ + _foreach_cur \ + , BOOST_FOREACH_TYPEOF(COL)) + +#define BOOST_FOREACH_DEREF(COL) \ + boost::foreach_detail_::deref( \ + _foreach_cur \ + , BOOST_FOREACH_TYPEOF(COL)) + +/////////////////////////////////////////////////////////////////////////////// +// BOOST_FOREACH +// +// For iterating over collections. Collections can be +// arrays, null-terminated strings, or STL containers. +// The loop variable can be a value or reference. For +// example: +// +// std::list int_list(/*stuff*/); +// BOOST_FOREACH(int &i, int_list) +// { +// /* +// * loop body goes here. +// * i is a reference to the int in int_list. +// */ +// } +// +// Alternately, you can declare the loop variable first, +// so you can access it after the loop finishes. Obviously, +// if you do it this way, then the loop variable cannot be +// a reference. +// +// int i; +// BOOST_FOREACH(i, int_list) +// { ... } +// +#define BOOST_FOREACH(VAR, COL) \ + BOOST_FOREACH_PREAMBLE() \ + if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else \ + if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_BEGIN(COL)) {} else \ + if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_END(COL)) {} else \ + for (bool _foreach_continue = true; \ + _foreach_continue && !BOOST_FOREACH_DONE(COL); \ + _foreach_continue ? BOOST_FOREACH_NEXT(COL) : (void)0) \ + if (boost::foreach_detail_::set_false(_foreach_continue)) {} else \ + for (VAR = BOOST_FOREACH_DEREF(COL); !_foreach_continue; _foreach_continue = true) + +#endif diff --git a/thirdparty/boost/format.hpp b/thirdparty/boost/format.hpp new file mode 100644 index 0000000..13516b4 --- /dev/null +++ b/thirdparty/boost/format.hpp @@ -0,0 +1,59 @@ +// ---------------------------------------------------------------------------- +// format.hpp : primary header +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_HPP +#define BOOST_FORMAT_HPP + +#include +#include +#include +#include + +#ifndef BOOST_NO_STD_LOCALE +#include +#endif + +// *** Compatibility framework +#include + +#ifdef BOOST_NO_LOCALE_ISIDIGIT +#include // we'll use the non-locale 's std::isdigit(int) +#endif + +// **** Forward declarations ---------------------------------- +#include // basic_format, and other frontends +#include // misc forward declarations for internal use + +// **** Auxiliary structs (stream_format_state , and format_item ) +#include + +// **** Format class interface -------------------------------- +#include + +// **** Exceptions ----------------------------------------------- +#include + +// **** Implementation ------------------------------------------- +#include // member functions +#include // class for grouping arguments +#include // argument-feeding functions +#include // format-string parsing (member-)functions + +// **** Implementation of the free functions ---------------------- +#include + + +// *** Undefine 'local' macros : +#include + +#endif // BOOST_FORMAT_HPP diff --git a/thirdparty/boost/format/alt_sstream.hpp b/thirdparty/boost/format/alt_sstream.hpp new file mode 100644 index 0000000..7574d54 --- /dev/null +++ b/thirdparty/boost/format/alt_sstream.hpp @@ -0,0 +1,176 @@ +// ---------------------------------------------------------------------------- +// alt_sstream.hpp : alternative stringstream +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + + + +#ifndef BOOST_SK_ALT_SSTREAM_HPP +#define BOOST_SK_ALT_SSTREAM_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace io { + + template, + class Alloc=::std::allocator > + class basic_altstringbuf; + + template, + class Alloc=::std::allocator > + class basic_oaltstringstream; + + + template + class basic_altstringbuf + : public ::std::basic_streambuf + { + typedef ::std::basic_streambuf streambuf_t; + typedef typename CompatAlloc::compatible_type compat_allocator_type; + typedef typename CompatTraits::compatible_type compat_traits_type; + public: + typedef Ch char_type; + typedef Tr traits_type; + typedef typename compat_traits_type::int_type int_type; + typedef typename compat_traits_type::pos_type pos_type; + typedef typename compat_traits_type::off_type off_type; + typedef Alloc allocator_type; + typedef ::std::basic_string string_type; + typedef typename string_type::size_type size_type; + + typedef ::std::streamsize streamsize; + + + explicit basic_altstringbuf(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : putend_(NULL), is_allocated_(false), mode_(mode) + {} + explicit basic_altstringbuf(const string_type& s, + ::std::ios_base::openmode mode + = ::std::ios_base::in | ::std::ios_base::out) + : putend_(NULL), is_allocated_(false), mode_(mode) + { dealloc(); str(s); } + virtual ~basic_altstringbuf() + { dealloc(); } + using streambuf_t::pbase; + using streambuf_t::pptr; + using streambuf_t::epptr; + using streambuf_t::eback; + using streambuf_t::gptr; + using streambuf_t::egptr; + + void clear_buffer(); + void str(const string_type& s); + + // 0-copy access : + Ch * begin() const; + size_type size() const; + size_type cur_size() const; // stop at current pointer + Ch * pend() const // the highest position reached by pptr() since creation + { return ((putend_ < pptr()) ? pptr() : putend_); } + size_type pcount() const + { return static_cast( pptr() - pbase()) ;} + + // copy buffer to string : + string_type str() const + { return string_type(begin(), size()); } + string_type cur_str() const + { return string_type(begin(), cur_size()); } + protected: + explicit basic_altstringbuf (basic_altstringbuf * s, + ::std::ios_base::openmode mode + = ::std::ios_base::in | ::std::ios_base::out) + : putend_(NULL), is_allocated_(false), mode_(mode) + { dealloc(); str(s); } + + virtual pos_type seekoff(off_type off, ::std::ios_base::seekdir way, + ::std::ios_base::openmode which + = ::std::ios_base::in | ::std::ios_base::out); + virtual pos_type seekpos (pos_type pos, + ::std::ios_base::openmode which + = ::std::ios_base::in | ::std::ios_base::out); + virtual int_type underflow(); + virtual int_type pbackfail(int_type meta = compat_traits_type::eof()); + virtual int_type overflow(int_type meta = compat_traits_type::eof()); + void dealloc(); + private: + enum { alloc_min = 256}; // minimum size of allocations + + Ch *putend_; // remembers (over seeks) the highest value of pptr() + bool is_allocated_; + ::std::ios_base::openmode mode_; + compat_allocator_type alloc_; // the allocator object + }; + + +// --- class basic_oaltstringstream ---------------------------------------- + template + class basic_oaltstringstream + : private base_from_member< shared_ptr< basic_altstringbuf< Ch, Tr, Alloc> > >, + public ::std::basic_ostream + { + class No_Op { + // used as no-op deleter for (not-owner) shared_pointers + public: + template + const T & operator()(const T & arg) { return arg; } + }; + typedef ::std::basic_ostream stream_t; + typedef boost::base_from_member > > + pbase_type; + typedef ::std::basic_string string_type; + typedef typename string_type::size_type size_type; + typedef basic_altstringbuf stringbuf_t; + public: + typedef Alloc allocator_type; + basic_oaltstringstream() + : pbase_type(new stringbuf_t), stream_t(rdbuf()) + { } + basic_oaltstringstream(::boost::shared_ptr buf) + : pbase_type(buf), stream_t(rdbuf()) + { } + basic_oaltstringstream(stringbuf_t * buf) + : pbase_type(buf, No_Op() ), stream_t(rdbuf()) + { } + stringbuf_t * rdbuf() const + { return pbase_type::member.get(); } + void clear_buffer() + { rdbuf()->clear_buffer(); } + + // 0-copy access : + Ch * begin() const + { return rdbuf()->begin(); } + size_type size() const + { return rdbuf()->size(); } + size_type cur_size() const // stops at current position + { return rdbuf()->cur_size(); } + + // copy buffer to string : + string_type str() const // [pbase, epptr[ + { return rdbuf()->str(); } + string_type cur_str() const // [pbase, pptr[ + { return rdbuf()->cur_str(); } + void str(const string_type& s) + { rdbuf()->str(s); } + }; + + } // N.S. io +} // N.S. boost + +#include + +#endif // include guard + diff --git a/thirdparty/boost/format/alt_sstream_impl.hpp b/thirdparty/boost/format/alt_sstream_impl.hpp new file mode 100644 index 0000000..ca7ffd1 --- /dev/null +++ b/thirdparty/boost/format/alt_sstream_impl.hpp @@ -0,0 +1,303 @@ +// ---------------------------------------------------------------------------- +// alt_sstream_impl.hpp : alternative stringstream, templates implementation +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_SK_ALT_SSTREAM_IMPL_HPP +#define BOOST_SK_ALT_SSTREAM_IMPL_HPP + +namespace boost { + namespace io { +// --- Implementation ------------------------------------------------------// + + template + void basic_altstringbuf:: + clear_buffer () { + const Ch * p = pptr(); + const Ch * b = pbase(); + if(p != NULL && p != b) { + seekpos(0, ::std::ios_base::out); + } + p = gptr(); + b = eback(); + if(p != NULL && p != b) { + seekpos(0, ::std::ios_base::in); + } + } + + template + void basic_altstringbuf:: + str (const string_type& s) { + size_type sz=s.size(); + if(sz != 0 && mode_ & (::std::ios_base::in | ::std::ios_base::out) ) { + Ch *new_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0); + // if this didnt throw, we're safe, update the buffer + dealloc(); + sz = s.copy(new_ptr, sz); + putend_ = new_ptr + sz; + if(mode_ & ::std::ios_base::in) + streambuf_t::setg(new_ptr, new_ptr, new_ptr + sz); + if(mode_ & ::std::ios_base::out) { + streambuf_t::setp(new_ptr, new_ptr + sz); + if(mode_ & (::std::ios_base::app | ::std::ios_base::ate)) + streambuf_t::pbump(static_cast(sz)); + if(gptr() == NULL) + streambuf_t::setg(new_ptr, NULL, new_ptr); + } + is_allocated_ = true; + } + else + dealloc(); + } + template + Ch* basic_altstringbuf:: + begin () const { + if(mode_ & ::std::ios_base::out && pptr() != NULL) + return pbase(); + else if(mode_ & ::std::ios_base::in && gptr() != NULL) + return eback(); + return NULL; + } + + template + typename std::basic_string::size_type + basic_altstringbuf:: + size () const { + if(mode_ & ::std::ios_base::out && pptr()) + return static_cast(pend() - pbase()); + else if(mode_ & ::std::ios_base::in && gptr()) + return static_cast(egptr() - eback()); + else + return 0; + } + + template + typename std::basic_string::size_type + basic_altstringbuf:: + cur_size () const { + if(mode_ & ::std::ios_base::out && pptr()) + return static_cast( pptr() - pbase()); + else if(mode_ & ::std::ios_base::in && gptr()) + return static_cast( gptr() - eback()); + else + return 0; + } + + template + typename basic_altstringbuf::pos_type + basic_altstringbuf:: + seekoff (off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) { + if(pptr() != NULL && putend_ < pptr()) + putend_ = pptr(); + if(which & ::std::ios_base::in && gptr() != NULL) { + // get area + if(way == ::std::ios_base::end) + off += static_cast(putend_ - gptr()); + else if(way == ::std::ios_base::beg) + off += static_cast(eback() - gptr()); + else if(way != ::std::ios_base::cur || (which & ::std::ios_base::out) ) + // (altering in&out is only supported if way is beg or end, not cur) + return pos_type(off_type(-1)); + if(eback() <= off+gptr() && off+gptr() <= putend_ ) { + // set gptr + streambuf_t::gbump(static_cast(off)); + if(which & ::std::ios_base::out && pptr() != NULL) + // update pptr to match gptr + streambuf_t::pbump(static_cast(gptr()-pptr())); + } + else + off = off_type(-1); + } + else if(which & ::std::ios_base::out && pptr() != NULL) { + // put area + if(way == ::std::ios_base::end) + off += static_cast(putend_ - pptr()); + else if(way == ::std::ios_base::beg) + off += static_cast(pbase() - pptr()); + else if(way != ::std::ios_base::beg) + return pos_type(off_type(-1)); + if(pbase() <= off+pptr() && off+pptr() <= putend_) + // set pptr + streambuf_t::pbump(static_cast(off)); + else + off = off_type(-1); + } + else // neither in nor out + off = off_type(-1); + return (pos_type(off)); + } + //- end seekoff(..) + + + template + typename basic_altstringbuf::pos_type + basic_altstringbuf:: + seekpos (pos_type pos, ::std::ios_base::openmode which) { + off_type off = off_type(pos); // operation guaranteed by §27.4.3.2 table 88 + if(pptr() != NULL && putend_ < pptr()) + putend_ = pptr(); + if(off != off_type(-1)) { + if(which & ::std::ios_base::in && gptr() != NULL) { + // get area + if(0 <= off && off <= putend_ - eback()) { + streambuf_t::gbump(static_cast(eback() - gptr() + off)); + if(which & ::std::ios_base::out && pptr() != NULL) { + // update pptr to match gptr + streambuf_t::pbump(static_cast(gptr()-pptr())); + } + } + else + off = off_type(-1); + } + else if(which & ::std::ios_base::out && pptr() != NULL) { + // put area + if(0 <= off && off <= putend_ - eback()) + streambuf_t::pbump(static_cast(eback() - pptr() + off)); + else + off = off_type(-1); + } + else // neither in nor out + off = off_type(-1); + return (pos_type(off)); + } + else { + BOOST_ASSERT(0); // §27.4.3.2 allows undefined-behaviour here + return pos_type(off_type(-1)); + } + } + // -end seekpos(..) + + + template + typename basic_altstringbuf::int_type + basic_altstringbuf:: + underflow () { + if(gptr() == NULL) // no get area -> nothing to get. + return (compat_traits_type::eof()); + else if(gptr() < egptr()) // ok, in buffer + return (compat_traits_type::to_int_type(*gptr())); + else if(mode_ & ::std::ios_base::in && pptr() != NULL + && (gptr() < pptr() || gptr() < putend_) ) + { // expand get area + if(putend_ < pptr()) + putend_ = pptr(); // remember pptr reached this far + streambuf_t::setg(eback(), gptr(), putend_); + return (compat_traits_type::to_int_type(*gptr())); + } + else // couldnt get anything. EOF. + return (compat_traits_type::eof()); + } + // -end underflow(..) + + + template + typename basic_altstringbuf::int_type + basic_altstringbuf:: + pbackfail (int_type meta) { + if(gptr() != NULL && (eback() < gptr()) + && (mode_ & (::std::ios_base::out) + || compat_traits_type::eq_int_type(compat_traits_type::eof(), meta) + || compat_traits_type::eq(compat_traits_type::to_char_type(meta), gptr()[-1]) ) ) { + streambuf_t::gbump(-1); // back one character + if(!compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)) + // put-back meta into get area + *gptr() = compat_traits_type::to_char_type(meta); + return (compat_traits_type::not_eof(meta)); + } + else + return (compat_traits_type::eof()); // failed putback + } + // -end pbackfail(..) + + + template + typename basic_altstringbuf::int_type + basic_altstringbuf:: + overflow (int_type meta) { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4996) +#endif + if(compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)) + return compat_traits_type::not_eof(meta); // nothing to do + else if(pptr() != NULL && pptr() < epptr()) { + streambuf_t::sputc(compat_traits_type::to_char_type(meta)); + return meta; + } + else if(! (mode_ & ::std::ios_base::out)) + // no write position, and cant make one + return compat_traits_type::eof(); + else { // make a write position available + std::size_t prev_size = pptr() == NULL ? 0 : epptr() - eback(); + std::size_t new_size = prev_size; + // exponential growth : size *= 1.5 + std::size_t add_size = new_size / 2; + if(add_size < alloc_min) + add_size = alloc_min; + Ch * newptr = NULL, *oldptr = eback(); + + // make sure adding add_size wont overflow size_t + while (0 < add_size && ((std::numeric_limits::max)() + - add_size < new_size) ) + add_size /= 2; + if(0 < add_size) { + new_size += add_size; + newptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0); + } + + if(0 < prev_size) + compat_traits_type::copy(newptr, oldptr, prev_size); + if(is_allocated_) + alloc_.deallocate(oldptr, prev_size); + is_allocated_=true; + + if(prev_size == 0) { // first allocation + putend_ = newptr; + streambuf_t::setp(newptr, newptr + new_size); + if(mode_ & ::std::ios_base::in) + streambuf_t::setg(newptr, newptr, newptr + 1); + else + streambuf_t::setg(newptr, 0, newptr); + } + else { // update pointers + putend_ = putend_ - oldptr + newptr; + int pptr_count = static_cast(pptr()-pbase()); + int gptr_count = static_cast(gptr()-eback()); + streambuf_t::setp(pbase() - oldptr + newptr, newptr + new_size); + streambuf_t::pbump(pptr_count); + if(mode_ & ::std::ios_base::in) + streambuf_t::setg(newptr, newptr + gptr_count, pptr() + 1); + else + streambuf_t::setg(newptr, 0, newptr); + } + streambuf_t::sputc(compat_traits_type::to_char_type(meta)); + return meta; + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + } + // -end overflow(..) + + template + void basic_altstringbuf:: dealloc() { + if(is_allocated_) + alloc_.deallocate(eback(), (pptr() != NULL ? epptr() : egptr()) - eback()); + is_allocated_ = false; + streambuf_t::setg(0, 0, 0); + streambuf_t::setp(0, 0); + putend_ = NULL; + } + + }// N.S. io +} // N.S. boost + +#endif // include guard + diff --git a/thirdparty/boost/format/detail/compat_workarounds.hpp b/thirdparty/boost/format/detail/compat_workarounds.hpp new file mode 100644 index 0000000..898ef30 --- /dev/null +++ b/thirdparty/boost/format/detail/compat_workarounds.hpp @@ -0,0 +1,86 @@ +// ---------------------------------------------------------------------------- +// compat_workarounds : general framework for non-conformance workarounds +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// see http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + + +// this file defines wrapper classes to hide non-conforming +// std::char_traits<> and std::allocator<> traits +// and Includes : config_macros.hpp (defines config macros +// and compiler-specific switches) + +// Non-conformant Std-libs fail to supply conformant traits (std::char_traits, +// std::allocator) and/or the std::string doesnt support them. +// We don't want to have hundreds of #ifdef workarounds, so we define +// replacement traits. +// But both char_traits and allocator traits are visible in the interface, +// (inside the final string type), thus we need to keep both +// the replacement type (typedefed to 'compatible_type') for real use, +// and the original stdlib type (typedef to 'type_for_string') for interface +// visibility. This is what Compat* classes do (as well as be transparent +// when good allocator and char traits are present) + +#ifndef BOOST_FORMAT_COMPAT_WORKAROUNDS_HPP +#define BOOST_FORMAT_COMPAT_WORKAROUNDS_HPP + +namespace boost { + namespace io { + + // gcc-2.95 char traits (non-conformantly named string_char_traits) + // lack several functions so we extend them in a replacement class. + template + class CompatTraits; + + // std::allocator in gcc-2.95 is ok, but basic_string only works + // with plain 'std::alloc' still, alt_stringbuf requires a functionnal + // alloc template argument, so we need a replacement allocator + template + class CompatAlloc; + } // N.S. io +}// N.S. boost + + +#include + // sets-up macros and load compiler-specific workarounds headers. + +#if !defined(BOOST_FORMAT_STREAMBUF_DEFINED) +// workarounds-gcc-2.95 might have defined own streambuf +#include +#endif + +#if !defined(BOOST_FORMAT_OSTREAM_DEFINED) +// workarounds-gcc-2.95 might already have included +#include +#endif + + + +namespace boost { + namespace io { + + // **** CompatTraits general definitions : ---------------------------- + template + class CompatTraits + { // general case : be transparent + public: + typedef Tr compatible_type; + }; + + // **** CompatAlloc general definitions : ----------------------------- + template + class CompatAlloc + { // general case : be transparent + public: + typedef Alloc compatible_type; + }; + + } //N.S. io +} // N.S. boost +#endif // include guard diff --git a/thirdparty/boost/format/detail/config_macros.hpp b/thirdparty/boost/format/detail/config_macros.hpp new file mode 100644 index 0000000..cccb463 --- /dev/null +++ b/thirdparty/boost/format/detail/config_macros.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- +// ---------------------------------------------------------------------------- +// config_macros.hpp : configuration macros for the format library +// only BOOST_IO_STD is absolutely needed (it should be 'std::' in general) +// others are compiler-specific workaround macros used in #ifdef switches +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// see http://www.boost.org/libs/format for library home page + + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_CONFIG_MACROS_HPP +#define BOOST_FORMAT_CONFIG_MACROS_HPP + +#include +#include + +// make sure our local macros wont override something : +#if defined(BOOST_NO_LOCALE_ISDIGIT) || defined(BOOST_OVERLOAD_FOR_NON_CONST) \ + || defined(BOOST_IO_STD) || defined( BOOST_IO_NEEDS_USING_DECLARATION ) \ + || defined(BOOST_NO_TEMPLATE_STD_STREAM) \ + || defined(BOOST_FORMAT_STREAMBUF_DEFINED) || defined(BOOST_FORMAT_OSTREAM_DEFINED) +#error "boost::format uses a local macro that is already defined." +#endif + +// specific workarounds. each header can define BOOS_IO_STD if it +// needs. (e.g. because of IO_NEEDS_USING_DECLARATION) +#include +#include + +#ifndef BOOST_IO_STD +# define BOOST_IO_STD ::std:: +#endif + +#if defined(BOOST_NO_STD_LOCALE) || \ + ( BOOST_WORKAROUND(__BORLANDC__, <= 0x564) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT( 0x570 ) ) ) +// some future __BORLANDC__ >0x564 versions might not need this +// 0x570 is Borland's kylix branch +#define BOOST_NO_LOCALE_ISDIGIT +#endif + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570) ) || BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1300)) +#define BOOST_NO_OVERLOAD_FOR_NON_CONST +#endif + +// gcc-2.95's native stringstream is not usable +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#define BOOST_FORMAT_IGNORE_STRINGSTREAM +#endif + + +// **** Workaround for io streams, stlport and msvc. +#ifdef BOOST_IO_NEEDS_USING_DECLARATION +namespace boost { + using std::char_traits; + using std::basic_ostream; + namespace io { + using std::basic_ostream; + namespace detail { + using std::basic_ios; + using std::basic_ostream; + } + } +#if ! defined(BOOST_NO_STD_LOCALE) + using std::locale; + namespace io { + using std::locale; + namespace detail { + using std::locale; + } + } +#endif // locale +} + // -end N.S. boost +#endif // needs_using_declaration + + +// *** hide std::locale if it doesnt exist. +// this typedef is either std::locale or int, avoids placing ifdefs everywhere +namespace boost { namespace io { namespace detail { +#if ! defined(BOOST_NO_STD_LOCALE) + typedef BOOST_IO_STD locale locale_t; +#else + typedef int locale_t; +#endif +} } } + + +// ---------------------------------------------------------------------------- + +#endif // BOOST_FORMAT_MACROS_DEFAULT_HPP diff --git a/thirdparty/boost/format/detail/msvc_disambiguater.hpp b/thirdparty/boost/format/detail/msvc_disambiguater.hpp new file mode 100644 index 0000000..9170db9 --- /dev/null +++ b/thirdparty/boost/format/detail/msvc_disambiguater.hpp @@ -0,0 +1,56 @@ +// ---------------------------------------------------------------------------- +// msvc_disambiguater.hpp : msvc workarounds. (for put_{head|last} overloads) +// the trick was described in boost's list by Aleksey Gurtovoy +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// see http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_MSVC_DISAMBIGUATER_HPP +#define BOOST_MSVC_DISAMBIGUATER_HPP + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1300) || \ + BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + // this whole header is specifically for msvc up to 7.0 + +#include +#include + +namespace boost { +namespace io { +namespace detail { + +template< class Ch, class Tr, class T > +struct disambiguater +{ + template< typename U > + static void put_head(BOOST_IO_STD basic_ostream& os, group1 const& x, long) + { + os << group_head(x.a1_); + } + static void put_head(BOOST_IO_STD basic_ostream& os, T const& x, int) + { + } + template< typename U > + static void put_last(BOOST_IO_STD basic_ostream& os, group1 const& x, long) + { + os << group_last(x.a1_); + } + static void put_last(BOOST_IO_STD basic_ostream& os, T const& x, int) + { + os << x; + } +}; + +} // namespace detail +} // namespace io +} // namespace boost + +#endif // -BOOST_MSVC + +#endif // -BOOST_MSVC_DISAMBIGUATER_HPP diff --git a/thirdparty/boost/format/detail/unset_macros.hpp b/thirdparty/boost/format/detail/unset_macros.hpp new file mode 100644 index 0000000..20226f0 --- /dev/null +++ b/thirdparty/boost/format/detail/unset_macros.hpp @@ -0,0 +1,34 @@ +// ---------------------------------------------------------------------------- +// unset_macros.hpp +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +// *** Undefine 'local' macros : +#ifdef BOOST_NO_OVERLOAD_FOR_NON_CONST +#undef BOOST_NO_OVERLOAD_FOR_NON_CONST +#endif +#ifdef BOOST_NO_LOCALE_ISDIGIT +#undef BOOST_NO_LOCALE_ISDIGIT +#endif +#ifdef BOOST_IO_STD +#undef BOOST_IO_STD +#endif +#ifdef BOOST_IO_NEEDS_USING_DECLARATION +#undef BOOST_IO_NEEDS_USING_DECLARATION +#endif +#ifdef BOOST_NO_TEMPLATE_STD_STREAM +#undef BOOST_NO_TEMPLATE_STD_STREAM +#endif +#ifdef BOOST_FORMAT_STREAMBUF_DEFINED +#undef BOOST_FORMAT_STREAMBUF_DEFINED +#endif +#ifdef BOOST_FORMAT_OSTREAM_DEFINED +#undef BOOST_FORMAT_OSTREAM_DEFINED +#endif diff --git a/thirdparty/boost/format/detail/workarounds_gcc-2_95.hpp b/thirdparty/boost/format/detail/workarounds_gcc-2_95.hpp new file mode 100644 index 0000000..86608c9 --- /dev/null +++ b/thirdparty/boost/format/detail/workarounds_gcc-2_95.hpp @@ -0,0 +1,162 @@ +// ---------------------------------------------------------------------------- +// workarounds for gcc < 3.0. +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + + +// ---------------------------------------------------------------------------- + +// There's a lot to do, the stdlib shipped with gcc prior to 3.x +// was terribly non-conforming. +// . defines macros switches +// . supplies template classes basic_foo where gcc only supplies foo. +// i.e : +// - basic_ios from ios +// - basic_ostream from ostream +// - basic_srteambuf from streambuf +// these can be used transparently. (it obviously does not work for wchar_t) +// . specialise CompatAlloc and CompatTraits to wrap gcc-2.95's +// string_char_traits and std::alloc + +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) + // only for gcc-2.95's native stdlib + +#ifndef BOOST_FORMAT_WORKAROUNDS_GCC295_H +#define BOOST_FORMAT_WORKAROUNDS_GCC295_H + +// SGI STL doesnt have and others, so we need iostream. +#include +#define BOOST_FORMAT_OSTREAM_DEFINED + +#include +#define BOOST_FORMAT_STREAMBUF_DEFINED + +#define BOOST_NO_TEMPLATE_STD_STREAM + +#ifndef BOOST_IO_STD +# define BOOST_IO_STD std:: +#endif + + + +// *** +// gcc's simple classes turned into standard-like template classes : + +namespace std { + + + // gcc has string_char_traits, it's incomplete. + // we declare a std::char_traits, and specialize CompatTraits<..> on it + // to do what is required + template + class char_traits; // no definition here, we will just use it as a tag. + + template + class basic_streambuf; + + template + class basic_streambuf : public streambuf { + }; + + template > + class basic_ios; + + template + class basic_ios : public ostream { + public: + basic_ios(streambuf * p) : ostream(p) {}; + char fill() const { return ios::fill(); } // gcc returns wchar.. + char fill(char c) { return ios::fill(c); } // gcc takes wchar.. + char widen(char c) { return c; } + char narrow(char c, char def) { return c; } + basic_ios& copyfmt(const ios& right) { + fill(right.fill()); + flags(right.flags() ); + exceptions(right.exceptions()); + width(right.width()); + precision(right.precision()); + return *this; + } + }; + + + typedef ios ios_base; + + template + class basic_ostream; + + template + class basic_ostream : public basic_ios + { + public: + basic_ostream(streambuf * p) : basic_ios (p) {} + }; + +} // namespace std + + +namespace boost { + namespace io { + + + // ** CompatTraits gcc2.95 specialisations ---------------------------- + template + class CompatTraits< ::std::string_char_traits > + : public ::std::string_char_traits + { + public: + typedef CompatTraits compatible_type; + + typedef Ch char_type; + typedef int int_type; + typedef ::std::streampos pos_type; + typedef ::std::streamoff off_type; + + static char_type + to_char_type(const int_type& meta) { + return static_cast(meta); } + static int_type + to_int_type(const char_type& ch) { + return static_cast(static_cast(ch) );} + static bool + eq_int_type(const int_type& left, const int_type& right) { + return left == right; } + static int_type + eof() { + return static_cast(EOF); + } + static int_type + not_eof(const int_type& meta) { + return (meta == eof()) ? 0 : meta; + } + }; + + template + class CompatTraits< ::std::char_traits > { + public: + typedef CompatTraits< ::std::string_char_traits > compatible_type; + }; + + // ** CompatAlloc gcc-2.95 specialisations --------------------------- + template<> + class CompatAlloc< ::std::alloc> + { + public: + typedef ::std::allocator compatible_type; + }; + + } // N.S. io +} // N.S. boost + + + + + +#endif // include guard + +#endif // if workaround diff --git a/thirdparty/boost/format/detail/workarounds_stlport.hpp b/thirdparty/boost/format/detail/workarounds_stlport.hpp new file mode 100644 index 0000000..92b8cb3 --- /dev/null +++ b/thirdparty/boost/format/detail/workarounds_stlport.hpp @@ -0,0 +1,42 @@ +// ---------------------------------------------------------------------------- +// workarounds_stlport.hpp : workaround STLport issues +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// see http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_MACROS_STLPORT_HPP +#define BOOST_MACROS_STLPORT_HPP + +#if defined(_STLPORT_VERSION) && BOOST_WORKAROUND( BOOST_MSVC, <= 1300) +// msvc-6-stlport fails to find basic_string::append( iterator, iterator) when linking +// might affect other MSwindows compilers +#define BOOST_NO_STRING_APPEND +#endif + +// *** This should go to "boost/config/stdlib/stlport.hpp". + +// If the streams are not native and there are problems with using templates +// accross namespaces, we define some macros to enable a workaround for this. + +// STLport 4.5 +#if !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) +# define BOOST_IO_STD +# define BOOST_IO_NEEDS_USING_DECLARATION +#endif + +// STLport 4.0 +#if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_OWN_NAMESPACE) && defined(BOOST_NO_USING_TEMPLATE) +# define BOOST_IO_STD +# define BOOST_IO_NEEDS_USING_DECLARATION +#endif + + +// ---------------------------------------------------------------------------- + +#endif // BOOST_MACROS_STLPORT_HPP diff --git a/thirdparty/boost/format/exceptions.hpp b/thirdparty/boost/format/exceptions.hpp new file mode 100644 index 0000000..54b4098 --- /dev/null +++ b/thirdparty/boost/format/exceptions.hpp @@ -0,0 +1,103 @@ +// ---------------------------------------------------------------------------- +// boost/format/exceptions.hpp +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 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/format/ for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_EXCEPTIONS_HPP +#define BOOST_FORMAT_EXCEPTIONS_HPP + + +#include + + +namespace boost { + + namespace io { + +// **** exceptions ----------------------------------------------- + + class format_error : public std::exception + { + public: + format_error() {} + virtual const char *what() const throw() { + return "boost::format_error: " + "format generic failure"; + } + }; + + class bad_format_string : public format_error + { + std::size_t pos_, next_; + public: + bad_format_string(std::size_t pos, std::size_t size) + : pos_(pos), next_(size) {} + std::size_t get_pos() const { return pos_; } + std::size_t get_next() const { return next_; } + virtual const char *what() const throw() { + return "boost::bad_format_string: format-string is ill-formed"; + } + }; + + class too_few_args : public format_error + { + std::size_t cur_, expected_; + public: + too_few_args(std::size_t cur, std::size_t expected) + : cur_(cur), expected_(expected) {} + std::size_t get_cur() const { return cur_; } + std::size_t get_expected() const { return expected_; } + virtual const char *what() const throw() { + return "boost::too_few_args: " + "format-string referred to more arguments than were passed"; + } + }; + + class too_many_args : public format_error + { + std::size_t cur_, expected_; + public: + too_many_args(std::size_t cur, std::size_t expected) + : cur_(cur), expected_(expected) {} + std::size_t get_cur() const { return cur_; } + std::size_t get_expected() const { return expected_; } + virtual const char *what() const throw() { + return "boost::too_many_args: " + "format-string referred to less arguments than were passed"; + } + }; + + + class out_of_range : public format_error + { + int index_, beg_, end_; // range is [ beg, end [ + public: + out_of_range(int index, int beg, int end) + : index_(index), beg_(beg), end_(end) {} + int get_index() const { return index_; } + int get_beg() const { return beg_; } + int get_end() const { return end_; } + virtual const char *what() const throw() { + return "boost::out_of_range: " + "tried to refer to an argument (or item) number which" + " is out of range, according to the format string"; + } + }; + + + } // namespace io + +} // namespace boost + + +#endif // BOOST_FORMAT_EXCEPTIONS_HPP diff --git a/thirdparty/boost/format/feed_args.hpp b/thirdparty/boost/format/feed_args.hpp new file mode 100644 index 0000000..5146e14 --- /dev/null +++ b/thirdparty/boost/format/feed_args.hpp @@ -0,0 +1,277 @@ +// ---------------------------------------------------------------------------- +// feed_args.hpp : functions for processing each argument +// (feed, feed_manip, and distribute) +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_FEED_ARGS_HPP +#define BOOST_FORMAT_FEED_ARGS_HPP + +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace io { +namespace detail { + + template + void mk_str( std::basic_string & res, + const Ch * beg, + typename std::basic_string::size_type size, + std::streamsize w, + const Ch fill_char, + std::ios_base::fmtflags f, + const Ch prefix_space, // 0 if no space-padding + bool center) + // applies centered/left/right padding to the string [beg, beg+size[ + // Effects : the result is placed in res. + { + typedef typename std::basic_string::size_type size_type; + res.resize(0); + if(w<=0 || static_cast(w) <=size) { + // no need to pad. + res.reserve(size + !!prefix_space); + if(prefix_space) + res.append(1, prefix_space); + if (size) + res.append(beg, size); + } + else { + std::streamsize n=static_cast(w-size-!!prefix_space); + std::streamsize n_after = 0, n_before = 0; + res.reserve(static_cast(w)); // allocate once for the 2 inserts + if(center) + n_after = n/2, n_before = n - n_after; + else + if(f & std::ios_base::left) + n_after = n; + else + n_before = n; + // now make the res string : + if(n_before) res.append(static_cast(n_before), fill_char); + if(prefix_space) + res.append(1, prefix_space); + if (size) + res.append(beg, size); + if(n_after) res.append(static_cast(n_after), fill_char); + } + } // -mk_str(..) + + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1300) || \ + BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) +// MSVC needs to be tricked to disambiguate this simple overload.. +// the trick is in "boost/format/msvc_disambiguater.hpp" + + template< class Ch, class Tr, class T> inline + void put_head (BOOST_IO_STD basic_ostream & os, const T& x ) { + disambiguater::put_head(os, x, 1L); + } + template< class Ch, class Tr, class T> inline + void put_last (BOOST_IO_STD basic_ostream & os, const T& x ) { + disambiguater::put_last(os, x, 1L); + } + +#else + + template< class Ch, class Tr, class T> inline + void put_head (BOOST_IO_STD basic_ostream &, const T& ) { + } + + template< class Ch, class Tr, class T> inline + void put_head( BOOST_IO_STD basic_ostream & os, const group1& x ) { + os << group_head(x.a1_); // send the first N-1 items, not the last + } + + template< class Ch, class Tr, class T> inline + void put_last( BOOST_IO_STD basic_ostream & os, const T& x ) { + os << x ; + } + + template< class Ch, class Tr, class T> inline + void put_last( BOOST_IO_STD basic_ostream & os, const group1& x ) { + os << group_last(x.a1_); // this selects the last element + } + +#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST + template< class Ch, class Tr, class T> inline + void put_head( BOOST_IO_STD basic_ostream &, T& ) { + } + + template< class Ch, class Tr, class T> inline + void put_last( BOOST_IO_STD basic_ostream & os, T& x) { + os << x ; + } +#endif +#endif // -msvc workaround + + + template< class Ch, class Tr, class Alloc, class T> + void put( T x, + const format_item& specs, + typename basic_format::string_type& res, + typename basic_format::internal_streambuf_t & buf, + io::detail::locale_t *loc_p = NULL) + { +#ifdef BOOST_MSVC + // If std::min or std::max are already instantiated + // at this point then we get a blizzard of warning messages when we call + // those templates with std::size_t as arguments. Weird and very annoyning... +#pragma warning(push) +#pragma warning(disable:4267) +#endif + // does the actual conversion of x, with given params, into a string + // using the supplied stringbuf. + + typedef typename basic_format::string_type string_type; + typedef typename basic_format::format_item_t format_item_t; + typedef typename string_type::size_type size_type; + + basic_oaltstringstream oss( &buf); + specs.fmtstate_.apply_on(oss, loc_p); + + // the stream format state can be modified by manipulators in the argument : + put_head( oss, x ); + // in case x is a group, apply the manip part of it, + // in order to find width + + const std::ios_base::fmtflags fl=oss.flags(); + const bool internal = (fl & std::ios_base::internal) != 0; + const std::streamsize w = oss.width(); + const bool two_stepped_padding= internal && (w!=0); + + res.resize(0); + if(! two_stepped_padding) { + if(w>0) // handle padding via mk_str, not natively in stream + oss.width(0); + put_last( oss, x); + const Ch * res_beg = buf.pbase(); + Ch prefix_space = 0; + if(specs.pad_scheme_ & format_item_t::spacepad) + if(buf.pcount()== 0 || + (res_beg[0] !=oss.widen('+') && res_beg[0] !=oss.widen('-') )) + prefix_space = oss.widen(' '); + size_type res_size = (std::min)( + static_cast(specs.truncate_ - !!prefix_space), + buf.pcount() ); + mk_str(res, res_beg, res_size, w, oss.fill(), fl, + prefix_space, (specs.pad_scheme_ & format_item_t::centered) !=0 ); + } + else { // 2-stepped padding + // internal can be implied by zeropad, or user-set. + // left, right, and centered alignment overrule internal, + // but spacepad or truncate might be mixed with internal (using manipulator) + put_last( oss, x); // may pad + const Ch * res_beg = buf.pbase(); + size_type res_size = buf.pcount(); + bool prefix_space=false; + if(specs.pad_scheme_ & format_item_t::spacepad) + if(buf.pcount()== 0 || + (res_beg[0] !=oss.widen('+') && res_beg[0] !=oss.widen('-') )) + prefix_space = true; + if(res_size == static_cast(w) && w<=specs.truncate_ && !prefix_space) { + // okay, only one thing was printed and padded, so res is fine + res.assign(res_beg, res_size); + } + else { // length w exceeded + // either it was multi-output with first output padding up all width.. + // either it was one big arg and we are fine. + // Note that res_size oss2( &buf); + specs.fmtstate_.apply_on(oss2, loc_p); + put_head( oss2, x ); + + oss2.width(0); + if(prefix_space) + oss2 << ' '; + put_last(oss2, x ); + if(buf.pcount()==0 && specs.pad_scheme_ & format_item_t::spacepad) { + prefix_space =true; + oss2 << ' '; + } + // we now have the minimal-length output + const Ch * tmp_beg = buf.pbase(); + size_type tmp_size = (std::min)(static_cast(specs.truncate_), + buf.pcount() ); + + + if(static_cast(w) <= tmp_size) { + // minimal length is already >= w, so no padding (cool!) + res.assign(tmp_beg, tmp_size); + } + else { // hum.. we need to pad (multi_output, or spacepad present) + //find where we should pad + size_type sz = (std::min)(res_size + (prefix_space ? 1 : 0), tmp_size); + size_type i = prefix_space; + for(; i=tmp_size) i=prefix_space; + res.assign(tmp_beg, i); + std::streamsize d = w - static_cast(tmp_size); + BOOST_ASSERT(d>0); + res.append(static_cast( d ), oss2.fill()); + res.append(tmp_beg+i, tmp_size-i); + BOOST_ASSERT(i+(tmp_size-i)+(std::max)(d,(std::streamsize)0) + == static_cast(w)); + BOOST_ASSERT(res.size() == static_cast(w)); + } + } + } + buf.clear_buffer(); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + } // end- put(..) + + + template< class Ch, class Tr, class Alloc, class T> + void distribute (basic_format& self, T x) { + // call put(x, ..) on every occurence of the current argument : + if(self.cur_arg_ >= self.num_args_) { + if( self.exceptions() & too_many_args_bit ) + boost::throw_exception(too_many_args(self.cur_arg_, self.num_args_)); + else return; + } + for(unsigned long i=0; i < self.items_.size(); ++i) { + if(self.items_[i].argN_ == self.cur_arg_) { + put (x, self.items_[i], self.items_[i].res_, + self.buf_, boost::get_pointer(self.loc_) ); + } + } + } + + template + basic_format& + feed (basic_format& self, T x) { + if(self.dumped_) self.clear(); + distribute (self, x); + ++self.cur_arg_; + if(self.bound_.size() != 0) { + while( self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_] ) + ++self.cur_arg_; + } + return self; + } + +} // namespace detail +} // namespace io +} // namespace boost + + +#endif // BOOST_FORMAT_FEED_ARGS_HPP diff --git a/thirdparty/boost/format/format_class.hpp b/thirdparty/boost/format/format_class.hpp new file mode 100644 index 0000000..32ae447 --- /dev/null +++ b/thirdparty/boost/format/format_class.hpp @@ -0,0 +1,143 @@ +// ---------------------------------------------------------------------------- +// format_class.hpp : class interface +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_CLASS_HPP +#define BOOST_FORMAT_CLASS_HPP + + +#include +#include + +#include // to store locale when needed + +#include +#include +#include +#include + +namespace boost { + + template + class basic_format + { + typedef typename io::CompatTraits::compatible_type compat_traits; + public: + typedef Ch CharT; // borland fails in operator% if we use Ch and Tr directly + typedef std::basic_string string_type; + typedef typename string_type::size_type size_type; + typedef io::detail::format_item format_item_t; + typedef io::basic_altstringbuf internal_streambuf_t; + + + explicit basic_format(const Ch* str=NULL); + explicit basic_format(const string_type& s); + basic_format(const basic_format& x); + basic_format& operator= (const basic_format& x); + void swap(basic_format& x); + +#if !defined(BOOST_NO_STD_LOCALE) + explicit basic_format(const Ch* str, const std::locale & loc); + explicit basic_format(const string_type& s, const std::locale & loc); +#endif + io::detail::locale_t getloc() const; + + basic_format& clear(); // empty all converted string buffers (except bound items) + basic_format& clear_binds(); // unbind all bound items, and call clear() + basic_format& parse(const string_type&); // resets buffers and parse a new format string + + // ** formatted result ** // + size_type size() const; // sum of the current string pieces sizes + string_type str() const; // final string + + // ** arguments passing ** // + template + basic_format& operator%(const T& x) + { return io::detail::feed(*this,x); } + +#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST + template basic_format& operator%(T& x) + { return io::detail::feed(*this,x); } +#endif + + // ** object modifying **// + template + basic_format& bind_arg(int argN, const T& val) + { return io::detail::bind_arg_body(*this, argN, val); } + basic_format& clear_bind(int argN); + template + basic_format& modify_item(int itemN, T manipulator) + { return io::detail::modify_item_body (*this, itemN, manipulator);} + + // Choosing which errors will throw exceptions : + unsigned char exceptions() const; + unsigned char exceptions(unsigned char newexcept); + +#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) \ + && !BOOST_WORKAROUND(__BORLANDC__, <= 0x570) \ + && !BOOST_WORKAROUND( _CRAYC, != 0) \ + && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + // use friend templates and private members only if supported + +#ifndef BOOST_NO_TEMPLATE_STD_STREAM + template + friend std::basic_ostream & + operator<<( std::basic_ostream & , + const basic_format& ); +#else + template + friend std::ostream & + operator<<( std::ostream & , + const basic_format& ); +#endif + + template + friend basic_format& + io::detail::feed (basic_format&, T); + + template friend + void io::detail::distribute (basic_format&, T); + + template friend + basic_format& + io::detail::modify_item_body (basic_format&, int, T); + + template friend + basic_format& + io::detail::bind_arg_body (basic_format&, int, const T&); + + private: +#endif + typedef io::detail::stream_format_state stream_format_state; + // flag bits, used for style_ + enum style_values { ordered = 1, // set only if all directives are positional + special_needs = 4 }; + + void make_or_reuse_data(std::size_t nbitems);// used for (re-)initialisation + + // member data --------------------------------------------// + std::vector items_; // each '%..' directive leads to a format_item + std::vector bound_; // stores which arguments were bound. size() == 0 || num_args + + int style_; // style of format-string : positional or not, etc + int cur_arg_; // keep track of wich argument is current + int num_args_; // number of expected arguments + mutable bool dumped_; // true only after call to str() or << + string_type prefix_; // piece of string to insert before first item + unsigned char exceptions_; + internal_streambuf_t buf_; // the internal stream buffer. + boost::optional loc_; + }; // class basic_format + +} // namespace boost + + +#endif // BOOST_FORMAT_CLASS_HPP diff --git a/thirdparty/boost/format/format_fwd.hpp b/thirdparty/boost/format/format_fwd.hpp new file mode 100644 index 0000000..60e36bb --- /dev/null +++ b/thirdparty/boost/format/format_fwd.hpp @@ -0,0 +1,49 @@ +// ---------------------------------------------------------------------------- +// format_fwd.hpp : forward declarations +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_FWD_HPP +#define BOOST_FORMAT_FWD_HPP + +#include +#include + +#include + +namespace boost { + + template , class Alloc = std::allocator > +#else + class Tr = std::string_char_traits, class Alloc = std::alloc > +#endif + class basic_format; + + typedef basic_format format; + +#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) \ + && !defined(BOOST_FORMAT_IGNORE_STRINGSTREAM) + typedef basic_format wformat; +#endif + + namespace io { + enum format_error_bits { bad_format_string_bit = 1, + too_few_args_bit = 2, too_many_args_bit = 4, + out_of_range_bit = 8, + all_error_bits = 255, no_error_bits=0 }; + + } // namespace io + +} // namespace boost + +#endif // BOOST_FORMAT_FWD_HPP diff --git a/thirdparty/boost/format/format_implementation.hpp b/thirdparty/boost/format/format_implementation.hpp new file mode 100644 index 0000000..6c6505b --- /dev/null +++ b/thirdparty/boost/format/format_implementation.hpp @@ -0,0 +1,288 @@ +// ---------------------------------------------------------------------------- +// format_implementation.hpp Implementation of the basic_format class +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_IMPLEMENTATION_HPP +#define BOOST_FORMAT_IMPLEMENTATION_HPP + +#include +#include +#include +#include +#include // std::swap + +namespace boost { + +// --- basic_format implementation -----------------------------------------// + + template< class Ch, class Tr, class Alloc> + basic_format:: basic_format(const Ch* s) + : style_(0), cur_arg_(0), num_args_(0), dumped_(false), + exceptions_(io::all_error_bits) + { + if( s) + parse( s ); + } + +#if !defined(BOOST_NO_STD_LOCALE) + template< class Ch, class Tr, class Alloc> + basic_format:: basic_format(const Ch* s, const std::locale & loc) + : style_(0), cur_arg_(0), num_args_(0), dumped_(false), + loc_(loc), exceptions_(io::all_error_bits) + { + if(s) parse( s ); + } + + template< class Ch, class Tr, class Alloc> + basic_format:: basic_format(const string_type& s, const std::locale & loc) + : style_(0), cur_arg_(0), num_args_(0), dumped_(false), + loc_(loc), exceptions_(io::all_error_bits) + { + parse(s); + } +#endif // ! BOOST_NO_STD_LOCALE + template< class Ch, class Tr, class Alloc> + io::detail::locale_t basic_format:: + getloc() const { + return loc_ ? loc_.get() : io::detail::locale_t(); + } + + template< class Ch, class Tr, class Alloc> + basic_format:: basic_format(const string_type& s) + : style_(0), cur_arg_(0), num_args_(0), dumped_(false), + exceptions_(io::all_error_bits) + { + parse(s); + } + + template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member + basic_format:: basic_format(const basic_format& x) + : items_(x.items_), bound_(x.bound_), style_(x.style_), + cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(false), + prefix_(x.prefix_), exceptions_(x.exceptions_), loc_(x.loc_) + { + } + + template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member + basic_format& basic_format:: + operator= (const basic_format& x) { + if(this == &x) + return *this; + (basic_format(x)).swap(*this); + return *this; + } + template< class Ch, class Tr, class Alloc> + void basic_format:: + swap (basic_format & x) { + std::swap(exceptions_, x.exceptions_); + std::swap(style_, x.style_); + std::swap(cur_arg_, x.cur_arg_); + std::swap(num_args_, x.num_args_); + std::swap(dumped_, x.dumped_); + + items_.swap(x.items_); + prefix_.swap(x.prefix_); + bound_.swap(x.bound_); + } + + template< class Ch, class Tr, class Alloc> + unsigned char basic_format:: exceptions() const { + return exceptions_; + } + + template< class Ch, class Tr, class Alloc> + unsigned char basic_format:: exceptions(unsigned char newexcept) { + unsigned char swp = exceptions_; + exceptions_ = newexcept; + return swp; + } + + template + void basic_format:: + make_or_reuse_data (std::size_t nbitems) { +#if !defined(BOOST_NO_STD_LOCALE) + Ch fill = ( BOOST_USE_FACET(std::ctype, getloc()) ). widen(' '); +#else + Ch fill = ' '; +#endif + if(items_.size() == 0) + items_.assign( nbitems, format_item_t(fill) ); + else { + if(nbitems>items_.size()) + items_.resize(nbitems, format_item_t(fill)); + bound_.resize(0); + for(std::size_t i=0; i < nbitems; ++i) + items_[i].reset(fill); // strings are resized, instead of reallocated + } + prefix_.resize(0); + } + + template< class Ch, class Tr, class Alloc> + basic_format& basic_format:: + clear () { + // empty the string buffers (except bound arguments) + // and make the format object ready for formatting a new set of arguments + + BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast(bound_.size()) ); + + for(unsigned long i=0; i + basic_format& basic_format:: + clear_binds () { + // remove all binds, then clear() + bound_.resize(0); + clear(); + return *this; + } + + template< class Ch, class Tr, class Alloc> + basic_format& basic_format:: + clear_bind (int argN) { + // remove the bind of ONE argument then clear() + if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] ) { + if( exceptions() & io::out_of_range_bit) + boost::throw_exception(io::out_of_range(argN, 1, num_args_+1 ) ); + else return *this; + } + bound_[argN-1]=false; + clear(); + return *this; + } + + template< class Ch, class Tr, class Alloc> + typename basic_format::string_type + basic_format:: + str () const { + if(items_.size()==0) + return prefix_; + if( cur_arg_ < num_args_) + if( exceptions() & io::too_few_args_bit ) + // not enough variables supplied + boost::throw_exception(io::too_few_args(cur_arg_, num_args_)); + + unsigned long i; + string_type res; + res.reserve(size()); + res += prefix_; + for(i=0; i < items_.size(); ++i) { + const format_item_t& item = items_[i]; + res += item.res_; + if( item.argN_ == format_item_t::argN_tabulation) { + BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation); + if( static_cast(item.fmtstate_.width_) > res.size() ) + res.append( static_cast(item.fmtstate_.width_) - res.size(), + item.fmtstate_.fill_ ); + } + res += item.appendix_; + } + dumped_=true; + return res; + } + template< class Ch, class Tr, class Alloc> + typename std::basic_string::size_type basic_format:: + size () const { +#ifdef BOOST_MSVC + // If std::min or std::max are already instantiated + // at this point then we get a blizzard of warning messages when we call + // those templates with std::size_t as arguments. Weird and very annoyning... +#pragma warning(push) +#pragma warning(disable:4267) +#endif + BOOST_USING_STD_MAX(); + size_type sz = prefix_.size(); + unsigned long i; + for(i=0; i < items_.size(); ++i) { + const format_item_t& item = items_[i]; + sz += item.res_.size(); + if( item.argN_ == format_item_t::argN_tabulation) + sz = max BOOST_PREVENT_MACRO_SUBSTITUTION (sz, + static_cast(item.fmtstate_.width_) ); + sz += item.appendix_.size(); + } + return sz; +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + } + +namespace io { +namespace detail { + + template + basic_format& + bind_arg_body (basic_format& self, int argN, const T& val) { + // bind one argument to a fixed value + // this is persistent over clear() calls, thus also over str() and << + if(self.dumped_) + self.clear(); // needed because we will modify cur_arg_ + if(argN<1 || argN > self.num_args_) { + if( self.exceptions() & io::out_of_range_bit ) + boost::throw_exception(io::out_of_range(argN, 1, self.num_args_+1 ) ); + else return self; + } + if(self.bound_.size()==0) + self.bound_.assign(self.num_args_,false); + else + BOOST_ASSERT( self.num_args_ == static_cast(self.bound_.size()) ); + int o_cur_arg = self.cur_arg_; + self.cur_arg_ = argN-1; // arrays begin at 0 + + self.bound_[self.cur_arg_]=false; // if already set, we unset and re-sets.. + self.operator%(val); // put val at the right place, because cur_arg is set + + + // Now re-position cur_arg before leaving : + self.cur_arg_ = o_cur_arg; + self.bound_[argN-1]=true; + if(self.cur_arg_ == argN-1 ) { + // hum, now this arg is bound, so move to next free arg + while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_]) + ++self.cur_arg_; + } + // In any case, we either have all args, or are on a non-binded arg : + BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]); + return self; + } + + template basic_format& + modify_item_body (basic_format& self, int itemN, T manipulator) { + // applies a manipulator to the format_item describing a given directive. + // this is a permanent change, clear or reset won't cancel that. + if(itemN<1 || itemN > static_cast(self.items_.size() )) { + if( self.exceptions() & io::out_of_range_bit ) + boost::throw_exception(io::out_of_range(itemN, 1, static_cast(self.items_.size()) )); + else return self; + } + self.items_[itemN-1].fmtstate_. template apply_manip ( manipulator ); + return self; + } + +} // namespace detail +} // namespace io +} // namespace boost + + + +#endif // BOOST_FORMAT_IMPLEMENTATION_HPP diff --git a/thirdparty/boost/format/free_funcs.hpp b/thirdparty/boost/format/free_funcs.hpp new file mode 100644 index 0000000..76b592a --- /dev/null +++ b/thirdparty/boost/format/free_funcs.hpp @@ -0,0 +1,70 @@ +// ---------------------------------------------------------------------------- +// free_funcs.hpp : implementation of the free functions of boost::format +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_FUNCS_HPP +#define BOOST_FORMAT_FUNCS_HPP + +#include +#include + +namespace boost { + + template inline + std::basic_string str(const basic_format& f) { + // adds up all pieces of strings and converted items, and return the formatted string + return f.str(); + } + namespace io { + using ::boost::str; // keep compatibility with when it was defined in this N.S. + } // - namespace io + +#ifndef BOOST_NO_TEMPLATE_STD_STREAM + template + std::basic_ostream & + operator<<( std::basic_ostream & os, + const basic_format& f) +#else + template + std::ostream & + operator<<( std::ostream & os, + const basic_format& f) +#endif + // effect: "return os << str(f);" but we can do it faster + { + typedef boost::basic_format format_t; + if(f.items_.size()==0) + os << f.prefix_; + else { + if(f.cur_arg_ < f.num_args_) + if( f.exceptions() & io::too_few_args_bit ) + // not enough variables supplied + boost::throw_exception(io::too_few_args(f.cur_arg_, f.num_args_)); + if(f.style_ & format_t::special_needs) + os << f.str(); + else { + // else we dont have to count chars output, so we dump directly to os : + os << f.prefix_; + for(unsigned long i=0; i + + +namespace boost { +namespace io { + + +namespace detail { + + +// empty group, but useful even though. +struct group0 +{ + group0() {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << ( BOOST_IO_STD basic_ostream& os, + const group0& ) +{ + return os; +} + +template +struct group1 +{ + T1 a1_; + group1(T1 a1) + : a1_(a1) + {} +private: + group1& operator=(const group1&); +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group1& x) +{ + os << x.a1_; + return os; +} + + + + +template +struct group2 +{ + T1 a1_; + T2 a2_; + group2(T1 a1,T2 a2) + : a1_(a1),a2_(a2) + {} +private: + group2& operator=(const group2&); +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group2& x) +{ + os << x.a1_<< x.a2_; + return os; +} + +template +struct group3 +{ + T1 a1_; + T2 a2_; + T3 a3_; + group3(T1 a1,T2 a2,T3 a3) + : a1_(a1),a2_(a2),a3_(a3) + {} +private: + group3& operator=(const group3&); +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group3& x) +{ + os << x.a1_<< x.a2_<< x.a3_; + return os; +} + +template +struct group4 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + group4(T1 a1,T2 a2,T3 a3,T4 a4) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4) + {} +private: + group4& operator=(const group4&); +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group4& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_; + return os; +} + +template +struct group5 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + group5(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group5& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_; + return os; +} + +template +struct group6 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + T6 a6_; + group6(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group6& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_; + return os; +} + +template +struct group7 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + T6 a6_; + T7 a7_; + group7(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group7& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_; + return os; +} + +template +struct group8 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + T6 a6_; + T7 a7_; + T8 a8_; + group8(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group8& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_; + return os; +} + +template +struct group9 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + T6 a6_; + T7 a7_; + T8 a8_; + T9 a9_; + group9(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group9& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_; + return os; +} + +template +struct group10 +{ + T1 a1_; + T2 a2_; + T3 a3_; + T4 a4_; + T5 a5_; + T6 a6_; + T7 a7_; + T8 a8_; + T9 a9_; + T10 a10_; + group10(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9,T10 a10) + : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9),a10_(a10) + {} +}; + +template +inline +BOOST_IO_STD basic_ostream& +operator << (BOOST_IO_STD basic_ostream& os, + const group10& x) +{ + os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_<< x.a10_; + return os; +} + + + + +template +inline +group1 +group_head( group2 const& x) +{ + return group1 (x.a1_); +} + +template +inline +group1 +group_last( group2 const& x) +{ + return group1 (x.a2_); +} + + + +template +inline +group2 +group_head( group3 const& x) +{ + return group2 (x.a1_,x.a2_); +} + +template +inline +group1 +group_last( group3 const& x) +{ + return group1 (x.a3_); +} + + + +template +inline +group3 +group_head( group4 const& x) +{ + return group3 (x.a1_,x.a2_,x.a3_); +} + +template +inline +group1 +group_last( group4 const& x) +{ + return group1 (x.a4_); +} + + + +template +inline +group4 +group_head( group5 const& x) +{ + return group4 (x.a1_,x.a2_,x.a3_,x.a4_); +} + +template +inline +group1 +group_last( group5 const& x) +{ + return group1 (x.a5_); +} + + + +template +inline +group5 +group_head( group6 const& x) +{ + return group5 (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_); +} + +template +inline +group1 +group_last( group6 const& x) +{ + return group1 (x.a6_); +} + + + +template +inline +group6 +group_head( group7 const& x) +{ + return group6 (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_); +} + +template +inline +group1 +group_last( group7 const& x) +{ + return group1 (x.a7_); +} + + + +template +inline +group7 +group_head( group8 const& x) +{ + return group7 (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_); +} + +template +inline +group1 +group_last( group8 const& x) +{ + return group1 (x.a8_); +} + + + +template +inline +group8 +group_head( group9 const& x) +{ + return group8 (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_); +} + +template +inline +group1 +group_last( group9 const& x) +{ + return group1 (x.a9_); +} + + + +template +inline +group9 +group_head( group10 const& x) +{ + return group9 (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_,x.a9_); +} + +template +inline +group1 +group_last( group10 const& x) +{ + return group1 (x.a10_); +} + + + + + +} // namespace detail + + + +// helper functions + + +inline detail::group1< detail::group0 > +group() { return detail::group1< detail::group0 > ( detail::group0() ); } + +template +inline +detail::group1< detail::group2 > + group(T1 a1, Var const& var) +{ + return detail::group1< detail::group2 > + ( detail::group2 + (a1, var) + ); +} + +template +inline +detail::group1< detail::group3 > + group(T1 a1,T2 a2, Var const& var) +{ + return detail::group1< detail::group3 > + ( detail::group3 + (a1,a2, var) + ); +} + +template +inline +detail::group1< detail::group4 > + group(T1 a1,T2 a2,T3 a3, Var const& var) +{ + return detail::group1< detail::group4 > + ( detail::group4 + (a1,a2,a3, var) + ); +} + +template +inline +detail::group1< detail::group5 > + group(T1 a1,T2 a2,T3 a3,T4 a4, Var const& var) +{ + return detail::group1< detail::group5 > + ( detail::group5 + (a1,a2,a3,a4, var) + ); +} + +template +inline +detail::group1< detail::group6 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var const& var) +{ + return detail::group1< detail::group6 > + ( detail::group6 + (a1,a2,a3,a4,a5, var) + ); +} + +template +inline +detail::group1< detail::group7 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var const& var) +{ + return detail::group1< detail::group7 > + ( detail::group7 + (a1,a2,a3,a4,a5,a6, var) + ); +} + +template +inline +detail::group1< detail::group8 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var const& var) +{ + return detail::group1< detail::group8 > + ( detail::group8 + (a1,a2,a3,a4,a5,a6,a7, var) + ); +} + +template +inline +detail::group1< detail::group9 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var const& var) +{ + return detail::group1< detail::group9 > + ( detail::group9 + (a1,a2,a3,a4,a5,a6,a7,a8, var) + ); +} + +template +inline +detail::group1< detail::group10 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var const& var) +{ + return detail::group1< detail::group10 > + ( detail::group10 + (a1,a2,a3,a4,a5,a6,a7,a8,a9, var) + ); +} + + +#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST + +template +inline +detail::group1< detail::group2 > + group(T1 a1, Var& var) +{ + return detail::group1< detail::group2 > + ( detail::group2 + (a1, var) + ); +} + +template +inline +detail::group1< detail::group3 > + group(T1 a1,T2 a2, Var& var) +{ + return detail::group1< detail::group3 > + ( detail::group3 + (a1,a2, var) + ); +} + +template +inline +detail::group1< detail::group4 > + group(T1 a1,T2 a2,T3 a3, Var& var) +{ + return detail::group1< detail::group4 > + ( detail::group4 + (a1,a2,a3, var) + ); +} + +template +inline +detail::group1< detail::group5 > + group(T1 a1,T2 a2,T3 a3,T4 a4, Var& var) +{ + return detail::group1< detail::group5 > + ( detail::group5 + (a1,a2,a3,a4, var) + ); +} + +template +inline +detail::group1< detail::group6 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var& var) +{ + return detail::group1< detail::group6 > + ( detail::group6 + (a1,a2,a3,a4,a5, var) + ); +} + +template +inline +detail::group1< detail::group7 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var& var) +{ + return detail::group1< detail::group7 > + ( detail::group7 + (a1,a2,a3,a4,a5,a6, var) + ); +} + +template +inline +detail::group1< detail::group8 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var& var) +{ + return detail::group1< detail::group8 > + ( detail::group8 + (a1,a2,a3,a4,a5,a6,a7, var) + ); +} + +template +inline +detail::group1< detail::group9 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var& var) +{ + return detail::group1< detail::group9 > + ( detail::group9 + (a1,a2,a3,a4,a5,a6,a7,a8, var) + ); +} + +template +inline +detail::group1< detail::group10 > + group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var& var) +{ + return detail::group1< detail::group10 > + ( detail::group10 + (a1,a2,a3,a4,a5,a6,a7,a8,a9, var) + ); +} + + +#endif // - BOOST_NO_OVERLOAD_FOR_NON_CONST + + +} // namespace io + +} // namespace boost + + +#endif // BOOST_FORMAT_GROUP_HPP diff --git a/thirdparty/boost/format/internals.hpp b/thirdparty/boost/format/internals.hpp new file mode 100644 index 0000000..9455e0b --- /dev/null +++ b/thirdparty/boost/format/internals.hpp @@ -0,0 +1,201 @@ +// ---------------------------------------------------------------------------- +// internals.hpp : internal structs : stream_format_state, format_item. +// included by format.hpp +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_INTERNALS_HPP +#define BOOST_FORMAT_INTERNALS_HPP + + +#include +#include +#include +#include +#include +#include // used as a dummy stream + +namespace boost { +namespace io { +namespace detail { + + +//---- stream_format_state --------------------------------------------------// + +// set of params that define the format state of a stream + template + struct stream_format_state + { + typedef BOOST_IO_STD basic_ios basic_ios; + + stream_format_state(Ch fill) { reset(fill); } +// stream_format_state(const basic_ios& os) { set_by_stream(os); } + + void reset(Ch fill); //- sets to default state. + void set_by_stream(const basic_ios& os); //- sets to os's state. + void apply_on(basic_ios & os, //- applies format_state to the stream + boost::io::detail::locale_t * loc_default = 0) const; + template + void apply_manip(T manipulator) //- modifies state by applying manipulator + { apply_manip_body( *this, manipulator) ; } + + // --- data --- + std::streamsize width_; + std::streamsize precision_; + Ch fill_; + std::ios_base::fmtflags flags_; + std::ios_base::iostate rdstate_; + std::ios_base::iostate exceptions_; + boost::optional loc_; + }; + + +//---- format_item ---------------------------------------------------------// + +// stores all parameters that can be specified in format strings + template + struct format_item + { + enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 }; + // 1. if zeropad is set, all other bits are not, + // 2. if tabulation is set, all others are not. + // centered and spacepad can be mixed freely. + enum arg_values { argN_no_posit = -1, // non-positional directive. will set argN later + argN_tabulation = -2, // tabulation directive. (no argument read) + argN_ignored = -3 // ignored directive. (no argument read) + }; + typedef BOOST_IO_STD basic_ios basic_ios; + typedef detail::stream_format_state stream_format_state; + typedef ::std::basic_string string_type; + + format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill), + truncate_(max_streamsize()), pad_scheme_(0) {} + void reset(Ch fill); + void compute_states(); // sets states according to truncate and pad_scheme. + + static std::streamsize max_streamsize() { + return (std::numeric_limits::max)(); + } + + // --- data --- + int argN_; //- argument number (starts at 0, eg : %1 => argN=0) + // negative values for items that don't process an argument + string_type res_; //- result of the formatting of this item + string_type appendix_; //- piece of string between this item and the next + + stream_format_state fmtstate_;// set by parsing, is only affected by modify_item + + std::streamsize truncate_;//- is set for directives like %.5s that ask truncation + unsigned int pad_scheme_;//- several possible padding schemes can mix. see pad_values + }; + + + +//--- Definitions ------------------------------------------------------------ + +// - stream_format_state:: ------------------------------------------------- + template + void stream_format_state:: apply_on (basic_ios & os, + boost::io::detail::locale_t * loc_default) const { + // set the state of this stream according to our params + if(width_ != -1) + os.width(width_); + if(precision_ != -1) + os.precision(precision_); + if(fill_ != 0) + os.fill(fill_); + os.flags(flags_); + os.clear(rdstate_); + os.exceptions(exceptions_); +#if !defined(BOOST_NO_STD_LOCALE) + if(loc_) + os.imbue(loc_.get()); + else if(loc_default) + os.imbue(*loc_default); +#else + (void) loc_default; // keep compiler quiet if we don't support locales +#endif + } + + template + void stream_format_state:: set_by_stream(const basic_ios& os) { + // set our params according to the state of this stream + flags_ = os.flags(); + width_ = os.width(); + precision_ = os.precision(); + fill_ = os.fill(); + rdstate_ = os.rdstate(); + exceptions_ = os.exceptions(); + } + + + template + void apply_manip_body( stream_format_state& self, + T manipulator) { + // modify our params according to the manipulator + basic_oaltstringstream ss; + self.apply_on( ss ); + ss << manipulator; + self.set_by_stream( ss ); + } + + template inline + void stream_format_state:: reset(Ch fill) { + // set our params to standard's default state. cf § 27.4.4.1 of the C++ norm + width_=0; precision_=6; + fill_=fill; // default is widen(' '), but we cant compute it without the locale + flags_ = std::ios_base::dec | std::ios_base::skipws; + // the adjust_field part is left equal to 0, which means right. + exceptions_ = std::ios_base::goodbit; + rdstate_ = std::ios_base::goodbit; + } + + +// --- format_item:: -------------------------------------------------------- + + template + void format_item:: + reset (Ch fill) { + argN_=argN_no_posit; truncate_ = max_streamsize(); pad_scheme_ =0; + res_.resize(0); appendix_.resize(0); + fmtstate_.reset(fill); + } + + template + void format_item:: + compute_states() { + // reflect pad_scheme_ on fmt_state_ + // because some pad_schemes has complex consequences on several state params. + if(pad_scheme_ & zeropad) { + // ignore zeropad in left alignment : + if(fmtstate_.flags_ & std::ios_base::left) { + BOOST_ASSERT(!(fmtstate_.flags_ &(std::ios_base::adjustfield ^std::ios_base::left))); + // only left bit might be set. (not right, nor internal) + pad_scheme_ = pad_scheme_ & (~zeropad); + } + else { + pad_scheme_ &= ~spacepad; // printf ignores spacepad when zeropadding + fmtstate_.fill_='0'; + fmtstate_.flags_ = (fmtstate_.flags_ & ~std::ios_base::adjustfield) + | std::ios_base::internal; + // removes all adjustfield bits, and adds internal. + } + } + if(pad_scheme_ & spacepad) { + if(fmtstate_.flags_ & std::ios_base::showpos) + pad_scheme_ &= ~spacepad; + } + } + + +} } } // namespaces boost :: io :: detail + + +#endif // BOOST_FORMAT_INTERNALS_HPP diff --git a/thirdparty/boost/format/internals_fwd.hpp b/thirdparty/boost/format/internals_fwd.hpp new file mode 100644 index 0000000..684d32a --- /dev/null +++ b/thirdparty/boost/format/internals_fwd.hpp @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------- +// internals_fwd.hpp : forward declarations, for internal headers +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_INTERNAL_FWD_HPP +#define BOOST_FORMAT_INTERNAL_FWD_HPP + +#include +#include + + +namespace boost { +namespace io { + +namespace detail { + template struct stream_format_state; + template struct format_item; + + + // these functions were intended as methods, + // but MSVC have problems with template member functions : + // defined in format_implementation.hpp : + template + basic_format& + modify_item_body (basic_format& self, + int itemN, T manipulator); + + template + basic_format& + bind_arg_body (basic_format& self, + int argN, const T& val); + + // in internals.hpp : + template + void apply_manip_body (stream_format_state& self, + T manipulator); + + // argument feeding (defined in feed_args.hpp ) : + template + void distribute (basic_format& self, T x); + + template + basic_format& + feed (basic_format& self, T x); + +} // namespace detail + +} // namespace io +} // namespace boost + + +#endif // BOOST_FORMAT_INTERNAL_FWD_HPP diff --git a/thirdparty/boost/format/parsing.hpp b/thirdparty/boost/format/parsing.hpp new file mode 100644 index 0000000..a42f924 --- /dev/null +++ b/thirdparty/boost/format/parsing.hpp @@ -0,0 +1,503 @@ +// ---------------------------------------------------------------------------- +// parsing.hpp : implementation of the parsing member functions +// ( parse, parse_printf_directive) +// ---------------------------------------------------------------------------- + +// Copyright Samuel Krempp 2003. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// see http://www.boost.org/libs/format for library home page + +// ---------------------------------------------------------------------------- + +#ifndef BOOST_FORMAT_PARSING_HPP +#define BOOST_FORMAT_PARSING_HPP + + +#include +#include +#include +#include + + +namespace boost { +namespace io { +namespace detail { + +#if defined(BOOST_NO_STD_LOCALE) + // streams will be used for narrow / widen. but these methods are not const + template + T& const_or_not(const T& x) { + return const_cast (x); + } +#else + template + const T& const_or_not(const T& x) { + return x; + } +#endif + + template inline + char wrap_narrow(const Facet& fac, Ch c, char deflt) { + return const_or_not(fac).narrow(c, deflt); + } + + template inline + bool wrap_isdigit(const Facet& fac, Ch c) { +#if ! defined( BOOST_NO_LOCALE_ISDIGIT ) + return fac.is(std::ctype::digit, c); +# else + using namespace std; + return isdigit(c); +#endif + } + + template + Iter wrap_scan_notdigit(const Facet & fac, Iter beg, Iter end) { + using namespace std; + for( ; beg!=end && wrap_isdigit(fac, *beg); ++beg) ; + return beg; + } + + + // Input : [start, last) iterators range and a + // a Facet to use its widen/narrow member function + // Effects : read sequence and convert digits into integral n, of type Res + // Returns : n + template + Iter str2int (const Iter & start, const Iter & last, Res & res, + const Facet& fac) + { + using namespace std; + Iter it; + res=0; + for(it=start; it != last && wrap_isdigit(fac, *it); ++it ) { + char cur_ch = wrap_narrow(fac, *it, 0); // cant fail. + res *= 10; + res += cur_ch - '0'; // 22.2.1.1.2.13 of the C++ standard + } + return it; + } + + // skip printf's "asterisk-fields" directives in the format-string buf + // Input : char string, with starting index *pos_p + // a Facet merely to use its widen/narrow member function + // Effects : advance *pos_p by skipping printf's asterisk fields. + // Returns : nothing + template + Iter skip_asterisk(Iter start, Iter last, const Facet& fac) + { + using namespace std; + ++ start; + start = wrap_scan_notdigit(fac, start, last); + if(start!=last && *start== const_or_not(fac).widen( '$') ) + ++start; + return start; + } + + + // auxiliary func called by parse_printf_directive + // for centralising error handling + // it either throws if user sets the corresponding flag, or does nothing. + inline void maybe_throw_exception(unsigned char exceptions, + std::size_t pos, std::size_t size) + { + if(exceptions & io::bad_format_string_bit) + boost::throw_exception(io::bad_format_string(pos, size) ); + } + + + // Input: the position of a printf-directive in the format-string + // a basic_ios& merely to use its widen/narrow member function + // a bitset'exceptions' telling whether to throw exceptions on errors. + // Returns: + // true if parse succeeded (ignore some errors if exceptions disabled) + // false if it failed so bad that the directive should be printed verbatim + // Effects: + // start is incremented so that *start is the first char after + // this directive + // *fpar is set with the parameters read in the directive + template + bool parse_printf_directive(Iter & start, const Iter& last, + detail::format_item * fpar, + const Facet& fac, + std::size_t offset, unsigned char exceptions) + { + typedef typename basic_format::format_item_t format_item_t; + + fpar->argN_ = format_item_t::argN_no_posit; // if no positional-directive + bool precision_set = false; + bool in_brackets=false; + Iter start0 = start; + std::size_t fstring_size = last-start0+offset; + + if(start>= last) { // empty directive : this is a trailing % + maybe_throw_exception(exceptions, start-start0 + offset, fstring_size); + return false; + } + + if(*start== const_or_not(fac).widen( '|')) { + in_brackets=true; + if( ++start >= last ) { + maybe_throw_exception(exceptions, start-start0 + offset, fstring_size); + return false; + } + } + + // the flag '0' would be picked as a digit for argument order, but here it's a flag : + if(*start== const_or_not(fac).widen( '0')) + goto parse_flags; + + // handle argument order (%2$d) or possibly width specification: %2d + if(wrap_isdigit(fac, *start)) { + int n; + start = str2int(start, last, n, fac); + if( start >= last ) { + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + return false; + } + + // %N% case : this is already the end of the directive + if( *start == const_or_not(fac).widen( '%') ) { + fpar->argN_ = n-1; + ++start; + if( in_brackets) + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + // but don't return. maybe "%" was used in lieu of '$', so we go on. + else + return true; + } + + if ( *start== const_or_not(fac).widen( '$') ) { + fpar->argN_ = n-1; + ++start; + } + else { + // non-positionnal directive + fpar->fmtstate_.width_ = n; + fpar->argN_ = format_item_t::argN_no_posit; + goto parse_precision; + } + } + + parse_flags: + // handle flags + while ( start != last) { // as long as char is one of + - = _ # 0 l h or ' ' + // misc switches + switch ( wrap_narrow(fac, *start, 0)) { + case '\'' : break; // no effect yet. (painful to implement) + case 'l': + case 'h': // short/long modifier : for printf-comaptibility (no action needed) + break; + case '-': + fpar->fmtstate_.flags_ |= std::ios_base::left; + break; + case '=': + fpar->pad_scheme_ |= format_item_t::centered; + break; + case '_': + fpar->fmtstate_.flags_ |= std::ios_base::internal; + break; + case ' ': + fpar->pad_scheme_ |= format_item_t::spacepad; + break; + case '+': + fpar->fmtstate_.flags_ |= std::ios_base::showpos; + break; + case '0': + fpar->pad_scheme_ |= format_item_t::zeropad; + // need to know alignment before really setting flags, + // so just add 'zeropad' flag for now, it will be processed later. + break; + case '#': + fpar->fmtstate_.flags_ |= std::ios_base::showpoint | std::ios_base::showbase; + break; + default: + goto parse_width; + } + ++start; + } // loop on flag. + + if( start>=last) { + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + return true; + } + parse_width: + // handle width spec + // first skip 'asterisk fields' : *, or *N$ + if(*start == const_or_not(fac).widen( '*') ) + start = skip_asterisk(start, last, fac); + if(start!=last && wrap_isdigit(fac, *start)) + start = str2int(start, last, fpar->fmtstate_.width_, fac); + + parse_precision: + if( start>= last) { + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + return true; + } + // handle precision spec + if (*start== const_or_not(fac).widen( '.')) { + ++start; + if(start != last && *start == const_or_not(fac).widen( '*') ) + start = skip_asterisk(start, last, fac); + if(start != last && wrap_isdigit(fac, *start)) { + start = str2int(start, last, fpar->fmtstate_.precision_, fac); + precision_set = true; + } + else + fpar->fmtstate_.precision_ =0; + } + + // handle formatting-type flags : + while( start != last && ( *start== const_or_not(fac).widen( 'l') + || *start== const_or_not(fac).widen( 'L') + || *start== const_or_not(fac).widen( 'h')) ) + ++start; + if( start>=last) { + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + return true; + } + + if( in_brackets && *start== const_or_not(fac).widen( '|') ) { + ++start; + return true; + } + switch ( wrap_narrow(fac, *start, 0) ) { + case 'X': + fpar->fmtstate_.flags_ |= std::ios_base::uppercase; + case 'p': // pointer => set hex. + case 'x': + fpar->fmtstate_.flags_ &= ~std::ios_base::basefield; + fpar->fmtstate_.flags_ |= std::ios_base::hex; + break; + + case 'o': + fpar->fmtstate_.flags_ &= ~std::ios_base::basefield; + fpar->fmtstate_.flags_ |= std::ios_base::oct; + break; + + case 'E': + fpar->fmtstate_.flags_ |= std::ios_base::uppercase; + case 'e': + fpar->fmtstate_.flags_ &= ~std::ios_base::floatfield; + fpar->fmtstate_.flags_ |= std::ios_base::scientific; + + fpar->fmtstate_.flags_ &= ~std::ios_base::basefield; + fpar->fmtstate_.flags_ |= std::ios_base::dec; + break; + + case 'f': + fpar->fmtstate_.flags_ &= ~std::ios_base::floatfield; + fpar->fmtstate_.flags_ |= std::ios_base::fixed; + case 'u': + case 'd': + case 'i': + fpar->fmtstate_.flags_ &= ~std::ios_base::basefield; + fpar->fmtstate_.flags_ |= std::ios_base::dec; + break; + + case 'T': + ++start; + if( start >= last) + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + else + fpar->fmtstate_.fill_ = *start; + fpar->pad_scheme_ |= format_item_t::tabulation; + fpar->argN_ = format_item_t::argN_tabulation; + break; + case 't': + fpar->fmtstate_.fill_ = const_or_not(fac).widen( ' '); + fpar->pad_scheme_ |= format_item_t::tabulation; + fpar->argN_ = format_item_t::argN_tabulation; + break; + + case 'G': + fpar->fmtstate_.flags_ |= std::ios_base::uppercase; + break; + case 'g': // 'g' conversion is default for floats. + fpar->fmtstate_.flags_ &= ~std::ios_base::basefield; + fpar->fmtstate_.flags_ |= std::ios_base::dec; + + // CLEAR all floatield flags, so stream will CHOOSE + fpar->fmtstate_.flags_ &= ~std::ios_base::floatfield; + break; + + case 'C': + case 'c': + fpar->truncate_ = 1; + break; + case 'S': + case 's': + if(precision_set) // handle truncation manually, with own parameter. + fpar->truncate_ = fpar->fmtstate_.precision_; + fpar->fmtstate_.precision_ = 6; // default stream precision. + break; + case 'n' : + fpar->argN_ = format_item_t::argN_ignored; + break; + default: + maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + } + ++start; + + if( in_brackets ) { + if( start != last && *start== const_or_not(fac).widen( '|') ) { + ++start; + return true; + } + else maybe_throw_exception(exceptions, start-start0+offset, fstring_size); + } + return true; + } + // -end parse_printf_directive() + + template + int upper_bound_from_fstring(const String& buf, + const typename String::value_type arg_mark, + const Facet& fac, + unsigned char exceptions) + { + // quick-parsing of the format-string to count arguments mark (arg_mark, '%') + // returns : upper bound on the number of format items in the format strings + using namespace boost::io; + typename String::size_type i1=0; + int num_items=0; + while( (i1=buf.find(arg_mark,i1)) != String::npos ) { + if( i1+1 >= buf.size() ) { + if(exceptions & bad_format_string_bit) + boost::throw_exception(bad_format_string(i1, buf.size() )); // must not end in ".. %" + else { + ++num_items; + break; + } + } + if(buf[i1+1] == buf[i1] ) {// escaped "%%" + i1+=2; continue; + } + + ++i1; + // in case of %N% directives, dont count it double (wastes allocations..) : + i1 = detail::wrap_scan_notdigit(fac, buf.begin()+i1, buf.end()) - buf.begin(); + if( i1 < buf.size() && buf[i1] == arg_mark ) + ++i1; + ++num_items; + } + return num_items; + } + template inline + void append_string(String& dst, const String& src, + const typename String::size_type beg, + const typename String::size_type end) { +#if !defined(BOOST_NO_STRING_APPEND) + dst.append(src.begin()+beg, src.begin()+end); +#else + dst += src.substr(beg, end-beg); +#endif + } + +} // detail namespace +} // io namespace + + + +// ----------------------------------------------- +// format :: parse(..) + + template + basic_format& basic_format:: + parse (const string_type& buf) { + // parse the format-string + using namespace std; +#if !defined(BOOST_NO_STD_LOCALE) + const std::ctype & fac = BOOST_USE_FACET( std::ctype, getloc()); +#else + io::basic_oaltstringstream fac; + //has widen and narrow even on compilers without locale +#endif + + const Ch arg_mark = io::detail::const_or_not(fac).widen( '%'); + bool ordered_args=true; + int max_argN=-1; + + // A: find upper_bound on num_items and allocates arrays + int num_items = io::detail::upper_bound_from_fstring(buf, arg_mark, fac, exceptions()); + make_or_reuse_data(num_items); + + // B: Now the real parsing of the format string : + num_items=0; + typename string_type::size_type i0=0, i1=0; + typename string_type::const_iterator it; + bool special_things=false; + int cur_item=0; + while( (i1=buf.find(arg_mark,i1)) != string_type::npos ) { + string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_; + if( buf[i1+1] == buf[i1] ) { // escaped mark, '%%' + io::detail::append_string(piece, buf, i0, i1+1); + i1+=2; i0=i1; + continue; + } + BOOST_ASSERT( static_cast(cur_item) < items_.size() || cur_item==0); + + if(i1!=i0) { + io::detail::append_string(piece, buf, i0, i1); + i0=i1; + } + ++i1; + it = buf.begin()+i1; + bool parse_ok = io::detail::parse_printf_directive( + it, buf.end(), &items_[cur_item], fac, i1, exceptions()); + i1 = it - buf.begin(); + if( ! parse_ok ) // the directive will be printed verbatim + continue; + i0=i1; + items_[cur_item].compute_states(); // process complex options, like zeropad, into params + + int argN=items_[cur_item].argN_; + if(argN == format_item_t::argN_ignored) + continue; + if(argN ==format_item_t::argN_no_posit) + ordered_args=false; + else if(argN == format_item_t::argN_tabulation) special_things=true; + else if(argN > max_argN) max_argN = argN; + ++num_items; + ++cur_item; + } // loop on %'s + BOOST_ASSERT(cur_item == num_items); + + // store the final piece of string + { + string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_; + io::detail::append_string(piece, buf, i0, buf.size()); + } + + if( !ordered_args) { + if(max_argN >= 0 ) { // dont mix positional with non-positionnal directives + if(exceptions() & io::bad_format_string_bit) + boost::throw_exception(io::bad_format_string(max_argN, 0)); + // else do nothing. => positionnal arguments are processed as non-positionnal + } + // set things like it would have been with positional directives : + int non_ordered_items = 0; + for(int i=0; i< num_items; ++i) + if(items_[i].argN_ == format_item_t::argN_no_posit) { + items_[i].argN_ = non_ordered_items; + ++non_ordered_items; + } + max_argN = non_ordered_items-1; + } + + // C: set some member data : + items_.resize(num_items, format_item_t(io::detail::const_or_not(fac).widen( ' ')) ); + + if(special_things) style_ |= special_needs; + num_args_ = max_argN + 1; + if(ordered_args) style_ |= ordered; + else style_ &= ~ordered; + return *this; + } + +} // namespace boost + + +#endif // BOOST_FORMAT_PARSING_HPP diff --git a/thirdparty/boost/function.hpp b/thirdparty/boost/function.hpp new file mode 100644 index 0000000..944ff83 --- /dev/null +++ b/thirdparty/boost/function.hpp @@ -0,0 +1,66 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org/libs/function + +// William Kempf, Jesse Jones and Karl Nelson were all very helpful in the +// design of this library. + +#include // unary_function, binary_function + +#include +#include + +#ifndef BOOST_FUNCTION_MAX_ARGS +# define BOOST_FUNCTION_MAX_ARGS 10 +#endif // BOOST_FUNCTION_MAX_ARGS + +// Include the prologue here so that the use of file-level iteration +// in anything that may be included by function_template.hpp doesn't break +#include + +// Visual Age C++ doesn't handle the file iteration well +#if BOOST_WORKAROUND(__IBMCPP__, >= 500) +# if BOOST_FUNCTION_MAX_ARGS >= 0 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 1 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 2 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 3 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 4 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 5 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 6 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 7 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 8 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 9 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 10 +# include +# endif +#else +// What is the '3' for? +# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_FUNCTION_MAX_ARGS,)) +# include BOOST_PP_ITERATE() +# undef BOOST_PP_ITERATION_PARAMS_1 +#endif diff --git a/thirdparty/boost/function/detail/function_iterate.hpp b/thirdparty/boost/function/detail/function_iterate.hpp new file mode 100644 index 0000000..d068cb7 --- /dev/null +++ b/thirdparty/boost/function/detail/function_iterate.hpp @@ -0,0 +1,16 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Function - do not include this file! +#endif + +#define BOOST_FUNCTION_NUM_ARGS BOOST_PP_ITERATION() +#include +#undef BOOST_FUNCTION_NUM_ARGS + diff --git a/thirdparty/boost/function/detail/gen_maybe_include.pl b/thirdparty/boost/function/detail/gen_maybe_include.pl new file mode 100644 index 0000000..1bfaab7 --- /dev/null +++ b/thirdparty/boost/function/detail/gen_maybe_include.pl @@ -0,0 +1,37 @@ +#!/usr/bin/perl -w +# +# Boost.Function library +# +# Copyright (C) 2001-2003 Douglas Gregor (gregod@cs.rpi.edu) +# +# Permission to copy, use, sell and distribute this software is granted +# provided this copyright notice appears in all copies. +# Permission to modify the code and to distribute modified code is granted +# provided this copyright notice appears in all copies, and a notice +# that the code was modified is included with the copyright notice. +# +# This software is provided "as is" without express or implied warranty, +# and with no claim as to its suitability for any purpose. +# +# For more information, see http://www.boost.org +use English; + +$max_args = $ARGV[0]; + +open (OUT, ">maybe_include.hpp") or die("Cannot write to maybe_include.hpp"); +for($on_arg = 0; $on_arg <= $max_args; ++$on_arg) { + if ($on_arg == 0) { + print OUT "#if"; + } + else { + print OUT "#elif"; + } + print OUT " BOOST_FUNCTION_NUM_ARGS == $on_arg\n"; + print OUT "# ifndef BOOST_FUNCTION_$on_arg\n"; + print OUT "# define BOOST_FUNCTION_$on_arg\n"; + print OUT "# include \n"; + print OUT "# endif\n"; +} +print OUT "#else\n"; +print OUT "# error Cannot handle Boost.Function objects that accept more than $max_args arguments!\n"; +print OUT "#endif\n"; diff --git a/thirdparty/boost/function/detail/maybe_include.hpp b/thirdparty/boost/function/detail/maybe_include.hpp new file mode 100644 index 0000000..10beac8 --- /dev/null +++ b/thirdparty/boost/function/detail/maybe_include.hpp @@ -0,0 +1,267 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#if BOOST_FUNCTION_NUM_ARGS == 0 +# ifndef BOOST_FUNCTION_0 +# define BOOST_FUNCTION_0 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 1 +# ifndef BOOST_FUNCTION_1 +# define BOOST_FUNCTION_1 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 2 +# ifndef BOOST_FUNCTION_2 +# define BOOST_FUNCTION_2 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 3 +# ifndef BOOST_FUNCTION_3 +# define BOOST_FUNCTION_3 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 4 +# ifndef BOOST_FUNCTION_4 +# define BOOST_FUNCTION_4 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 5 +# ifndef BOOST_FUNCTION_5 +# define BOOST_FUNCTION_5 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 6 +# ifndef BOOST_FUNCTION_6 +# define BOOST_FUNCTION_6 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 7 +# ifndef BOOST_FUNCTION_7 +# define BOOST_FUNCTION_7 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 8 +# ifndef BOOST_FUNCTION_8 +# define BOOST_FUNCTION_8 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 9 +# ifndef BOOST_FUNCTION_9 +# define BOOST_FUNCTION_9 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 10 +# ifndef BOOST_FUNCTION_10 +# define BOOST_FUNCTION_10 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 11 +# ifndef BOOST_FUNCTION_11 +# define BOOST_FUNCTION_11 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 12 +# ifndef BOOST_FUNCTION_12 +# define BOOST_FUNCTION_12 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 13 +# ifndef BOOST_FUNCTION_13 +# define BOOST_FUNCTION_13 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 14 +# ifndef BOOST_FUNCTION_14 +# define BOOST_FUNCTION_14 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 15 +# ifndef BOOST_FUNCTION_15 +# define BOOST_FUNCTION_15 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 16 +# ifndef BOOST_FUNCTION_16 +# define BOOST_FUNCTION_16 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 17 +# ifndef BOOST_FUNCTION_17 +# define BOOST_FUNCTION_17 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 18 +# ifndef BOOST_FUNCTION_18 +# define BOOST_FUNCTION_18 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 19 +# ifndef BOOST_FUNCTION_19 +# define BOOST_FUNCTION_19 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 20 +# ifndef BOOST_FUNCTION_20 +# define BOOST_FUNCTION_20 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 21 +# ifndef BOOST_FUNCTION_21 +# define BOOST_FUNCTION_21 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 22 +# ifndef BOOST_FUNCTION_22 +# define BOOST_FUNCTION_22 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 23 +# ifndef BOOST_FUNCTION_23 +# define BOOST_FUNCTION_23 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 24 +# ifndef BOOST_FUNCTION_24 +# define BOOST_FUNCTION_24 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 25 +# ifndef BOOST_FUNCTION_25 +# define BOOST_FUNCTION_25 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 26 +# ifndef BOOST_FUNCTION_26 +# define BOOST_FUNCTION_26 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 27 +# ifndef BOOST_FUNCTION_27 +# define BOOST_FUNCTION_27 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 28 +# ifndef BOOST_FUNCTION_28 +# define BOOST_FUNCTION_28 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 29 +# ifndef BOOST_FUNCTION_29 +# define BOOST_FUNCTION_29 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 30 +# ifndef BOOST_FUNCTION_30 +# define BOOST_FUNCTION_30 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 31 +# ifndef BOOST_FUNCTION_31 +# define BOOST_FUNCTION_31 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 32 +# ifndef BOOST_FUNCTION_32 +# define BOOST_FUNCTION_32 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 33 +# ifndef BOOST_FUNCTION_33 +# define BOOST_FUNCTION_33 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 34 +# ifndef BOOST_FUNCTION_34 +# define BOOST_FUNCTION_34 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 35 +# ifndef BOOST_FUNCTION_35 +# define BOOST_FUNCTION_35 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 36 +# ifndef BOOST_FUNCTION_36 +# define BOOST_FUNCTION_36 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 37 +# ifndef BOOST_FUNCTION_37 +# define BOOST_FUNCTION_37 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 38 +# ifndef BOOST_FUNCTION_38 +# define BOOST_FUNCTION_38 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 39 +# ifndef BOOST_FUNCTION_39 +# define BOOST_FUNCTION_39 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 40 +# ifndef BOOST_FUNCTION_40 +# define BOOST_FUNCTION_40 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 41 +# ifndef BOOST_FUNCTION_41 +# define BOOST_FUNCTION_41 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 42 +# ifndef BOOST_FUNCTION_42 +# define BOOST_FUNCTION_42 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 43 +# ifndef BOOST_FUNCTION_43 +# define BOOST_FUNCTION_43 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 44 +# ifndef BOOST_FUNCTION_44 +# define BOOST_FUNCTION_44 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 45 +# ifndef BOOST_FUNCTION_45 +# define BOOST_FUNCTION_45 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 46 +# ifndef BOOST_FUNCTION_46 +# define BOOST_FUNCTION_46 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 47 +# ifndef BOOST_FUNCTION_47 +# define BOOST_FUNCTION_47 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 48 +# ifndef BOOST_FUNCTION_48 +# define BOOST_FUNCTION_48 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 49 +# ifndef BOOST_FUNCTION_49 +# define BOOST_FUNCTION_49 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 50 +# ifndef BOOST_FUNCTION_50 +# define BOOST_FUNCTION_50 +# include +# endif +#else +# error Cannot handle Boost.Function objects that accept more than 50 arguments! +#endif diff --git a/thirdparty/boost/function/detail/prologue.hpp b/thirdparty/boost/function/detail/prologue.hpp new file mode 100644 index 0000000..3872c0a --- /dev/null +++ b/thirdparty/boost/function/detail/prologue.hpp @@ -0,0 +1,25 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_PROLOGUE_HPP +#define BOOST_FUNCTION_PROLOGUE_HPP +# include +# include +# include // unary_function, binary_function +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // BOOST_FUNCTION_PROLOGUE_HPP diff --git a/thirdparty/boost/function/function0.hpp b/thirdparty/boost/function/function0.hpp new file mode 100644 index 0000000..e510889 --- /dev/null +++ b/thirdparty/boost/function/function0.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 0 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function1.hpp b/thirdparty/boost/function/function1.hpp new file mode 100644 index 0000000..3109f50 --- /dev/null +++ b/thirdparty/boost/function/function1.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 1 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function10.hpp b/thirdparty/boost/function/function10.hpp new file mode 100644 index 0000000..0818f67 --- /dev/null +++ b/thirdparty/boost/function/function10.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 10 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function2.hpp b/thirdparty/boost/function/function2.hpp new file mode 100644 index 0000000..76e3b8c --- /dev/null +++ b/thirdparty/boost/function/function2.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 2 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function3.hpp b/thirdparty/boost/function/function3.hpp new file mode 100644 index 0000000..dd4f8cf --- /dev/null +++ b/thirdparty/boost/function/function3.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 3 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function4.hpp b/thirdparty/boost/function/function4.hpp new file mode 100644 index 0000000..32357e7 --- /dev/null +++ b/thirdparty/boost/function/function4.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 4 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function5.hpp b/thirdparty/boost/function/function5.hpp new file mode 100644 index 0000000..72f1479 --- /dev/null +++ b/thirdparty/boost/function/function5.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 5 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function6.hpp b/thirdparty/boost/function/function6.hpp new file mode 100644 index 0000000..1f82528 --- /dev/null +++ b/thirdparty/boost/function/function6.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 6 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function7.hpp b/thirdparty/boost/function/function7.hpp new file mode 100644 index 0000000..bf827b3 --- /dev/null +++ b/thirdparty/boost/function/function7.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 7 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function8.hpp b/thirdparty/boost/function/function8.hpp new file mode 100644 index 0000000..4511bc4 --- /dev/null +++ b/thirdparty/boost/function/function8.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 8 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function9.hpp b/thirdparty/boost/function/function9.hpp new file mode 100644 index 0000000..05725d5 --- /dev/null +++ b/thirdparty/boost/function/function9.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 9 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/thirdparty/boost/function/function_base.hpp b/thirdparty/boost/function/function_base.hpp new file mode 100644 index 0000000..b47a706 --- /dev/null +++ b/thirdparty/boost/function/function_base.hpp @@ -0,0 +1,762 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_BASE_HEADER +#define BOOST_FUNCTION_BASE_HEADER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_SFINAE +# include "boost/utility/enable_if.hpp" +#else +# include "boost/mpl/bool.hpp" +#endif +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4793 ) // complaint about native code generation +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info. +#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE +// Embedded VC++ does not have type_info in namespace std +# define BOOST_FUNCTION_STD_NS +#else +# define BOOST_FUNCTION_STD_NS std +#endif + +// Borrowed from Boost.Python library: determines the cases where we +// need to use std::type_info::name to compare instead of operator==. +# if (defined(__GNUC__) && __GNUC__ >= 3) \ + || defined(_AIX) \ + || ( defined(__sgi) && defined(__host_mips)) +# include +# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \ + (std::strcmp((X).name(),(Y).name()) == 0) +# else +# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) +#endif + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) +# define BOOST_FUNCTION_TARGET_FIX(x) x +#else +# define BOOST_FUNCTION_TARGET_FIX(x) +#endif // not MSVC + +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG) +// Work around a compiler bug. +// boost::python::objects::function has to be seen by the compiler before the +// boost::function class template. +namespace boost { namespace python { namespace objects { + class function; +}}} +#endif + +#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \ + || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540) +# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX +#endif + +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) +# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ + typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \ + (::boost::is_integral::value)>::value), \ + Type>::type +#else +// BCC doesn't recognize this depends on a template argument and complains +// about the use of 'typename' +# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ + ::boost::enable_if_c<(::boost::type_traits::ice_not< \ + (::boost::is_integral::value)>::value), \ + Type>::type +#endif + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) +namespace boost { + +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG) +// The library shipping with MIPSpro 7.3.1.3m has a broken allocator +class function_base; + +template > +class function; +#else +template > +class function; +#endif + +template +inline void swap(function& f1, + function& f2) +{ + f1.swap(f2); +} + +} // end namespace boost +#endif // have partial specialization + +namespace boost { + namespace detail { + namespace function { + class X; + + /** + * A buffer used to store small function objects in + * boost::function. It is a union containing function pointers, + * object pointers, and a structure that resembles a bound + * member function pointer. + */ + union function_buffer + { + // For pointers to function objects + void* obj_ptr; + + // For pointers to std::type_info objects + // (get_functor_type_tag, check_functor_type_tag). + const void* const_obj_ptr; + + // For function pointers of all kinds + mutable void (*func_ptr)(); + + // For bound member pointers + struct bound_memfunc_ptr_t { + void (X::*memfunc_ptr)(int); + void* obj_ptr; + } bound_memfunc_ptr; + + // To relax aliasing constraints + mutable char data; + }; + + /** + * The unusable class is a placeholder for unused function arguments + * It is also completely unusable except that it constructable from + * anything. This helps compilers without partial specialization to + * handle Boost.Function objects returning void. + */ + struct unusable + { + unusable() {} + template unusable(const T&) {} + }; + + /* Determine the return type. This supports compilers that do not support + * void returns or partial specialization by silently changing the return + * type to "unusable". + */ + template struct function_return_type { typedef T type; }; + + template<> + struct function_return_type + { + typedef unusable type; + }; + + // The operation type to perform on the given functor/function pointer + enum functor_manager_operation_type { + clone_functor_tag, + destroy_functor_tag, + check_functor_type_tag, + get_functor_type_tag + }; + + // Tags used to decide between different types of functions + struct function_ptr_tag {}; + struct function_obj_tag {}; + struct member_ptr_tag {}; + struct function_obj_ref_tag {}; + + template + class get_function_tag + { + typedef typename mpl::if_c<(is_pointer::value), + function_ptr_tag, + function_obj_tag>::type ptr_or_obj_tag; + + typedef typename mpl::if_c<(is_member_pointer::value), + member_ptr_tag, + ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag; + + typedef typename mpl::if_c<(is_reference_wrapper::value), + function_obj_ref_tag, + ptr_or_obj_or_mem_tag>::type or_ref_tag; + + public: + typedef or_ref_tag type; + }; + + // The trivial manager does nothing but return the same pointer (if we + // are cloning) or return the null pointer (if we are deleting). + template + struct reference_manager + { + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + switch (op) { + case clone_functor_tag: + out_buffer.obj_ptr = in_buffer.obj_ptr; + return; + + case destroy_functor_tag: + out_buffer.obj_ptr = 0; + return; + + case check_functor_type_tag: + { + // DPG TBD: Since we're only storing a pointer, it's + // possible that the user could ask for a base class or + // derived class. Is that okay? + const BOOST_FUNCTION_STD_NS::type_info& check_type = + *static_cast(out_buffer.const_obj_ptr); + if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))) + out_buffer.obj_ptr = in_buffer.obj_ptr; + else + out_buffer.obj_ptr = 0; + } + return; + + case get_functor_type_tag: + out_buffer.const_obj_ptr = &typeid(F); + return; + } + } + }; + + /** + * Determine if boost::function can use the small-object + * optimization with the function object type F. + */ + template + struct function_allows_small_object_optimization + { + BOOST_STATIC_CONSTANT + (bool, + value = ((sizeof(F) <= sizeof(function_buffer) && + (alignment_of::value + % alignment_of::value == 0)))); + }; + + /** + * The functor_manager class contains a static function "manage" which + * can clone or destroy the given function/function object pointer. + */ + template + struct functor_manager + { + private: + typedef Functor functor_type; + + // For function pointers, the manager is trivial + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_ptr_tag) + { + if (op == clone_functor_tag) + out_buffer.func_ptr = in_buffer.func_ptr; + else if (op == destroy_functor_tag) + out_buffer.func_ptr = 0; + else /* op == check_functor_type_tag */ { + const BOOST_FUNCTION_STD_NS::type_info& check_type = + *static_cast(out_buffer.const_obj_ptr); + if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) + out_buffer.obj_ptr = &in_buffer.func_ptr; + else + out_buffer.obj_ptr = 0; + } + } + + // Function objects that fit in the small-object buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::true_) + { + if (op == clone_functor_tag) { + const functor_type* in_functor = + reinterpret_cast(&in_buffer.data); + new ((void*)&out_buffer.data) functor_type(*in_functor); + } else if (op == destroy_functor_tag) { + // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. + reinterpret_cast(&out_buffer.data)->~Functor(); + } else /* op == check_functor_type_tag */ { + const BOOST_FUNCTION_STD_NS::type_info& check_type = + *static_cast(out_buffer.const_obj_ptr); + if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) + out_buffer.obj_ptr = &in_buffer.data; + else + out_buffer.obj_ptr = 0; + } + } + + // Function objects that require heap allocation + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::false_) + { +#ifndef BOOST_NO_STD_ALLOCATOR + typedef typename Allocator::template rebind::other + allocator_type; + typedef typename allocator_type::pointer pointer_type; +#else + typedef functor_type* pointer_type; +#endif // BOOST_NO_STD_ALLOCATOR + +# ifndef BOOST_NO_STD_ALLOCATOR + allocator_type allocator; +# endif // BOOST_NO_STD_ALLOCATOR + + if (op == clone_functor_tag) { + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + const functor_type* f = + (const functor_type*)(in_buffer.obj_ptr); + + // Clone the functor +# ifndef BOOST_NO_STD_ALLOCATOR + pointer_type copy = allocator.allocate(1); + allocator.construct(copy, *f); + + // Get back to the original pointer type + functor_type* new_f = static_cast(copy); +# else + functor_type* new_f = new functor_type(*f); +# endif // BOOST_NO_STD_ALLOCATOR + out_buffer.obj_ptr = new_f; + } else if (op == destroy_functor_tag) { + /* Cast from the void pointer to the functor pointer type */ + functor_type* f = + static_cast(out_buffer.obj_ptr); + +# ifndef BOOST_NO_STD_ALLOCATOR + /* Cast from the functor pointer type to the allocator's pointer + type */ + pointer_type victim = static_cast(f); + + // Destroy and deallocate the functor + allocator.destroy(victim); + allocator.deallocate(victim, 1); +# else + delete f; +# endif // BOOST_NO_STD_ALLOCATOR + out_buffer.obj_ptr = 0; + } else /* op == check_functor_type_tag */ { + const BOOST_FUNCTION_STD_NS::type_info& check_type = + *static_cast(out_buffer.const_obj_ptr); + if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor))) + out_buffer.obj_ptr = in_buffer.obj_ptr; + else + out_buffer.obj_ptr = 0; + } + } + + // For function objects, we determine whether the function + // object can use the small-object optimization buffer or + // whether we need to allocate it on the heap. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_obj_tag) + { + manager(in_buffer, out_buffer, op, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + } + + // For member pointers, we treat them as function objects with + // the small-object optimization always enabled. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, member_ptr_tag) + { + manager(in_buffer, out_buffer, op, mpl::true_()); + } + + public: + /* Dispatch to an appropriate manager based on whether we have a + function pointer or a function object pointer. */ + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + typedef typename get_function_tag::type tag_type; + switch (op) { + case get_functor_type_tag: + out_buffer.const_obj_ptr = &typeid(functor_type); + return; + + default: + manager(in_buffer, out_buffer, op, tag_type()); + return; + } + } + }; + + // A type that is only used for comparisons against zero + struct useless_clear_type {}; + +#ifdef BOOST_NO_SFINAE + // These routines perform comparisons between a Boost.Function + // object and an arbitrary function object (when the last + // parameter is mpl::bool_) or against zero (when the + // last parameter is mpl::bool_). They are only necessary + // for compilers that don't support SFINAE. + template + bool + compare_equal(const Function& f, const Functor&, int, mpl::bool_) + { return f.empty(); } + + template + bool + compare_not_equal(const Function& f, const Functor&, int, + mpl::bool_) + { return !f.empty(); } + + template + bool + compare_equal(const Function& f, const Functor& g, long, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + + template + bool + compare_equal(const Function& f, const reference_wrapper& g, + int, mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + + template + bool + compare_not_equal(const Function& f, const Functor& g, long, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + + template + bool + compare_not_equal(const Function& f, + const reference_wrapper& g, int, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } +#endif // BOOST_NO_SFINAE + + /** + * Stores the "manager" portion of the vtable for a + * boost::function object. + */ + struct vtable_base + { + void (*manager)(const function_buffer& in_buffer, + function_buffer& out_buffer, + functor_manager_operation_type op); + }; + } // end namespace function + } // end namespace detail + +/** + * The function_base class contains the basic elements needed for the + * function1, function2, function3, etc. classes. It is common to all + * functions (and as such can be used to tell if we have one of the + * functionN objects). + */ +class function_base +{ +public: + function_base() : vtable(0) { } + + /** Determine if the function is empty (i.e., has no target). */ + bool empty() const { return !vtable; } + + /** Retrieve the type of the stored function object, or typeid(void) + if this is empty. */ + const BOOST_FUNCTION_STD_NS::type_info& target_type() const + { + if (!vtable) return typeid(void); + + detail::function::function_buffer type; + vtable->manager(functor, type, detail::function::get_functor_type_tag); + return *static_cast(type.const_obj_ptr); + } + + template + Functor* target() + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.const_obj_ptr = &typeid(Functor); + vtable->manager(functor, type_result, + detail::function::check_functor_type_tag); + return static_cast(type_result.obj_ptr); + } + + template +#if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300) + const Functor* target( Functor * = 0 ) const +#else + const Functor* target() const +#endif + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.const_obj_ptr = &typeid(Functor); + vtable->manager(functor, type_result, + detail::function::check_functor_type_tag); + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + return (const Functor*)(type_result.obj_ptr); + } + + template + bool contains(const F& f) const + { +#if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300) + if (const F* fp = this->target( (F*)0 )) +#else + if (const F* fp = this->template target()) +#endif + { + return function_equal(*fp, f); + } else { + return false; + } + } + +#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3 + // GCC 3.3 and newer cannot copy with the global operator==, due to + // problems with instantiation of function return types before it + // has been verified that the argument types match up. + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g) const + { + if (const Functor* fp = target()) + return function_equal(*fp, g); + else return false; + } + + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g) const + { + if (const Functor* fp = target()) + return !function_equal(*fp, g); + else return true; + } +#endif + +public: // should be protected, but GCC 2.95.3 will fail to allow access + const detail::function::vtable_base* vtable; + mutable detail::function::function_buffer functor; +}; + +/** + * The bad_function_call exception class is thrown when a boost::function + * object is invoked + */ +class bad_function_call : public std::runtime_error +{ +public: + bad_function_call() : std::runtime_error("call to empty boost::function") {} +}; + +#ifndef BOOST_NO_SFINAE +inline bool operator==(const function_base& f, + detail::function::useless_clear_type*) +{ + return f.empty(); +} + +inline bool operator!=(const function_base& f, + detail::function::useless_clear_type*) +{ + return !f.empty(); +} + +inline bool operator==(detail::function::useless_clear_type*, + const function_base& f) +{ + return f.empty(); +} + +inline bool operator!=(detail::function::useless_clear_type*, + const function_base& f) +{ + return !f.empty(); +} +#endif + +#ifdef BOOST_NO_SFINAE +// Comparisons between boost::function objects and arbitrary function objects +template + inline bool operator==(const function_base& f, Functor g) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator==(Functor g, const function_base& f) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(const function_base& f, Functor g) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(Functor g, const function_base& f) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } +#else + +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) +// Comparisons between boost::function objects and arbitrary function +// objects. GCC 3.3 and before has an obnoxious bug that prevents this +// from working. +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return function_equal(g, *fp); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return !function_equal(g, *fp); + else return true; + } +# endif + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() == fp; + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() != fp; + else return true; + } + +#endif // Compiler supporting SFINAE + +namespace detail { + namespace function { + inline bool has_empty_target(const function_base* f) + { + return f->empty(); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + inline bool has_empty_target(const void*) + { + return false; + } +#else + inline bool has_empty_target(...) + { + return false; + } +#endif + } // end namespace function +} // end namespace detail +} // end namespace boost + +#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL +#undef BOOST_FUNCTION_COMPARE_TYPE_ID + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif + +#endif // BOOST_FUNCTION_BASE_HEADER diff --git a/thirdparty/boost/function/function_template.hpp b/thirdparty/boost/function/function_template.hpp new file mode 100644 index 0000000..1cc5cf9 --- /dev/null +++ b/thirdparty/boost/function/function_template.hpp @@ -0,0 +1,969 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +// Note: this header is a header template and must NOT have multiple-inclusion +// protection. +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) + +#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) + +#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I) + +#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) + +#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) + +#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ + typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); + +#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) + +// Type of the default allocator +#ifndef BOOST_NO_STD_ALLOCATOR +# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator +#else +# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int +#endif // BOOST_NO_STD_ALLOCATOR + +// Comma if nonzero number of arguments +#if BOOST_FUNCTION_NUM_ARGS == 0 +# define BOOST_FUNCTION_COMMA +#else +# define BOOST_FUNCTION_COMMA , +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + +// Class names used in this version of the code +#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_INVOKER \ + BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ + BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \ + BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \ + BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_MEMBER_INVOKER \ + BOOST_JOIN(member_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \ + BOOST_JOIN(void_member_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ + BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \ + BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_MEMBER_INVOKER \ + BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_INVOKER \ + BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) + +#ifndef BOOST_NO_VOID_RETURNS +# define BOOST_FUNCTION_VOID_RETURN_TYPE void +# define BOOST_FUNCTION_RETURN(X) X +#else +# define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable +# define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE () +#endif + +namespace boost { + namespace detail { + namespace function { + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_INVOKER + { + static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + { + FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); + return f(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); + BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(&function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(&function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_REF_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Handle invocation of member pointers. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_MEMBER_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(&function_obj_ptr.data); + return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_MEMBER_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(&function_obj_ptr.data); + BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); + } + }; +#endif + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the appropriate invoker for a member pointer. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_MEMBER_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; +#endif + + /* Given the tag returned by get_function_tag, retrieve the + actual invoker that will be used for the given function + object. + + Each specialization contains an "apply" nested class template + that accepts the function object, return type, function + argument types, and allocator. The resulting "apply" class + contains two typedefs, "invoker_type" and "manager_type", + which correspond to the invoker and manager types. */ + template + struct BOOST_FUNCTION_GET_INVOKER { }; + + /* Retrieve the invoker for a function pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the invoker for a member pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; +#endif + + /* Retrieve the invoker for a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; + + /* Retrieve the invoker for a reference to a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< + typename RefWrapper::type, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef reference_manager manager_type; + }; + }; + + /** + * vtable for a specific boost::function instance. + */ + template + struct BOOST_FUNCTION_VTABLE + { +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename function_return_type::type result_type; +#endif // BOOST_NO_VOID_RETURNS + + typedef result_type (*invoker_type)(function_buffer& + BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS); + + template + bool assign_to(const F& f, function_buffer& functor) const + { + typedef typename get_function_tag::type tag; + return assign_to(f, functor, tag()); + } + + void clear(function_buffer& functor) const + { + if (base.manager) + base.manager(functor, functor, destroy_functor_tag); + } +#ifndef BOOST_NO_PRIVATE_IN_AGGREGATE + private: +#endif + // Function pointers + template + bool + assign_to(FunctionPtr f, function_buffer& functor, + function_ptr_tag) const + { + this->clear(functor); + if (f) { + // should be a reinterpret cast, but some compilers insist + // on giving cv-qualifiers to free functions + functor.func_ptr = (void (*)())(f); + return true; + } else { + return false; + } + } + + // Member pointers +#if BOOST_FUNCTION_NUM_ARGS > 0 + template + bool + assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const + { + if (f) { + // Always use the small-object optimization for member + // pointers. + assign_functor(f, functor, mpl::true_()); + return true; + } else { + return false; + } + } +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + + // Function objects + // Assign to a function object using the small object optimization + template + void + assign_functor(const FunctionObj& f, function_buffer& functor, + mpl::true_) const + { + new ((void*)&functor.data) FunctionObj(f); + } + + // Assign to a function object allocated on the heap. + template + void + assign_functor(const FunctionObj& f, function_buffer& functor, + mpl::false_) const + { +#ifndef BOOST_NO_STD_ALLOCATOR + typedef typename Allocator::template rebind::other + allocator_type; + typedef typename allocator_type::pointer pointer_type; + + allocator_type allocator; + pointer_type copy = allocator.allocate(1); + allocator.construct(copy, f); + + // Get back to the original pointer type + functor.obj_ptr = static_cast(copy); +# else + functor.obj_ptr = new FunctionObj(f); +# endif // BOOST_NO_STD_ALLOCATOR + } + + template + bool + assign_to(const FunctionObj& f, function_buffer& functor, + function_obj_tag) const + { + if (!boost::detail::function::has_empty_target(boost::addressof(f))) { + assign_functor(f, functor, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + return true; + } else { + return false; + } + } + + // Reference to a function object + template + bool + assign_to(const reference_wrapper& f, + function_buffer& functor, function_obj_ref_tag) const + { + if (!boost::detail::function::has_empty_target(f.get_pointer())) { + // DPG TBD: We might need to detect constness of + // FunctionObj to assign into obj_ptr or const_obj_ptr to + // be truly legit, but no platform in existence makes + // const void* different from void*. + functor.const_obj_ptr = f.get_pointer(); + return true; + } else { + return false; + } + } + + public: + vtable_base base; + invoker_type invoker; + }; + } // end namespace function + } // end namespace detail + + template< + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS, + typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR + > + class BOOST_FUNCTION_FUNCTION : public function_base + +#if BOOST_FUNCTION_NUM_ARGS == 1 + + , public std::unary_function + +#elif BOOST_FUNCTION_NUM_ARGS == 2 + + , public std::binary_function + +#endif + + { + public: +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename boost::detail::function::function_return_type::type + result_type; +#endif // BOOST_NO_VOID_RETURNS + + private: + typedef boost::detail::function::BOOST_FUNCTION_VTABLE< + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, Allocator> + vtable_type; + + struct clear_type {}; + + public: + BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); + + // add signature for boost::lambda + template + struct sig + { + typedef result_type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS == 1 + typedef T0 argument_type; +#elif BOOST_FUNCTION_NUM_ARGS == 2 + typedef T0 first_argument_type; + typedef T1 second_argument_type; +#endif + + BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); + BOOST_FUNCTION_ARG_TYPES + + typedef Allocator allocator_type; + typedef BOOST_FUNCTION_FUNCTION self_type; + + BOOST_FUNCTION_FUNCTION() : function_base() { } + + // MSVC chokes if the following two constructors are collapsed into + // one with a default parameter. + template + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f +#ifndef BOOST_NO_SFINAE + ,typename enable_if_c< + (boost::type_traits::ice_not< + (is_integral::value)>::value), + int>::type = 0 +#endif // BOOST_NO_SFINAE + ) : + function_base() + { + this->assign_to(f); + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } +#else + BOOST_FUNCTION_FUNCTION(int zero) : function_base() + { + BOOST_ASSERT(zero == 0); + } +#endif + + BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base() + { + this->assign_to_own(f); + } + + ~BOOST_FUNCTION_FUNCTION() { clear(); } + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // MSVC 6.0 and prior require all definitions to be inline, but + // these definitions can become very costly. + result_type operator()(BOOST_FUNCTION_PARMS) const + { + if (this->empty()) + boost::throw_exception(bad_function_call()); + + return reinterpret_cast(vtable)->invoker + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); + } +#else + result_type operator()(BOOST_FUNCTION_PARMS) const; +#endif + + // The distinction between when to use BOOST_FUNCTION_FUNCTION and + // when to use self_type is obnoxious. MSVC cannot handle self_type as + // the return type of these assignment operators, but Borland C++ cannot + // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to + // construct. + template +#ifndef BOOST_NO_SFINAE + typename enable_if_c< + (boost::type_traits::ice_not< + (is_integral::value)>::value), + BOOST_FUNCTION_FUNCTION&>::type +#else + BOOST_FUNCTION_FUNCTION& +#endif + operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) + { + this->clear(); +#ifndef BOOST_NO_EXCEPTIONS + try { + this->assign_to(f); + } catch (...) { + vtable = 0; + throw; + } +#else + this->assign_to(f); +#endif + return *this; + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION& operator=(clear_type*) + { + this->clear(); + return *this; + } +#else + BOOST_FUNCTION_FUNCTION& operator=(int zero) + { + BOOST_ASSERT(zero == 0); + this->clear(); + return *this; + } +#endif + + // Assignment from another BOOST_FUNCTION_FUNCTION + BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f) + { + if (&f == this) + return *this; + + this->clear(); +#ifndef BOOST_NO_EXCEPTIONS + try { + this->assign_to_own(f); + } catch (...) { + vtable = 0; + throw; + } +#else + this->assign_to_own(f); +#endif + return *this; + } + + void swap(BOOST_FUNCTION_FUNCTION& other) + { + if (&other == this) + return; + + BOOST_FUNCTION_FUNCTION tmp = *this; + *this = other; + other = tmp; + } + + // Clear out a target, if there is one + void clear() + { + if (vtable) { + reinterpret_cast(vtable)->clear(this->functor); + vtable = 0; + } + } + +#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) + // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it + operator bool () const { return !this->empty(); } +#else + private: + struct dummy { + void nonnull() {}; + }; + + typedef void (dummy::*safe_bool)(); + + public: + operator safe_bool () const + { return (this->empty())? 0 : &dummy::nonnull; } + + bool operator!() const + { return this->empty(); } +#endif + + private: + void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) + { + if (!f.empty()) { + this->vtable = f.vtable; + f.vtable->manager(f.functor, this->functor, + boost::detail::function::clone_functor_tag); + } + } + + template + void assign_to(const Functor& f) + { + using detail::function::vtable_base; + + typedef typename detail::function::get_function_tag::type tag; + typedef detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; + typedef typename get_invoker:: + template apply + handler_type; + + typedef typename handler_type::invoker_type invoker_type; + typedef typename handler_type::manager_type manager_type; + + static const vtable_type stored_vtable = + { { &manager_type::manage }, &invoker_type::invoke }; + + if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base; + else vtable = 0; + } + }; + + template + inline void swap(BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator + >& f1, + BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS, + Allocator + >& f2) + { + f1.swap(f2); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + typename BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, + Allocator>::result_type + BOOST_FUNCTION_FUNCTION + ::operator()(BOOST_FUNCTION_PARMS) const + { + if (this->empty()) + boost::throw_exception(bad_function_call()); + + return reinterpret_cast(vtable)->invoker + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); + } +#endif + +// Poison comparisons between boost::function objects of the same type. +template + void operator==(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>&); +template + void operator!=(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>&); + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + +#if BOOST_FUNCTION_NUM_ARGS == 0 +#define BOOST_FUNCTION_PARTIAL_SPEC R (void) +#else +#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T)) +#endif + +template +class function + : public BOOST_FUNCTION_FUNCTION +{ + typedef BOOST_FUNCTION_FUNCTION base_type; + typedef function self_type; + + struct clear_type {}; + +public: + typedef typename base_type::allocator_type allocator_type; + + function() : base_type() {} + + template + function(Functor f +#ifndef BOOST_NO_SFINAE + ,typename enable_if_c< + (boost::type_traits::ice_not< + (is_integral::value)>::value), + int>::type = 0 +#endif + ) : + base_type(f) + { + } + +#ifndef BOOST_NO_SFINAE + function(clear_type*) : base_type() {} +#endif + + function(const self_type& f) : base_type(static_cast(f)){} + + function(const base_type& f) : base_type(static_cast(f)){} + + self_type& operator=(const self_type& f) + { + self_type(f).swap(*this); + return *this; + } + + template +#ifndef BOOST_NO_SFINAE + typename enable_if_c< + (boost::type_traits::ice_not< + (is_integral::value)>::value), + self_type&>::type +#else + self_type& +#endif + operator=(Functor f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_SFINAE + self_type& operator=(clear_type*) + { + this->clear(); + return *this; + } +#endif + + self_type& operator=(const base_type& f) + { + self_type(f).swap(*this); + return *this; + } +}; + +#undef BOOST_FUNCTION_PARTIAL_SPEC +#endif // have partial specialization + +} // end namespace boost + +// Cleanup after ourselves... +#undef BOOST_FUNCTION_VTABLE +#undef BOOST_FUNCTION_GET_INVOKER +#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR +#undef BOOST_FUNCTION_COMMA +#undef BOOST_FUNCTION_FUNCTION +#undef BOOST_FUNCTION_FUNCTION_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER +#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_MEMBER_INVOKER +#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_GET_MEMBER_INVOKER +#undef BOOST_FUNCTION_TEMPLATE_PARMS +#undef BOOST_FUNCTION_TEMPLATE_ARGS +#undef BOOST_FUNCTION_PARMS +#undef BOOST_FUNCTION_PARM +#undef BOOST_FUNCTION_ARGS +#undef BOOST_FUNCTION_ARG_TYPE +#undef BOOST_FUNCTION_ARG_TYPES +#undef BOOST_FUNCTION_VOID_RETURN_TYPE +#undef BOOST_FUNCTION_RETURN + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif diff --git a/thirdparty/boost/function/gen_function_N.pl b/thirdparty/boost/function/gen_function_N.pl new file mode 100644 index 0000000..6d1ca2f --- /dev/null +++ b/thirdparty/boost/function/gen_function_N.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl -w +# +# Boost.Function library +# +# Copyright Douglas Gregor 2001-2003. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# For more information, see http://www.boost.org +use English; + +if ($#ARGV < 0) { + print "Usage: perl gen_function_N \n"; + exit; +} + + +$totalNumArgs = $ARGV[0]; +for ($numArgs = 0; $numArgs <= $totalNumArgs; ++$numArgs) { + open OUT, ">function$numArgs.hpp"; + print OUT "#define BOOST_FUNCTION_NUM_ARGS $numArgs\n"; + print OUT "#include \n"; + print OUT "#undef BOOST_FUNCTION_NUM_ARGS\n"; + close OUT; +} diff --git a/thirdparty/boost/function_equal.hpp b/thirdparty/boost/function_equal.hpp new file mode 100644 index 0000000..35e6642 --- /dev/null +++ b/thirdparty/boost/function_equal.hpp @@ -0,0 +1,28 @@ +// Copyright Douglas Gregor 2004. +// Copyright 2005 Peter Dimov + +// Use, modification and distribution is subject to +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org +#ifndef BOOST_FUNCTION_EQUAL_HPP +#define BOOST_FUNCTION_EQUAL_HPP + +namespace boost { + +template + bool function_equal_impl(const F& f, const G& g, long) + { return f == g; } + +// function_equal_impl needs to be unqualified to pick +// user overloads on two-phase compilers + +template + bool function_equal(const F& f, const G& g) + { return function_equal_impl(f, g, 0); } + +} // end namespace boost + +#endif // BOOST_FUNCTION_EQUAL_HPP diff --git a/thirdparty/boost/function_output_iterator.hpp b/thirdparty/boost/function_output_iterator.hpp new file mode 100644 index 0000000..8227cbb --- /dev/null +++ b/thirdparty/boost/function_output_iterator.hpp @@ -0,0 +1,56 @@ +// (C) Copyright Jeremy Siek 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) + +// Revision History: + +// 27 Feb 2001 Jeremy Siek +// Initial checkin. + +#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP +#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP + +#include + +namespace boost { + + template + class function_output_iterator { + typedef function_output_iterator self; + public: + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit function_output_iterator() {} + + explicit function_output_iterator(const UnaryFunction& f) + : m_f(f) {} + + struct output_proxy { + output_proxy(UnaryFunction& f) : m_f(f) { } + template output_proxy& operator=(const T& value) { + m_f(value); + return *this; + } + UnaryFunction& m_f; + }; + output_proxy operator*() { return output_proxy(m_f); } + self& operator++() { return *this; } + self& operator++(int) { return *this; } + private: + UnaryFunction m_f; + }; + + template + inline function_output_iterator + make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) { + return function_output_iterator(f); + } + +} // namespace boost + +#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP diff --git a/thirdparty/boost/function_types/components.hpp b/thirdparty/boost/function_types/components.hpp new file mode 100644 index 0000000..6963d00 --- /dev/null +++ b/thirdparty/boost/function_types/components.hpp @@ -0,0 +1,431 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_COMPONENTS_HPP_INCLUDED +#define BOOST_FT_COMPONENTS_HPP_INCLUDED + +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x656)) +# include + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +#endif + +#ifndef BOOST_FT_NO_CV_FUNC_SUPPORT +# include +#endif + +#include + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# if BOOST_FT_MAX_ARITY < 10 +# include +# elif BOOST_FT_MAX_ARITY < 20 +# include +# elif BOOST_FT_MAX_ARITY < 30 +# include +# elif BOOST_FT_MAX_ARITY < 40 +# include +# elif BOOST_FT_MAX_ARITY < 50 +# include +# endif +#else +# include +#endif + +#include +#include + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +namespace boost +{ + namespace function_types + { + + using mpl::placeholders::_; + + template< typename T, typename ClassTypeTransform = add_reference<_> > + struct components; + + namespace detail + { + template struct components_impl; +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x565)) + template struct components_bcc; +#endif + } + + template + struct components +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x565)) + : detail::components_impl +#else + : detail::components_bcc::type,T, + ClassTypeTransform> +#endif + { + typedef components type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,components,(T,ClassTypeTransform)) + }; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + namespace detail { + + struct components_mpl_sequence_tag; + + struct components_non_func_base + { + typedef mpl::vector0<> types; + typedef void function_arity; + + typedef detail::constant<0> bits; + typedef detail::constant<0> mask; + + typedef components_mpl_sequence_tag tag; + }; + + template + < typename Components + , typename IfTagged + , typename ThenTag + , typename DefaultBase = components_non_func_base + > + struct retagged_if + : mpl::if_ + < detail::represents_impl + , detail::changed_tag + , DefaultBase + >::type + { }; + + // We detect plain function types and function references as function + // pointers by recursive instantiation of components_impl. + // The third specialization of components_impl makes sure the recursion + // terminates (when adding pointers). + template + struct components_impl + : detail::retagged_if + < detail::components_impl + , pointer_tag, /* --> */ function_tag > + { }; + template + struct components_impl + : detail::retagged_if + < detail::components_impl + , pointer_tag, /* --> */ reference_tag > + { }; + +#if !BOOST_FT_NO_CV_FUNC_SUPPORT + // Retry the type with a member pointer attached to detect cv functions + class a_class; + + template + struct cv_func_base + : detail::retagged_if + { + typedef typename + mpl::remove + < typename Base::types + , typename detail::class_transform::type>::type + types; + }; + + template + struct components_impl + : mpl::if_ + < detail::represents_impl< detail::components_impl + , member_pointer_tag > + , detail::cv_func_base< detail::components_impl, T, L> + , components_non_func_base + >::type + { }; + + template + struct components_impl + : components_non_func_base + { }; +#else + template + struct components_impl + : components_non_func_base + { }; +#endif + + template + struct components_impl + : components_impl + { }; + + template + struct components_impl + : components_impl + { }; + + template + struct components_impl + : components_impl + { }; + + template + struct components_impl + : components_impl + { }; + + template + struct components_impl + : components_impl + { }; + + template + struct components_impl + : components_impl + { }; + + + template + struct member_obj_ptr_result + { typedef T & type; }; + + template + struct member_obj_ptr_result + { typedef T const & type; }; + + template + struct member_obj_ptr_result + { typedef T volatile & type; }; + + template + struct member_obj_ptr_result + { typedef T const volatile & type; }; + + template + struct member_obj_ptr_result + { typedef T & type; }; + + template + struct member_obj_ptr_result + { typedef T & type; }; + + template + struct member_obj_ptr_result + { typedef T & type; }; + + template + struct member_obj_ptr_result + { typedef T & type; }; + + template + struct member_obj_ptr_components + : member_object_pointer_base + { + typedef function_types::components type; + typedef components_mpl_sequence_tag tag; + + typedef mpl::integral_c function_arity; + + typedef mpl::vector2< typename detail::member_obj_ptr_result::type, + typename detail::class_transform::type > types; + }; + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x565)) +# define BOOST_FT_variations BOOST_FT_pointer|BOOST_FT_member_pointer + + template + struct components_impl + : member_obj_ptr_components + { }; + +#else +# define BOOST_FT_variations BOOST_FT_pointer + + // This workaround removes the member pointer from the type to allow + // detection of member function pointers with BCC. + template + struct components_impl + : detail::retagged_if + < detail::components_impl::type *, L> + , pointer_tag, /* --> */ member_function_pointer_tag + , member_obj_ptr_components > + { }; + + // BCC lets us test the cv-qualification of a function type by template + // partial specialization - so we use this bug feature to find out the + // member function's cv-qualification (unfortunately there are some + // invisible modifiers that impose some limitations on these types even if + // we remove the qualifiers, So we cannot exploit the same bug to make the + // library work for cv-qualified function types). + template struct encode_cv + { typedef char (& type)[1]; BOOST_STATIC_CONSTANT(std::size_t, value = 1); }; + template struct encode_cv + { typedef char (& type)[2]; BOOST_STATIC_CONSTANT(std::size_t, value = 2); }; + template struct encode_cv + { typedef char (& type)[3]; BOOST_STATIC_CONSTANT(std::size_t, value = 3); }; + template struct encode_cv + { typedef char (& type)[4]; BOOST_STATIC_CONSTANT(std::size_t, value = 4); }; + + // For member function pointers we have to use a function template (partial + // template specialization for a member pointer drops the cv qualification + // of the function type). + template + typename encode_cv::type mfp_cv_tester(T C::*); + + template struct encode_mfp_cv + { + BOOST_STATIC_CONSTANT(std::size_t, value = + sizeof(detail::mfp_cv_tester((T)0L))); + }; + + // Associate bits with the CV codes above. + template struct cv_tag_mfp_impl; + + template struct cv_tag_mfp + : detail::cv_tag_mfp_impl + < ::boost::function_types::detail::encode_mfp_cv::value > + { }; + + template<> struct cv_tag_mfp_impl<1> : non_cv { }; + template<> struct cv_tag_mfp_impl<2> : const_non_volatile { }; + template<> struct cv_tag_mfp_impl<3> : volatile_non_const { }; + template<> struct cv_tag_mfp_impl<4> : cv_qualified { }; + + // Metafunction to decode the cv code and apply it to a type. + // We add a pointer, because otherwise cv-qualifiers won't stick (another bug). + template struct decode_cv; + + template struct decode_cv : mpl::identity {}; + template struct decode_cv : mpl::identity {}; + template struct decode_cv : mpl::identity {}; + template struct decode_cv + : mpl::identity {}; + + // The class type transformation comes after adding cv-qualifiers. We have + // wrap it to remove the pointer added in decode_cv_impl. + template struct bcc_class_transform_impl; + template struct bcc_class_transform_impl + : class_transform + { }; + + template struct bcc_class_transform + : bcc_class_transform_impl + < typename decode_cv + < T + , ::boost::function_types::detail::encode_mfp_cv::value + >::type + , L + > + { }; + + // After extracting the member pointee from the type the class type is still + // in the type (somewhere -- you won't see with RTTI, that is) and that type + // is flagged unusable and *not* identical to the nonmember function type. + // We can, however, decompose this type via components_impl but surprisingly + // a pointer to the const qualified class type pops up again as the first + // parameter type. + // We have to replace this type with the properly cv-qualified and + // transformed class type, integrate the cv qualification into the bits. + template + struct mfp_components; + + + template + struct mfp_components + { + private: + typedef typename mpl::front::type result_type; + typedef typename detail::bcc_class_transform::type class_type; + + typedef mpl::vector2 result_and_class_type; + + typedef typename + mpl::advance + < typename mpl::begin::type + , typename mpl::if_ + < mpl::equal_to< typename detail::classifier::function_arity + , typename Base::function_arity > + , mpl::integral_c , mpl::integral_c + >::type + >::type + from; + typedef typename mpl::end::type to; + + typedef mpl::iterator_range param_types; + + typedef mpl::joint_view< result_and_class_type, param_types> types_view; + public: + + typedef typename + mpl::reverse_copy > >::type + types; + + typedef typename + function_types::tag< Base, detail::cv_tag_mfp >::bits + bits; + + typedef typename Base::mask mask; + + typedef typename detail::classifier::function_arity function_arity; + + typedef components_mpl_sequence_tag tag; + }; + + // Now put it all together: detect cv-qualification of function types and do + // the weird transformations above for member function pointers. + template + struct components_bcc + : mpl::if_ + < detail::represents_impl< detail::components_impl + , member_function_pointer_tag> + , detail::mfp_components,T,OrigT,L> + , detail::components_impl + >::type + { }; + +#endif // end of BORLAND WORKAROUND + +#define BOOST_FT_al_path boost/function_types/detail/components_impl +#include + + } } // namespace function_types::detail + + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::components) + +} // namespace ::boost + +#include +#include + +#endif + diff --git a/thirdparty/boost/function_types/config/cc_names.hpp b/thirdparty/boost/function_types/config/cc_names.hpp new file mode 100644 index 0000000..1353219 --- /dev/null +++ b/thirdparty/boost/function_types/config/cc_names.hpp @@ -0,0 +1,31 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_CONFIG_CC_NAMES_HPP_INCLUDED +#define BOOST_FT_CONFIG_CC_NAMES_HPP_INCLUDED + +#define BOOST_FT_BUILTIN_CC_NAMES \ + (( IMPLICIT , implicit_cc , BOOST_PP_EMPTY ))\ + (( CDECL , cdecl_cc , BOOST_PP_IDENTITY(__cdecl ) ))\ + (( STDCALL , stdcall_cc , BOOST_PP_IDENTITY(__stdcall ) ))\ + (( PASCAL , pascal_cc , BOOST_PP_IDENTITY(pascal ) ))\ + (( FASTCALL , fastcall_cc , BOOST_PP_IDENTITY(__fastcall) ))\ + (( CLRCALL , clrcall_cc , BOOST_PP_IDENTITY(__clrcall ) ))\ + (( THISCALL , thiscall_cc , BOOST_PP_IDENTITY(__thiscall) ))\ + (( IMPLICIT_THISCALL , thiscall_cc , BOOST_PP_EMPTY )) + +// append user-defined cc names to builtin ones +#ifdef BOOST_FT_CC_NAMES +# define BOOST_FT_CC_NAMES_SEQ BOOST_FT_BUILTIN_CC_NAMES BOOST_FT_CC_NAMES +# define BOOST_FT_CC_PREPROCESSING 1 +#else +# define BOOST_FT_CC_NAMES_SEQ BOOST_FT_BUILTIN_CC_NAMES +#endif + +#endif + diff --git a/thirdparty/boost/function_types/config/compiler.hpp b/thirdparty/boost/function_types/config/compiler.hpp new file mode 100644 index 0000000..c4d66a3 --- /dev/null +++ b/thirdparty/boost/function_types/config/compiler.hpp @@ -0,0 +1,116 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_CONFIG_COMPILER_HPP_INCLUDED +#define BOOST_FT_CONFIG_COMPILER_HPP_INCLUDED + +#include +#include + +#if defined(BOOST_MSVC) + +# if BOOST_MSVC < 1310 +# error "unsupported compiler version" +# endif + +# ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS + + // enable clrcall calling covention (call to .NET managed code) when + // compiling with /clr +# if BOOST_MSVC >= 1400 && defined(__cplusplus_cli) +# ifndef BOOST_FT_CC_CLRCALL +# define BOOST_FT_CC_CLRCALL callable_builtin +# endif +# endif + + // Intel x86 architecture specific calling conventions +# ifdef _M_IX86 +# define BOOST_FT_COMMON_X86_CCs callable_builtin +# if BOOST_MSVC < 1400 + // version 7.1 is missing a keyword to specify the thiscall cc ... +# ifndef BOOST_FT_CC_IMPLICIT_THISCALL +# define BOOST_FT_CC_IMPLICIT_THISCALL non_variadic|member|callable_builtin +# ifndef BOOST_FT_CONFIG_OK +# pragma message("INFO| /Gd /Gr /Gz will compiler options will cause") +# pragma message("INFO| a compile error.") +# pragma message("INFO| Reconfigure Boost.FunctionTypes in this case.") +# pragma message("INFO| This message can be suppressed by defining") +# pragma message("INFO| BOOST_FT_CONFIG_OK.") +# endif +# endif +# else + // ...introduced in version 8 +# ifndef BOOST_FT_CC_THISCALL +# define BOOST_FT_CC_THISCALL non_variadic|member|callable_builtin +# endif +# endif +# endif +# endif + +#elif defined(__GNUC__) && !defined(BOOST_INTEL_LINUX) + +# if __GNUC__ < 3 +# error "unsupported compiler version" +# endif + +# ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS + +# if defined(__i386__) +# // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20439 +# // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29328 +# if BOOST_WORKAROUND(__GNUC__,BOOST_TESTED_AT(4)) +# ifndef BOOST_FT_CC_IMPLICIT +# define BOOST_FT_CC_IMPLICIT member|callable_builtin +# endif +# define BOOST_FT_COMMON_X86_CCs non_member|callable_builtin +# else +# define BOOST_FT_COMMON_X86_CCs callable_builtin +# endif +# else +# ifndef BOOST_FT_CC_IMPLICIT +# define BOOST_FT_CC_IMPLICIT callable_builtin +# endif +# endif +# endif + +# if (defined(BOOST_FT_CC_CDECL) || defined(BOOST_FT_COMMON_X86_CCs)) \ + && !defined(__cdecl) +# define __cdecl __attribute__((__cdecl__)) +# endif +# if (defined(BOOST_FT_CC_STDCALL) || defined(BOOST_FT_COMMON_X86_CCs)) \ + && !defined(__stdcall) +# define __stdcall __attribute__((__stdcall__)) +# endif +# if (defined(BOOST_FT_CC_FASTCALL) || defined(BOOST_FT_COMMON_X86_CCs)) \ + && !defined(__fastcall) +# define __fastcall __attribute__((__fastcall__)) +# endif + +#elif defined(__BORLANDC__) + +# if __BORLANDC__ < 0x550 +# error "unsupported compiler version" +# elif __BORLANDC__ > 0x565 +# pragma message("WARNING: library untested with this compiler version") +# endif + +# ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS +# define BOOST_FT_COMMON_X86_CCs callable_builtin +# endif + + // syntactic specialities of cc specifier +# define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \ + result() cc_spec() lparen() type_mod() name() rparen() +#else + // only enable default calling convention +# define BOOST_FT_CC_IMPLICIT callable_builtin +#endif + + +#endif + diff --git a/thirdparty/boost/function_types/config/config.hpp b/thirdparty/boost/function_types/config/config.hpp new file mode 100644 index 0000000..49f0019 --- /dev/null +++ b/thirdparty/boost/function_types/config/config.hpp @@ -0,0 +1,59 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_CONFIG_HPP_INCLUDED +#define BOOST_FT_CONFIG_HPP_INCLUDED + +#include +#include + +// maximum allowed arity +#ifndef BOOST_FT_MAX_ARITY +#define BOOST_FT_MAX_ARITY 20 +#endif + +// the most common calling conventions for x86 architecture can be enabled at +// once in the compiler config +#ifdef BOOST_FT_COMMON_X86_CCs +# ifndef BOOST_FT_CC_CDECL +# define BOOST_FT_CC_CDECL BOOST_FT_COMMON_X86_CCs +# endif +# ifndef BOOST_FT_CC_STDCALL +# define BOOST_FT_CC_STDCALL non_variadic|BOOST_FT_COMMON_X86_CCs +# endif +# ifndef BOOST_FT_CC_FASTCALL +# define BOOST_FT_CC_FASTCALL non_variadic|BOOST_FT_COMMON_X86_CCs +# endif +#endif + +// where to place the cc specifier (the common way) +#ifndef BOOST_FT_SYNTAX +# define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \ + result() lparen() cc_spec() type_mod() name() rparen() +#endif + +// param for nullary functions +// set to "void" for compilers that require nullary functions to read +// "R (void)" in template partial specialization +#ifndef BOOST_FT_NULLARY_PARAM +#define BOOST_FT_NULLARY_PARAM +#endif + +// there is a pending defect report on cv qualified function types, so support +// for these types is disabled, unless for compilers where it's known to work +#ifndef BOOST_FT_NO_CV_FUNC_SUPPORT +#define BOOST_FT_NO_CV_FUNC_SUPPORT 1 +#endif + +// full preprocessing implies preprocessing of the ccs +#if defined(BOOST_FT_PREPROCESSING_MODE) && !defined(BOOST_FT_CC_PREPROCESSING) +# define BOOST_FT_CC_PREPROCESSING 1 +#endif + +#endif + diff --git a/thirdparty/boost/function_types/detail/class_transform.hpp b/thirdparty/boost/function_types/detail/class_transform.hpp new file mode 100644 index 0000000..c354aa0 --- /dev/null +++ b/thirdparty/boost/function_types/detail/class_transform.hpp @@ -0,0 +1,62 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_CLASS_TRANSFORM_HPP_INCLUDED +#define BOOST_FT_DETAIL_CLASS_TRANSFORM_HPP_INCLUDED + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { namespace function_types { namespace detail { + +using mpl::placeholders::_; + +// Transformation metafunction for the class type of member function pointers. +template +struct class_transform +{ typedef typename mpl::apply1::type type; }; + + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +// We can short-circuit the mechanism implemented in the primary template for +// the most common lambda expression and save both the "un-lambdaing" and the +// type traits invocation (we know that T can only be a class type). + +template struct class_transform< T, mpl::identity<_> > +{ typedef T type; }; + +template struct class_transform< T, add_reference<_> > +{ typedef T & type; }; + +template struct class_transform< T, add_pointer<_> > +{ typedef T * type; }; + +template struct class_transform< T, remove_cv<_> > +{ typedef typename boost::remove_cv::type type; }; + +template struct class_transform< T, add_reference< remove_cv<_> > > +{ typedef typename boost::remove_cv::type & type; }; + +template struct class_transform< T, add_pointer< remove_cv<_> > > +{ typedef typename boost::remove_cv::type * type; }; + +template struct class_transform< T, mpl::always > +{ typedef U type; }; +#endif + + +} } } // namespace ::boost::function_types::detail + +#endif + diff --git a/thirdparty/boost/function_types/detail/classifier.hpp b/thirdparty/boost/function_types/detail/classifier.hpp new file mode 100644 index 0000000..401e7f8 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier.hpp @@ -0,0 +1,82 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_CLASSIFIER_HPP_INCLUDED +#define BOOST_FT_DETAIL_CLASSIFIER_HPP_INCLUDED + +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { namespace function_types { namespace detail { + +template struct classifier; + +template struct char_array { typedef char (&type)[S]; }; + +template struct encode_charr +{ + typedef typename char_array< + ::boost::function_types::detail::encode_charr_impl::value + >::type type; +}; + +char BOOST_TT_DECL classifier_impl(...); + +#define BOOST_FT_variations BOOST_FT_function|BOOST_FT_pointer|\ + BOOST_FT_member_pointer + +#define BOOST_FT_type_function(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,* BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) + +#define BOOST_FT_type_function_pointer(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,** BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) + +#define BOOST_FT_type_member_function_pointer(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,T0::** BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) + +#define BOOST_FT_al_path boost/function_types/detail/classifier_impl +#include + +template struct classifier_bits +{ + static typename boost::add_reference::type tester; + + BOOST_STATIC_CONSTANT(bits_t,value = (bits_t)sizeof( + boost::function_types::detail::classifier_impl(& tester) + )-1); +}; + +template struct classifier +{ + typedef detail::constant< + ::boost::function_types::detail::decode_bits< + ::boost::function_types::detail::classifier_bits::value + >::tag_bits > + bits; + + typedef detail::full_mask mask; + + typedef detail::constant< + ::boost::function_types::detail::decode_bits< + ::boost::function_types::detail::classifier_bits::value + >::arity > + function_arity; +}; + + + +} } } // namespace ::boost::function_types::detail + +#endif + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity10_0.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity10_0.hpp new file mode 100644 index 0000000..bc39132 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity10_0.hpp @@ -0,0 +1,55 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +template< typename R > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (BOOST_FT_nullary_param BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity10_1.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity10_1.hpp new file mode 100644 index 0000000..e9f5f81 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity10_1.hpp @@ -0,0 +1,52 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +template< typename R , typename T0 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) ( BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity20_0.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity20_0.hpp new file mode 100644 index 0000000..589ca58 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity20_0.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity20_1.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity20_1.hpp new file mode 100644 index 0000000..35aedeb --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity20_1.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity30_0.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity30_0.hpp new file mode 100644 index 0000000..928966c --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity30_0.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity30_1.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity30_1.hpp new file mode 100644 index 0000000..792d750 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity30_1.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity40_0.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity40_0.hpp new file mode 100644 index 0000000..4269561 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity40_0.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity40_1.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity40_1.hpp new file mode 100644 index 0000000..b312bcf --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity40_1.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity50_0.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity50_0.hpp new file mode 100644 index 0000000..dee818f --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity50_0.hpp @@ -0,0 +1,53 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49 BOOST_FT_ell) BOOST_FT_cv); + diff --git a/thirdparty/boost/function_types/detail/classifier_impl/arity50_1.hpp b/thirdparty/boost/function_types/detail/classifier_impl/arity50_1.hpp new file mode 100644 index 0000000..ac6ed1a --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/arity50_1.hpp @@ -0,0 +1,52 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); +template< typename R , 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 > +typename encode_charr ::type +classifier_impl(BOOST_FT_syntax(BOOST_FT_cc, BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv); diff --git a/thirdparty/boost/function_types/detail/classifier_impl/master.hpp b/thirdparty/boost/function_types/detail/classifier_impl/master.hpp new file mode 100644 index 0000000..0a24911 --- /dev/null +++ b/thirdparty/boost/function_types/detail/classifier_impl/master.hpp @@ -0,0 +1,33 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +#if BOOST_FT_ARITY_LOOP_PREFIX + +# ifndef BOOST_FT_DETAIL_CLASSIFIER_IMPL_MASTER_HPP_INCLUDED +# define BOOST_FT_DETAIL_CLASSIFIER_IMPL_MASTER_HPP_INCLUDED +# include +# endif + +# define BOOST_FT_type_name + +#elif BOOST_FT_ARITY_LOOP_IS_ITERATING + +template< BOOST_FT_tplargs(BOOST_PP_IDENTITY(typename)) > +typename encode_charr::type +classifier_impl(BOOST_FT_type); + +#elif BOOST_FT_ARITY_LOOP_SUFFIX + +# undef BOOST_FT_type_name + +#else +# error "attempt to use arity loop master file without loop" +#endif + diff --git a/thirdparty/boost/function_types/detail/components_as_mpl_sequence.hpp b/thirdparty/boost/function_types/detail/components_as_mpl_sequence.hpp new file mode 100644 index 0000000..feefef0 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_as_mpl_sequence.hpp @@ -0,0 +1,138 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_COMPONENTS_AS_MPL_SEQUENCE_HPP_INCLUDED +#define BOOST_FT_DETAIL_COMPONENTS_AS_MPL_SEQUENCE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl { + +template<> struct size_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::size + { }; +}; +template<> struct empty_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::empty + { }; +}; +template<> struct front_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::front + { }; +}; +template<> struct back_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::back + { }; +}; +template<> struct at_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S, typename N > struct apply + : mpl::at + { }; +}; +template<> struct begin_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::begin + { }; +}; +template<> struct end_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > struct apply + : mpl::end + { }; +}; +template<> struct clear_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > + struct apply + : S + { + typedef apply type; + typedef typename mpl::clear< typename S::types >::type types; + }; +}; +template<> +struct push_front_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S, typename T > + struct apply + : S + { + typedef apply type; + typedef typename mpl::push_front< typename S::types, T >::type types; + }; +}; +template<> +struct pop_front_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > + struct apply + : S + { + typedef apply type; + typedef typename mpl::pop_front< typename S::types >::type types; + }; +}; +template<> +struct push_back_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S, typename T > + struct apply + : S + { + typedef apply type; + typedef typename mpl::push_back< typename S::types, T >::type types; + }; +}; +template<> +struct pop_back_impl +< function_types::detail::components_mpl_sequence_tag > +{ + template< typename S > + struct apply + : S + { + typedef apply type; + typedef typename mpl::pop_back< typename S::types >::type types; + }; +}; + +} } // namespace ::boost::mpl + +#endif + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity10_0.hpp b/thirdparty/boost/function_types/detail/components_impl/arity10_0.hpp new file mode 100644 index 0000000..6cbd0db --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity10_0.hpp @@ -0,0 +1,132 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +template< typename R, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector1< R BOOST_FT_nullary_param > types; +}; +template< typename R , typename T0, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector2< R , T0 > types; +}; +template< typename R , typename T0 , typename T1, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector3< R , T0 , T1 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector4< R , T0 , T1 , T2 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector5< R , T0 , T1 , T2 , T3 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector6< R , T0 , T1 , T2 , T3 , T4 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector7< R , T0 , T1 , T2 , T3 , T4 , T5 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector8< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector9< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector10< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector11< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity10_1.hpp b/thirdparty/boost/function_types/detail/components_impl/arity10_1.hpp new file mode 100644 index 0000000..a0a35de --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity10_1.hpp @@ -0,0 +1,122 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +template< typename R , typename T0, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector2< R, typename class_transform ::type > types; +}; +template< typename R , typename T0 , typename T1, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector3< R, typename class_transform ::type , T1 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector4< R, typename class_transform ::type , T1 , T2 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector5< R, typename class_transform ::type , T1 , T2 , T3 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector6< R, typename class_transform ::type , T1 , T2 , T3 , T4 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector7< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector8< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector9< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector10< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 > types; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector11< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity20_0.hpp b/thirdparty/boost/function_types/detail/components_impl/arity20_0.hpp new file mode 100644 index 0000000..224403f --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity20_0.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector12< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector13< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector14< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector15< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector16< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector17< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector18< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector19< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector20< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector21< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity20_1.hpp b/thirdparty/boost/function_types/detail/components_impl/arity20_1.hpp new file mode 100644 index 0000000..fb51b63 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity20_1.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector12< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector13< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector14< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector15< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector16< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector17< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector18< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector19< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector20< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector21< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity30_0.hpp b/thirdparty/boost/function_types/detail/components_impl/arity30_0.hpp new file mode 100644 index 0000000..56ba414 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity30_0.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector22< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector23< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector24< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector25< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector26< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector27< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector28< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector29< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector30< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector31< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity30_1.hpp b/thirdparty/boost/function_types/detail/components_impl/arity30_1.hpp new file mode 100644 index 0000000..583a8cd --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity30_1.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector22< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector23< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector24< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector25< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector26< R, typename class_transform ::type , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector27< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector28< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector29< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector30< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector31< R, typename class_transform ::type , 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 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity40_0.hpp b/thirdparty/boost/function_types/detail/components_impl/arity40_0.hpp new file mode 100644 index 0000000..9c43fc1 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity40_0.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector32< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector33< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector34< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector35< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector36< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector37< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector38< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector39< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector40< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector41< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity40_1.hpp b/thirdparty/boost/function_types/detail/components_impl/arity40_1.hpp new file mode 100644 index 0000000..739abdd --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity40_1.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector32< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector33< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector34< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector35< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector36< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector37< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector38< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector39< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector40< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector41< R, typename class_transform ::type , 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 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity50_0.hpp b/thirdparty/boost/function_types/detail/components_impl/arity50_0.hpp new file mode 100644 index 0000000..335e412 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity50_0.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector42< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector43< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector44< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector45< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector46< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector47< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector48< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector49< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector50< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 > types; +}; +template< typename R , 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, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector51< R , T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/arity50_1.hpp b/thirdparty/boost/function_types/detail/components_impl/arity50_1.hpp new file mode 100644 index 0000000..b064ef7 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/arity50_1.hpp @@ -0,0 +1,123 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector42< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector43< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector44< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector45< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector46< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector47< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector48< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector49< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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 L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector50< R, typename class_transform ::type , 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 > types; +}; +template< typename R , 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, typename L> +struct components_impl +{ +typedef encode_bits bits; +typedef constant mask; +typedef function_types::components type; +typedef components_mpl_sequence_tag tag; +typedef mpl::integral_c function_arity; +typedef mpl::vector51< R, typename class_transform ::type , 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 > types; +}; + diff --git a/thirdparty/boost/function_types/detail/components_impl/master.hpp b/thirdparty/boost/function_types/detail/components_impl/master.hpp new file mode 100644 index 0000000..dba8467 --- /dev/null +++ b/thirdparty/boost/function_types/detail/components_impl/master.hpp @@ -0,0 +1,61 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +#if BOOST_FT_ARITY_LOOP_PREFIX + +# ifndef BOOST_FT_DETAIL_COMPONENTS_IMPL_MASTER_HPP_INCLUDED +# define BOOST_FT_DETAIL_COMPONENTS_IMPL_MASTER_HPP_INCLUDED +# include +# include +# include +# include +# include +# endif + +# define BOOST_FT_type_name + +# if !BOOST_FT_mfp + +# define BOOST_FT_types \ + R BOOST_PP_COMMA_IF(BOOST_FT_arity) BOOST_FT_params(BOOST_PP_EMPTY) +# else + +# define BOOST_FT_types \ + R, typename class_transform::type \ + BOOST_PP_COMMA_IF(BOOST_PP_DEC(BOOST_FT_arity)) \ + BOOST_FT_params(BOOST_PP_EMPTY) + +# endif + +#elif BOOST_FT_ARITY_LOOP_IS_ITERATING + +template< BOOST_FT_tplargs(BOOST_PP_IDENTITY(typename)), typename L> +struct components_impl +{ + typedef encode_bits bits; + typedef constant mask; + + typedef function_types::components type; + typedef components_mpl_sequence_tag tag; + + typedef mpl::integral_c function_arity; + + typedef BOOST_PP_CAT(mpl::vector,BOOST_FT_n)< BOOST_FT_types > types; +}; + +#elif BOOST_FT_ARITY_LOOP_SUFFIX + +# undef BOOST_FT_types +# undef BOOST_FT_type_name + +#else +# error "attempt to use arity loop master file without loop" +#endif + diff --git a/thirdparty/boost/function_types/detail/cv_traits.hpp b/thirdparty/boost/function_types/detail/cv_traits.hpp new file mode 100644 index 0000000..8381d8c --- /dev/null +++ b/thirdparty/boost/function_types/detail/cv_traits.hpp @@ -0,0 +1,134 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED +#define BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED + +#include +#include + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || BOOST_WORKAROUND(__BORLANDC__, <= 0x582) +# include +# include +# include +#endif + +#include + +namespace boost { namespace function_types { namespace detail { + +#if ! (defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || BOOST_WORKAROUND(__BORLANDC__, <= 0x582)) + +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; +template struct cv_traits +{ typedef non_cv tag; typedef T type; }; + +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; +template struct cv_traits +{ typedef const_non_volatile tag; typedef T type; }; + +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; +template struct cv_traits +{ typedef volatile_non_const tag; typedef T type; }; + +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; +template struct cv_traits +{ typedef cv_qualified tag; typedef T type; }; + +#else +template struct cv_tag_impl; + +template<> struct cv_tag_impl<1> { typedef non_cv type;}; +template<> struct cv_tag_impl<2> { typedef const_non_volatile type; }; +template<> struct cv_tag_impl<3> { typedef volatile_non_const type; }; +template<> struct cv_tag_impl<4> { typedef cv_qualified type; }; + +typedef char (& case_1)[1]; +typedef char (& case_2)[2]; +typedef char (& case_3)[3]; +typedef char (& case_4)[4]; + +template case_1 switch_cv(T *); +template case_2 switch_cv(T const *); +template case_3 switch_cv(T volatile *); +template case_4 switch_cv(T const volatile *); + +template T * ref_to_ptr(T &); +template T const * ref_to_ptr(T const &); +template T volatile * ref_to_ptr(T volatile &); +template T const volatile * ref_to_ptr(T const volatile &); + +template T * ref_to_ptr(T * const volatile &); + +template +struct cv_code +{ + static T _t; + BOOST_STATIC_CONSTANT(std::size_t, value = + sizeof(::boost::function_types::detail::switch_cv( + ::boost::function_types::detail::ref_to_ptr(_t) ) )); +}; + +template struct cv_traits +{ + typedef typename boost::function_types::detail::cv_tag_impl< + ::boost::function_types::detail::cv_code::value >::type + tag; + + // may require Boost.TypeTraits broken compiler specializations + // to work + typedef typename boost::remove_cv< + typename boost::remove_pointer< + typename boost::remove_reference::type + >::type + >::type type; +}; +#endif + +} } } // namespace boost::function_types::detail + +#endif + diff --git a/thirdparty/boost/function_types/detail/encoding/aliases_def.hpp b/thirdparty/boost/function_types/detail/encoding/aliases_def.hpp new file mode 100644 index 0000000..2cf2379 --- /dev/null +++ b/thirdparty/boost/function_types/detail/encoding/aliases_def.hpp @@ -0,0 +1,16 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +#define callable_builtin BOOST_FT_callable_builtin +#define member BOOST_FT_member_pointer +#define non_member BOOST_FT_non_member +#define variadic BOOST_FT_variadic +#define non_variadic BOOST_FT_non_variadic + diff --git a/thirdparty/boost/function_types/detail/encoding/aliases_undef.hpp b/thirdparty/boost/function_types/detail/encoding/aliases_undef.hpp new file mode 100644 index 0000000..f5f1c09 --- /dev/null +++ b/thirdparty/boost/function_types/detail/encoding/aliases_undef.hpp @@ -0,0 +1,16 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +#undef callable_builtin +#undef member +#undef non_member +#undef variadic +#undef non_variadic + diff --git a/thirdparty/boost/function_types/detail/encoding/def.hpp b/thirdparty/boost/function_types/detail/encoding/def.hpp new file mode 100644 index 0000000..20e19d7 --- /dev/null +++ b/thirdparty/boost/function_types/detail/encoding/def.hpp @@ -0,0 +1,51 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +// Type encoding: +// +// bit 0: callable builtin +// bit 1: non member +// bit 2: naked function +// bit 3: pointer +// bit 4: reference +// bit 5: member pointer +// bit 6: member function pointer +// bit 7: member object pointer + +#define BOOST_FT_type_mask 0x000000ff // 1111 1111 +#define BOOST_FT_callable_builtin 0x00000001 // 0000 0001 +#define BOOST_FT_non_member 0x00000002 // 0000 0010 +#define BOOST_FT_function 0x00000007 // 0000 0111 +#define BOOST_FT_pointer 0x0000000b // 0000 1011 +#define BOOST_FT_reference 0x00000013 // 0001 0011 +#define BOOST_FT_non_member_callable_builtin 0x00000003 // 0000 0011 +#define BOOST_FT_member_pointer 0x00000020 // 0010 0000 +#define BOOST_FT_member_function_pointer 0x00000061 // 0110 0001 +#define BOOST_FT_member_object_pointer 0x000000a3 // 1010 0001 +#define BOOST_FT_member_object_pointer_flags 0x000002a3 + +#define BOOST_FT_variadic 0x00000100 +#define BOOST_FT_non_variadic 0x00000200 +#define BOOST_FT_variadic_mask 0x00000300 + +#define BOOST_FT_const 0x00000400 +#define BOOST_FT_volatile 0x00000800 + +#define BOOST_FT_default_cc 0x00008000 +#define BOOST_FT_cc_mask 0x00ff8000 + +#define BOOST_FT_kind_mask 0x000000fc + +#define BOOST_FT_flags_mask 0x00000fff +#define BOOST_FT_full_mask 0x00ff0fff + +#define BOOST_FT_arity_shift 24 +#define BOOST_FT_arity_mask 0x7f000000 + diff --git a/thirdparty/boost/function_types/detail/encoding/undef.hpp b/thirdparty/boost/function_types/detail/encoding/undef.hpp new file mode 100644 index 0000000..c87a86e --- /dev/null +++ b/thirdparty/boost/function_types/detail/encoding/undef.hpp @@ -0,0 +1,38 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +#undef BOOST_FT_type_mask +#undef BOOST_FT_kind_mask +#undef BOOST_FT_callable_builtin +#undef BOOST_FT_non_member +#undef BOOST_FT_function +#undef BOOST_FT_pointer +#undef BOOST_FT_reference +#undef BOOST_FT_non_member_callable_builtin +#undef BOOST_FT_member_pointer +#undef BOOST_FT_member_function_pointer +#undef BOOST_FT_member_object_pointer +#undef BOOST_FT_member_object_pointer_flags + +#undef BOOST_FT_variadic +#undef BOOST_FT_non_variadic +#undef BOOST_FT_variadic_mask + +#undef BOOST_FT_const +#undef BOOST_FT_volatile + +#undef BOOST_FT_default_cc +#undef BOOST_FT_cc_mask + +#undef BOOST_FT_flags_mask +#undef BOOST_FT_full_mask + +#undef BOOST_FT_arity_mask + diff --git a/thirdparty/boost/function_types/detail/pp_arity_loop.hpp b/thirdparty/boost/function_types/detail/pp_arity_loop.hpp new file mode 100644 index 0000000..0794765 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_arity_loop.hpp @@ -0,0 +1,149 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +#ifndef BOOST_FT_PREPROCESSING_MODE +// input: BOOST_FT_mfp 0 or 1 <=> member function pointer? +// input: BOOST_FT_type_name BOOST_FT_type --> "R (* ..._type_name)()" (pass2) +#endif +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +#ifdef __WAVE__ +# pragma wave option(preserve: 0) +#endif + +#ifndef BOOST_FT_ARITY_LOOP_IS_ITERATING + +# define BOOST_FT_AL_PREPROCESSED \ + BOOST_FT_AL_FILE(BOOST_FT_al_path,BOOST_FT_FROM_ARITY,BOOST_FT_mfp) + +# define BOOST_FT_AL_FILE(base_path,max_arity,mfp) \ + BOOST_FT_AL_FILE_I(base_path,max_arity,mfp) +# define BOOST_FT_AL_FILE_I(base_path,max_arity,mfp) \ + + +# if !defined(BOOST_FT_PREPROCESSING_MODE) + +# if BOOST_FT_MAX_ARITY < 10 +# define BOOST_FT_FROM_ARITY 0 +# elif BOOST_FT_MAX_ARITY < 20 +# define BOOST_FT_FROM_ARITY 10 +# elif BOOST_FT_MAX_ARITY < 30 +# define BOOST_FT_FROM_ARITY 20 +# elif BOOST_FT_MAX_ARITY < 40 +# define BOOST_FT_FROM_ARITY 30 +# endif + +# if BOOST_FT_FROM_ARITY +# include BOOST_FT_AL_PREPROCESSED +# endif + +# elif !defined(BOOST_FT_FROM_ARITY) // single pass preprocessing +# define BOOST_FT_FROM_ARITY 0 + +# elif BOOST_FT_FROM_ARITY > 0 // arity20 includes arity10 +BOOST_PP_EXPAND(#) include BOOST_FT_AL_PREPROCESSED +# endif + +# undef BOOST_FT_AL_PREPROCESSED + +# undef BOOST_FT_AL_FILE +# undef BOOST_FT_AL_FILE_I + +# if BOOST_FT_MAX_ARITY > BOOST_FT_FROM_ARITY + +# ifndef BOOST_FT_DETAIL_ARITY_LOOP_HPP_INCLUDED +# define BOOST_FT_DETAIL_ARITY_LOOP_HPP_INCLUDED +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif + +# define BOOST_FT_AL_INCLUDE_FILE + +# define BOOST_FT_ARITY_LOOP_PREFIX 1 +# include BOOST_FT_AL_INCLUDE_FILE +# undef BOOST_FT_ARITY_LOOP_PREFIX + +# if !BOOST_PP_IS_ITERATING +# define BOOST_PP_FILENAME_1 BOOST_FT_AL_INCLUDE_FILE +# elif BOOST_PP_ITERATION_DEPTH() == 1 +# define BOOST_PP_FILENAME_2 BOOST_FT_AL_INCLUDE_FILE +# else +# error "loops nested too deeply" +# endif + +# define BOOST_FT_arity BOOST_PP_ITERATION() +# define BOOST_FT_n BOOST_PP_INC(BOOST_FT_arity) + +# define BOOST_FT_type \ + BOOST_FT_syntax(BOOST_FT_cc,BOOST_FT_type_name BOOST_PP_EMPTY)\ + (BOOST_FT_params(BOOST_PP_EMPTY) BOOST_FT_ell) BOOST_FT_cv + +# define BOOST_FT_tplargs(prefx) \ + prefx() R BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_FT_arity,prefx() T) + +# if !BOOST_FT_mfp + +# define BOOST_FT_params(prefx) \ + BOOST_PP_IF(BOOST_FT_arity,BOOST_PP_ENUM_PARAMS, \ + BOOST_FT_nullary_param BOOST_PP_TUPLE_EAT(2))( \ + BOOST_FT_arity,prefx() T) +# else + +# define BOOST_FT_params(prefx) \ + BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_FT_arity,prefx() T) + +# endif + +# if !BOOST_FT_FROM_ARITY +# define BOOST_PP_ITERATION_LIMITS (BOOST_FT_mfp, BOOST_FT_MAX_ARITY) +# else +# define BOOST_PP_ITERATION_LIMITS \ + (BOOST_FT_FROM_ARITY+1, BOOST_FT_MAX_ARITY) +# endif + +# define BOOST_FT_ARITY_LOOP_IS_ITERATING 1 +# include BOOST_PP_ITERATE() +# undef BOOST_FT_ARITY_LOOP_IS_ITERATING + +# undef BOOST_FT_arity +# undef BOOST_FT_params +# undef BOOST_FT_tplargs +# undef BOOST_FT_type + +# define BOOST_FT_ARITY_LOOP_SUFFIX 1 +# include BOOST_FT_AL_INCLUDE_FILE +# undef BOOST_FT_ARITY_LOOP_SUFFIX + +# undef BOOST_FT_AL_INCLUDE_FILE +# endif + +# undef BOOST_FT_FROM_ARITY + +#else +# error "attempt to nest arity loops" +#endif + diff --git a/thirdparty/boost/function_types/detail/pp_cc_loop/master.hpp b/thirdparty/boost/function_types/detail/pp_cc_loop/master.hpp new file mode 100644 index 0000000..232eb47 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_cc_loop/master.hpp @@ -0,0 +1,136 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +#ifdef __WAVE__ +// this file has been generated from the master.hpp file in the same directory +# pragma wave option(preserve: 0) +#endif + + +#if !BOOST_PP_IS_ITERATING + +# ifndef BOOST_FT_DETAIL_CC_LOOP_MASTER_HPP_INCLUDED +# define BOOST_FT_DETAIL_CC_LOOP_MASTER_HPP_INCLUDED +# include + +# include +# include +# include +# include +# include +# include +# include +# endif + +# include +# include + +# define BOOST_PP_FILENAME_1 \ + +# define BOOST_PP_ITERATION_LIMITS \ + (0,BOOST_PP_SEQ_SIZE(BOOST_FT_CC_NAMES_SEQ)-1) +# include BOOST_PP_ITERATE() +# if !defined(BOOST_FT_config_valid) && BOOST_FT_CC_PREPROCESSING +# define BOOST_FT_cc_id 1 +# define BOOST_FT_cc_name implicit_cc +# define BOOST_FT_cc BOOST_PP_EMPTY +# define BOOST_FT_cond callable_builtin +# include BOOST_FT_cc_file +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# elif !defined(BOOST_FT_config_valid) // and generating preprocessed file +BOOST_PP_EXPAND(#) ifndef BOOST_FT_config_valid +BOOST_PP_EXPAND(#) define BOOST_FT_cc_id 1 +BOOST_PP_EXPAND(#) define BOOST_FT_cc_name implicit_cc +BOOST_PP_EXPAND(#) define BOOST_FT_cc BOOST_PP_EMPTY +BOOST_PP_EXPAND(#) define BOOST_FT_cond callable_builtin +#define _() +BOOST_PP_EXPAND(#) include BOOST_FT_cc_file +#undef _ +BOOST_PP_EXPAND(#) undef BOOST_FT_cond +BOOST_PP_EXPAND(#) undef BOOST_FT_cc_name +BOOST_PP_EXPAND(#) undef BOOST_FT_cc +BOOST_PP_EXPAND(#) undef BOOST_FT_cc_id +BOOST_PP_EXPAND(#) else +BOOST_PP_EXPAND(#) undef BOOST_FT_config_valid +BOOST_PP_EXPAND(#) endif + +# else +# undef BOOST_FT_config_valid +# endif + +# include +# include + +#elif BOOST_FT_CC_PREPROCESSING + +# define BOOST_FT_cc_id BOOST_PP_INC(BOOST_PP_FRAME_ITERATION(1)) +# define BOOST_FT_cc_inf \ + BOOST_PP_SEQ_ELEM(BOOST_PP_FRAME_ITERATION(1),BOOST_FT_CC_NAMES_SEQ) + +# define BOOST_FT_cc_pp_name BOOST_PP_TUPLE_ELEM(3,0,BOOST_FT_cc_inf) +# define BOOST_FT_cc_name BOOST_PP_TUPLE_ELEM(3,1,BOOST_FT_cc_inf) +# define BOOST_FT_cc BOOST_PP_TUPLE_ELEM(3,2,BOOST_FT_cc_inf) + +# define BOOST_FT_cond BOOST_PP_CAT(BOOST_FT_CC_,BOOST_FT_cc_pp_name) + +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif + +# undef BOOST_FT_cond + +# undef BOOST_FT_cc_pp_name +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc + +# undef BOOST_FT_cc_id +# undef BOOST_FT_cc_inf + +#else // if generating preprocessed file +BOOST_PP_EXPAND(#) define BOOST_FT_cc_id BOOST_PP_INC(BOOST_PP_ITERATION()) + +# define BOOST_FT_cc_inf \ + BOOST_PP_SEQ_ELEM(BOOST_PP_ITERATION(),BOOST_FT_CC_NAMES_SEQ) + +# define BOOST_FT_cc_pp_name BOOST_PP_TUPLE_ELEM(3,0,BOOST_FT_cc_inf) + +# define BOOST_FT_CC_DEF(name,index) \ + name BOOST_PP_TUPLE_ELEM(3,index,BOOST_FT_cc_inf) +BOOST_PP_EXPAND(#) define BOOST_FT_CC_DEF(BOOST_FT_cc_name,1) +BOOST_PP_EXPAND(#) define BOOST_FT_CC_DEF(BOOST_FT_cc,2) +# undef BOOST_FT_CC_DEF + +# define BOOST_FT_cc_cond_v BOOST_PP_CAT(BOOST_FT_CC_,BOOST_FT_cc_pp_name) +BOOST_PP_EXPAND(#) define BOOST_FT_cond BOOST_FT_cc_cond_v +# undef BOOST_FT_cc_cond_v + +# undef BOOST_FT_cc_pp_name +# undef BOOST_FT_cc_inf + +BOOST_PP_EXPAND(#) if BOOST_FT_cond +BOOST_PP_EXPAND(#) define BOOST_FT_config_valid 1 +#define _() +BOOST_PP_EXPAND(#) include BOOST_FT_cc_file +#undef _ +BOOST_PP_EXPAND(#) endif + +BOOST_PP_EXPAND(#) undef BOOST_FT_cond + +BOOST_PP_EXPAND(#) undef BOOST_FT_cc_name +BOOST_PP_EXPAND(#) undef BOOST_FT_cc + +BOOST_PP_EXPAND(#) undef BOOST_FT_cc_id + +#endif + diff --git a/thirdparty/boost/function_types/detail/pp_cc_loop/preprocessed.hpp b/thirdparty/boost/function_types/detail/pp_cc_loop/preprocessed.hpp new file mode 100644 index 0000000..aaee74f --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_cc_loop/preprocessed.hpp @@ -0,0 +1,120 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +// this file has been generated from the master.hpp file in the same directory +# define BOOST_FT_cc_id 1 +# define BOOST_FT_cc_name implicit_cc +# define BOOST_FT_cc BOOST_PP_EMPTY +# define BOOST_FT_cond BOOST_FT_CC_IMPLICIT +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 2 +# define BOOST_FT_cc_name cdecl_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(__cdecl ) +# define BOOST_FT_cond BOOST_FT_CC_CDECL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 3 +# define BOOST_FT_cc_name stdcall_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(__stdcall ) +# define BOOST_FT_cond BOOST_FT_CC_STDCALL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 4 +# define BOOST_FT_cc_name pascal_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(pascal ) +# define BOOST_FT_cond BOOST_FT_CC_PASCAL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 5 +# define BOOST_FT_cc_name fastcall_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(__fastcall) +# define BOOST_FT_cond BOOST_FT_CC_FASTCALL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 6 +# define BOOST_FT_cc_name clrcall_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(__clrcall ) +# define BOOST_FT_cond BOOST_FT_CC_CLRCALL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 7 +# define BOOST_FT_cc_name thiscall_cc +# define BOOST_FT_cc BOOST_PP_IDENTITY(__thiscall) +# define BOOST_FT_cond BOOST_FT_CC_THISCALL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# define BOOST_FT_cc_id 8 +# define BOOST_FT_cc_name thiscall_cc +# define BOOST_FT_cc BOOST_PP_EMPTY +# define BOOST_FT_cond BOOST_FT_CC_IMPLICIT_THISCALL +# if BOOST_FT_cond +# define BOOST_FT_config_valid 1 +# include BOOST_FT_cc_file +# endif +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# ifndef BOOST_FT_config_valid +# define BOOST_FT_cc_id 1 +# define BOOST_FT_cc_name implicit_cc +# define BOOST_FT_cc BOOST_PP_EMPTY +# define BOOST_FT_cond 0x00000001 +# include BOOST_FT_cc_file +# undef BOOST_FT_cond +# undef BOOST_FT_cc_name +# undef BOOST_FT_cc +# undef BOOST_FT_cc_id +# else +# undef BOOST_FT_config_valid +# endif diff --git a/thirdparty/boost/function_types/detail/pp_loop.hpp b/thirdparty/boost/function_types/detail/pp_loop.hpp new file mode 100644 index 0000000..97c595a --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_loop.hpp @@ -0,0 +1,80 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + +#ifndef BOOST_FT_DETAIL_PP_LOOP_HPP_INCLUDED +#define BOOST_FT_DETAIL_PP_LOOP_HPP_INCLUDED +# include +# include +# include +#endif + +#include +#include + +#if defined(BOOST_FT_PREPROCESSING_MODE) +# define BOOST_FT_loop +#else +# define BOOST_FT_loop \ + +#endif + +#if defined(BOOST_FT_al_path) + +# define BOOST_FT_cc_file \ + +# define BOOST_FT_variate_file \ + + +# ifndef BOOST_FT_type_function +# define BOOST_FT_type_function(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_EMPTY,cc,BOOST_PP_EMPTY,name,BOOST_PP_EMPTY) +# endif +# ifndef BOOST_FT_type_function_pointer +# define BOOST_FT_type_function_pointer(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,* BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) +# endif +# ifndef BOOST_FT_type_function_reference +# define BOOST_FT_type_function_reference(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,& BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) +# endif +# ifndef BOOST_FT_type_member_function_pointer +# define BOOST_FT_type_member_function_pointer(cc,name) BOOST_FT_SYNTAX( \ + R BOOST_PP_EMPTY,BOOST_PP_LPAREN,cc,T0::* BOOST_PP_EMPTY,name,BOOST_PP_RPAREN) +# endif + +# include BOOST_FT_loop + +# undef BOOST_FT_type_function +# undef BOOST_FT_type_function_pointer +# undef BOOST_FT_type_function_reference +# undef BOOST_FT_type_member_function_pointer + +# undef BOOST_FT_variations +# undef BOOST_FT_variate_file +# undef BOOST_FT_cc_file +# undef BOOST_FT_al_path + +#elif defined(BOOST_FT_cc_file) + +# include BOOST_FT_loop +# undef BOOST_FT_cc_file + +#else + +# error "argument missing" + +#endif + +#undef BOOST_FT_loop + +#include +#include + + diff --git a/thirdparty/boost/function_types/detail/pp_retag_default_cc/master.hpp b/thirdparty/boost/function_types/detail/pp_retag_default_cc/master.hpp new file mode 100644 index 0000000..4123d37 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_retag_default_cc/master.hpp @@ -0,0 +1,103 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is guarded externally + +#ifdef __WAVE__ +// this file has been generated from the master.hpp file in the same directory +# pragma wave option(preserve: 0) +#endif + +#if !defined(BOOST_PP_VALUE) +# include +# include + +# include +# include + +namespace boost { namespace function_types { + +namespace detail +{ + template struct selector_bits + { +# define BOOST_PP_VALUE non_member|member|non_variadic|variadic +# include BOOST_PP_ASSIGN_SLOT(1) + + BOOST_STATIC_CONSTANT(bits_t, value = ( + ::boost::function_types::detail::bits::value & BOOST_FT_default_cc + | ::boost::function_types::detail::bits::value & BOOST_PP_SLOT(1) + )); + }; + + template struct default_cc_tag; + + template struct retag_default_cc + : detail::compound_tag + < Tag, detail::default_cc_tag< + ::boost::function_types::detail::selector_bits::value > > + { }; + + template struct default_cc_tag + { + typedef null_tag::bits bits; + typedef null_tag::mask mask; + }; + + class test_class; + typedef constant cc_mask_constant; + +# define BOOST_FT_self \ + + +# define default_cc_ BOOST_FT_default_cc + +# define BOOST_PP_VALUE default_cc_|non_member|non_variadic +# define BOOST_FT_tester void (*tester)() +# define BOOST_PP_INDIRECT_SELF BOOST_FT_self +# include BOOST_PP_INCLUDE_SELF() + +# define BOOST_PP_VALUE default_cc_|non_member|variadic +# define BOOST_FT_tester void (*tester)(...) +# define BOOST_PP_INDIRECT_SELF BOOST_FT_self +# include BOOST_PP_INCLUDE_SELF() + +# define BOOST_PP_VALUE default_cc_|member|non_variadic +# define BOOST_FT_tester void (test_class::*tester)() +# define BOOST_PP_INDIRECT_SELF BOOST_FT_self +# include BOOST_PP_INCLUDE_SELF() + +# define BOOST_PP_VALUE default_cc_|member|variadic +# define BOOST_FT_tester void (test_class::*tester)(...) +# define BOOST_PP_INDIRECT_SELF BOOST_FT_self +# include BOOST_PP_INCLUDE_SELF() + +# undef default_cc_ + +# undef BOOST_FT_self + +} } } // namespace ::boost::function_types::detail + +# include +# include + +#else // if defined(BOOST_PP_VALUE) + +# include BOOST_PP_ASSIGN_SLOT(1) + + template<> struct default_cc_tag + { + typedef BOOST_FT_tester; + typedef mpl::bitand_::bits,cc_mask_constant> bits; + typedef cc_mask_constant mask; + }; + +# undef BOOST_FT_tester + +#endif + diff --git a/thirdparty/boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp b/thirdparty/boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp new file mode 100644 index 0000000..f419728 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp @@ -0,0 +1,59 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is guarded externally + +// this file has been generated from the master.hpp file in the same directory +namespace boost { namespace function_types { +namespace detail +{ +template struct selector_bits +{ +BOOST_STATIC_CONSTANT(bits_t, value = ( +::boost::function_types::detail::bits ::value & 0x00008000 +| ::boost::function_types::detail::bits ::value & 802 +)); +}; +template struct default_cc_tag; +template struct retag_default_cc +: detail::compound_tag +< Tag, detail::default_cc_tag< +::boost::function_types::detail::selector_bits ::value > > +{ }; +template struct default_cc_tag +{ +typedef null_tag::bits bits; +typedef null_tag::mask mask; +}; +class test_class; +typedef constant<0x00ff8000> cc_mask_constant; +template< > struct default_cc_tag<33282> +{ +typedef void ( *tester)(); +typedef mpl::bitand_ ::bits,cc_mask_constant> bits; +typedef cc_mask_constant mask; +}; +template< > struct default_cc_tag<33026> +{ +typedef void ( *tester)( ... ); +typedef mpl::bitand_ ::bits,cc_mask_constant> bits; +typedef cc_mask_constant mask; +}; +template< > struct default_cc_tag<33312> +{ +typedef void (test_class:: *tester)(); +typedef mpl::bitand_ ::bits,cc_mask_constant> bits; +typedef cc_mask_constant mask; +}; +template< > struct default_cc_tag<33056> +{ +typedef void (test_class:: *tester)( ... ); +typedef mpl::bitand_ ::bits,cc_mask_constant> bits; +typedef cc_mask_constant mask; +}; +} } } diff --git a/thirdparty/boost/function_types/detail/pp_tags/cc_tag.hpp b/thirdparty/boost/function_types/detail/pp_tags/cc_tag.hpp new file mode 100644 index 0000000..743f787 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_tags/cc_tag.hpp @@ -0,0 +1,17 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusions + + struct BOOST_FT_cc_name + { + typedef detail::encode_bits<0,BOOST_FT_cc_id> bits; + typedef detail::constant mask; + }; + + diff --git a/thirdparty/boost/function_types/detail/pp_tags/master.hpp b/thirdparty/boost/function_types/detail/pp_tags/master.hpp new file mode 100644 index 0000000..3b3b727 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_tags/master.hpp @@ -0,0 +1,126 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is guarded externally + +#ifdef __WAVE__ +// this file has been generated from the master.hpp file in the same directory +# pragma wave option(preserve: 0) +#endif + +#if !defined(BOOST_FT_PREPROCESSING_MODE) || defined(BOOST_FT_CONFIG_HPP_INCLUDED) +# error "this file used with two-pass preprocessing, only" +#endif + +#include +#include + +namespace boost { namespace function_types { + +typedef detail::property_tag non_variadic; +typedef detail::property_tag variadic; + +typedef detail::property_tag<0,BOOST_FT_const> non_const; +typedef detail::property_tag const_qualified; + +typedef detail::property_tag<0,BOOST_FT_volatile> non_volatile; +typedef detail::property_tag volatile_qualified; + +typedef detail::property_tag default_cc; + +#define BOOST_PP_VALUE BOOST_FT_const|BOOST_FT_volatile +#include BOOST_PP_ASSIGN_SLOT(1) + +typedef detail::property_tag<0 , BOOST_PP_SLOT(1)> non_cv; +typedef detail::property_tag const_non_volatile; +typedef detail::property_tag volatile_non_const; +typedef detail::property_tag cv_qualified; + +namespace detail { + + typedef constant full_mask; + + template struct encode_bits_impl + { + BOOST_STATIC_CONSTANT( bits_t, value = + Flags | (BOOST_FT_default_cc * CCID) << 1 ); + }; + + template + struct encode_charr_impl + { + BOOST_STATIC_CONSTANT(std::size_t, value = (std::size_t)(1+ + Flags | (BOOST_FT_default_cc * CCID) << 1 | Arity << BOOST_FT_arity_shift + )); + }; + + template struct decode_bits + { + BOOST_STATIC_CONSTANT(bits_t, flags = Bits & BOOST_FT_flags_mask); + + BOOST_STATIC_CONSTANT(bits_t, cc_id = + ( (Bits & BOOST_FT_full_mask) / BOOST_FT_default_cc) >> 1 + ); + + BOOST_STATIC_CONSTANT(bits_t, tag_bits = (Bits & BOOST_FT_full_mask)); + + BOOST_STATIC_CONSTANT(std::size_t, arity = (std::size_t) + (Bits >> BOOST_FT_arity_shift) + ); + }; + + template + struct tag_ice + { + BOOST_STATIC_CONSTANT(bool, match = + RHS_bits == (LHS_bits & RHS_mask & (RHS_bits |~BOOST_FT_type_mask)) + ); + + BOOST_STATIC_CONSTANT(bits_t, combined_bits = + LHS_bits & ~RHS_mask | RHS_bits + ); + + BOOST_STATIC_CONSTANT(bits_t, combined_mask = + LHS_mask | RHS_mask + ); + + BOOST_STATIC_CONSTANT(bits_t, extracted_bits = + LHS_bits & RHS_mask + ); + + }; + +#define BOOST_FT_mask BOOST_FT_type_mask + typedef property_tag callable_builtin_tag; + typedef property_tag nonmember_callable_builtin_tag; + typedef property_tag function_tag; + typedef property_tag reference_tag; + typedef property_tag pointer_tag; + typedef property_tag member_function_pointer_tag; + typedef property_tag member_object_pointer_tag; + typedef property_tag member_object_pointer_base; + typedef property_tag member_pointer_tag; +#undef BOOST_FT_mask + +#define BOOST_PP_VALUE BOOST_FT_function|BOOST_FT_non_variadic|BOOST_FT_default_cc +#include BOOST_PP_ASSIGN_SLOT(1) +#define BOOST_PP_VALUE BOOST_FT_type_mask|BOOST_FT_variadic_mask|BOOST_FT_cc_mask +#include BOOST_PP_ASSIGN_SLOT(2) + + typedef property_tag< BOOST_PP_SLOT(1) , BOOST_PP_SLOT(2) > nv_dcc_func; + +#define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_non_variadic|BOOST_FT_default_cc +#include BOOST_PP_ASSIGN_SLOT(1) + + typedef property_tag< BOOST_PP_SLOT(1) , BOOST_PP_SLOT(2) > nv_dcc_mfp; + +} // namespace detail + +} } // namespace ::boost::function_types + diff --git a/thirdparty/boost/function_types/detail/pp_tags/preprocessed.hpp b/thirdparty/boost/function_types/detail/pp_tags/preprocessed.hpp new file mode 100644 index 0000000..7b0de66 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_tags/preprocessed.hpp @@ -0,0 +1,77 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is guarded externally + +// this file has been generated from the master.hpp file in the same directory +namespace boost { namespace function_types { +typedef detail::property_tag<0x00000200,0x00000300> non_variadic; +typedef detail::property_tag<0x00000100,0x00000300> variadic; +typedef detail::property_tag<0,0x00000400> non_const; +typedef detail::property_tag<0x00000400,0x00000400> const_qualified; +typedef detail::property_tag<0,0x00000800> non_volatile; +typedef detail::property_tag<0x00000800,0x00000800> volatile_qualified; +typedef detail::property_tag<0x00008000,0x00ff8000> default_cc; +typedef detail::property_tag<0 , 3072> non_cv; +typedef detail::property_tag<0x00000400 , 3072> const_non_volatile; +typedef detail::property_tag<0x00000800, 3072> volatile_non_const; +typedef detail::property_tag<3072 , 3072> cv_qualified; +namespace detail { +typedef constant<0x00ff0fff> full_mask; +template struct encode_bits_impl +{ +BOOST_STATIC_CONSTANT( bits_t, value = +Flags | (0x00008000 * CCID) << 1 ); +}; +template +struct encode_charr_impl +{ +BOOST_STATIC_CONSTANT(std::size_t, value = (std::size_t)(1+ +Flags | (0x00008000 * CCID) << 1 | Arity << 24 +)); +}; +template struct decode_bits +{ +BOOST_STATIC_CONSTANT(bits_t, flags = Bits & 0x00000fff); +BOOST_STATIC_CONSTANT(bits_t, cc_id = +( (Bits & 0x00ff0fff) / 0x00008000) >> 1 +); +BOOST_STATIC_CONSTANT(bits_t, tag_bits = (Bits & 0x00ff0fff)); +BOOST_STATIC_CONSTANT(std::size_t, arity = (std::size_t) +(Bits >> 24) +); +}; +template +struct tag_ice +{ +BOOST_STATIC_CONSTANT(bool, match = +RHS_bits == (LHS_bits & RHS_mask & (RHS_bits | ~0x000000ff)) +); +BOOST_STATIC_CONSTANT(bits_t, combined_bits = +LHS_bits & ~RHS_mask | RHS_bits +); +BOOST_STATIC_CONSTANT(bits_t, combined_mask = +LHS_mask | RHS_mask +); +BOOST_STATIC_CONSTANT(bits_t, extracted_bits = +LHS_bits & RHS_mask +); +}; +typedef property_tag<0x00000001,0x000000ff> callable_builtin_tag; +typedef property_tag<0x00000003,0x000000ff> nonmember_callable_builtin_tag; +typedef property_tag<0x00000007,0x000000ff> function_tag; +typedef property_tag<0x00000013,0x000000ff> reference_tag; +typedef property_tag<0x0000000b,0x000000ff> pointer_tag; +typedef property_tag<0x00000061,0x000000ff> member_function_pointer_tag; +typedef property_tag<0x000000a3,0x000000ff> member_object_pointer_tag; +typedef property_tag<0x000002a3,0x00ff0fff> member_object_pointer_base; +typedef property_tag<0x00000020,0x000000ff> member_pointer_tag; +typedef property_tag< 33287 , 16745471 > nv_dcc_func; +typedef property_tag< 33377 , 16745471 > nv_dcc_mfp; +} +} } diff --git a/thirdparty/boost/function_types/detail/pp_variate_loop/master.hpp b/thirdparty/boost/function_types/detail/pp_variate_loop/master.hpp new file mode 100644 index 0000000..ae7d995 --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_variate_loop/master.hpp @@ -0,0 +1,152 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifdef __WAVE__ +// this file has been generated from the master.hpp file in the same directory +# pragma wave option(preserve: 0) +#endif + +#if !defined(BOOST_FT_PREPROCESSING_MODE) +# error "this file is only for two-pass preprocessing" +#endif + +#if !defined(BOOST_PP_VALUE) +# include +# include +# include +# include + +BOOST_PP_EXPAND(#) define BOOST_FT_mfp 0 +BOOST_PP_EXPAND(#) define BOOST_FT_syntax BOOST_FT_type_function + +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_non_variadic +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_variadic +# include __FILE__ + +BOOST_PP_EXPAND(#) if !BOOST_FT_NO_CV_FUNC_SUPPORT +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_non_variadic|BOOST_FT_const +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_variadic|BOOST_FT_const +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_non_variadic|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_variadic|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_non_variadic|BOOST_FT_const|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_function|BOOST_FT_variadic|BOOST_FT_const|BOOST_FT_volatile +# include __FILE__ +BOOST_PP_EXPAND(#) endif + + +BOOST_PP_EXPAND(#) undef BOOST_FT_syntax +BOOST_PP_EXPAND(#) define BOOST_FT_syntax BOOST_FT_type_function_pointer + +# define BOOST_PP_VALUE \ + BOOST_FT_pointer|BOOST_FT_non_variadic +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_pointer|BOOST_FT_variadic +# include __FILE__ + +BOOST_PP_EXPAND(#) undef BOOST_FT_syntax +BOOST_PP_EXPAND(#) define BOOST_FT_syntax BOOST_FT_type_function_reference + +# define BOOST_PP_VALUE \ + BOOST_FT_reference|BOOST_FT_non_variadic +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_reference|BOOST_FT_variadic +# include __FILE__ + +BOOST_PP_EXPAND(#) undef BOOST_FT_syntax +BOOST_PP_EXPAND(#) undef BOOST_FT_mfp + +BOOST_PP_EXPAND(#) define BOOST_FT_mfp 1 +BOOST_PP_EXPAND(#) define BOOST_FT_syntax BOOST_FT_type_member_function_pointer + +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_non_variadic +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_variadic +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_non_variadic|BOOST_FT_const +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_variadic|BOOST_FT_const +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_non_variadic|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_variadic|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_non_variadic|BOOST_FT_const|BOOST_FT_volatile +# include __FILE__ +# define BOOST_PP_VALUE \ + BOOST_FT_member_function_pointer|BOOST_FT_variadic|BOOST_FT_const|BOOST_FT_volatile +# include __FILE__ + +BOOST_PP_EXPAND(#) undef BOOST_FT_syntax +BOOST_PP_EXPAND(#) undef BOOST_FT_mfp + +# include +#else + +# include BOOST_PP_ASSIGN_SLOT(1) + +# define BOOST_PP_VALUE BOOST_PP_SLOT(1) & BOOST_FT_kind_mask +# include BOOST_PP_ASSIGN_SLOT(2) + +BOOST_PP_EXPAND(#) if !!(BOOST_PP_SLOT(2) & (BOOST_FT_variations)) +BOOST_PP_EXPAND(#) if (BOOST_PP_SLOT(1) & (BOOST_FT_cond)) == (BOOST_FT_cond) + +# if ( BOOST_PP_SLOT(1) & (BOOST_FT_variadic) ) +BOOST_PP_EXPAND(#) define BOOST_FT_ell ... +BOOST_PP_EXPAND(#) define BOOST_FT_nullary_param +# else +BOOST_PP_EXPAND(#) define BOOST_FT_ell +BOOST_PP_EXPAND(#) define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# endif + +# if !( BOOST_PP_SLOT(1) & (BOOST_FT_volatile) ) +# if !( BOOST_PP_SLOT(1) & (BOOST_FT_const) ) +BOOST_PP_EXPAND(#) define BOOST_FT_cv +# else +BOOST_PP_EXPAND(#) define BOOST_FT_cv const +# endif +# else +# if !( BOOST_PP_SLOT(1) & (BOOST_FT_const) ) +BOOST_PP_EXPAND(#) define BOOST_FT_cv volatile +# else +BOOST_PP_EXPAND(#) define BOOST_FT_cv const volatile +# endif +# endif +BOOST_PP_EXPAND(#) define BOOST_FT_flags BOOST_PP_SLOT(1) +BOOST_PP_EXPAND(#) include BOOST_FT_variate_file + +BOOST_PP_EXPAND(#) undef BOOST_FT_cv +BOOST_PP_EXPAND(#) undef BOOST_FT_ell +BOOST_PP_EXPAND(#) undef BOOST_FT_nullary_param +BOOST_PP_EXPAND(#) undef BOOST_FT_flags +BOOST_PP_EXPAND(#) endif +BOOST_PP_EXPAND(#) endif +#endif + diff --git a/thirdparty/boost/function_types/detail/pp_variate_loop/preprocessed.hpp b/thirdparty/boost/function_types/detail/pp_variate_loop/preprocessed.hpp new file mode 100644 index 0000000..a5ca48f --- /dev/null +++ b/thirdparty/boost/function_types/detail/pp_variate_loop/preprocessed.hpp @@ -0,0 +1,283 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// this file has been generated from the master.hpp file in the same directory +# define BOOST_FT_mfp 0 +# define BOOST_FT_syntax BOOST_FT_type_function +# if ! ! (4 & (BOOST_FT_variations)) +# if (519 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv +# define BOOST_FT_flags 519 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (263 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv +# define BOOST_FT_flags 263 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if !BOOST_FT_NO_CV_FUNC_SUPPORT +# if ! ! (4 & (BOOST_FT_variations)) +# if (1543 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv const +# define BOOST_FT_flags 1543 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (1287 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv const +# define BOOST_FT_flags 1287 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (2567 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv volatile +# define BOOST_FT_flags 2567 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (2311 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv volatile +# define BOOST_FT_flags 2311 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (3591 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv const volatile +# define BOOST_FT_flags 3591 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (4 & (BOOST_FT_variations)) +# if (3335 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv const volatile +# define BOOST_FT_flags 3335 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# endif +# undef BOOST_FT_syntax +# define BOOST_FT_syntax BOOST_FT_type_function_pointer +# if ! ! (8 & (BOOST_FT_variations)) +# if (523 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv +# define BOOST_FT_flags 523 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (8 & (BOOST_FT_variations)) +# if (267 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv +# define BOOST_FT_flags 267 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# undef BOOST_FT_syntax +# define BOOST_FT_syntax BOOST_FT_type_function_reference +# if ! ! (16 & (BOOST_FT_variations)) +# if (531 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv +# define BOOST_FT_flags 531 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (16 & (BOOST_FT_variations)) +# if (275 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv +# define BOOST_FT_flags 275 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# undef BOOST_FT_syntax +# undef BOOST_FT_mfp +# define BOOST_FT_mfp 1 +# define BOOST_FT_syntax BOOST_FT_type_member_function_pointer +# if ! ! (96 & (BOOST_FT_variations)) +# if (609 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv +# define BOOST_FT_flags 609 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (353 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv +# define BOOST_FT_flags 353 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (1633 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv const +# define BOOST_FT_flags 1633 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (1377 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv const +# define BOOST_FT_flags 1377 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (2657 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv volatile +# define BOOST_FT_flags 2657 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (2401 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv volatile +# define BOOST_FT_flags 2401 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (3681 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell +# define BOOST_FT_nullary_param BOOST_FT_NULLARY_PARAM +# define BOOST_FT_cv const volatile +# define BOOST_FT_flags 3681 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# if ! ! (96 & (BOOST_FT_variations)) +# if (3425 & (BOOST_FT_cond)) == (BOOST_FT_cond) +# define BOOST_FT_ell ... +# define BOOST_FT_nullary_param +# define BOOST_FT_cv const volatile +# define BOOST_FT_flags 3425 +# include BOOST_FT_variate_file +# undef BOOST_FT_cv +# undef BOOST_FT_ell +# undef BOOST_FT_nullary_param +# undef BOOST_FT_flags +# endif +# endif +# undef BOOST_FT_syntax +# undef BOOST_FT_mfp diff --git a/thirdparty/boost/function_types/detail/retag_default_cc.hpp b/thirdparty/boost/function_types/detail/retag_default_cc.hpp new file mode 100644 index 0000000..324c6bb --- /dev/null +++ b/thirdparty/boost/function_types/detail/retag_default_cc.hpp @@ -0,0 +1,23 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_RETAG_DEFAULT_CC_HPP_INCLUDED +#define BOOST_FT_DETAIL_RETAG_DEFAULT_CC_HPP_INCLUDED + +#include + +#include + +#if defined(BOOST_FT_PREPROCESSING_MODE) +# include +#else +# include +#endif + +#endif + diff --git a/thirdparty/boost/function_types/detail/synthesize.hpp b/thirdparty/boost/function_types/detail/synthesize.hpp new file mode 100644 index 0000000..dcd98d5 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize.hpp @@ -0,0 +1,79 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_SYNTHESIZE_HPP_INCLUDED +#define BOOST_FT_DETAIL_SYNTHESIZE_HPP_INCLUDED + +#include + +#include +#include + +#include +#include +#include +#include + +namespace boost { namespace function_types { namespace detail { + +template +struct synthesize_impl_o +{ + template struct synthesize_impl_i { }; +}; + +template +struct synthesize_impl + : detail::synthesize_impl_o + < ::boost::function_types::detail::decode_bits::flags + , ::boost::function_types::detail::decode_bits::cc_id + , ::boost::mpl::size::value + > + ::template synthesize_impl_i +{ }; + +template +struct synthesize_func + : detail::synthesize_impl + < Seq + , ::boost::function_types::detail::bits + < detail::retag_default_cc + < function_types::tag > + >::value + > +{ }; + +template +struct synthesize_mfp + : detail::synthesize_impl + < Seq + , ::boost::function_types::detail::bits + < detail::retag_default_cc + < function_types::tag + < typename detail::cv_traits< typename mpl::at_c::type >::tag + , nv_dcc_mfp, Tag + > > + >::value + > +{ }; + +template::type, + typename C = typename mpl::at_c::type> +struct synthesize_mop +{ + typedef R C::* type; +}; + +#define BOOST_FT_variations BOOST_FT_function|BOOST_FT_member_pointer +#define BOOST_FT_al_path boost/function_types/detail/synthesize_impl +#include + +} } } // namespace ::boost::function_types::detail + +#endif + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity10_0.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity10_0.hpp new file mode 100644 index 0000000..6d7c0f0 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity10_0.hpp @@ -0,0 +1,334 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,0) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (BOOST_FT_nullary_param BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 1 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,0) +< typename mpl::deref< iter_0 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,1) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 2 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,1) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,2) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 3 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,2) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,3) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 4 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,3) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,4) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 5 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,4) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,5) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 6 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,5) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,6) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 7 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,6) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,7) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 8 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,7) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,8) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 9 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,8) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,9) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 10 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,9) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,10) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 11 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,10) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity10_1.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity10_1.hpp new file mode 100644 index 0000000..38a9200 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity10_1.hpp @@ -0,0 +1,326 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , typename T0 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,1) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) ( BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 2 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,1) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,2) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 3 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,2) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,3) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 4 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,3) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,4) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 5 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,4) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,5) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 6 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,5) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,6) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 7 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,6) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,7) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 8 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,7) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,8) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 9 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,8) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,9) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 10 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,9) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +> ::type type; +}; +}; +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,10) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 11 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,10) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity20_0.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity20_0.hpp new file mode 100644 index 0000000..4f25172 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity20_0.hpp @@ -0,0 +1,517 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,11) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 12 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,11) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,12) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 13 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,12) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,13) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 14 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,13) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,14) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 15 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,14) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,15) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 16 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,15) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,16) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 17 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,16) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,17) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 18 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,17) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,18) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 19 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,18) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,19) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 20 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,19) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,20) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 21 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,20) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity20_1.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity20_1.hpp new file mode 100644 index 0000000..fa3f0e2 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity20_1.hpp @@ -0,0 +1,527 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,11) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 12 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,11) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,12) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 13 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,12) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,13) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 14 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,13) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,14) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 15 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,14) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,15) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 16 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,15) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,16) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 17 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,16) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,17) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 18 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,17) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,18) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 19 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,18) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,19) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 20 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,19) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,20) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 21 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,20) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity30_0.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity30_0.hpp new file mode 100644 index 0000000..9cd81de --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity30_0.hpp @@ -0,0 +1,717 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,21) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 22 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,21) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,22) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 23 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,22) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,23) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 24 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,23) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,24) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 25 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,24) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,25) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 26 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,25) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,26) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 27 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,26) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,27) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 28 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,27) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,28) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 29 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,28) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,29) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 30 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,29) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,30) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 31 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,30) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity30_1.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity30_1.hpp new file mode 100644 index 0000000..708d351 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity30_1.hpp @@ -0,0 +1,727 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,21) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 22 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,21) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,22) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 23 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,22) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,23) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 24 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,23) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,24) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 25 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,24) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,25) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 26 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,25) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,26) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 27 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,26) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,27) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 28 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,27) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,28) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 29 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,28) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,29) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 30 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,29) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,30) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 31 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,30) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity40_0.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity40_0.hpp new file mode 100644 index 0000000..a7d922f --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity40_0.hpp @@ -0,0 +1,917 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,31) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 32 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,31) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,32) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 33 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,32) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,33) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 34 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,33) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,34) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 35 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,34) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,35) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 36 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,35) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,36) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 37 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,36) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,37) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 38 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,37) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,38) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 39 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,38) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,39) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 40 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,39) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,40) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 41 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,40) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity40_1.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity40_1.hpp new file mode 100644 index 0000000..37a1190 --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity40_1.hpp @@ -0,0 +1,927 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,31) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 32 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,31) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,32) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 33 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,32) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,33) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 34 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,33) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,34) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 35 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,34) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,35) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 36 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,35) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,36) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 37 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,36) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,37) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 38 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,37) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,38) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 39 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,38) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,39) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 40 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,39) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,40) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 41 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,40) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity50_0.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity50_0.hpp new file mode 100644 index 0000000..2f7100c --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity50_0.hpp @@ -0,0 +1,1117 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,41) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 42 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,41) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,42) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 43 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,42) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,43) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 44 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,43) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,44) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 45 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,44) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,45) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 46 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,45) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,46) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 47 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,46) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,47) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 48 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,47) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,48) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 49 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,48) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,49) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 50 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +typedef typename mpl::next< iter_48 > ::type iter_49; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,49) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +, typename mpl::deref< iter_49 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,50) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 51 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +typedef typename mpl::next< iter_48 > ::type iter_49; +typedef typename mpl::next< iter_49 > ::type iter_50; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,50) +< typename mpl::deref< iter_0 > ::type +, typename mpl::deref< iter_1 > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +, typename mpl::deref< iter_49 > ::type +, typename mpl::deref< iter_50 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/arity50_1.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/arity50_1.hpp new file mode 100644 index 0000000..27afcfc --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/arity50_1.hpp @@ -0,0 +1,1127 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +// input: BOOST_FT_syntax type macro to use +// input: BOOST_FT_cc empty or cc specifier +// input: BOOST_FT_ell empty or "..." +// input: BOOST_FT_cv empty or cv qualifiers +// input: BOOST_FT_flags single decimal integer encoding the flags +// output: BOOST_FT_n number of component types (arity+1) +// output: BOOST_FT_arity current arity +// output: BOOST_FT_type macro that expands to the type +// output: BOOST_FT_tplargs(p) template arguments with given prefix +// output: BOOST_FT_params(p) parameters with given prefix + +# include +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,41) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 42 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,41) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,42) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 43 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,42) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,43) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 44 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,43) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,44) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 45 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,44) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,45) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 46 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,45) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,46) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 47 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,46) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,47) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 48 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,47) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,48) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 49 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,48) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,49) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 50 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +typedef typename mpl::next< iter_48 > ::type iter_49; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,49) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +, typename mpl::deref< iter_49 > ::type +> ::type type; +}; +}; +template< typename R , 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 BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,50) +{ +typedef BOOST_FT_syntax(BOOST_FT_cc,type BOOST_PP_EMPTY) (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 BOOST_FT_ell) BOOST_FT_cv ; +}; +template< > +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, 51 > +{ +template struct synthesize_impl_i +{ +private: +typedef typename mpl::begin ::type iter_0; +typedef typename mpl::next< iter_0 > ::type iter_1; +typedef typename mpl::next< iter_1 > ::type iter_2; +typedef typename mpl::next< iter_2 > ::type iter_3; +typedef typename mpl::next< iter_3 > ::type iter_4; +typedef typename mpl::next< iter_4 > ::type iter_5; +typedef typename mpl::next< iter_5 > ::type iter_6; +typedef typename mpl::next< iter_6 > ::type iter_7; +typedef typename mpl::next< iter_7 > ::type iter_8; +typedef typename mpl::next< iter_8 > ::type iter_9; +typedef typename mpl::next< iter_9 > ::type iter_10; +typedef typename mpl::next< iter_10 > ::type iter_11; +typedef typename mpl::next< iter_11 > ::type iter_12; +typedef typename mpl::next< iter_12 > ::type iter_13; +typedef typename mpl::next< iter_13 > ::type iter_14; +typedef typename mpl::next< iter_14 > ::type iter_15; +typedef typename mpl::next< iter_15 > ::type iter_16; +typedef typename mpl::next< iter_16 > ::type iter_17; +typedef typename mpl::next< iter_17 > ::type iter_18; +typedef typename mpl::next< iter_18 > ::type iter_19; +typedef typename mpl::next< iter_19 > ::type iter_20; +typedef typename mpl::next< iter_20 > ::type iter_21; +typedef typename mpl::next< iter_21 > ::type iter_22; +typedef typename mpl::next< iter_22 > ::type iter_23; +typedef typename mpl::next< iter_23 > ::type iter_24; +typedef typename mpl::next< iter_24 > ::type iter_25; +typedef typename mpl::next< iter_25 > ::type iter_26; +typedef typename mpl::next< iter_26 > ::type iter_27; +typedef typename mpl::next< iter_27 > ::type iter_28; +typedef typename mpl::next< iter_28 > ::type iter_29; +typedef typename mpl::next< iter_29 > ::type iter_30; +typedef typename mpl::next< iter_30 > ::type iter_31; +typedef typename mpl::next< iter_31 > ::type iter_32; +typedef typename mpl::next< iter_32 > ::type iter_33; +typedef typename mpl::next< iter_33 > ::type iter_34; +typedef typename mpl::next< iter_34 > ::type iter_35; +typedef typename mpl::next< iter_35 > ::type iter_36; +typedef typename mpl::next< iter_36 > ::type iter_37; +typedef typename mpl::next< iter_37 > ::type iter_38; +typedef typename mpl::next< iter_38 > ::type iter_39; +typedef typename mpl::next< iter_39 > ::type iter_40; +typedef typename mpl::next< iter_40 > ::type iter_41; +typedef typename mpl::next< iter_41 > ::type iter_42; +typedef typename mpl::next< iter_42 > ::type iter_43; +typedef typename mpl::next< iter_43 > ::type iter_44; +typedef typename mpl::next< iter_44 > ::type iter_45; +typedef typename mpl::next< iter_45 > ::type iter_46; +typedef typename mpl::next< iter_46 > ::type iter_47; +typedef typename mpl::next< iter_47 > ::type iter_48; +typedef typename mpl::next< iter_48 > ::type iter_49; +typedef typename mpl::next< iter_49 > ::type iter_50; +public: +typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,50) +< typename mpl::deref< iter_0 > ::type +, typename detail::cv_traits< +typename mpl::deref< iter_1 > ::type > ::type +, typename mpl::deref< iter_2 > ::type +, typename mpl::deref< iter_3 > ::type +, typename mpl::deref< iter_4 > ::type +, typename mpl::deref< iter_5 > ::type +, typename mpl::deref< iter_6 > ::type +, typename mpl::deref< iter_7 > ::type +, typename mpl::deref< iter_8 > ::type +, typename mpl::deref< iter_9 > ::type +, typename mpl::deref< iter_10 > ::type +, typename mpl::deref< iter_11 > ::type +, typename mpl::deref< iter_12 > ::type +, typename mpl::deref< iter_13 > ::type +, typename mpl::deref< iter_14 > ::type +, typename mpl::deref< iter_15 > ::type +, typename mpl::deref< iter_16 > ::type +, typename mpl::deref< iter_17 > ::type +, typename mpl::deref< iter_18 > ::type +, typename mpl::deref< iter_19 > ::type +, typename mpl::deref< iter_20 > ::type +, typename mpl::deref< iter_21 > ::type +, typename mpl::deref< iter_22 > ::type +, typename mpl::deref< iter_23 > ::type +, typename mpl::deref< iter_24 > ::type +, typename mpl::deref< iter_25 > ::type +, typename mpl::deref< iter_26 > ::type +, typename mpl::deref< iter_27 > ::type +, typename mpl::deref< iter_28 > ::type +, typename mpl::deref< iter_29 > ::type +, typename mpl::deref< iter_30 > ::type +, typename mpl::deref< iter_31 > ::type +, typename mpl::deref< iter_32 > ::type +, typename mpl::deref< iter_33 > ::type +, typename mpl::deref< iter_34 > ::type +, typename mpl::deref< iter_35 > ::type +, typename mpl::deref< iter_36 > ::type +, typename mpl::deref< iter_37 > ::type +, typename mpl::deref< iter_38 > ::type +, typename mpl::deref< iter_39 > ::type +, typename mpl::deref< iter_40 > ::type +, typename mpl::deref< iter_41 > ::type +, typename mpl::deref< iter_42 > ::type +, typename mpl::deref< iter_43 > ::type +, typename mpl::deref< iter_44 > ::type +, typename mpl::deref< iter_45 > ::type +, typename mpl::deref< iter_46 > ::type +, typename mpl::deref< iter_47 > ::type +, typename mpl::deref< iter_48 > ::type +, typename mpl::deref< iter_49 > ::type +, typename mpl::deref< iter_50 > ::type +> ::type type; +}; +}; +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl + diff --git a/thirdparty/boost/function_types/detail/synthesize_impl/master.hpp b/thirdparty/boost/function_types/detail/synthesize_impl/master.hpp new file mode 100644 index 0000000..131be3d --- /dev/null +++ b/thirdparty/boost/function_types/detail/synthesize_impl/master.hpp @@ -0,0 +1,87 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +// no include guards, this file is intended for multiple inclusion + +#if BOOST_FT_ARITY_LOOP_PREFIX + +# ifndef BOOST_FT_DETAIL_SYNTHESIZE_IMPL_MASTER_HPP_INCLUDED +# define BOOST_FT_DETAIL_SYNTHESIZE_IMPL_MASTER_HPP_INCLUDED +# include +# include +# include +# include +# include +# endif + +# define BOOST_FT_type_name type + +# ifdef BOOST_FT_flags +# define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +# define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +# else +BOOST_PP_EXPAND(#) define BOOST_FT_make_type(flags,cc,arity) BOOST_FT_make_type_impl(flags,cc,arity) +BOOST_PP_EXPAND(#) define BOOST_FT_make_type_impl(flags,cc,arity) make_type_ ## flags ## _ ## cc ## _ ## arity +# endif + +# define BOOST_FT_iter(i) BOOST_PP_CAT(iter_,i) + +#elif BOOST_FT_ARITY_LOOP_IS_ITERATING + +template< BOOST_FT_tplargs(BOOST_PP_IDENTITY(typename)) > +struct BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,BOOST_FT_arity) +{ + typedef BOOST_FT_type ; +}; + +template<> +struct synthesize_impl_o< BOOST_FT_flags, BOOST_FT_cc_id, BOOST_FT_n > +{ + template struct synthesize_impl_i + { + private: + typedef typename mpl::begin::type BOOST_FT_iter(0); +# if BOOST_FT_n > 1 +# define BOOST_PP_LOCAL_MACRO(i) typedef typename mpl::next< \ + BOOST_FT_iter(BOOST_PP_DEC(i)) >::type BOOST_FT_iter(i); +# define BOOST_PP_LOCAL_LIMITS (1,BOOST_FT_n-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + public: + typedef typename detail::BOOST_FT_make_type(BOOST_FT_flags,BOOST_FT_cc_id,BOOST_FT_arity) + < typename mpl::deref< BOOST_FT_iter(0) >::type +# if BOOST_FT_mfp + , typename detail::cv_traits< + typename mpl::deref< BOOST_FT_iter(1) >::type >::type +# endif +# if BOOST_FT_n > (BOOST_FT_mfp+1) +# define BOOST_PP_LOCAL_LIMITS (BOOST_FT_mfp+1,BOOST_FT_n-1) +# define BOOST_PP_LOCAL_MACRO(i) \ + , typename mpl::deref< BOOST_FT_iter(i) >::type +# include BOOST_PP_LOCAL_ITERATE() +# endif + >::type type; + }; +}; + +#elif BOOST_FT_ARITY_LOOP_SUFFIX + +# ifdef BOOST_FT_flags +# undef BOOST_FT_make_type +# undef BOOST_FT_make_type_impl +# else +BOOST_PP_EXPAND(#) undef BOOST_FT_make_type +BOOST_PP_EXPAND(#) undef BOOST_FT_make_type_impl +# endif +# undef BOOST_FT_iter +# undef BOOST_FT_type_name + +#else +# error "attempt to use arity loop master file without loop" +#endif + diff --git a/thirdparty/boost/function_types/detail/to_sequence.hpp b/thirdparty/boost/function_types/detail/to_sequence.hpp new file mode 100644 index 0000000..aa3e2a1 --- /dev/null +++ b/thirdparty/boost/function_types/detail/to_sequence.hpp @@ -0,0 +1,47 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_TO_SEQUENCE_HPP_INCLUDED +#define BOOST_FT_DETAIL_TO_SEQUENCE_HPP_INCLUDED + +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace function_types { namespace detail { + +// wrap first arguments in components, if callable builtin type +template +struct to_sequence +{ + typedef typename + mpl::eval_if + < is_callable_builtin + , to_sequence< components > + , mpl::identity< T > + >::type + type; +}; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +// reduce template instantiations, if possible +template +struct to_sequence< components > +{ + typedef typename components::types type; +}; +#endif + +} } } // namespace ::boost::function_types::detail + +#endif + diff --git a/thirdparty/boost/function_types/function_arity.hpp b/thirdparty/boost/function_types/function_arity.hpp new file mode 100644 index 0000000..84d2f2b --- /dev/null +++ b/thirdparty/boost/function_types/function_arity.hpp @@ -0,0 +1,38 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_FUNCTION_ARITY_HPP_INCLUDED +#define BOOST_FT_FUNCTION_ARITY_HPP_INCLUDED + +#include +#include + +#include +#include + +#include +#include + +namespace boost +{ + namespace function_types + { + template struct function_arity + : mpl::if_ + < function_types::is_callable_builtin + , typename components::function_arity, boost::blank + >::type + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,function_arity,(T)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::function_arity) +} + +#endif + diff --git a/thirdparty/boost/function_types/function_pointer.hpp b/thirdparty/boost/function_types/function_pointer.hpp new file mode 100644 index 0000000..5182bc9 --- /dev/null +++ b/thirdparty/boost/function_types/function_pointer.hpp @@ -0,0 +1,32 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_FUNCTION_POINTER_HPP_INCLUDED +#define BOOST_FT_FUNCTION_POINTER_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template struct function_pointer + { + typedef typename function_types::function_type::type * type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_pointer,(Types,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_pointer) +} + +#endif + diff --git a/thirdparty/boost/function_types/function_reference.hpp b/thirdparty/boost/function_types/function_reference.hpp new file mode 100644 index 0000000..58d0bbb --- /dev/null +++ b/thirdparty/boost/function_types/function_reference.hpp @@ -0,0 +1,32 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_FUNCTION_REFERENCE_HPP_INCLUDED +#define BOOST_FT_FUNCTION_REFERENCE_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template struct function_reference + { + typedef typename function_types::function_type::type & type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_reference,(Types,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_reference) +} + +#endif + diff --git a/thirdparty/boost/function_types/function_type.hpp b/thirdparty/boost/function_types/function_type.hpp new file mode 100644 index 0000000..2fca242 --- /dev/null +++ b/thirdparty/boost/function_types/function_type.hpp @@ -0,0 +1,29 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_FUNCTION_TYPE_HPP_INCLUDED +#define BOOST_FT_FUNCTION_TYPE_HPP_INCLUDED + +#include +#include + +namespace boost +{ + namespace function_types + { + template struct function_type + : detail::synthesize_func::type, Tag> + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,function_type,(Types,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::function_type) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_callable_builtin.hpp b/thirdparty/boost/function_types/is_callable_builtin.hpp new file mode 100644 index 0000000..f323cda --- /dev/null +++ b/thirdparty/boost/function_types/is_callable_builtin.hpp @@ -0,0 +1,35 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_CALLABLE_BUILTIN_HPP_INCLUDED +#define BOOST_FT_IS_CALLABLE_BUILTIN_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_callable_builtin + : function_types::represents + < function_types::components + , function_types::tag + > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_callable_builtin,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_callable_builtin) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_function.hpp b/thirdparty/boost/function_types/is_function.hpp new file mode 100644 index 0000000..6cb2049 --- /dev/null +++ b/thirdparty/boost/function_types/is_function.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_FUNCTION_HPP_INCLUDED +#define BOOST_FT_IS_FUNCTION_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_function + : function_types::represents + < function_types::components + , function_types::tag + > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_function_pointer.hpp b/thirdparty/boost/function_types/is_function_pointer.hpp new file mode 100644 index 0000000..be52c2b --- /dev/null +++ b/thirdparty/boost/function_types/is_function_pointer.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_FUNCTION_POINTER_HPP_INCLUDED +#define BOOST_FT_IS_FUNCTION_POINTER_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_function_pointer + : function_types::represents + < function_types::components + , function_types::tag + > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function_pointer,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function_pointer) +} + +#endif diff --git a/thirdparty/boost/function_types/is_function_reference.hpp b/thirdparty/boost/function_types/is_function_reference.hpp new file mode 100644 index 0000000..08b4644 --- /dev/null +++ b/thirdparty/boost/function_types/is_function_reference.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_FUNCTION_REFERENCE_HPP_INCLUDED +#define BOOST_FT_IS_FUNCTION_REFERENCE_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_function_reference + : function_types::represents + < function_types::components + , function_types::tag > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_function_reference,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_function_reference) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_member_function_pointer.hpp b/thirdparty/boost/function_types/is_member_function_pointer.hpp new file mode 100644 index 0000000..744829b --- /dev/null +++ b/thirdparty/boost/function_types/is_member_function_pointer.hpp @@ -0,0 +1,33 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED +#define BOOST_FT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_member_function_pointer + : function_types::represents + < function_types::components + , function_types::tag > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_member_function_pointer,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_member_function_pointer) +} +#endif + diff --git a/thirdparty/boost/function_types/is_member_object_pointer.hpp b/thirdparty/boost/function_types/is_member_object_pointer.hpp new file mode 100644 index 0000000..a21a68f --- /dev/null +++ b/thirdparty/boost/function_types/is_member_object_pointer.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_MEMBER_OBJECT_POINTER_HPP_INCLUDED +#define BOOST_FT_IS_MEMBER_OBJECT_POINTER_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T > + struct is_member_object_pointer + : function_types::detail::represents_impl + < function_types::components + , detail::member_object_pointer_tag > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_member_object_pointer,(T)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::is_member_object_pointer) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_member_pointer.hpp b/thirdparty/boost/function_types/is_member_pointer.hpp new file mode 100644 index 0000000..2d3b89a --- /dev/null +++ b/thirdparty/boost/function_types/is_member_pointer.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_MEMBER_POINTER_HPP_INCLUDED +#define BOOST_FT_IS_MEMBER_POINTER_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_member_pointer + : function_types::represents + < function_types::components + , function_types::tag + > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_member_pointer,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_member_pointer) +} + +#endif + diff --git a/thirdparty/boost/function_types/is_nonmember_callable_builtin.hpp b/thirdparty/boost/function_types/is_nonmember_callable_builtin.hpp new file mode 100644 index 0000000..f63babc --- /dev/null +++ b/thirdparty/boost/function_types/is_nonmember_callable_builtin.hpp @@ -0,0 +1,35 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_IS_NONMEMBER_CALLABLE_BUILTIN_HPP_INCLUDED +#define BOOST_FT_IS_NONMEMBER_CALLABLE_BUILTIN_HPP_INCLUDED + +#include +#include + +#include + +namespace boost +{ + namespace function_types + { + template< typename T, typename Tag = null_tag > + struct is_nonmember_callable_builtin + : function_types::represents + < function_types::components + , function_types::tag + > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_nonmember_callable_builtin,(T,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::is_nonmember_callable_builtin) +} + +#endif + diff --git a/thirdparty/boost/function_types/member_function_pointer.hpp b/thirdparty/boost/function_types/member_function_pointer.hpp new file mode 100644 index 0000000..082713c --- /dev/null +++ b/thirdparty/boost/function_types/member_function_pointer.hpp @@ -0,0 +1,33 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_MEMBER_FUNCTION_POINTER_HPP_INCLUDED +#define BOOST_FT_MEMBER_FUNCTION_POINTER_HPP_INCLUDED + +#include +#include + +#include +#include + +namespace boost +{ + namespace function_types + { + template + struct member_function_pointer + : detail::synthesize_mfp< typename detail::to_sequence::type, Tag > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,member_function_pointer,(Types,Tag)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::member_function_pointer) +} + +#endif + diff --git a/thirdparty/boost/function_types/member_object_pointer.hpp b/thirdparty/boost/function_types/member_object_pointer.hpp new file mode 100644 index 0000000..070a334 --- /dev/null +++ b/thirdparty/boost/function_types/member_object_pointer.hpp @@ -0,0 +1,34 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_MEMBER_OBJECT_POINTER_HPP_INCLUDED +#define BOOST_FT_MEMBER_OBJECT_POINTER_HPP_INCLUDED + +#include +#include + +#include +#include + +namespace boost +{ + namespace function_types + { + template + struct member_object_pointer + : detail::synthesize_mop< typename detail::to_sequence::type > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,member_object_pointer,(Types)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::member_object_pointer) +} + +#endif + + diff --git a/thirdparty/boost/function_types/parameter_types.hpp b/thirdparty/boost/function_types/parameter_types.hpp new file mode 100644 index 0000000..08fb793 --- /dev/null +++ b/thirdparty/boost/function_types/parameter_types.hpp @@ -0,0 +1,55 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_PARAMETER_TYPES_HPP_INCLUDED +#define BOOST_FT_PARAMETER_TYPES_HPP_INCLUDED + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace boost +{ + namespace function_types + { + using mpl::placeholders::_; + + template< typename T, typename ClassTypeTransform = add_reference<_> > + struct parameter_types; + + namespace detail + { + template + struct parameter_types_impl + : mpl::pop_front + < typename function_types::components::types + >::type + { }; + } + + template struct parameter_types + : mpl::if_ + < function_types::is_callable_builtin + , detail::parameter_types_impl, boost::blank + >::type + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,parameter_types,(T,ClassTypeTransform)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(2,function_types::parameter_types) +} + +#endif + diff --git a/thirdparty/boost/function_types/property_tags.hpp b/thirdparty/boost/function_types/property_tags.hpp new file mode 100644 index 0000000..74f710a --- /dev/null +++ b/thirdparty/boost/function_types/property_tags.hpp @@ -0,0 +1,149 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_DETAIL_TAGS_HPP_INCLUDED +#define BOOST_FT_DETAIL_TAGS_HPP_INCLUDED + +#include + +#include +#include + + +namespace boost { namespace function_types { + +namespace detail +{ + typedef long bits_t; + + template struct constant + : boost::integral_constant + { }; + + template struct property_tag + { + typedef constant bits; + typedef constant mask; + }; + + template struct bits : T::bits { }; + template struct mask : T::mask { }; + + // forward declaration, defined in pp_tags + template struct encode_bits_impl; + + // forward declaration, defined in pp_tags + template + struct tag_ice; + + // forward declaration, defined in retag_default_cc + template struct retag_default_cc; + + template struct encode_bits + : constant< + ::boost::function_types::detail::encode_bits_impl::value + > + { }; + + template struct compound_tag + { + typedef constant< + ::boost::function_types::detail::tag_ice + < ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + , ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + >::combined_bits + > bits; + + typedef constant< + ::boost::function_types::detail::tag_ice + < ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + , ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + >::combined_mask + > mask; + }; + + template + struct changed_tag + : Base + { + typedef mpl::bitxor_ + + bits; + }; + + template struct represents_impl + : boost::integral_constant::value + , ::boost::function_types::detail::mask::value + , ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + >::match + > + { }; + +} // namespace detail + +typedef detail::property_tag<0,0> null_tag; + +template +struct tag + : detail::compound_tag< detail::compound_tag, + detail::compound_tag > +{ }; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template struct tag + : detail::compound_tag,Tag3> +{ }; +template struct tag + : detail::compound_tag +{ }; +template struct tag + : Tag1 +{ }; +#endif + + +template struct represents + : detail::represents_impl > +{ }; + + +template struct extract +{ + typedef detail::constant< + ::boost::function_types::detail::tag_ice + < ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + , ::boost::function_types::detail::bits::value + , ::boost::function_types::detail::mask::value + >::extracted_bits + > bits; + + typedef detail::constant< + ::boost::function_types::detail::mask::value + > mask; +}; + +} } // namespace ::boost::function_types + +#include + +namespace boost { namespace function_types { +#define BOOST_FT_cc_file +#include +} } // namespace boost::function_types + +#endif + diff --git a/thirdparty/boost/function_types/result_type.hpp b/thirdparty/boost/function_types/result_type.hpp new file mode 100644 index 0000000..3bf1726 --- /dev/null +++ b/thirdparty/boost/function_types/result_type.hpp @@ -0,0 +1,50 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#ifndef BOOST_FT_RESULT_TYPE_HPP_INCLUDED +#define BOOST_FT_RESULT_TYPE_HPP_INCLUDED + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace boost +{ + namespace function_types + { + template< typename T > struct result_type; + + namespace detail + { + template struct result_type_impl + : mpl::at_c + < typename function_types::components::types, 0 > + { }; + } + + template struct result_type + : mpl::if_ + < function_types::is_callable_builtin + , detail::result_type_impl, boost::blank + >::type + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,result_type,(T)) + }; + } + BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,function_types::result_type) +} + +#endif + diff --git a/thirdparty/boost/functional.hpp b/thirdparty/boost/functional.hpp new file mode 100644 index 0000000..b1854a9 --- /dev/null +++ b/thirdparty/boost/functional.hpp @@ -0,0 +1,548 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2000 Cadenza New Zealand Ltd +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// ------------------------------------------------------------------------------ +// Boost functional.hpp header file +// See http://www.boost.org/libs/functional for documentation. +// ------------------------------------------------------------------------------ +// $Id: functional.hpp 36246 2006-12-02 14:17:26Z andreas_huber69 $ +// ------------------------------------------------------------------------------ + +#ifndef BOOST_FUNCTIONAL_HPP +#define BOOST_FUNCTIONAL_HPP + +#include +#include +#include + +namespace boost +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // -------------------------------------------------------------------------- + // The following traits classes allow us to avoid the need for ptr_fun + // because the types of arguments and the result of a function can be + // deduced. + // + // In addition to the standard types defined in unary_function and + // binary_function, we add + // + // - function_type, the type of the function or function object itself. + // + // - param_type, the type that should be used for passing the function or + // function object as an argument. + // -------------------------------------------------------------------------- + namespace detail + { + template + struct unary_traits_imp; + + template + struct unary_traits_imp + { + typedef Operation function_type; + typedef const function_type & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::argument_type argument_type; + }; + + template + struct unary_traits_imp + { + typedef R (*function_type)(A); + typedef R (*param_type)(A); + typedef R result_type; + typedef A argument_type; + }; + + template + struct binary_traits_imp; + + template + struct binary_traits_imp + { + typedef Operation function_type; + typedef const function_type & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::first_argument_type first_argument_type; + typedef typename Operation::second_argument_type second_argument_type; + }; + + template + struct binary_traits_imp + { + typedef R (*function_type)(A1,A2); + typedef R (*param_type)(A1,A2); + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + }; + } // namespace detail + + template + struct unary_traits + { + typedef typename detail::unary_traits_imp::function_type function_type; + typedef typename detail::unary_traits_imp::param_type param_type; + typedef typename detail::unary_traits_imp::result_type result_type; + typedef typename detail::unary_traits_imp::argument_type argument_type; + }; + + template + struct unary_traits + { + typedef R (*function_type)(A); + typedef R (*param_type)(A); + typedef R result_type; + typedef A argument_type; + }; + + template + struct binary_traits + { + typedef typename detail::binary_traits_imp::function_type function_type; + typedef typename detail::binary_traits_imp::param_type param_type; + typedef typename detail::binary_traits_imp::result_type result_type; + typedef typename detail::binary_traits_imp::first_argument_type first_argument_type; + typedef typename detail::binary_traits_imp::second_argument_type second_argument_type; + }; + + template + struct binary_traits + { + typedef R (*function_type)(A1,A2); + typedef R (*param_type)(A1,A2); + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + }; +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // -------------------------------------------------------------------------- + // If we have no partial specialisation available, decay to a situation + // that is no worse than in the Standard, i.e., ptr_fun will be required. + // -------------------------------------------------------------------------- + + template + struct unary_traits + { + typedef Operation function_type; + typedef const Operation& param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::argument_type argument_type; + }; + + template + struct binary_traits + { + typedef Operation function_type; + typedef const Operation & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::first_argument_type first_argument_type; + typedef typename Operation::second_argument_type second_argument_type; + }; +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // -------------------------------------------------------------------------- + // unary_negate, not1 + // -------------------------------------------------------------------------- + template + class unary_negate + : public std::unary_function::argument_type,bool> + { + public: + explicit unary_negate(typename unary_traits::param_type x) + : + pred(x) + {} + bool operator()(typename call_traits::argument_type>::param_type x) const + { + return !pred(x); + } + private: + typename unary_traits::function_type pred; + }; + + template + unary_negate not1(const Predicate &pred) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return unary_negate((typename unary_traits::param_type)pred); + } + + template + unary_negate not1(Predicate &pred) + { + return unary_negate(pred); + } + + // -------------------------------------------------------------------------- + // binary_negate, not2 + // -------------------------------------------------------------------------- + template + class binary_negate + : public std::binary_function::first_argument_type, + typename binary_traits::second_argument_type, + bool> + { + public: + explicit binary_negate(typename binary_traits::param_type x) + : + pred(x) + {} + bool operator()(typename call_traits::first_argument_type>::param_type x, + typename call_traits::second_argument_type>::param_type y) const + { + return !pred(x,y); + } + private: + typename binary_traits::function_type pred; + }; + + template + binary_negate not2(const Predicate &pred) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binary_negate((typename binary_traits::param_type)pred); + } + + template + binary_negate not2(Predicate &pred) + { + return binary_negate(pred); + } + + // -------------------------------------------------------------------------- + // binder1st, bind1st + // -------------------------------------------------------------------------- + template + class binder1st + : public std::unary_function::second_argument_type, + typename binary_traits::result_type> + { + public: + binder1st(typename binary_traits::param_type x, + typename call_traits::first_argument_type>::param_type y) + : + op(x), value(y) + {} + + typename binary_traits::result_type + operator()(typename call_traits::second_argument_type>::param_type x) const + { + return op(value, x); + } + + protected: + typename binary_traits::function_type op; + typename binary_traits::first_argument_type value; + }; + + template + inline binder1st bind1st(const Operation &op, + typename call_traits< + typename binary_traits::first_argument_type + >::param_type x) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binder1st((typename binary_traits::param_type)op, x); + } + + template + inline binder1st bind1st(Operation &op, + typename call_traits< + typename binary_traits::first_argument_type + >::param_type x) + { + return binder1st(op, x); + } + + // -------------------------------------------------------------------------- + // binder2nd, bind2nd + // -------------------------------------------------------------------------- + template + class binder2nd + : public std::unary_function::first_argument_type, + typename binary_traits::result_type> + { + public: + binder2nd(typename binary_traits::param_type x, + typename call_traits::second_argument_type>::param_type y) + : + op(x), value(y) + {} + + typename binary_traits::result_type + operator()(typename call_traits::first_argument_type>::param_type x) const + { + return op(x, value); + } + + protected: + typename binary_traits::function_type op; + typename binary_traits::second_argument_type value; + }; + + template + inline binder2nd bind2nd(const Operation &op, + typename call_traits< + typename binary_traits::second_argument_type + >::param_type x) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binder2nd((typename binary_traits::param_type)op, x); + } + + template + inline binder2nd bind2nd(Operation &op, + typename call_traits< + typename binary_traits::second_argument_type + >::param_type x) + { + return binder2nd(op, x); + } + + // -------------------------------------------------------------------------- + // mem_fun, etc + // -------------------------------------------------------------------------- + template + class mem_fun_t : public std::unary_function + { + public: + explicit mem_fun_t(S (T::*p)()) + : + ptr(p) + {} + S operator()(T* p) const + { + return (p->*ptr)(); + } + private: + S (T::*ptr)(); + }; + + template + class mem_fun1_t : public std::binary_function + { + public: + explicit mem_fun1_t(S (T::*p)(A)) + : + ptr(p) + {} + S operator()(T* p, typename call_traits::param_type x) const + { + return (p->*ptr)(x); + } + private: + S (T::*ptr)(A); + }; + + template + class const_mem_fun_t : public std::unary_function + { + public: + explicit const_mem_fun_t(S (T::*p)() const) + : + ptr(p) + {} + S operator()(const T* p) const + { + return (p->*ptr)(); + } + private: + S (T::*ptr)() const; + }; + + template + class const_mem_fun1_t : public std::binary_function + { + public: + explicit const_mem_fun1_t(S (T::*p)(A) const) + : + ptr(p) + {} + S operator()(const T* p, typename call_traits::param_type x) const + { + return (p->*ptr)(x); + } + private: + S (T::*ptr)(A) const; + }; + + template + inline mem_fun_t mem_fun(S (T::*f)()) + { + return mem_fun_t(f); + } + + template + inline mem_fun1_t mem_fun(S (T::*f)(A)) + { + return mem_fun1_t(f); + } + +#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST + template + inline const_mem_fun_t mem_fun(S (T::*f)() const) + { + return const_mem_fun_t(f); + } + + template + inline const_mem_fun1_t mem_fun(S (T::*f)(A) const) + { + return const_mem_fun1_t(f); + } +#endif // BOOST_NO_POINTER_TO_MEMBER_CONST + + // -------------------------------------------------------------------------- + // mem_fun_ref, etc + // -------------------------------------------------------------------------- + template + class mem_fun_ref_t : public std::unary_function + { + public: + explicit mem_fun_ref_t(S (T::*p)()) + : + ptr(p) + {} + S operator()(T& p) const + { + return (p.*ptr)(); + } + private: + S (T::*ptr)(); + }; + + template + class mem_fun1_ref_t : public std::binary_function + { + public: + explicit mem_fun1_ref_t(S (T::*p)(A)) + : + ptr(p) + {} + S operator()(T& p, typename call_traits::param_type x) const + { + return (p.*ptr)(x); + } + private: + S (T::*ptr)(A); + }; + + template + class const_mem_fun_ref_t : public std::unary_function + { + public: + explicit const_mem_fun_ref_t(S (T::*p)() const) + : + ptr(p) + {} + + S operator()(const T &p) const + { + return (p.*ptr)(); + } + private: + S (T::*ptr)() const; + }; + + template + class const_mem_fun1_ref_t : public std::binary_function + { + public: + explicit const_mem_fun1_ref_t(S (T::*p)(A) const) + : + ptr(p) + {} + + S operator()(const T& p, typename call_traits::param_type x) const + { + return (p.*ptr)(x); + } + private: + S (T::*ptr)(A) const; + }; + + template + inline mem_fun_ref_t mem_fun_ref(S (T::*f)()) + { + return mem_fun_ref_t(f); + } + + template + inline mem_fun1_ref_t mem_fun_ref(S (T::*f)(A)) + { + return mem_fun1_ref_t(f); + } + +#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST + template + inline const_mem_fun_ref_t mem_fun_ref(S (T::*f)() const) + { + return const_mem_fun_ref_t(f); + } + + template + inline const_mem_fun1_ref_t mem_fun_ref(S (T::*f)(A) const) + { + return const_mem_fun1_ref_t(f); + } +#endif // BOOST_NO_POINTER_TO_MEMBER_CONST + + // -------------------------------------------------------------------------- + // ptr_fun + // -------------------------------------------------------------------------- + template + class pointer_to_unary_function : public std::unary_function + { + public: + explicit pointer_to_unary_function(Result (*f)(Arg)) + : + func(f) + {} + + Result operator()(typename call_traits::param_type x) const + { + return func(x); + } + + private: + Result (*func)(Arg); + }; + + template + inline pointer_to_unary_function ptr_fun(Result (*f)(Arg)) + { + return pointer_to_unary_function(f); + } + + template + class pointer_to_binary_function : public std::binary_function + { + public: + explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)) + : + func(f) + {} + + Result operator()(typename call_traits::param_type x, typename call_traits::param_type y) const + { + return func(x,y); + } + + private: + Result (*func)(Arg1, Arg2); + }; + + template + inline pointer_to_binary_function ptr_fun(Result (*f)(Arg1, Arg2)) + { + return pointer_to_binary_function(f); + } +} // namespace boost + +#endif diff --git a/thirdparty/boost/functional/detail/container_fwd.hpp b/thirdparty/boost/functional/detail/container_fwd.hpp new file mode 100644 index 0000000..21b4981 --- /dev/null +++ b/thirdparty/boost/functional/detail/container_fwd.hpp @@ -0,0 +1,95 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_DETAIL_CONTAINER_FWD_HPP) +#define BOOST_DETAIL_CONTAINER_FWD_HPP + +#include +#include + +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#define BOOST_HASH_CHAR_TRAITS string_char_traits +#else +#define BOOST_HASH_CHAR_TRAITS char_traits +#endif + +#if (defined(__GLIBCXX__) && defined(_GLIBCXX_DEBUG)) \ + || BOOST_WORKAROUND(__BORLANDC__, > 0x551) \ + || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \ + || (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) + +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && \ + defined(__STL_CONFIG_H) + +#define BOOST_CONTAINER_FWD_BAD_BITSET + +#if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) +#define BOOST_CONTAINER_FWD_BAD_DEQUE +#endif + +#endif + +#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE) +#include +#endif + +#if defined(BOOST_CONTAINER_FWD_BAD_BITSET) +#include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4099) // struct/class mismatch in fwd declarations +#endif + +namespace std +{ + template class allocator; + template class basic_string; + template struct BOOST_HASH_CHAR_TRAITS; + template class complex; +} + +// gcc 3.4 and greater +namespace std +{ +#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE) + template class deque; +#endif + + template class list; + template class vector; + template class map; + template + class multimap; + template class set; + template class multiset; + +#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET) + template class bitset; +#endif + template struct pair; +} + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif + +#endif diff --git a/thirdparty/boost/functional/detail/float_functions.hpp b/thirdparty/boost/functional/detail/float_functions.hpp new file mode 100644 index 0000000..e88f5eb --- /dev/null +++ b/thirdparty/boost/functional/detail/float_functions.hpp @@ -0,0 +1,154 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP) +#define BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP + +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// The C++ standard requires that the C float functions are overloarded +// for float, double and long double in the std namespace, but some of the older +// library implementations don't support this. On some that don't, the C99 +// float functions (frexpf, frexpl, etc.) are available. +// +// Some of this is based on guess work. If I don't know any better I assume that +// the standard C++ overloaded functions are available. If they're not then this +// means that the argument is cast to a double and back, which is inefficient +// and will give pretty bad results for long doubles - so if you know better +// let me know. + +// STLport: +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +# if (defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))) || defined(__DMC__) +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# elif defined(BOOST_MSVC) && BOOST_MSVC < 1300 +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# else +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +# endif + +// Roguewave: +// +// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't +// defined, but for the same version of roguewave on sunpro they are. +#elif defined(_RWSTD_VER) +# if defined(__BORLANDC__) +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# define BOOST_HASH_C99_NO_FLOAT_FUNCS +# elif defined(__DECCXX) +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# else +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +# endif + +// libstdc++ (gcc 3.0 onwards, I think) +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS + +// SGI: +#elif defined(__STL_CONFIG_H) +# if defined(linux) || defined(__linux) || defined(__linux__) +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# else +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +# endif + +// Dinkumware. +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Overloaded float functions were probably introduced in an earlier version +// than this. +# if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402) +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +# else +# define BOOST_HASH_USE_C99_FLOAT_FUNCS +# endif + +// Digital Mars +#elif defined(__DMC__) +# define BOOST_HASH_USE_C99_FLOAT_FUNCS + +// Use overloaded float functions by default. +#else +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +#endif + +namespace boost +{ + namespace hash_detail + { + + inline float call_ldexp(float v, int exp) + { + using namespace std; +#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \ + defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) + return ldexp(v, exp); +#else + return ldexpf(v, exp); +#endif + } + + inline double call_ldexp(double v, int exp) + { + using namespace std; + return ldexp(v, exp); + } + + inline long double call_ldexp(long double v, int exp) + { + using namespace std; +#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) + return ldexp(v, exp); +#else + return ldexpl(v, exp); +#endif + } + + inline float call_frexp(float v, int* exp) + { + using namespace std; +#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \ + defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) + return frexp(v, exp); +#else + return frexpf(v, exp); +#endif + } + + inline double call_frexp(double v, int* exp) + { + using namespace std; + return frexp(v, exp); + } + + inline long double call_frexp(long double v, int* exp) + { + using namespace std; +#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) + return frexp(v, exp); +#else + return frexpl(v, exp); +#endif + } + } +} + +#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS) +#undef BOOST_HASH_USE_C99_FLOAT_FUNCS +#endif + +#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) +#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS +#endif + +#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) +#undef BOOST_HASH_C99_NO_FLOAT_FUNCS +#endif + +#endif diff --git a/thirdparty/boost/functional/detail/hash_float.hpp b/thirdparty/boost/functional/detail/hash_float.hpp new file mode 100644 index 0000000..9dd29f5 --- /dev/null +++ b/thirdparty/boost/functional/detail/hash_float.hpp @@ -0,0 +1,196 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER) +#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +#if BOOST_MSVC >= 1400 +#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does + // not satisfy test. Loop body not executed +#endif +#endif + +#include +#include +#include +#include +#include + +// Select implementation for the current platform. + +// Cygwn +#if defined(__CYGWIN__) +# if defined(__i386__) || defined(_M_IX86) +# define BOOST_HASH_USE_x86_BINARY_HASH +# endif + +// STLport +#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// _fpclass and fpclassify aren't good enough on STLport. + +// GNU libstdc++ 3 +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \ + !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +# define BOOST_HASH_USE_FPCLASSIFY +# endif + +// Dinkumware Library, on Visual C++ +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) + +// Not using _fpclass because it causes a warning about a conversion +// from 'long double' to 'double'. Pity. +// +//# if defined(BOOST_MSVC) +//# define BOOST_HASH_USE_FPCLASS +//# endif + +#endif + +namespace boost +{ + namespace hash_detail + { + inline void hash_float_combine(std::size_t& seed, std::size_t value) + { + seed ^= value + (seed<<6) + (seed>>2); + } + +// A simple, non-portable hash algorithm for x86. +#if defined(BOOST_HASH_USE_x86_BINARY_HASH) + inline std::size_t float_hash_impl(float v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr; + return seed; + } + + inline std::size_t float_hash_impl(double v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr++; + hash_float_combine(seed, *ptr); + return seed; + } + + inline std::size_t float_hash_impl(long double v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr++; + hash_float_combine(seed, *ptr++); + hash_float_combine(seed, *(boost::uint16_t*)ptr); + return seed; + } + +#else + + template + inline std::size_t float_hash_impl(T v) + { + int exp = 0; + + v = boost::hash_detail::call_frexp(v, &exp); + + // A postive value is easier to hash, so combine the + // sign with the exponent. + if(v < 0) { + v = -v; + exp += std::numeric_limits::max_exponent - + std::numeric_limits::min_exponent; + } + + // The result of frexp is always between 0.5 and 1, so its + // top bit will always be 1. Subtract by 0.5 to remove that. + v -= T(0.5); + v = boost::hash_detail::call_ldexp(v, + std::numeric_limits::digits + 1); + std::size_t seed = static_cast(v); + v -= seed; + + // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1; + std::size_t const length + = (std::numeric_limits::digits * + boost::static_log2::radix>::value + - 1) + / std::numeric_limits::digits; + + for(std::size_t i = 0; i != length; ++i) + { + v = boost::hash_detail::call_ldexp(v, + std::numeric_limits::digits); + std::size_t part = static_cast(v); + v -= part; + hash_float_combine(seed, part); + } + + hash_float_combine(seed, exp); + + return seed; + } +#endif + + template + inline std::size_t float_hash_value(T v) + { +#if defined(BOOST_HASH_USE_FPCLASSIFY) + using namespace std; + switch (fpclassify(v)) { + case FP_ZERO: + return 0; + case FP_INFINITE: + return (std::size_t)(v > 0 ? -1 : -2); + case FP_NAN: + return (std::size_t)(-3); + case FP_NORMAL: + case FP_SUBNORMAL: + return float_hash_impl(v); + default: + BOOST_ASSERT(0); + return 0; + } +#elif defined(BOOST_HASH_USE_FPCLASS) + switch(_fpclass(v)) { + case _FPCLASS_NZ: + case _FPCLASS_PZ: + return 0; + case _FPCLASS_PINF: + return (std::size_t)(-1); + case _FPCLASS_NINF: + return (std::size_t)(-2); + case _FPCLASS_SNAN: + case _FPCLASS_QNAN: + return (std::size_t)(-3); + case _FPCLASS_NN: + case _FPCLASS_ND: + return float_hash_impl(v); + case _FPCLASS_PD: + case _FPCLASS_PN: + return float_hash_impl(v); + default: + BOOST_ASSERT(0); + return 0; + } +#else + return v == 0 ? 0 : float_hash_impl(v); +#endif + } + } +} + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif diff --git a/thirdparty/boost/functional/hash.hpp b/thirdparty/boost/functional/hash.hpp new file mode 100644 index 0000000..8498ef1 --- /dev/null +++ b/thirdparty/boost/functional/hash.hpp @@ -0,0 +1,10 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#include diff --git a/thirdparty/boost/functional/hash/deque.hpp b/thirdparty/boost/functional/hash/deque.hpp new file mode 100644 index 0000000..3b934cd --- /dev/null +++ b/thirdparty/boost/functional/hash/deque.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_DEQUE_HPP) +#define BOOST_FUNCTIONAL_HASH_DEQUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/deque.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/deque.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash/hash.hpp b/thirdparty/boost/functional/hash/hash.hpp new file mode 100644 index 0000000..f22c8e6 --- /dev/null +++ b/thirdparty/boost/functional/hash/hash.hpp @@ -0,0 +1,693 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP) +#define BOOST_FUNCTIONAL_HASH_HASH_HPP + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#include +#endif + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +#include +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +#include +#endif + +namespace boost +{ + std::size_t hash_value(bool); + std::size_t hash_value(char); + std::size_t hash_value(unsigned char); + std::size_t hash_value(signed char); + std::size_t hash_value(short); + std::size_t hash_value(unsigned short); + std::size_t hash_value(int); + std::size_t hash_value(unsigned int); + std::size_t hash_value(long); + std::size_t hash_value(unsigned long); + +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + std::size_t hash_value(wchar_t); +#endif + +#if defined(BOOST_HAS_LONG_LONG) + std::size_t hash_value(long long); + std::size_t hash_value(unsigned long long); +#endif + +#if !BOOST_WORKAROUND(__DMC__, <= 0x848) + template std::size_t hash_value(T* const&); +#else + template std::size_t hash_value(T*); +#endif + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template< class T, unsigned N > + std::size_t hash_value(const T (&array)[N]); + + template< class T, unsigned N > + std::size_t hash_value(T (&array)[N]); +#endif + + std::size_t hash_value(float v); + std::size_t hash_value(double v); + std::size_t hash_value(long double v); + + template + std::size_t hash_value(std::basic_string, A> const&); + + template + std::size_t hash_value(std::pair const&); + template + std::size_t hash_value(std::vector const&); + template + std::size_t hash_value(std::list const& v); + template + std::size_t hash_value(std::deque const& v); + template + std::size_t hash_value(std::set const& v); + template + std::size_t hash_value(std::multiset const& v); + template + std::size_t hash_value(std::map const& v); + template + std::size_t hash_value(std::multimap const& v); + + template + std::size_t hash_value(std::complex const&); + + // Implementation + + namespace hash_detail + { + template + inline std::size_t hash_value_signed(T val) + { + const int size_t_bits = std::numeric_limits::digits; + // ceiling(std::numeric_limits::digits / size_t_bits) - 1 + const int length = (std::numeric_limits::digits - 1) + / size_t_bits; + + std::size_t seed = 0; + T positive = val < 0 ? -1 - val : val; + + // Hopefully, this loop can be unrolled. + for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) + { + seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2); + } + seed ^= (std::size_t) val + (seed<<6) + (seed>>2); + + return seed; + } + + template + inline std::size_t hash_value_unsigned(T val) + { + const int size_t_bits = std::numeric_limits::digits; + // ceiling(std::numeric_limits::digits / size_t_bits) - 1 + const int length = (std::numeric_limits::digits - 1) + / size_t_bits; + + std::size_t seed = 0; + + // Hopefully, this loop can be unrolled. + for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) + { + seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2); + } + seed ^= (std::size_t) val + (seed<<6) + (seed>>2); + + return seed; + } + } + + inline std::size_t hash_value(bool v) + { + return static_cast(v); + } + + inline std::size_t hash_value(char v) + { + return static_cast(v); + } + + inline std::size_t hash_value(unsigned char v) + { + return static_cast(v); + } + + inline std::size_t hash_value(signed char v) + { + return static_cast(v); + } + + inline std::size_t hash_value(short v) + { + return static_cast(v); + } + + inline std::size_t hash_value(unsigned short v) + { + return static_cast(v); + } + + inline std::size_t hash_value(int v) + { + return static_cast(v); + } + + inline std::size_t hash_value(unsigned int v) + { + return static_cast(v); + } + + inline std::size_t hash_value(long v) + { + return static_cast(v); + } + + inline std::size_t hash_value(unsigned long v) + { + return static_cast(v); + } + +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + inline std::size_t hash_value(wchar_t v) + { + return static_cast(v); + } +#endif + +#if defined(BOOST_HAS_LONG_LONG) + inline std::size_t hash_value(long long v) + { + return hash_detail::hash_value_signed(v); + } + + inline std::size_t hash_value(unsigned long long v) + { + return hash_detail::hash_value_unsigned(v); + } +#endif + + // Implementation by Alberto Barbati and Dave Harris. +#if !BOOST_WORKAROUND(__DMC__, <= 0x848) + template std::size_t hash_value(T* const& v) +#else + template std::size_t hash_value(T* v) +#endif + { + std::size_t x = static_cast( + reinterpret_cast(v)); + + return x + (x >> 3); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + inline void hash_combine(std::size_t& seed, T& v) +#else + template + inline void hash_combine(std::size_t& seed, T const& v) +#endif + { + boost::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + + template + inline std::size_t hash_range(It first, It last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + template + inline void hash_range(std::size_t& seed, It first, It last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + template + inline std::size_t hash_range(T* first, T* last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + boost::hash hasher; + seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + + return seed; + } + + template + inline void hash_range(std::size_t& seed, T* first, T* last) + { + for(; first != last; ++first) + { + boost::hash hasher; + seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + } +#endif + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template< class T, unsigned N > + inline std::size_t hash_value(const T (&array)[N]) + { + return hash_range(array, array + N); + } + + template< class T, unsigned N > + inline std::size_t hash_value(T (&array)[N]) + { + return hash_range(array, array + N); + } +#endif + + template + inline std::size_t hash_value(std::basic_string, A> const& v) + { + return hash_range(v.begin(), v.end()); + } + + inline std::size_t hash_value(float v) + { + return boost::hash_detail::float_hash_value(v); + } + + inline std::size_t hash_value(double v) + { + return boost::hash_detail::float_hash_value(v); + } + + inline std::size_t hash_value(long double v) + { + return boost::hash_detail::float_hash_value(v); + } + + template + std::size_t hash_value(std::pair const& v) + { + std::size_t seed = 0; + hash_combine(seed, v.first); + hash_combine(seed, v.second); + return seed; + } + + template + std::size_t hash_value(std::vector const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::list const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::deque const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::set const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multiset const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::map const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multimap const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::complex const& v) + { + boost::hash hasher; + std::size_t seed = hasher(v.imag()); + seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); + return seed; + } + + // + // boost::hash + // + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) +#define BOOST_HASH_SPECIALIZE(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_REF(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; +#else +#define BOOST_HASH_SPECIALIZE(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; \ + \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(const type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_REF(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; \ + \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; +#endif + + BOOST_HASH_SPECIALIZE(bool) + BOOST_HASH_SPECIALIZE(char) + BOOST_HASH_SPECIALIZE(signed char) + BOOST_HASH_SPECIALIZE(unsigned char) +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_HASH_SPECIALIZE(wchar_t) +#endif + BOOST_HASH_SPECIALIZE(short) + BOOST_HASH_SPECIALIZE(unsigned short) + BOOST_HASH_SPECIALIZE(int) + BOOST_HASH_SPECIALIZE(unsigned int) + BOOST_HASH_SPECIALIZE(long) + BOOST_HASH_SPECIALIZE(unsigned long) + + BOOST_HASH_SPECIALIZE(float) + BOOST_HASH_SPECIALIZE(double) + BOOST_HASH_SPECIALIZE(long double) + + BOOST_HASH_SPECIALIZE_REF(std::string) +#if !defined(BOOST_NO_STD_WSTRING) + BOOST_HASH_SPECIALIZE_REF(std::wstring) +#endif + +#undef BOOST_HASH_SPECIALIZE +#undef BOOST_HASH_SPECIALIZE_REF + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct hash + : public std::unary_function + { + std::size_t operator()(T* v) const + { +#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) + return boost::hash_value(v); +#else + std::size_t x = static_cast( + reinterpret_cast(v)); + + return x + (x >> 3); +#endif + } + }; +#else + namespace hash_detail + { + template + struct hash_impl; + + template <> + struct hash_impl + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T val) const + { +#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590) + return boost::hash_value(val); +#else + std::size_t x = static_cast( + reinterpret_cast(val)); + + return x + (x >> 3); +#endif + } + }; + }; + } + + template struct hash + : public boost::hash_detail::hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; +#endif +} + +#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP +//////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_HASH_NO_EXTENSIONS) \ + && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) +#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP + +namespace boost +{ + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + namespace hash_detail + { + template + struct call_hash_impl + { + template + struct inner + { + static std::size_t call(T const& v) + { + using namespace boost; + return hash_value(v); + } + }; + }; + + template <> + struct call_hash_impl + { + template + struct inner + { +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + static std::size_t call(Array const& v) +#else + static std::size_t call(Array& v) +#endif + { + const int size = sizeof(v) / sizeof(*v); + return boost::hash_range(v, v + size); + } + }; + }; + + template + struct call_hash + : public call_hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; + } +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template struct hash + : std::unary_function + { +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + std::size_t operator()(T const& val) const + { + return hash_value(val); + } +#else + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } +#endif + }; + +#if BOOST_WORKAROUND(__DMC__, <= 0x848) + template struct hash + : std::unary_function + { + std::size_t operator()(const T* val) const + { + return boost::hash_range(val, val+n); + } + }; +#endif + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // On compilers without partial specialization, boost::hash + // has already been declared to deal with pointers, so just + // need to supply the non-pointer version. + + namespace hash_detail + { + template + struct hash_impl; + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + template <> + struct hash_impl + { + template + struct inner + : std::unary_function + { +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + std::size_t operator()(T const& val) const + { + return hash_value(val); + } +#else + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } +#endif + }; + }; + +#else // Visual C++ 6.5 + + // There's probably a more elegant way to Visual C++ 6.5 to work + // but I don't know what it is. + + template + struct hash_impl_msvc + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } + + std::size_t operator()(T& val) const + { + return hash_detail::call_hash::call(val); + } + }; + }; + + template <> + struct hash_impl_msvc + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T& val) const + { + return hash_detail::call_hash::call(val); + } + }; + }; + + template + struct hash_impl_msvc2 + : public hash_impl_msvc::value> + ::BOOST_NESTED_TEMPLATE inner {}; + + template <> + struct hash_impl + { + template + struct inner : public hash_impl_msvc2 {}; + }; + +#endif // Visual C++ 6.5 + } +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +} + +#endif + diff --git a/thirdparty/boost/functional/hash/list.hpp b/thirdparty/boost/functional/hash/list.hpp new file mode 100644 index 0000000..300ad89 --- /dev/null +++ b/thirdparty/boost/functional/hash/list.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_LIST_HPP) +#define BOOST_FUNCTIONAL_HASH_LIST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/list.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/list.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash/map.hpp b/thirdparty/boost/functional/hash/map.hpp new file mode 100644 index 0000000..c8870a6 --- /dev/null +++ b/thirdparty/boost/functional/hash/map.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_MAP_HPP) +#define BOOST_FUNCTIONAL_HASH_MAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/map.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/map.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash/pair.hpp b/thirdparty/boost/functional/hash/pair.hpp new file mode 100644 index 0000000..5ff07f0 --- /dev/null +++ b/thirdparty/boost/functional/hash/pair.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_PAIR_HPP) +#define BOOST_FUNCTIONAL_HASH_PAIR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/pair.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/pair.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash/set.hpp b/thirdparty/boost/functional/hash/set.hpp new file mode 100644 index 0000000..e2fabc0 --- /dev/null +++ b/thirdparty/boost/functional/hash/set.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_SET_HPP) +#define BOOST_FUNCTIONAL_HASH_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/set.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/set.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash/vector.hpp b/thirdparty/boost/functional/hash/vector.hpp new file mode 100644 index 0000000..f37e383 --- /dev/null +++ b/thirdparty/boost/functional/hash/vector.hpp @@ -0,0 +1,27 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_VECTOR_HPP) +#define BOOST_FUNCTIONAL_HASH_VECTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(__EDG__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) +#pragma message("Warning: boost/functional/hash/vector.hpp is deprecated, use boost/functional/hash.hpp instead.") +#elif defined(__GNUC__) || defined(__HP_aCC) || \ + defined(__SUNPRO_CC) || defined(__IBMCPP__) +#warning "boost/functional/hash/vector.hpp is deprecated, use boost/functional/hash.hpp instead." +#endif + +#include + +#endif diff --git a/thirdparty/boost/functional/hash_fwd.hpp b/thirdparty/boost/functional/hash_fwd.hpp new file mode 100644 index 0000000..93b0d32 --- /dev/null +++ b/thirdparty/boost/functional/hash_fwd.hpp @@ -0,0 +1,40 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template struct hash; + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template void hash_combine(std::size_t& seed, T& v); +#else + template void hash_combine(std::size_t& seed, T const& v); +#endif + + template std::size_t hash_range(It, It); + template void hash_range(std::size_t&, It, It); + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + template inline std::size_t hash_range(T*, T*); + template inline void hash_range(std::size_t&, T*, T*); +#endif +} + +#endif diff --git a/thirdparty/boost/fusion/adapted.hpp b/thirdparty/boost/fusion/adapted.hpp new file mode 100644 index 0000000..7a797ed --- /dev/null +++ b/thirdparty/boost/fusion/adapted.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_ADAPTED_30122005_1420) +#define BOOST_FUSION_ADAPTED_30122005_1420 + +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/adapted/array.hpp b/thirdparty/boost/fusion/adapted/array.hpp new file mode 100644 index 0000000..71bd212 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_ARRAY_27122005_1035) +#define BOOST_FUSION_ARRAY_27122005_1035 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/array_iterator.hpp b/thirdparty/boost/fusion/adapted/array/array_iterator.hpp new file mode 100644 index 0000000..2830dff --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/array_iterator.hpp @@ -0,0 +1,107 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_ARRAY_ITERATOR_26122005_2250) +#define BOOST_FUSION_ARRAY_ITERATOR_26122005_2250 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + template + struct array_iterator + : iterator_facade, random_access_traversal_tag> + { + BOOST_MPL_ASSERT_RELATION(Pos, >=, 0); + BOOST_MPL_ASSERT_RELATION(Pos, <=, Array::static_size); + + typedef mpl::int_ index; + typedef Array array_type; + + array_iterator(Array& a) + : array(a) {} + + Array& array; + + template + struct value_of + { + typedef typename Iterator::array_type array_type; + typedef typename array_type::value_type type; + }; + + template + struct deref + { + typedef typename Iterator::array_type array_type; + typedef typename + mpl::if_< + is_const + , typename array_type::const_reference + , typename array_type::reference + >::type + type; + + static type + call(Iterator const & it) + { + return it.array[Iterator::index::value]; + } + }; + + template + struct advance + { + typedef typename Iterator::index index; + typedef typename Iterator::array_type array_type; + typedef array_iterator type; + + static type + call(Iterator const& i) + { + return type(i.array); + } + }; + + template + struct next : advance > {}; + + template + struct prior : advance > {}; + + template + struct distance : mpl::minus + { + typedef typename + mpl::minus< + typename I2::index, typename I1::index + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + + private: + + array_iterator& operator=(array_iterator const&); + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/at_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/at_impl.hpp new file mode 100644 index 0000000..4b9ee23 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/at_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_AT_IMPL_27122005_1241) +#define BOOST_FUSION_AT_IMPL_27122005_1241 + +#include + +#include + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct at_impl; + + template<> + struct at_impl + { + template + struct apply + { + typedef typename mpl::if_< + is_const, + typename Sequence::const_reference, + typename Sequence::reference>::type type; + + static type + call(Sequence& seq) + { + return seq[N::value]; + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/begin_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/begin_impl.hpp new file mode 100644 index 0000000..75864e7 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/begin_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_BEGIN_IMPL_27122005_1117) +#define BOOST_FUSION_BEGIN_IMPL_27122005_1117 + +#include + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef array_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/category_of_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/category_of_impl.hpp new file mode 100644 index 0000000..d561d0d --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/category_of_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_CATEGORY_OF_IMPL_27122005_1044) +#define BOOST_FUSION_CATEGORY_OF_IMPL_27122005_1044 + +#include + +namespace boost { namespace fusion { + + struct array_tag; + struct random_access_traversal_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + { + typedef random_access_traversal_tag type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/end_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/end_impl.hpp new file mode 100644 index 0000000..ffbc0b5 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/end_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_END_IMPL_27122005_1120) +#define BOOST_FUSION_END_IMPL_27122005_1120 + +#include + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef array_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/is_sequence_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/is_sequence_impl.hpp new file mode 100644 index 0000000..12fe24f --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/is_sequence_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_SEQUENCE_IMPL_27122005_1648) +#define BOOST_FUSION_IS_SEQUENCE_IMPL_27122005_1648 + +#include + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/is_view_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/is_view_impl.hpp new file mode 100644 index 0000000..355f67f --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/is_view_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_VIEW_IMPL_27042006_2221) +#define BOOST_FUSION_IS_VIEW_IMPL_27042006_2221 + +#include + +namespace boost { namespace fusion +{ + struct array_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::false_ + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/size_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/size_impl.hpp new file mode 100644 index 0000000..81970ce --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/size_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_SIZE_IMPL_27122005_1251) +#define BOOST_FUSION_SIZE_IMPL_27122005_1251 + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct size_impl; + + template<> + struct size_impl + { + template + struct apply : mpl::int_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/detail/value_at_impl.hpp b/thirdparty/boost/fusion/adapted/array/detail/value_at_impl.hpp new file mode 100644 index 0000000..fbf74ed --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/detail/value_at_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_IMPL_27122005_1256) +#define BOOST_FUSION_VALUE_AT_IMPL_27122005_1256 + +namespace boost { namespace fusion { + + struct array_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply + { + typedef typename Sequence::value_type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/array/tag_of.hpp b/thirdparty/boost/fusion/adapted/array/tag_of.hpp new file mode 100644 index 0000000..ed3c9a3 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/array/tag_of.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_TAG_OF_27122005_1030) +#define FUSION_SEQUENCE_TAG_OF_27122005_1030 + +#include + +#include + +namespace boost +{ + template + class array; +} + +namespace boost { namespace fusion +{ + struct array_tag; + + namespace traits + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct tag_of, void > +#else + struct tag_of > +#endif + { + typedef array_tag type; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple.hpp b/thirdparty/boost/fusion/adapted/boost_tuple.hpp new file mode 100644 index 0000000..0b26fbb --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_BOOST_TUPLE_09272006_0732) +#define BOOST_FUSION_BOOST_TUPLE_09272006_0732 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp new file mode 100644 index 0000000..9f7a552 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp @@ -0,0 +1,149 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BOOST_TUPLE_ITERATOR_09262006_1851) +#define FUSION_BOOST_TUPLE_ITERATOR_09262006_1851 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct forward_traversal_tag; + + namespace detail + { + template + struct boost_tuple_is_empty : mpl::false_ {}; + + template <> + struct boost_tuple_is_empty : mpl::true_ {}; + + template <> + struct boost_tuple_is_empty : mpl::true_ {}; + + template <> + struct boost_tuple_is_empty > : mpl::true_ {}; + + template <> + struct boost_tuple_is_empty const> : mpl::true_ {}; + } + + template + struct boost_tuple_iterator + : iterator_facade, forward_traversal_tag> + { + typedef Cons cons_type; + + explicit boost_tuple_iterator(Cons& cons) + : cons(cons) {} + Cons& cons; + + template + struct value_of : mpl::identity {}; + + template + struct deref + { + typedef typename value_of::type element; + + typedef typename + mpl::if_< + is_const + , typename tuples::access_traits::const_type + , typename tuples::access_traits::non_const_type + >::type + type; + + static type + call(Iterator const& iter) + { + return iter.cons.get_head(); + } + }; + + template + struct next + { + typedef typename Iterator::cons_type cons_type; + typedef typename cons_type::tail_type tail_type; + + typedef boost_tuple_iterator< + typename mpl::eval_if< + is_const + , add_const + , mpl::identity + >::type> + type; + + static type + call(Iterator const& iter) + { + return type(iter.cons.get_tail()); + } + }; + }; + + template + struct boost_tuple_null_iterator + : iterator_facade, forward_traversal_tag> + { + typedef Null cons_type; + + template + struct equal_to + : mpl::or_< + is_same + , mpl::and_< + detail::boost_tuple_is_empty + , detail::boost_tuple_is_empty + > + > + {}; + }; + + template <> + struct boost_tuple_iterator + : boost_tuple_null_iterator + { + template + explicit boost_tuple_iterator(Cons const&) {} + }; + + template <> + struct boost_tuple_iterator + : boost_tuple_null_iterator + { + template + explicit boost_tuple_iterator(Cons const&) {} + }; + + template <> + struct boost_tuple_iterator > + : boost_tuple_null_iterator > + { + template + explicit boost_tuple_iterator(Cons const&) {} + }; + + template <> + struct boost_tuple_iterator const> + : boost_tuple_null_iterator const> + { + template + explicit boost_tuple_iterator(Cons const&) {} + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/at_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/at_impl.hpp new file mode 100644 index 0000000..3f0369a --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/at_impl.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_AT_IMPL_09262006_1920) +#define BOOST_FUSION_AT_IMPL_09262006_1920 + +#include +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + typedef typename + tuples::element::type + element; + + typedef typename + mpl::if_< + is_const + , typename tuples::access_traits::const_type + , typename tuples::access_traits::non_const_type + >::type + type; + + static type + call(Sequence& seq) + { + return tuples::get(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/begin_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/begin_impl.hpp new file mode 100644 index 0000000..4364f65 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/begin_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_BEGIN_IMPL_09272006_0719) +#define BOOST_FUSION_BEGIN_IMPL_09272006_0719 + +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef boost_tuple_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/category_of_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/category_of_impl.hpp new file mode 100644 index 0000000..663b69e --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/category_of_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_CATEGORY_OF_IMPL_09272006_0726) +#define BOOST_FUSION_CATEGORY_OF_IMPL_09272006_0726 + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + struct forward_traversal_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + { + typedef forward_traversal_tag type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/end_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/end_impl.hpp new file mode 100644 index 0000000..70ab663 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/end_impl.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_END_IMPL_09272006_0721) +#define BOOST_FUSION_END_IMPL_09272006_0721 + +#include +#include +#include + +namespace boost { namespace tuples +{ + struct null_type; +}} + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef + boost_tuple_iterator< + typename mpl::if_< + is_const + , tuples::null_type const + , tuples::null_type + >::type + > + type; + + static type + call(Sequence& seq) + { + return type(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_sequence_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_sequence_impl.hpp new file mode 100644 index 0000000..c8336b9 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_sequence_impl.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_IS_SEQUENCE_IMPL_09272006_0726) +#define BOOST_FUSION_IS_SEQUENCE_IMPL_09272006_0726 + +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_view_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_view_impl.hpp new file mode 100644 index 0000000..d5182fc --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/is_view_impl.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_IS_VIEW_IMPL_09272006_0725) +#define BOOST_FUSION_IS_VIEW_IMPL_09272006_0725 + +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::false_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/size_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/size_impl.hpp new file mode 100644 index 0000000..73aac0d --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/size_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_SIZE_IMPL_09272006_0724) +#define BOOST_FUSION_SIZE_IMPL_09272006_0724 + +#include +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply : mpl::int_::value> {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/detail/value_at_impl.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/detail/value_at_impl.hpp new file mode 100644 index 0000000..b45fbd6 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/detail/value_at_impl.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_VALUE_AT_IMPL_09262006_1926) +#define BOOST_FUSION_VALUE_AT_IMPL_09262006_1926 + +#include + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply : tuples::element {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/boost_tuple/tag_of.hpp b/thirdparty/boost/fusion/adapted/boost_tuple/tag_of.hpp new file mode 100644 index 0000000..32a7be4 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/boost_tuple/tag_of.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_TAG_OF_09262006_1900) +#define BOOST_FUSION_TAG_OF_09262006_1900 + +#include + +namespace boost { namespace tuples +{ + struct null_type; + + template < + class T0, class T1, class T2, class T3, class T4, + class T5, class T6, class T7, class T8, class T9 + > + class tuple; + + template + struct cons; +}} + +namespace boost { namespace fusion +{ + struct boost_tuple_tag; + + namespace traits + { + template < + class T0, class T1, class T2, class T3, class T4, + class T5, class T6, class T7, class T8, class T9 + > +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct tag_of, void > +#else + struct tag_of > +#endif + { + typedef boost_tuple_tag type; + }; + + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct tag_of, void > +#else + struct tag_of > +#endif + { + typedef boost_tuple_tag type; + }; + + template <> + struct tag_of + { + typedef boost_tuple_tag type; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl.hpp b/thirdparty/boost/fusion/adapted/mpl.hpp new file mode 100644 index 0000000..3f021cf --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_MPL_31122005_1152) +#define BOOST_FUSION_MPL_31122005_1152 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/at_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/at_impl.hpp new file mode 100644 index 0000000..38e7ec0 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/at_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_AT_IMPL_31122005_1642) +#define BOOST_FUSION_AT_IMPL_31122005_1642 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + typedef typename mpl::at::type type; + + static type + call(Sequence) + { + return type(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/begin_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/begin_impl.hpp new file mode 100644 index 0000000..66ca4ba --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/begin_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_BEGIN_IMPL_31122005_1209) +#define BOOST_FUSION_BEGIN_IMPL_31122005_1209 + +#include +#include +#include + +namespace boost { namespace fusion { + + struct mpl_sequence_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename mpl::begin< + typename remove_const::type + >::type iterator; + typedef mpl_iterator type; + + static type + call(Sequence) + { + return type(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/category_of_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/category_of_impl.hpp new file mode 100644 index 0000000..c3f862a --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/category_of_impl.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_CATEGORY_OF_IMPL_20060217_2141) +#define BOOST_FUSION_CATEGORY_OF_IMPL_20060217_2141 + +#include +#include +#include +#include + +namespace boost { namespace fusion { + + namespace detail + { + template + struct mpl_sequence_category_of + { + // assumes T is an mpl sequence + // there should be no way this will ever be + // called where T is an mpl iterator + + BOOST_STATIC_ASSERT(mpl::is_sequence::value); + typedef typename + mpl_iterator_category< + typename mpl::begin::type::category + >::type + type; + }; + } + + struct mpl_sequence_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + : detail::mpl_sequence_category_of + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/empty_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/empty_impl.hpp new file mode 100644 index 0000000..6d3bb0f --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/empty_impl.hpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_EMPTY_IMPL_31122005_1554) +#define BOOST_FUSION_EMPTY_IMPL_31122005_1554 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template <> + struct empty_impl + { + template + struct apply : mpl::empty {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/end_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/end_impl.hpp new file mode 100644 index 0000000..7db72a9 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/end_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_END_IMPL_31122005_1237) +#define BOOST_FUSION_END_IMPL_31122005_1237 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename mpl::end< + typename remove_const::type + >::type iterator; + typedef mpl_iterator type; + + static type + call(Sequence) + { + return type(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/has_key_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/has_key_impl.hpp new file mode 100644 index 0000000..9a03278 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/has_key_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_HAS_KEY_IMPL_31122005_1647) +#define BOOST_FUSION_HAS_KEY_IMPL_31122005_1647 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct has_key_impl; + + template <> + struct has_key_impl + { + template + struct apply : mpl::has_key {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/is_sequence_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/is_sequence_impl.hpp new file mode 100644 index 0000000..497be61 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/is_sequence_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_SEQUENCE_IMPL_31122005_1505) +#define BOOST_FUSION_IS_SEQUENCE_IMPL_31122005_1505 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/is_view_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/is_view_impl.hpp new file mode 100644 index 0000000..3b935ba --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/is_view_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_VIEW_IMPL_03202006_0048) +#define BOOST_FUSION_IS_VIEW_IMPL_03202006_0048 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::true_ + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/size_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/size_impl.hpp new file mode 100644 index 0000000..d3bfdac --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/size_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_SIZE_IMPL_31122005_1508) +#define BOOST_FUSION_SIZE_IMPL_31122005_1508 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply : mpl::size {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/detail/value_at_impl.hpp b/thirdparty/boost/fusion/adapted/mpl/detail/value_at_impl.hpp new file mode 100644 index 0000000..7368bac --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/detail/value_at_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_IMPL_31122005_1621) +#define BOOST_FUSION_VALUE_AT_IMPL_31122005_1621 + +#include + +namespace boost { namespace fusion +{ + struct mpl_sequence_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply : mpl::at {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/mpl/mpl_iterator.hpp b/thirdparty/boost/fusion/adapted/mpl/mpl_iterator.hpp new file mode 100644 index 0000000..06db99e --- /dev/null +++ b/thirdparty/boost/fusion/adapted/mpl/mpl_iterator.hpp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MPL_ITERATOR_05052005_0731) +#define FUSION_MPL_ITERATOR_05052005_0731 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + template + struct mpl_iterator + : iterator_facade< + mpl_iterator + , typename detail::mpl_iterator_category::type + > + { + typedef typename remove_const::type iterator_type; + + template + struct value_of : mpl::deref {}; + + template + struct deref + { + typedef typename mpl::deref< + typename Iterator::iterator_type>::type + type; + + static type + call(Iterator) + { + return type(); + } + }; + + template + struct next + { + typedef mpl_iterator< + typename mpl::next::type> + type; + + static type + call(Iterator) + { + return type(); + } + }; + + template + struct prior + { + typedef mpl_iterator< + typename mpl::prior::type> + type; + + static type + call(Iterator) + { + return type(); + } + }; + + template + struct advance + { + typedef mpl_iterator< + typename mpl::advance::type> + type; + + static type + call(Iterator const& i) + { + return type(); + } + }; + + template + struct distance : + mpl::distance< + typename I1::iterator_type + , typename I2::iterator_type> + { + typedef typename + mpl::distance< + typename I1::iterator_type + , typename I2::iterator_type + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/adapted/std_pair.hpp b/thirdparty/boost/fusion/adapted/std_pair.hpp new file mode 100644 index 0000000..8fa9c30 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_STD_PAIR_24122005_1744) +#define BOOST_FUSION_STD_PAIR_24122005_1744 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace traits + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct tag_of, void > +#else + struct tag_of > +#endif + { + typedef struct_tag type; + }; + } + + namespace extension + { + template + struct struct_member; + + template + struct struct_size; + + template + struct struct_member, 0> + { + typedef T1 type; + + static type& call(std::pair& pair) + { + return pair.first; + } + }; + + template + struct struct_member, 1> + { + typedef T2 type; + + static type& call(std::pair& pair) + { + return pair.second; + } + }; + + template + struct struct_size > : mpl::int_<2> + { + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/at_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/at_impl.hpp new file mode 100644 index 0000000..f6d124c --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/at_impl.hpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_AT_IMPL_24122005_1807) +#define BOOST_FUSION_AT_IMPL_24122005_1807 + +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + static int const n_value = N::value; + BOOST_STATIC_ASSERT((n_value >= 0 && n_value < 2)); + typedef typename + mpl::if_c< + (n_value == 0) + , typename Sequence::first_type + , typename Sequence::second_type + > + element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + template + static RT get(Sequence& p, mpl::int_<0>) + { + return p.first; + } + + template + static RT get(Sequence& p, mpl::int_<1>) + { + return p.second; + } + + static type + call(Sequence& p) + { + return get(p, N()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/begin_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/begin_impl.hpp new file mode 100644 index 0000000..2c42d4d --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/begin_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_BEGIN_IMPL_24122005_1752) +#define BOOST_FUSION_BEGIN_IMPL_24122005_1752 + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef std_pair_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/category_of_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/category_of_impl.hpp new file mode 100644 index 0000000..66c4589 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/category_of_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_CATEGORY_OF_IMPL_24122005_1731) +#define BOOST_FUSION_CATEGORY_OF_IMPL_24122005_1731 + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + struct random_access_traversal_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + { + typedef random_access_traversal_tag type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/end_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/end_impl.hpp new file mode 100644 index 0000000..a0f9f3d --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/end_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_END_IMPL_24122005_1755) +#define BOOST_FUSION_END_IMPL_24122005_1755 + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef std_pair_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/is_sequence_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/is_sequence_impl.hpp new file mode 100644 index 0000000..45d5bbf --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/is_sequence_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_SEQUENCE_IMPL_27122005_1651) +#define BOOST_FUSION_IS_SEQUENCE_IMPL_27122005_1651 + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/is_view_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/is_view_impl.hpp new file mode 100644 index 0000000..f171fb4 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/is_view_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_VIEW_IMPL_27042006_2219) +#define BOOST_FUSION_IS_VIEW_IMPL_27042006_2219 + +#include + +namespace boost { namespace fusion +{ + struct std_pair_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::false_ + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/size_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/size_impl.hpp new file mode 100644 index 0000000..1b8d2f9 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/size_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_SIZE_IMPL_24122005_1759) +#define BOOST_FUSION_SIZE_IMPL_24122005_1759 + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply : mpl::int_<2> {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/detail/value_at_impl.hpp b/thirdparty/boost/fusion/adapted/std_pair/detail/value_at_impl.hpp new file mode 100644 index 0000000..2a5a42a --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/detail/value_at_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_IMPL_24122005_1917) +#define BOOST_FUSION_VALUE_AT_IMPL_24122005_1917 + +#include +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply + { + static int const n_value = N::value; + BOOST_STATIC_ASSERT((n_value >= 0 && n_value < 2)); + typedef typename + mpl::if_c< + (n_value == 0) + , typename Sequence::first_type + , typename Sequence::second_type + >::type + type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/std_pair/std_pair_iterator.hpp b/thirdparty/boost/fusion/adapted/std_pair/std_pair_iterator.hpp new file mode 100644 index 0000000..6fda544 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/std_pair_iterator.hpp @@ -0,0 +1,127 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_STD_PAIR_ITERATOR_09262005_0934) +#define FUSION_STD_PAIR_ITERATOR_09262005_0934 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + template + struct std_pair_iterator + : iterator_facade, random_access_traversal_tag> + { + BOOST_MPL_ASSERT_RELATION(N_, >=, 0); + BOOST_MPL_ASSERT_RELATION(N_, <=, 2); + + typedef mpl::int_ index; + typedef Pair_ pair_type; + + std_pair_iterator(Pair_& pair) + : pair(pair) {} + Pair_& pair; + + template + struct value_of; + + template + struct value_of > + : mpl::identity {}; + + template + struct value_of > + : mpl::identity {}; + + template + struct deref; + + template + struct deref > + { + typedef typename + mpl::if_< + is_const + , typename Pair::first_type const& + , typename Pair::first_type& + >::type + type; + + static type + call(std_pair_iterator const& iter) + { + return iter.pair.first; + } + }; + + template + struct deref > + { + typedef typename + mpl::if_< + is_const + , typename Pair::second_type const& + , typename Pair::second_type& + >::type + type; + + static type + call(std_pair_iterator const& iter) + { + return iter.pair.second; + } + }; + + template + struct advance + { + typedef typename Iterator::index index; + typedef typename Iterator::pair_type pair_type; + typedef std_pair_iterator type; + + static type + call(Iterator const& iter) + { + return type(iter.pair); + } + }; + + template + struct next : advance > {}; + + template + struct prior : advance > {}; + + template + struct distance : mpl::minus + { + typedef typename + mpl::minus< + typename I2::index, typename I1::index + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/adapted/std_pair/tag_of.hpp b/thirdparty/boost/fusion/adapted/std_pair/tag_of.hpp new file mode 100644 index 0000000..d676dd0 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/std_pair/tag_of.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_TAG_OF_24122005_1722) +#define BOOST_FUSION_TAG_OF_24122005_1722 + +#include + +#include + +namespace boost { namespace fusion { + + struct std_pair_tag; + + namespace traits + { + template + struct tag_of > + { + typedef std_pair_tag type; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct.hpp b/thirdparty/boost/fusion/adapted/struct.hpp new file mode 100644 index 0000000..b662c08 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct.hpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_STRUCT_24122005_1744) +#define BOOST_FUSION_STRUCT_24122005_1744 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/adapt_assoc_struct.hpp b/thirdparty/boost/fusion/adapted/struct/adapt_assoc_struct.hpp new file mode 100644 index 0000000..7cc4677 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/adapt_assoc_struct.hpp @@ -0,0 +1,94 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_ADAPT_ASSOC_STRUCT_20070508_2207) +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_20070508_2207 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace extension { + template + struct struct_assoc_member; +}}} + + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT(name, bseq) \ + BOOST_FUSION_ADAPT_ASSOC_STRUCT_I( \ + name, BOOST_PP_CAT(BOOST_FUSION_ADAPT_ASSOC_STRUCT_X bseq, 0)) \ + /***/ + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_X(x, y, z) ((x, y, z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y(x, y, z) ((x, y, z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_X +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_X0 +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y0 + +// BOOST_FUSION_ADAPT_ASSOC_STRUCT_I generates the overarching structure and uses +// SEQ_FOR_EACH_I to generate the "linear" substructures. +// Thanks to Paul Mensonides for the PP macro help + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_I(name, seq) \ + namespace boost { namespace fusion { namespace traits \ + { \ + template <> \ + struct tag_of \ + { \ + typedef struct_tag type; \ + }; \ + }}} \ + namespace boost { namespace fusion { namespace extension \ + { \ + template <> \ + struct struct_size : mpl::int_ {}; \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_ADAPT_ASSOC_STRUCT_C, name, seq) \ + }}} \ + /***/ + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C(r, name, i, xy) \ + template <> \ + struct struct_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(3, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(3, 1, xy); \ + }; \ + }; \ + template<> \ + struct struct_assoc_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(3, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(3, 1, xy); \ + }; \ + }; + /***/ + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/adapt_struct.hpp b/thirdparty/boost/fusion/adapted/struct/adapt_struct.hpp new file mode 100644 index 0000000..aec48f4 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/adapt_struct.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_ADAPT_STRUCT_APRIL_2_2007_1158AM) +#define BOOST_FUSION_ADAPT_STRUCT_APRIL_2_2007_1158AM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_FUSION_ADAPT_STRUCT(name, bseq) \ + BOOST_FUSION_ADAPT_STRUCT_I( \ + name, BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_X bseq, 0)) \ + /***/ + +#define BOOST_FUSION_ADAPT_STRUCT_X(x, y) ((x, y)) BOOST_FUSION_ADAPT_STRUCT_Y +#define BOOST_FUSION_ADAPT_STRUCT_Y(x, y) ((x, y)) BOOST_FUSION_ADAPT_STRUCT_X +#define BOOST_FUSION_ADAPT_STRUCT_X0 +#define BOOST_FUSION_ADAPT_STRUCT_Y0 + +// BOOST_FUSION_ADAPT_STRUCT_I generates the overarching structure and uses +// SEQ_FOR_EACH_I to generate the "linear" substructures. +// Thanks to Paul Mensonides for the PP macro help + +#define BOOST_FUSION_ADAPT_STRUCT_I(name, seq) \ + namespace boost { namespace fusion { namespace traits \ + { \ + template <> \ + struct tag_of \ + { \ + typedef struct_tag type; \ + }; \ + }}} \ + namespace boost { namespace fusion { namespace extension \ + { \ + template <> \ + struct struct_size : mpl::int_ {}; \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_ADAPT_STRUCT_C, name, seq) \ + }}} \ + /***/ + +#define BOOST_FUSION_ADAPT_STRUCT_C(r, name, i, xy) \ + template <> \ + struct struct_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(2, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(2, 1, xy); \ + }; \ + }; \ + /***/ + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/at_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/at_impl.hpp new file mode 100644 index 0000000..2705d95 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/at_impl.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_AT_IMPL_24122005_1807) +#define BOOST_FUSION_AT_IMPL_24122005_1807 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct at_impl; + + template + struct struct_member; + + template + struct struct_size; + + template <> + struct at_impl + { + template + struct apply + { + static int const n_value = N::value; + BOOST_MPL_ASSERT_RELATION( + n_value, <=, extension::struct_size::value); + + typedef typename + extension::struct_member + element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& seq) + { + return extension:: + struct_member::call(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/at_key_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/at_key_impl.hpp new file mode 100644 index 0000000..b75945e --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/at_key_impl.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + Distributed under the 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_FUSION_AT_KEY_IMPL_20070508_2248) +#define BOOST_FUSION_AT_KEY_IMPL_20070508_2248 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct at_key_impl; + + template + struct struct_assoc_member; + + template <> + struct at_key_impl + { + template + struct apply + { + typedef typename + extension::struct_assoc_member + element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& seq) + { + return extension:: + struct_assoc_member::call(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/begin_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/begin_impl.hpp new file mode 100644 index 0000000..5154c2a --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/begin_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_BEGIN_IMPL_24122005_1752) +#define BOOST_FUSION_BEGIN_IMPL_24122005_1752 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef struct_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/category_of_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/category_of_impl.hpp new file mode 100644 index 0000000..0546bf9 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/category_of_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_CATEGORY_OF_IMPL_24122005_1731) +#define BOOST_FUSION_CATEGORY_OF_IMPL_24122005_1731 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + struct random_access_traversal_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + { + typedef random_access_traversal_tag type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/end_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/end_impl.hpp new file mode 100644 index 0000000..b797885 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/end_impl.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_END_IMPL_24122005_1755) +#define BOOST_FUSION_END_IMPL_24122005_1755 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct end_impl; + + template + struct struct_size; + + template <> + struct end_impl + { + template + struct apply + { + typedef + struct_iterator< + Sequence + , struct_size::value + > + type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/has_key_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/has_key_impl.hpp new file mode 100644 index 0000000..50b8127 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/has_key_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + Distributed under the 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_FUSION_HAS_KEY_IMPL_20070508_2231) +#define BOOST_FUSION_HAS_KEY_IMPL_20070508_2231 + +#include +#include + +namespace boost { namespace fusion { + + struct struct_tag; + + namespace extension + { + struct no_such_member; + + template + struct has_key_impl; + + template + struct struct_assoc_member; + + template<> + struct has_key_impl + { + template + struct apply + : mpl::not_::type> > + { + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/is_sequence_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/is_sequence_impl.hpp new file mode 100644 index 0000000..52a7d5b --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/is_sequence_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_SEQUENCE_IMPL_27122005_1651) +#define BOOST_FUSION_IS_SEQUENCE_IMPL_27122005_1651 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/is_view_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/is_view_impl.hpp new file mode 100644 index 0000000..1df129c --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/is_view_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_IS_VIEW_IMPL_27042006_2219) +#define BOOST_FUSION_IS_VIEW_IMPL_27042006_2219 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::false_ + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/size_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/size_impl.hpp new file mode 100644 index 0000000..0db7000 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/size_impl.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_SIZE_IMPL_24122005_1759) +#define BOOST_FUSION_SIZE_IMPL_24122005_1759 + +#include + +namespace boost { namespace fusion +{ + namespace extension + { + template + struct struct_size; + } + + struct struct_tag; + + namespace extension + { + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply : extension::struct_size {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/value_at_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/value_at_impl.hpp new file mode 100644 index 0000000..e7d7a9c --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/value_at_impl.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_IMPL_24122005_1917) +#define BOOST_FUSION_VALUE_AT_IMPL_24122005_1917 + +#include +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct value_at_impl; + + template + struct struct_member; + + template + struct struct_size; + + template <> + struct value_at_impl + { + template + struct apply + { + static int const n_value = N::value; + BOOST_MPL_ASSERT_RELATION( + n_value, <=, extension::struct_size::value); + + typedef typename + extension::struct_member::type + type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/detail/value_at_key_impl.hpp b/thirdparty/boost/fusion/adapted/struct/detail/value_at_key_impl.hpp new file mode 100644 index 0000000..69578a6 --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/detail/value_at_key_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_KEY_IMPL_20070508_2300) +#define BOOST_FUSION_VALUE_AT_KEY_IMPL_20070508_2300 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct value_at_key_impl; + + template + struct struct_assoc_member; + + template <> + struct value_at_key_impl + { + template + struct apply + { + typedef typename + extension::struct_assoc_member::type + type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/adapted/struct/extension.hpp b/thirdparty/boost/fusion/adapted/struct/extension.hpp new file mode 100644 index 0000000..7e7109a --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/extension.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_STRUCT_EXTENSION_APRIL_2_2007_1008AM) +#define FUSION_STRUCT_EXTENSION_APRIL_2_2007_1008AM + +#include + +namespace boost { namespace fusion { namespace extension +{ + template + struct struct_member; + + template + struct struct_size; + + template + struct struct_member + { + typedef typename + add_const::type>::type + type; + + static type& + call(Struct const& struct_) + { + return struct_member::call( + const_cast(struct_)); + } + }; + + template + struct struct_size + : struct_size + {}; + + struct no_such_member; + + template + struct struct_assoc_member + { + typedef no_such_member type; + }; + + template + struct struct_assoc_member + { + typedef typename + add_const::type>::type + type; + + static type& + call(Struct const& struct_) + { + return struct_assoc_member::call( + const_cast(struct_)); + } + }; + +}}} + +#endif + + diff --git a/thirdparty/boost/fusion/adapted/struct/struct_iterator.hpp b/thirdparty/boost/fusion/adapted/struct/struct_iterator.hpp new file mode 100644 index 0000000..472cc1f --- /dev/null +++ b/thirdparty/boost/fusion/adapted/struct/struct_iterator.hpp @@ -0,0 +1,103 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_STRUCT_ITERATOR_APRIL_2_2007_1008AM) +#define FUSION_STRUCT_ITERATOR_APRIL_2_2007_1008AM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + template + struct struct_iterator + : iterator_facade, random_access_traversal_tag> + { + BOOST_MPL_ASSERT_RELATION(N_, >=, 0); + BOOST_MPL_ASSERT_RELATION(N_, <=, extension::struct_size::value); + + typedef mpl::int_ index; + typedef Struct struct_type; + + struct_iterator(Struct& struct_) + : struct_(struct_) {} + Struct& struct_; + + template + struct value_of + : extension::struct_member + { + }; + + template + struct deref + { + typedef typename + add_reference< + typename extension::struct_member::type + >::type + type; + + static type + call(Iterator const& iter) + { + return extension::struct_member:: + call(iter.struct_); + } + }; + + template + struct advance + { + typedef typename Iterator::index index; + typedef typename Iterator::struct_type struct_type; + typedef struct_iterator type; + + static type + call(Iterator const& iter) + { + return type(iter.struct_); + } + }; + + template + struct next : advance > {}; + + template + struct prior : advance > {}; + + template + struct distance : mpl::minus + { + typedef typename + mpl::minus< + typename I2::index, typename I1::index + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/algorithm.hpp b/thirdparty/boost/fusion/algorithm.hpp new file mode 100644 index 0000000..3beb66e --- /dev/null +++ b/thirdparty/boost/fusion/algorithm.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ALGORITHM_10022005_0549) +#define FUSION_ALGORITHM_10022005_0549 + +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/algorithm/iteration.hpp b/thirdparty/boost/fusion/algorithm/iteration.hpp new file mode 100644 index 0000000..db2400b --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ALGORITHM_ITERATION_10022005_0549) +#define FUSION_ALGORITHM_ITERATION_10022005_0549 + +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/algorithm/iteration/accumulate.hpp b/thirdparty/boost/fusion/algorithm/iteration/accumulate.hpp new file mode 100644 index 0000000..2cc3810 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/accumulate.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ACCUMULATE_09172005_1032) +#define FUSION_ACCUMULATE_09172005_1032 + +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template + struct accumulate + : result_of::fold + {}; + } + + template + inline typename result_of::accumulate::type + accumulate(Sequence& seq, State const& state, F f) + { + return fusion::fold(seq, state, f); + } + + template + inline typename result_of::accumulate::type + accumulate(Sequence const& seq, State const& state, F f) + { + return fusion::fold(seq, state, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/iteration/detail/fold.hpp b/thirdparty/boost/fusion/algorithm/iteration/detail/fold.hpp new file mode 100644 index 0000000..0b8c238 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/detail/fold.hpp @@ -0,0 +1,278 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the 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_FUSION_FOLD_HPP_20070528_1253) +#define BOOST_FUSION_FOLD_HPP_20070528_1253 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { namespace fusion { +namespace result_of +{ + template + struct fold; +} +namespace detail +{ + template + struct apply_fold_result + { + template + struct apply + : boost::result_of + {}; + }; + + template + struct fold_apply + { + typedef typename result_of::deref::type dereferenced; + typedef typename add_reference::type>::type lvalue_state; + typedef typename boost::result_of::type type; + }; + + template + struct static_fold; + + template + struct next_result_of_fold + { + typedef typename + static_fold< + typename result_of::next::type + , Last + , typename fold_apply::type + , F + >::type + type; + }; + + template + struct static_fold + { + typedef typename + mpl::if_< + result_of::equal_to + , mpl::identity + , next_result_of_fold + >::type + result; + + typedef typename result::type type; + }; + + template + struct result_of_unrolled_fold; + + template + struct unrolled_fold + { + template + static typename result_of_unrolled_fold::type + call(I0 const& i0, State const& state, F f) + { + typedef typename result_of::next::type I1; + I1 i1 = fusion::next(i0); + typedef typename result_of::next::type I2; + I2 i2 = fusion::next(i1); + typedef typename result_of::next::type I3; + I3 i3 = fusion::next(i2); + typedef typename result_of::next::type I4; + I4 i4 = fusion::next(i3); + + return unrolled_fold::call(i4, f(*i3, f(*i2, f(*i1, f(*i0, state)))), f); + } + }; + + template<> + struct unrolled_fold<3> + { + template + static typename result_of_unrolled_fold::type + call(I0 const& i0, State const& state, F f) + { + typedef typename result_of::next::type I1; + I1 i1 = fusion::next(i0); + typedef typename result_of::next::type I2; + I2 i2 = fusion::next(i1); + return f(*i2, f(*i1, f(*i0, state))); + } + }; + + template<> + struct unrolled_fold<2> + { + template + static typename result_of_unrolled_fold::type + call(I0 const& i0, State const& state, F f) + { + typedef typename result_of::next::type I1; + I1 i1 = fusion::next(i0); + return f(*i1, f(*i0, state)); + } + }; + + template<> + struct unrolled_fold<1> + { + template + static typename result_of_unrolled_fold::type + call(I0 const& i0, State const& state, F f) + { + return f(*i0, state); + } + }; + + template<> + struct unrolled_fold<0> + { + template + static State call(I0 const&, State const& state, F) + { + return state; + } + }; + + // terminal case + template + inline State const& + linear_fold(First const&, Last const&, State const& state, F, mpl::true_) + { + return state; + } + + // non-terminal case + template + inline typename static_fold::type + linear_fold( + First const& first + , Last const& last + , State const& state + , F f + , mpl::false_) + { + return detail::linear_fold( + fusion::next(first) + , last + , f(*first, state) + , f + , result_of::equal_to::type, Last>() + ); + } + + template + struct result_of_unrolled_fold + { + typedef typename result_of::next::type I1; + typedef typename result_of::next::type I2; + typedef typename result_of::next::type I3; + typedef typename result_of::next::type I4; + typedef typename fold_apply::type Rest1; + typedef typename fold_apply::type Rest2; + typedef typename fold_apply::type Rest3; + typedef typename fold_apply::type Rest4; + + typedef typename result_of_unrolled_fold::type type; + }; + + template + struct result_of_unrolled_fold + { + typedef typename result_of::next::type I1; + typedef typename result_of::next::type I2; + typedef typename fold_apply::type Rest; + typedef typename fold_apply::type Rest2; + typedef typename fold_apply::type type; + }; + + template + struct result_of_unrolled_fold + { + typedef typename result_of::next::type I1; + typedef typename fold_apply::type Rest; + typedef typename fold_apply::type type; + }; + + template + struct result_of_unrolled_fold + { + typedef typename fold_apply::type type; + }; + + template + struct result_of_unrolled_fold + { + typedef State type; + }; + + template + struct choose_fold; + + template + struct choose_fold + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + typedef typename result_of_unrolled_fold< + begin, State, F, result_of::distance::type::value>::type type; + }; + + template + struct choose_fold + { + typedef typename + detail::static_fold< + typename result_of::begin::type + , typename result_of::end::type + , State + , F + >::type + type; + }; + + template + typename result_of::fold::type + fold(Sequence& seq, State const& state, F f, Tag) + { + return linear_fold( + fusion::begin(seq) + , fusion::end(seq) + , state + , f + , result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type>() + ); + } + + template + typename result_of::fold::type + fold(Sequence& seq, State const& state, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return unrolled_fold::type::value>::call( + fusion::begin(seq) + , state + , f); + } +}}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/iteration/detail/for_each.hpp b/thirdparty/boost/fusion/algorithm/iteration/detail/for_each.hpp new file mode 100644 index 0000000..c48c937 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/detail/for_each.hpp @@ -0,0 +1,130 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FOR_EACH_05052005_1028) +#define FUSION_FOR_EACH_05052005_1028 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { +namespace detail +{ + template + inline void + for_each_linear(First const&, Last const&, F const&, mpl::true_) + { + } + + template + inline void + for_each_linear(First const& first, Last const& last, F const& f, mpl::false_) + { + f(*first); + detail::for_each_linear(fusion::next(first), last, f, + result_of::equal_to::type, Last>()); + } + + + template + inline void + for_each(Sequence& seq, F const& f, Tag) + { + detail::for_each_linear( + fusion::begin(seq) + , fusion::end(seq) + , f + , result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type>()); + } + + template + struct for_each_unrolled + { + template + static void call(I0 const& i0, F const& f) + { + f(*i0); + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + f(*i1); + typedef typename result_of::next::type I2; + I2 i2(fusion::next(i1)); + f(*i2); + typedef typename result_of::next::type I3; + I3 i3(fusion::next(i2)); + f(*i3); + for_each_unrolled::call(fusion::next(i3), f); + } + }; + + template<> + struct for_each_unrolled<3> + { + template + static void call(I0 const& i0, F const& f) + { + f(*i0); + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + f(*i1); + typedef typename result_of::next::type I2; + I2 i2(fusion::next(i1)); + f(*i2); + } + }; + + template<> + struct for_each_unrolled<2> + { + template + static void call(I0 const& i0, F const& f) + { + f(*i0); + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + f(*i1); + } + }; + + template<> + struct for_each_unrolled<1> + { + template + static void call(I0 const& i0, F const& f) + { + f(*i0); + } + }; + + template<> + struct for_each_unrolled<0> + { + template + static void call(It const&, F const&) + { + } + }; + + template + inline void + for_each(Sequence& seq, F const& f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + for_each_unrolled::type::value>::call(fusion::begin(seq), f); + } +}}} + + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp b/thirdparty/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp new file mode 100644 index 0000000..e1174c8 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp @@ -0,0 +1,91 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FOR_EACH_S_05022006_1027) +#define FUSION_FOR_EACH_S_05022006_1027 + +#include +#include +#include +#include +#include + +// fwd declarations +namespace boost { namespace fusion +{ + template + void + for_each_s(Sequence& seq, F const& f); + + template + void + for_each_s(Sequence const& seq, F const& f); +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct for_each_s_bind + { + explicit for_each_s_bind(F const &f) + : f_(f) + {} + + template + void operator ()(Sequence &seq) const + { + fusion::for_each_s(seq, this->f_); + } + + template + void operator ()(Sequence const &seq) const + { + fusion::for_each_s(seq, this->f_); + } + private: + F const &f_; + }; + + template + void for_each_s(Sequence &seq, F const &f, mpl::true_) + { + fusion::for_each_s(fusion::segments(seq), for_each_s_bind(f)); + } + + template + void for_each_s(Sequence &seq, F const &f, mpl::false_) + { + fusion::for_each(seq, f); + } +}}} + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct for_each_s + { + typedef void type; + }; + } + + template + inline void + for_each_s(Sequence& seq, F const& f) + { + detail::for_each_s(seq, f, traits::is_segmented()); + } + + template + inline void + for_each_s(Sequence const& seq, F const& f) + { + detail::for_each_s(seq, f, traits::is_segmented()); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/iteration/fold.hpp b/thirdparty/boost/fusion/algorithm/iteration/fold.hpp new file mode 100644 index 0000000..497e89f --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/fold.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_FOLD_05052005_1214) +#define BOOST_FUSION_FOLD_05052005_1214 + +#include +#include +#include + +#include +#include + +namespace boost { namespace fusion { + + struct random_access_traversal_tag; + + namespace result_of + { + template + struct fold + : fusion::detail::choose_fold< + Sequence, State, F + , is_base_of::type>::value> + {}; + } + + template + inline typename result_of::fold::type + fold(Sequence& seq, State const& state, F f) + { + return detail::fold(seq, state, f, typename traits::category_of::type()); + } + + template + inline typename result_of::fold::type + fold(Sequence const& seq, State const& state, F f) + { + return detail::fold(seq, state, f, typename traits::category_of::type()); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/iteration/for_each.hpp b/thirdparty/boost/fusion/algorithm/iteration/for_each.hpp new file mode 100644 index 0000000..e7b5165 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/iteration/for_each.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_FOR_EACH_20070527_0943) +#define BOOST_FUSION_FOR_EACH_20070527_0943 + +#include + +#include + +namespace boost { namespace fusion { + + namespace result_of + { + template + struct for_each + { + typedef void type; + }; + } + + struct random_access_traversal_tag; + + template + inline void + for_each(Sequence& seq, F const& f) + { + detail::for_each(seq, f, typename traits::category_of::type()); + } + + template + inline void + for_each(Sequence const& seq, F const& f) + { + detail::for_each(seq, f, typename traits::category_of::type()); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/query.hpp b/thirdparty/boost/fusion/algorithm/query.hpp new file mode 100644 index 0000000..2536c08 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ALGORITHM_QUERY_10022005_0549) +#define FUSION_ALGORITHM_QUERY_10022005_0549 + +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/algorithm/query/all.hpp b/thirdparty/boost/fusion/algorithm/query/all.hpp new file mode 100644 index 0000000..82739e9 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/all.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_ALL_05052005_1238) +#define BOOST_FUSION_ALL_05052005_1238 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct all + { + typedef bool type; + }; + } + + template + inline bool + all(Sequence const& seq, F f) + { + return detail::all(seq, f, typename traits::category_of::type()); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/any.hpp b/thirdparty/boost/fusion/algorithm/query/any.hpp new file mode 100644 index 0000000..f72a6d0 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/any.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005 Eric Niebler + Copyright (c) 2007 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ANY_05052005_1230) +#define FUSION_ANY_05052005_1230 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct any + { + typedef bool type; + }; + } + + template + inline bool + any(Sequence const& seq, F f) + { + return detail::any(seq, f, typename traits::category_of::type()); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/count.hpp b/thirdparty/boost/fusion/algorithm/query/count.hpp new file mode 100644 index 0000000..d61a495 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/count.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 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) +==============================================================================*/ +#if !defined(BOOST_FUSION_COUNT_09162005_0150) +#define BOOST_FUSION_COUNT_09162005_0150 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct count + { + typedef int type; + }; + } + + template + inline int + count(Sequence const& seq, T const& x) + { + detail::count_compare f(x); + return fusion::count_if(seq, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/count_if.hpp b/thirdparty/boost/fusion/algorithm/query/count_if.hpp new file mode 100644 index 0000000..9889e97 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/count_if.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_COUNT_IF_09162005_0137) +#define BOOST_FUSION_COUNT_IF_09162005_0137 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct count_if + { + typedef int type; + }; + } + + template + inline int + count_if(Sequence const& seq, F f) + { + return detail::count_if( + seq, f, typename traits::category_of::type()); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/detail/all.hpp b/thirdparty/boost/fusion/algorithm/query/detail/all.hpp new file mode 100644 index 0000000..9d4cef8 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/all.hpp @@ -0,0 +1,127 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ALL_05052005_1237) +#define FUSION_ALL_05052005_1237 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + inline bool + linear_all(First const&, Last const&, F const&, mpl::true_) + { + return true; + } + + template + inline bool + linear_all(First const& first, Last const& last, F& f, mpl::false_) + { + typename result_of::deref::type x = *first; + return f(x) && + detail::linear_all( + fusion::next(first) + , last + , f + , result_of::equal_to::type, Last>()); + } + + template + inline bool + all(Sequence const& seq, F f, Tag) + { + return detail::linear_all( + fusion::begin(seq) + , fusion::end(seq) + , f + , result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type>()); + } + + template + struct unrolled_all + { + template + static bool call(It const& it, F f) + { + return + f(*it) && + f(*fusion::advance_c<1>(it))&& + f(*fusion::advance_c<2>(it)) && + f(*fusion::advance_c<3>(it)) && + detail::unrolled_all::call(fusion::advance_c<4>(it), f); + } + }; + + template<> + struct unrolled_all<3> + { + template + static bool call(It const& it, F f) + { + return + f(*it) && + f(*fusion::advance_c<1>(it)) && + f(*fusion::advance_c<2>(it)); + } + }; + + template<> + struct unrolled_all<2> + { + template + static bool call(It const& it, F f) + { + return + f(*it) && + f(*fusion::advance_c<1>(it)); + } + }; + + template<> + struct unrolled_all<1> + { + template + static bool call(It const& it, F f) + { + return f(*it); + } + }; + + template<> + struct unrolled_all<0> + { + template + static bool call(It const& it, F f) + { + return false; + } + }; + + template + inline bool + all(Sequence const& seq, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return detail::unrolled_all::type::value>::call( + fusion::begin(seq), f); + } +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/detail/any.hpp b/thirdparty/boost/fusion/algorithm/query/detail/any.hpp new file mode 100644 index 0000000..aedac55 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/any.hpp @@ -0,0 +1,130 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005 Eric Niebler + Copyright (c) 2007 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ANY_05052005_1229) +#define FUSION_ANY_05052005_1229 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + struct random_access_traversal_tag; +namespace detail +{ + template + inline bool + linear_any(First const&, Last const&, F const&, mpl::true_) + { + return false; + } + + template + inline bool + linear_any(First const& first, Last const& last, F& f, mpl::false_) + { + typename result_of::deref::type x = *first; + return f(x) || + detail::linear_any( + fusion::next(first) + , last + , f + , result_of::equal_to::type, Last>()); + } + + template + inline bool + any(Sequence const& seq, F f, Tag) + { + return detail::linear_any( + fusion::begin(seq) + , fusion::end(seq) + , f + , result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type>()); + } + + template + struct unrolled_any + { + template + static bool call(It const& it, F f) + { + return + f(*it) || + f(*fusion::advance_c<1>(it))|| + f(*fusion::advance_c<2>(it)) || + f(*fusion::advance_c<3>(it)) || + detail::unrolled_any::call(fusion::advance_c<4>(it), f); + } + }; + + template<> + struct unrolled_any<3> + { + template + static bool call(It const& it, F f) + { + return + f(*it) || + f(*fusion::advance_c<1>(it)) || + f(*fusion::advance_c<2>(it)); + } + }; + + template<> + struct unrolled_any<2> + { + template + static bool call(It const& it, F f) + { + return + f(*it) || + f(*fusion::advance_c<1>(it)); + } + }; + + template<> + struct unrolled_any<1> + { + template + static bool call(It const& it, F f) + { + return f(*it); + } + }; + + template<> + struct unrolled_any<0> + { + template + static bool call(It const& it, F f) + { + return false; + } + }; + + template + inline bool + any(Sequence const& seq, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return detail::unrolled_any::type::value>::call( + fusion::begin(seq), f); + } +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/detail/assoc_find.hpp b/thirdparty/boost/fusion/algorithm/query/detail/assoc_find.hpp new file mode 100644 index 0000000..eebb9a0 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/assoc_find.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ASSOC_FIND_09242005_1133) +#define FUSION_ASSOC_FIND_09242005_1133 + +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct assoc_find + { + typedef typename + mpl::if_< + is_const + , typename Sequence::template meta_find_impl_const::type + , typename Sequence::template meta_find_impl::type + >::type + type; + + static type + call(Sequence& s) + { + return s.find_impl(mpl::identity()); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/query/detail/count.hpp b/thirdparty/boost/fusion/algorithm/query/detail/count.hpp new file mode 100644 index 0000000..0140a02 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/count.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_COUNT_09162005_0158) +#define FUSION_COUNT_09162005_0158 + +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct compare_convertible; + + // T1 is convertible to T2 or vice versa + template <> + struct compare_convertible + { + template + static bool + call(T1 const& x, T2 const& y) + { + return x == y; + } + }; + + // T1 is NOT convertible to T2 NOR vice versa + template <> + struct compare_convertible + { + template + static bool + call(T1 const&, T2 const&) + { + return false; + } + }; + + template + struct count_compare + { + typedef typename detail::call_param::type param; + count_compare(param x) + : x(x) {} + + template + bool + operator()(T2 const& y) + { + return + compare_convertible< + mpl::or_< + is_convertible + , is_convertible + >::value + >::call(x, y); + } + + param x; + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/detail/count_if.hpp b/thirdparty/boost/fusion/algorithm/query/detail/count_if.hpp new file mode 100644 index 0000000..91b56fc --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/count_if.hpp @@ -0,0 +1,170 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_COUNT_IF_09162005_0141) +#define BOOST_FUSION_COUNT_IF_09162005_0141 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + struct random_access_traversal_tag; +namespace detail +{ + template + inline int + linear_count_if(First const&, Last const&, F const&, mpl::true_) + { + return 0; + } + + template + inline int + linear_count_if(First const& first, Last const& last, F& f, mpl::false_) + { + int n = + detail::linear_count_if( + fusion::next(first) + , last + , f + , result_of::equal_to::type, Last>()); + if (f(*first)) + ++n; + return n; + } + + template + inline int + count_if(Sequence const& seq, F f, Tag) + { + return detail::linear_count_if( + fusion::begin(seq) + , fusion::end(seq) + , f + , result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type>()); + } + + template + struct unrolled_count_if + { + template + static int call(I0 const& i0, F f) + { + int ct = unrolled_count_if:: + call(fusion::advance_c<4>(i0), f); + if(f(*i0)) + ++ct; + + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + if(f(*i1)) + ++ct; + + typedef typename result_of::next::type I2; + I2 i2(fusion::next(i1)); + if(f(*i2)) + ++ct; + + typedef typename result_of::next::type I3; + I3 i3(fusion::next(i2)); + if(f(*i3)) + ++ct; + + return ct; + } + }; + + template<> + struct unrolled_count_if<3> + { + template + static int call(I0 const& i0, F f) + { + int ct = 0; + if(f(*i0)) + ++ct; + + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + if(f(*i1)) + ++ct; + + typedef typename result_of::next::type I2; + I2 i2(fusion::next(i1)); + if(f(*i2)) + ++ct; + + return ct; + } + }; + + template<> + struct unrolled_count_if<2> + { + template + static int call(I0 const& i0, F f) + { + int ct = 0; + + if(f(*i0)) + ++ct; + + typedef typename result_of::next::type I1; + I1 i1(fusion::next(i0)); + if(f(*i1)) + ++ct; + + return ct; + } + }; + + template<> + struct unrolled_count_if<1> + { + template + static int call(I0 const& i0, F f) + { + int ct = 0; + if(f(*i0)) + ++ct; + return ct; + } + }; + + + template<> + struct unrolled_count_if<0> + { + template + static int call(I0 const&, F) + { + return 0; + } + }; + + template + inline int + count_if(Sequence const& seq, F f, random_access_traversal_tag) + { + typedef typename result_of::begin::type begin; + typedef typename result_of::end::type end; + return detail::unrolled_count_if::type::value>:: + call(fusion::begin(seq), f); + } +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/detail/find_if.hpp b/thirdparty/boost/fusion/algorithm/query/detail/find_if.hpp new file mode 100644 index 0000000..b25dec3 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/detail/find_if.hpp @@ -0,0 +1,252 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FIND_IF_05052005_1107) +#define FUSION_FIND_IF_05052005_1107 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + struct random_access_traversal_tag; +namespace detail +{ + template + struct apply_filter + { + typedef typename mpl::apply1< + Pred, typename result_of::value_of::type>::type type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + + template + struct main_find_if; + + template + struct recursive_find_if + { + typedef typename + main_find_if< + typename result_of::next::type, Last, Pred + >::type + type; + }; + + template + struct main_find_if + { + typedef mpl::or_< + result_of::equal_to + , apply_filter > + filter; + + typedef typename + mpl::eval_if< + filter + , mpl::identity + , recursive_find_if + >::type + type; + }; + + template< + typename First, typename Last, + typename Pred, bool> + struct choose_find_if; + + template + struct choose_find_if + : main_find_if + {}; + + template + struct unroll_again; + + template + struct apply_offset_filter + { + typedef typename result_of::advance_c::type Shifted; + typedef typename + mpl::apply1< + Pred + , typename result_of::value_of::type + >::type + type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + + template + struct unrolled_find_if + { + typedef typename mpl::eval_if< + apply_filter, + mpl::identity, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + unroll_again< + Iter, + Pred, + n, + 4> > > > >::type type; + }; + + template + struct unrolled_find_if + { + typedef typename mpl::eval_if< + apply_filter, + mpl::identity, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + result_of::advance_c > > >::type type; + }; + + template + struct unrolled_find_if + { + typedef typename mpl::eval_if< + apply_filter, + mpl::identity, + mpl::eval_if< + apply_offset_filter, + result_of::advance_c, + result_of::advance_c > >::type type; + }; + + template + struct unrolled_find_if + { + typedef typename mpl::eval_if< + apply_filter, + mpl::identity, + result_of::advance_c >::type type; + }; + + template + struct unroll_again + { + typedef typename unrolled_find_if< + typename result_of::advance_c::type, + Pred, + n-unrolling>::type type; + }; + + template + struct unrolled_find_if + { + typedef Iter type; + }; + + template + struct choose_find_if + { + typedef typename result_of::distance::type N; + typedef typename unrolled_find_if::type type; + }; + + template + struct static_find_if + { + typedef typename + choose_find_if< + First + , Last + , typename mpl::lambda::type + , is_base_of::type>::value + >::type + type; + + template + static type + recursive_call(Iterator const& iter, mpl::true_) + { + return iter; + } + + template + static type + recursive_call(Iterator const& iter, mpl::false_) + { + return recursive_call(fusion::next(iter)); + } + + template + static type + recursive_call(Iterator const& iter) + { + typedef result_of::equal_to found; + return recursive_call(iter, found()); + } + + template + static type + choose_call(Iterator const& iter, Tag) + { + return recursive_call(iter); + } + + template + static type + choose_call(Iterator const& iter, random_access_traversal_tag) + { + typedef typename result_of::distance::type N; + return fusion::advance(iter); + } + + template + static type + call(Iterator const& iter) + { + return choose_call(iter, typename traits::category_of::type()); + } + }; + + template + struct static_seq_find_if : static_find_if + { + typedef typename static_find_if::type type; + + template + static type + call(Sequence const& seq) + { + return static_find_if::call(fusion::begin(seq)); + } + + template + static type + call(Sequence& seq) + { + return static_find_if::call(fusion::begin(seq)); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/query/ext_/find_if_s.hpp b/thirdparty/boost/fusion/algorithm/query/ext_/find_if_s.hpp new file mode 100644 index 0000000..e84db95 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/ext_/find_if_s.hpp @@ -0,0 +1,222 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Distributed under the 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(FIND_IF_S_05152006_1027) +#define FIND_IF_S_05152006_1027 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fwd declarations +namespace boost { namespace fusion +{ + namespace detail + { + template::value> + struct static_find_if_s_recurse; + } + + namespace result_of + { + template + struct find_if_s; + } +}} + +namespace boost { namespace fusion { namespace detail +{ + + template::value> + struct is_found + : mpl::not_::type> > + {}; + + template + struct is_found + : mpl::not_ > + {}; + + template< + typename SegmentedRange + , typename Where + , typename Sequence = typename remove_reference< + typename result_of::deref< + typename SegmentedRange::iterator_type + >::type + >::type + , bool IsSegmented = traits::is_segmented::value + > + struct as_segmented_cons + { + typedef cons< + SegmentedRange + , cons > + > type; + + static type call(SegmentedRange const &range, Where const &where) + { + return fusion::make_cons( + range + , fusion::make_cons( + segmented_range(*fusion::begin(range), where) + ) + ); + } + }; + + template< + typename SegmentedRange + , typename Where + , typename Sequence + > + struct as_segmented_cons + { + typedef cons type; + + static type call(SegmentedRange const &range, Where const &where) + { + return fusion::make_cons(range, where); + } + }; + + template< + typename SegmentedRange + , typename Pred + , bool IsEmpty = is_empty::value + > + struct static_find_if_s_seg + { + typedef typename SegmentedRange::iterator_type first; + typedef typename result_of::deref::type segment_ref; + typedef typename remove_reference::type segment; + typedef static_find_if_s_recurse where; + typedef range_next next; + typedef is_found is_found; + typedef as_segmented_cons found; + typedef static_find_if_s_seg not_found; + typedef typename mpl::eval_if::type type; + + static type call(SegmentedRange const &range) + { + return call_(range, is_found()); + } + + private: + static type call_(SegmentedRange const &range, mpl::true_) + { + return found::call(range, where::call(*range.where_)); + } + + static type call_(SegmentedRange const &range, mpl::false_) + { + return not_found::call(next::call(range)); + } + }; + + template< + typename SegmentedRange + , typename Pred + > + struct static_find_if_s_seg + { + typedef nil type; + + static type call(SegmentedRange const &) + { + return nil(); + } + }; + + template + struct static_find_if_s_recurse + { + typedef typename as_segmented_range::type range; + typedef static_find_if_s_seg find_if; + typedef typename find_if::type type; + + static type call(Sequence &seq) + { + return find_if::call(range(fusion::segments(seq))); + } + }; + + template + struct static_find_if_s_recurse + { + typedef typename result_of::find_if::type type; + + static type call(Sequence &seq) + { + return fusion::find_if(seq); + } + }; + + template::value> + struct static_find_if_s + : static_find_if_s_recurse + {}; + + template + struct static_find_if_s + { + typedef typename as_segmented_range::type range; + typedef static_find_if_s_recurse find_if; + typedef typename find_if::type found; + + typedef segmented_iterator::type> type; + + static type call(Sequence &seq) + { + return type(reverse_cons::call(find_if::call(seq))); + } + }; +}}} + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct find_if_s + { + typedef typename + detail::static_find_if_s< + Sequence + , Pred + >::type + type; + }; + } + + template + typename lazy_disable_if< + is_const + , result_of::find_if_s + >::type + find_if_s(Sequence& seq) + { + return detail::static_find_if_s::call(seq); + } + + template + typename result_of::find_if_s::type + find_if_s(Sequence const& seq) + { + return detail::static_find_if_s::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/query/find.hpp b/thirdparty/boost/fusion/algorithm/query/find.hpp new file mode 100644 index 0000000..74be310 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/find.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FIND_05052005_1107) +#define FUSION_FIND_05052005_1107 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct associative_sequence_tag; + + namespace result_of + { + template < + typename Sequence + , typename T + , bool is_associative_sequence = traits::is_associative::value > + struct find; + + template + struct find + { + typedef + detail::static_seq_find_if< + typename result_of::begin::type + , typename result_of::end::type + , is_same + > + filter; + + typedef typename filter::type type; + }; + + template + struct find + { + typedef detail::assoc_find filter; + typedef typename filter::type type; + }; + } + + template + inline typename + lazy_disable_if< + is_const + , result_of::find + >::type const + find(Sequence& seq) + { + typedef typename result_of::find::filter filter; + return filter::call(seq); + } + + template + inline typename result_of::find::type const + find(Sequence const& seq) + { + typedef typename result_of::find::filter filter; + return filter::call(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/find_if.hpp b/thirdparty/boost/fusion/algorithm/query/find_if.hpp new file mode 100644 index 0000000..90d0b7f --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/find_if.hpp @@ -0,0 +1,69 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FIND_IF_05052005_1108) +#define FUSION_FIND_IF_05052005_1108 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct find_if + { + typedef typename + detail::static_find_if< + typename result_of::begin::type + , typename result_of::end::type + , Pred + >::type + type; + }; + } + + template + inline typename + lazy_disable_if< + is_const + , result_of::find_if + >::type + find_if(Sequence& seq) + { + typedef + detail::static_find_if< + typename result_of::begin::type + , typename result_of::end::type + , Pred + > + filter; + + return filter::call(fusion::begin(seq)); + } + + template + inline typename result_of::find_if::type const + find_if(Sequence const& seq) + { + typedef + detail::static_find_if< + typename result_of::begin::type + , typename result_of::end::type + , Pred + > + filter; + + return filter::call(fusion::begin(seq)); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/query/none.hpp b/thirdparty/boost/fusion/algorithm/query/none.hpp new file mode 100644 index 0000000..fcf663a --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/query/none.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_NONE_07062005_1128) +#define BOOST_FUSION_NONE_07062005_1128 + +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct none + { + typedef bool type; + }; + } + + template + inline bool + none(Sequence const& seq, F f) + { + return !fusion::any(seq, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation.hpp b/thirdparty/boost/fusion/algorithm/transformation.hpp new file mode 100644 index 0000000..f0b2c61 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation.hpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ALGORITHM_TRANSFORMATION_10022005_0551) +#define FUSION_ALGORITHM_TRANSFORMATION_10022005_0551 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/algorithm/transformation/clear.hpp b/thirdparty/boost/fusion/algorithm/transformation/clear.hpp new file mode 100644 index 0000000..4fae37c --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/clear.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CLEAR_09172005_1127) +#define FUSION_CLEAR_09172005_1127 + +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct clear + { + typedef vector0 type; + }; + } + + template + inline typename result_of::clear::type + clear(Sequence const& seq) + { + return vector0(); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/detail/replace.hpp b/thirdparty/boost/fusion/algorithm/transformation/detail/replace.hpp new file mode 100644 index 0000000..ab73075 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/detail/replace.hpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REPLACE_08182005_0841) +#define FUSION_REPLACE_08182005_0841 + +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct replacer_helper; + + template <> + struct replacer_helper + { + template + static U& + call(U& x, T const&, T const&) + { + return x; + } + }; + + template <> + struct replacer_helper + { + template + static U + call(U& x, T const& old_value, T const& new_value) + { + return (x == old_value) ? new_value : x; + } + }; + + template + struct replacer + { + replacer(T const& old_value, T const& new_value) + : old_value(old_value), new_value(new_value) {} + + template + struct result; + + template + struct result(U2)> + { + typedef typename remove_reference::type value; + typedef typename + mpl::if_, value, value const&>::type + type; + }; + + template + typename result::type + operator()(U const& x) const + { + return replacer_helper::value>:: + call(x, old_value, new_value); + } + + T old_value; + T new_value; + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/detail/replace_if.hpp b/thirdparty/boost/fusion/algorithm/transformation/detail/replace_if.hpp new file mode 100644 index 0000000..d4f6f7d --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/detail/replace_if.hpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REPLACE_IF_08182005_0946) +#define FUSION_REPLACE_IF_08182005_0946 + +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct replacer_if_helper; + + template <> + struct replacer_if_helper + { + template + static U& + call(U& x, F&, T const&) + { + return x; + } + }; + + template <> + struct replacer_if_helper + { + template + static U + call(U& x, F& f, T const& new_value) + { + return f(x) ? new_value : x; + } + }; + + template + struct replacer_if + { + replacer_if(F f, T const& new_value) + : f(f), new_value(new_value) {} + + template + struct result; + + template + struct result(U)> + { + typedef typename remove_reference::type value; + typedef typename + mpl::if_, value, value const&>::type + type; + }; + + template + typename result::type + operator()(U const& x) const + { + return replacer_if_helper::value>:: + call(x, f, new_value); + } + + F f; + T new_value; + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/erase.hpp b/thirdparty/boost/fusion/algorithm/transformation/erase.hpp new file mode 100644 index 0000000..9806ac7 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/erase.hpp @@ -0,0 +1,108 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ERASE_07232005_0534) +#define FUSION_ERASE_07232005_0534 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct compute_erase_last // put this in detail!!! + { + typedef typename result_of::end::type seq_last_type; + typedef typename convert_iterator::type first_type; + typedef typename + mpl::if_< + result_of::equal_to + , first_type + , typename result_of::next::type + >::type + type; + + static type + call(First const& first, mpl::false_) + { + return fusion::next(convert_iterator::call(first)); + } + + static type + call(First const& first, mpl::true_) + { + return convert_iterator::call(first); + } + + static type + call(First const& first) + { + return call(first, result_of::equal_to()); + } + }; + + template < + typename Sequence + , typename First + , typename Last = typename compute_erase_last::type> + struct erase + { + typedef typename result_of::begin::type seq_first_type; + typedef typename result_of::end::type seq_last_type; + BOOST_STATIC_ASSERT((!result_of::equal_to::value)); + + typedef typename convert_iterator::type first_type; + typedef typename convert_iterator::type last_type; + typedef iterator_range left_type; + typedef iterator_range right_type; + typedef joint_view type; + }; + } + + template + typename result_of::erase::type + erase(Sequence const& seq, First const& first) + { + typedef result_of::erase result_of; + typedef typename result_of::left_type left_type; + typedef typename result_of::right_type right_type; + typedef typename result_of::type result_type; + + left_type left( + fusion::begin(seq) + , convert_iterator::call(first)); + right_type right( + fusion::result_of::compute_erase_last::call(first) + , fusion::end(seq)); + return result_type(left, right); + } + + template + typename result_of::erase::type + erase(Sequence const& seq, First const& first, Last const& last) + { + typedef result_of::erase result_of; + typedef typename result_of::left_type left_type; + typedef typename result_of::right_type right_type; + typedef typename result_of::type result_type; + + left_type left(fusion::begin(seq), first); + right_type right(last, fusion::end(seq)); + return result_type(left, right); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/erase_key.hpp b/thirdparty/boost/fusion/algorithm/transformation/erase_key.hpp new file mode 100644 index 0000000..e195217 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/erase_key.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ERASE_KEY_10022005_1851) +#define FUSION_ERASE_KEY_10022005_1851 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct erase_key + { + typedef detail::assoc_find filter; + typedef typename erase::type type; + }; + } + + template + inline typename result_of::erase_key::type + erase_key(Sequence const& seq) + { + typedef typename result_of::erase_key::filter filter; + return erase(seq, filter::call(seq)); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/filter.hpp b/thirdparty/boost/fusion/algorithm/transformation/filter.hpp new file mode 100644 index 0000000..b39d478 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/filter.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FILTER_02122005_1839) +#define FUSION_FILTER_02122005_1839 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct filter + { + typedef filter_view > type; + }; + } + + template + inline typename result_of::filter::type + filter(Sequence const& seq) + { + return filter_view >(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/filter_if.hpp b/thirdparty/boost/fusion/algorithm/transformation/filter_if.hpp new file mode 100644 index 0000000..227ccc2 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/filter_if.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FILTER_IF_07172005_0818) +#define FUSION_FILTER_IF_07172005_0818 + +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct filter_if + { + typedef filter_view type; + }; + } + + template + inline typename result_of::filter_if::type + filter_if(Sequence const& seq) + { + return filter_view(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/insert.hpp b/thirdparty/boost/fusion/algorithm/transformation/insert.hpp new file mode 100644 index 0000000..638fdec --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/insert.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INSERT_07222005_0730) +#define FUSION_INSERT_07222005_0730 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct insert + { + typedef typename detail::as_fusion_element::type element_type; + typedef typename convert_iterator::type pos_type; + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + + typedef iterator_range left_type; + typedef iterator_range right_type; + typedef fusion::single_view single_view; + typedef joint_view left_insert_type; + typedef joint_view type; + }; + } + + template + inline typename result_of::insert< + Sequence const, Position, T>::type + insert(Sequence const& seq, Position const& pos, T const& x) + { + typedef result_of::insert< + Sequence const, Position, T> + result_of; + typedef typename result_of::left_type left_type; + typedef typename result_of::right_type right_type; + typedef typename result_of::single_view single_view; + typedef typename result_of::left_insert_type left_insert_type; + typedef typename result_of::type result; + + left_type left(fusion::begin(seq), convert_iterator::call(pos)); + right_type right(convert_iterator::call(pos), fusion::end(seq)); + single_view insert(x); + left_insert_type left_insert(left, insert); + return result(left_insert, right); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/insert_range.hpp b/thirdparty/boost/fusion/algorithm/transformation/insert_range.hpp new file mode 100644 index 0000000..8dc2290 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/insert_range.hpp @@ -0,0 +1,55 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INSERT_RANGE_009172005_1147) +#define FUSION_INSERT_RANGE_009172005_1147 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct insert_range + { + typedef typename convert_iterator::type pos_type; + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + + typedef iterator_range left_type; + typedef iterator_range right_type; + typedef joint_view left_insert_type; + typedef joint_view type; + }; + } + + template + inline typename result_of::insert_range::type + insert_range(Sequence const& seq, Position const& pos, Range const& range) + { + typedef result_of::insert_range result_of; + typedef typename result_of::left_type left_type; + typedef typename result_of::right_type right_type; + typedef typename result_of::left_insert_type left_insert_type; + typedef typename result_of::type result; + + left_type left(fusion::begin(seq), convert_iterator::call(pos)); + right_type right(convert_iterator::call(pos), fusion::end(seq)); + left_insert_type left_insert(left, range); + return result(left_insert, right); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/join.hpp b/thirdparty/boost/fusion/algorithm/transformation/join.hpp new file mode 100644 index 0000000..62842bb --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/join.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_JOIN_200601222109) +#define FUSION_JOIN_200601222109 + +#include + +namespace boost { namespace fusion { + + namespace result_of + { + template + struct join + { + typedef joint_view type; + }; + } + + template + inline typename result_of::join::type + join(LhSequence const& lhs, RhSequence const& rhs) + { + return typename result_of::join::type( + lhs, rhs); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/algorithm/transformation/pop_back.hpp b/thirdparty/boost/fusion/algorithm/transformation/pop_back.hpp new file mode 100644 index 0000000..b23a700 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/pop_back.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_POP_BACK_09172005_1038) +#define FUSION_POP_BACK_09172005_1038 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct pop_back + { + typedef + iterator_range< + typename begin::type + , typename prior< + typename end::type + >::type + > + type; + }; + } + + template + inline typename result_of::pop_back::type + pop_back(Sequence const& seq) + { + typedef typename result_of::pop_back::type result; + return result(fusion::begin(seq), fusion::prior(fusion::end(seq))); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/pop_front.hpp b/thirdparty/boost/fusion/algorithm/transformation/pop_front.hpp new file mode 100644 index 0000000..6e59a73 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/pop_front.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_POP_FRONT_09172005_1115) +#define FUSION_POP_FRONT_09172005_1115 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct pop_front + { + typedef + iterator_range< + typename next< + typename begin::type + >::type + , typename end::type + > + type; + }; + } + + template + inline typename result_of::pop_front::type + pop_front(Sequence const& seq) + { + typedef typename result_of::pop_front::type result; + return result(fusion::next(fusion::begin(seq)), fusion::end(seq)); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/push_back.hpp b/thirdparty/boost/fusion/algorithm/transformation/push_back.hpp new file mode 100644 index 0000000..cd48d3a --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/push_back.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PUSH_BACK_07162005_0235) +#define FUSION_PUSH_BACK_07162005_0235 + +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct push_back + { + typedef fusion::single_view::type> single_view; + typedef joint_view type; + }; + } + + template + inline typename result_of::push_back::type + push_back(Sequence const& seq, T const& x) + { + typedef typename result_of::push_back push_back; + typedef typename push_back::single_view single_view; + typedef typename push_back::type result; + single_view x_(x); + return result(seq, x_); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/push_front.hpp b/thirdparty/boost/fusion/algorithm/transformation/push_front.hpp new file mode 100644 index 0000000..c6ef7f6 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/push_front.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PUSH_FRONT_07162005_0749) +#define FUSION_PUSH_FRONT_07162005_0749 + +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct push_front + { + typedef fusion::single_view::type> single_view; + typedef joint_view type; + }; + } + + template + inline typename result_of::push_front::type + push_front(Sequence const& seq, T const& x) + { + typedef typename result_of::push_front push_front; + typedef typename push_front::single_view single_view; + typedef typename push_front::type result; + single_view x_(x); + return result(x_, seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/remove.hpp b/thirdparty/boost/fusion/algorithm/transformation/remove.hpp new file mode 100644 index 0000000..40c2370 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/remove.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REMOVE_07162005_0818) +#define FUSION_REMOVE_07162005_0818 + +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct remove + { + typedef filter_view > > type; + }; + } + + template + inline typename result_of::remove::type + remove(Sequence const& seq) + { + typedef typename result_of::remove::type result_type; + return result_type(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/remove_if.hpp b/thirdparty/boost/fusion/algorithm/transformation/remove_if.hpp new file mode 100644 index 0000000..e4fb561 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/remove_if.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REMOVE_IF_07162005_0818) +#define FUSION_REMOVE_IF_07162005_0818 + +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct remove_if + { + typedef filter_view > type; + }; + } + + template + inline typename result_of::remove_if::type + remove_if(Sequence const& seq) + { + typedef typename result_of::remove_if::type result_type; + return result_type(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/replace.hpp b/thirdparty/boost/fusion/algorithm/transformation/replace.hpp new file mode 100644 index 0000000..be8487f --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/replace.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REPLACE_08182005_0830) +#define FUSION_REPLACE_08182005_0830 + +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct replace + { + typedef transform_view > type; + }; + } + + template + inline typename result_of::replace::type + replace(Sequence const& seq, T const& old_value, T const& new_value) + { + typedef typename result_of::replace::type result; + detail::replacer f(old_value, new_value); + return result(seq, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/replace_if.hpp b/thirdparty/boost/fusion/algorithm/transformation/replace_if.hpp new file mode 100644 index 0000000..df8c714 --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/replace_if.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REPLACE_IF_08182005_0939) +#define FUSION_REPLACE_IF_08182005_0939 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct replace_if + { + typedef transform_view > type; + }; + } + + template + inline typename result_of::replace_if::type + replace_if(Sequence const& seq, F pred, T const& new_value) + { + typedef typename result_of::replace_if::type result; + detail::replacer_if f(pred, new_value); + return result(seq, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/reverse.hpp b/thirdparty/boost/fusion/algorithm/transformation/reverse.hpp new file mode 100644 index 0000000..34df14c --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/reverse.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REVERSE_07212005_1230) +#define FUSION_REVERSE_07212005_1230 + +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct reverse + { + typedef reverse_view type; + }; + } + + template + inline reverse_view + reverse(Sequence const& view) + { + return reverse_view(view); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/transform.hpp b/thirdparty/boost/fusion/algorithm/transformation/transform.hpp new file mode 100644 index 0000000..b0d006d --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/transform.hpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TRANSFORM_07052005_1057) +#define FUSION_TRANSFORM_07052005_1057 + +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template + struct transform + { + typedef transform_view type; + }; + + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct transform +#else + struct transform +#endif + { + typedef transform_view type; + }; + } + + template + inline typename result_of::transform::type + transform(Sequence const& seq, F f) + { + return transform_view(seq, f); + } + + template + inline typename result_of::transform::type + transform(Sequence1 const& seq1, Sequence2 const& seq2, F f) + { + return transform_view(seq1, seq2, f); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/algorithm/transformation/zip.hpp b/thirdparty/boost/fusion/algorithm/transformation/zip.hpp new file mode 100644 index 0000000..24b0e0a --- /dev/null +++ b/thirdparty/boost/fusion/algorithm/transformation/zip.hpp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_ZIP_HPP_20060125_2058) +#define FUSION_ZIP_HPP_20060125_2058 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(FUSION_MAX_ZIP_SEQUENCES) +#define FUSION_MAX_ZIP_SEQUENCES 10 +#endif + +namespace boost { namespace fusion { + + struct void_; + + namespace result_of + { + template + struct zip; + } + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (2, FUSION_MAX_ZIP_SEQUENCES) +#include BOOST_PP_ITERATE() + +}} + +#endif + +#else + +#define ZIP_ITERATION BOOST_PP_ITERATION() + + namespace result_of + { + template< BOOST_PP_ENUM_PARAMS(ZIP_ITERATION, typename T) > +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct zip< BOOST_PP_ENUM_PARAMS(ZIP_ITERATION, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(ZIP_ITERATION), FUSION_MAX_ZIP_SEQUENCES, TEXT, void_) > + #undef TEXT +#else + struct zip< BOOST_PP_ENUM_PARAMS(ZIP_ITERATION, T) > +#endif + { + typedef mpl::vector< BOOST_PP_ENUM_PARAMS(ZIP_ITERATION, T) > sequences; + typedef typename mpl::transform >::type ref_params; + typedef zip_view::type> type; + }; + } + +#define FUSION_REF_PARAM(z, n, data) const T ## n& + + template + inline typename result_of::zip::type + zip(BOOST_PP_ENUM_BINARY_PARAMS(ZIP_ITERATION, T, const& t)) + { + fusion::vector seqs( + BOOST_PP_ENUM_PARAMS(ZIP_ITERATION, t)); + return typename result_of::zip::type( + seqs); + } + +#undef FUSION_REF_PARAM +#undef ZIP_ITERATION + +#endif diff --git a/thirdparty/boost/fusion/container.hpp b/thirdparty/boost/fusion/container.hpp new file mode 100644 index 0000000..f92aa04 --- /dev/null +++ b/thirdparty/boost/fusion/container.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_CLASS_10022005_0614) +#define FUSION_SEQUENCE_CLASS_10022005_0614 + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/deque.hpp b/thirdparty/boost/fusion/container/deque.hpp new file mode 100644 index 0000000..433c1a2 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_SEQUENCE_CONTAINER_DEQUE_24112006_2036) +#define BOOST_FUSION_SEQUENCE_CONTAINER_DEQUE_24112006_2036 + +#include +#include + +#endif + diff --git a/thirdparty/boost/fusion/container/deque/back_extended_deque.hpp b/thirdparty/boost/fusion/container/deque/back_extended_deque.hpp new file mode 100644 index 0000000..747f5ce --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/back_extended_deque.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_BACK_EXTENDED_DEQUE_26112006_2209) +#define BOOST_FUSION_BACK_EXTENDED_DEQUE_26112006_2209 + +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { namespace fusion { + template + struct back_extended_deque + : detail::keyed_element, + sequence_base > + { + typedef detail::keyed_element base; + typedef typename Deque::next_down next_down; + typedef mpl::int_ >::value> next_up; + typedef mpl::plus::type, mpl::int_<1> > size; + + back_extended_deque(Deque const& deque, typename add_reference::type>::type t) + : base(t, deque) + {} + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/convert.hpp b/thirdparty/boost/fusion/container/deque/convert.hpp new file mode 100644 index 0000000..ea7170a --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/convert.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_20061213_2207) +#define FUSION_CONVERT_20061213_2207 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct as_deque + { + typedef typename detail::as_deque::value> gen; + typedef typename gen:: + template apply::type>::type + type; + }; + } + + template + inline typename result_of::as_deque::type + as_deque(Sequence& seq) + { + typedef typename result_of::as_deque::gen gen; + return gen::call(fusion::begin(seq)); + } + + template + inline typename result_of::as_deque::type + as_deque(Sequence const& seq) + { + typedef typename result_of::as_deque::gen gen; + return gen::call(fusion::begin(seq)); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/deque.hpp b/thirdparty/boost/fusion/container/deque/deque.hpp new file mode 100644 index 0000000..842e43c --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/deque.hpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_26112006_1649) +#define BOOST_FUSION_DEQUE_26112006_1649 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { namespace fusion { + + struct deque_tag; + + template + struct deque + : + detail::deque_keyed_values::type, + sequence_base > + { + typedef deque_tag fusion_tag; + typedef typename detail::deque_keyed_values::type base; + typedef typename detail::deque_initial_size::type size; + typedef mpl::int_ next_up; + typedef mpl::int_< + mpl::if_ >, mpl::int_<0>, mpl::int_<-1> >::type::value> next_down; + typedef mpl::false_ is_view; + +#include + + deque() + {} + + explicit deque(typename add_reference::type>::type t0) + : base(t0, detail::nil_keyed_element()) + {} + + template + deque(deque const& seq) + : base(seq) + {} + + template + deque(Sequence const& seq, typename disable_if >::type* dummy = 0) + : base(base::from_iterator(fusion::begin(seq))) + {} + + template + deque& + operator=(deque const& rhs) + { + base::operator=(rhs); + return *this; + } + + template + deque& + operator=(T const& rhs) + { + base::operator=(rhs); + return *this; + } + + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/deque_fwd.hpp b/thirdparty/boost/fusion/container/deque/deque_fwd.hpp new file mode 100644 index 0000000..2839e3a --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/deque_fwd.hpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2005-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEQUE_FORWARD_02092007_0749) +#define FUSION_DEQUE_FORWARD_02092007_0749 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template< + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_DEQUE_SIZE, typename T, void_)> + struct deque; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/deque_iterator.hpp b/thirdparty/boost/fusion/container/deque/deque_iterator.hpp new file mode 100644 index 0000000..5723cca --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/deque_iterator.hpp @@ -0,0 +1,106 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_ITERATOR_26112006_2154) +#define BOOST_FUSION_DEQUE_ITERATOR_26112006_2154 + +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct bidirectional_traversal_tag; + + template + struct deque_iterator + : iterator_facade, bidirectional_traversal_tag> + { + typedef Seq sequence; + typedef mpl::int_ index; + + deque_iterator(Seq& seq) + : seq_(seq) + {} + + template + struct value_of + : detail::keyed_element_value_at< + typename Iterator::sequence, typename Iterator::index> + {}; + + template + struct deref + { + typedef typename detail::keyed_element_value_at< + typename Iterator::sequence, typename Iterator::index>::type element_type; + + typedef typename add_reference< + typename mpl::eval_if< + is_const, + add_const, + mpl::identity >::type>::type type; + + static type + call(Iterator const& it) + { + return it.seq_.get(typename Iterator::index()); + } + }; + + template + struct advance + { + typedef typename Iterator::index index; + typedef typename Iterator::sequence sequence; + typedef deque_iterator type; + + static type + call(Iterator const& i) + { + return type(i.seq_); + } + }; + + template + struct next + : advance > + {}; + + template + struct prior + : advance > + {}; + + template + struct distance : mpl::minus + { + typedef typename + mpl::minus< + typename I2::index, typename I1::index + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + + template + struct equal_to + : mpl::equal_to + {}; + + Seq& seq_; + }; + +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/as_deque.hpp b/thirdparty/boost/fusion/container/deque/detail/as_deque.hpp new file mode 100644 index 0000000..e13289e --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/as_deque.hpp @@ -0,0 +1,102 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_AS_DEQUE_20061213_2210) +#define FUSION_AS_DEQUE_20061213_2210 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct as_deque; + + template <> + struct as_deque<0> + { + template + struct apply + { + typedef deque<> type; + }; + + template + static typename apply::type + call(Iterator) + { + return deque<>(); + } + }; + +#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::next::type \ + BOOST_PP_CAT(I, BOOST_PP_INC(n)); + +#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \ + typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \ + BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n)); + +#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::value_of::type \ + BOOST_PP_CAT(T, n); + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_DEQUE_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_NEXT_ITERATOR +#undef BOOST_FUSION_NEXT_CALL_ITERATOR +#undef BOOST_FUSION_VALUE_OF_ITERATOR + +}}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template <> + struct as_deque + { + template + struct apply + { + BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _) + BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _) + typedef deque type; + }; + + template + static typename apply::type + call(Iterator const& i0) + { + typedef apply gen; + typedef typename gen::type result; + BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _) + return result(BOOST_PP_ENUM_PARAMS(N, *i)); + } + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/deque/detail/at_impl.hpp b/thirdparty/boost/fusion/container/deque/detail/at_impl.hpp new file mode 100644 index 0000000..94b0751 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/at_impl.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_AT_IMPL_09122006_2017) +#define BOOST_FUSION_DEQUE_AT_IMPL_09122006_2017 + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { namespace fusion { + + struct deque_tag; + + namespace extension + { + template + struct at_impl; + + template<> + struct at_impl + { + template + struct apply + { + typedef typename Sequence::next_up next_up; + typedef typename Sequence::next_down next_down; + BOOST_MPL_ASSERT_RELATION(next_down::value, !=, next_up::value); + + typedef mpl::plus > offset; + typedef mpl::int_::value> adjusted_index; + typedef typename detail::keyed_element_value_at::type element_type; + typedef typename add_reference< + typename mpl::eval_if< + is_const, + add_const, + mpl::identity >::type>::type type; + + static type call(Sequence& seq) + { + return seq.get(adjusted_index()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/begin_impl.hpp b/thirdparty/boost/fusion/container/deque/detail/begin_impl.hpp new file mode 100644 index 0000000..e33fb31 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/begin_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_BEGIN_IMPL_09122006_2034) +#define BOOST_FUSION_DEQUE_BEGIN_IMPL_09122006_2034 + +#include + +#include +#include + +namespace boost { namespace fusion { + + struct deque_tag; + + namespace extension + { + template + struct begin_impl; + + template<> + struct begin_impl + { + template + struct apply + { + typedef typename mpl::if_< + mpl::equal_to, + deque_iterator, + deque_iterator< + Sequence, mpl::plus >::value> >::type type; + + static type call(Sequence& seq) + { + return type(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/convert_impl.hpp b/thirdparty/boost/fusion/container/deque/detail/convert_impl.hpp new file mode 100644 index 0000000..82c5d95 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/convert_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_IMPL_20061213_2207) +#define FUSION_CONVERT_IMPL_20061213_2207 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct deque_tag; + + namespace extension + { + template + struct convert_impl; + + template <> + struct convert_impl + { + template + struct apply + { + typedef typename detail::as_deque::value> gen; + typedef typename gen:: + template apply::type>::type + type; + + static type call(Sequence& seq) + { + return gen::call(fusion::begin(seq)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/deque_forward_ctor.hpp b/thirdparty/boost/fusion/container/deque/detail/deque_forward_ctor.hpp new file mode 100644 index 0000000..ecdabdc --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/deque_forward_ctor.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_PP_IS_ITERATING) +#if !defined(BOOST_FUSION_SEQUENCE_DEQUE_DETAIL_DEQUE_FORWARD_CTOR_04122006_2212) +#define BOOST_FUSION_SEQUENCE_DEQUE_DETAIL_DEQUE_FORWARD_CTOR_04122006_2212 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (2, FUSION_MAX_DEQUE_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else + +#define N BOOST_PP_ITERATION() + +deque(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type>::type t)) + : base(detail::deque_keyed_values::call(BOOST_PP_ENUM_PARAMS(N, t))) +{} + +#undef N +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/deque_initial_size.hpp b/thirdparty/boost/fusion/container/deque/detail/deque_initial_size.hpp new file mode 100644 index 0000000..e7b29e4 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/deque_initial_size.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_DETAIL_DEQUE_INITIAL_SIZE_26112006_2139) +#define BOOST_FUSION_DEQUE_DETAIL_DEQUE_INITIAL_SIZE_26112006_2139 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct void_; + +namespace detail { + + template + struct deque_initial_size + { + typedef mpl::vector args; + typedef typename mpl::find::type first_void; + typedef typename mpl::distance::type, first_void>::type type; + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values.hpp b/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values.hpp new file mode 100644 index 0000000..b44ee1f --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_DETAIL_DEQUE_KEYED_VALUES_26112006_1330) +#define BOOST_FUSION_DEQUE_DETAIL_DEQUE_KEYED_VALUES_26112006_1330 + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define FUSION_VOID(z, n, _) void_ + +namespace boost { namespace fusion { + + struct void_; + +namespace detail { + + template + struct keyed_element; + + struct nil_keyed_element; + + template + struct deque_keyed_values_impl; + + template + struct deque_keyed_values_impl + { + typedef nil_keyed_element type; + + static type call() + { + return type(); + } + }; + + template + struct deque_keyed_values_impl + { + typedef mpl::int_ >::value> next_index; + + typedef typename deque_keyed_values_impl< + next_index, + BOOST_PP_ENUM_SHIFTED_PARAMS(FUSION_MAX_DEQUE_SIZE, T)>::type tail; + typedef keyed_element type; + +#include + + }; + + template + struct deque_keyed_values + : deque_keyed_values_impl, BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, T)> + {}; + +}}} + +#undef FUSION_VOID + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp b/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp new file mode 100644 index 0000000..41c98ca --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_PP_IS_ITERATING) +#if !defined(BOOST_FUSION_SEQUENCE_DEQUE_DETAIL_DEQUE_KEYED_VALUES_CALL_04122006_2211) +#define BOOST_FUSION_SEQUENCE_DEQUE_DETAIL_DEQUE_KEYED_VALUES_CALL_04122006_2211 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_DEQUE_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else + +#define N BOOST_PP_ITERATION() + +static type call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type>::type t)) +{ + return type(t0, + deque_keyed_values_impl< + next_index +#if N > 1 + , BOOST_PP_ENUM_SHIFTED_PARAMS(N, T) +#endif + >::call(BOOST_PP_ENUM_SHIFTED_PARAMS(N, t))); +} + +#undef N +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/end_impl.hpp b/thirdparty/boost/fusion/container/deque/detail/end_impl.hpp new file mode 100644 index 0000000..5e7aa4e --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/end_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_END_IMPL_09122006_2034) +#define BOOST_FUSION_DEQUE_END_IMPL_09122006_2034 + +#include + +#include +#include + +namespace boost { namespace fusion { + + struct deque_tag; + + namespace extension + { + template + struct end_impl; + + template<> + struct end_impl + { + template + struct apply + { + typedef typename mpl::if_< + mpl::equal_to, + deque_iterator, + deque_iterator< + Sequence, Sequence::next_up::value> >::type type; + + static type call(Sequence& seq) + { + return type(seq); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/keyed_element.hpp b/thirdparty/boost/fusion/container/deque/detail/keyed_element.hpp new file mode 100644 index 0000000..e02ff49 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/keyed_element.hpp @@ -0,0 +1,111 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330) +#define BOOST_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330 + +#include +#include + +#include +#include + +namespace boost { namespace fusion { + + struct fusion_sequence_tag; + +namespace detail { + + struct nil_keyed_element + { + typedef fusion_sequence_tag tag; + void get(); + + template + static nil_keyed_element + from_iterator(It const&) + { + return nil_keyed_element(); + } + }; + + template + struct keyed_element + : Rest + { + typedef Rest base; + typedef fusion_sequence_tag tag; + using Rest::get; + + template + static keyed_element + from_iterator(It const& it) + { + return keyed_element( + *it, base::from_iterator(fusion::next(it))); + } + + template + keyed_element(keyed_element const& rhs) + : Rest(rhs.get_base()), value_(rhs.value_) + {} + + Rest const get_base() const + { + return *this; + } + + typename add_reference::type>::type get(Key) const + { + return value_; + } + + typename add_reference::type get(Key) + { + return value_; + } + + keyed_element(typename add_reference::type>::type value, Rest const& rest) + : Rest(rest), value_(value) + {} + + keyed_element() + : Rest(), value_() + {} + + template + keyed_element& operator=(keyed_element const& rhs) + { + base::operator=(static_cast(rhs)); // cast for msvc-7.1 + value_ = rhs.value_; + return *this; + } + + keyed_element& operator=(keyed_element const& rhs) + { + base::operator=(rhs); + value_ = rhs.value_; + return *this; + } + + Value value_; + }; + + template + struct keyed_element_value_at + : keyed_element_value_at + {}; + + template + struct keyed_element_value_at, Key> + { + typedef Value type; + }; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/detail/value_at_impl.hpp b/thirdparty/boost/fusion/container/deque/detail/value_at_impl.hpp new file mode 100644 index 0000000..838feb4 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/detail/value_at_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_VALUE_AT_IMPL_08122006_0756) +#define BOOST_FUSION_DEQUE_VALUE_AT_IMPL_08122006_0756 + +#include + +#include +#include + +namespace boost { namespace fusion { + + struct deque_tag; + + namespace extension + { + template + struct value_at_impl; + + template<> + struct value_at_impl + { + template + struct apply + { + typedef typename Sequence::next_up next_up; + typedef typename Sequence::next_down next_down; + BOOST_MPL_ASSERT_RELATION(next_down::value, !=, next_up::value); + + typedef mpl::plus > offset; + typedef mpl::int_::value> adjusted_index; + typedef typename detail::keyed_element_value_at::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/front_extended_deque.hpp b/thirdparty/boost/fusion/container/deque/front_extended_deque.hpp new file mode 100644 index 0000000..8e1add2 --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/front_extended_deque.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_FRONT_EXTENDED_DEQUE_26112006_2209) +#define BOOST_FUSION_FRONT_EXTENDED_DEQUE_26112006_2209 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace boost { namespace fusion { + template + struct front_extended_deque + : detail::keyed_element, + sequence_base > + { + typedef detail::keyed_element base; + typedef mpl::int_ >::value> next_down; + typedef typename Deque::next_up next_up; + typedef mpl::plus::type, mpl::int_<1> > size; + + front_extended_deque(Deque const& deque, typename add_reference::type>::type t) + : base(t, deque) + {} + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/deque/limits.hpp b/thirdparty/boost/fusion/container/deque/limits.hpp new file mode 100644 index 0000000..7a5336d --- /dev/null +++ b/thirdparty/boost/fusion/container/deque/limits.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_DEQUE_LIMITS_26112006_1737) +#define BOOST_FUSION_DEQUE_LIMITS_26112006_1737 + +#if !defined(FUSION_MAX_DEQUE_SIZE) +#define FUSION_MAX_DEQUE_SIZE 10 +#endif + +#endif diff --git a/thirdparty/boost/fusion/container/ext_/tree.hpp b/thirdparty/boost/fusion/container/ext_/tree.hpp new file mode 100644 index 0000000..1ea8320 --- /dev/null +++ b/thirdparty/boost/fusion/container/ext_/tree.hpp @@ -0,0 +1,130 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef FUSION_BINARY_TREE_EAN_05032006_1027 +#define FUSION_BINARY_TREE_EAN_05032006_1027 + +#include +#include +#include +#include +#include +#include +#include +#include // for nil +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct tree_tag; + + namespace detail + { + template + struct reference : add_reference {}; + + template + struct reference : reference::type, false> {}; + + template + struct reference : reference {}; + } + + template + struct tree + : sequence_base > + { + typedef Data data_type; + typedef Left left_type; + typedef Right right_type; + typedef tree_tag fusion_tag; + typedef forward_traversal_tag category; + typedef mpl::false_ is_view; + + typedef typename mpl::if_< + traits::is_sequence + , Data + , single_view + >::type data_view; + + explicit tree( + typename fusion::detail::call_param::type data_ + , typename fusion::detail::call_param::type left_ = Left() + , typename fusion::detail::call_param::type right_ = Right() + ) + : segments(left_, data_view(data_), right_) + {} + + typedef vector3 segments_type; + segments_type segments; + }; + + template + tree make_tree(Data const &data) + { + return tree(data); + } + + template + tree make_tree(Data const &data, Left const &left, Right const &right) + { + return tree(data, left, right); + } + + namespace extension + { + template<> + struct is_segmented_impl + { + template + struct apply : mpl::true_ {}; + }; + + template<> + struct segments_impl + { + template + struct apply + { + typedef typename mpl::if_< + is_const + , typename Sequence::segments_type const & + , typename Sequence::segments_type & + >::type type; + + static type call(Sequence &seq) + { + return seq.segments; + } + }; + }; + + template<> + struct begin_impl + { + template + struct apply + : segmented_begin + {}; + }; + + template<> + struct end_impl + { + template + struct apply + : segmented_end + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/generation.hpp b/thirdparty/boost/fusion/container/generation.hpp new file mode 100644 index 0000000..40d96ee --- /dev/null +++ b/thirdparty/boost/fusion/container/generation.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_GENERATION_10022005_0615) +#define FUSION_SEQUENCE_GENERATION_10022005_0615 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/generation/cons_tie.hpp b/thirdparty/boost/fusion/container/generation/cons_tie.hpp new file mode 100644 index 0000000..bd69006 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/cons_tie.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONS_TIE_07182005_0854) +#define FUSION_CONS_TIE_07182005_0854 + +#include + +namespace boost { namespace fusion +{ + struct nil; + + namespace result_of + { + template + struct cons_tie + { + typedef cons type; + }; + } + + // $$$ do we really want a cons_tie? $$$ + template + inline cons + cons_tie(Car& car) + { + return cons(car); + } + + // $$$ do we really want a cons_tie? $$$ + template + inline cons + cons_tie(Car& car, Cdr const& cdr) + { + return cons(car, cdr); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/generation/deque_tie.hpp b/thirdparty/boost/fusion/container/generation/deque_tie.hpp new file mode 100644 index 0000000..251eaa0 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/deque_tie.hpp @@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_DEQUE_TIE_07192005_1242) +#define FUSION_DEQUE_TIE_07192005_1242 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_DEQUE_SIZE, typename T, void_) + , typename Extra = void_ + > + struct deque_tie; + } + +#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)& + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_DEQUE_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_REF + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct deque_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_DEQUE_SIZE, TEXT, void_) > + #undef TEXT +#else + struct deque_tie +#endif + { + typedef deque type; + }; + } + + template + inline deque + deque_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & _)) + { + return deque( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/ignore.hpp b/thirdparty/boost/fusion/container/generation/ignore.hpp new file mode 100644 index 0000000..77e44f9 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/ignore.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001 Doug Gregor + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IGNORE_07192005_0329) +#define FUSION_IGNORE_07192005_0329 + +namespace boost { namespace fusion +{ + // Swallows any assignment (by Doug Gregor) + namespace detail + { + struct swallow_assign + { + template + swallow_assign const& + operator=(const T&) const + { + return *this; + } + }; + } + + // "ignore" allows tuple positions to be ignored when using "tie". + detail::swallow_assign const ignore = detail::swallow_assign(); +}} + +#endif diff --git a/thirdparty/boost/fusion/container/generation/list_tie.hpp b/thirdparty/boost/fusion/container/generation/list_tie.hpp new file mode 100644 index 0000000..60eb8c5 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/list_tie.hpp @@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_LIST_TIE_07192005_0109) +#define FUSION_LIST_TIE_07192005_0109 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_LIST_SIZE, typename T, void_) + , typename Extra = void_ + > + struct list_tie; + } + +// $$$ shouldn't we remove_reference first to allow references? $$$ +#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)& + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_REF + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct list_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) > + #undef TEXT +#else + struct list_tie +#endif + { + typedef list type; + }; + } + + template + inline list + list_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & _)) + { + return list( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/make_cons.hpp b/thirdparty/boost/fusion/container/generation/make_cons.hpp new file mode 100644 index 0000000..9eab801 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_cons.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MAKE_CONS_07172005_0918) +#define FUSION_MAKE_CONS_07172005_0918 + +#include +#include + +namespace boost { namespace fusion +{ + struct nil; + + namespace result_of + { + template + struct make_cons + { + typedef cons::type, Cdr> type; + }; + } + + template + inline cons::type> + make_cons(Car const& car) + { + return cons::type>(car); + } + + template + inline cons::type, Cdr> + make_cons(Car const& car, Cdr const& cdr) + { + return cons::type, Cdr>(car, cdr); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/generation/make_deque.hpp b/thirdparty/boost/fusion/container/generation/make_deque.hpp new file mode 100644 index 0000000..a581c01 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_deque.hpp @@ -0,0 +1,98 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_DEQUE_07162005_0243) +#define FUSION_MAKE_DEQUE_07162005_0243 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_DEQUE_SIZE, typename T, void_) + , typename Extra = void_ + > + struct make_deque; + + template <> + struct make_deque<> + { + typedef deque<> type; + }; + } + + inline deque<> + make_deque() + { + return deque<>(); + } + +#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \ + typename detail::as_fusion_element::type + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_DEQUE_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_AS_FUSION_ELEMENT + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct make_deque< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_DEQUE_SIZE, TEXT, void_) > + #undef TEXT +#else + struct make_deque +#endif + { + typedef deque type; + }; + } + + template + inline deque + make_deque(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + { + return deque( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/make_list.hpp b/thirdparty/boost/fusion/container/generation/make_list.hpp new file mode 100644 index 0000000..b5a3883 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_list.hpp @@ -0,0 +1,91 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_LIST_07192005_1239) +#define FUSION_MAKE_LIST_07192005_1239 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_LIST_SIZE, typename T, void_) + , typename Extra = void_ + > + struct make_list; + + template <> + struct make_list<> + { + typedef list<> type; + }; + } + + inline list<> + make_list() + { + return list<>(); + } + +#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \ + typename detail::as_fusion_element::type + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_AS_FUSION_ELEMENT + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct make_list< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_LIST_SIZE, TEXT, void_) > + #undef TEXT +#else + struct make_list +#endif + { + typedef list type; + }; + } + + template + inline list + make_list(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + { + return list( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/make_map.hpp b/thirdparty/boost/fusion/container/generation/make_map.hpp new file mode 100644 index 0000000..2b17160 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_map.hpp @@ -0,0 +1,106 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_MAP_07222005_1247) +#define FUSION_MAKE_MAP_07222005_1247 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename K, void_) + , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename D, void_) + , typename Extra = void_ + > + struct make_map; + + template <> + struct make_map<> + { + typedef map<> type; + }; + } + + inline map<> + make_map() + { + return map<>(); + } + +#define BOOST_FUSION_PAIR(z, n, data) \ + fusion::pair< \ + BOOST_PP_CAT(K, n) \ + , typename detail::as_fusion_element::type> + +#define BOOST_FUSION_MAKE_PAIR(z, n, data) \ + fusion::make_pair(BOOST_PP_CAT(_, n)) \ + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_PAIR +#undef BOOST_FUSION_MAKE_PAIR + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS(N, typename K) + , BOOST_PP_ENUM_PARAMS(N, typename D) + > +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct make_map + #undef TEXT +#else + struct make_map +#endif + { + typedef map type; + }; + } + + template < + BOOST_PP_ENUM_PARAMS(N, typename K) + , BOOST_PP_ENUM_PARAMS(N, typename D) + > + inline map + make_map(BOOST_PP_ENUM_BINARY_PARAMS(N, D, const& _)) + { + return map( + BOOST_PP_ENUM(N, BOOST_FUSION_MAKE_PAIR, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/make_set.hpp b/thirdparty/boost/fusion/container/generation/make_set.hpp new file mode 100644 index 0000000..a7b6715 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_set.hpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_SET_09162005_1125) +#define FUSION_MAKE_SET_09162005_1125 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename T, void_) + , typename Extra = void_ + > + struct make_set; + + template <> + struct make_set<> + { + typedef set<> type; + }; + } + + inline set<> + make_set() + { + return set<>(); + } + +#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \ + typename detail::as_fusion_element::type + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_ELEMENT +#undef BOOST_FUSION_AS_ELEMENT + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct make_set< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_SET_SIZE, TEXT, void_) > + #undef TEXT +#else + struct make_set +#endif + { + typedef set type; + }; + } + + template + inline set + make_set(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + { + return set( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/make_vector.hpp b/thirdparty/boost/fusion/container/generation/make_vector.hpp new file mode 100644 index 0000000..7d0e663 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/make_vector.hpp @@ -0,0 +1,91 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_VECTOR_07162005_0243) +#define FUSION_MAKE_VECTOR_07162005_0243 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename T, void_) + , typename Extra = void_ + > + struct make_vector; + + template <> + struct make_vector<> + { + typedef vector<> type; + }; + } + + inline vector<> + make_vector() + { + return vector<>(); + } + +#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \ + typename detail::as_fusion_element::type + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_AS_FUSION_ELEMENT + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct make_vector< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) > + #undef TEXT +#else + struct make_vector +#endif + { + typedef vector type; + }; + } + + template + inline vector + make_vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + { + return vector( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/map_tie.hpp b/thirdparty/boost/fusion/container/generation/map_tie.hpp new file mode 100644 index 0000000..619893f --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/map_tie.hpp @@ -0,0 +1,110 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAP_TIE_20060814_1116) +#define FUSION_MAP_TIE_20060814_1116 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_MAP_SIZE, typename K, void_) + , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_MAP_SIZE, typename D, void_) + , typename Extra = void_ + > + struct map_tie; + + template <> + struct map_tie<> + { + typedef map<> type; + }; + } + + inline map<> + map_tie() + { + return map<>(); + } + +#define BOOST_FUSION_TIED_PAIR(z, n, data) \ + fusion::pair< \ + BOOST_PP_CAT(K, n) \ + , typename add_reference::type> + +#define BOOST_FUSION_PAIR_TIE(z, n, data) \ + fusion::pair_tie(BOOST_PP_CAT(_, n)) \ + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_MAP_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_PAIR +#undef BOOST_FUSION_MAKE_PAIR + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS(N, typename K) + , BOOST_PP_ENUM_PARAMS(N, typename D) + > +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + + struct map_tie + #undef TEXT +#else + struct map_tie +#endif + { + typedef map type; + }; + } + + template < + BOOST_PP_ENUM_PARAMS(N, typename K) + , BOOST_PP_ENUM_PARAMS(N, typename D) + > + inline map + map_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, D, & _)) + { + return map( + BOOST_PP_ENUM(N, BOOST_FUSION_PAIR_TIE, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/generation/pair_tie.hpp b/thirdparty/boost/fusion/container/generation/pair_tie.hpp new file mode 100644 index 0000000..d66900c --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/pair_tie.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the 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_FUSION_PAIR_TIE_20060812_2058) +#define BOOST_FUSION_PAIR_TIE_20060812_2058 + +#include +#include + +namespace boost { namespace fusion { + + template + struct pair; + + namespace result_of + { + template + struct pair_tie + { + typedef fusion::pair type; + }; + } + + template + typename disable_if, typename result_of::pair_tie::type>::type + pair_tie(T& t) + { + return typename result_of::pair_tie::type(t); + } + + template + typename result_of::pair_tie::type + pair_tie(T const& t) + { + return typename result_of::pair_tie::type(t); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/generation/vector_tie.hpp b/thirdparty/boost/fusion/container/generation/vector_tie.hpp new file mode 100644 index 0000000..513d038 --- /dev/null +++ b/thirdparty/boost/fusion/container/generation/vector_tie.hpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_VECTOR_TIE_07192005_1242) +#define FUSION_VECTOR_TIE_07192005_1242 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename T, void_) + , typename Extra = void_ + > + struct vector_tie; + } + +#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)& + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_REF + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + namespace result_of + { + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + #define TEXT(z, n, text) , text + struct vector_tie< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, void_) > + #undef TEXT +#else + struct vector_tie +#endif + { + typedef vector type; + }; + } + + template + inline vector + vector_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & _)) + { + return vector( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/list.hpp b/thirdparty/boost/fusion/container/list.hpp new file mode 100644 index 0000000..5da732c --- /dev/null +++ b/thirdparty/boost/fusion/container/list.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_CLASS_LIST_10022005_0605) +#define FUSION_SEQUENCE_CLASS_LIST_10022005_0605 + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/list/cons.hpp b/thirdparty/boost/fusion/container/list/cons.hpp new file mode 100644 index 0000000..09daf43 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/cons.hpp @@ -0,0 +1,143 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONS_07172005_0843) +#define FUSION_CONS_07172005_0843 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + struct cons_tag; + struct forward_traversal_tag; + struct fusion_sequence_tag; + + struct nil : sequence_base + { + typedef mpl::int_<0> size; + typedef cons_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + typedef forward_traversal_tag category; + typedef void_ car_type; + typedef void_ cdr_type; + + nil() {} + + template + nil(Iterator const& iter, mpl::true_ /*this_is_an_iterator*/) + {} + + template + void assign_from_iter(Iterator const& iter) + { + } + }; + + template + struct cons : sequence_base > + { + typedef mpl::int_ size; + typedef cons_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + typedef forward_traversal_tag category; + typedef Car car_type; + typedef Cdr cdr_type; + + cons() + : car(), cdr() {} + + explicit cons(typename detail::call_param::type car) + : car(car), cdr() {} + + cons( + typename detail::call_param::type car + , typename detail::call_param::type cdr) + : car(car), cdr(cdr) {} + + template + cons(cons const& rhs) + : car(rhs.car), cdr(rhs.cdr) {} + + cons(cons const& rhs) + : car(rhs.car), cdr(rhs.cdr) {} + + template + cons( + Sequence const& seq + , typename disable_if< + mpl::or_< + is_convertible // use copy ctor instead + , is_convertible // use copy to car instead + > + >::type* dummy = 0 + ) + : car(*fusion::begin(seq)) + , cdr(fusion::next(fusion::begin(seq)), mpl::true_()) {} + + template + cons(Iterator const& iter, mpl::true_ /*this_is_an_iterator*/) + : car(*iter) + , cdr(fusion::next(iter), mpl::true_()) {} + + template + cons& operator=(cons const& rhs) + { + car = rhs.car; + cdr = rhs.cdr; + return *this; + } + + cons& operator=(cons const& rhs) + { + car = rhs.car; + cdr = rhs.cdr; + return *this; + } + + template + typename disable_if, cons&>::type + operator=(Sequence const& seq) + { + typedef typename result_of::begin::type Iterator; + Iterator iter = fusion::begin(seq); + this->assign_from_iter(iter); + return *this; + } + + template + void assign_from_iter(Iterator const& iter) + { + car = *iter; + cdr.assign_from_iter(fusion::next(iter)); + } + + car_type car; + cdr_type cdr; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/list/cons_iterator.hpp b/thirdparty/boost/fusion/container/list/cons_iterator.hpp new file mode 100644 index 0000000..2fa1c63 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/cons_iterator.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONS_ITERATOR_07172005_0849) +#define FUSION_CONS_ITERATOR_07172005_0849 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct nil; + struct cons_iterator_tag; + struct forward_traversal_tag; + + template + struct cons_iterator_identity; + + template + struct cons_iterator : iterator_base > + { + typedef cons_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + typedef Cons cons_type; + typedef cons_iterator_identity< + typename add_const::type> + identity; + + explicit cons_iterator(cons_type& cons) + : cons(cons) {} + + cons_type& cons; + }; + + struct nil_iterator : iterator_base + { + typedef forward_traversal_tag category; + typedef cons_iterator_tag fusion_tag; + typedef nil cons_type; + typedef cons_iterator_identity< + add_const::type> + identity; + nil_iterator() {} + explicit nil_iterator(nil const&) {} + }; + + template <> + struct cons_iterator : nil_iterator + { + cons_iterator() {} + explicit cons_iterator(nil const&) {} + }; + + template <> + struct cons_iterator : nil_iterator + { + cons_iterator() {} + explicit cons_iterator(nil const&) {} + }; + + template <> + struct cons_iterator > : nil_iterator + { + cons_iterator() {} + explicit cons_iterator(nil const&) {} + }; + + template <> + struct cons_iterator const> : nil_iterator + { + cons_iterator() {} + explicit cons_iterator(nil const&) {} + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/convert.hpp b/thirdparty/boost/fusion/container/list/convert.hpp new file mode 100644 index 0000000..61c371c --- /dev/null +++ b/thirdparty/boost/fusion/container/list/convert.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_09232005_1215) +#define FUSION_CONVERT_09232005_1215 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct as_list + { + typedef typename + detail::build_cons< + typename result_of::begin::type + , typename result_of::end::type + > + build_cons; + + typedef typename build_cons::type type; + + static type + call(Sequence& seq) + { + return build_cons::call(fusion::begin(seq), fusion::end(seq)); + } + }; + } + + template + inline typename result_of::as_list::type + as_list(Sequence& seq) + { + return result_of::as_list::call(seq); + } + + template + inline typename result_of::as_list::type + as_list(Sequence const& seq) + { + return result_of::as_list::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/at_impl.hpp b/thirdparty/boost/fusion/container/list/detail/at_impl.hpp new file mode 100644 index 0000000..593f01e --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/at_impl.hpp @@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_IMPL_07172005_0726) +#define FUSION_AT_IMPL_07172005_0726 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + typedef typename + mpl::eval_if< + is_const + , add_const + , mpl::identity + >::type + cdr_type; + + typedef typename + mpl::eval_if< + mpl::bool_ + , mpl::identity + , apply > + > + element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + template + static type + call(Cons& s, mpl::int_) + { + return call(s.cdr, mpl::int_()); + } + + template + static type + call(Cons& s, mpl::int_<0>) + { + return s.car; + } + + static type + call(Sequence& s) + { + return call(s, mpl::int_()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/begin_impl.hpp b/thirdparty/boost/fusion/container/list/detail/begin_impl.hpp new file mode 100644 index 0000000..2228d26 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/begin_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_07172005_0824) +#define FUSION_BEGIN_IMPL_07172005_0824 + +#include +#include + +namespace boost { namespace fusion +{ + struct nil; + + struct cons_tag; + + template + struct cons; + + template + struct cons_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef cons_iterator type; + + static type + call(Sequence& t) + { + return type(t); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/build_cons.hpp b/thirdparty/boost/fusion/container/list/detail/build_cons.hpp new file mode 100644 index 0000000..9abd1d9 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/build_cons.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BUILD_CONS_09232005_1222) +#define FUSION_BUILD_CONS_09232005_1222 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template < + typename First + , typename Last + , bool is_empty = result_of::equal_to::value> + struct build_cons; + + template + struct build_cons + { + typedef nil type; + + static nil + call(First const&, Last const&) + { + return nil(); + } + }; + + template + struct build_cons + { + typedef + build_cons::type, Last> + next_build_cons; + + typedef cons< + typename result_of::value_of::type + , typename next_build_cons::type> + type; + + static type + call(First const& f, Last const& l) + { + return type(*f, next_build_cons::call(fusion::next(f), l)); + } + }; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/convert_impl.hpp b/thirdparty/boost/fusion/container/list/detail/convert_impl.hpp new file mode 100644 index 0000000..332f15b --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/convert_impl.hpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_IMPL_09232005_1215) +#define FUSION_CONVERT_IMPL_09232005_1215 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_tag; + + namespace extension + { + template + struct convert_impl; + + template <> + struct convert_impl + { + template + struct apply + { + typedef typename + detail::build_cons< + typename result_of::begin::type + , typename result_of::end::type + > + build_cons; + + typedef typename build_cons::type type; + + static type + call(Sequence& seq) + { + return build_cons::call(fusion::begin(seq), fusion::end(seq)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/deref_impl.hpp b/thirdparty/boost/fusion/container/list/detail/deref_impl.hpp new file mode 100644 index 0000000..1ab9f98 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/deref_impl.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_07172005_0831) +#define FUSION_DEREF_IMPL_07172005_0831 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + { + template + struct apply + { + typedef typename Iterator::cons_type cons_type; + typedef typename cons_type::car_type value_type; + + typedef typename mpl::eval_if< + is_const + , add_reference::type> + , add_reference >::type + type; + + static type + call(Iterator const& i) + { + return i.cons.car; + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/container/list/detail/empty_impl.hpp b/thirdparty/boost/fusion/container/list/detail/empty_impl.hpp new file mode 100644 index 0000000..cf4f097 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/empty_impl.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_SEQUENCE_EMPTY_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_SEQUENCE_EMPTY_IMPL_HPP_INCLUDED + +#include + +namespace boost { namespace fusion +{ + struct cons_tag; + + struct nil; + + template + struct cons; + + namespace extension + { + template + struct empty_impl; + + template <> + struct empty_impl + { + template + struct apply + : boost::is_convertible + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/end_impl.hpp b/thirdparty/boost/fusion/container/list/detail/end_impl.hpp new file mode 100644 index 0000000..7059995 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/end_impl.hpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_07172005_0828) +#define FUSION_END_IMPL_07172005_0828 + +#include +#include + +namespace boost { namespace fusion +{ + struct nil; + + struct cons_tag; + + template + struct cons; + + template + struct cons_iterator; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef cons_iterator< + typename mpl::if_, nil const, nil>::type> + type; + + static type + call(Sequence& t) + { + return type(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/equal_to_impl.hpp b/thirdparty/boost/fusion/container/list/detail/equal_to_impl.hpp new file mode 100644 index 0000000..6f4dad1 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/equal_to_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_IMPL_09172005_1120) +#define FUSION_EQUAL_TO_IMPL_09172005_1120 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_iterator_tag; + + namespace extension + { + template + struct equal_to_impl; + + template <> + struct equal_to_impl + { + template + struct apply + : is_same< + typename I1::identity + , typename I2::identity + > + { + }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/list/detail/list_forward_ctor.hpp b/thirdparty/boost/fusion/container/list/detail/list_forward_ctor.hpp new file mode 100644 index 0000000..9fcee3d --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/list_forward_ctor.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_LIST_FORWARD_CTOR_07172005_0113) +#define FUSION_LIST_FORWARD_CTOR_07172005_0113 + +#include +#include +#include +#include +#include + +#define FUSION_LIST_CTOR_MAKE_CONS(z, n, type) tie_cons(BOOST_PP_CAT(_, n) +#define FUSION_LIST_CL_PAREN(z, n, type) ) + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE) +#include BOOST_PP_ITERATE() + +#undef FUSION_LIST_CTOR_MAKE_CONS +#undef FUSION_LIST_CL_PAREN + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + +#if N == 1 + explicit +#endif + list(BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : inherited_type(list_to_cons::call(BOOST_PP_ENUM_PARAMS(N, _))) + {} + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/list/detail/list_to_cons.hpp b/thirdparty/boost/fusion/container/list/detail/list_to_cons.hpp new file mode 100644 index 0000000..745d827 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/list_to_cons.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LIST_TO_CONS_07172005_1041) +#define FUSION_LIST_TO_CONS_07172005_1041 + +#include +#include +#include +#include +#include +#include + +#define FUSION_VOID(z, n, _) void_ + +namespace boost { namespace fusion +{ + struct nil; + struct void_; +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct list_to_cons + { + typedef T0 head_type; + typedef list_to_cons< + BOOST_PP_ENUM_SHIFTED_PARAMS(FUSION_MAX_LIST_SIZE, T), void_> + tail_list_to_cons; + typedef typename tail_list_to_cons::type tail_type; + + typedef cons type; + + #include + }; + + template <> + struct list_to_cons + { + typedef nil type; + }; +}}} + +#undef FUSION_VOID +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/list_to_cons_call.hpp b/thirdparty/boost/fusion/container/list/detail/list_to_cons_call.hpp new file mode 100644 index 0000000..9c59dd2 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/list_to_cons_call.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_LIST_TO_CONS_CALL_07192005_0138) +#define FUSION_LIST_TO_CONS_CALL_07192005_0138 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_LIST_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + static type + call(BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + { + return type(_0 +#if N > 1 + , tail_list_to_cons::call(BOOST_PP_ENUM_SHIFTED_PARAMS(N, _))); +#else + ); +#endif + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/list/detail/next_impl.hpp b/thirdparty/boost/fusion/container/list/detail/next_impl.hpp new file mode 100644 index 0000000..20acaa6 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/next_impl.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_07172005_0836) +#define FUSION_NEXT_IMPL_07172005_0836 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_iterator_tag; + + template + struct cons_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::cons_type cons_type; + typedef typename cons_type::cdr_type cdr_type; + + typedef cons_iterator< + typename mpl::eval_if< + is_const + , add_const + , mpl::identity + >::type> + type; + + static type + call(Iterator const& i) + { + return type(i.cons.cdr); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/container/list/detail/value_at_impl.hpp b/thirdparty/boost/fusion/container/list/detail/value_at_impl.hpp new file mode 100644 index 0000000..472a89d --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/value_at_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_IMPL_07172005_0952) +#define FUSION_VALUE_AT_IMPL_07172005_0952 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply + { + typedef typename + mpl::eval_if< + mpl::bool_ + , mpl::identity + , apply > + >::type + type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/detail/value_of_impl.hpp b/thirdparty/boost/fusion/container/list/detail/value_of_impl.hpp new file mode 100644 index 0000000..01a14e5 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/detail/value_of_impl.hpp @@ -0,0 +1,36 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2005 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_07172005_0838) +#define FUSION_VALUE_OF_IMPL_07172005_0838 + +namespace boost { namespace fusion +{ + struct cons_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename Iterator::cons_type cons_type; + typedef typename cons_type::car_type type; + }; + }; + } + +}} + +#endif + + diff --git a/thirdparty/boost/fusion/container/list/limits.hpp b/thirdparty/boost/fusion/container/list/limits.hpp new file mode 100644 index 0000000..c84cfdb --- /dev/null +++ b/thirdparty/boost/fusion/container/list/limits.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LIST_LIMITS_07172005_0112) +#define FUSION_LIST_LIMITS_07172005_0112 + +#if !defined(FUSION_MAX_LIST_SIZE) +# define FUSION_MAX_LIST_SIZE 10 +#else +# if FUSION_MAX_LIST_SIZE < 3 +# undef FUSION_MAX_LIST_SIZE +# define FUSION_MAX_LIST_SIZE 10 +# endif +#endif + +#endif diff --git a/thirdparty/boost/fusion/container/list/list.hpp b/thirdparty/boost/fusion/container/list/list.hpp new file mode 100644 index 0000000..fa5226c --- /dev/null +++ b/thirdparty/boost/fusion/container/list/list.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LIST_07172005_1153) +#define FUSION_LIST_07172005_1153 + +#include +#include + +namespace boost { namespace fusion +{ + struct nil; + struct void_; + + template + struct list + : detail::list_to_cons::type + { + private: + typedef + detail::list_to_cons + list_to_cons; + + public: + typedef typename list_to_cons::type inherited_type; + + list() + : inherited_type() {} + + template + list(list const& rhs) + : inherited_type(rhs) {} + + template + list(Sequence const& rhs) + : inherited_type(rhs) {} + + // Expand a couple of forwarding constructors for arguments + // of type (T0), (T0, T1), (T0, T1, T2) etc. Exanple: + // + // list( + // typename detail::call_param::type _0 + // , typename detail::call_param::type _1) + // : inherited_type(list_to_cons::call(_0, _1)) {} + #include + + template + list& + operator=(list const& rhs) + { + inherited_type::operator=(rhs); + return *this; + } + + template + list& + operator=(T const& rhs) + { + inherited_type::operator=(rhs); + return *this; + } + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/list/list_fwd.hpp b/thirdparty/boost/fusion/container/list/list_fwd.hpp new file mode 100644 index 0000000..283ba44 --- /dev/null +++ b/thirdparty/boost/fusion/container/list/list_fwd.hpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LIST_FORWARD_07172005_0224) +#define FUSION_LIST_FORWARD_07172005_0224 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_LIST_SIZE, typename T, void_) + > + struct list; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map.hpp b/thirdparty/boost/fusion/container/map.hpp new file mode 100644 index 0000000..120772d --- /dev/null +++ b/thirdparty/boost/fusion/container/map.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_CLASS_MAP_10022005_0606) +#define FUSION_SEQUENCE_CLASS_MAP_10022005_0606 + +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/map/convert.hpp b/thirdparty/boost/fusion/container/map/convert.hpp new file mode 100644 index 0000000..860512a --- /dev/null +++ b/thirdparty/boost/fusion/container/map/convert.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_09232005_1340) +#define FUSION_CONVERT_09232005_1340 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct as_map + { + typedef typename detail::as_map::value> gen; + typedef typename gen:: + template apply::type>::type + type; + }; + } + + template + inline typename result_of::as_map::type + as_map(Sequence& seq) + { + typedef typename result_of::as_map::gen gen; + return gen::call(fusion::begin(seq)); + } + + template + inline typename result_of::as_map::type + as_map(Sequence const& seq) + { + typedef typename result_of::as_map::gen gen; + return gen::call(fusion::begin(seq)); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/detail/as_map.hpp b/thirdparty/boost/fusion/container/map/detail/as_map.hpp new file mode 100644 index 0000000..e1a6d4c --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/as_map.hpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_AS_MAP_0932005_1339) +#define FUSION_AS_MAP_0932005_1339 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct as_map; + + template <> + struct as_map<0> + { + template + struct apply + { + typedef map<> type; + }; + + template + static typename apply::type + call(Iterator) + { + return map<>(); + } + }; + +#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::next::type \ + BOOST_PP_CAT(I, BOOST_PP_INC(n)); + +#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \ + typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \ + BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n)); + +#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::value_of::type \ + BOOST_PP_CAT(T, n); + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_MAP_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_NEXT_ITERATOR +#undef BOOST_FUSION_NEXT_CALL_ITERATOR +#undef BOOST_FUSION_VALUE_OF_ITERATOR + +}}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template <> + struct as_map + { + template + struct apply + { + BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _) + BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _) + typedef map type; + }; + + template + static typename apply::type + call(Iterator const& i0) + { + typedef apply gen; + typedef typename gen::type result; + BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _) + return result(BOOST_PP_ENUM_PARAMS(N, *i)); + } + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/map/detail/at_key_impl.hpp b/thirdparty/boost/fusion/container/map/detail/at_key_impl.hpp new file mode 100644 index 0000000..fba7d13 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/at_key_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_KEY_IMPL_05222005_0254) +#define FUSION_AT_KEY_IMPL_05222005_0254 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct map_tag; + + namespace extension + { + template + struct at_key_impl; + + template <> + struct at_key_impl + { + template + struct apply + { + typedef typename Sequence::template meta_at_impl element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& m) + { + return m.at_impl(mpl::identity()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/detail/begin_impl.hpp b/thirdparty/boost/fusion/container/map/detail/begin_impl.hpp new file mode 100644 index 0000000..f22483f --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/begin_impl.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_05222005_1108) +#define FUSION_BEGIN_IMPL_05222005_1108 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct map_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename + result_of::begin::type + iterator_type; + + typedef typename + result_of::begin::type + const_iterator_type; + + typedef typename + mpl::eval_if< + is_const + , mpl::identity + , mpl::identity + >::type + type; + + static type + call(Sequence& m) + { + return fusion::begin(m.get_data()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/detail/convert_impl.hpp b/thirdparty/boost/fusion/container/map/detail/convert_impl.hpp new file mode 100644 index 0000000..d6d5350 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/convert_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_IMPL_09232005_1340) +#define FUSION_CONVERT_IMPL_09232005_1340 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct map_tag; + + namespace extension + { + template + struct convert_impl; + + template <> + struct convert_impl + { + template + struct apply + { + typedef typename detail::as_map::value> gen; + typedef typename gen:: + template apply::type>::type + type; + + static type call(Sequence& seq) + { + return gen::call(fusion::begin(seq)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/detail/end_impl.hpp b/thirdparty/boost/fusion/container/map/detail/end_impl.hpp new file mode 100644 index 0000000..f95de62 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/end_impl.hpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_05222005_1108) +#define FUSION_END_IMPL_05222005_1108 + +#include + +namespace boost { namespace fusion +{ + struct map_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename + result_of::end::type + iterator_type; + + typedef typename + result_of::end::type + const_iterator_type; + + typedef typename + mpl::eval_if< + is_const + , mpl::identity + , mpl::identity + >::type + type; + + static type + call(Sequence& m) + { + return fusion::end(m.get_data()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/detail/lookup_key.hpp b/thirdparty/boost/fusion/container/map/detail/lookup_key.hpp new file mode 100644 index 0000000..1d30e21 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/lookup_key.hpp @@ -0,0 +1,99 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LOOKUP_KEY_07222005_1248) +#define FUSION_LOOKUP_KEY_07222005_1248 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct map_data_type + { + typedef typename + add_reference< + typename T::second_type + >::type + type; + }; + + template <> + struct map_data_type + { + typedef void_& type; + }; + + template + struct map_const_data_type + { + typedef typename + add_reference< + typename add_const< + typename T::second_type + >::type + >::type + type; + }; + + template <> + struct map_const_data_type + { + typedef void_ const& type; + }; + + template + struct map_value_type + { + typedef typename T::second_type type; + }; + + template <> + struct map_value_type + { + typedef void_ type; + }; + + template + struct map_key_type + { + typedef typename T::first_type type; + }; + + template + struct map_key_type + { + typedef unknown_key type; + }; + + template + struct map_lookup_key + { + static RT + call(Vector& vec) + { + return vec.at_impl(mpl::int_()).second; + } + }; + + template + struct map_lookup_key, Vector> + { + static void_& + call(Vector& vec); // intentionally undefined + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/container/map/detail/map_forward_ctor.hpp b/thirdparty/boost/fusion/container/map/detail/map_forward_ctor.hpp new file mode 100644 index 0000000..cea402f --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/map_forward_ctor.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAP_FORWARD_CTOR_07222005_0106) +#define FUSION_MAP_FORWARD_CTOR_07222005_0106 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_MAP_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + +#if N == 1 + explicit +#endif + map(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + : data(BOOST_PP_ENUM_PARAMS(N, _)) {} + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/map/detail/map_lookup.hpp b/thirdparty/boost/fusion/container/map/detail/map_lookup.hpp new file mode 100644 index 0000000..8372c14 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/map_lookup.hpp @@ -0,0 +1,128 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAP_LOOKUP_07212005_1118) +#define FUSION_MAP_LOOKUP_07212005_1118 + +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1310) +#pragma warning (push) +#pragma warning(disable: 4348) // redefinition of default parameter +#endif + + template + struct meta_at_impl + { + typedef void_ type; + }; + + template + struct meta_find_impl + { + typedef vector_iterator type; + }; + + template + struct meta_find_impl_const + { + typedef vector_iterator type; + }; + + template + vector_iterator + find_impl(mpl::identity) const + { + return vector_iterator(data); + } + + template + vector_iterator + find_impl(mpl::identity) + { + return vector_iterator(data); + } + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_DEC(FUSION_MAX_MAP_SIZE)) +#include BOOST_PP_ITERATE() + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1310) +#pragma warning (pop) +#endif + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template + struct meta_at_impl< + typename detail::map_key_type::type, dummy> + { + typedef typename detail::map_value_type::type type; + }; + + typename detail::map_data_type::type + at_impl(mpl::identity::type>) + { + return detail::map_lookup_key< + N + , typename detail::map_data_type::type + , typename detail::map_key_type::type + , storage_type>::call(data); + } + + typename detail::map_const_data_type::type + at_impl(mpl::identity::type>) const + { + return detail::map_lookup_key< + N + , typename detail::map_const_data_type::type + , typename detail::map_key_type::type + , storage_type const>::call(data); + } + + template + struct meta_find_impl< + typename detail::map_key_type::type, dummy> + { + typedef vector_iterator type; + }; + + template + struct meta_find_impl_const< + typename detail::map_key_type::type, dummy> + { + typedef vector_iterator type; + }; + + vector_iterator + find_impl(mpl::identity::type>) + { + return vector_iterator(data); + } + + vector_iterator + find_impl(mpl::identity::type>) const + { + return vector_iterator(data); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/map/detail/value_at_key_impl.hpp b/thirdparty/boost/fusion/container/map/detail/value_at_key_impl.hpp new file mode 100644 index 0000000..fa014ef --- /dev/null +++ b/thirdparty/boost/fusion/container/map/detail/value_at_key_impl.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_KEY_IMPL_05222005_0325) +#define FUSION_VALUE_AT_KEY_IMPL_05222005_0325 + +namespace boost { namespace fusion +{ + struct map_tag; + + namespace extension + { + template + struct value_at_key_impl; + + template <> + struct value_at_key_impl + { + template + struct apply + { + typedef typename Sequence:: + template meta_at_impl::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/limits.hpp b/thirdparty/boost/fusion/container/map/limits.hpp new file mode 100644 index 0000000..23d3e7f --- /dev/null +++ b/thirdparty/boost/fusion/container/map/limits.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MAP_LIMITS_07212005_1104) +#define FUSION_MAP_LIMITS_07212005_1104 + +#include + +#if !defined(FUSION_MAX_MAP_SIZE) +# define FUSION_MAX_MAP_SIZE FUSION_MAX_VECTOR_SIZE +#else +# if FUSION_MAX_MAP_SIZE < 3 +# undef FUSION_MAX_MAP_SIZE +# if (FUSION_MAX_VECTOR_SIZE > 10) +# define FUSION_MAX_MAP_SIZE 10 +# else +# define FUSION_MAX_MAP_SIZE FUSION_MAX_VECTOR_SIZE +# endif +# endif +#endif + +#endif diff --git a/thirdparty/boost/fusion/container/map/map.hpp b/thirdparty/boost/fusion/container/map/map.hpp new file mode 100644 index 0000000..1d22856 --- /dev/null +++ b/thirdparty/boost/fusion/container/map/map.hpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MAP_07212005_1106) +#define FUSION_MAP_07212005_1106 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + struct map_tag; + struct fusion_sequence_tag; + + template + struct map : sequence_base > + { + struct category : forward_traversal_tag, associative_sequence_tag {}; + + typedef map_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + + typedef vector< + BOOST_PP_ENUM_PARAMS(FUSION_MAX_MAP_SIZE, T)> + storage_type; + + typedef typename storage_type::size size; + + map() + : data() {} + + template + map(Sequence const& rhs) + : data(rhs) {} + + #include + #include + + template + map& + operator=(T const& rhs) + { + data = rhs; + return *this; + } + + storage_type& get_data() { return data; } + storage_type const& get_data() const { return data; } + + private: + + storage_type data; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/map/map_fwd.hpp b/thirdparty/boost/fusion/container/map/map_fwd.hpp new file mode 100644 index 0000000..6542a7e --- /dev/null +++ b/thirdparty/boost/fusion/container/map/map_fwd.hpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MAP_FORWARD_07212005_1105) +#define FUSION_MAP_FORWARD_07212005_1105 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_MAP_SIZE, typename T, void_) + > + struct map; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set.hpp b/thirdparty/boost/fusion/container/set.hpp new file mode 100644 index 0000000..b0620e3 --- /dev/null +++ b/thirdparty/boost/fusion/container/set.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_CLASS_SET_10022005_0607) +#define FUSION_SEQUENCE_CLASS_SET_10022005_0607 + +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/set/convert.hpp b/thirdparty/boost/fusion/container/set/convert.hpp new file mode 100644 index 0000000..d7da9e5 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/convert.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_09232005_1341) +#define FUSION_CONVERT_09232005_1341 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct as_set + { + typedef typename detail::as_set::value> gen; + typedef typename gen:: + template apply::type>::type + type; + }; + } + + template + inline typename result_of::as_set::type + as_set(Sequence& seq) + { + typedef typename result_of::as_set::gen gen; + return gen::call(fusion::begin(seq)); + } + + template + inline typename result_of::as_set::type + as_set(Sequence const& seq) + { + typedef typename result_of::as_set::gen gen; + return gen::call(fusion::begin(seq)); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/detail/as_set.hpp b/thirdparty/boost/fusion/container/set/detail/as_set.hpp new file mode 100644 index 0000000..536de9b --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/as_set.hpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_AS_SET_0932005_1341) +#define FUSION_AS_SET_0932005_1341 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct as_set; + + template <> + struct as_set<0> + { + template + struct apply + { + typedef set<> type; + }; + + template + static typename apply::type + call(Iterator) + { + return set<>(); + } + }; + +#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::next::type \ + BOOST_PP_CAT(I, BOOST_PP_INC(n)); + +#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \ + typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \ + BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n)); + +#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::value_of::type \ + BOOST_PP_CAT(T, n); + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_SET_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_NEXT_ITERATOR +#undef BOOST_FUSION_NEXT_CALL_ITERATOR +#undef BOOST_FUSION_VALUE_OF_ITERATOR + +}}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template <> + struct as_set + { + template + struct apply + { + BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _) + BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _) + typedef set type; + }; + + template + static typename apply::type + call(Iterator const& i0) + { + typedef apply gen; + typedef typename gen::type result; + BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _) + return result(BOOST_PP_ENUM_PARAMS(N, *i)); + } + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/set/detail/at_key_impl.hpp b/thirdparty/boost/fusion/container/set/detail/at_key_impl.hpp new file mode 100644 index 0000000..fd167a5 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/at_key_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_KEY_IMPL_09162005_1118) +#define FUSION_AT_KEY_IMPL_09162005_1118 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct set_tag; + + namespace extension + { + template + struct at_key_impl; + + template <> + struct at_key_impl + { + template + struct apply + { + typedef typename Sequence::template meta_at_impl element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& s) + { + return s.at_impl(mpl::identity()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/detail/begin_impl.hpp b/thirdparty/boost/fusion/container/set/detail/begin_impl.hpp new file mode 100644 index 0000000..7dece64 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/begin_impl.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_09162005_1120) +#define FUSION_BEGIN_IMPL_09162005_1120 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct set_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename + result_of::begin::type + iterator_type; + + typedef typename + result_of::begin::type + const_iterator_type; + + typedef typename + mpl::eval_if< + is_const + , mpl::identity + , mpl::identity + >::type + type; + + static type + call(Sequence& s) + { + return fusion::begin(s.get_data()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/detail/convert_impl.hpp b/thirdparty/boost/fusion/container/set/detail/convert_impl.hpp new file mode 100644 index 0000000..e77bd87 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/convert_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_IMPL_09232005_1341) +#define FUSION_CONVERT_IMPL_09232005_1341 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct set_tag; + + namespace extension + { + template + struct convert_impl; + + template <> + struct convert_impl + { + template + struct apply + { + typedef typename detail::as_set::value> gen; + typedef typename gen:: + template apply::type>::type + type; + + static type call(Sequence& seq) + { + return gen::call(fusion::begin(seq)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/detail/end_impl.hpp b/thirdparty/boost/fusion/container/set/detail/end_impl.hpp new file mode 100644 index 0000000..f01b4e4 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/end_impl.hpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_09162005_1121) +#define FUSION_END_IMPL_09162005_1121 + +#include + +namespace boost { namespace fusion +{ + struct set_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename + result_of::end::type + iterator_type; + + typedef typename + result_of::end::type + const_iterator_type; + + typedef typename + mpl::eval_if< + is_const + , mpl::identity + , mpl::identity + >::type + type; + + static type + call(Sequence& s) + { + return fusion::end(s.get_data()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/detail/lookup_key.hpp b/thirdparty/boost/fusion/container/set/detail/lookup_key.hpp new file mode 100644 index 0000000..2af31ee --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/lookup_key.hpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LOOKUP_KEY_09162005_1111) +#define FUSION_LOOKUP_KEY_09162005_1111 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct set_data_type + { + typedef typename add_reference::type type; + }; + + template <> + struct set_data_type + { + typedef void_& type; + }; + + template + struct set_const_data_type + { + typedef typename + add_reference< + typename add_const::type + >::type + type; + }; + + template <> + struct set_const_data_type + { + typedef void_ const& type; + }; + + template + struct set_value_type + { + typedef T type; + }; + + template <> + struct set_value_type + { + typedef void_ type; + }; + + template + struct set_key_type + { + typedef T type; + }; + + template + struct set_key_type + { + typedef unknown_key type; + }; + + template + struct set_lookup_key + { + static RT + call(Vector& vec) + { + return vec.at_impl(mpl::int_()); + } + }; + + template + struct set_lookup_key, Vector> + { + static void_& + call(Vector& vec); // intentionally undefined + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/container/set/detail/set_forward_ctor.hpp b/thirdparty/boost/fusion/container/set/detail/set_forward_ctor.hpp new file mode 100644 index 0000000..80b2207 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/set_forward_ctor.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_SET_FORWARD_CTOR_09162005_1115) +#define FUSION_SET_FORWARD_CTOR_09162005_1115 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_SET_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + +#if N == 1 + explicit +#endif + set(BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : data(BOOST_PP_ENUM_PARAMS(N, _)) {} + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/set/detail/set_lookup.hpp b/thirdparty/boost/fusion/container/set/detail/set_lookup.hpp new file mode 100644 index 0000000..59e9a77 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/set_lookup.hpp @@ -0,0 +1,128 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_SET_LOOKUP_09162005_1116) +#define FUSION_SET_LOOKUP_09162005_1116 + +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1310) +#pragma warning (push) +#pragma warning(disable: 4348) // redefinition of default parameter +#endif + + template + struct meta_at_impl + { + typedef void_ type; + }; + + template + struct meta_find_impl + { + typedef vector_iterator type; + }; + + template + struct meta_find_impl_const + { + typedef vector_iterator type; + }; + + template + vector_iterator + find_impl(mpl::identity) const + { + return vector_iterator(data); + } + + template + vector_iterator + find_impl(mpl::identity) + { + return vector_iterator(data); + } + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_DEC(FUSION_MAX_SET_SIZE)) +#include BOOST_PP_ITERATE() + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1310) +#pragma warning (pop) +#endif + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template + struct meta_at_impl< + typename detail::set_key_type::type, dummy> + { + typedef typename detail::set_value_type::type type; + }; + + typename detail::set_data_type::type + at_impl(mpl::identity::type>) + { + return detail::set_lookup_key< + N + , typename detail::set_data_type::type + , typename detail::set_key_type::type + , storage_type>::call(data); + } + + typename detail::set_const_data_type::type + at_impl(mpl::identity::type>) const + { + return detail::set_lookup_key< + N + , typename detail::set_const_data_type::type + , typename detail::set_key_type::type + , storage_type const>::call(data); + } + + template + struct meta_find_impl< + typename detail::set_key_type::type, dummy> + { + typedef vector_iterator type; + }; + + template + struct meta_find_impl_const< + typename detail::set_key_type::type, dummy> + { + typedef vector_iterator type; + }; + + vector_iterator + find_impl(mpl::identity::type>) + { + return vector_iterator(data); + } + + vector_iterator + find_impl(mpl::identity::type>) const + { + return vector_iterator(data); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/set/detail/value_at_key_impl.hpp b/thirdparty/boost/fusion/container/set/detail/value_at_key_impl.hpp new file mode 100644 index 0000000..4fbd726 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/detail/value_at_key_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_KEY_IMPL_09162005_1123) +#define FUSION_VALUE_AT_KEY_IMPL_09162005_1123 + +#include + +namespace boost { namespace fusion +{ + struct set_tag; + + namespace extension + { + template + struct value_at_key_impl; + + template <> + struct value_at_key_impl + { + template + struct apply + { + typedef typename Sequence:: + template meta_at_impl::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/limits.hpp b/thirdparty/boost/fusion/container/set/limits.hpp new file mode 100644 index 0000000..7bc590a --- /dev/null +++ b/thirdparty/boost/fusion/container/set/limits.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SET_LIMITS_09162005_1103) +#define FUSION_SET_LIMITS_09162005_1103 + +#include + +#if !defined(FUSION_MAX_SET_SIZE) +# define FUSION_MAX_SET_SIZE FUSION_MAX_VECTOR_SIZE +#else +# if FUSION_MAX_SET_SIZE < 3 +# undef FUSION_MAX_SET_SIZE +# if (FUSION_MAX_VECTOR_SIZE > 10) +# define FUSION_MAX_SET_SIZE 10 +# else +# define FUSION_MAX_SET_SIZE FUSION_MAX_VECTOR_SIZE +# endif +# endif +#endif + +#endif diff --git a/thirdparty/boost/fusion/container/set/set.hpp b/thirdparty/boost/fusion/container/set/set.hpp new file mode 100644 index 0000000..08e5bf1 --- /dev/null +++ b/thirdparty/boost/fusion/container/set/set.hpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SET_09162005_1104) +#define FUSION_SET_09162005_1104 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + struct set_tag; + struct fusion_sequence_tag; + + template + struct set : sequence_base > + { + struct category : forward_traversal_tag, associative_sequence_tag {}; + + typedef set_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + + typedef vector< + BOOST_PP_ENUM_PARAMS(FUSION_MAX_SET_SIZE, T)> + storage_type; + + typedef typename storage_type::size size; + + set() + : data() {} + + template + set(Sequence const& rhs) + : data(rhs) {} + + #include + #include + + template + set& + operator=(T const& rhs) + { + data = rhs; + return *this; + } + + storage_type& get_data() { return data; } + storage_type const& get_data() const { return data; } + + private: + + storage_type data; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/set/set_fwd.hpp b/thirdparty/boost/fusion/container/set/set_fwd.hpp new file mode 100644 index 0000000..522dd6c --- /dev/null +++ b/thirdparty/boost/fusion/container/set/set_fwd.hpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SET_FORWARD_09162005_1102) +#define FUSION_SET_FORWARD_09162005_1102 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_SET_SIZE, typename T, void_) + > + struct set; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector.hpp b/thirdparty/boost/fusion/container/vector.hpp new file mode 100644 index 0000000..9755786 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_CLASS_VECTOR_10022005_0602) +#define FUSION_SEQUENCE_CLASS_VECTOR_10022005_0602 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/container/vector/convert.hpp b/thirdparty/boost/fusion/container/vector/convert.hpp new file mode 100644 index 0000000..8a49d5d --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/convert.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_09222005_1104) +#define FUSION_CONVERT_09222005_1104 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template + struct as_vector + { + typedef typename detail::as_vector::value> gen; + typedef typename gen:: + template apply::type>::type + type; + }; + } + + template + inline typename result_of::as_vector::type + as_vector(Sequence& seq) + { + typedef typename result_of::as_vector::gen gen; + return gen::call(fusion::begin(seq)); + } + + template + inline typename result_of::as_vector::type + as_vector(Sequence const& seq) + { + typedef typename result_of::as_vector::gen gen; + return gen::call(fusion::begin(seq)); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/advance_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/advance_impl.hpp new file mode 100644 index 0000000..348d6b0 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/advance_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_IMPL_09172005_1156) +#define FUSION_ADVANCE_IMPL_09172005_1156 + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + + template + struct vector_iterator; + + namespace extension + { + template + struct advance_impl; + + template <> + struct advance_impl + { + template + struct apply + { + typedef typename Iterator::index index; + typedef typename Iterator::vector vector; + typedef vector_iterator type; + + static type + call(Iterator const& i) + { + return type(i.vec); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/as_vector.hpp b/thirdparty/boost/fusion/container/vector/detail/as_vector.hpp new file mode 100644 index 0000000..8def5eb --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/as_vector.hpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_AS_VECTOR_09222005_0950) +#define FUSION_AS_VECTOR_09222005_0950 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct as_vector; + + template <> + struct as_vector<0> + { + template + struct apply + { + typedef vector<> type; + }; + + template + static typename apply::type + call(Iterator) + { + return vector<>(); + } + }; + +#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::next::type \ + BOOST_PP_CAT(I, BOOST_PP_INC(n)); + +#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \ + typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \ + BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n)); + +#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \ + typedef typename fusion::result_of::value_of::type \ + BOOST_PP_CAT(T, n); + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_NEXT_ITERATOR +#undef BOOST_FUSION_NEXT_CALL_ITERATOR +#undef BOOST_FUSION_VALUE_OF_ITERATOR + +}}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template <> + struct as_vector + { + template + struct apply + { + BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _) + BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _) + typedef vector type; + }; + + template + static typename apply::type + call(Iterator const& i0) + { + typedef apply gen; + typedef typename gen::type result; + BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_FUSION_NEXT_CALL_ITERATOR, _) + return result(BOOST_PP_ENUM_PARAMS(N, *i)); + } + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/vector/detail/at_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/at_impl.hpp new file mode 100644 index 0000000..4c47368 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/at_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_IMPL_05042005_0741) +#define FUSION_AT_IMPL_05042005_0741 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + typedef mpl::at element; + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& v) + { + return v.at_impl(N()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/begin_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/begin_impl.hpp new file mode 100644 index 0000000..5d397e4 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/begin_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_05042005_1136) +#define FUSION_BEGIN_IMPL_05042005_1136 + +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef vector_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/convert_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/convert_impl.hpp new file mode 100644 index 0000000..7a29baf --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/convert_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_IMPL_09222005_1104) +#define FUSION_CONVERT_IMPL_09222005_1104 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace extension + { + template + struct convert_impl; + + template <> + struct convert_impl + { + template + struct apply + { + typedef typename detail::as_vector::value> gen; + typedef typename gen:: + template apply::type>::type + type; + + static type call(Sequence& seq) + { + return gen::call(fusion::begin(seq)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/deref_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/deref_impl.hpp new file mode 100644 index 0000000..d88f255 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/deref_impl.hpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_05042005_1037) +#define FUSION_DEREF_IMPL_05042005_1037 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + { + template + struct apply + { + typedef typename Iterator::vector vector; + typedef typename Iterator::index index; + typedef typename mpl::at< + typename vector::types, index> + element; + + typedef typename + mpl::eval_if< + is_const + , fusion::detail::cref_result + , fusion::detail::ref_result + >::type + type; + + static type + call(Iterator const& i) + { + return i.vec.at_impl(index()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/distance_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/distance_impl.hpp new file mode 100644 index 0000000..c61d6c6 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/distance_impl.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_IMPL_09172005_0751) +#define FUSION_DISTANCE_IMPL_09172005_0751 + +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + + namespace extension + { + template + struct distance_impl; + + template <> + struct distance_impl + { + template + struct apply : mpl::minus + { + static typename mpl::minus< + typename Last::index, typename First::index>::type + call(First const&, Last const&) + { + typedef typename mpl::minus< + typename Last::index, typename First::index>::type + result; + return result(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/end_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/end_impl.hpp new file mode 100644 index 0000000..9d5f864 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/end_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_05042005_1142) +#define FUSION_END_IMPL_05042005_1142 + +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::size size; + typedef vector_iterator type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/equal_to_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/equal_to_impl.hpp new file mode 100644 index 0000000..612751b --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/equal_to_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_IMPL_05052005_1215) +#define FUSION_EQUAL_TO_IMPL_05052005_1215 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + + namespace extension + { + template + struct equal_to_impl; + + template <> + struct equal_to_impl + { + template + struct apply + : is_same< + typename I1::identity + , typename I2::identity + > + { + }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/detail/next_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/next_impl.hpp new file mode 100644 index 0000000..8ab794c --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/next_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_05042005_1058) +#define FUSION_NEXT_IMPL_05042005_1058 + +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + template + struct vector_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::vector vector; + typedef typename Iterator::index index; + typedef vector_iterator type; + + static type + call(Iterator const& i) + { + return type(i.vec); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/prior_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/prior_impl.hpp new file mode 100644 index 0000000..4251b51 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/prior_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PRIOR_IMPL_05042005_1145) +#define FUSION_PRIOR_IMPL_05042005_1145 + +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + template + struct vector_iterator; + + namespace extension + { + template + struct prior_impl; + + template <> + struct prior_impl + { + template + struct apply + { + typedef typename Iterator::vector vector; + typedef typename Iterator::index index; + typedef vector_iterator type; + + static type + call(Iterator const& i) + { + return type(i.vec); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/value_at_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/value_at_impl.hpp new file mode 100644 index 0000000..9c6b894 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/value_at_impl.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_IMPL_05052005_0232) +#define FUSION_VALUE_AT_IMPL_05052005_0232 + +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply + { + typedef typename mpl::at::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/value_of_impl.hpp b/thirdparty/boost/fusion/container/vector/detail/value_of_impl.hpp new file mode 100644 index 0000000..4b6613b --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/value_of_impl.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_05052005_1128) +#define FUSION_VALUE_OF_IMPL_05052005_1128 + +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename Iterator::vector vector; + typedef typename Iterator::index index; + typedef typename mpl::at< + typename vector::types, index>::type + type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/detail/vector_forward_ctor.hpp b/thirdparty/boost/fusion/container/vector/detail/vector_forward_ctor.hpp new file mode 100644 index 0000000..d5c8b3c --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/vector_forward_ctor.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_VECTOR_FORWARD_CTOR_07122005_1123) +#define FUSION_VECTOR_FORWARD_CTOR_07122005_1123 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + +#if N == 1 + explicit +#endif + vector(BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : vec(BOOST_PP_ENUM_PARAMS(N, _)) {} + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/container/vector/detail/vector_n.hpp b/thirdparty/boost/fusion/container/vector/detail/vector_n.hpp new file mode 100644 index 0000000..9a12966 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/vector_n.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +// No include guard. This file is meant to be included many times + +#if !defined(FUSION_MACRO_05042005) +#define FUSION_MACRO_05042005 + +#define FUSION_MEMBER_DEFAULT_INIT(z, n, _) m##n(T##n()) +#define FUSION_MEMBER_INIT(z, n, _) m##n(_##n) +#define FUSION_COPY_INIT(z, n, _) m##n(other.m##n) +#define FUSION_MEMBER_DECL(z, n, _) T##n m##n; + +#define FUSION_MEMBER_ASSIGN(z, n, _) \ + this->BOOST_PP_CAT(m, n) = vec.BOOST_PP_CAT(m, n); + +#define FUSION_DEREF_MEMBER_ASSIGN(z, n, _) \ + this->BOOST_PP_CAT(m, n) = *BOOST_PP_CAT(i, n); + +#define FUSION_AT_IMPL(z, n, _) \ + typename add_reference::type \ + at_impl(mpl::int_) { return this->m##n; } \ + typename add_reference::type>::type \ + at_impl(mpl::int_) const { return this->m##n; } + +#define FUSION_ITER_DECL_VAR(z, n, _) \ + typedef typename result_of::next< \ + BOOST_PP_CAT(I, BOOST_PP_DEC(n))>::type BOOST_PP_CAT(I, n); \ + BOOST_PP_CAT(I, n) BOOST_PP_CAT(i, n) \ + = fusion::next(BOOST_PP_CAT(i, BOOST_PP_DEC(n))); + +#endif + +#define N BOOST_PP_ITERATION() + + template + struct BOOST_PP_CAT(vector_data, N) : sequence_base + { + BOOST_PP_CAT(vector_data, N)() + : BOOST_PP_ENUM(N, FUSION_MEMBER_DEFAULT_INIT, _) {} + + BOOST_PP_CAT(vector_data, N)( + BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : BOOST_PP_ENUM(N, FUSION_MEMBER_INIT, _) {} + + BOOST_PP_CAT(vector_data, N)( + BOOST_PP_CAT(vector_data, N) const& other) + : BOOST_PP_ENUM(N, FUSION_COPY_INIT, _) {} + + BOOST_PP_CAT(vector_data, N)& + operator=(BOOST_PP_CAT(vector_data, N) const& vec) + { + BOOST_PP_REPEAT(N, FUSION_MEMBER_ASSIGN, _) + return *this; + } + + template + static BOOST_PP_CAT(vector_data, N) + init_from_sequence(Sequence const& seq) + { + typedef typename result_of::begin::type I0; + I0 i0 = fusion::begin(seq); + BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_ITER_DECL_VAR, _) + return BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_PARAMS(N, *i)); + } + + BOOST_PP_REPEAT(N, FUSION_MEMBER_DECL, _) + }; + + template + struct BOOST_PP_CAT(vector, N) + : BOOST_PP_CAT(vector_data, N)< + BOOST_PP_CAT(vector, N) + , BOOST_PP_ENUM_PARAMS(N, T)> + { + typedef BOOST_PP_CAT(vector, N) this_type; + typedef BOOST_PP_CAT(vector_data, N) base_type; + typedef mpl::BOOST_PP_CAT(vector, N) types; + typedef vector_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + typedef random_access_traversal_tag category; + typedef mpl::int_ size; + + BOOST_PP_CAT(vector, N)() {} + +#if (N == 1) + explicit +#endif + BOOST_PP_CAT(vector, N)( + BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {} + + template + BOOST_PP_CAT(vector, N)( + BOOST_PP_CAT(vector, N) const& vec) + : base_type(BOOST_PP_ENUM_PARAMS(N, vec.m)) {} + + template + BOOST_PP_CAT(vector, N)( + Sequence const& seq +#if (N == 1) + , typename disable_if >::type* dummy = 0 +#endif + ) + : base_type(base_type::init_from_sequence(seq)) {} + + template + BOOST_PP_CAT(vector, N)& + operator=(BOOST_PP_CAT(vector, N) const& vec) + { + BOOST_PP_REPEAT(N, FUSION_MEMBER_ASSIGN, _) + return *this; + } + + template + typename disable_if, this_type&>::type + operator=(Sequence const& seq) + { + typedef typename result_of::begin::type I0; + I0 i0 = fusion::begin(seq); + BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_ITER_DECL_VAR, _) + BOOST_PP_REPEAT(N, FUSION_DEREF_MEMBER_ASSIGN, _) + return *this; + } + + BOOST_PP_REPEAT(N, FUSION_AT_IMPL, _) + + template + typename add_reference::type>::type + at_impl(I i) + { + return this->at_impl(mpl::int_()); + } + + template + typename add_reference::type>::type>::type + at_impl(I i) const + { + return this->at_impl(mpl::int_()); + } + }; + +#undef N + diff --git a/thirdparty/boost/fusion/container/vector/detail/vector_n_chooser.hpp b/thirdparty/boost/fusion/container/vector/detail/vector_n_chooser.hpp new file mode 100644 index 0000000..66691fb --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/detail/vector_n_chooser.hpp @@ -0,0 +1,99 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_VECTOR_N_CHOOSER_07072005_1248) +#define FUSION_VECTOR_N_CHOOSER_07072005_1248 + +#include + +// include vector0..N where N is FUSION_MAX_VECTOR_SIZE +#include +#if (FUSION_MAX_VECTOR_SIZE > 10) +#include +#endif +#if (FUSION_MAX_VECTOR_SIZE > 20) +#include +#endif +#if (FUSION_MAX_VECTOR_SIZE > 30) +#include +#endif +#if (FUSION_MAX_VECTOR_SIZE > 40) +#include +#endif + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct get_vector_n; + + template <> + struct get_vector_n<0> + { + template + struct call + { + typedef vector0 type; + }; + }; + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + + template + struct vector_n_chooser + { + typedef + mpl::BOOST_PP_CAT(vector, FUSION_MAX_VECTOR_SIZE) + + input; + + typedef typename mpl::begin::type begin; + typedef typename mpl::find::type end; + typedef typename mpl::distance::type size; + + typedef typename get_vector_n::template + call::type + type; + }; +}}} + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#else // defined(BOOST_PP_IS_ITERATING) + +#define N BOOST_PP_ITERATION() + + template <> + struct get_vector_n + { + template + struct call + { + typedef BOOST_PP_CAT(vector, N) type; + }; + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) diff --git a/thirdparty/boost/fusion/container/vector/limits.hpp b/thirdparty/boost/fusion/container/vector/limits.hpp new file mode 100644 index 0000000..be00c65 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/limits.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR_LIMITS_07072005_1246) +#define FUSION_VECTOR_LIMITS_07072005_1246 + +#if !defined(FUSION_MAX_VECTOR_SIZE) +# define FUSION_MAX_VECTOR_SIZE 10 +#else +# if FUSION_MAX_VECTOR_SIZE < 3 +# undef FUSION_MAX_VECTOR_SIZE +# define FUSION_MAX_VECTOR_SIZE 10 +# endif +#endif + +#endif diff --git a/thirdparty/boost/fusion/container/vector/vector.hpp b/thirdparty/boost/fusion/container/vector/vector.hpp new file mode 100644 index 0000000..6e13367 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector.hpp @@ -0,0 +1,151 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR_07072005_1244) +#define FUSION_VECTOR_07072005_1244 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + struct fusion_sequence_tag; + + template + struct vector + : sequence_base > + { + private: + + typedef typename detail::vector_n_chooser< + BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>::type + vector_n; + + template + friend struct vector; + + public: + + typedef typename vector_n::types types; + typedef typename vector_n::fusion_tag fusion_tag; + typedef typename vector_n::tag tag; + typedef typename vector_n::size size; + typedef typename vector_n::category category; + typedef typename vector_n::is_view is_view; + + vector() + : vec() {} + + template + vector(vector const& rhs) + : vec(rhs.vec) {} + + vector(vector const& rhs) + : vec(rhs.vec) {} + + template + vector(Sequence const& rhs) +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) + : vec(ctor_helper(rhs, is_base_of())) {} +#else + : vec(rhs) {} +#endif + + // Expand a couple of forwarding constructors for arguments + // of type (T0), (T0, T1), (T0, T1, T2) etc. Example: + // + // vector( + // typename detail::call_param::type _0 + // , typename detail::call_param::type _1) + // : vec(_0, _1) {} + #include + + template + vector& + operator=(vector const& rhs) + { + vec = rhs.vec; + return *this; + } + + template + vector& + operator=(T const& rhs) + { + vec = rhs; + return *this; + } + + template + typename add_reference< + typename mpl::at_c::type + >::type + at_impl(mpl::int_ index) + { + return vec.at_impl(index); + } + + template + typename add_reference< + typename add_const< + typename mpl::at_c::type + >::type + >::type + at_impl(mpl::int_ index) const + { + return vec.at_impl(index); + } + + template + typename add_reference< + typename mpl::at::type + >::type + at_impl(I index) + { + return vec.at_impl(mpl::int_()); + } + + template + typename add_reference< + typename add_const< + typename mpl::at::type + >::type + >::type + at_impl(I index) const + { + return vec.at_impl(mpl::int_()); + } + + private: + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) + static vector_n const& + ctor_helper(vector const& rhs, mpl::true_) + { + return rhs.vec; + } + + template + static T const& + ctor_helper(T const& rhs, mpl::false_) + { + return rhs; + } +#endif + + vector_n vec; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/vector10.hpp b/thirdparty/boost/fusion/container/vector/vector10.hpp new file mode 100644 index 0000000..f2a8426 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector10.hpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR10_05042005_0257) +#define FUSION_VECTOR10_05042005_0257 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct fusion_sequence_tag; + struct random_access_traversal_tag; + + struct vector0 : sequence_base + { + typedef mpl::vector0<> types; + typedef vector_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + typedef random_access_traversal_tag category; + typedef mpl::int_<0> size; + + vector0() {} + + template + vector0(Sequence const& seq) + {} + }; + +// expand vector1 to vector10 +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, 10) +#include BOOST_PP_ITERATE() + +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/vector20.hpp b/thirdparty/boost/fusion/container/vector/vector20.hpp new file mode 100644 index 0000000..816d1be --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector20.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR20_05052005_0205) +#define FUSION_VECTOR20_05052005_0205 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct fusion_sequence_tag; + struct random_access_traversal_tag; + +// expand vector11 to vector20 +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (11, 20) +#include BOOST_PP_ITERATE() + +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/vector30.hpp b/thirdparty/boost/fusion/container/vector/vector30.hpp new file mode 100644 index 0000000..02a40c2 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector30.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR30_05052005_0206) +#define FUSION_VECTOR30_05052005_0206 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct fusion_sequence_tag; + struct random_access_traversal_tag; + +// expand vector21 to vector30 +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (21, 30) +#include BOOST_PP_ITERATE() + +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/vector40.hpp b/thirdparty/boost/fusion/container/vector/vector40.hpp new file mode 100644 index 0000000..5b6d7d5 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector40.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR40_05052005_0208) +#define FUSION_VECTOR40_05052005_0208 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct fusion_sequence_tag; + struct random_access_traversal_tag; + +// expand vector31 to vector40 +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (31, 40) +#include BOOST_PP_ITERATE() + +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/vector50.hpp b/thirdparty/boost/fusion/container/vector/vector50.hpp new file mode 100644 index 0000000..f1387db --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector50.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR50_05052005_0207) +#define FUSION_VECTOR50_05052005_0207 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct fusion_sequence_tag; + struct random_access_traversal_tag; + +// expand vector41 to vector50 +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (41, 50) +#include BOOST_PP_ITERATE() + +}} + +#endif + diff --git a/thirdparty/boost/fusion/container/vector/vector_fwd.hpp b/thirdparty/boost/fusion/container/vector/vector_fwd.hpp new file mode 100644 index 0000000..7c396cb --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector_fwd.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR_FORWARD_07072005_0125) +#define FUSION_VECTOR_FORWARD_07072005_0125 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename T, void_) + > + struct vector; +}} + +#endif diff --git a/thirdparty/boost/fusion/container/vector/vector_iterator.hpp b/thirdparty/boost/fusion/container/vector/vector_iterator.hpp new file mode 100644 index 0000000..5cc9f26 --- /dev/null +++ b/thirdparty/boost/fusion/container/vector/vector_iterator.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VECTOR_ITERATOR_05042005_0635) +#define FUSION_VECTOR_ITERATOR_05042005_0635 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_iterator_tag; + struct random_access_traversal_tag; + + template + struct vector_iterator_identity; + + template + struct vector_iterator : iterator_base > + { + typedef mpl::int_ index; + typedef Vector vector; + typedef vector_iterator_tag fusion_tag; + typedef random_access_traversal_tag category; + typedef vector_iterator_identity< + typename add_const::type, N> identity; + + vector_iterator(Vector& vec) + : vec(vec) {} + Vector& vec; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/functional.hpp b/thirdparty/boost/fusion/functional.hpp new file mode 100644 index 0000000..e0457e9 --- /dev/null +++ b/thirdparty/boost/fusion/functional.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_HPP_INCLUDED + +#include +#include +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter.hpp b/thirdparty/boost/fusion/functional/adapter.hpp new file mode 100644 index 0000000..8c377f3 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_HPP_INCLUDED +#include +#include +#include +#include +#include +#include +#include +#endif diff --git a/thirdparty/boost/fusion/functional/adapter/detail/access.hpp b/thirdparty/boost/fusion/functional/adapter/detail/access.hpp new file mode 100644 index 0000000..bc8898e --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/detail/access.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_DETAIL_ACCESS_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_DETAIL_ACCESS_HPP_INCLUDED + +namespace boost { namespace fusion { namespace detail +{ + // const reference deduction for function templates that accept T const & + template struct cref { typedef T const& type; }; + template struct cref { typedef T const& type; }; + template struct cref { typedef T const& type; }; + + // mutable reference deduction for function templates that accept T & + template struct mref { typedef T & type; }; + template struct mref { typedef T & type; }; + + // generic reference deduction for function templates that are overloaded + // to accept both T const & and T & + template struct gref { typedef T const& type; }; + template struct gref { typedef T & type; }; + template struct gref { typedef T const& type; }; + + // appropriately qualified target function in const context + template struct qf_c { typedef T const type; }; + template struct qf_c { typedef T const type; }; + template struct qf_c { typedef T type; }; + + // appropriately qualified target function in non-const context + template struct qf { typedef T type; }; + template struct qf { typedef T const type; }; + template struct qf { typedef T type; }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/detail/pow2_explode.hpp b/thirdparty/boost/fusion/functional/adapter/detail/pow2_explode.hpp new file mode 100644 index 0000000..2e5b8cf --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/detail/pow2_explode.hpp @@ -0,0 +1,118 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_PP_IS_ITERATING) +# error "This file has to be included by a preprocessor loop construct!" +#elif BOOST_PP_ITERATION_DEPTH() == 1 + +# if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_DETAIL_POW2_EXPLODE_HPP_INCLUDED) +# include +# include +# include +# define BOOST_FUSION_FUNCTIONAL_ADAPTER_DETAIL_POW2_EXPLODE_HPP_INCLUDED +# endif + +# define BOOST_PP_VALUE 0 +# include BOOST_PP_ASSIGN_SLOT(1) + +# define BOOST_PP_FILENAME_2 \ + +# define BOOST_PP_VALUE (1 << N) >> 4 +# if BOOST_PP_VALUE > BOOST_PP_LIMIT_ITERATION +# error "Preprocessor limit exceeded." +# endif + +# include BOOST_PP_ASSIGN_SLOT(2) +# define BOOST_PP_ITERATION_LIMITS (0,BOOST_PP_DEC(BOOST_PP_SLOT_2())) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 + +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# if BOOST_PP_SLOT_1() < 1 << N +# include BOOST_PP_INDIRECT_SELF +# define BOOST_PP_VALUE BOOST_PP_SLOT_1() + 1 +# include BOOST_PP_ASSIGN_SLOT(1) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/detail/pt_def.hpp b/thirdparty/boost/fusion/functional/adapter/detail/pt_def.hpp new file mode 100644 index 0000000..11cc40f --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/detail/pt_def.hpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +// No include guard - this file is included multiple times intentionally. + +#if BOOST_PP_SLOT_1() & 0x001 +# define PT0 T0 & +#else +# define PT0 T0 const & +#endif +#if BOOST_PP_SLOT_1() & 0x002 +# define PT1 T1 & +#else +# define PT1 T1 const & +#endif +#if BOOST_PP_SLOT_1() & 0x004 +# define PT2 T2 & +#else +# define PT2 T2 const & +#endif +#if BOOST_PP_SLOT_1() & 0x008 +# define PT3 T3 & +#else +# define PT3 T3 const & +#endif +#if BOOST_PP_SLOT_1() & 0x010 +# define PT4 T4 & +#else +# define PT4 T4 const & +#endif +#if BOOST_PP_SLOT_1() & 0x020 +# define PT5 T5 & +#else +# define PT5 T5 const & +#endif +#if BOOST_PP_SLOT_1() & 0x040 +# define PT6 T6 & +#else +# define PT6 T6 const & +#endif +#if BOOST_PP_SLOT_1() & 0x080 +# define PT7 T7 & +#else +# define PT7 T7 const & +#endif +#if BOOST_PP_SLOT_1() & 0x100 +# define PT8 T8 & +#else +# define PT8 T8 const & +#endif +#if BOOST_PP_SLOT_1() & 0x200 +# define PT9 T9 & +#else +# define PT9 T9 const & +#endif +#if BOOST_PP_SLOT_1() & 0x400 +# define PT10 T10 & +#else +# define PT10 T10 const & +#endif +#if BOOST_PP_SLOT_1() & 0x800 +# define PT11 T11 & +#else +# define PT11 T11 const & +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/detail/pt_undef.hpp b/thirdparty/boost/fusion/functional/adapter/detail/pt_undef.hpp new file mode 100644 index 0000000..c239723 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/detail/pt_undef.hpp @@ -0,0 +1,23 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +// No include guard - this file is included multiple times intentionally. + +#undef PT0 +#undef PT1 +#undef PT2 +#undef PT3 +#undef PT4 +#undef PT5 +#undef PT6 +#undef PT7 +#undef PT8 +#undef PT9 +#undef PT10 +#undef PT11 + diff --git a/thirdparty/boost/fusion/functional/adapter/fused.hpp b/thirdparty/boost/fusion/functional/adapter/fused.hpp new file mode 100644 index 0000000..86ae64b --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/fused.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_HPP_INCLUDED + +#include + +#include +#include + +namespace boost { namespace fusion +{ + template class fused; + + //----- ---- --- -- - - - - + + template + class fused + { + Function fnc_transformed; + + typedef typename detail::qf_c::type & func_const_fwd_t; + typedef typename detail::qf::type & func_fwd_t; + + public: + + inline explicit fused(func_const_fwd_t f = Function()) + : fnc_transformed(f) + { } + + template + inline typename result_of::invoke::type + operator()(Seq const & s) const + { + return fusion::invoke(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke::type + operator()(Seq const & s) + { + return fusion::invoke(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke::type + operator()(Seq & s) const + { + return fusion::invoke(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke::type + operator()(Seq & s) + { + return fusion::invoke(this->fnc_transformed,s); + } + + template + struct result; + + template + struct result< Self const (Seq) > + : result_of::invoke::type > + { }; + + template + struct result< Self(Seq) > + : result_of::invoke::type > + { }; + + }; + +}} + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/fused_function_object.hpp b/thirdparty/boost/fusion/functional/adapter/fused_function_object.hpp new file mode 100644 index 0000000..7db735b --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/fused_function_object.hpp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_FUNCTION_OBJECT_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_FUNCTION_OBJECT_HPP_INCLUDED + +#include + +#include +#include + +namespace boost { namespace fusion +{ + template class fused_function_object; + + //----- ---- --- -- - - - - + + template + class fused_function_object + { + Function fnc_transformed; + + typedef typename detail::qf_c::type & func_const_fwd_t; + typedef typename detail::qf::type & func_fwd_t; + + public: + + inline explicit fused_function_object(func_const_fwd_t f = Function()) + : fnc_transformed(f) + { } + + template + inline typename result_of::invoke_function_object::type operator()(Seq const & s) const + { + return fusion::invoke_function_object< + func_const_fwd_t >(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke_function_object::type + operator()(Seq const & s) + { + return fusion::invoke_function_object< + func_fwd_t >(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke_function_object::type + operator()(Seq & s) const + { + return fusion::invoke_function_object< + func_const_fwd_t >(this->fnc_transformed,s); + } + + template + inline typename result_of::invoke_function_object::type + operator()(Seq & s) + { + return fusion::invoke_function_object< + func_fwd_t >(this->fnc_transformed,s); + } + + template + struct result; + + template + struct result< Self const (Seq) > + : result_of::invoke_function_object::type > + { }; + + template + struct result< Self(Seq) > + : result_of::invoke_function_object::type > + { }; + }; + +}} + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/fused_procedure.hpp b/thirdparty/boost/fusion/functional/adapter/fused_procedure.hpp new file mode 100644 index 0000000..b748519 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/fused_procedure.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_PROCEDURE_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_FUSED_PROCEDURE_HPP_INCLUDED + +#include + +#include +#include + +namespace boost { namespace fusion +{ + template class fused_procedure; + + //----- ---- --- -- - - - - + + template + class fused_procedure + { + Function fnc_transformed; + + typedef typename detail::qf_c::type & func_const_fwd_t; + typedef typename detail::qf::type & func_fwd_t; + + public: + + inline explicit fused_procedure(func_const_fwd_t f = Function()) + : fnc_transformed(f) + { } + + template + inline void operator()(Seq const & s) const + { + fusion::invoke_procedure< + func_const_fwd_t >(this->fnc_transformed,s); + } + + template + inline void operator()(Seq const & s) + { + fusion::invoke_procedure< + func_fwd_t >(this->fnc_transformed,s); + } + + template + inline void operator()(Seq & s) const + { + fusion::invoke_procedure< + func_const_fwd_t >(this->fnc_transformed,s); + } + + template + inline void operator()(Seq & s) + { + return fusion::invoke_procedure< + func_fwd_t >(this->fnc_transformed,s); + } + + typedef void result_type; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/limits.hpp b/thirdparty/boost/fusion/functional/adapter/limits.hpp new file mode 100644 index 0000000..73d1199 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/limits.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED) +# define BOOST_FUSION_FUNCTIONAL_ADAPTER_LIMITS_HPP_INCLUDED + +# include + +# if !defined(BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY) +# define BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY 6 +# elif BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY > FUSION_MAX_VECTOR_SIZE +# error "BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY > FUSION_MAX_VECTOR_SIZE" +# endif +# if !defined(BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY) +# define BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY 6 +# elif BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE +# error "BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE" +# endif +# if !defined(BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY) +# define BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY 6 +# elif BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE +# error "BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY > FUSION_MAX_VECTOR_SIZE" +# endif +# if !defined(BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY) +# define BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY 6 +# elif BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY > FUSION_MAX_VECTOR_SIZE +# error "BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY > FUSION_MAX_VECTOR_SIZE" +# endif +# if !defined(BOOST_FUSION_CONSTRUCTOR_MAX_ARITY) +# define BOOST_FUSION_CONSTRUCTOR_MAX_ARITY 6 +# endif + +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/unfused_generic.hpp b/thirdparty/boost/fusion/functional/adapter/unfused_generic.hpp new file mode 100644 index 0000000..c6cee28 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/unfused_generic.hpp @@ -0,0 +1,175 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_GENERIC_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +namespace boost { namespace fusion +{ + template class unfused_generic; + + //----- ---- --- -- - - - - + + template + class unfused_generic + { + Function fnc_transformed; + + typedef typename detail::qf_c::type function_c; + typedef typename detail::qf::type function; + + typedef typename detail::call_param::type func_const_fwd_t; + + public: + + inline explicit unfused_generic(func_const_fwd_t f = Function()) + : fnc_transformed(f) + { } + + template + struct result; + + typedef typename boost::result_of< + function_c(fusion::vector0 &) >::type call_const_0_result; + + inline call_const_0_result operator()() const + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + typedef typename boost::result_of< + function (fusion::vector0 &) >::type call_0_result; + + inline call_0_result operator()() + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + #define BOOST_FUSION_CODE(tpl_params,arg_types,params,args) \ + template \ + inline typename boost::result_of & )>::type \ + operator()(params) const \ + { \ + BOOST_PP_CAT(fusion::vector,N) arg(args); \ + return this->fnc_transformed(arg); \ + } \ + template \ + inline typename boost::result_of & )>::type \ + operator()(params) \ + { \ + BOOST_PP_CAT(fusion::vector,N) arg(args); \ + return this->fnc_transformed(arg); \ + } + + #define BOOST_PP_INDIRECT_SELF \ + + #define BOOST_PP_FILENAME_1 \ + + #define BOOST_PP_ITERATION_LIMITS \ + (1,BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY) + #define N BOOST_PP_ITERATION_1 + #include BOOST_PP_ITERATE() + #undef N + + #undef BOOST_FUSION_CODE + }; +}} + +namespace boost +{ + template + struct result_of const ()> + { + typedef typename boost::fusion::unfused_generic::call_const_0_result type; + }; + template + struct result_of()> + { + typedef typename boost::fusion::unfused_generic::call_0_result type; + }; +} + +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_GENERIC_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#include + +#if BOOST_PP_SLOT_1() == 0 + template + struct result + < Self const (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of::type BOOST_PP_INTERCEPT) > & )> + { }; + + template + struct result + < Self(BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of::type BOOST_PP_INTERCEPT) > & )> + { }; +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const + { + BOOST_PP_CAT(fusion::vector,N) + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) + { + BOOST_PP_CAT(fusion::vector,N) + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } +#else + BOOST_FUSION_CODE(BOOST_PP_ENUM_PARAMS(N,typename T), + BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a), + BOOST_PP_ENUM_PARAMS(N,a) ) + // ...generates uglier code but is faster - it caches ENUM_* +#endif + +#include + +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/unfused_lvalue_args.hpp b/thirdparty/boost/fusion/functional/adapter/unfused_lvalue_args.hpp new file mode 100644 index 0000000..1ad5631 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/unfused_lvalue_args.hpp @@ -0,0 +1,136 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_LVALUE_ARGS_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +namespace boost { namespace fusion +{ + template class unfused_lvalue_args; + + //----- ---- --- -- - - - - + + template class unfused_lvalue_args + { + Function fnc_transformed; + + typedef typename detail::qf_c::type function_c; + typedef typename detail::qf::type function; + + typedef typename detail::call_param::type func_const_fwd_t; + + public: + + inline explicit unfused_lvalue_args(func_const_fwd_t f = function()) + : fnc_transformed(f) + { } + + template + struct result; + + typedef typename boost::result_of< + function_c(fusion::vector0 &) >::type call_const_0_result; + + inline call_const_0_result operator()() const + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + typedef typename boost::result_of< + function(fusion::vector0 &) >::type call_0_result; + + inline call_0_result operator()() + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + #define BOOST_PP_FILENAME_1 \ + + #define BOOST_PP_ITERATION_LIMITS \ + (1,BOOST_FUSION_UNFUSED_LVALUE_ARGS_MAX_ARITY) + #include BOOST_PP_ITERATE() + }; +}} + +namespace boost +{ + template + struct result_of< boost::fusion::unfused_lvalue_args const () > + { + typedef typename boost::fusion::unfused_lvalue_args::call_const_0_result type; + }; + template + struct result_of< boost::fusion::unfused_lvalue_args() > + { + typedef typename boost::fusion::unfused_lvalue_args::call_0_result type; + }; +} + +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_LVALUE_ARGS_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +//////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +//////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + template + struct result< Self const (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function_c( + BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, + typename detail::mref::type BOOST_PP_INTERCEPT) > & )> + { }; + + template + struct result< Self(BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function( + BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, + typename detail::mref::type BOOST_PP_INTERCEPT) > & )> + { }; + + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } + + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/unfused_rvalue_args.hpp b/thirdparty/boost/fusion/functional/adapter/unfused_rvalue_args.hpp new file mode 100644 index 0000000..21ea204 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/unfused_rvalue_args.hpp @@ -0,0 +1,137 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_RVALUE_ARGS_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +namespace boost { namespace fusion +{ + template class unfused_rvalue_args; + + //----- ---- --- -- - - - - + + template class unfused_rvalue_args + { + Function fnc_transformed; + + typedef typename detail::qf_c::type function_c; + typedef typename detail::qf::type function; + + typedef typename detail::call_param::type func_const_fwd_t; + + public: + + inline explicit unfused_rvalue_args(func_const_fwd_t f = function()) + : fnc_transformed(f) + { } + + template + struct result; + + typedef typename boost::result_of< + function_c(fusion::vector0 &) >::type call_const_0_result; + + inline call_const_0_result operator()() const + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + typedef typename boost::result_of< + function(fusion::vector0 &) >::type call_0_result; + + inline call_0_result operator()() + { + fusion::vector0 arg; + return this->fnc_transformed(arg); + } + + #define BOOST_PP_FILENAME_1 \ + + #define BOOST_PP_ITERATION_LIMITS \ + (1,BOOST_FUSION_UNFUSED_RVALUE_ARGS_MAX_ARITY) + #include BOOST_PP_ITERATE() + }; +}} + +namespace boost +{ + template + struct result_of const ()> + { + typedef typename boost::fusion::unfused_rvalue_args::call_const_0_result type; + }; + template + struct result_of()> + { + typedef typename boost::fusion::unfused_rvalue_args::call_0_result type; + }; +} + +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_RVALUE_ARGS_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +//////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +//////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + template + struct result< Self const (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function_c( + BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, + typename detail::cref::type BOOST_PP_INTERCEPT) > & )> + { }; + + template + struct result< Self (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function( + BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, + typename detail::cref::type BOOST_PP_INTERCEPT) > & )> + { }; + + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } + + template + inline typename boost::result_of & )>::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return this->fnc_transformed(arg); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/adapter/unfused_typed.hpp b/thirdparty/boost/fusion/functional/adapter/unfused_typed.hpp new file mode 100644 index 0000000..8d69a88 --- /dev/null +++ b/thirdparty/boost/fusion/functional/adapter/unfused_typed.hpp @@ -0,0 +1,155 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_TYPED_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + + +namespace boost { namespace fusion +{ + + template class unfused_typed; + + //----- ---- --- -- - - - - + + namespace detail + { + template + struct unfused_typed_impl; + } + + template + class unfused_typed + : public detail::unfused_typed_impl + < unfused_typed, Function, Sequence, + result_of::size::value > + { + Function fnc_transformed; + + template + friend struct detail::unfused_typed_impl; + + typedef typename detail::call_param::type func_const_fwd_t; + + public: + + inline explicit unfused_typed(func_const_fwd_t f = Function()) + : fnc_transformed(f) + { } + }; + + #define BOOST_PP_FILENAME_1 + #define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY) + #include BOOST_PP_ITERATE() + +}} + +namespace boost +{ + template + struct result_of< boost::fusion::unfused_typed const () > + : boost::fusion::unfused_typed::template result< + boost::fusion::unfused_typed const () > + { }; + template + struct result_of< boost::fusion::unfused_typed() > + : boost::fusion::unfused_typed::template result< + boost::fusion::unfused_typed () > + { }; +} + + +#define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_TYPED_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + namespace detail + { + + template + struct unfused_typed_impl + { + typedef typename detail::qf_c::type function_c; + typedef typename detail::qf::type function; + typedef typename result_of::as_vector::type arg_vector_t; + + public: + +#define M(z,i,s) \ + typename call_param::type>::type a##i + + inline typename boost::result_of< + function_c(arg_vector_t &) >::type + operator()(BOOST_PP_ENUM(N,M,arg_vector_t)) const + { +#if N > 0 + arg_vector_t arg(BOOST_PP_ENUM_PARAMS(N,a)); +#else + arg_vector_t arg; +#endif + return static_cast(this)->fnc_transformed(arg); + } + + inline typename boost::result_of< + function(arg_vector_t &) >::type + operator()(BOOST_PP_ENUM(N,M,arg_vector_t)) + { +#if N > 0 + arg_vector_t arg(BOOST_PP_ENUM_PARAMS(N,a)); +#else + arg_vector_t arg; +#endif + return static_cast(this)->fnc_transformed(arg); + } + +#undef M + + template struct result { typedef void type; }; + + template + struct result< Self const (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function_c(arg_vector_t &) > + { }; + + template + struct result< Self (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< function(arg_vector_t &) > + { }; + }; + + } // namespace detail + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/generation.hpp b/thirdparty/boost/fusion/functional/generation.hpp new file mode 100644 index 0000000..a0bec29 --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/functional/generation/detail/gen_make_adapter.hpp b/thirdparty/boost/fusion/functional/generation/detail/gen_make_adapter.hpp new file mode 100644 index 0000000..3fc36f9 --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/detail/gen_make_adapter.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +// No include guard - this file is included multiple times intentionally. + +#include +#include + +#if !defined(BOOST_FUSION_CLASS_TPL_NAME) +# error "BOOST_FUSION_CLASS_TPL_NAME undefined" +#endif + +#define BOOST_FUSION_FUNC_NAME BOOST_PP_CAT(make_,BOOST_FUSION_CLASS_TPL_NAME) + +namespace boost { namespace fusion +{ + + namespace result_of + { + template + struct BOOST_FUSION_FUNC_NAME + { + typedef fusion::BOOST_FUSION_CLASS_TPL_NAME< + typename fusion::detail::as_fusion_element::type > type; + }; + } + + template + inline typename result_of::BOOST_FUSION_FUNC_NAME::type + BOOST_FUSION_FUNC_NAME(F const & f) + { + return typename result_of::BOOST_FUSION_FUNC_NAME::type(f); + } + +}} + +#undef BOOST_FUSION_CLASS_TPL_NAME +#undef BOOST_FUSION_FUNC_NAME + diff --git a/thirdparty/boost/fusion/functional/generation/make_fused.hpp b/thirdparty/boost/fusion/functional/generation/make_fused.hpp new file mode 100644 index 0000000..a7a1dba --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_fused.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME fused +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/generation/make_fused_function_object.hpp b/thirdparty/boost/fusion/functional/generation/make_fused_function_object.hpp new file mode 100644 index 0000000..b4c3fce --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_fused_function_object.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_FUNCTION_OBJECT_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_FUNCTION_OBJECT_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME fused_function_object +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/generation/make_fused_procedure.hpp b/thirdparty/boost/fusion/functional/generation/make_fused_procedure.hpp new file mode 100644 index 0000000..886a35b --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_fused_procedure.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_PROCEDURE_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_FUSED_PROCEDURE_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME fused_procedure +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/generation/make_unfused_generic.hpp b/thirdparty/boost/fusion/functional/generation/make_unfused_generic.hpp new file mode 100644 index 0000000..980cf0d --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_unfused_generic.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_GENERIC_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_GENERIC_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME unfused_generic +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/generation/make_unfused_lvalue_args.hpp b/thirdparty/boost/fusion/functional/generation/make_unfused_lvalue_args.hpp new file mode 100644 index 0000000..a085e18 --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_unfused_lvalue_args.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_LVALUE_ARGS_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_LVALUE_ARGS_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME unfused_lvalue_args +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/generation/make_unfused_rvalue_args.hpp b/thirdparty/boost/fusion/functional/generation/make_unfused_rvalue_args.hpp new file mode 100644 index 0000000..027b8bb --- /dev/null +++ b/thirdparty/boost/fusion/functional/generation/make_unfused_rvalue_args.hpp @@ -0,0 +1,18 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_RVALUE_ARGS_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_GENERATION_MAKE_UNFUSED_RVALUE_ARGS_HPP_INCLUDED + +#include + +#define BOOST_FUSION_CLASS_TPL_NAME unfused_rvalue_args +#include + +#endif + diff --git a/thirdparty/boost/fusion/functional/invocation.hpp b/thirdparty/boost/fusion/functional/invocation.hpp new file mode 100644 index 0000000..95b9311 --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation.hpp @@ -0,0 +1,16 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_INVOCATION_HPP_INCLUDED + +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/functional/invocation/detail/that_ptr.hpp b/thirdparty/boost/fusion/functional/invocation/detail/that_ptr.hpp new file mode 100644 index 0000000..7c32a10 --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation/detail/that_ptr.hpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_DETAIL_THAT_PTR_HPP_INCLUDED) +#define BOOST_FUSION_FUNCTIONAL_INVOCATION_DETAIL_THAT_PTR_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct that_ptr + { + private: + + typedef typename remove_reference::type pointee; + + template + static inline pointee * do_get_pointer(T &, pointee * x) + { + return x; + } + template + static inline pointee * do_get_pointer(T & x, void const *) + { + return get_pointer(x); + } + + public: + + static inline pointee * get(pointee * x) + { + return x; + } + + static inline pointee * get(pointee & x) + { + return boost::addressof(x); + } + + template static inline pointee * get(T & x) + { + return do_get_pointer(x, boost::addressof(x)); + } + }; + + template struct non_const_pointee; + + namespace adl_barrier + { + using boost::get_pointer; + void const * BOOST_TT_DECL get_pointer(...); // fallback + + template< typename T> char const_tester(T *); + template< typename T> long const_tester(T const *); + + template + struct non_const_pointee_impl + { + static Ptr & what; + + static bool const value = + sizeof(const_tester(get_pointer(what))) == 1; + }; + } + + template struct non_const_pointee + : adl_barrier::non_const_pointee_impl< + typename remove_cv< + typename remove_reference::type >::type > + { + typedef non_const_pointee type; + typedef bool value_type; + }; + +}}} + +#endif + diff --git a/thirdparty/boost/fusion/functional/invocation/invoke.hpp b/thirdparty/boost/fusion/functional/invocation/invoke.hpp new file mode 100644 index 0000000..3cd843c --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation/invoke.hpp @@ -0,0 +1,306 @@ +/*============================================================================= + Copyright (c) 2005-2006 João Abecasis + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#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 + +namespace boost { namespace fusion +{ + namespace result_of + { + template struct invoke; + } + + template + inline typename result_of::invoke::type + invoke(Function, Sequence &); + + template + inline typename result_of::invoke::type + invoke(Function, Sequence const &); + + //----- ---- --- -- - - - - + + namespace detail + { + namespace ft = function_types; + + template< + typename Function, class Sequence, + int N = result_of::size::value, + bool CBI = ft::is_callable_builtin::value, + bool RandomAccess = traits::is_random_access::value + > + struct invoke_impl; + + template + struct invoke_param_types; + + template + struct invoke_data_member; + + template + struct invoke_mem_fn; + + #define BOOST_PP_FILENAME_1 + #define BOOST_PP_ITERATION_LIMITS (0, BOOST_FUSION_INVOKE_MAX_ARITY) + #include BOOST_PP_ITERATE() + + template + struct invoke_nonmember_builtin + // use same implementation as for function objects but... + : invoke_impl< // ...work around boost::result_of bugs + typename mpl::eval_if< ft::is_function, + boost::add_reference, boost::remove_cv >::type, + Sequence, N, false, RandomAccess > + { }; + + template + struct invoke_impl + : mpl::if_< ft::is_member_function_pointer, + invoke_mem_fn, + invoke_nonmember_builtin + >::type + { }; + + template + struct invoke_impl + : mpl::eval_if< ft::is_member_pointer, + mpl::if_< ft::is_member_function_pointer, + invoke_mem_fn, + invoke_data_member >, + mpl::identity< invoke_nonmember_builtin< + Function,Sequence,1,RandomAccess> > + >::type + { }; + + template + struct invoke_data_member< T C::*, Sequence > + { + private: + + typedef typename result_of::front::type that; + + typedef mpl::or_< boost::is_convertible, + boost::is_convertible, + non_const_pointee > non_const_cond; + + typedef typename mpl::eval_if< non_const_cond, + mpl::identity, add_const >::type qualified_class; + + typedef typename mpl::eval_if< non_const_cond, + mpl::identity, add_const >::type qualified_type; + + public: + + typedef typename boost::add_reference::type + result_type; + + static inline result_type call(T C::* f, Sequence & s) + { + typename result_of::front::type c = fusion::front(s); + return that_ptr::get(c)->*f; + } + }; + } + + namespace result_of + { + template struct invoke + { + typedef typename detail::invoke_impl< + typename boost::remove_reference::type, Sequence + >::result_type type; + }; + } + + template + inline typename result_of::invoke::type + invoke(Function f, Sequence & s) + { + return detail::invoke_impl< + typename boost::remove_reference::type,Sequence + >::call(f,s); + } + + template + inline typename result_of::invoke::type + invoke(Function f, Sequence const & s) + { + return detail::invoke_impl< + typename boost::remove_reference::type,Sequence const + >::call(f,s); + } + +}} + +#define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + template + struct invoke_impl + { + public: + + typedef typename boost::result_of< +#define M(z,j,data) typename result_of::at_c::type + Function(BOOST_PP_ENUM(N,M,~)) >::type result_type; +#undef M + + template + static inline result_type + call(F & f, Sequence & s) + { +#define M(z,j,data) fusion::at_c(s) + return f( BOOST_PP_ENUM(N,M,~) ); + } + }; + + +#if N > 0 + template + struct invoke_mem_fn + { + public: + + typedef typename ft::result_type::type result_type; + + template + static inline result_type + call(F & f, Sequence & s) + { + return (that_ptr >::type + >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~)); + } + }; +#endif + +#undef M + +#define M(z,j,data) \ + typename seq::I##j i##j = \ + fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j))); + + template + struct invoke_impl + { + private: + typedef invoke_param_types seq; + public: + + typedef typename boost::result_of< + Function(BOOST_PP_ENUM_PARAMS(N,typename seq::T)) + >::type result_type; + + template + static inline result_type + call(F & f, Sequence & s) + { +#if N > 0 + typename seq::I0 i0 = fusion::begin(s); + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) +#endif + return f( BOOST_PP_ENUM_PARAMS(N,*i) ); + } + }; + +#if N > 0 + template + struct invoke_mem_fn + { + private: + typedef invoke_param_types seq; + public: + + typedef typename ft::result_type::type result_type; + + template + static inline result_type + call(F & f, Sequence & s) + { + typename seq::I0 i0 = fusion::begin(s); + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) + + return (that_ptr< typename mpl::front< + ft::parameter_types >::type + >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i)); + } + }; +#endif + +#undef M + + template struct invoke_param_types + { +#if N > 0 + typedef typename result_of::begin::type I0; + typedef typename result_of::deref::type T0; + +#define M(z,i,data) \ + typedef typename result_of::next< \ + BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \ + typedef typename result_of::deref::type T##i; + + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) +#undef M +#endif + }; + + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/invocation/invoke_function_object.hpp b/thirdparty/boost/fusion/functional/invocation/invoke_function_object.hpp new file mode 100644 index 0000000..ce8ad22 --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation/invoke_function_object.hpp @@ -0,0 +1,177 @@ +/*============================================================================= + Copyright (c) 2005-2006 João Abecasis + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_FUNCTION_OBJECT_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template struct invoke_function_object; + } + + template + inline typename result_of::invoke_function_object::type + invoke_function_object(Function, Sequence &); + + template + inline typename result_of::invoke_function_object::type invoke_function_object(Function, Sequence const &); + + //----- ---- --- -- - - - - + + namespace detail + { + template< + class Function, class Sequence, + int N = result_of::size::value, + bool RandomAccess = traits::is_random_access::value + > + struct invoke_function_object_impl; + + template + struct invoke_function_object_param_types; + + #define BOOST_PP_FILENAME_1 \ + + #define BOOST_PP_ITERATION_LIMITS \ + (0, BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY) + #include BOOST_PP_ITERATE() + } + + namespace result_of + { + template struct invoke_function_object + { + typedef typename detail::invoke_function_object_impl< + typename boost::remove_reference::type, Sequence + >::result_type type; + }; + } + + template + inline typename result_of::invoke_function_object::type + invoke_function_object(Function f, Sequence & s) + { + return detail::invoke_function_object_impl< + typename boost::remove_reference::type,Sequence + >::call(f,s); + } + + template + inline typename result_of::invoke_function_object::type + invoke_function_object(Function f, Sequence const & s) + { + return detail::invoke_function_object_impl< + typename boost::remove_reference::type,Sequence const + >::call(f,s); + } + +}} + +#define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_FUNCTION_OBJECT_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + + template + struct invoke_function_object_impl + { + public: + + typedef typename boost::result_of< +#define M(z,j,data) \ + typename result_of::at_c::type + Function (BOOST_PP_ENUM(N,M,~)) >::type result_type; +#undef M + + template + static inline result_type + call(F & f, Sequence & s) + { +#define M(z,j,data) fusion::at_c(s) + return f( BOOST_PP_ENUM(N,M,~) ); +#undef M + } + }; + + template + struct invoke_function_object_impl + { + private: + typedef invoke_function_object_param_types seq; + public: + typedef typename boost::result_of< + Function (BOOST_PP_ENUM_PARAMS(N,typename seq::T)) + >::type result_type; + + template + static inline result_type + call(F & f, Sequence & s) + { +#if N > 0 + typename seq::I0 i0 = fusion::begin(s); +#define M(z,j,data) \ + typename seq::I##j i##j = \ + fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j))); + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) +#undef M +#endif + return f( BOOST_PP_ENUM_PARAMS(N,*i) ); + } + }; + + template + struct invoke_function_object_param_types + { +#if N > 0 + typedef typename result_of::begin::type I0; + typedef typename result_of::deref::type T0; + +#define M(z,i,data) \ + typedef typename result_of::next< \ + BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \ + typedef typename result_of::deref::type T##i; + + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) +#undef M +#endif + }; + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/invocation/invoke_procedure.hpp b/thirdparty/boost/fusion/functional/invocation/invoke_procedure.hpp new file mode 100644 index 0000000..ae7ef52 --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation/invoke_procedure.hpp @@ -0,0 +1,171 @@ +/*============================================================================= + Copyright (c) 2005-2006 João Abecasis + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_PROCEDURE_HPP_INCLUDED) +#if !defined(BOOST_PP_IS_ITERATING) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace result_of + { + template struct invoke_procedure + { + typedef void type; + }; + } + + template + inline void invoke_procedure(Function, Sequence &); + + template + inline void invoke_procedure(Function, Sequence const &); + + //----- ---- --- -- - - - - + + namespace detail + { + namespace ft = function_types; + + template< + typename Function, class Sequence, + int N = result_of::size::value, + bool MFP = ft::is_member_function_pointer::value, + bool RandomAccess = traits::is_random_access::value + > + struct invoke_procedure_impl; + + #define BOOST_PP_FILENAME_1 \ + + #define BOOST_PP_ITERATION_LIMITS \ + (0, BOOST_FUSION_INVOKE_PROCEDURE_MAX_ARITY) + #include BOOST_PP_ITERATE() + + } + + template + inline void invoke_procedure(Function f, Sequence & s) + { + detail::invoke_procedure_impl< + typename boost::remove_reference::type,Sequence + >::call(f,s); + } + + template + inline void invoke_procedure(Function f, Sequence const & s) + { + detail::invoke_procedure_impl< + typename boost::remove_reference::type,Sequence const + >::call(f,s); + } + +}} + +#define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_PROCEDURE_HPP_INCLUDED +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#define N BOOST_PP_ITERATION() + +#define M(z,j,data) fusion::at_c(s) + + template + struct invoke_procedure_impl + { + static inline void call(Function & f, Sequence & s) + { + f(BOOST_PP_ENUM(N,M,~)); + } + }; + +#if N > 0 + template + struct invoke_procedure_impl + { + static inline void call(Function & f, Sequence & s) + { + (that_ptr >::type + >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~)); + } + }; +#endif + +#undef M + +#define M(z,j,data) \ + typedef typename result_of::next< BOOST_PP_CAT(I,BOOST_PP_DEC(j)) \ + >::type I ## j ; \ + I##j i##j = fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j))); + + template + struct invoke_procedure_impl + { + static inline void call(Function & f, Sequence & s) + { +#if N > 0 + typedef typename result_of::begin::type I0; + I0 i0 = fusion::begin(s); + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) +#endif + f( BOOST_PP_ENUM_PARAMS(N,*i) ); + } + }; + +#if N > 0 + template + struct invoke_procedure_impl + { + static inline void call(Function & f, Sequence & s) + { + typedef typename result_of::begin::type I0; + I0 i0 = fusion::begin(s); + BOOST_PP_REPEAT_FROM_TO(1,N,M,~) + + (that_ptr >::type + >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i)); + } + }; +#endif + +#undef M + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) +#endif + diff --git a/thirdparty/boost/fusion/functional/invocation/limits.hpp b/thirdparty/boost/fusion/functional/invocation/limits.hpp new file mode 100644 index 0000000..e90f57d --- /dev/null +++ b/thirdparty/boost/fusion/functional/invocation/limits.hpp @@ -0,0 +1,23 @@ +/*============================================================================= + Copyright (c) 2006-2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_LIMITS_HPP_INCLUDED) +# define BOOST_FUSION_FUNCTIONAL_INVOCATION_LIMITS_HPP_INCLUDED + +# if !defined(BOOST_FUSION_INVOKE_MAX_ARITY) +# define BOOST_FUSION_INVOKE_MAX_ARITY 6 +# endif +# if !defined(BOOST_FUSION_INVOKE_PROCEDURE_MAX_ARITY) +# define BOOST_FUSION_INVOKE_PROCEDURE_MAX_ARITY 6 +# endif +# if !defined(BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY) +# define BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY 6 +# endif + +#endif + diff --git a/thirdparty/boost/fusion/include/accumulate.hpp b/thirdparty/boost/fusion/include/accumulate.hpp new file mode 100644 index 0000000..be3c1c3 --- /dev/null +++ b/thirdparty/boost/fusion/include/accumulate.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ACCUMULATE) +#define FUSION_INCLUDE_ACCUMULATE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/adapt_struct.hpp b/thirdparty/boost/fusion/include/adapt_struct.hpp new file mode 100644 index 0000000..8d12025 --- /dev/null +++ b/thirdparty/boost/fusion/include/adapt_struct.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ADAPT_STRUCT) +#define FUSION_INCLUDE_ADAPT_STRUCT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/adapted.hpp b/thirdparty/boost/fusion/include/adapted.hpp new file mode 100644 index 0000000..17dcb16 --- /dev/null +++ b/thirdparty/boost/fusion/include/adapted.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ADAPTED) +#define FUSION_INCLUDE_ADAPTED + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/adapter.hpp b/thirdparty/boost/fusion/include/adapter.hpp new file mode 100644 index 0000000..b94591f --- /dev/null +++ b/thirdparty/boost/fusion/include/adapter.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ADAPTER) +#define FUSION_INCLUDE_ADAPTER + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/advance.hpp b/thirdparty/boost/fusion/include/advance.hpp new file mode 100644 index 0000000..0674237 --- /dev/null +++ b/thirdparty/boost/fusion/include/advance.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ADVANCE) +#define FUSION_INCLUDE_ADVANCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/algorithm.hpp b/thirdparty/boost/fusion/include/algorithm.hpp new file mode 100644 index 0000000..2bb296c --- /dev/null +++ b/thirdparty/boost/fusion/include/algorithm.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ALGORITHM) +#define FUSION_INCLUDE_ALGORITHM + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/all.hpp b/thirdparty/boost/fusion/include/all.hpp new file mode 100644 index 0000000..b8254c9 --- /dev/null +++ b/thirdparty/boost/fusion/include/all.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ALL) +#define FUSION_INCLUDE_ALL + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/any.hpp b/thirdparty/boost/fusion/include/any.hpp new file mode 100644 index 0000000..891f1ea --- /dev/null +++ b/thirdparty/boost/fusion/include/any.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ANY) +#define FUSION_INCLUDE_ANY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/array.hpp b/thirdparty/boost/fusion/include/array.hpp new file mode 100644 index 0000000..31f2aa6 --- /dev/null +++ b/thirdparty/boost/fusion/include/array.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ARRAY) +#define FUSION_INCLUDE_ARRAY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/as_deque.hpp b/thirdparty/boost/fusion/include/as_deque.hpp new file mode 100644 index 0000000..45c27ed --- /dev/null +++ b/thirdparty/boost/fusion/include/as_deque.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AS_DEQUE) +#define FUSION_INCLUDE_AS_DEQUE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/as_list.hpp b/thirdparty/boost/fusion/include/as_list.hpp new file mode 100644 index 0000000..d67d53c --- /dev/null +++ b/thirdparty/boost/fusion/include/as_list.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AS_LIST) +#define FUSION_INCLUDE_AS_LIST + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/as_map.hpp b/thirdparty/boost/fusion/include/as_map.hpp new file mode 100644 index 0000000..c56e8e5 --- /dev/null +++ b/thirdparty/boost/fusion/include/as_map.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AS_MAP) +#define FUSION_INCLUDE_AS_MAP + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/as_set.hpp b/thirdparty/boost/fusion/include/as_set.hpp new file mode 100644 index 0000000..fa27211 --- /dev/null +++ b/thirdparty/boost/fusion/include/as_set.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AS_SET) +#define FUSION_INCLUDE_AS_SET + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/as_vector.hpp b/thirdparty/boost/fusion/include/as_vector.hpp new file mode 100644 index 0000000..e213f23 --- /dev/null +++ b/thirdparty/boost/fusion/include/as_vector.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AS_VECTOR) +#define FUSION_INCLUDE_AS_VECTOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/at.hpp b/thirdparty/boost/fusion/include/at.hpp new file mode 100644 index 0000000..0eaf5c5 --- /dev/null +++ b/thirdparty/boost/fusion/include/at.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AT) +#define FUSION_INCLUDE_AT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/at_key.hpp b/thirdparty/boost/fusion/include/at_key.hpp new file mode 100644 index 0000000..dbeded3 --- /dev/null +++ b/thirdparty/boost/fusion/include/at_key.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_AT_KEY) +#define FUSION_INCLUDE_AT_KEY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/back.hpp b/thirdparty/boost/fusion/include/back.hpp new file mode 100644 index 0000000..b58621d --- /dev/null +++ b/thirdparty/boost/fusion/include/back.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_BACK) +#define FUSION_INCLUDE_BACK + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/begin.hpp b/thirdparty/boost/fusion/include/begin.hpp new file mode 100644 index 0000000..dba926b --- /dev/null +++ b/thirdparty/boost/fusion/include/begin.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_BEGIN) +#define FUSION_INCLUDE_BEGIN + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/boost_tuple.hpp b/thirdparty/boost/fusion/include/boost_tuple.hpp new file mode 100644 index 0000000..c56b7ed --- /dev/null +++ b/thirdparty/boost/fusion/include/boost_tuple.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_BOOST_TUPLE) +#define FUSION_INCLUDE_BOOST_TUPLE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/category_of.hpp b/thirdparty/boost/fusion/include/category_of.hpp new file mode 100644 index 0000000..787d8af --- /dev/null +++ b/thirdparty/boost/fusion/include/category_of.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CATEGORY_OF) +#define FUSION_INCLUDE_CATEGORY_OF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/clear.hpp b/thirdparty/boost/fusion/include/clear.hpp new file mode 100644 index 0000000..895b112 --- /dev/null +++ b/thirdparty/boost/fusion/include/clear.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CLEAR) +#define FUSION_INCLUDE_CLEAR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/comparison.hpp b/thirdparty/boost/fusion/include/comparison.hpp new file mode 100644 index 0000000..f55169d --- /dev/null +++ b/thirdparty/boost/fusion/include/comparison.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_COMPARISON) +#define FUSION_INCLUDE_COMPARISON + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/cons.hpp b/thirdparty/boost/fusion/include/cons.hpp new file mode 100644 index 0000000..b0f257d --- /dev/null +++ b/thirdparty/boost/fusion/include/cons.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CONS) +#define FUSION_INCLUDE_CONS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/cons_tie.hpp b/thirdparty/boost/fusion/include/cons_tie.hpp new file mode 100644 index 0000000..d79f545 --- /dev/null +++ b/thirdparty/boost/fusion/include/cons_tie.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CONS_TIE) +#define FUSION_INCLUDE_CONS_TIE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/container.hpp b/thirdparty/boost/fusion/include/container.hpp new file mode 100644 index 0000000..984d46c --- /dev/null +++ b/thirdparty/boost/fusion/include/container.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CONTAINER) +#define FUSION_INCLUDE_CONTAINER + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/convert.hpp b/thirdparty/boost/fusion/include/convert.hpp new file mode 100644 index 0000000..16a9fa8 --- /dev/null +++ b/thirdparty/boost/fusion/include/convert.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_CONVERT) +#define FUSION_INCLUDE_CONVERT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/count.hpp b/thirdparty/boost/fusion/include/count.hpp new file mode 100644 index 0000000..793898d --- /dev/null +++ b/thirdparty/boost/fusion/include/count.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_COUNT) +#define FUSION_INCLUDE_COUNT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/count_if.hpp b/thirdparty/boost/fusion/include/count_if.hpp new file mode 100644 index 0000000..6ba0a10 --- /dev/null +++ b/thirdparty/boost/fusion/include/count_if.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_COUNT_IF) +#define FUSION_INCLUDE_COUNT_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deduce.hpp b/thirdparty/boost/fusion/include/deduce.hpp new file mode 100644 index 0000000..88a3c85 --- /dev/null +++ b/thirdparty/boost/fusion/include/deduce.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DEDUCE) +#define FUSION_INCLUDE_DEDUCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deduce_sequence.hpp b/thirdparty/boost/fusion/include/deduce_sequence.hpp new file mode 100644 index 0000000..3e88ea6 --- /dev/null +++ b/thirdparty/boost/fusion/include/deduce_sequence.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DEDUCE_SEQUENCE) +#define FUSION_INCLUDE_DEDUCE_SEQUENCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deque.hpp b/thirdparty/boost/fusion/include/deque.hpp new file mode 100644 index 0000000..2df2648 --- /dev/null +++ b/thirdparty/boost/fusion/include/deque.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DEQUE) +#define FUSION_INCLUDE_DEQUE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deque_fwd.hpp b/thirdparty/boost/fusion/include/deque_fwd.hpp new file mode 100644 index 0000000..b81d8d3 --- /dev/null +++ b/thirdparty/boost/fusion/include/deque_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DEQUE) +#define FUSION_INCLUDE_DEQUE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deque_tie.hpp b/thirdparty/boost/fusion/include/deque_tie.hpp new file mode 100644 index 0000000..e5c3fba --- /dev/null +++ b/thirdparty/boost/fusion/include/deque_tie.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_GENERATION) +#define FUSION_INCLUDE_GENERATION + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/deref.hpp b/thirdparty/boost/fusion/include/deref.hpp new file mode 100644 index 0000000..0cee05b --- /dev/null +++ b/thirdparty/boost/fusion/include/deref.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DEREF) +#define FUSION_INCLUDE_DEREF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/distance.hpp b/thirdparty/boost/fusion/include/distance.hpp new file mode 100644 index 0000000..5e68437 --- /dev/null +++ b/thirdparty/boost/fusion/include/distance.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_DISTANCE) +#define FUSION_INCLUDE_DISTANCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/empty.hpp b/thirdparty/boost/fusion/include/empty.hpp new file mode 100644 index 0000000..884db51 --- /dev/null +++ b/thirdparty/boost/fusion/include/empty.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_EMPTY) +#define FUSION_INCLUDE_EMPTY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/end.hpp b/thirdparty/boost/fusion/include/end.hpp new file mode 100644 index 0000000..6e8a22f --- /dev/null +++ b/thirdparty/boost/fusion/include/end.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_BEGIN) +#define FUSION_INCLUDE_BEGIN + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/equal_to.hpp b/thirdparty/boost/fusion/include/equal_to.hpp new file mode 100644 index 0000000..b8c89c5 --- /dev/null +++ b/thirdparty/boost/fusion/include/equal_to.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_EQUAL_TO) +#define FUSION_INCLUDE_EQUAL_TO + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/erase.hpp b/thirdparty/boost/fusion/include/erase.hpp new file mode 100644 index 0000000..dec92fb --- /dev/null +++ b/thirdparty/boost/fusion/include/erase.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ERASE) +#define FUSION_INCLUDE_ERASE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/erase_key.hpp b/thirdparty/boost/fusion/include/erase_key.hpp new file mode 100644 index 0000000..4ce77b5 --- /dev/null +++ b/thirdparty/boost/fusion/include/erase_key.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ERASE_KEY) +#define FUSION_INCLUDE_ERASE_KEY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/filter.hpp b/thirdparty/boost/fusion/include/filter.hpp new file mode 100644 index 0000000..e02103c --- /dev/null +++ b/thirdparty/boost/fusion/include/filter.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FILTER) +#define FUSION_INCLUDE_FILTER + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/filter_if.hpp b/thirdparty/boost/fusion/include/filter_if.hpp new file mode 100644 index 0000000..c878074 --- /dev/null +++ b/thirdparty/boost/fusion/include/filter_if.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FILTER_IF) +#define FUSION_INCLUDE_FILTER_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/filter_view.hpp b/thirdparty/boost/fusion/include/filter_view.hpp new file mode 100644 index 0000000..2ffe945 --- /dev/null +++ b/thirdparty/boost/fusion/include/filter_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FILTER_VIEW) +#define FUSION_INCLUDE_FILTER_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/find.hpp b/thirdparty/boost/fusion/include/find.hpp new file mode 100644 index 0000000..deb9545 --- /dev/null +++ b/thirdparty/boost/fusion/include/find.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FIND) +#define FUSION_INCLUDE_FIND + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/find_if.hpp b/thirdparty/boost/fusion/include/find_if.hpp new file mode 100644 index 0000000..bede105 --- /dev/null +++ b/thirdparty/boost/fusion/include/find_if.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FIND_IF) +#define FUSION_INCLUDE_FIND_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/fold.hpp b/thirdparty/boost/fusion/include/fold.hpp new file mode 100644 index 0000000..d294cc1 --- /dev/null +++ b/thirdparty/boost/fusion/include/fold.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FOLD) +#define FUSION_INCLUDE_FOLD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/for_each.hpp b/thirdparty/boost/fusion/include/for_each.hpp new file mode 100644 index 0000000..f8959ac --- /dev/null +++ b/thirdparty/boost/fusion/include/for_each.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FOR_EACH) +#define FUSION_INCLUDE_FOR_EACH + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/front.hpp b/thirdparty/boost/fusion/include/front.hpp new file mode 100644 index 0000000..aa0a4ad --- /dev/null +++ b/thirdparty/boost/fusion/include/front.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FRONT) +#define FUSION_INCLUDE_FRONT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/functional.hpp b/thirdparty/boost/fusion/include/functional.hpp new file mode 100644 index 0000000..19d4240 --- /dev/null +++ b/thirdparty/boost/fusion/include/functional.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FUNCTIONAL) +#define FUSION_INCLUDE_FUNCTIONAL + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/fused.hpp b/thirdparty/boost/fusion/include/fused.hpp new file mode 100644 index 0000000..b4f964a --- /dev/null +++ b/thirdparty/boost/fusion/include/fused.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FUSED) +#define FUSION_INCLUDE_FUSED + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/fused_function_object.hpp b/thirdparty/boost/fusion/include/fused_function_object.hpp new file mode 100644 index 0000000..3299128 --- /dev/null +++ b/thirdparty/boost/fusion/include/fused_function_object.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FUSED_FUNCTION_OBJECT) +#define FUSION_INCLUDE_FUSED_FUNCTION_OBJECT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/fused_procedure.hpp b/thirdparty/boost/fusion/include/fused_procedure.hpp new file mode 100644 index 0000000..d36e0ed --- /dev/null +++ b/thirdparty/boost/fusion/include/fused_procedure.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_FUSED_PROCEDURE) +#define FUSION_INCLUDE_FUSED_PROCEDURE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/generation.hpp b/thirdparty/boost/fusion/include/generation.hpp new file mode 100644 index 0000000..e5c3fba --- /dev/null +++ b/thirdparty/boost/fusion/include/generation.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_GENERATION) +#define FUSION_INCLUDE_GENERATION + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/greater.hpp b/thirdparty/boost/fusion/include/greater.hpp new file mode 100644 index 0000000..d0de047 --- /dev/null +++ b/thirdparty/boost/fusion/include/greater.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_NOT_GREATER) +#define FUSION_INCLUDE_NOT_GREATER + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/greater_equal.hpp b/thirdparty/boost/fusion/include/greater_equal.hpp new file mode 100644 index 0000000..b1e7a39 --- /dev/null +++ b/thirdparty/boost/fusion/include/greater_equal.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_GREATER_EQUAL) +#define FUSION_INCLUDE_GREATER_EQUAL + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/has_key.hpp b/thirdparty/boost/fusion/include/has_key.hpp new file mode 100644 index 0000000..acd578b --- /dev/null +++ b/thirdparty/boost/fusion/include/has_key.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_HAS_KEY) +#define FUSION_INCLUDE_EMPTY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/ignore.hpp b/thirdparty/boost/fusion/include/ignore.hpp new file mode 100644 index 0000000..e5c3fba --- /dev/null +++ b/thirdparty/boost/fusion/include/ignore.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_GENERATION) +#define FUSION_INCLUDE_GENERATION + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/in.hpp b/thirdparty/boost/fusion/include/in.hpp new file mode 100644 index 0000000..85d474e --- /dev/null +++ b/thirdparty/boost/fusion/include/in.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_IN) +#define FUSION_INCLUDE_IN + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/insert.hpp b/thirdparty/boost/fusion/include/insert.hpp new file mode 100644 index 0000000..38378ef --- /dev/null +++ b/thirdparty/boost/fusion/include/insert.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INSERT) +#define FUSION_INCLUDE_INSERT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/insert_range.hpp b/thirdparty/boost/fusion/include/insert_range.hpp new file mode 100644 index 0000000..39b88fe --- /dev/null +++ b/thirdparty/boost/fusion/include/insert_range.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INSERT_RANGE) +#define FUSION_INCLUDE_INSERT_RANGE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/intrinsic.hpp b/thirdparty/boost/fusion/include/intrinsic.hpp new file mode 100644 index 0000000..3c8e135 --- /dev/null +++ b/thirdparty/boost/fusion/include/intrinsic.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INTRINSIC) +#define FUSION_INCLUDE_INTRINSIC + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/invocation.hpp b/thirdparty/boost/fusion/include/invocation.hpp new file mode 100644 index 0000000..f9f35b7 --- /dev/null +++ b/thirdparty/boost/fusion/include/invocation.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INVOCATION) +#define FUSION_INCLUDE_INVOCATION + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/invoke.hpp b/thirdparty/boost/fusion/include/invoke.hpp new file mode 100644 index 0000000..c63e597 --- /dev/null +++ b/thirdparty/boost/fusion/include/invoke.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INVOKE) +#define FUSION_INCLUDE_INVOKE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/invoke_function_object.hpp b/thirdparty/boost/fusion/include/invoke_function_object.hpp new file mode 100644 index 0000000..ac9ca19 --- /dev/null +++ b/thirdparty/boost/fusion/include/invoke_function_object.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INVOKE_FUNCTION_OBJECT) +#define FUSION_INCLUDE_INVOKE_FUNCTION_OBJECT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/invoke_procedure.hpp b/thirdparty/boost/fusion/include/invoke_procedure.hpp new file mode 100644 index 0000000..a5872ff --- /dev/null +++ b/thirdparty/boost/fusion/include/invoke_procedure.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_INVOKE_PROCEDURE) +#define FUSION_INCLUDE_INVOKE_PROCEDURE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/io.hpp b/thirdparty/boost/fusion/include/io.hpp new file mode 100644 index 0000000..cd4015d --- /dev/null +++ b/thirdparty/boost/fusion/include/io.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_IO) +#define FUSION_INCLUDE_IO + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/is_iterator.hpp b/thirdparty/boost/fusion/include/is_iterator.hpp new file mode 100644 index 0000000..be8fc93 --- /dev/null +++ b/thirdparty/boost/fusion/include/is_iterator.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_IS_ITERATOR) +#define FUSION_INCLUDE_IS_ITERATOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/is_sequence.hpp b/thirdparty/boost/fusion/include/is_sequence.hpp new file mode 100644 index 0000000..4007a90 --- /dev/null +++ b/thirdparty/boost/fusion/include/is_sequence.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_IS_SEQUENCE) +#define FUSION_INCLUDE_IS_SEQUENCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/is_view.hpp b/thirdparty/boost/fusion/include/is_view.hpp new file mode 100644 index 0000000..d42f344 --- /dev/null +++ b/thirdparty/boost/fusion/include/is_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_IS_VIEW) +#define FUSION_INCLUDE_IS_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/iteration.hpp b/thirdparty/boost/fusion/include/iteration.hpp new file mode 100644 index 0000000..ea8494b --- /dev/null +++ b/thirdparty/boost/fusion/include/iteration.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ITERATION) +#define FUSION_INCLUDE_ITERATION + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/iterator.hpp b/thirdparty/boost/fusion/include/iterator.hpp new file mode 100644 index 0000000..bc1dc42 --- /dev/null +++ b/thirdparty/boost/fusion/include/iterator.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ITERATOR) +#define FUSION_INCLUDE_ITERATOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/iterator_base.hpp b/thirdparty/boost/fusion/include/iterator_base.hpp new file mode 100644 index 0000000..738781d --- /dev/null +++ b/thirdparty/boost/fusion/include/iterator_base.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ITERATOR_BASE) +#define FUSION_INCLUDE_ITERATOR_BASE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/iterator_facade.hpp b/thirdparty/boost/fusion/include/iterator_facade.hpp new file mode 100644 index 0000000..db30003 --- /dev/null +++ b/thirdparty/boost/fusion/include/iterator_facade.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ITERATOR_FACADE) +#define FUSION_INCLUDE_ITERATOR_FACADE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/iterator_range.hpp b/thirdparty/boost/fusion/include/iterator_range.hpp new file mode 100644 index 0000000..0f5f95f --- /dev/null +++ b/thirdparty/boost/fusion/include/iterator_range.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ITERATOR_RANGE) +#define FUSION_INCLUDE_ITERATOR_RANGE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/join.hpp b/thirdparty/boost/fusion/include/join.hpp new file mode 100644 index 0000000..3db5725 --- /dev/null +++ b/thirdparty/boost/fusion/include/join.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_JOIN) +#define FUSION_INCLUDE_JOIN + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/joint_view.hpp b/thirdparty/boost/fusion/include/joint_view.hpp new file mode 100644 index 0000000..22a3d51 --- /dev/null +++ b/thirdparty/boost/fusion/include/joint_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_JOINT_VIEW) +#define FUSION_INCLUDE_JOINT_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/less.hpp b/thirdparty/boost/fusion/include/less.hpp new file mode 100644 index 0000000..e04cc16 --- /dev/null +++ b/thirdparty/boost/fusion/include/less.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_LESS) +#define FUSION_INCLUDE_LESS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/less_equal.hpp b/thirdparty/boost/fusion/include/less_equal.hpp new file mode 100644 index 0000000..288a892 --- /dev/null +++ b/thirdparty/boost/fusion/include/less_equal.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_LESS_EQUAL) +#define FUSION_INCLUDE_LESS_EQUAL + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/list.hpp b/thirdparty/boost/fusion/include/list.hpp new file mode 100644 index 0000000..05973de --- /dev/null +++ b/thirdparty/boost/fusion/include/list.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_LIST) +#define FUSION_INCLUDE_LIST + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/list_fwd.hpp b/thirdparty/boost/fusion/include/list_fwd.hpp new file mode 100644 index 0000000..047fb28 --- /dev/null +++ b/thirdparty/boost/fusion/include/list_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_LIST_FWD) +#define FUSION_INCLUDE_LIST_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/list_tie.hpp b/thirdparty/boost/fusion/include/list_tie.hpp new file mode 100644 index 0000000..e5c3fba --- /dev/null +++ b/thirdparty/boost/fusion/include/list_tie.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_GENERATION) +#define FUSION_INCLUDE_GENERATION + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_cons.hpp b/thirdparty/boost/fusion/include/make_cons.hpp new file mode 100644 index 0000000..92ed25d --- /dev/null +++ b/thirdparty/boost/fusion/include/make_cons.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_CONS) +#define FUSION_INCLUDE_MAKE_CONS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_deque.hpp b/thirdparty/boost/fusion/include/make_deque.hpp new file mode 100644 index 0000000..3c88d1f --- /dev/null +++ b/thirdparty/boost/fusion/include/make_deque.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_DEQUE) +#define FUSION_INCLUDE_MAKE_DEQUE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_fused.hpp b/thirdparty/boost/fusion/include/make_fused.hpp new file mode 100644 index 0000000..e58c451 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_fused.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_FUSED) +#define FUSION_INCLUDE_MAKE_FUSED + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_fused_function_object.hpp b/thirdparty/boost/fusion/include/make_fused_function_object.hpp new file mode 100644 index 0000000..cd39298 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_fused_function_object.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_FUSED_FUNCTION_OBJECT) +#define FUSION_INCLUDE_MAKE_FUSED_FUNCTION_OBJECT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_fused_procedure.hpp b/thirdparty/boost/fusion/include/make_fused_procedure.hpp new file mode 100644 index 0000000..19022a1 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_fused_procedure.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_FUSED_PROCEDURE) +#define FUSION_INCLUDE_MAKE_FUSED_PROCEDURE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_list.hpp b/thirdparty/boost/fusion/include/make_list.hpp new file mode 100644 index 0000000..27c80c0 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_list.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_LIST) +#define FUSION_INCLUDE_MAKE_LIST + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_map.hpp b/thirdparty/boost/fusion/include/make_map.hpp new file mode 100644 index 0000000..f8a83c3 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_map.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_MAP) +#define FUSION_INCLUDE_MAKE_MAP + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_set.hpp b/thirdparty/boost/fusion/include/make_set.hpp new file mode 100644 index 0000000..1896ed3 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_set.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_SET) +#define FUSION_INCLUDE_MAKE_SET + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_tuple.hpp b/thirdparty/boost/fusion/include/make_tuple.hpp new file mode 100644 index 0000000..49b653e --- /dev/null +++ b/thirdparty/boost/fusion/include/make_tuple.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_TUPLE) +#define FUSION_INCLUDE_MAKE_TUPLE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_unfused_generic.hpp b/thirdparty/boost/fusion/include/make_unfused_generic.hpp new file mode 100644 index 0000000..4fea38d --- /dev/null +++ b/thirdparty/boost/fusion/include/make_unfused_generic.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_UNFUSED_GENERIC) +#define FUSION_INCLUDE_MAKE_UNFUSED_GENERIC + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_unfused_lvalue_args.hpp b/thirdparty/boost/fusion/include/make_unfused_lvalue_args.hpp new file mode 100644 index 0000000..ce85b0c --- /dev/null +++ b/thirdparty/boost/fusion/include/make_unfused_lvalue_args.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_UNFUSED_LVALUE_ARGS) +#define FUSION_INCLUDE_MAKE_UNFUSED_LVALUE_ARGS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_unfused_rvalue_args.hpp b/thirdparty/boost/fusion/include/make_unfused_rvalue_args.hpp new file mode 100644 index 0000000..9960c81 --- /dev/null +++ b/thirdparty/boost/fusion/include/make_unfused_rvalue_args.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_UNFUSED_RVALUE_ARGS) +#define FUSION_INCLUDE_MAKE_UNFUSED_RVALUE_ARGS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/make_vector.hpp b/thirdparty/boost/fusion/include/make_vector.hpp new file mode 100644 index 0000000..92bea2f --- /dev/null +++ b/thirdparty/boost/fusion/include/make_vector.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAKE_VECTOR) +#define FUSION_INCLUDE_MAKE_VECTOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/map.hpp b/thirdparty/boost/fusion/include/map.hpp new file mode 100644 index 0000000..4800d00 --- /dev/null +++ b/thirdparty/boost/fusion/include/map.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAP) +#define FUSION_INCLUDE_MAP + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/map_fwd.hpp b/thirdparty/boost/fusion/include/map_fwd.hpp new file mode 100644 index 0000000..ef1111e --- /dev/null +++ b/thirdparty/boost/fusion/include/map_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAP_FWD) +#define FUSION_INCLUDE_MAP_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/map_tie.hpp b/thirdparty/boost/fusion/include/map_tie.hpp new file mode 100644 index 0000000..eed3f9b --- /dev/null +++ b/thirdparty/boost/fusion/include/map_tie.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MAP_TIE) +#define FUSION_INCLUDE_MAP_TIE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/mpl.hpp b/thirdparty/boost/fusion/include/mpl.hpp new file mode 100644 index 0000000..2d07a1e --- /dev/null +++ b/thirdparty/boost/fusion/include/mpl.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_MPL) +#define FUSION_INCLUDE_MPL + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/next.hpp b/thirdparty/boost/fusion/include/next.hpp new file mode 100644 index 0000000..1c63f19 --- /dev/null +++ b/thirdparty/boost/fusion/include/next.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_NEXT) +#define FUSION_INCLUDE_NEXT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/none.hpp b/thirdparty/boost/fusion/include/none.hpp new file mode 100644 index 0000000..fc475a7 --- /dev/null +++ b/thirdparty/boost/fusion/include/none.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_NONE) +#define FUSION_INCLUDE_NONE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/not_equal_to.hpp b/thirdparty/boost/fusion/include/not_equal_to.hpp new file mode 100644 index 0000000..46433bc --- /dev/null +++ b/thirdparty/boost/fusion/include/not_equal_to.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_NOT_EQUAL_TO) +#define FUSION_INCLUDE_NOT_EQUAL_TO + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/include/out.hpp b/thirdparty/boost/fusion/include/out.hpp new file mode 100644 index 0000000..f4df7b5 --- /dev/null +++ b/thirdparty/boost/fusion/include/out.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_OUT) +#define FUSION_INCLUDE_OUT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/pair.hpp b/thirdparty/boost/fusion/include/pair.hpp new file mode 100644 index 0000000..8bf6c96 --- /dev/null +++ b/thirdparty/boost/fusion/include/pair.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_PAIR) +#define FUSION_INCLUDE_PAIR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/pair_tie.hpp b/thirdparty/boost/fusion/include/pair_tie.hpp new file mode 100644 index 0000000..067bbf4 --- /dev/null +++ b/thirdparty/boost/fusion/include/pair_tie.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_PAIR_TIE) +#define FUSION_INCLUDE_PAIR_TIE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/pop_back.hpp b/thirdparty/boost/fusion/include/pop_back.hpp new file mode 100644 index 0000000..007ae13 --- /dev/null +++ b/thirdparty/boost/fusion/include/pop_back.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_POP_BACK) +#define FUSION_INCLUDE_POP_BACK + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/pop_front.hpp b/thirdparty/boost/fusion/include/pop_front.hpp new file mode 100644 index 0000000..fe3e900 --- /dev/null +++ b/thirdparty/boost/fusion/include/pop_front.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_POP_FRONT) +#define FUSION_INCLUDE_POP_FRONT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/prior.hpp b/thirdparty/boost/fusion/include/prior.hpp new file mode 100644 index 0000000..00b19be --- /dev/null +++ b/thirdparty/boost/fusion/include/prior.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_PRIOR) +#define FUSION_INCLUDE_PRIOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/push_back.hpp b/thirdparty/boost/fusion/include/push_back.hpp new file mode 100644 index 0000000..6924cc1 --- /dev/null +++ b/thirdparty/boost/fusion/include/push_back.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_PUSH_BACK) +#define FUSION_INCLUDE_PUSH_BACK + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/push_front.hpp b/thirdparty/boost/fusion/include/push_front.hpp new file mode 100644 index 0000000..0e4b88d --- /dev/null +++ b/thirdparty/boost/fusion/include/push_front.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_PUSH_FRONT) +#define FUSION_INCLUDE_PUSH_FRONT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/query.hpp b/thirdparty/boost/fusion/include/query.hpp new file mode 100644 index 0000000..43f9762 --- /dev/null +++ b/thirdparty/boost/fusion/include/query.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_QUERY) +#define FUSION_INCLUDE_QUERY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/remove.hpp b/thirdparty/boost/fusion/include/remove.hpp new file mode 100644 index 0000000..6440817 --- /dev/null +++ b/thirdparty/boost/fusion/include/remove.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REMOVE_IF) +#define FUSION_INCLUDE_REMOVE_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/remove_if.hpp b/thirdparty/boost/fusion/include/remove_if.hpp new file mode 100644 index 0000000..6440817 --- /dev/null +++ b/thirdparty/boost/fusion/include/remove_if.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REMOVE_IF) +#define FUSION_INCLUDE_REMOVE_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/repetetive_view.hpp b/thirdparty/boost/fusion/include/repetetive_view.hpp new file mode 100644 index 0000000..4773c8e --- /dev/null +++ b/thirdparty/boost/fusion/include/repetetive_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REPETETIVE_VIEW) +#define FUSION_INCLUDE_REPETETIVE_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/replace.hpp b/thirdparty/boost/fusion/include/replace.hpp new file mode 100644 index 0000000..0f9176b --- /dev/null +++ b/thirdparty/boost/fusion/include/replace.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REPLACE) +#define FUSION_INCLUDE_REPLACE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/replace_if.hpp b/thirdparty/boost/fusion/include/replace_if.hpp new file mode 100644 index 0000000..fc02163 --- /dev/null +++ b/thirdparty/boost/fusion/include/replace_if.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REPLACE_IF) +#define FUSION_INCLUDE_REPLACE_IF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/reverse.hpp b/thirdparty/boost/fusion/include/reverse.hpp new file mode 100644 index 0000000..250d037 --- /dev/null +++ b/thirdparty/boost/fusion/include/reverse.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REVERSE) +#define FUSION_INCLUDE_REVERSE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/reverse_view.hpp b/thirdparty/boost/fusion/include/reverse_view.hpp new file mode 100644 index 0000000..2d47e5d --- /dev/null +++ b/thirdparty/boost/fusion/include/reverse_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_REVERSE_VIEW) +#define FUSION_INCLUDE_REVERSE_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/sequence.hpp b/thirdparty/boost/fusion/include/sequence.hpp new file mode 100644 index 0000000..4d83ba7 --- /dev/null +++ b/thirdparty/boost/fusion/include/sequence.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SEQUENCE) +#define FUSION_INCLUDE_SEQUENCE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/sequence_base.hpp b/thirdparty/boost/fusion/include/sequence_base.hpp new file mode 100644 index 0000000..c68a4fb --- /dev/null +++ b/thirdparty/boost/fusion/include/sequence_base.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SEQUENCE_BASE) +#define FUSION_INCLUDE_SEQUENCE_BASE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/sequence_facade.hpp b/thirdparty/boost/fusion/include/sequence_facade.hpp new file mode 100644 index 0000000..107e172 --- /dev/null +++ b/thirdparty/boost/fusion/include/sequence_facade.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SEQUENCE_FACADE) +#define FUSION_INCLUDE_SEQUENCE_FACADE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/set.hpp b/thirdparty/boost/fusion/include/set.hpp new file mode 100644 index 0000000..8773bfc --- /dev/null +++ b/thirdparty/boost/fusion/include/set.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SET) +#define FUSION_INCLUDE_SET + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/set_fwd.hpp b/thirdparty/boost/fusion/include/set_fwd.hpp new file mode 100644 index 0000000..5ddbd51 --- /dev/null +++ b/thirdparty/boost/fusion/include/set_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SET_FWD) +#define FUSION_INCLUDE_SET_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/single_view.hpp b/thirdparty/boost/fusion/include/single_view.hpp new file mode 100644 index 0000000..4eebf17 --- /dev/null +++ b/thirdparty/boost/fusion/include/single_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SINGLE_VIEW) +#define FUSION_INCLUDE_SINGLE_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/size.hpp b/thirdparty/boost/fusion/include/size.hpp new file mode 100644 index 0000000..f4e8a4b --- /dev/null +++ b/thirdparty/boost/fusion/include/size.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SIZE) +#define FUSION_INCLUDE_SIZE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/std_pair.hpp b/thirdparty/boost/fusion/include/std_pair.hpp new file mode 100644 index 0000000..b15b144 --- /dev/null +++ b/thirdparty/boost/fusion/include/std_pair.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_STD_PAIR) +#define FUSION_INCLUDE_STD_PAIR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/struct.hpp b/thirdparty/boost/fusion/include/struct.hpp new file mode 100644 index 0000000..2577755 --- /dev/null +++ b/thirdparty/boost/fusion/include/struct.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_STRUCT) +#define FUSION_INCLUDE_STRUCT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/support.hpp b/thirdparty/boost/fusion/include/support.hpp new file mode 100644 index 0000000..725aee5 --- /dev/null +++ b/thirdparty/boost/fusion/include/support.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SUPPORT) +#define FUSION_INCLUDE_SUPPORT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/swap.hpp b/thirdparty/boost/fusion/include/swap.hpp new file mode 100644 index 0000000..370b2b6 --- /dev/null +++ b/thirdparty/boost/fusion/include/swap.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_SWAP) +#define FUSION_INCLUDE_SWAP + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/tag_of.hpp b/thirdparty/boost/fusion/include/tag_of.hpp new file mode 100644 index 0000000..d07860f --- /dev/null +++ b/thirdparty/boost/fusion/include/tag_of.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TAG_OF) +#define FUSION_INCLUDE_TAG_OF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/tag_of_fwd.hpp b/thirdparty/boost/fusion/include/tag_of_fwd.hpp new file mode 100644 index 0000000..a0184da --- /dev/null +++ b/thirdparty/boost/fusion/include/tag_of_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TAG_OF_FWD) +#define FUSION_INCLUDE_TAG_OF_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/transform.hpp b/thirdparty/boost/fusion/include/transform.hpp new file mode 100644 index 0000000..cbc6dcb --- /dev/null +++ b/thirdparty/boost/fusion/include/transform.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TRANSFORM) +#define FUSION_INCLUDE_TRANSFORM + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/transform_view.hpp b/thirdparty/boost/fusion/include/transform_view.hpp new file mode 100644 index 0000000..fe36280 --- /dev/null +++ b/thirdparty/boost/fusion/include/transform_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TRANSFORM_VIEW) +#define FUSION_INCLUDE_TRANSFORM_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/transformation.hpp b/thirdparty/boost/fusion/include/transformation.hpp new file mode 100644 index 0000000..5a0b7e3 --- /dev/null +++ b/thirdparty/boost/fusion/include/transformation.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TRANSFORMATION) +#define FUSION_INCLUDE_TRANSFORMATION + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/tuple.hpp b/thirdparty/boost/fusion/include/tuple.hpp new file mode 100644 index 0000000..01176b2 --- /dev/null +++ b/thirdparty/boost/fusion/include/tuple.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TUPLE) +#define FUSION_INCLUDE_TUPLE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/tuple_fwd.hpp b/thirdparty/boost/fusion/include/tuple_fwd.hpp new file mode 100644 index 0000000..cbf52d8 --- /dev/null +++ b/thirdparty/boost/fusion/include/tuple_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TUPLE_FWD) +#define FUSION_INCLUDE_TUPLE_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/tuple_tie.hpp b/thirdparty/boost/fusion/include/tuple_tie.hpp new file mode 100644 index 0000000..c1c4aae --- /dev/null +++ b/thirdparty/boost/fusion/include/tuple_tie.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_TUPLE_TIE) +#define FUSION_INCLUDE_TUPLE_TIE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/unfused_generic.hpp b/thirdparty/boost/fusion/include/unfused_generic.hpp new file mode 100644 index 0000000..e916fab --- /dev/null +++ b/thirdparty/boost/fusion/include/unfused_generic.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_UNFUSED_GENERIC) +#define FUSION_INCLUDE_UNFUSED_GENERIC + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/unfused_lvalue_args.hpp b/thirdparty/boost/fusion/include/unfused_lvalue_args.hpp new file mode 100644 index 0000000..8c79871 --- /dev/null +++ b/thirdparty/boost/fusion/include/unfused_lvalue_args.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_UNFUSED_LVALUE_ARGS) +#define FUSION_INCLUDE_UNFUSED_LVALUE_ARGS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/unfused_rvalue_args.hpp b/thirdparty/boost/fusion/include/unfused_rvalue_args.hpp new file mode 100644 index 0000000..fbd1f63 --- /dev/null +++ b/thirdparty/boost/fusion/include/unfused_rvalue_args.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_UNFUSED_RVALUE_ARGS) +#define FUSION_INCLUDE_UNFUSED_RVALUE_ARGS + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/unfused_typed.hpp b/thirdparty/boost/fusion/include/unfused_typed.hpp new file mode 100644 index 0000000..fd6b085 --- /dev/null +++ b/thirdparty/boost/fusion/include/unfused_typed.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_UNFUSED_TYPED) +#define FUSION_INCLUDE_UNFUSED_TYPED + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/unused.hpp b/thirdparty/boost/fusion/include/unused.hpp new file mode 100644 index 0000000..e2c52cf --- /dev/null +++ b/thirdparty/boost/fusion/include/unused.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_UNUSED) +#define FUSION_INCLUDE_UNUSED + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/value_at.hpp b/thirdparty/boost/fusion/include/value_at.hpp new file mode 100644 index 0000000..3b246f6 --- /dev/null +++ b/thirdparty/boost/fusion/include/value_at.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VALUE_AT) +#define FUSION_INCLUDE_VALUE_AT + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/value_at_key.hpp b/thirdparty/boost/fusion/include/value_at_key.hpp new file mode 100644 index 0000000..e8c0595 --- /dev/null +++ b/thirdparty/boost/fusion/include/value_at_key.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VALUE_AT_KEY) +#define FUSION_INCLUDE_VALUE_AT_KEY + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/value_of.hpp b/thirdparty/boost/fusion/include/value_of.hpp new file mode 100644 index 0000000..33a6321 --- /dev/null +++ b/thirdparty/boost/fusion/include/value_of.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VALUE_OF) +#define FUSION_INCLUDE_VALUE_OF + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector.hpp b/thirdparty/boost/fusion/include/vector.hpp new file mode 100644 index 0000000..4520156 --- /dev/null +++ b/thirdparty/boost/fusion/include/vector.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR) +#define FUSION_INCLUDE_VECTOR + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector10.hpp b/thirdparty/boost/fusion/include/vector10.hpp new file mode 100644 index 0000000..6d92c54 --- /dev/null +++ b/thirdparty/boost/fusion/include/vector10.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR10) +#define FUSION_INCLUDE_VECTOR10 + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector20.hpp b/thirdparty/boost/fusion/include/vector20.hpp new file mode 100644 index 0000000..408c87f --- /dev/null +++ b/thirdparty/boost/fusion/include/vector20.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR20) +#define FUSION_INCLUDE_VECTOR20 + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector30.hpp b/thirdparty/boost/fusion/include/vector30.hpp new file mode 100644 index 0000000..d8dddaa --- /dev/null +++ b/thirdparty/boost/fusion/include/vector30.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR30) +#define FUSION_INCLUDE_VECTOR30 + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector40.hpp b/thirdparty/boost/fusion/include/vector40.hpp new file mode 100644 index 0000000..ebac151 --- /dev/null +++ b/thirdparty/boost/fusion/include/vector40.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR40) +#define FUSION_INCLUDE_VECTOR40 + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector50.hpp b/thirdparty/boost/fusion/include/vector50.hpp new file mode 100644 index 0000000..b3e352b --- /dev/null +++ b/thirdparty/boost/fusion/include/vector50.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR50) +#define FUSION_INCLUDE_VECTOR50 + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector_fwd.hpp b/thirdparty/boost/fusion/include/vector_fwd.hpp new file mode 100644 index 0000000..de13429 --- /dev/null +++ b/thirdparty/boost/fusion/include/vector_fwd.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR_FWD) +#define FUSION_INCLUDE_VECTOR_FWD + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/vector_tie.hpp b/thirdparty/boost/fusion/include/vector_tie.hpp new file mode 100644 index 0000000..a5323be --- /dev/null +++ b/thirdparty/boost/fusion/include/vector_tie.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VECTOR_TIE) +#define FUSION_INCLUDE_VECTOR_TIE + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/view.hpp b/thirdparty/boost/fusion/include/view.hpp new file mode 100644 index 0000000..c7c2405 --- /dev/null +++ b/thirdparty/boost/fusion/include/view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VIEW) +#define FUSION_INCLUDE_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/void.hpp b/thirdparty/boost/fusion/include/void.hpp new file mode 100644 index 0000000..b540320 --- /dev/null +++ b/thirdparty/boost/fusion/include/void.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_VOID) +#define FUSION_INCLUDE_VOID + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/zip.hpp b/thirdparty/boost/fusion/include/zip.hpp new file mode 100644 index 0000000..c93da43 --- /dev/null +++ b/thirdparty/boost/fusion/include/zip.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ZIP) +#define FUSION_INCLUDE_ZIP + +#include + +#endif diff --git a/thirdparty/boost/fusion/include/zip_view.hpp b/thirdparty/boost/fusion/include/zip_view.hpp new file mode 100644 index 0000000..dbc369a --- /dev/null +++ b/thirdparty/boost/fusion/include/zip_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INCLUDE_ZIP_VIEW) +#define FUSION_INCLUDE_ZIP_VIEW + +#include + +#endif diff --git a/thirdparty/boost/fusion/iterator.hpp b/thirdparty/boost/fusion/iterator.hpp new file mode 100644 index 0000000..c8c8d04 --- /dev/null +++ b/thirdparty/boost/fusion/iterator.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ITERATOR_10022005_0559) +#define FUSION_ITERATOR_10022005_0559 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/iterator/advance.hpp b/thirdparty/boost/fusion/iterator/advance.hpp new file mode 100644 index 0000000..50dd509 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/advance.hpp @@ -0,0 +1,92 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_09172005_1146) +#define FUSION_ADVANCE_09172005_1146 + +#include +#include + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct advance_impl + { + // default implementation + template + struct apply : + mpl::if_c< + (N::value > 0) + , advance_detail::forward + , advance_detail::backward + >::type + { + BOOST_MPL_ASSERT_NOT((traits::is_random_access)); + }; + }; + + template <> + struct advance_impl + { + template + struct apply : Iterator::template advance {}; + }; + + template <> + struct advance_impl; + + template <> + struct advance_impl; + + template <> + struct advance_impl; + } + + namespace result_of + { + template + struct advance_c + : extension::advance_impl::type>::template apply > + {}; + + template + struct advance + : extension::advance_impl::type>::template apply + {}; + } + + template + inline typename result_of::advance_c::type const + advance_c(Iterator const& i) + { + return result_of::advance_c::call(i); + } + + template + inline typename result_of::advance::type const + advance(Iterator const& i) + { + return result_of::advance::call(i); + } + +}} // namespace boost::fusion + +#endif diff --git a/thirdparty/boost/fusion/iterator/deref.hpp b/thirdparty/boost/fusion/iterator/deref.hpp new file mode 100644 index 0000000..8cba4f9 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/deref.hpp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_05042005_1019) +#define FUSION_DEREF_05042005_1019 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct deref_impl + { + template + struct apply {}; + }; + + template <> + struct deref_impl + { + template + struct apply : Iterator::template deref {}; + }; + + template <> + struct deref_impl; + + template <> + struct deref_impl; + + template <> + struct deref_impl; + } + + namespace result_of + { + template + struct deref + : extension::deref_impl::type>:: + template apply + {}; + } + + template + typename result_of::deref::type + deref(Iterator const& i) + { + typedef result_of::deref deref_meta; + return deref_meta::call(i); + } + + template + typename result_of::deref::type + operator*(iterator_base const& i) + { + return fusion::deref(i.cast()); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/detail/adapt_deref_traits.hpp b/thirdparty/boost/fusion/iterator/detail/adapt_deref_traits.hpp new file mode 100644 index 0000000..cbaf808 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/detail/adapt_deref_traits.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADAPT_DEREF_TRAITS_05062005_0900) +#define FUSION_ADAPT_DEREF_TRAITS_05062005_0900 + +#include + +namespace boost { namespace fusion { namespace detail +{ + struct adapt_deref_traits + { + template + struct apply + { + typedef typename + result_of::deref::type + type; + + static type + call(Iterator const& i) + { + return *i.first; + } + }; + }; +}}} + +#endif + + diff --git a/thirdparty/boost/fusion/iterator/detail/adapt_value_traits.hpp b/thirdparty/boost/fusion/iterator/detail/adapt_value_traits.hpp new file mode 100644 index 0000000..96434fc --- /dev/null +++ b/thirdparty/boost/fusion/iterator/detail/adapt_value_traits.hpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADAPT_VALUE_TRAITS_05062005_0859) +#define FUSION_ADAPT_VALUE_TRAITS_05062005_0859 + +#include + +namespace boost { namespace fusion { namespace detail +{ + struct adapt_value_traits + { + template + struct apply + { + typedef typename + result_of::value_of::type + type; + }; + }; +}}} + +#endif + + diff --git a/thirdparty/boost/fusion/iterator/detail/advance.hpp b/thirdparty/boost/fusion/iterator/detail/advance.hpp new file mode 100644 index 0000000..74d3ca9 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/detail/advance.hpp @@ -0,0 +1,102 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_09172005_1149) +#define FUSION_ADVANCE_09172005_1149 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace advance_detail +{ + // Default advance implementation, perform next(i) + // or prior(i) N times. + + template + struct forward; + + template + struct next_forward + { + typedef typename + forward< + typename result_of::next::type + , N-1 + >::type + type; + }; + + template + struct forward + { + typedef typename + mpl::eval_if_c< + (N == 0) + , mpl::identity + , next_forward + >::type + type; + + static type const& + call(type const& i) + { + return i; + } + + template + static type + call(I const& i) + { + return call(fusion::next(i)); + } + }; + + template + struct backward; + + template + struct next_backward + { + typedef typename + backward< + typename result_of::prior::type + , N+1 + >::type + type; + }; + + template + struct backward + { + typedef typename + mpl::eval_if_c< + (N == 0) + , mpl::identity + , next_backward + >::type + type; + + static type const& + call(type const& i) + { + return i; + } + + template + static type + call(I const& i) + { + return call(fusion::prior(i)); + } + }; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/detail/distance.hpp b/thirdparty/boost/fusion/iterator/detail/distance.hpp new file mode 100644 index 0000000..9d24d1d --- /dev/null +++ b/thirdparty/boost/fusion/iterator/detail/distance.hpp @@ -0,0 +1,64 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_09172005_0730) +#define FUSION_DISTANCE_09172005_0730 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace distance_detail +{ + // Default distance implementation, linear + // search for the Last iterator. + + template + struct linear_distance; + + template + struct next_distance + { + typedef typename + mpl::next< + typename linear_distance< + typename result_of::next::type + , Last + >::type + >::type + type; + }; + + template + struct linear_distance + : mpl::eval_if< + result_of::equal_to + , mpl::identity > + , next_distance + >::type + { + typedef typename + mpl::eval_if< + result_of::equal_to + , mpl::identity > + , next_distance + >::type + type; + + static type + call(First const&, Last const&) + { + return type(); + } + }; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/distance.hpp b/thirdparty/boost/fusion/iterator/distance.hpp new file mode 100644 index 0000000..4a6517f --- /dev/null +++ b/thirdparty/boost/fusion/iterator/distance.hpp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_09172005_0721) +#define FUSION_DISTANCE_09172005_0721 + +#include +#include + +#include +#include +#include + +#include + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct distance_impl + { + // default implementation + template + struct apply : distance_detail::linear_distance + { + BOOST_MPL_ASSERT_NOT((traits::is_random_access)); + BOOST_MPL_ASSERT_NOT((traits::is_random_access)); + }; + }; + + template <> + struct distance_impl + { + template + struct apply : First::template distance {}; + }; + + template <> + struct distance_impl; + + template <> + struct distance_impl; + + template <> + struct distance_impl; + } + + namespace result_of + { + template + struct distance + : extension::distance_impl::type>:: + template apply + { + typedef typename extension::distance_impl::type>:: + template apply::type distance_application; + BOOST_STATIC_CONSTANT(int, value = distance_application::value); + }; + } + + template + inline typename result_of::distance::type + distance(First const& a, Last const& b) + { + return result_of::distance::call(a,b); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/equal_to.hpp b/thirdparty/boost/fusion/iterator/equal_to.hpp new file mode 100644 index 0000000..23f4312 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/equal_to.hpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_05052005_1208) +#define FUSION_EQUAL_TO_05052005_1208 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct equal_to_impl + { + // default implementation + template + struct apply + : is_same::type, typename add_const::type> + {}; + }; + + template <> + struct equal_to_impl + { + template + struct apply : I1::template equal_to {}; + }; + + template <> + struct equal_to_impl; + + template <> + struct equal_to_impl; + + template <> + struct equal_to_impl; + } + + namespace result_of + { + template + struct equal_to + : extension::equal_to_impl::type>:: + template apply + {}; + } + + namespace iterator_operators + { + template + inline typename + enable_if< + mpl::and_, is_fusion_iterator > + , bool + >::type + operator==(Iter1 const&, Iter2 const&) + { + return result_of::equal_to::value; + } + + template + inline typename + enable_if< + mpl::and_, is_fusion_iterator > + , bool + >::type + operator!=(Iter1 const&, Iter2 const&) + { + return !result_of::equal_to::value; + } + } + + using iterator_operators::operator==; + using iterator_operators::operator!=; +}} + +#endif + diff --git a/thirdparty/boost/fusion/iterator/iterator_facade.hpp b/thirdparty/boost/fusion/iterator/iterator_facade.hpp new file mode 100644 index 0000000..a0c196c --- /dev/null +++ b/thirdparty/boost/fusion/iterator/iterator_facade.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ITERATOR_FACADE_09252006_1011) +#define FUSION_ITERATOR_FACADE_09252006_1011 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct iterator_facade_tag; + + template + struct iterator_facade : iterator_base + { + typedef iterator_facade_tag fusion_tag; + typedef Derived derived_type; + typedef Category category; + + // default implementation + template + struct equal_to // default implementation + : is_same< + typename I1::derived_type + , typename I2::derived_type + > + {}; + + // default implementation + template + struct advance : + mpl::if_c< + (N::value > 0) + , advance_detail::forward + , advance_detail::backward + >::type + { + BOOST_MPL_ASSERT_NOT((traits::is_random_access)); + }; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/mpl.hpp b/thirdparty/boost/fusion/iterator/mpl.hpp new file mode 100644 index 0000000..06d5141 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/mpl.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ITERATOR_MPL_10022005_0557) +#define FUSION_ITERATOR_MPL_10022005_0557 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/iterator/mpl/convert_iterator.hpp b/thirdparty/boost/fusion/iterator/mpl/convert_iterator.hpp new file mode 100644 index 0000000..16fd22a --- /dev/null +++ b/thirdparty/boost/fusion/iterator/mpl/convert_iterator.hpp @@ -0,0 +1,58 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_ITERATOR_05062005_1218) +#define FUSION_CONVERT_ITERATOR_05062005_1218 + +#include +#include +#include + +namespace boost { namespace fusion +{ + template + struct mpl_iterator; // forward declaration + + // Test T. If it is a fusion iterator, return a reference to it. + // else, assume it is an mpl iterator. + + template + struct convert_iterator + { + typedef typename + mpl::if_< + is_fusion_iterator + , T + , mpl_iterator + >::type + type; + + static T const& + call(T const& x, mpl::true_) + { + return x; + } + + static mpl_iterator + call(T const& x, mpl::false_) + { + return mpl_iterator(); + } + + static typename + mpl::if_< + is_fusion_iterator + , T const& + , mpl_iterator + >::type + call(T const& x) + { + return call(x, is_fusion_iterator()); + } + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/mpl/fusion_iterator.hpp b/thirdparty/boost/fusion/iterator/mpl/fusion_iterator.hpp new file mode 100644 index 0000000..0950637 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/mpl/fusion_iterator.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FUSION_ITERATOR_10012005_1551) +#define FUSION_FUSION_ITERATOR_10012005_1551 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct fusion_iterator + { + typedef typename fusion::result_of::value_of::type type; + typedef typename fusion::traits::category_of::type category; + typedef Iterator iterator; + }; + + template + struct next > + { + typedef fusion_iterator::type> type; + }; + + template + struct prior > + { + typedef fusion_iterator::type> type; + }; + + template + struct advance, N> + { + typedef fusion_iterator::type> type; + }; + + template + struct distance, fusion_iterator > + : fusion::result_of::distance + {}; + +}} + +#endif + + diff --git a/thirdparty/boost/fusion/iterator/next.hpp b/thirdparty/boost/fusion/iterator/next.hpp new file mode 100644 index 0000000..2ac83e0 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/next.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_05042005_1101) +#define FUSION_NEXT_05042005_1101 + +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct next_impl + { + template + struct apply {}; + }; + + template <> + struct next_impl + { + template + struct apply : Iterator::template next {}; + }; + + template <> + struct next_impl; + + template <> + struct next_impl; + + template <> + struct next_impl; + } + + namespace result_of + { + template + struct next + : extension::next_impl::type>:: + template apply + {}; + } + + template + typename result_of::next::type const + next(Iterator const& i) + { + return result_of::next::call(i); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/prior.hpp b/thirdparty/boost/fusion/iterator/prior.hpp new file mode 100644 index 0000000..49c55ca --- /dev/null +++ b/thirdparty/boost/fusion/iterator/prior.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PRIOR_05042005_1144) +#define FUSION_PRIOR_05042005_1144 + +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct prior_impl + { + template + struct apply {}; + }; + + template <> + struct prior_impl + { + template + struct apply : Iterator::template prior {}; + }; + + template <> + struct prior_impl; + + template <> + struct prior_impl; + + template <> + struct prior_impl; + } + + namespace result_of + { + template + struct prior + : extension::prior_impl::type>:: + template apply + {}; + } + + template + typename result_of::prior::type const + prior(Iterator const& i) + { + return result_of::prior::call(i); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/iterator/value_of.hpp b/thirdparty/boost/fusion/iterator/value_of.hpp new file mode 100644 index 0000000..18a9b46 --- /dev/null +++ b/thirdparty/boost/fusion/iterator/value_of.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_05052005_1126) +#define FUSION_VALUE_OF_05052005_1126 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct iterator_facade_tag; // iterator facade tag + struct array_iterator_tag; // boost::array iterator tag + struct mpl_iterator_tag; // mpl sequence iterator tag + struct std_pair_iterator_tag; // std::pair iterator tag + + namespace extension + { + template + struct value_of_impl + { + template + struct apply {}; + }; + + template <> + struct value_of_impl + { + template + struct apply : Iterator::template value_of {}; + }; + + template <> + struct value_of_impl; + + template <> + struct value_of_impl; + + template <> + struct value_of_impl; + } + + namespace result_of + { + template + struct value_of + : extension::value_of_impl::type>:: + template apply + {}; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl.hpp b/thirdparty/boost/fusion/mpl.hpp new file mode 100644 index 0000000..75a0622 --- /dev/null +++ b/thirdparty/boost/fusion/mpl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MPL_09172006_2049) +#define FUSION_MPL_09172006_2049 + +// The fusion <--> MPL link headers +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/mpl/at.hpp b/thirdparty/boost/fusion/mpl/at.hpp new file mode 100644 index 0000000..8dd6206 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/at.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_10022005_1616) +#define FUSION_AT_10022005_1616 + +#include +#include + +namespace boost { +namespace fusion +{ + struct fusion_sequence_tag; +} + +namespace mpl +{ + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply : fusion::result_of::value_at {}; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/back.hpp b/thirdparty/boost/fusion/mpl/back.hpp new file mode 100644 index 0000000..b80a0c8 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/back.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BACK_10022005_1620) +#define FUSION_BACK_10022005_1620 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct back_impl; + + template <> + struct back_impl + { + template + struct apply : + fusion::result_of::value_of< + typename fusion::result_of::prior< + typename fusion::result_of::end::type + >::type> {}; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/begin.hpp b/thirdparty/boost/fusion/mpl/begin.hpp new file mode 100644 index 0000000..532ad19 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/begin.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_10022005_1620) +#define FUSION_BEGIN_10022005_1620 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef fusion_iterator::type> type; + }; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/clear.hpp b/thirdparty/boost/fusion/mpl/clear.hpp new file mode 100644 index 0000000..fb94dab --- /dev/null +++ b/thirdparty/boost/fusion/mpl/clear.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CLEAR_10022005_1817) +#define FUSION_CLEAR_10022005_1817 + +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct clear_impl; + + template <> + struct clear_impl + { + template + struct apply + { + typedef typename + fusion::detail::clear::type>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/detail/clear.hpp b/thirdparty/boost/fusion/mpl/detail/clear.hpp new file mode 100644 index 0000000..8c1447a --- /dev/null +++ b/thirdparty/boost/fusion/mpl/detail/clear.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CLEAR_10022005_1442) +#define FUSION_CLEAR_10022005_1442 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct cons_tag; + struct map_tag; + struct set_tag; + struct vector_tag; + struct deque_tag; + + namespace detail + { + template + struct clear; + + template <> + struct clear : mpl::identity > {}; + + template <> + struct clear : mpl::identity > {}; + + template <> + struct clear : mpl::identity > {}; + + template <> + struct clear : mpl::identity > {}; + + template <> + struct clear : mpl::identity > {}; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/empty.hpp b/thirdparty/boost/fusion/mpl/empty.hpp new file mode 100644 index 0000000..15c7d64 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/empty.hpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EMPTY_10022005_1619) +#define FUSION_EMPTY_10022005_1619 + +#include +#include + +namespace boost { namespace mpl +{ + template + struct empty_impl; + + template <> + struct empty_impl + { + template + struct apply : fusion::result_of::empty {}; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/end.hpp b/thirdparty/boost/fusion/mpl/end.hpp new file mode 100644 index 0000000..dfcb37a --- /dev/null +++ b/thirdparty/boost/fusion/mpl/end.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_10022005_1619) +#define FUSION_END_10022005_1619 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef fusion_iterator::type> type; + }; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/erase.hpp b/thirdparty/boost/fusion/mpl/erase.hpp new file mode 100644 index 0000000..9853465 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/erase.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ERASE_10022005_1835) +#define FUSION_ERASE_10022005_1835 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct erase_impl; + + template <> + struct erase_impl + { + template + struct apply + { + typedef typename + fusion::result_of::erase::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/erase_key.hpp b/thirdparty/boost/fusion/mpl/erase_key.hpp new file mode 100644 index 0000000..0816287 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/erase_key.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ERASE_KEY_10022005_1907) +#define FUSION_ERASE_KEY_10022005_1907 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct erase_key_impl; + + template <> + struct erase_key_impl + { + template + struct apply + { + typedef typename + fusion::result_of::erase_key::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/front.hpp b/thirdparty/boost/fusion/mpl/front.hpp new file mode 100644 index 0000000..1c58225 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/front.hpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FRONT_10022005_1618) +#define FUSION_FRONT_10022005_1618 + +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct front_impl; + + template <> + struct front_impl + { + template + struct apply : + fusion::result_of::value_of::type> {}; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/mpl/has_key.hpp b/thirdparty/boost/fusion/mpl/has_key.hpp new file mode 100644 index 0000000..f64acc9 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/has_key.hpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_HAS_KEY_10022005_1617) +#define FUSION_HAS_KEY_10022005_1617 + +#include +#include + +namespace boost { namespace mpl +{ + template + struct has_key_impl; + + template <> + struct has_key_impl + { + template + struct apply : fusion::result_of::has_key {}; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/insert.hpp b/thirdparty/boost/fusion/mpl/insert.hpp new file mode 100644 index 0000000..006282f --- /dev/null +++ b/thirdparty/boost/fusion/mpl/insert.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INSERT_10022005_1837) +#define FUSION_INSERT_10022005_1837 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct insert_impl; + + template <> + struct insert_impl + { + template + struct apply + { + typedef typename + fusion::result_of::insert::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/insert_range.hpp b/thirdparty/boost/fusion/mpl/insert_range.hpp new file mode 100644 index 0000000..36765bb --- /dev/null +++ b/thirdparty/boost/fusion/mpl/insert_range.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_INSERT_RANGE_10022005_1838) +#define FUSION_INSERT_RANGE_10022005_1838 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct insert_range_impl; + + template <> + struct insert_range_impl + { + template + struct apply + { + typedef typename + fusion::result_of::insert_range::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/pop_back.hpp b/thirdparty/boost/fusion/mpl/pop_back.hpp new file mode 100644 index 0000000..379a4b6 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/pop_back.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_POP_BACK_10022005_1801) +#define FUSION_POP_BACK_10022005_1801 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct pop_back_impl; + + template <> + struct pop_back_impl + { + template + struct apply + { + typedef typename + fusion::result_of::pop_back::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/pop_front.hpp b/thirdparty/boost/fusion/mpl/pop_front.hpp new file mode 100644 index 0000000..175ad8d --- /dev/null +++ b/thirdparty/boost/fusion/mpl/pop_front.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_POP_FRONT_10022005_1800) +#define FUSION_POP_FRONT_10022005_1800 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct pop_front_impl; + + template <> + struct pop_front_impl + { + template + struct apply + { + typedef typename + fusion::result_of::pop_front::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/push_back.hpp b/thirdparty/boost/fusion/mpl/push_back.hpp new file mode 100644 index 0000000..09ca085 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/push_back.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PUSH_BACK_10022005_1647) +#define FUSION_PUSH_BACK_10022005_1647 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct push_back_impl; + + template <> + struct push_back_impl + { + template + struct apply + { + typedef typename + fusion::result_of::push_back::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/push_front.hpp b/thirdparty/boost/fusion/mpl/push_front.hpp new file mode 100644 index 0000000..15d5622 --- /dev/null +++ b/thirdparty/boost/fusion/mpl/push_front.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PUSH_FRONT_10022005_1720) +#define FUSION_PUSH_FRONT_10022005_1720 + +#include +#include +#include +#include + +namespace boost { namespace mpl +{ + template + struct push_front_impl; + + template <> + struct push_front_impl + { + template + struct apply + { + typedef typename + fusion::result_of::push_front::type + result; + + typedef typename + fusion::result_of::convert< + typename fusion::detail::tag_of::type, result>::type + type; + }; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/mpl/size.hpp b/thirdparty/boost/fusion/mpl/size.hpp new file mode 100644 index 0000000..0b2f06c --- /dev/null +++ b/thirdparty/boost/fusion/mpl/size.hpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SIZE_10022005_1617) +#define FUSION_SIZE_10022005_1617 + +#include +#include + +namespace boost { namespace mpl +{ + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply : fusion::result_of::size {}; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence.hpp b/thirdparty/boost/fusion/sequence.hpp new file mode 100644 index 0000000..bffd60d --- /dev/null +++ b/thirdparty/boost/fusion/sequence.hpp @@ -0,0 +1,16 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_10022005_0559) +#define FUSION_ITERATOR_10022005_0559 + +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison.hpp b/thirdparty/boost/fusion/sequence/comparison.hpp new file mode 100644 index 0000000..a4325ad --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_COMPARISON_10022005_0615) +#define FUSION_SEQUENCE_COMPARISON_10022005_0615 + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/enable_comparison.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/enable_comparison.hpp new file mode 100644 index 0000000..c393086 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/enable_comparison.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ENABLE_COMPARISON_09232005_1958) +#define FUSION_ENABLE_COMPARISON_09232005_1958 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct is_native_fusion_sequence : is_base_of {}; + + template + struct enable_equality + : mpl::or_, is_native_fusion_sequence > + {}; + + template + struct enable_comparison + : mpl::and_< + mpl::or_, is_native_fusion_sequence > + , mpl::equal_to, result_of::size > + > + {}; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/equal_to.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/equal_to.hpp new file mode 100644 index 0000000..b85d00f --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/equal_to.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_05052005_1142) +#define FUSION_EQUAL_TO_05052005_1142 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_equal_to + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return true; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a == *b + && call(fusion::next(a), fusion::next(b)); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; + + template + struct sequence_equal_to + { + template + static bool + call(I1 const& a, I2 const& b) + { + return false; + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/greater.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/greater.hpp new file mode 100644 index 0000000..042b402 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/greater.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_GREATER_05052005_1142) +#define FUSION_GREATER_05052005_1142 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_greater + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return false; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a > *b + || !(*b > *a) + && call(fusion::next(a), fusion::next(b)); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/greater_equal.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/greater_equal.hpp new file mode 100644 index 0000000..0468079 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/greater_equal.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_GREATER_EQUAL_05052005_1142) +#define FUSION_GREATER_EQUAL_05052005_1142 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_greater_equal + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return true; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a >= *b + && (!(*b >= *a) || call(fusion::next(a), fusion::next(b))); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/less.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/less.hpp new file mode 100644 index 0000000..16febcc --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/less.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LESS_05052005_1141) +#define FUSION_LESS_05052005_1141 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_less + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return false; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a < *b + || !(*b < *a) + && call(fusion::next(a), fusion::next(b)); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/less_equal.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/less_equal.hpp new file mode 100644 index 0000000..903ed8a --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/less_equal.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LESS_EQUAL_05052005_1141) +#define FUSION_LESS_EQUAL_05052005_1141 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_less_equal + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return true; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a <= *b + && (!(*b <= *a) || call(fusion::next(a), fusion::next(b))); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp b/thirdparty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp new file mode 100644 index 0000000..7ccb2e9 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NOT_EQUAL_TO_05052005_1141) +#define FUSION_NOT_EQUAL_TO_05052005_1141 + +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct sequence_not_equal_to + { + typedef typename result_of::end::type end1_type; + typedef typename result_of::end::type end2_type; + + template + static bool + call(I1 const&, I2 const&, mpl::true_) + { + return false; + } + + template + static bool + call(I1 const& a, I2 const& b, mpl::false_) + { + return *a != *b + || call(fusion::next(a), fusion::next(b)); + } + + template + static bool + call(I1 const& a, I2 const& b) + { + typename result_of::equal_to::type eq; + return call(a, b, eq); + } + }; + + template + struct sequence_not_equal_to + { + template + static bool + call(I1 const& a, I2 const& b) + { + return true; + } + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/equal_to.hpp b/thirdparty/boost/fusion/sequence/comparison/equal_to.hpp new file mode 100644 index 0000000..0acb54c --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/equal_to.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_05052005_0431) +#define FUSION_EQUAL_TO_05052005_0431 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + template + inline bool + equal_to(Seq1 const& a, Seq2 const& b) + { + return result_of::size::value == result_of::size::value + && detail::sequence_equal_to< + Seq1 const, Seq2 const + , result_of::size::value == result_of::size::value>:: + call(fusion::begin(a), fusion::begin(b)); + } + + namespace operators + { + template + inline typename + enable_if< + detail::enable_equality + , bool + >::type + operator==(Seq1 const& a, Seq2 const& b) + { + return fusion::equal_to(a, b); + } + } + using operators::operator==; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/greater.hpp b/thirdparty/boost/fusion/sequence/comparison/greater.hpp new file mode 100644 index 0000000..361bc2f --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/greater.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_GREATER_05052005_0432) +#define FUSION_GREATER_05052005_0432 + +#include +#include +#include +#include + +#if defined(FUSION_DIRECT_OPERATOR_USAGE) +#include +#else +#include +#endif + +namespace boost { namespace fusion +{ + template + inline bool + greater(Seq1 const& a, Seq2 const& b) + { +#if defined(FUSION_DIRECT_OPERATOR_USAGE) + return detail::sequence_greater:: + call(fusion::begin(a), fusion::begin(b)); +#else + return (b < a); +#endif + } + + namespace operators + { + template + inline typename + enable_if< + detail::enable_comparison + , bool + >::type + operator>(Seq1 const& a, Seq2 const& b) + { + return fusion::greater(a, b); + } + } + using operators::operator>; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/greater_equal.hpp b/thirdparty/boost/fusion/sequence/comparison/greater_equal.hpp new file mode 100644 index 0000000..fd1daf2 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/greater_equal.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_GREATER_EQUAL_05052005_0432) +#define FUSION_GREATER_EQUAL_05052005_0432 + +#include +#include +#include +#include + +#if defined(FUSION_DIRECT_OPERATOR_USAGE) +#include +#else +#include +#endif + +namespace boost { namespace fusion +{ + template + inline bool + greater_equal(Seq1 const& a, Seq2 const& b) + { +#if defined(FUSION_DIRECT_OPERATOR_USAGE) + return detail::sequence_greater_equal:: + call(fusion::begin(a), fusion::begin(b)); +#else + return !(a < b); +#endif + } + + namespace operators + { + template + inline typename + enable_if< + detail::enable_comparison + , bool + >::type + operator>=(Seq1 const& a, Seq2 const& b) + { + return fusion::greater_equal(a, b); + } + } + using operators::operator>=; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/less.hpp b/thirdparty/boost/fusion/sequence/comparison/less.hpp new file mode 100644 index 0000000..bb09a5c --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/less.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LESS_05052005_0432) +#define FUSION_LESS_05052005_0432 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + template + inline bool + less(Seq1 const& a, Seq2 const& b) + { + return detail::sequence_less:: + call(fusion::begin(a), fusion::begin(b)); + } + + namespace operators + { + template + inline typename + enable_if< + detail::enable_comparison + , bool + >::type + operator<(Seq1 const& a, Seq2 const& b) + { + return fusion::less(a, b); + } + } + using operators::operator<; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/less_equal.hpp b/thirdparty/boost/fusion/sequence/comparison/less_equal.hpp new file mode 100644 index 0000000..ae2b18f --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/less_equal.hpp @@ -0,0 +1,80 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_LESS_EQUAL_05052005_0432) +#define FUSION_LESS_EQUAL_05052005_0432 + +#include +#include +#include +#include + +#if defined(FUSION_DIRECT_OPERATOR_USAGE) +#include +#else +#include +#endif + +namespace boost { namespace fusion +{ + template + inline bool + less_equal(Seq1 const& a, Seq2 const& b) + { +#if defined(FUSION_DIRECT_OPERATOR_USAGE) + return detail::sequence_less_equal:: + call(fusion::begin(a), fusion::begin(b)); +#else + return !(b < a); +#endif + } + + namespace operators + { +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1400) +// Workaround for VC8.0 and VC7.1 + template + inline bool + operator<=(sequence_base const& a, sequence_base const& b) + { + return less_equal(a.derived(), b.derived()); + } + + template + inline typename disable_if, bool>::type + operator<=(sequence_base const& a, Seq2 const& b) + { + return less_equal(a.derived(), b); + } + + template + inline typename disable_if, bool>::type + operator<=(Seq1 const& a, sequence_base const& b) + { + return less_equal(a, b.derived()); + } + +#else +// Somehow VC8.0 and VC7.1 does not like this code +// but barfs somewhere else. + + template + inline typename + enable_if< + detail::enable_comparison + , bool + >::type + operator<=(Seq1 const& a, Seq2 const& b) + { + return fusion::less_equal(a, b); + } +#endif + } + using operators::operator<=; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/comparison/not_equal_to.hpp b/thirdparty/boost/fusion/sequence/comparison/not_equal_to.hpp new file mode 100644 index 0000000..1c728f9 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/comparison/not_equal_to.hpp @@ -0,0 +1,55 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NOT_EQUAL_TO_05052005_0431) +#define FUSION_NOT_EQUAL_TO_05052005_0431 + +#include +#include +#include +#include + +#if defined(FUSION_DIRECT_OPERATOR_USAGE) +#include +#else +#include +#endif + +namespace boost { namespace fusion +{ + template + inline bool + not_equal_to(Seq1 const& a, Seq2 const& b) + { +#if defined(FUSION_DIRECT_OPERATOR_USAGE) + return result_of::size::value != result_of::size::value + || detail::sequence_not_equal_to< + Seq1 const, Seq2 const + , result_of::size::value == result_of::size::value>:: + call(fusion::begin(a), fusion::begin(b)); +#else + return !(a == b); +#endif + } + + namespace operators + { + template + inline typename + enable_if< + detail::enable_equality + , bool + >::type + operator!=(Seq1 const& a, Seq2 const& b) + { + return fusion::not_equal_to(a, b); + } + } + using operators::operator!=; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/convert.hpp b/thirdparty/boost/fusion/sequence/convert.hpp new file mode 100644 index 0000000..fc12fd0 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/convert.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CONVERT_10022005_1442) +#define FUSION_CONVERT_10022005_1442 + +namespace boost { namespace fusion +{ + namespace extension + { + template + struct convert_impl; + } + + namespace result_of + { + template + struct convert + { + typedef typename extension::convert_impl gen; + + typedef typename + gen::template apply::type + type; + }; + } + + template + inline typename result_of::convert::type + convert(Sequence& seq) + { + typedef typename result_of::convert::gen gen; + return gen::call(seq); + } + + template + inline typename result_of::convert::type + convert(Sequence const& seq) + { + typedef typename result_of::convert::gen gen; + return gen::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic.hpp b/thirdparty/boost/fusion/sequence/intrinsic.hpp new file mode 100644 index 0000000..f38210e --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_INTRINSIC_10022005_0618) +#define FUSION_SEQUENCE_INTRINSIC_10022005_0618 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/at.hpp b/thirdparty/boost/fusion/sequence/intrinsic/at.hpp new file mode 100644 index 0000000..0c773e0 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/at.hpp @@ -0,0 +1,106 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_05042005_0722) +#define FUSION_AT_05042005_0722 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct at_impl + { + template + struct apply; + }; + + template <> + struct at_impl + { + template + struct apply : Sequence::template at {}; + }; + + template <> + struct at_impl; + + template <> + struct at_impl; + + template <> + struct at_impl; + + template <> + struct at_impl; + } + + namespace result_of + { + template + struct at + : extension::at_impl::type>:: + template apply + {}; + + template + struct at_c + : at > + {}; + } + + + template + inline typename + lazy_disable_if< + is_const + , result_of::at + >::type + at(Sequence& seq) + { + return result_of::at::call(seq); + } + + template + inline typename result_of::at::type + at(Sequence const& seq) + { + return result_of::at::call(seq); + } + + template + inline typename + lazy_disable_if< + is_const + , result_of::at_c + >::type + at_c(Sequence& seq) + { + return at >(seq); + } + + template + inline typename result_of::at_c::type + at_c(Sequence const& seq) + { + return at >(seq); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/sequence/intrinsic/at_key.hpp b/thirdparty/boost/fusion/sequence/intrinsic/at_key.hpp new file mode 100644 index 0000000..53eaeb7 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/at_key.hpp @@ -0,0 +1,77 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the 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_FUSION_AT_KEY_20060304_1755) +#define BOOST_FUSION_AT_KEY_20060304_1755 + +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct at_key_impl + { + template + struct apply; + }; + + template <> + struct at_key_impl + { + template + struct apply : Sequence::template at_key {}; + }; + + template <> + struct at_key_impl; + + template <> + struct at_key_impl; + + template <> + struct at_key_impl; + } + + namespace result_of + { + template + struct at_key + : extension::at_key_impl::type>:: + template apply + {}; + } + + template + inline typename + lazy_disable_if< + is_const + , result_of::at_key + >::type + at_key(Sequence& seq) + { + return result_of::at_key::call(seq); + } + + template + inline typename result_of::at_key::type + at_key(Sequence const& seq) + { + return result_of::at_key::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/back.hpp b/thirdparty/boost/fusion/sequence/intrinsic/back.hpp new file mode 100644 index 0000000..486b3f7 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/back.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BACK_09162005_0350) +#define FUSION_BACK_09162005_0350 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct fusion_sequence_tag; + + namespace result_of + { + template + struct back + : result_of::deref::type>::type> + {}; + } + + template + inline typename result_of::back::type + back(Sequence& seq) + { + return *fusion::prior(fusion::end(seq)); + } + + template + inline typename result_of::back::type + back(Sequence const& seq) + { + return *fusion::prior(fusion::end(seq)); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/begin.hpp b/thirdparty/boost/fusion/sequence/intrinsic/begin.hpp new file mode 100644 index 0000000..927d823 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/begin.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_04052005_1132) +#define FUSION_BEGIN_04052005_1132 + +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; // iterator facade tag + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct begin_impl + { + template + struct apply; + }; + + template <> + struct begin_impl + { + template + struct apply : Sequence::template begin {}; + }; + + template <> + struct begin_impl; + + template <> + struct begin_impl; + + template <> + struct begin_impl; + + template <> + struct begin_impl; + } + + namespace result_of + { + template + struct begin + : extension::begin_impl::type>:: + template apply + {}; + } + + template + inline typename result_of::begin::type const + begin(Sequence& seq) + { + return result_of::begin::call(seq); + } + + template + inline typename result_of::begin::type const + begin(Sequence const& seq) + { + return result_of::begin::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/empty.hpp b/thirdparty/boost/fusion/sequence/intrinsic/empty.hpp new file mode 100644 index 0000000..36cd55f --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/empty.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EMPTY_09162005_0335) +#define FUSION_EMPTY_09162005_0335 + +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct mpl_sequence_tag; // mpl sequence tag + + namespace extension + { + template + struct empty_impl + { + template + struct apply + : mpl::bool_<(result_of::size::value == 0)> + {}; + }; + + template <> + struct empty_impl + { + template + struct apply : Sequence::template empty {}; + }; + + template <> + struct empty_impl; + } + + namespace result_of + { + template + struct empty + : extension::empty_impl::type>:: + template apply + {}; + } + + template + inline typename result_of::empty::type + empty(Sequence const&) + { + typedef typename result_of::empty::type result; + return result(); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/end.hpp b/thirdparty/boost/fusion/sequence/intrinsic/end.hpp new file mode 100644 index 0000000..29b284c --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/end.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_04052005_1141) +#define FUSION_END_04052005_1141 + +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct end_impl + { + template + struct apply; + }; + + template <> + struct end_impl + { + template + struct apply : Sequence::template end {}; + }; + + template <> + struct end_impl; + + template <> + struct end_impl; + + template <> + struct end_impl; + + template <> + struct end_impl; + } + + namespace result_of + { + template + struct end + : extension::end_impl::type>:: + template apply + {}; + } + + template + inline typename result_of::end::type const + end(Sequence& seq) + { + return result_of::end::call(seq); + } + + template + inline typename result_of::end::type const + end(Sequence const& seq) + { + return result_of::end::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/ext_/segments.hpp b/thirdparty/boost/fusion/sequence/intrinsic/ext_/segments.hpp new file mode 100644 index 0000000..8bd1030 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/ext_/segments.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEGMENTS_04052005_1141) +#define FUSION_SEGMENTS_04052005_1141 + +#include + +namespace boost { namespace fusion +{ + // segments: returns a sequence of sequences + namespace extension + { + template + struct segments_impl + { + template + struct apply {}; + }; + } + + namespace result_of + { + template + struct segments + { + typedef typename + extension::segments_impl::type>:: + template apply::type + type; + }; + } + + template + typename result_of::segments::type + segments(Sequence & seq) + { + return + extension::segments_impl::type>:: + template apply::call(seq); + } + + template + typename result_of::segments::type + segments(Sequence const& seq) + { + return + extension::segments_impl::type>:: + template apply::call(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/ext_/size_s.hpp b/thirdparty/boost/fusion/sequence/intrinsic/ext_/size_s.hpp new file mode 100644 index 0000000..d85d97d --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/ext_/size_s.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SIZE_S_08112006_1141) +#define FUSION_SIZE_S_08112006_1141 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + /////////////////////////////////////////////////////////////////////////// + // calculates the size of any segmented data structure. + template::value> + struct segmented_size; + + namespace detail + { + struct size_plus + { + template + struct result; + + template + struct result + : mpl::plus< + segmented_size::type> + , typename remove_reference::type + > + {}; + }; + } + + /////////////////////////////////////////////////////////////////////////// + template + struct segmented_size + : result_of::fold< + typename result_of::segments::type + , mpl::size_t<0> + , detail::size_plus + >::type + {}; + + template + struct segmented_size + : result_of::size + {}; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/front.hpp b/thirdparty/boost/fusion/sequence/intrinsic/front.hpp new file mode 100644 index 0000000..0959c74 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/front.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FRONT_09162005_0343) +#define FUSION_FRONT_09162005_0343 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct fusion_sequence_tag; + + namespace result_of + { + template + struct front + : result_of::deref::type> + {}; + } + + template + inline typename result_of::front::type + front(Sequence& seq) + { + return *fusion::begin(seq); + } + + template + inline typename result_of::front::type + front(Sequence const& seq) + { + return *fusion::begin(seq); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/has_key.hpp b/thirdparty/boost/fusion/sequence/intrinsic/has_key.hpp new file mode 100644 index 0000000..63498c9 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/has_key.hpp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_HAS_KEY_09232005_1454) +#define FUSION_HAS_KEY_09232005_1454 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + // Special tags: + struct sequence_facade_tag; + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct has_key_impl + { + template + struct apply + : mpl::not_::type, void_> > + {}; + }; + + template <> + struct has_key_impl + { + template + struct apply : Sequence::template has_key {}; + }; + + template <> + struct has_key_impl; + + template <> + struct has_key_impl; + + template <> + struct has_key_impl; + } + + namespace result_of + { + template + struct has_key + : extension::has_key_impl::type>:: + template apply + {}; + } + + template + inline typename result_of::has_key::type + has_key(Sequence const& seq) + { + typedef typename result_of::has_key::type result; + return result(); + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/sequence/intrinsic/size.hpp b/thirdparty/boost/fusion/sequence/intrinsic/size.hpp new file mode 100644 index 0000000..39c9bf4 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/size.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SIZE_05052005_0214) +#define FUSION_SIZE_05052005_0214 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct size_impl + { + template + struct apply : Sequence::size {}; + }; + + template <> + struct size_impl + { + template + struct apply : Sequence::template size {}; + }; + + template <> + struct size_impl; + + template <> + struct size_impl; + + template <> + struct size_impl; + + template <> + struct size_impl; + } + + namespace result_of + { + template + struct size + : extension::size_impl::type>:: + template apply + + { + typedef typename extension::size_impl::type>:: + template apply::type size_application; + BOOST_STATIC_CONSTANT(int, value = size_application::value); + }; + } + + template + inline typename result_of::size::type + size(Sequence const&) + { + typedef typename result_of::size::type result; + return result(); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/swap.hpp b/thirdparty/boost/fusion/sequence/intrinsic/swap.hpp new file mode 100644 index 0000000..15cd899 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/swap.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the 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_FUSION_SWAP_20070501_1956) +#define BOOST_FUSION_SWAP_20070501_1956 + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + namespace result_of + { + template + struct swap + { + typedef void type; + }; + } + + namespace detail + { + struct swap + { + template + struct result + { + typedef void type; + }; + + template + void operator()(Elem const& e) const + { + using std::swap; + swap(front(e), back(e)); + } + }; + } + + template + typename enable_if, traits::is_sequence >, void>::type + swap(Seq1& lhs, Seq2& rhs) + { + typedef vector references; + for_each(zip_view(references(lhs, rhs)), detail::swap()); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/intrinsic/value_at.hpp b/thirdparty/boost/fusion/sequence/intrinsic/value_at.hpp new file mode 100644 index 0000000..8dc898b --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/value_at.hpp @@ -0,0 +1,67 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_05052005_0229) +#define FUSION_VALUE_AT_05052005_0229 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct value_at_impl + { + template + struct apply; + }; + + template <> + struct value_at_impl + { + template + struct apply : Sequence::template value_at {}; + }; + + template <> + struct value_at_impl; + + template <> + struct value_at_impl; + + template <> + struct value_at_impl; + + template <> + struct value_at_impl; + } + + namespace result_of + { + template + struct value_at + : extension::value_at_impl::type>:: + template apply + {}; + + template + struct value_at_c + : fusion::result_of::value_at > + {}; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/sequence/intrinsic/value_at_key.hpp b/thirdparty/boost/fusion/sequence/intrinsic/value_at_key.hpp new file mode 100644 index 0000000..9add446 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/intrinsic/value_at_key.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_KEY_05052005_0229) +#define FUSION_VALUE_AT_KEY_05052005_0229 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct value_at_key_impl + { + template + struct apply; + }; + + template <> + struct value_at_key_impl + { + template + struct apply : Sequence::template value_at_key {}; + }; + + template <> + struct value_at_key_impl; + + template <> + struct value_at_key_impl; + + template <> + struct value_at_key_impl; + } + + namespace result_of + { + template + struct value_at_key + : extension::value_at_key_impl::type>:: + template apply + {}; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/sequence/io.hpp b/thirdparty/boost/fusion/sequence/io.hpp new file mode 100644 index 0000000..aa6a244 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_IO_10032005_0836) +#define FUSION_SEQUENCE_IO_10032005_0836 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/sequence/io/detail/in.hpp b/thirdparty/boost/fusion/sequence/io/detail/in.hpp new file mode 100644 index 0000000..e90416a --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io/detail/in.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 1999-2003 Jeremiah Willcock + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IN_05052005_0121) +#define FUSION_IN_05052005_0121 + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct delimiter_in + { + // read a delimiter + template + static void + read(IS& is, char const* delim, mpl::false_ = mpl::false_()) + { + detail::string_ios_manip manip(is); + manip.read(delim); + } + + template + static void + read(IS& is, char const* delim, mpl::true_) + { + } + }; + + struct read_sequence_loop + { + template + static void + call(IS& is, First const&, Last const&, mpl::true_) + { + } + + template + static void + call(IS& is, First const& first, Last const& last, mpl::false_) + { + result_of::equal_to< + typename result_of::next::type + , Last + > + is_last; + + is >> *first; + delimiter_in::read(is, " ", is_last); + call(is, fusion::next(first), last, is_last); + } + + template + static void + call(IS& is, First const& first, Last const& last) + { + result_of::equal_to eq; + call(is, first, last, eq); + } + }; + + template + inline void + read_sequence(IS& is, Sequence& seq) + { + delimiter_in::read(is, "("); + read_sequence_loop::call(is, fusion::begin(seq), fusion::end(seq)); + delimiter_in::read(is, ")"); + } +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/io/detail/manip.hpp b/thirdparty/boost/fusion/sequence/io/detail/manip.hpp new file mode 100644 index 0000000..2a9dee1 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io/detail/manip.hpp @@ -0,0 +1,316 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jeremiah Willcock + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MANIP_05052005_1200) +#define FUSION_MANIP_05052005_1200 + +#include +#include +#include +#include + +// Tuple I/O manipulators + +#define FUSION_GET_CHAR_TYPE(T) typename T::char_type +#define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type + +#if defined (BOOST_NO_TEMPLATED_STREAMS) +#define FUSION_STRING_OF_STREAM(Stream) std::string +#else +#define FUSION_STRING_OF_STREAM(Stream) \ + std::basic_string< \ + FUSION_GET_CHAR_TYPE(Stream) \ + , FUSION_GET_TRAITS_TYPE(Stream) \ + > +#endif + +//$$$ these should be part of the public API$$$ +//$$$ rename tuple_open, tuple_close and tuple_delimiter to +// open, close and delimeter and add these synonyms to the +// TR1 tuple module. + +namespace boost { namespace fusion +{ + namespace detail + { + template + int get_xalloc_index(Tag* = 0) + { + // each Tag will have a unique index + static int index = std::ios::xalloc(); + return index; + } + + template + struct stream_data + { + struct arena + { + ~arena() + { + for ( + typename std::vector::iterator i = data.begin() + ; i != data.end() + ; ++i) + { + delete *i; + } + } + + std::vector data; + }; + + static void attach(Stream& stream, T const& data) + { + static arena ar; // our arena + ar.data.push_back(new T(data)); + stream.pword(get_xalloc_index()) = ar.data.back(); + } + + static T const* get(Stream& stream) + { + return (T const*)stream.pword(get_xalloc_index()); + } + }; + + template + class string_ios_manip + { + public: + + typedef FUSION_STRING_OF_STREAM(Stream) string_type; + + typedef stream_data stream_data_t; + + string_ios_manip(Stream& str_) + : stream(str_) + {} + + void + set(string_type const& s) + { + stream_data_t::attach(stream, s); + } + + void + print(char const* default_) const + { + // print a delimiter + string_type const* p = stream_data_t::get(stream); + if (p) + stream << *p; + else + stream << default_; + } + + void + read(char const* default_) const + { + // read a delimiter + string_type const* p = stream_data_t::get(stream); + using namespace std; + ws(stream); + + if (p) + { + typedef typename string_type::const_iterator iterator; + for (iterator i = p->begin(); i != p->end(); ++i) + check_delim(*i); + } + else + { + while (*default_) + check_delim(*default_++); + } + } + + private: + + template + void + check_delim(Char c) const + { + if (!isspace(c)) + { + if (stream.get() != c) + { + stream.unget(); + stream.setstate(std::ios::failbit); + } + } + } + + Stream& stream; + }; + + } // detail + +#if defined (BOOST_NO_TEMPLATED_STREAMS) + +#define STD_TUPLE_DEFINE_MANIPULATOR(name) \ + namespace detail \ + { \ + struct name##_tag; \ + \ + struct name##_type \ + { \ + typedef std::string string_type; \ + string_type data; \ + name##_type(const string_type& d): data(d) {} \ + }; \ + \ + template \ + Stream& operator>>(Stream& s, const name##_type& m) \ + { \ + string_ios_manip(s).set(m.data); \ + return s; \ + } \ + \ + template \ + Stream& operator<<(Stream& s, const name##_type& m) \ + { \ + string_ios_manip(s).set(m.data); \ + return s; \ + } \ + } + +#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \ + inline detail::name##_type \ + name(const std::string& s) \ + { \ + return detail::name##_type(s); \ + } \ + \ + inline detail::name##_type \ + name(const char* s) \ + { \ + return detail::name##_type(std::string(s)); \ + } \ + \ + inline detail::name##_type \ + name(char c) \ + { \ + return detail::name##_type(std::string(1, c)); \ + } + +#else // defined(BOOST_NO_TEMPLATED_STREAMS) + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \ + template \ + inline detail::name##_type \ + name(const std::basic_string& s) \ + { \ + return detail::name##_type(s); \ + } \ + \ + inline detail::name##_type \ + name(char const* s) \ + { \ + return detail::name##_type(std::basic_string(s)); \ + } \ + \ + inline detail::name##_type \ + name(wchar_t const* s) \ + { \ + return detail::name##_type(std::basic_string(s)); \ + } \ + \ + inline detail::name##_type \ + name(char c) \ + { \ + return detail::name##_type(std::basic_string(1, c)); \ + } \ + \ + inline detail::name##_type \ + name(wchar_t c) \ + { \ + return detail::name##_type(std::basic_string(1, c)); \ + } + +#else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \ + template \ + inline detail::name##_type \ + name(const std::basic_string& s) \ + { \ + return detail::name##_type(s); \ + } \ + \ + template \ + inline detail::name##_type \ + name(Char s[]) \ + { \ + return detail::name##_type(std::basic_string(s)); \ + } \ + \ + template \ + inline detail::name##_type \ + name(Char const s[]) \ + { \ + return detail::name##_type(std::basic_string(s)); \ + } \ + \ + template \ + inline detail::name##_type \ + name(Char c) \ + { \ + return detail::name##_type(std::basic_string(1, c)); \ + } + +#endif + +#define STD_TUPLE_DEFINE_MANIPULATOR(name) \ + namespace detail \ + { \ + struct name##_tag; \ + \ + template > \ + struct name##_type \ + { \ + typedef std::basic_string string_type; \ + string_type data; \ + name##_type(const string_type& d): data(d) {} \ + }; \ + \ + template \ + Stream& operator>>(Stream& s, const name##_type& m) \ + { \ + string_ios_manip(s).set(m.data); \ + return s; \ + } \ + \ + template \ + Stream& operator<<(Stream& s, const name##_type& m) \ + { \ + string_ios_manip(s).set(m.data); \ + return s; \ + } \ + } \ + +#endif // defined(BOOST_NO_TEMPLATED_STREAMS) + + STD_TUPLE_DEFINE_MANIPULATOR(tuple_open) + STD_TUPLE_DEFINE_MANIPULATOR(tuple_close) + STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter) + + STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open) + STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close) + STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter) + +#undef STD_TUPLE_DEFINE_MANIPULATOR +#undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS +#undef FUSION_STRING_OF_STREAM +#undef FUSION_GET_CHAR_TYPE +#undef FUSION_GET_TRAITS_TYPE + +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/io/detail/out.hpp b/thirdparty/boost/fusion/sequence/io/detail/out.hpp new file mode 100644 index 0000000..7167b58 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io/detail/out.hpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 1999-2003 Jeremiah Willcock + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_OUT_05052005_0121) +#define FUSION_OUT_05052005_0121 + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct delimiter_out + { + // print a delimiter + template + static void + print(OS& os, char const* delim, mpl::false_ = mpl::false_()) + { + detail::string_ios_manip manip(os); + manip.print(delim); + } + + template + static void + print(OS& os, char const* delim, mpl::true_) + { + } + }; + + struct print_sequence_loop + { + template + static void + call(OS& os, First const&, Last const&, mpl::true_) + { + } + + template + static void + call(OS& os, First const& first, Last const& last, mpl::false_) + { + result_of::equal_to< + typename result_of::next::type + , Last + > + is_last; + + os << *first; + delimiter_out::print(os, " ", is_last); + call(os, fusion::next(first), last, is_last); + } + + template + static void + call(OS& os, First const& first, Last const& last) + { + result_of::equal_to eq; + call(os, first, last, eq); + } + }; + + template + inline void + print_sequence(OS& os, Sequence const& seq) + { + delimiter_out::print(os, "("); + print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq)); + delimiter_out::print(os, ")"); + } +}}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/io/in.hpp b/thirdparty/boost/fusion/sequence/io/in.hpp new file mode 100644 index 0000000..a28f009 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io/in.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 1999-2003 Jeremiah Willcock + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_IN_05042005_0120) +#define BOOST_IN_05042005_0120 + +#include +#include +#include + +namespace boost { namespace fusion +{ + template + inline std::istream& + in(std::istream& is, Sequence& seq) + { + detail::read_sequence(is, seq); + return is; + } + + namespace operators + { + template + inline typename + enable_if< + fusion::traits::is_sequence + , std::istream& + >::type + operator>>(std::istream& is, Sequence& seq) + { + return fusion::in(is, seq); + } + } + using operators::operator>>; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/io/out.hpp b/thirdparty/boost/fusion/sequence/io/out.hpp new file mode 100644 index 0000000..1c294b3 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/io/out.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 1999-2003 Jeremiah Willcock + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_OUT_05042005_0120) +#define BOOST_OUT_05042005_0120 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + template + inline std::ostream& + out(std::ostream& os, Sequence& seq) + { + detail::print_sequence(os, seq); + return os; + } + + namespace operators + { + template + inline typename + enable_if< + fusion::traits::is_sequence + , std::ostream& + >::type + operator<<(std::ostream& os, Sequence const& seq) + { + return fusion::out(os, seq); + } + } + using operators::operator<<; +}} + +#endif diff --git a/thirdparty/boost/fusion/sequence/sequence_facade.hpp b/thirdparty/boost/fusion/sequence/sequence_facade.hpp new file mode 100644 index 0000000..d5d4e77 --- /dev/null +++ b/thirdparty/boost/fusion/sequence/sequence_facade.hpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_FACADE_09252006_1044) +#define FUSION_SEQUENCE_FACADE_09252006_1044 + +#include +#include + +namespace boost { namespace fusion +{ + struct sequence_facade_tag; + + template + struct sequence_facade : sequence_base + { + typedef sequence_facade_tag fusion_tag; + typedef Derived derived_type; + typedef Category category; + typedef IsView is_view; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/support.hpp b/thirdparty/boost/fusion/support.hpp new file mode 100644 index 0000000..08c8c69 --- /dev/null +++ b/thirdparty/boost/fusion/support.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SUPPORT_10022005_0545) +#define FUSION_SUPPORT_10022005_0545 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/support/category_of.hpp b/thirdparty/boost/fusion/support/category_of.hpp new file mode 100644 index 0000000..5e97cc2 --- /dev/null +++ b/thirdparty/boost/fusion/support/category_of.hpp @@ -0,0 +1,112 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CATEGORY_OF_07202005_0308) +#define FUSION_CATEGORY_OF_07202005_0308 + +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + struct incrementable_traversal_tag {}; + + struct single_pass_traversal_tag + : incrementable_traversal_tag {}; + + struct forward_traversal_tag + : single_pass_traversal_tag {}; + + struct bidirectional_traversal_tag + : forward_traversal_tag {}; + + struct random_access_traversal_tag + : bidirectional_traversal_tag {}; + + struct associative_sequence_tag {}; + + namespace extension + { + template + struct category_of_impl + { + template + struct apply : detail::fusion_category_of {}; + }; + + template <> + struct category_of_impl; + + template <> + struct category_of_impl; + + template <> + struct category_of_impl; + + template <> + struct category_of_impl; + } + + namespace traits + { + template + struct category_of + : extension::category_of_impl::type>:: + template apply + {}; + + template + struct is_associative + : is_base_of< + associative_sequence_tag + , typename category_of::type> + {}; + + template + struct is_incrementable + : is_base_of< + incrementable_traversal_tag + , typename category_of::type> + {}; + + template + struct is_single_pass + : is_base_of< + single_pass_traversal_tag + , typename category_of::type> + {}; + + template + struct is_forward + : is_base_of< + forward_traversal_tag + , typename category_of::type> + {}; + + template + struct is_bidirectional + : is_base_of< + bidirectional_traversal_tag + , typename category_of::type> + {}; + + template + struct is_random_access + : is_base_of< + random_access_traversal_tag + , typename category_of::type> + {}; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/deduce.hpp b/thirdparty/boost/fusion/support/deduce.hpp new file mode 100644 index 0000000..942cedc --- /dev/null +++ b/thirdparty/boost/fusion/support/deduce.hpp @@ -0,0 +1,105 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_SUPPORT_DEDUCE_HPP_INCLUDED) +#define BOOST_FUSION_SUPPORT_DEDUCE_HPP_INCLUDED + +#include + +namespace boost { namespace fusion { namespace traits +{ + template struct deduce; + + //----- ---- --- -- - - - - + + // Non-references pass unchanged + + template + struct deduce + { + typedef T type; + }; + + template + struct deduce + { + typedef T type; + }; + + template + struct deduce + { + typedef T type; + }; + + template + struct deduce + { + typedef T type; + }; + + // Keep references on mutable LValues + + template + struct deduce + { + typedef T & type; + }; + + template + struct deduce + { + typedef T volatile& type; + }; + + // Store away potential RValues + + template + struct deduce + { + typedef T type; + }; + + template + struct deduce + { + typedef T type; + }; + + // Unwrap Boost.RefS (referencee cv is deduced) + + template + struct deduce & > + { + typedef T& type; + }; + + template + struct deduce const & > + { + typedef T& type; + }; + + // Keep references on arrays, even if const + + template + struct deduce + { + typedef const T(&type)[N]; + }; + + template + struct deduce + { + typedef const volatile T(&type)[N]; + }; + +}}} + +#endif + diff --git a/thirdparty/boost/fusion/support/deduce_sequence.hpp b/thirdparty/boost/fusion/support/deduce_sequence.hpp new file mode 100644 index 0000000..694bf25 --- /dev/null +++ b/thirdparty/boost/fusion/support/deduce_sequence.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + 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). +==============================================================================*/ + +#if !defined(BOOST_FUSION_SUPPORT_DEDUCE_SEQUENCE_HPP_INCLUDED) +#define BOOST_FUSION_SUPPORT_DEDUCE_SEQUENCE_HPP_INCLUDED + +#include +#include +#include + + +namespace boost { namespace fusion { namespace traits +{ + template struct deduce_sequence; + + namespace detail + { + struct deducer + { + template + struct result; + + template + struct result< Self(T) > + : fusion::traits::deduce + { }; + }; + } + + template + struct deduce_sequence + : result_of::as_vector< + fusion::transform_view > + { }; + +}}} + +#endif + diff --git a/thirdparty/boost/fusion/support/detail/access.hpp b/thirdparty/boost/fusion/support/detail/access.hpp new file mode 100644 index 0000000..bab85c1 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/access.hpp @@ -0,0 +1,55 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ACCESS_04182005_0737) +#define FUSION_ACCESS_04182005_0737 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct ref_result + { + typedef typename add_reference::type type; + }; + + template + struct cref_result + { + typedef typename + add_reference< + typename add_const::type + >::type + type; + }; + + template + struct non_ref_parameter + { + typedef typename boost::remove_cv::type const& type; + }; + + template + struct call_param + { + typedef typename + mpl::eval_if< + is_reference + , mpl::identity + , non_ref_parameter + >::type + type; + }; +}}} + +#endif + diff --git a/thirdparty/boost/fusion/support/detail/as_fusion_element.hpp b/thirdparty/boost/fusion/support/detail/as_fusion_element.hpp new file mode 100644 index 0000000..c75fea0 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/as_fusion_element.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 1999-2003 Jaakko Järvi + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AS_FUSION_ELEMENT_05052005_0338) +#define FUSION_AS_FUSION_ELEMENT_05052005_0338 + +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct as_fusion_element + { + typedef T type; + }; + + template + struct as_fusion_element > + { + typedef T& type; + }; + + template + struct as_fusion_element + { + typedef const T(&type)[N]; + }; + + template + struct as_fusion_element + { + typedef const volatile T(&type)[N]; + }; + + template + struct as_fusion_element + { + typedef const volatile T(&type)[N]; + }; + +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/detail/category_of.hpp b/thirdparty/boost/fusion/support/detail/category_of.hpp new file mode 100644 index 0000000..f268e74 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/category_of.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_CATEGORY_OF_07212005_1025) +#define FUSION_CATEGORY_OF_07212005_1025 + +namespace boost { namespace fusion { namespace detail +{ + template + struct fusion_category_of + { + typedef typename T::category type; + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/detail/is_mpl_sequence.hpp b/thirdparty/boost/fusion/support/detail/is_mpl_sequence.hpp new file mode 100644 index 0000000..1713aba --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/is_mpl_sequence.hpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DETAIL_IS_MPL_SEQUENCE_29122006_1105) +#define FUSION_DETAIL_IS_MPL_SEQUENCE_29122006_1105 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ + template + struct is_mpl_sequence + : mpl::and_< + mpl::not_ > + , mpl::is_sequence > + {}; +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/detail/is_view.hpp b/thirdparty/boost/fusion/support/detail/is_view.hpp new file mode 100644 index 0000000..9925fb1 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/is_view.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IS_VIEW_03202006_0018) +#define FUSION_IS_VIEW_03202006_0018 + +namespace boost { namespace fusion { namespace detail +{ + template + struct fusion_is_view + { + typedef typename T::is_view type; + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/detail/mpl_iterator_category.hpp b/thirdparty/boost/fusion/support/detail/mpl_iterator_category.hpp new file mode 100644 index 0000000..1ee0053 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/mpl_iterator_category.hpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_MPL_ITERATOR_CATEGORY_07212005_0923) +#define FUSION_MPL_ITERATOR_CATEGORY_07212005_0923 + +namespace boost { namespace mpl +{ + struct forward_iterator_tag; + struct bidirectional_iterator_tag; + struct random_access_iterator_tag; +}} + +namespace boost { namespace fusion +{ + struct forward_traversal_tag; + struct bidirectional_traversal_tag; + struct random_access_traversal_tag; +}} + +namespace boost { namespace fusion { namespace detail +{ + template + struct mpl_iterator_category; + + template <> + struct mpl_iterator_category + { + typedef forward_traversal_tag type; + }; + + template <> + struct mpl_iterator_category + { + typedef bidirectional_traversal_tag type; + }; + + template <> + struct mpl_iterator_category + { + typedef random_access_traversal_tag type; + }; + + template <> + struct mpl_iterator_category + { + typedef forward_traversal_tag type; + }; + + template <> + struct mpl_iterator_category + { + typedef bidirectional_traversal_tag type; + }; + + template <> + struct mpl_iterator_category + { + typedef random_access_traversal_tag type; + }; +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/detail/unknown_key.hpp b/thirdparty/boost/fusion/support/detail/unknown_key.hpp new file mode 100644 index 0000000..a3ec0b5 --- /dev/null +++ b/thirdparty/boost/fusion/support/detail/unknown_key.hpp @@ -0,0 +1,16 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_UNKNOWN_KEY_09242005_1219) +#define FUSION_UNKNOWN_KEY_09242005_1219 + +namespace boost { namespace fusion { namespace detail +{ + template + struct unknown_key {}; +}}} + +#endif diff --git a/thirdparty/boost/fusion/support/ext_/is_segmented.hpp b/thirdparty/boost/fusion/support/ext_/is_segmented.hpp new file mode 100644 index 0000000..3986266 --- /dev/null +++ b/thirdparty/boost/fusion/support/ext_/is_segmented.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IS_SEGMENTED_03202006_0015) +#define FUSION_IS_SEGMENTED_03202006_0015 + +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + struct iterator_range_tag; + + namespace extension + { + template + struct is_segmented_impl + { + template + struct apply + : mpl::false_ + {}; + }; + + template<> + struct is_segmented_impl; + } + + namespace traits + { + template + struct is_segmented + : extension::is_segmented_impl::type>:: + template apply + { + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/is_iterator.hpp b/thirdparty/boost/fusion/support/is_iterator.hpp new file mode 100644 index 0000000..b87de24 --- /dev/null +++ b/thirdparty/boost/fusion/support/is_iterator.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IS_ITERATOR_05062005_1219) +#define FUSION_IS_ITERATOR_05062005_1219 + +#include + +namespace boost { namespace fusion +{ + struct iterator_root; + + template + struct is_fusion_iterator : is_base_of {}; +}} + +#endif diff --git a/thirdparty/boost/fusion/support/is_sequence.hpp b/thirdparty/boost/fusion/support/is_sequence.hpp new file mode 100644 index 0000000..84df480 --- /dev/null +++ b/thirdparty/boost/fusion/support/is_sequence.hpp @@ -0,0 +1,65 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IS_SEQUENCE_05052005_1002) +#define FUSION_IS_SEQUENCE_05052005_1002 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct non_fusion_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct is_sequence_impl + { + template + struct apply : is_base_of {}; + }; + + template <> + struct is_sequence_impl + { + template + struct apply : mpl::false_ {}; + }; + + template <> + struct is_sequence_impl; + + template <> + struct is_sequence_impl; + + template <> + struct is_sequence_impl; + + template <> + struct is_sequence_impl; + } + + namespace traits + { + template + struct is_sequence + : extension::is_sequence_impl::type>:: + template apply + {}; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/is_view.hpp b/thirdparty/boost/fusion/support/is_view.hpp new file mode 100644 index 0000000..5a43591 --- /dev/null +++ b/thirdparty/boost/fusion/support/is_view.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_IS_VIEW_03202006_0015) +#define FUSION_IS_VIEW_03202006_0015 + +#include +#include + +namespace boost { namespace fusion +{ + // Special tags: + struct sequence_facade_tag; + struct boost_tuple_tag; // boost::tuples::tuple tag + struct array_tag; // boost::array tag + struct mpl_sequence_tag; // mpl sequence tag + struct std_pair_tag; // std::pair tag + + namespace extension + { + template + struct is_view_impl + { + template + struct apply + : detail::fusion_is_view + {}; + }; + + template <> + struct is_view_impl + { + template + struct apply : Sequence::is_view {}; + }; + + template <> + struct is_view_impl; + + template <> + struct is_view_impl; + + template <> + struct is_view_impl; + + template <> + struct is_view_impl; + } + + namespace traits + { + template + struct is_view : + extension::is_view_impl::type>:: + template apply::type + {}; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/iterator_base.hpp b/thirdparty/boost/fusion/support/iterator_base.hpp new file mode 100644 index 0000000..e926703 --- /dev/null +++ b/thirdparty/boost/fusion/support/iterator_base.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ITERATOR_BASE_05042005_1008) +#define FUSION_ITERATOR_BASE_05042005_1008 + +namespace boost { namespace fusion +{ + struct iterator_root {}; + + template + struct iterator_base : iterator_root + { + Iterator const& + cast() const + { + return static_cast(*this); + } + + Iterator& + cast() + { + return static_cast(*this); + } + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/support/pair.hpp b/thirdparty/boost/fusion/support/pair.hpp new file mode 100644 index 0000000..2b73edc --- /dev/null +++ b/thirdparty/boost/fusion/support/pair.hpp @@ -0,0 +1,102 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + Copyright (c) 2006 Tobias Schwinger + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PAIR_07222005_1203) +#define FUSION_PAIR_07222005_1203 + +#include +#include + +namespace boost { namespace fusion +{ + // A half runtime pair where the first type does not have data + template + struct pair + { + pair() + : second() {} + + pair(typename detail::call_param::type val) + : second(val) {} + + template + pair(pair const& rhs) + : second(rhs.second) {} + + template + pair& operator=(pair const& rhs) + { + second = rhs.second; + return *this; + } + + typedef First first_type; + typedef Second second_type; + Second second; + }; + + namespace result_of + { + template + struct make_pair + { + typedef fusion::pair::type> type; + }; + + template + struct first + { + typedef typename Pair::first_type type; + }; + + template + struct second + { + typedef typename Pair::second_type type; + }; + } + + template + inline typename result_of::make_pair::type + make_pair(Second const& val) + { + return pair::type>(val); + } + + template + inline OStream& + operator<<(OStream& os, pair const& p) + { + os << p.second; + return os; + } + + template + inline IStream& + operator>>(IStream& is, pair& p) + { + is >> p.second; + return is; + } + + template + inline bool + operator==(pair const& l, pair const& r) + { + return l.second == r.second; + } + + template + inline bool + operator!=(pair const& l, pair const& r) + { + return l.second != r.second; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/sequence_base.hpp b/thirdparty/boost/fusion/support/sequence_base.hpp new file mode 100644 index 0000000..9957093 --- /dev/null +++ b/thirdparty/boost/fusion/support/sequence_base.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Tobias Schwinger + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_BASE_04182005_0737) +#define FUSION_SEQUENCE_BASE_04182005_0737 + +#include + +namespace boost { namespace fusion +{ + struct sequence_root {}; + + template + struct sequence_base : sequence_root + { + Sequence const& + derived() const + { + return static_cast(*this); + } + + Sequence& + derived() + { + return static_cast(*this); + } + }; + + struct fusion_sequence_tag; +}} + +namespace boost { namespace mpl +{ + // Deliberately break mpl::begin, so it doesn't lie that a Fusion sequence + // is not an MPL sequence by returning mpl::void_. + // In other words: Fusion Sequences are always MPL Sequences, but they can + // be incompletely defined. + template<> struct begin_impl< boost::fusion::fusion_sequence_tag >; +}} + +#endif diff --git a/thirdparty/boost/fusion/support/tag_of.hpp b/thirdparty/boost/fusion/support/tag_of.hpp new file mode 100644 index 0000000..3577244 --- /dev/null +++ b/thirdparty/boost/fusion/support/tag_of.hpp @@ -0,0 +1,110 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TAG_OF_09232005_0845) +#define FUSION_TAG_OF_09232005_0845 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + template + class array; // forward + + namespace tuples + { + struct null_type; + + template < + class T0, class T1, class T2, class T3, class T4, + class T5, class T6, class T7, class T8, class T9 + > + class tuple; + + template + struct cons; + } +} + +namespace boost { namespace fusion +{ + struct non_fusion_tag; + struct mpl_sequence_tag; + + namespace detail + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(fusion_tag) + + template + struct is_specialized + : mpl::false_ + {}; + + template < + class T0, class T1, class T2, class T3, class T4, + class T5, class T6, class T7, class T8, class T9 + > + struct is_specialized > + : mpl::true_ + {}; + + template + struct is_specialized > + : mpl::true_ + {}; + + template <> + struct is_specialized + : mpl::true_ + {}; + + template + struct is_specialized > + : mpl::true_ + {}; + + template + struct is_specialized > + : mpl::true_ + {}; + } + + namespace traits + { + template + struct tag_of + : mpl::if_< detail::is_mpl_sequence, + mpl::identity, + mpl::identity >::type + { + BOOST_MPL_ASSERT_NOT((detail::is_specialized)); + }; + + template + struct tag_of >::type> + { + typedef typename Sequence::fusion_tag type; + }; + } + + namespace detail + { + template + struct tag_of + : traits::tag_of::type> + {}; + } +}} +#endif diff --git a/thirdparty/boost/fusion/support/tag_of_fwd.hpp b/thirdparty/boost/fusion/support/tag_of_fwd.hpp new file mode 100644 index 0000000..b725bb3 --- /dev/null +++ b/thirdparty/boost/fusion/support/tag_of_fwd.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_TAG_OF_FWD_31122005_1445) +#define BOOST_FUSION_TAG_OF_FWD_31122005_1445 + +namespace boost { namespace fusion +{ + namespace traits + { + template + struct tag_of; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/support/unused.hpp b/thirdparty/boost/fusion/support/unused.hpp new file mode 100644 index 0000000..ca57fe2 --- /dev/null +++ b/thirdparty/boost/fusion/support/unused.hpp @@ -0,0 +1,62 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_SUPPORT_UNUSED_20070305_1038) +#define BOOST_FUSION_SUPPORT_UNUSED_20070305_1038 + +#include +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4522) // multiple assignment operators specified warning +#endif + +namespace boost { namespace fusion { + struct unused_type + { + unused_type() + { + } + + template + unused_type(T const&) + { + } + + template + unused_type const& + operator=(T const&) const + { + return *this; + } + + template + unused_type& + operator=(T const&) + { + return *this; + } + + unused_type const& + operator=(unused_type const&) const + { + return *this; + } + + unused_type& + operator=(unused_type const&) + { + return *this; + } + }; + + unused_type const unused = unused_type(); +}} + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif diff --git a/thirdparty/boost/fusion/support/void.hpp b/thirdparty/boost/fusion/support/void.hpp new file mode 100644 index 0000000..e0d0c45 --- /dev/null +++ b/thirdparty/boost/fusion/support/void.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_SUPPORT_VOID_20070706_2125) +#define BOOST_FUSION_SUPPORT_VOID_20070706_2125 + +namespace boost { namespace fusion +{ + struct void_ {}; +}} + +#endif diff --git a/thirdparty/boost/fusion/tuple.hpp b/thirdparty/boost/fusion/tuple.hpp new file mode 100644 index 0000000..eeccf5e --- /dev/null +++ b/thirdparty/boost/fusion/tuple.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TUPLE_10032005_0806) +#define FUSION_TUPLE_10032005_0806 + +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/tuple/detail/tuple_forward_ctor.hpp b/thirdparty/boost/fusion/tuple/detail/tuple_forward_ctor.hpp new file mode 100644 index 0000000..42b7e0e --- /dev/null +++ b/thirdparty/boost/fusion/tuple/detail/tuple_forward_ctor.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_TUPLE_FORWARD_CTOR_10032005_0815) +#define FUSION_TUPLE_FORWARD_CTOR_10032005_0815 + +#include +#include +#include + +#define BOOST_PP_FILENAME_1 \ + +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + +#if N == 1 + explicit +#endif + tuple(BOOST_PP_ENUM_BINARY_PARAMS( + N, typename detail::call_param::type _)) + : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {} + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/tuple/make_tuple.hpp b/thirdparty/boost/fusion/tuple/make_tuple.hpp new file mode 100644 index 0000000..46bc14c --- /dev/null +++ b/thirdparty/boost/fusion/tuple/make_tuple.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_MAKE_TUPLE_10032005_0843) +#define FUSION_MAKE_TUPLE_10032005_0843 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + inline tuple<> + make_tuple() + { + return tuple<>(); + } + +#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \ + typename detail::as_fusion_element::type + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_AS_FUSION_ELEMENT + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template + inline tuple + make_tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _)) + { + return tuple( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/tuple/tuple.hpp b/thirdparty/boost/fusion/tuple/tuple.hpp new file mode 100644 index 0000000..078d642 --- /dev/null +++ b/thirdparty/boost/fusion/tuple/tuple.hpp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TUPLE_10032005_0810) +#define FUSION_TUPLE_10032005_0810 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + template + struct tuple : vector + { + typedef vector< + BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)> + base_type; + + tuple() + : base_type() {} + + template + tuple(Sequence const& rhs) + : base_type(rhs) {} + + #include + + template + tuple& + operator=(T const& rhs) + { + base_type::operator=(rhs); + return *this; + } + }; + + template + struct tuple_size : result_of::size {}; + + template + struct tuple_element : result_of::value_at_c {}; + + template + inline typename + lazy_disable_if< + is_const + , result_of::at_c + >::type + get(Tuple& tup) + { + return at_c(tup); + } + + template + inline typename result_of::at_c::type + get(Tuple const& tup) + { + return at_c(tup); + } +}} + +#endif diff --git a/thirdparty/boost/fusion/tuple/tuple_fwd.hpp b/thirdparty/boost/fusion/tuple/tuple_fwd.hpp new file mode 100644 index 0000000..546e8e4 --- /dev/null +++ b/thirdparty/boost/fusion/tuple/tuple_fwd.hpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2005 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TUPLE_FORWARD_10032005_0956) +#define FUSION_TUPLE_FORWARD_10032005_0956 + +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + FUSION_MAX_VECTOR_SIZE, typename T, void_) + > + struct tuple; +}} + +#endif diff --git a/thirdparty/boost/fusion/tuple/tuple_tie.hpp b/thirdparty/boost/fusion/tuple/tuple_tie.hpp new file mode 100644 index 0000000..4c84c55 --- /dev/null +++ b/thirdparty/boost/fusion/tuple/tuple_tie.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef BOOST_PP_IS_ITERATING +#if !defined(FUSION_TUPLE_TIE_10032005_0846) +#define FUSION_TUPLE_TIE_10032005_0846 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ +#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)& + +#define BOOST_PP_FILENAME_1 +#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) +#include BOOST_PP_ITERATE() + +#undef BOOST_FUSION_REF + +}} + +#endif +#else // defined(BOOST_PP_IS_ITERATING) +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// + +#define N BOOST_PP_ITERATION() + + template + inline tuple + tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & _)) + { + return tuple( + BOOST_PP_ENUM_PARAMS(N, _)); + } + +#undef N +#endif // defined(BOOST_PP_IS_ITERATING) + diff --git a/thirdparty/boost/fusion/view.hpp b/thirdparty/boost/fusion/view.hpp new file mode 100644 index 0000000..805a99f --- /dev/null +++ b/thirdparty/boost/fusion/view.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_10022005_0620) +#define FUSION_SEQUENCE_VIEW_10022005_0620 + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/detail/strictest_traversal.hpp b/thirdparty/boost/fusion/view/detail/strictest_traversal.hpp new file mode 100644 index 0000000..b79881d --- /dev/null +++ b/thirdparty/boost/fusion/view/detail/strictest_traversal.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_STRICTEST_TRAVERSAL_20060123_2101) +#define FUSION_STRICTEST_TRAVERSAL_20060123_2101 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct forward_traversal_tag; + struct bidirectional_traversal_tag; + struct random_access_traversal_tag; + + namespace detail + { + template::value> + struct stricter_traversal + { + typedef Tag1 type; + }; + + template + struct stricter_traversal + { + typedef Tag2 type; + }; + + struct strictest_traversal_impl + { + template + struct result; + + template + struct result + { + typedef typename remove_reference::type next_value; + typedef typename remove_reference::type strictest_so_far; + + typedef strictest_so_far tag1; + typedef typename traits::category_of::type tag2; + + typedef typename stricter_traversal::type type; + }; + }; + + template + struct strictest_traversal + : result_of::fold< + Sequence, fusion::random_access_traversal_tag, + strictest_traversal_impl> + {}; + + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/ext_/multiple_view.hpp b/thirdparty/boost/fusion/view/ext_/multiple_view.hpp new file mode 100644 index 0000000..89c4e4c --- /dev/null +++ b/thirdparty/boost/fusion/view/ext_/multiple_view.hpp @@ -0,0 +1,178 @@ +/*============================================================================= + Copyright (c) 2001-2006 Eric Niebler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef FUSION_MULTIPLE_VIEW_05052005_0335 +#define FUSION_MULTIPLE_VIEW_05052005_0335 + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct multiple_view_tag; + struct forward_traversal_tag; + struct fusion_sequence_tag; + + template + struct multiple_view + : sequence_base > + { + typedef multiple_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef forward_traversal_tag category; + typedef mpl::true_ is_view; + typedef mpl::int_ size; + typedef T value_type; + + multiple_view() + : val() + {} + + explicit multiple_view(typename detail::call_param::type val) + : val(val) + {} + + value_type val; + }; + + template + inline multiple_view::type> + make_multiple_view(T const& v) + { + return multiple_view::type>(v); + } + + struct multiple_view_iterator_tag; + struct forward_traversal_tag; + + template + struct multiple_view_iterator + : iterator_base > + { + typedef multiple_view_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + typedef typename MultipleView::value_type value_type; + typedef MultipleView multiple_view_type; + typedef Index index; + + explicit multiple_view_iterator(multiple_view_type const &view_) + : view(view_) + {} + + multiple_view_type view; + }; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef multiple_view_iterator< + typename mpl::next::type + , typename Iterator::multiple_view_type + > type; + + static type + call(Iterator const &where) + { + return type(where.view); + } + }; + }; + + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef multiple_view_iterator< + typename Sequence::size + , Sequence + > type; + + static type + call(Sequence &seq) + { + return type(seq); + } + }; + }; + + template + struct deref_impl; + + template <> + struct deref_impl + { + template + struct apply + { + typedef typename Iterator::value_type type; + + static type + call(Iterator const& i) + { + return i.view.val; + } + }; + }; + + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef multiple_view_iterator< + mpl::int_<0> + , Sequence + > type; + + static type + call(Sequence &seq) + { + return type(seq); + } + }; + }; + + template + struct value_of_impl; + + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename Iterator::multiple_view_type multiple_view_type; + typedef typename multiple_view_type::value_type type; + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/ext_/segmented_iterator.hpp b/thirdparty/boost/fusion/view/ext_/segmented_iterator.hpp new file mode 100644 index 0000000..f5a7f87 --- /dev/null +++ b/thirdparty/boost/fusion/view/ext_/segmented_iterator.hpp @@ -0,0 +1,425 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027 +#define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for nil +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct fusion_sequence_tag; + + namespace detail + { + using mpl::_; + using mpl::not_; + + //////////////////////////////////////////////////////////////////////////// + template + struct is_empty + : result_of::equal_to< + typename result_of::begin::type + , typename result_of::end::type + > + {}; + + template + struct is_empty + : is_empty + {}; + + struct segmented_range_tag; + + //////////////////////////////////////////////////////////////////////////// + template + struct segmented_range + : sequence_base > + { + BOOST_MPL_ASSERT_NOT((is_reference)); + typedef mpl::bool_ is_segmented; + typedef segmented_range_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + typedef Iterator iterator_type; + + // If this is a range of segments, skip over the empty ones + typedef typename mpl::if_< + is_segmented + , filter_view > > + , Sequence + >::type sequence_non_ref_type; + + typedef typename mpl::if_< + traits::is_view + , sequence_non_ref_type + , sequence_non_ref_type & + >::type sequence_type; + + typedef typename traits::category_of::type category; + + explicit segmented_range(Sequence &sequence_) + : sequence(sequence_type(sequence_)) + , where_(fusion::begin(sequence)) + {} + + segmented_range(sequence_type sequence_, iterator_type const &wh) + : sequence(sequence_) + , where_(wh) + {} + + sequence_type sequence; + iterator_type where_; + }; + } + + namespace extension + { + template<> + struct is_segmented_impl + { + template + struct apply + : Sequence::is_segmented + {}; + }; + + template<> + struct size_impl + { + template + struct apply + : mpl::int_< + result_of::distance< + typename Sequence::iterator_type + , typename result_of::end::type + >::value + > + {}; + }; + + template<> + struct segments_impl + { + template + struct apply + { + typedef Sequence &type; + static type call(Sequence &seq) + { + return seq; + } + }; + }; + + template<> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::iterator_type type; + static type call(Sequence &seq) + { + return seq.where_; + } + }; + }; + + template<> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::sequence_non_ref_type sequence; + typedef typename result_of::end::type type; + + static type call(Sequence &seq) + { + return fusion::end(seq.sequence); + } + }; + }; + } + + namespace detail + { + /////////////////////////////////////////////////////////////////////// + template + struct range_next; + + template + struct range_next > + { + typedef typename result_of::next::type iterator_type; + typedef segmented_range type; + + static type call(segmented_range const &rng) + { + return type(rng.sequence, fusion::next(rng.where_)); + } + }; + + /////////////////////////////////////////////////////////////////////// + template + struct is_range_next_empty + : is_empty::type> + {}; + + template<> + struct is_range_next_empty + : mpl::true_ + {}; + + /////////////////////////////////////////////////////////////////////// + template::value> + struct as_segmented_range + { + typedef typename result_of::segments::type segments; + typedef typename remove_reference::type sequence; + typedef typename result_of::begin > > >::type begin; + typedef segmented_range type; + + static type call(Sequence &seq) + { + segments segs(fusion::segments(seq)); + return type(segs); + } + }; + + template + struct as_segmented_range + { + typedef typename remove_reference::type sequence; + typedef typename result_of::begin::type begin; + typedef segmented_range type; + + static type call(Sequence &seq) + { + return type(seq); + } + }; + + template + struct as_segmented_range, IsSegmented> + { + typedef segmented_range type; + static type &call(type &seq) + { + return seq; + } + }; + + /////////////////////////////////////////////////////////////////////// + template< + typename Sequence + , typename State = nil + , bool IsSegmented = traits::is_segmented::value + > + struct push_segments + { + typedef typename as_segmented_range::type range; + typedef typename result_of::begin::type begin; + typedef typename result_of::deref::type next_ref; + typedef typename remove_reference::type next; + typedef push_segments > push; + typedef typename push::type type; + + static type call(Sequence &seq, State const &state) + { + range rng(as_segmented_range::call(seq)); + next_ref nxt(*fusion::begin(rng)); + return push::call(nxt, fusion::make_cons(rng, state)); + } + }; + + template + struct push_segments + { + typedef typename as_segmented_range::type range; + typedef cons type; + + static type call(Sequence &seq, State const &state) + { + range rng(as_segmented_range::call(seq)); + return fusion::make_cons(rng, state); + } + }; + + /////////////////////////////////////////////////////////////////////// + template::value> + struct pop_segments + { + typedef range_next next; + typedef push_segments push; + typedef typename push::type type; + + static type call(State const &state) + { + typename next::type rng(next::call(state.car)); + return push::call(rng, state.cdr); + } + }; + + template + struct pop_segments + { + typedef pop_segments pop; + typedef typename pop::type type; + + static type call(State const &state) + { + return pop::call(state.cdr); + } + }; + + template<> + struct pop_segments + { + typedef nil type; + + static type call(nil const &) + { + return nil(); + } + }; + } // namespace detail + + struct segmented_iterator_tag; + + //////////////////////////////////////////////////////////////////////////// + template + struct segmented_iterator + : fusion::iterator_base > + { + typedef segmented_iterator_tag fusion_tag; + typedef fusion::forward_traversal_tag category; + + typedef Cons cons_type; + typedef typename Cons::car_type car_type; + typedef typename Cons::cdr_type cdr_type; + + explicit segmented_iterator(Cons const &cons) + : cons_(cons) + {} + + cons_type const &cons() const { return this->cons_; }; + car_type const &car() const { return this->cons_.car; }; + cdr_type const &cdr() const { return this->cons_.cdr; }; + + private: + Cons cons_; + }; + + /////////////////////////////////////////////////////////////////////////// + template + struct segmented_begin + { + typedef typename detail::push_segments push; + typedef segmented_iterator type; + + static type call(Sequence &seq) + { + return type(push::call(seq, nil())); + } + }; + + /////////////////////////////////////////////////////////////////////////// + template + struct segmented_end + { + typedef segmented_iterator type; + + static type call(Sequence &) + { + return type(nil()); + } + }; + + namespace extension + { + template<> + struct value_of_impl + { + template + struct apply + { + typedef typename result_of::begin::type begin; + typedef typename result_of::value_of::type type; + }; + }; + + template<> + struct deref_impl + { + template + struct apply + { + typedef typename result_of::begin::type begin; + typedef typename result_of::deref::type type; + + static type call(Iterator const &it) + { + return *fusion::begin(it.car()); + } + }; + }; + + // discards the old head, expands the right child of the new head + // and pushes the result to the head of the list. + + template<> + struct next_impl + { + template< + typename Iterator + , bool IsSegmentDone = detail::is_range_next_empty::value + > + struct apply + { + typedef typename Iterator::cdr_type cdr_type; + typedef detail::range_next next; + typedef segmented_iterator > type; + + static type call(Iterator const &it) + { + return type(fusion::make_cons(next::call(it.car()), it.cdr())); + } + }; + + template + struct apply // segment done, move to next segment + { + typedef typename Iterator::cdr_type cdr_type; + typedef typename detail::pop_segments pop; + typedef segmented_iterator type; + + static type call(Iterator const &it) + { + return type(pop::call(it.cdr())); + } + }; + }; + } +}} // namespace boost::fusion + +#endif diff --git a/thirdparty/boost/fusion/view/ext_/segmented_iterator_range.hpp b/thirdparty/boost/fusion/view/ext_/segmented_iterator_range.hpp new file mode 100644 index 0000000..86feddd --- /dev/null +++ b/thirdparty/boost/fusion/view/ext_/segmented_iterator_range.hpp @@ -0,0 +1,537 @@ +/*============================================================================= + Copyright (c) 2006 Eric Niebler + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#ifndef FUSION_SEGMENTED_ITERATOR_RANGE_EAN_05032006_1027 +#define FUSION_SEGMENTED_ITERATOR_RANGE_EAN_05032006_1027 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + namespace detail + { + //////////////////////////////////////////////////////////////////////////// + template + struct reverse_cons; + + template + struct reverse_cons, State> + { + typedef reverse_cons > reverse; + typedef typename reverse::type type; + + static type call(cons const &cons, State const &state = State()) + { + return reverse::call(cons.cdr, fusion::make_cons(cons.car, state)); + } + }; + + template + struct reverse_cons + { + typedef State type; + + static State const &call(nil const &, State const &state = State()) + { + return state; + } + }; + + //////////////////////////////////////////////////////////////////////////// + // tags + struct full_view {}; + struct left_view {}; + struct right_view {}; + struct center_view {}; + + template + struct segmented_view_tag; + + //////////////////////////////////////////////////////////////////////////// + // a segmented view of that includes all elements either to the + // right or the left of a segmented iterator. + template + struct segmented_view + : sequence_base > + { + typedef segmented_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + typedef forward_traversal_tag category; + + explicit segmented_view(Cons1 const &cons) + : cons(cons) + {} + + typedef Cons1 cons_type; + cons_type const &cons; + }; + + // a segmented view that contains all the elements in between + // two segmented iterators + template + struct segmented_view + : sequence_base > + { + typedef segmented_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + typedef forward_traversal_tag category; + + segmented_view(Cons1 const &lcons, Cons2 const &rcons) + : left_cons(lcons) + , right_cons(rcons) + {} + + typedef Cons1 left_cons_type; + typedef Cons2 right_cons_type; + + left_cons_type const &left_cons; + right_cons_type const &right_cons; + }; + + //////////////////////////////////////////////////////////////////////////// + // Used to transform a sequence of segments. The first segment is + // bounded by RightCons, and the last segment is bounded by LeftCons + // and all the others are passed through unchanged. + template + struct segments_transform + { + explicit segments_transform(RightCons const &cons_) + : right_cons(cons_) + , left_cons(cons_) + {} + + segments_transform(RightCons const &right_cons_, LeftCons const &left_cons_) + : right_cons(right_cons_) + , left_cons(left_cons_) + {} + + template + struct result_; + + template + struct result_ + { + typedef segmented_view type; + }; + + template + struct result_ + { + typedef segmented_view type; + }; + + template + struct result_ + { + typedef Second type; + }; + + template + struct result; + + template + struct result + : result_< + typename remove_cv::type>::type + , typename remove_cv::type>::type + > + {}; + + template + segmented_view operator ()(right_view, Second &second) const + { + return segmented_view(this->right_cons); + } + + template + segmented_view operator ()(left_view, Second &second) const + { + return segmented_view(this->left_cons); + } + + template + Second &operator ()(full_view, Second &second) const + { + return second; + } + + private: + RightCons const &right_cons; + LeftCons const &left_cons; + }; + + } // namespace detail + + namespace extension + { + //////////////////////////////////////////////////////////////////////////// + template + struct is_segmented_impl > + { + template + struct apply + : mpl::true_ + {}; + }; + + //////////////////////////////////////////////////////////////////////////// + template<> + struct segments_impl > + { + template< + typename Sequence + , typename Cdr = typename Sequence::cons_type::cdr_type + > + struct apply + { + typedef typename Sequence::cons_type::car_type segmented_range; + typedef typename result_of::size::type size; + typedef typename mpl::prior::type size_minus_1; + typedef detail::segments_transform tfx; + typedef joint_view< + single_view const + , multiple_view const + > mask; + typedef transform_view type; + + static type call(Sequence &seq) + { + return type( + mask( + make_single_view(detail::right_view()) + , make_multiple_view(detail::full_view()) + ) + , seq.cons.car + , tfx(seq.cons.cdr) + ); + } + }; + + template + struct apply + { + typedef typename Sequence::cons_type::car_type segmented_range; + typedef typename segmented_range::iterator_type begin; + typedef typename segmented_range::sequence_non_ref_type sequence_type; + typedef typename result_of::end::type end; + typedef iterator_range range; + typedef single_view type; + + static type call(Sequence &seq) + { + return type(range(seq.cons.car.where_, fusion::end(seq.cons.car.sequence))); + } + }; + }; + + //////////////////////////////////////////////////////////////////////////// + template<> + struct segments_impl > + { + template< + typename Sequence + , typename Cdr = typename Sequence::cons_type::cdr_type + > + struct apply + { + typedef typename Sequence::cons_type::car_type right_segmented_range; + typedef typename right_segmented_range::sequence_type sequence_type; + typedef typename right_segmented_range::iterator_type iterator_type; + + typedef iterator_range< + typename result_of::begin::type + , typename result_of::next::type + > segmented_range; + + typedef detail::segments_transform tfx; + typedef typename result_of::size::type size; + typedef typename mpl::prior::type size_minus_1; + typedef joint_view< + multiple_view const + , single_view const + > mask; + typedef transform_view type; + + static type call(Sequence &seq) + { + return type( + mask( + make_multiple_view(detail::full_view()) + , make_single_view(detail::left_view()) + ) + , segmented_range(fusion::begin(seq.cons.car.sequence), fusion::next(seq.cons.car.where_)) + , tfx(seq.cons.cdr) + ); + } + }; + + template + struct apply + { + typedef typename Sequence::cons_type::car_type segmented_range; + typedef typename segmented_range::sequence_non_ref_type sequence_type; + typedef typename result_of::begin::type begin; + typedef typename segmented_range::iterator_type end; + typedef iterator_range range; + typedef single_view type; + + static type call(Sequence &seq) + { + return type(range(fusion::begin(seq.cons.car.sequence), seq.cons.car.where_)); + } + }; + }; + + //////////////////////////////////////////////////////////////////////////// + template<> + struct segments_impl > + { + template + struct apply + { + typedef typename Sequence::right_cons_type right_cons_type; + typedef typename Sequence::left_cons_type left_cons_type; + typedef typename right_cons_type::car_type right_segmented_range; + typedef typename left_cons_type::car_type left_segmented_range; + + typedef iterator_range< + typename result_of::begin::type + , typename result_of::next::type>::type + > segmented_range; + + typedef typename mpl::minus< + typename result_of::size::type + , mpl::int_<2> + >::type size_minus_2; + + BOOST_MPL_ASSERT_RELATION(0, <=, size_minus_2::value); + + typedef detail::segments_transform< + typename left_cons_type::cdr_type + , typename right_cons_type::cdr_type + > tfx; + + typedef joint_view< + multiple_view const + , single_view const + > left_mask; + + typedef joint_view< + single_view const + , left_mask const + > mask; + + typedef transform_view type; + + static type call(Sequence &seq) + { + left_mask lmask( + make_multiple_view(detail::full_view()) + , make_single_view(detail::left_view()) + ); + return type( + mask(make_single_view(detail::right_view()), lmask) + , segmented_range(fusion::begin(seq.left_cons.car), fusion::next(fusion::begin(seq.right_cons.car))) + , tfx(seq.left_cons.cdr, seq.right_cons.cdr) + ); + } + }; + }; + } + + // specialize iterator_range for use with segmented iterators, so that + // it presents a segmented view of the range. + template + struct iterator_range; + + template + struct iterator_range, segmented_iterator > + : sequence_base, segmented_iterator > > + { + typedef typename convert_iterator >::type begin_type; + typedef typename convert_iterator >::type end_type; + typedef typename detail::reverse_cons::type begin_cons_type; + typedef typename detail::reverse_cons::type end_cons_type; + typedef iterator_range_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef typename traits::category_of::type category; + typedef typename result_of::distance::type size; + typedef mpl::true_ is_view; + + iterator_range(segmented_iterator const& first_, segmented_iterator const& last_) + : first(convert_iterator >::call(first_)) + , last(convert_iterator >::call(last_)) + , first_cons(detail::reverse_cons::call(first_.cons())) + , last_cons(detail::reverse_cons::call(last_.cons())) + {} + + begin_type first; + end_type last; + + begin_cons_type first_cons; + end_cons_type last_cons; + }; + + namespace detail + { + + template + struct same_segment + : mpl::false_ + {}; + + template + struct same_segment, cons > + : mpl::and_< + traits::is_segmented + , is_same + > + {}; + + //////////////////////////////////////////////////////////////////////////// + template + struct segments_gen; + + //////////////////////////////////////////////////////////////////////////// + template + struct segments_gen2 + { + typedef segments_gen gen; + typedef typename gen::type type; + + static type call(Cons1 const &cons1, Cons2 const &cons2) + { + return gen::call(cons1.cdr, cons2.cdr); + } + }; + + template + struct segments_gen2 + { + typedef segmented_view view; + typedef typename result_of::segments::type type; + + static type call(Cons1 const &cons1, Cons2 const &cons2) + { + view v(cons1, cons2); + return fusion::segments(v); + } + }; + + template + struct segments_gen2, cons, false> + { + typedef iterator_range< + typename Car1::iterator_type + , typename Car2::iterator_type + > range; + + typedef single_view type; + + static type call(cons const &cons1, cons const &cons2) + { + return type(range(cons1.car.where_, cons2.car.where_)); + } + }; + + //////////////////////////////////////////////////////////////////////////// + template + struct segments_gen + : segments_gen2::value> + {}; + + template + struct segments_gen, nil> + { + typedef segmented_view > view; + typedef typename result_of::segments::type type; + + static type call(cons const &cons, nil const &) + { + view v(cons); + return fusion::segments(v); + } + }; + + template<> + struct segments_gen + { + typedef nil type; + + static type call(nil const &, nil const &) + { + return nil(); + } + }; + } // namespace detail + + namespace extension + { + template + struct is_segmented_impl; + + // An iterator_range of segmented_iterators is segmented + template<> + struct is_segmented_impl + { + template + struct is_segmented_iterator : mpl::false_ {}; + + template + struct is_segmented_iterator > : mpl::true_ {}; + + template + struct apply + : mpl::and_< + is_segmented_iterator + , is_segmented_iterator + > + {}; + }; + + template + struct segments_impl; + + template<> + struct segments_impl + { + template + struct apply + { + typedef typename Sequence::begin_cons_type begin_cons; + typedef typename Sequence::end_cons_type end_cons; + + typedef detail::segments_gen gen; + typedef typename gen::type type; + + static type call(Sequence &sequence) + { + return gen::call(sequence.first_cons, sequence.last_cons); + } + }; + }; + } + +}} + +#endif diff --git a/thirdparty/boost/fusion/view/filter_view.hpp b/thirdparty/boost/fusion/view/filter_view.hpp new file mode 100644 index 0000000..2db434e --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_FILTER_VIEW_10022005_0608) +#define FUSION_SEQUENCE_VIEW_FILTER_VIEW_10022005_0608 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/filter_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/begin_impl.hpp new file mode 100644 index 0000000..998e4f7 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/begin_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_05062005_0903) +#define FUSION_BEGIN_IMPL_05062005_0903 + +namespace boost { namespace fusion +{ + struct filter_view_tag; + + template + struct filter_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::first_type first_type; + typedef typename Sequence::last_type last_type; + typedef typename Sequence::pred_type pred_type; + typedef filter_iterator type; + + static type + call(Sequence& s) + { + return type(s.first()); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/deref_impl.hpp new file mode 100644 index 0000000..13f2cf4 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/deref_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_05062005_0905) +#define FUSION_DEREF_IMPL_05062005_0905 + +#include + +namespace boost { namespace fusion +{ + struct filter_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + : detail::adapt_deref_traits {}; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/end_impl.hpp new file mode 100644 index 0000000..1708b40 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/end_impl.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_05062005_0906) +#define FUSION_END_IMPL_05062005_0906 + +namespace boost { namespace fusion +{ + struct filter_view_tag; + + template + struct filter_iterator; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::last_type last_type; + typedef typename Sequence::pred_type pred_type; + typedef filter_iterator type; + + static type + call(Sequence& s) + { + return type(s.last()); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/detail/equal_to_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/equal_to_impl.hpp new file mode 100644 index 0000000..cf69034 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/equal_to_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_EQUAL_TO_IMPL_02012005_2133) +#define BOOST_FUSION_EQUAL_TO_IMPL_02012005_2133 + +namespace boost { namespace fusion +{ + struct filter_view_iterator_tag; + + namespace extension + { + template + struct equal_to; + + template + struct equal_to_impl; + + template<> + struct equal_to_impl + { + template + struct apply + : result_of::equal_to + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/filter_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/next_impl.hpp new file mode 100644 index 0000000..d6df530 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/next_impl.hpp @@ -0,0 +1,64 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_06052005_0900) +#define FUSION_NEXT_IMPL_06052005_0900 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct filter_view_iterator_tag; + + template + struct filter_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename Iterator::last_type last_type; + typedef typename Iterator::pred_type pred_type; + + typedef typename + mpl::eval_if< + result_of::equal_to + , mpl::identity + , result_of::next + >::type + next_type; + + typedef typename detail::static_find_if< + next_type, last_type, pred_type> + filter; + + typedef filter_iterator< + typename filter::type, last_type, pred_type> + type; + + static type + call(Iterator const& i) + { + return type(filter::call(i.first)); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/detail/size_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/size_impl.hpp new file mode 100644 index 0000000..e81cc1f --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/size_impl.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SIZE_IMPL_09232005_1058) +#define FUSION_SIZE_IMPL_09232005_1058 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct filter_view_tag; + + namespace extension + { + template + struct size_impl; + + template <> + struct size_impl + { + template + struct apply + : result_of::distance< + typename result_of::begin::type + , typename result_of::end::type> + {}; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/filter_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..25c3b4a --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/detail/value_of_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_05062005_0857) +#define FUSION_VALUE_OF_IMPL_05062005_0857 + +#include + +namespace boost { namespace fusion +{ + struct filter_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + : detail::adapt_value_traits {}; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/filter_view.hpp b/thirdparty/boost/fusion/view/filter_view/filter_view.hpp new file mode 100644 index 0000000..0149993 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/filter_view.hpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_FILTER_VIEW_HPP) +#define FUSION_SEQUENCE_FILTER_VIEW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct filter_view_tag; + struct forward_traversal_tag; + struct fusion_sequence_tag; + + template + struct filter_view : sequence_base > + { + typedef filter_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef forward_traversal_tag category; + typedef mpl::true_ is_view; + + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + typedef Pred pred_type; + + filter_view(Sequence& seq) + : seq(seq) + {} + + first_type first() const { return fusion::begin(seq); } + last_type last() const { return fusion::end(seq); } + typename mpl::if_, Sequence, Sequence&>::type seq; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/filter_view/filter_view_iterator.hpp b/thirdparty/boost/fusion/view/filter_view/filter_view_iterator.hpp new file mode 100644 index 0000000..71a1f73 --- /dev/null +++ b/thirdparty/boost/fusion/view/filter_view/filter_view_iterator.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_FILTER_VIEW_ITERATOR_05062005_0849) +#define FUSION_FILTER_VIEW_ITERATOR_05062005_0849 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct filter_view_iterator_tag; + struct forward_traversal_tag; + + template + struct filter_iterator : iterator_base > + { + typedef convert_iterator first_converter; + typedef typename first_converter::type first_iter; + typedef convert_iterator last_converter; + typedef typename last_converter::type last_iter; + + typedef filter_view_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + typedef detail::static_find_if filter; + typedef typename filter::type first_type; + typedef last_iter last_type; + typedef Pred pred_type; + + filter_iterator(First const& first) + : first(filter::call(first_converter::call(first))) {} + + first_type first; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/iterator_range.hpp b/thirdparty/boost/fusion/view/iterator_range.hpp new file mode 100644 index 0000000..b23a890 --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_ITERATOR_RANGE_10022005_0610) +#define FUSION_SEQUENCE_VIEW_ITERATOR_RANGE_10022005_0610 + +#include + +#endif diff --git a/thirdparty/boost/fusion/view/iterator_range/detail/at_impl.hpp b/thirdparty/boost/fusion/view/iterator_range/detail/at_impl.hpp new file mode 100644 index 0000000..f48df8c --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range/detail/at_impl.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_ITERATOR_RANGE_AT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_ITERATOR_RANGE_AT_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion +{ + struct iterator_range_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + typedef typename Seq::begin_type begin_type; + typedef typename result_of::advance::type pos; + typedef typename result_of::deref::type type; + + static type + call(Seq& s) + { + return * advance(s.first); + } + }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/iterator_range/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/iterator_range/detail/begin_impl.hpp new file mode 100644 index 0000000..47971db --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range/detail/begin_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_05062005_1226) +#define FUSION_BEGIN_IMPL_05062005_1226 + +namespace boost { namespace fusion +{ + struct iterator_range_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::begin_type type; + + static type + call(Sequence& s) + { + return s.first; + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/iterator_range/detail/end_impl.hpp b/thirdparty/boost/fusion/view/iterator_range/detail/end_impl.hpp new file mode 100644 index 0000000..10a391f --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range/detail/end_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_05062005_1226) +#define FUSION_END_IMPL_05062005_1226 + +namespace boost { namespace fusion +{ + struct iterator_range_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::end_type type; + + static type + call(Sequence& s) + { + return s.last; + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/iterator_range/detail/value_at_impl.hpp b/thirdparty/boost/fusion/view/iterator_range/detail/value_at_impl.hpp new file mode 100644 index 0000000..d2a342e --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range/detail/value_at_impl.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_ITERATOR_RANGE_VALUE_AT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_ITERATOR_RANGE_VALUE_AT_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion +{ + struct iterator_range_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply + { + typedef typename Seq::begin_type begin_type; + typedef typename result_of::advance::type pos; + typedef typename result_of::value_of::type type; + }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/iterator_range/iterator_range.hpp b/thirdparty/boost/fusion/view/iterator_range/iterator_range.hpp new file mode 100644 index 0000000..e75e73f --- /dev/null +++ b/thirdparty/boost/fusion/view/iterator_range/iterator_range.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ITERATOR_RANGE_05062005_1224) +#define FUSION_ITERATOR_RANGE_05062005_1224 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct iterator_range_tag; + struct fusion_sequence_tag; + + template + struct iterator_range : sequence_base > + { + typedef typename convert_iterator::type begin_type; + typedef typename convert_iterator::type end_type; + typedef iterator_range_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef typename result_of::distance::type size; + typedef mpl::true_ is_view; + + typedef typename traits::category_of::type category; + + iterator_range(First const& first, Last const& last) + : first(convert_iterator::call(first)) + , last(convert_iterator::call(last)) {} + + begin_type first; + end_type last; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/joint_view.hpp b/thirdparty/boost/fusion/view/joint_view.hpp new file mode 100644 index 0000000..8cfae3a --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_JOINT_VIEW_10022005_0610) +#define FUSION_SEQUENCE_VIEW_JOINT_VIEW_10022005_0610 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/joint_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/joint_view/detail/begin_impl.hpp new file mode 100644 index 0000000..9415f68 --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/detail/begin_impl.hpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_07162005_0115) +#define FUSION_BEGIN_IMPL_07162005_0115 + +#include +#include + +namespace boost { namespace fusion +{ + struct joint_view_tag; + + template + struct joint_view_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::first_type first_type; + typedef typename Sequence::last_type last_type; + typedef typename Sequence::concat_type concat_type; + typedef result_of::equal_to equal_to; + + typedef typename + mpl::if_< + equal_to + , concat_type + , joint_view_iterator + >::type + type; + + static type + call(Sequence& s, mpl::true_) + { + return s.concat(); + } + + static type + call(Sequence& s, mpl::false_) + { + return type(s.first(), s.concat()); + } + + static type + call(Sequence& s) + { + return call(s, equal_to()); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/joint_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/joint_view/detail/deref_impl.hpp new file mode 100644 index 0000000..444704f --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/detail/deref_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_07162005_0137) +#define FUSION_DEREF_IMPL_07162005_0137 + +#include + +namespace boost { namespace fusion +{ + struct joint_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + : detail::adapt_deref_traits {}; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/joint_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/joint_view/detail/end_impl.hpp new file mode 100644 index 0000000..fecaa7a --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/detail/end_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_07162005_0128) +#define FUSION_END_IMPL_07162005_0128 + +#include +#include + +namespace boost { namespace fusion +{ + struct joint_view_tag; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::concat_last_type type; + + static type + call(Sequence& s) + { + return s.concat_last(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/joint_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/joint_view/detail/next_impl.hpp new file mode 100644 index 0000000..4db9319 --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/detail/next_impl.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_07162005_0136) +#define FUSION_NEXT_IMPL_07162005_0136 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct joint_view_iterator_tag; + + template + struct joint_view_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename Iterator::last_type last_type; + typedef typename Iterator::concat_type concat_type; + typedef typename result_of::next::type next_type; + typedef result_of::equal_to equal_to; + + typedef typename + mpl::if_< + equal_to + , concat_type + , joint_view_iterator + >::type + type; + + static type + call(Iterator const& i, mpl::true_) + { + return i.concat; + } + + static type + call(Iterator const& i, mpl::false_) + { + return type(fusion::next(i.first), i.concat); + } + + static type + call(Iterator const& i) + { + return call(i, equal_to()); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/joint_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/joint_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..a84b0cf --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/detail/value_of_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_IMPL_07162005_0132) +#define FUSION_VALUE_IMPL_07162005_0132 + +#include + +namespace boost { namespace fusion +{ + struct joint_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + : detail::adapt_value_traits {}; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/joint_view/joint_view.hpp b/thirdparty/boost/fusion/view/joint_view/joint_view.hpp new file mode 100644 index 0000000..ad08506 --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/joint_view.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_JOINT_VIEW_07162005_0140) +#define FUSION_JOINT_VIEW_07162005_0140 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct joint_view_tag; + struct forward_traversal_tag; + struct fusion_sequence_tag; + + template + struct joint_view : sequence_base > + { + typedef joint_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef forward_traversal_tag category; + typedef mpl::true_ is_view; + + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + typedef typename result_of::begin::type concat_type; + typedef typename result_of::end::type concat_last_type; + typedef typename mpl::plus, result_of::size >::type size; + + joint_view(Sequence1& seq1, Sequence2& seq2) + : seq1(seq1) + , seq2(seq2) + {} + + first_type first() const { return fusion::begin(seq1); } + concat_type concat() const { return fusion::begin(seq2); } + concat_last_type concat_last() const { return fusion::end(seq2); } + + private: + + typename mpl::if_, Sequence1, Sequence1&>::type seq1; + typename mpl::if_, Sequence2, Sequence2&>::type seq2; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/joint_view/joint_view_iterator.hpp b/thirdparty/boost/fusion/view/joint_view/joint_view_iterator.hpp new file mode 100644 index 0000000..e922073 --- /dev/null +++ b/thirdparty/boost/fusion/view/joint_view/joint_view_iterator.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_JOINT_VIEW_ITERATOR_07162005_0140) +#define FUSION_JOINT_VIEW_ITERATOR_07162005_0140 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct joint_view_iterator_tag; + struct forward_traversal_tag; + + template + struct joint_view_iterator + : iterator_base > + { + typedef convert_iterator first_converter; + typedef convert_iterator last_converter; + typedef convert_iterator concat_converter; + + typedef typename first_converter::type first_type; + typedef typename last_converter::type last_type; + typedef typename concat_converter::type concat_type; + + typedef joint_view_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + BOOST_STATIC_ASSERT((!result_of::equal_to::value)); + + joint_view_iterator(First const& first, Concat const& concat) + : first(first_converter::call(first)) + , concat(concat_converter::call(concat)) + {} + + first_type first; + concat_type concat; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/repetitive_view.hpp b/thirdparty/boost/fusion/view/repetitive_view.hpp new file mode 100644 index 0000000..c5f2208 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_HPP_INCLUDED + +#include +#include + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/repetitive_view/detail/begin_impl.hpp new file mode 100644 index 0000000..540fb59 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/detail/begin_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_BEGIN_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_BEGIN_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_tag; + + template + struct repetitive_view_iterator; + + namespace extension + { + template + struct begin_impl; + + template<> + struct begin_impl + { + template + struct apply + { + typedef typename View::sequence_type sequence_type; + + typedef repetitive_view_iterator::type > type; + + static type call(View const& v) + { + return type(v.seq); + } + }; + }; + + } + +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/repetitive_view/detail/deref_impl.hpp new file mode 100644 index 0000000..90c1cf2 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/detail/deref_impl.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_DEREF_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_DEREF_IMPL_HPP_INCLUDED + +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template<> + struct deref_impl + { + template + struct apply + { + typedef typename + result_of::deref::type + type; + + static type call(Iterator const& i) + { + return *i.pos; + } + }; + }; + + } + +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/repetitive_view/detail/end_impl.hpp new file mode 100644 index 0000000..2766c6a --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/detail/end_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_END_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_END_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_tag; + + template + struct repetitive_view_iterator; + + namespace extension + { + template + struct end_impl; + + template<> + struct end_impl + { + template + struct apply + { + typedef typename View::sequence_type sequence_type; + + typedef repetitive_view_iterator::type > type; + + static type call(View const& v) + { + return type(v.seq,end(v.seq)); + } + }; + }; + + } + +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/repetitive_view/detail/next_impl.hpp new file mode 100644 index 0000000..be9c1f2 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/detail/next_impl.hpp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_NEXT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_NEXT_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_iterator_tag; + + template + struct repetitive_view_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template::type>::value > + struct apply_nonempty // + { + // advanvce to next position + + typedef repetitive_view_iterator< + typename Iterator::sequence_type, + typename result_of::next::type + > + type; + + static type call(Iterator const& i) + { + return type(i.seq, next(i.pos)); + } + }; + template + struct apply_nonempty + { + // reset to beginning + + typedef repetitive_view_iterator< + typename Iterator::sequence_type, + typename Iterator::first_type + > + type; + + static type call(Iterator const& i) + { + return type(i.seq); + } + }; + + template ::value > + struct apply // + : apply_nonempty + { }; + + template + struct apply + { + // eps^n = eps + + typedef Iterator type; + + static type call(Iterator const& i) + { + return type(i); + } + }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/repetitive_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..0fa76e1 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/detail/value_of_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_VALUE_OF_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_VALUE_OF_IMPL_HPP_INCLUDED + +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template<> + struct value_of_impl + { + template + struct apply + : result_of::value_of + { }; + }; + } +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/repetitive_view.hpp b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view.hpp new file mode 100644 index 0000000..990ca02 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_REPETITIVE_VIEW_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_REPETITIVE_VIEW_HPP_INCLUDED + +#include +#include + +#include +#include + +#include +#include + + +namespace boost { namespace fusion +{ + struct repetitive_view_tag; + struct fusion_sequence_tag; + + template struct repetitive_view + : sequence_base< repetitive_view > + { + typedef repetitive_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + + typedef single_pass_traversal_tag category; + + typedef typename boost::remove_reference::type sequence_type; + typedef typename + mpl::if_, Sequence, sequence_type&>::type + stored_seq_type; + + repetitive_view(Sequence& seq) + : seq(seq) {} + + stored_seq_type seq; + }; + +}} + +#endif diff --git a/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_fwd.hpp b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_fwd.hpp new file mode 100644 index 0000000..08d0e27 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_fwd.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_FWD_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_FWD_HPP_INCLUDED + +namespace boost { namespace fusion +{ + struct repetitive_view_tag; + + template struct repetitive_view; +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp new file mode 100644 index 0000000..b9e1625 --- /dev/null +++ b/thirdparty/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Distributed under the 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_FUSION_REPETITIVE_VIEW_ITERATOR_HPP_INCLUDED) +#define BOOST_FUSION_REPETITIVE_VIEW_HPP_ITERATOR_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct repetitive_view_iterator_tag; + + template::type> + struct repetitive_view_iterator + : iterator_base< repetitive_view_iterator > + { + typedef repetitive_view_iterator_tag fusion_tag; + + typedef Sequence sequence_type; + typedef typename convert_iterator::type pos_type; + typedef typename convert_iterator::type>::type first_type; + typedef typename convert_iterator::type>::type end_type; + typedef single_pass_traversal_tag category; + + explicit repetitive_view_iterator(Sequence& seq) + : seq(seq), pos(begin(seq)) {} + + repetitive_view_iterator(Sequence& seq, pos_type const& pos) + : seq(seq), pos(pos) {} + + Sequence& seq; + pos_type pos; + + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/reverse_view.hpp b/thirdparty/boost/fusion/view/reverse_view.hpp new file mode 100644 index 0000000..d10dad3 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_REVERSE_VIEW_10022005_0612) +#define FUSION_SEQUENCE_VIEW_REVERSE_VIEW_10022005_0612 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/advance_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/advance_impl.hpp new file mode 100644 index 0000000..ebb2c84 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/advance_impl.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_IMPL_14122005_2015) +#define FUSION_ADVANCE_IMPL_14122005_2015 + +#include +#include + +namespace boost { namespace fusion { + + struct reverse_view_iterator_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template + struct advance_impl; + + template<> + struct advance_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename mpl::negate::type negative_dist; + typedef typename result_of::advance::type advanced_type; + typedef reverse_view_iterator type; + + static type + call(Iterator const& i) + { + return type(boost::fusion::advance(i.first)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/begin_impl.hpp new file mode 100644 index 0000000..32e4b34 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/begin_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_07202005_0849) +#define FUSION_BEGIN_IMPL_07202005_0849 + +namespace boost { namespace fusion +{ + struct reverse_view_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef reverse_view_iterator type; + + static type + call(Sequence const& s) + { + return type(s.last()); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/deref_impl.hpp new file mode 100644 index 0000000..260077e --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/deref_impl.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_07202005_0851) +#define FUSION_DEREF_IMPL_07202005_0851 + +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + { + template + struct apply + { + typedef typename + result_of::deref< + typename result_of::prior< + typename Iterator::first_type + >::type + >::type + type; + + static type + call(Iterator const& i) + { + return *fusion::prior(i.first); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/distance_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/distance_impl.hpp new file mode 100644 index 0000000..32c6f21 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/distance_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_IMPL_14122005_2104) +#define FUSION_DISTANCE_IMPL_14122005_2104 + +#include + +namespace boost { namespace fusion { + + struct reverse_view_iterator_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template + struct distance_impl; + + template<> + struct distance_impl + { + template + struct apply + { + typedef typename First::first_type first_type; + typedef typename Last::first_type last_type; + typedef typename result_of::distance::type type; + + static type + call(First const& first, Last const& last) + { + return boost::fusion::distance(last.first, first.first); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/end_impl.hpp new file mode 100644 index 0000000..eda092e --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/end_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_07202005_0851) +#define FUSION_END_IMPL_07202005_0851 + +namespace boost { namespace fusion +{ + struct reverse_view_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef reverse_view_iterator type; + + static type + call(Sequence const& s) + { + return type(s.first()); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/next_impl.hpp new file mode 100644 index 0000000..d519af2 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/next_impl.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_07202005_0856) +#define FUSION_NEXT_IMPL_07202005_0856 + +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_iterator_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename prior_impl:: + template apply + wrapped; + + typedef reverse_view_iterator type; + + static type + call(Iterator const& i) + { + return type(wrapped::call(i.first)); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/prior_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/prior_impl.hpp new file mode 100644 index 0000000..49a0b93 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/prior_impl.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PRIOR_IMPL_07202005_0857) +#define FUSION_PRIOR_IMPL_07202005_0857 + +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_iterator_tag; + + template + struct reverse_view_iterator; + + namespace extension + { + template <> + struct prior_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename next_impl:: + template apply + wrapped; + + typedef reverse_view_iterator type; + + static type + call(Iterator const& i) + { + return type(wrapped::call(i.first)); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/reverse_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..bb6e4b0 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/detail/value_of_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_07202005_0900) +#define FUSION_VALUE_OF_IMPL_07202005_0900 + +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename + result_of::value_of< + typename result_of::prior< + typename Iterator::first_type + >::type + >::type + type; + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/reverse_view.hpp b/thirdparty/boost/fusion/view/reverse_view/reverse_view.hpp new file mode 100644 index 0000000..c0fd481 --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/reverse_view.hpp @@ -0,0 +1,58 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REVERSE_VIEW_07202005_0836) +#define FUSION_REVERSE_VIEW_07202005_0836 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_tag; + struct fusion_sequence_tag; + + template + struct reverse_view : sequence_base > + { + typedef reverse_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + + typedef typename traits::category_of::type category; + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + typedef typename result_of::size::type size; + + BOOST_STATIC_ASSERT(( + is_base_of< + bidirectional_traversal_tag + , typename traits::category_of::type>::value)); + + reverse_view(Sequence& seq) + : seq(seq) + {} + + first_type first() const { return fusion::begin(seq); } + last_type last() const { return fusion::end(seq); } + typename mpl::if_, Sequence, Sequence&>::type seq; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/reverse_view/reverse_view_iterator.hpp b/thirdparty/boost/fusion/view/reverse_view/reverse_view_iterator.hpp new file mode 100644 index 0000000..dcab3be --- /dev/null +++ b/thirdparty/boost/fusion/view/reverse_view/reverse_view_iterator.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_REVERSE_VIEW_ITERATOR_07202005_0835) +#define FUSION_REVERSE_VIEW_ITERATOR_07202005_0835 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct reverse_view_iterator_tag; + + template + struct reverse_view_iterator + : iterator_base > + { + typedef convert_iterator converter; + typedef typename converter::type first_type; + typedef reverse_view_iterator_tag fusion_tag; + typedef typename traits::category_of::type category; + + BOOST_STATIC_ASSERT(( + is_base_of< + bidirectional_traversal_tag + , category>::value)); + + reverse_view_iterator(First const& first) + : first(converter::call(first)) {} + + first_type first; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/single_view.hpp b/thirdparty/boost/fusion/view/single_view.hpp new file mode 100644 index 0000000..7003442 --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SINGLE_VIEW_03192006_2216) +#define FUSION_SINGLE_VIEW_03192006_2216 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/single_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/single_view/detail/begin_impl.hpp new file mode 100644 index 0000000..933802b --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/detail/begin_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_05052005_0305) +#define FUSION_BEGIN_IMPL_05052005_0305 + +namespace boost { namespace fusion +{ + struct single_view_tag; + + template + struct single_view_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + typedef single_view_iterator type; + + static type + call(Sequence& s) + { + return type(s); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/single_view/detail/deref_impl.hpp new file mode 100644 index 0000000..900fa6f --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/detail/deref_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_05052005_0258) +#define FUSION_DEREF_IMPL_05052005_0258 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct single_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template <> + struct deref_impl + { + template + struct apply + { + typedef typename Iterator::value_type type; + + static type + call(Iterator const& i) + { + return i.val; + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/single_view/detail/end_impl.hpp new file mode 100644 index 0000000..7b84f29 --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/detail/end_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_05052005_0332) +#define FUSION_END_IMPL_05052005_0332 + +namespace boost { namespace fusion +{ + struct single_view_tag; + + template + struct single_view_iterator_end; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + typedef single_view_iterator_end type; + + static type + call(Sequence&) + { + return type(); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/single_view/detail/next_impl.hpp new file mode 100644 index 0000000..650fb6b --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/detail/next_impl.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_05052005_0331) +#define FUSION_NEXT_IMPL_05052005_0331 + +namespace boost { namespace fusion +{ + struct single_view_iterator_tag; + + template + struct single_view_iterator_end; + + template + struct single_view_iterator; + + namespace extension + { + template + struct next_impl; + + template <> + struct next_impl + { + template + struct apply + { + typedef single_view_iterator_end< + typename Iterator::single_view_type> + type; + + static type + call(Iterator) + { + return type(); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/single_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..8c313e3 --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/detail/value_of_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_IMPL_05052005_0324) +#define FUSION_VALUE_IMPL_05052005_0324 + +namespace boost { namespace fusion +{ + struct single_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename Iterator::single_view_type single_view_type; + typedef typename single_view_type::value_type type; + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/single_view.hpp b/thirdparty/boost/fusion/view/single_view/single_view.hpp new file mode 100644 index 0000000..2ddd348 --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/single_view.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SINGLE_VIEW_05052005_0335) +#define FUSION_SINGLE_VIEW_05052005_0335 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct single_view_tag; + struct forward_traversal_tag; + struct fusion_sequence_tag; + + template + struct single_view : sequence_base > + { + typedef single_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef forward_traversal_tag category; + typedef mpl::true_ is_view; + typedef mpl::int_<1> size; + typedef T value_type; + + single_view() + : val() {} + + explicit single_view(typename detail::call_param::type val) + : val(val) {} + + value_type val; + }; + + template + inline single_view::type> + make_single_view(T const& v) + { + return single_view::type>(v); + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/single_view/single_view_iterator.hpp b/thirdparty/boost/fusion/view/single_view/single_view_iterator.hpp new file mode 100644 index 0000000..b5cb330 --- /dev/null +++ b/thirdparty/boost/fusion/view/single_view/single_view_iterator.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SINGLE_VIEW_ITERATOR_05052005_0340) +#define FUSION_SINGLE_VIEW_ITERATOR_05052005_0340 + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct single_view_iterator_tag; + struct forward_traversal_tag; + + template + struct single_view_iterator_end + : iterator_base > + { + typedef single_view_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + }; + + template + struct single_view_iterator + : iterator_base > + { + typedef single_view_iterator_tag fusion_tag; + typedef forward_traversal_tag category; + typedef typename SingleView::value_type value_type; + typedef SingleView single_view_type; + + explicit single_view_iterator(single_view_type const& view) + : val(view.val) {} + + value_type val; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view.hpp b/thirdparty/boost/fusion/view/transform_view.hpp new file mode 100644 index 0000000..aa0cf59 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SEQUENCE_VIEW_TRANSFORM_VIEW_10022005_0612) +#define FUSION_SEQUENCE_VIEW_TRANSFORM_VIEW_10022005_0612 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/advance_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/advance_impl.hpp new file mode 100644 index 0000000..41f3294 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/advance_impl.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_IMPL_13122005_1906) +#define FUSION_ADVANCE_IMPL_13122005_1906 + +#include + +namespace boost { namespace fusion +{ + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + template + struct transform_view_iterator; + + template + struct transform_view_iterator2; + + namespace extension + { + template + struct advance_impl; + + // Unary Version + template<> + struct advance_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename result_of::advance::type advanced_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator type; + + static type + call(Iterator const& i) + { + return type(boost::fusion::advance(i.first), i.f); + } + }; + }; + + // Binary Version + template<> + struct advance_impl + { + template + struct apply + { + typedef typename Iterator::first1_type first1_type; + typedef typename Iterator::first2_type first2_type; + typedef typename result_of::advance::type advanced1_type; + typedef typename result_of::advance::type advanced2_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator2 type; + + static type + call(Iterator const& i) + { + return type( + boost::fusion::advance(i.first1) + , boost::fusion::advance(i.first2), i.f); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/apply_transform_result.hpp b/thirdparty/boost/fusion/view/transform_view/detail/apply_transform_result.hpp new file mode 100644 index 0000000..2913a43 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/apply_transform_result.hpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + Distributed under the 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_FUSION_APPLY_TRANSFORM_RESULT_02092006_1936) +#define BOOST_FUSION_APPLY_TRANSFORM_RESULT_02092006_1936 + +#include + +namespace boost { namespace fusion +{ + struct void_; + + namespace detail + { + template + struct apply_transform_result + { + template + struct apply + : boost::result_of + {}; + + template + struct apply + : boost::result_of + {}; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/detail/at_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/at_impl.hpp new file mode 100644 index 0000000..27e299c --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/at_impl.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_AT_IMPL_20061029_1946) +#define BOOST_FUSION_AT_IMPL_20061029_1946 + +#include +#include +#include + +namespace boost { namespace fusion { + struct transform_view_tag; + struct transform_view2_tag; + + namespace extension + { + template + struct at_impl; + + template<> + struct at_impl + { + template + struct apply + { + typedef typename Seq::transform_type F; + typedef detail::apply_transform_result transform_type; + typedef typename boost::fusion::result_of::at::type value_type; + typedef typename mpl::apply::type type; + + static type call(Seq& seq) + { + return seq.f(boost::fusion::at(seq.seq)); + } + }; + }; + + template<> + struct at_impl + { + template + struct apply + { + typedef typename Seq::transform_type F; + typedef detail::apply_transform_result transform_type; + typedef typename boost::fusion::result_of::at::type value1_type; + typedef typename boost::fusion::result_of::at::type value2_type; + typedef typename mpl::apply::type type; + + static type call(Seq& seq) + { + return seq.f(boost::fusion::at(seq.seq1), boost::fusion::at(seq.seq2)); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/begin_impl.hpp new file mode 100644 index 0000000..bcf3311 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/begin_impl.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_07162005_1031) +#define FUSION_BEGIN_IMPL_07162005_1031 + +#include + +namespace boost { namespace fusion +{ + template + struct transform_view_iterator; + + template + struct transform_view_iterator2; + + namespace extension + { + template + struct begin_impl; + + // Unary Version + template <> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::first_type first_type; + typedef typename Sequence::transform_type transform_type; + typedef transform_view_iterator type; + + static type + call(Sequence& s) + { + return type(s.first(), s.f); + } + }; + }; + + // Binary Version + template <> + struct begin_impl + { + template + struct apply + { + typedef typename Sequence::first1_type first1_type; + typedef typename Sequence::first2_type first2_type; + typedef typename Sequence::transform_type transform_type; + typedef transform_view_iterator2 type; + + static type + call(Sequence& s) + { + return type(s.first1(), s.first2(), s.f); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/deref_impl.hpp new file mode 100644 index 0000000..342fbaf --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/deref_impl.hpp @@ -0,0 +1,76 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_07162005_1026) +#define FUSION_DEREF_IMPL_07162005_1026 + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + namespace extension + { + template + struct deref_impl; + + // Unary Version + template <> + struct deref_impl + { + template + struct apply + { + typedef typename + result_of::deref::type + value_type; + + typedef detail::apply_transform_result transform_type; + typedef typename mpl::apply::type type; + + static type + call(Iterator const& i) + { + return i.f(*i.first); + } + }; + }; + + // Binary Version + template <> + struct deref_impl + { + template + struct apply + { + typedef typename + result_of::deref::type + value1_type; + typedef typename + result_of::deref::type + value2_type; + + typedef detail::apply_transform_result transform_type; + typedef typename mpl::apply::type type; + + static type + call(Iterator const& i) + { + return i.f(*i.first1, *i.first2); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/detail/distance_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/distance_impl.hpp new file mode 100644 index 0000000..158e25b --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/distance_impl.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_IMPL_13122005_2139) +#define FUSION_DISTANCE_IMPL_13122005_2139 + +#include + +namespace boost { namespace fusion { + + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + namespace extension + { + template + struct distance_impl; + + // Unary Version + template<> + struct distance_impl + { + template + struct apply + : result_of::distance + { + static + typename result_of::distance::type + call(First const& first, Last const& last) + { + return boost::fusion::distance(first.first, last.first); + } + }; + }; + + // Binary Version + template<> + struct distance_impl + { + template + struct apply + : result_of::distance + { + static + typename result_of::distance::type + call(First const& first, Last const& last) + { + return boost::fusion::distance(first.first1, last.first1); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/end_impl.hpp new file mode 100644 index 0000000..7d600de --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/end_impl.hpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_07162005_1028) +#define FUSION_END_IMPL_07162005_1028 + +#include + +namespace boost { namespace fusion +{ + template + struct transform_view_iterator; + + template + struct transform_view_iterator2; + + namespace extension + { + template + struct end_impl; + + // Unary Version + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::last_type last_type; + typedef typename Sequence::transform_type transform_type; + typedef transform_view_iterator type; + + static type + call(Sequence& s) + { + return type(s.last(), s.f); + } + }; + }; + + // Binary Version + template <> + struct end_impl + { + template + struct apply + { + typedef typename Sequence::last1_type last1_type; + typedef typename Sequence::last2_type last2_type; + typedef typename Sequence::transform_type transform_type; + typedef transform_view_iterator2 type; + + static type + call(Sequence& s) + { + return type(s.last1(), s.last2(), s.f); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/detail/equal_to_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/equal_to_impl.hpp new file mode 100644 index 0000000..3d1e8e6 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/equal_to_impl.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_TRANSFORM_VIEW_ITERATOR_20070127_0957) +#define BOOST_FUSION_TRANSFORM_VIEW_ITERATOR_20070127_0957 + +#include + +namespace boost { namespace fusion { + + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + namespace extension + { + template + struct equal_to_impl; + + template<> + struct equal_to_impl + { + template + struct apply + : result_of::equal_to + {}; + }; + + template<> + struct equal_to_impl + { + template + struct apply + : result_of::equal_to + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/next_impl.hpp new file mode 100644 index 0000000..0cdbb99 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/next_impl.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_07162005_1029) +#define FUSION_NEXT_IMPL_07162005_1029 + +#include + +namespace boost { namespace fusion +{ + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + template + struct transform_view_iterator; + + template + struct transform_view_iterator2; + + namespace extension + { + template + struct next_impl; + + // Unary Version + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename result_of::next::type next_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator type; + + static type + call(Iterator const& i) + { + return type(fusion::next(i.first), i.f); + } + }; + }; + + // Binary Version + template <> + struct next_impl + { + template + struct apply + { + typedef typename Iterator::first1_type first1_type; + typedef typename Iterator::first2_type first2_type; + typedef typename result_of::next::type next1_type; + typedef typename result_of::next::type next2_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator2 type; + + static type + call(Iterator const& i) + { + return type(fusion::next(i.first1), fusion::next(i.first2), i.f); + } + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/detail/prior_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/prior_impl.hpp new file mode 100644 index 0000000..57da20b --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/prior_impl.hpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PREV_IMPL_13122005_2110) +#define FUSION_PREV_IMPL_13122005_2110 + +#include + +namespace boost { namespace fusion +{ + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + template + struct transform_view_iterator; + + template + struct transform_view_iterator2; + + namespace extension + { + template + struct prior_impl; + + // Unary Version + template<> + struct prior_impl + { + template + struct apply + { + typedef typename Iterator::first_type first_type; + typedef typename result_of::prior::type prior_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator type; + + static type + call(Iterator const& i) + { + return type(fusion::prior(i.first), i.f); + } + }; + }; + + // Binary Version + template<> + struct prior_impl + { + template + struct apply + { + typedef typename Iterator::first1_type first1_type; + typedef typename Iterator::first2_type first2_type; + typedef typename result_of::prior::type prior1_type; + typedef typename result_of::prior::type prior2_type; + typedef typename Iterator::transform_type transform_type; + typedef transform_view_iterator2 type; + + static type + call(Iterator const& i) + { + return type(fusion::prior(i.first1), fusion::prior(i.first2), i.f); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/value_at_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/value_at_impl.hpp new file mode 100644 index 0000000..055ad43 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/value_at_impl.hpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the 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_FUSION_VALUE_AT_IMPL_20061101_0745) +#define BOOST_FUSION_VALUE_AT_IMPL_20061101_0745 + +#include +#include +#include + +namespace boost { namespace fusion { + struct transform_view_tag; + struct transform_view2_tag; + + namespace extension + { + template + struct value_at_impl; + + template<> + struct value_at_impl + { + template + struct apply + { + typedef typename Seq::transform_type F; + typedef detail::apply_transform_result transform_type; + typedef typename boost::fusion::result_of::value_at::type value_type; + typedef typename mpl::apply::type type; + }; + }; + + template<> + struct value_at_impl + { + template + struct apply + { + typedef typename Seq::transform_type F; + typedef detail::apply_transform_result transform_type; + typedef typename boost::fusion::result_of::value_at::type value1_type; + typedef typename boost::fusion::result_of::value_at::type value2_type; + typedef typename mpl::apply::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/transform_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/transform_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..44ccfbb --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/detail/value_of_impl.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_07162005_1030) +#define FUSION_VALUE_OF_IMPL_07162005_1030 + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct transform_view_iterator_tag; + struct transform_view_iterator2_tag; + + namespace extension + { + template + struct value_of_impl; + + // Unary Version + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename + result_of::value_of::type + value_type; + + typedef detail::apply_transform_result transform_type; + typedef typename mpl::apply::type type; + }; + }; + + // Binary Version + template <> + struct value_of_impl + { + template + struct apply + { + typedef typename + result_of::value_of::type + value1_type; + typedef typename + result_of::value_of::type + value2_type; + + typedef detail::apply_transform_result transform_type; + typedef typename mpl::apply::type type; + }; + }; + } +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/transform_view.hpp b/thirdparty/boost/fusion/view/transform_view/transform_view.hpp new file mode 100644 index 0000000..cd0ab25 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/transform_view.hpp @@ -0,0 +1,107 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TRANSFORM_VIEW_07162005_1037) +#define FUSION_TRANSFORM_VIEW_07162005_1037 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct void_; + struct transform_view_tag; + struct transform_view2_tag; + struct fusion_sequence_tag; + + // Binary Version + template + struct transform_view : sequence_base > + { + BOOST_STATIC_ASSERT(result_of::size::value == result_of::size::value); + typedef transform_view2_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + + typedef typename traits::category_of::type category1; + typedef typename traits::category_of::type category2; + typedef typename detail::strictest_traversal< + fusion::vector2 >::type category; + typedef typename result_of::begin::type first1_type; + typedef typename result_of::begin::type first2_type; + typedef typename result_of::end::type last1_type; + typedef typename result_of::end::type last2_type; + typedef typename result_of::size::type size; + typedef Sequence1 sequence1_type; + typedef Sequence2 sequence2_type; + typedef F transform_type; + + transform_view(Sequence1& seq1, Sequence2& seq2, F const& binop) + : f(binop) + , seq1(seq1) + , seq2(seq2) + {} + + first1_type first1() const { return fusion::begin(seq1); } + first2_type first2() const { return fusion::begin(seq2); } + last1_type last1() const { return fusion::end(seq1); } + last2_type last2() const { return fusion::end(seq2); } + + transform_type f; + typename mpl::if_, Sequence1, Sequence1&>::type seq1; + typename mpl::if_, Sequence2, Sequence2&>::type seq2; + }; + + // Unary Version + template +#if defined(BOOST_PARTIAL_SPECIALIZATION_EXPLICT_ARGS) + struct transform_view : sequence_base > +#else + struct transform_view : sequence_base > +#endif + { + typedef transform_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + + typedef typename traits::category_of::type category; + typedef typename result_of::begin::type first_type; + typedef typename result_of::end::type last_type; + typedef typename result_of::size::type size; + typedef Sequence sequence_type; + typedef F transform_type; + + transform_view(Sequence& seq, F const& f) + : seq(seq) + , f(f) + {} + + first_type first() const { return fusion::begin(seq); } + last_type last() const { return fusion::end(seq); } + typename mpl::if_, Sequence, Sequence&>::type seq; + transform_type f; + }; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/transform_view_fwd.hpp b/thirdparty/boost/fusion/view/transform_view/transform_view_fwd.hpp new file mode 100644 index 0000000..2062f5c --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/transform_view_fwd.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TRANSFORM_VIEW_FORWARD_01052006_1839) +#define FUSION_TRANSFORM_VIEW_FORWARD_01052006_1839 + +namespace boost { namespace fusion +{ + struct void_; + struct transform_view_tag; + struct transform_view2_tag; + + template + struct transform_view; +}} + +#endif + + diff --git a/thirdparty/boost/fusion/view/transform_view/transform_view_iterator.hpp b/thirdparty/boost/fusion/view/transform_view/transform_view_iterator.hpp new file mode 100644 index 0000000..c0bebc9 --- /dev/null +++ b/thirdparty/boost/fusion/view/transform_view/transform_view_iterator.hpp @@ -0,0 +1,69 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_TRANSFORM_VIEW_ITERATOR_07162005_1033) +#define FUSION_TRANSFORM_VIEW_ITERATOR_07162005_1033 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + // Unary Version + struct transform_view_iterator_tag; + + template + struct transform_view_iterator + : iterator_base > + { + typedef transform_view_iterator_tag fusion_tag; + typedef convert_iterator converter; + typedef typename converter::type first_type; + typedef typename traits::category_of::type category; + typedef F transform_type; + + transform_view_iterator(First const& first, F const& f) + : first(converter::call(first)), f(f) {} + + first_type first; + transform_type f; + }; + + // Binary Version + struct transform_view_iterator2_tag; + + template + struct transform_view_iterator2 + : iterator_base > + { + typedef transform_view_iterator2_tag fusion_tag; + typedef convert_iterator converter1; + typedef convert_iterator converter2; + typedef typename converter1::type first1_type; + typedef typename converter2::type first2_type; + typedef typename traits::category_of::type category; + typedef F transform_type; + + transform_view_iterator2(First1 const& first1, First2 const& first2, F const& f) + : first1(converter1::call(first1)), first2(converter2::call(first2)), f(f) {} + + first1_type first1; + first2_type first2; + transform_type f; + }; +}} + +#endif + diff --git a/thirdparty/boost/fusion/view/zip_view.hpp b/thirdparty/boost/fusion/view/zip_view.hpp new file mode 100644 index 0000000..669f952 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ZIP_VIEW_23012006_0811) +#define FUSION_ZIP_VIEW_23012006_0811 + +#include +#include + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/advance_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/advance_impl.hpp new file mode 100644 index 0000000..f59bc0c --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/advance_impl.hpp @@ -0,0 +1,69 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ADVANCE_IMPL_20061024_2021) +#define FUSION_ADVANCE_IMPL_20061024_2021 + +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + namespace detail + { + template + struct poly_advance + { + template + struct result; + + template + struct result(It)> + { + typedef typename remove_reference::type it; + typedef typename result_of::advance::type type; + }; + + template + typename result::type + operator()(const It& it) const + { + return fusion::advance(it); + } + }; + } + + namespace extension + { + template + struct advance_impl; + + template<> + struct advance_impl + { + template + struct apply + { + typedef zip_view_iterator< + typename result_of::transform >::type> type; + + static type + call(It const& it) + { + return type( + fusion::transform(it.iterators_, detail::poly_advance())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/at_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/at_impl.hpp new file mode 100644 index 0000000..5a70f27 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/at_impl.hpp @@ -0,0 +1,92 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_AT_IMPL_20060124_1933) +#define FUSION_AT_IMPL_20060124_1933 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace fusion +{ + struct zip_view_tag; + + namespace detail + { + template + struct poly_at + { + template + struct result; + + template + struct result(SeqRef)> + : mpl::eval_if, + mpl::identity, + result_of::at::type, N> > + { + BOOST_MPL_ASSERT((is_reference)); + }; + + template + typename result::type + operator()(Seq& seq) const + { + return fusion::at(seq); + } + + template + typename result::type + operator()(Seq const& seq) const + { + return fusion::at(seq); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct at_impl; + + template<> + struct at_impl + { + template + struct apply + { + typedef typename result_of::as_vector< + typename result_of::transform< + typename Seq::sequences, detail::poly_at >::type>::type type; + + static type + call(Seq& seq) + { + return type( + fusion::transform(seq.sequences_, detail::poly_at())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/begin_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/begin_impl.hpp new file mode 100644 index 0000000..53e82a0 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/begin_impl.hpp @@ -0,0 +1,92 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_BEGIN_IMPL_20060123_2147) +#define FUSION_BEGIN_IMPL_20060123_2147 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_tag; + + namespace detail + { + struct poly_begin + { + template + struct result; + + template + struct result + : mpl::eval_if, + mpl::identity, + result_of::begin::type> > + { + BOOST_MPL_ASSERT((is_reference)); + }; + + template + typename result::type + operator()(Seq& seq) const + { + return fusion::begin(seq); + } + + template + typename result::type + operator()(Seq const& seq) const + { + return fusion::begin(seq); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct begin_impl; + + template<> + struct begin_impl + { + template + struct apply + { + typedef zip_view_iterator< + typename result_of::transform::type, + typename Sequence::category> type; + + static type + call(Sequence& sequence) + { + return type( + fusion::transform(sequence.sequences_, detail::poly_begin())); + } + }; + + + + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/deref_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/deref_impl.hpp new file mode 100644 index 0000000..80b7168 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/deref_impl.hpp @@ -0,0 +1,83 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DEREF_IMPL_20061024_1959) +#define FUSION_DEREF_IMPL_20061024_1959 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + namespace detail + { + struct poly_deref + { + template + struct result; + + template + struct result + { + typedef typename remove_const< + typename remove_reference::type>::type it; + + typedef typename mpl::eval_if, + mpl::identity, + result_of::deref >::type type; + }; + + template + typename result::type + operator()(const It& it) const + { + return fusion::deref(it); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct deref_impl; + + template<> + struct deref_impl + { + template + struct apply + { + typedef typename result_of::as_vector< + typename result_of::transform::type>::type type; + + static type + call(It const& it) + { + return type( + fusion::transform(it.iterators_, detail::poly_deref())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/distance_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/distance_impl.hpp new file mode 100644 index 0000000..1b167cc --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/distance_impl.hpp @@ -0,0 +1,82 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_DISTANCE_IMPL_20060124_2033) +#define FUSION_DISTANCE_IMPL_20060124_2033 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + struct random_access_iterator_tag; + + namespace detail + { + template + struct best_distance + { + typedef typename result_of::find_if< + typename SearchIt::iterators, is_same, random_access_iterator_tag> > finder; + + BOOST_MPL_ASSERT_NOT((is_same >)); + + typedef typename result_of::distance::type type; + }; + + template + struct default_distance + : result_of::distance< + typename result_of::value_at_c::type, + typename result_of::value_at_c::type> + {}; + + template + struct zip_view_iterator_distance + { + typedef typename result_of::find_if< + typename It1::iterators, is_same, random_access_iterator_tag> > finder; + + typedef typename mpl::eval_if< + is_same::type>, + detail::default_distance , + detail::best_distance >::type type; + }; + } + + namespace extension + { + template + struct distance_impl; + + template<> + struct distance_impl + { + template + struct apply + : detail::zip_view_iterator_distance::type + { + static typename detail::zip_view_iterator_distance::type + call(It1 const& it1, It2 const& it2) + { + return typename detail::zip_view_iterator_distance::type(); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/end_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/end_impl.hpp new file mode 100644 index 0000000..fb5fba1 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/end_impl.hpp @@ -0,0 +1,103 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_END_IMPL_20060123_2208) +#define FUSION_END_IMPL_20060123_2208 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_tag; + + namespace detail + { + template + struct get_endpoint + { + typedef typename remove_reference::type Seq; + typedef typename result_of::begin::type begin; + typedef typename result_of::advance::type type; + }; + + template + struct endpoints + { + template + struct result; + + template + struct result(SeqRef)> + : mpl::eval_if, + mpl::identity, + get_endpoint > + { + BOOST_MPL_ASSERT((is_reference)); + }; + + template + typename result::type + operator()(Seq& seq) const + { + return fusion::advance(fusion::begin(seq)); + } + + template + typename result::type + operator()(Seq const& seq) + { + return fusion::advance(fusion::begin(seq)); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct end_impl; + + template<> + struct end_impl + { + template + struct apply + { + typedef zip_view_iterator< + typename result_of::transform >::type, + typename Sequence::category> type; + + static type + call(Sequence& sequence) + { + return type( + fusion::transform(sequence.sequences_, detail::endpoints())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/equal_to_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/equal_to_impl.hpp new file mode 100644 index 0000000..7a18678 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/equal_to_impl.hpp @@ -0,0 +1,62 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_EQUAL_TO_IMPL_20060128_1423) +#define FUSION_EQUAL_TO_IMPL_20060128_1423 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + namespace detail + { + template + struct zip_iterators_equal + { + typedef mpl::zip_view > zipped; + typedef mpl::transform_view > > transformed; + + typedef typename mpl::find_if >::type found; + + typedef typename is_same::type, found>::type type; + }; + } + + namespace extension + { + template + struct equal_to_impl; + + template<> + struct equal_to_impl + { + template + struct apply + : detail::zip_iterators_equal::type + {}; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/next_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/next_impl.hpp new file mode 100644 index 0000000..ef89868 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/next_impl.hpp @@ -0,0 +1,83 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_NEXT_IMPL_20060124_2006) +#define FUSION_NEXT_IMPL_20060124_2006 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + namespace detail + { + struct poly_next + { + template + struct result; + + template + struct result + { + typedef typename remove_const< + typename remove_reference::type>::type it; + + typedef typename mpl::eval_if, + mpl::identity, + result_of::next >::type type; + }; + + template + typename result::type + operator()(const It& it) const + { + return fusion::next(it); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct next_impl; + + template<> + struct next_impl + { + template + struct apply + { + typedef fusion::zip_view_iterator< + typename result_of::transform::type, + typename Iterator::category> type; + + static type + call(Iterator const& it) + { + return type( + fusion::transform(it.iterators_, detail::poly_next())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/prior_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/prior_impl.hpp new file mode 100644 index 0000000..83ea2ba --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/prior_impl.hpp @@ -0,0 +1,83 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_PRIOR_IMPL_20060124_2006) +#define FUSION_PRIOR_IMPL_20060124_2006 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + namespace detail + { + struct poly_prior + { + template + struct result; + + template + struct result + { + typedef typename remove_const< + typename remove_reference::type>::type it; + typedef typename mpl::eval_if, + mpl::identity, + result_of::prior >::type type; + }; + + template + typename result::type + operator()(const It& it) const + { + return fusion::prior(it); + } + + unused_type operator()(unused_type const&) const + { + return unused_type(); + } + }; + } + + namespace extension + { + template + struct prior_impl; + + template<> + struct prior_impl + { + template + struct apply + { + typedef zip_view_iterator< + typename result_of::transform::type, + typename Iterator::category> type; + + static type + call(Iterator const& it) + + { + return type( + fusion::transform(it.iterators_, detail::poly_prior())); + } + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/size_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/size_impl.hpp new file mode 100644 index 0000000..03e6c18 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/size_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_SIZE_IMPL_20060124_0800) +#define FUSION_SIZE_IMPL_20060124_0800 + +namespace boost { namespace fusion { + + struct zip_view_tag; + + namespace extension + { + template + struct size; + + template + struct size_impl; + + template<> + struct size_impl + { + template + struct apply + { + typedef typename Sequence::size type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/value_at_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/value_at_impl.hpp new file mode 100644 index 0000000..2b52a28 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/value_at_impl.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_AT_IMPL_20060124_2129) +#define FUSION_VALUE_AT_IMPL_20060124_2129 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + + struct zip_view_tag; + + namespace detail + { + template + struct poly_value_at + { + template + struct result; + + template + struct result(Seq)> + : mpl::eval_if, + mpl::identity, + result_of::value_at::type, N> > + {}; + }; + } + + namespace extension + { + template + struct value_at_impl; + + template<> + struct value_at_impl + { + template + struct apply + { + typedef typename result_of::transform< + typename Sequence::sequences, + detail::poly_value_at >::type values; + typedef typename result_of::as_vector::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/detail/value_of_impl.hpp b/thirdparty/boost/fusion/view/zip_view/detail/value_of_impl.hpp new file mode 100644 index 0000000..c082a59 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/detail/value_of_impl.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_VALUE_OF_IMPL_20060124_2147) +#define FUSION_VALUE_OF_IMPL_20060124_2147 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct zip_view_iterator_tag; + + namespace detail + { + struct poly_value_of + { + template + struct result; + + template + struct result + : mpl::eval_if, + mpl::identity, + result_of::value_of > + {}; + }; + } + + namespace extension + { + template + struct value_of_impl; + + template<> + struct value_of_impl + { + template + struct apply + { + typedef typename result_of::transform< + typename Iterator::iterators, + detail::poly_value_of>::type values; + + typedef typename result_of::as_vector::type type; + }; + }; + } +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/zip_view.hpp b/thirdparty/boost/fusion/view/zip_view/zip_view.hpp new file mode 100644 index 0000000..1441f02 --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/zip_view.hpp @@ -0,0 +1,115 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ZIP_VIEW_23012006_0813) +#define FUSION_ZIP_VIEW_23012006_0813 + +#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 + +namespace boost { namespace fusion { + + namespace detail + { + template + struct all_references + : fusion::result_of::equal_to > >::type, typename fusion::result_of::end::type> + {}; + + struct seq_ref_size + { + template + struct result; + + template + struct result + { + static int const high_int = static_cast( + (static_cast(~0) >> 1) - 1); + + typedef typename remove_reference::type SeqClass; + + typedef typename mpl::eval_if< + traits::is_forward, + result_of::size, + mpl::int_ >::type type; + }; + }; + + struct poly_min + { + template + struct result; + + template + struct result + { + typedef typename remove_reference::type lhs; + typedef typename remove_reference::type rhs; + typedef typename mpl::min::type type; + }; + }; + + template + struct min_size + { + typedef typename result_of::transform::type sizes; + typedef typename result_of::fold::type, detail::poly_min>::type type; + }; + } + + struct zip_view_tag; + struct fusion_sequence_tag; + + template + struct zip_view : sequence_base< zip_view > + { + typedef typename result_of::remove::type real_sequences; + BOOST_MPL_ASSERT((detail::all_references)); + typedef typename detail::strictest_traversal::type category; + typedef zip_view_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::true_ is_view; + typedef typename fusion::result_of::as_vector::type sequences; + typedef typename detail::min_size::type size; + + zip_view( + const Sequences& seqs) + : sequences_(seqs) + {}; + + sequences sequences_; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/zip_view_iterator.hpp b/thirdparty/boost/fusion/view/zip_view/zip_view_iterator.hpp new file mode 100644 index 0000000..3afbe0c --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/zip_view_iterator.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ZIP_VIEW_ITERATOR_23012006_0814) +#define FUSION_ZIP_VIEW_ITERATOR_23012006_0814 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { namespace fusion { + + struct zip_view_iterator_tag; + + template< + typename IteratorSequence, + typename Traversal> + struct zip_view_iterator + : iterator_base > + { + typedef zip_view_iterator_tag fusion_tag; + typedef Traversal category; + + template + zip_view_iterator( + const InitSeq& iterator_seq) + : iterators_(iterator_seq) + {} + + typedef typename result_of::as_vector::type iterators; + iterators iterators_; + }; +}} + +#endif diff --git a/thirdparty/boost/fusion/view/zip_view/zip_view_iterator_fwd.hpp b/thirdparty/boost/fusion/view/zip_view/zip_view_iterator_fwd.hpp new file mode 100644 index 0000000..87b2abc --- /dev/null +++ b/thirdparty/boost/fusion/view/zip_view/zip_view_iterator_fwd.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2001-2006 Joel de Guzman + Copyright (c) 2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(FUSION_ZIP_VIEW_ITERATOR_FWD) +#define FUSION_ZIP_VIEW_ITERATOR_FWD + +#include + +namespace boost { namespace fusion { + + template< + typename IteratorSequence, + typename Traversal = typename detail::strictest_traversal::type> + struct zip_view_iterator; + +}} + +#endif diff --git a/thirdparty/boost/generator_iterator.hpp b/thirdparty/boost/generator_iterator.hpp new file mode 100644 index 0000000..fc27371 --- /dev/null +++ b/thirdparty/boost/generator_iterator.hpp @@ -0,0 +1,80 @@ +// (C) Copyright Jens Maurer 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) +// +// Revision History: + +// 15 Nov 2001 Jens Maurer +// created. + +// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation. + +#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP +#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP + +#include +#include + +namespace boost { + +template +class generator_iterator + : public iterator_facade< + generator_iterator + , typename Generator::result_type + , single_pass_traversal_tag + , typename Generator::result_type const& + > +{ + typedef iterator_facade< + generator_iterator + , typename Generator::result_type + , single_pass_traversal_tag + , typename Generator::result_type const& + > super_t; + + public: + generator_iterator() {} + generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {} + + void increment() + { + m_value = (*m_g)(); + } + + const typename Generator::result_type& + dereference() const + { + return m_value; + } + + bool equal(generator_iterator const& y) const + { + return this->m_g == y.m_g && this->m_value == y.m_value; + } + + private: + Generator* m_g; + typename Generator::result_type m_value; +}; + +template +struct generator_iterator_generator +{ + typedef generator_iterator type; +}; + +template +inline generator_iterator +make_generator_iterator(Generator & gen) +{ + typedef generator_iterator result_t; + return result_t(&gen); +} + +} // namespace boost + + +#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP + diff --git a/thirdparty/boost/get_pointer.hpp b/thirdparty/boost/get_pointer.hpp new file mode 100644 index 0000000..22066e8 --- /dev/null +++ b/thirdparty/boost/get_pointer.hpp @@ -0,0 +1,29 @@ +// Copyright Peter Dimov and David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef GET_POINTER_DWA20021219_HPP +# define GET_POINTER_DWA20021219_HPP + +# include + +namespace boost { + +// get_pointer(p) extracts a ->* capable pointer from p + +template T * get_pointer(T * p) +{ + return p; +} + +// get_pointer(shared_ptr const & p) has been moved to shared_ptr.hpp + +template T * get_pointer(std::auto_ptr const& p) +{ + return p.get(); +} + + +} // namespace boost + +#endif // GET_POINTER_DWA20021219_HPP diff --git a/thirdparty/boost/gil/algorithm.hpp b/thirdparty/boost/gil/algorithm.hpp new file mode 100644 index 0000000..08675de --- /dev/null +++ b/thirdparty/boost/gil/algorithm.hpp @@ -0,0 +1,1014 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + + +/*************************************************************************************************/ + +#ifndef GIL_ALGORITHM_HPP +#define GIL_ALGORITHM_HPP + +#include +#include +#include +#include +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "color_base_algorithm.hpp" +#include "image_view.hpp" +#include "image_view_factory.hpp" +#include "bit_aligned_pixel_iterator.hpp" + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Some basic STL-style algorithms when applied to image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 6, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable : 4244) // conversion from 'gil::image::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) +//#endif + +namespace boost { namespace gil { + +//forward declarations +template +struct planar_pixel_iterator; +template +class memory_based_step_iterator; +template +class memory_based_2d_locator; + +// a tag denoting incompatible arguments +struct error_t {}; + +/// \defgroup ImageViewSTLAlgorithms STL-like Algorithms +/// \ingroup ImageViewAlgorithm +/// \brief Image view-equivalents of STL algorithms +/// +/// Image views provide 1D iteration of their pixels via \p begin() and \p end() methods, +/// which makes it possible to use STL algorithms with them. However, using nested loops +/// over X and Y is in many cases more efficient. The algorithms in this section resemble +/// STL algorithms, but they abstract away the nested loops and take views (as opposed to ranges) as input. +/// +/// Most algorithms check whether the image views are 1D-traversable. A 1D-traversable image view has no gaps +/// at the end of the rows. In other words, if an x_iterator of that view is advanced past the last pixel in a row +/// it will move to the first pixel of the next row. When image views are 1D-traversable, the algorithms use +/// a single loop and run more efficiently. If one or more of the input views are not 1D-traversable, the algorithms +/// fall-back to an X-loop nested inside a Y-loop. +/// +/// The algorithms typically delegate the work to their corresponding STL algorithms. For example, \p copy_pixels calls +/// \p std::copy either for each row, or, when the images are 1D-traversable, once for all pixels. +/// +/// In addition, overloads are sometimes provided for the STL algorithms. For example, std::copy for planar iterators +/// is overloaded to perform \p std::copy for each of the planes. \p std::copy over bitwise-copiable pixels results in +/// std::copy over unsigned char, which STL typically implements via \p memmove. +/// +/// As a result \p copy_pixels may result in a single call to \p memmove for interleaved 1D-traversable views, +/// or one per each plane of planar 1D-traversable views, or one per each row of interleaved non-1D-traversable images, etc. + + +/// \defgroup STLOptimizations Performance overloads of STL algorithms +/// \ingroup ImageViewAlgorithm +/// \brief overloads of STL algorithms allowing more efficient implementation when used with GIL constructs + +/// \brief A generic binary operation on views +/// \ingroup ImageViewSTLAlgorithms +/// +/// Use this class as a convenience superclass when defining an operation for any image views. +/// Many operations have different behavior when the two views are compatible. This class checks +/// for compatibility and invokes apply_compatible(V1,V2) or apply_incompatible(V1,V2) of the subclass. +/// You must provide apply_compatible(V1,V2) method in your subclass, but apply_incompatible(V1,V2) +/// is not required and the default throws std::bad_cast. +template +struct binary_operation_obj { + typedef Result result_type; + + template GIL_FORCEINLINE + result_type operator()(const std::pair& p) const { + return apply(*p.first, *p.second, typename views_are_compatible::type()); + } + + template GIL_FORCEINLINE + result_type operator()(const V1& v1, const V2& v2) const { + return apply(v1, v2, typename views_are_compatible::type()); + } + + result_type operator()(const error_t&) const { throw std::bad_cast(); } +private: + + // dispatch from apply overload to a function with distinct name + template + GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::false_) const { + return ((const Derived*)this)->apply_incompatible(v1,v2); + } + + // dispatch from apply overload to a function with distinct name + template + GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::true_) const { + return ((const Derived*)this)->apply_compatible(v1,v2); + } + + // function with distinct name - it can be overloaded by subclasses + template + GIL_FORCEINLINE result_type apply_incompatible(const V1& v1, const V2& v2) const { + throw std::bad_cast(); + } +}; +} } // namespace boost::gil + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// std::copy and gil::copy_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsCopyPixels copy_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief std::copy for image views + +namespace std { + +/// \ingroup STLOptimizations +/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove +template +GIL_FORCEINLINE boost::gil::pixel* +copy(boost::gil::pixel* first, boost::gil::pixel* last, + boost::gil::pixel* dst) { + return (boost::gil::pixel*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst); +} + +/// \ingroup STLOptimizations +/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove +template +GIL_FORCEINLINE boost::gil::pixel* +copy(const boost::gil::pixel* first, const boost::gil::pixel* last, + boost::gil::pixel* dst) { + return (boost::gil::pixel*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst); +} +} // namespace std + +namespace boost { namespace gil { +namespace detail { +template struct copy_fn { + GIL_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy(first,last,dst); } +}; +} // namespace detail +} } // namespace boost::gil + +namespace std { +/// \ingroup STLOptimizations +/// \brief Copy when both src and dst are planar pointers is copy for each channel +template GIL_FORCEINLINE +boost::gil::planar_pixel_iterator copy(boost::gil::planar_pixel_iterator first, boost::gil::planar_pixel_iterator last, boost::gil::planar_pixel_iterator dst) { + boost::gil::gil_function_requires::value_type,typename std::iterator_traits::value_type> >(); + static_for_each(first,last,dst,boost::gil::detail::copy_fn()); + return dst+(last-first); +} +} // namespace std + +namespace boost { namespace gil { +namespace detail { +/// Does a copy-n. If the inputs contain image iterators, performs a copy at each row using the row iterators +/// \ingroup CopyPixels +template +struct copier_n { + GIL_FORCEINLINE void operator()(I src, typename std::iterator_traits::difference_type n, O dst) const { std::copy(src,src+n, dst); } +}; + +/// Source range is delimited by image iterators +template // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept +struct copier_n,O> { + typedef typename std::iterator_traits >::difference_type diff_t; + GIL_FORCEINLINE void operator()(iterator_from_2d src, diff_t n, O dst) const { + gil_function_requires >(); + gil_function_requires >(); + while (n>0) { + typedef typename iterator_from_2d::difference_type diff_t; + diff_t l=src.width()-src.x_pos(); + diff_t numToCopy=(n // I Models ConstPixelIteratorConcept, OL Models PixelLocatorConcept +struct copier_n > { + typedef typename std::iterator_traits::difference_type diff_t; + GIL_FORCEINLINE void operator()(I src, diff_t n, iterator_from_2d

    dst) const { + gil_function_requires >(); + gil_function_requires >(); + while (n>0) { + diff_t l=dst.width()-dst.x_pos(); + diff_t numToCopy=(n +struct copier_n,iterator_from_2d
      > { + typedef typename iterator_from_2d::difference_type diff_t; + GIL_FORCEINLINE void operator()(iterator_from_2d src, diff_t n, iterator_from_2d
        dst) const { + gil_function_requires >(); + gil_function_requires >(); + if (src.x_pos()!=dst.x_pos() || src.width()!=dst.width()) { + while(n-->0) { + *dst++=*src++; + } + } + while (n>0) { + diff_t l=dst.width()-dst.x_pos(); + diff_t numToCopy=(n +GIL_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) { + typedef typename SrcIterator::x_iterator src_x_iterator; + typedef typename DstIterator::x_iterator dst_x_iterator; + + typename SrcIterator::difference_type n = last - first; + + if (first.is_1d_traversable()) { + if (dst.is_1d_traversable()) + copier_n()(first.x(),n, dst.x()); + else + copier_n()(first.x(),n, dst); + } else { + if (dst.is_1d_traversable()) + copier_n()(first,n, dst.x()); + else + copier_n()(first,n,dst); + } + return dst+n; +} + +} // namespace detail +} } // namespace boost::gil + +namespace std { +/// \ingroup STLOptimizations +/// \brief std::copy(I1,I1,I2) with I1 and I2 being a iterator_from_2d +template +GIL_FORCEINLINE boost::gil::iterator_from_2d
          copy1(boost::gil::iterator_from_2d first, boost::gil::iterator_from_2d last, boost::gil::iterator_from_2d
            dst) { + return boost::gil::detail::copy_with_2d_iterators(first,last,dst); +} + +} // namespace std + +namespace boost { namespace gil { + + +/// \ingroup ImageViewSTLAlgorithmsCopyPixels +/// \brief std::copy for image views +template GIL_FORCEINLINE +void copy_pixels(const View1& src, const View2& dst) { + assert(src.dimensions()==dst.dimensions()); + detail::copy_with_2d_iterators(src.begin(),src.end(),dst.begin()); +} + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// copy_and_convert_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsCopyAndConvertPixels copy_and_convert_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief copies src view into dst view, color converting if necessary. +/// +/// Versions taking static and runtime views are provided. Versions taking user-defined color convered are provided. + +namespace detail { +template +class copy_and_convert_pixels_fn : public binary_operation_obj > { +private: + CC _cc; +public: + typedef typename binary_operation_obj >::result_type result_type; + copy_and_convert_pixels_fn() {} + copy_and_convert_pixels_fn(CC cc_in) : _cc(cc_in) {} + // when the two color spaces are incompatible, a color conversion is performed + template GIL_FORCEINLINE + result_type apply_incompatible(const V1& src, const V2& dst) const { + copy_pixels(color_converted_view(src,_cc),dst); + } + + // If the two color spaces are compatible, copy_and_convert is just copy + template GIL_FORCEINLINE + result_type apply_compatible(const V1& src, const V2& dst) const { + copy_pixels(src,dst); + } +}; +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template +GIL_FORCEINLINE +void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) { + detail::copy_and_convert_pixels_fn ccp(cc); + ccp(src,dst); +} + +struct default_color_converter; + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template +GIL_FORCEINLINE +void copy_and_convert_pixels(const View1& src, const View2& dst) { + detail::copy_and_convert_pixels_fn ccp; + ccp(src,dst); +} + +} } // namespace boost::gil + +////////////////////////////////////////////////////////////////////////////////////// +// +// std::fill and gil::fill_pixels +// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsFillPixels fill_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief std::fill for image views + + +namespace std { +/// \ingroup STLOptimizations +/// \brief std::fill(I,I,V) with I being a iterator_from_2d +/// +/// Invoked when one calls std::fill(I,I,V) with I being a iterator_from_2d (which is +/// a 1D iterator over the pixels in an image). For contiguous images (i.e. images that have +/// no alignment gap at the end of each row) it is more efficient to use the underlying +/// pixel iterator that does not check for the end of rows. For non-contiguous images fill +/// resolves to fill of each row using the underlying pixel iterator, which is still faster +template +void fill(boost::gil::iterator_from_2d first, boost::gil::iterator_from_2d last, const V& val) { + boost::gil::gil_function_requires >(); + if (first.is_1d_traversable()) { + std::fill(first.x(), last.x(), val); + } else { + // fill row by row + std::ptrdiff_t n=last-first; + while (n>0) { + std::ptrdiff_t numToDo=std::min(n,(std::ptrdiff_t)(first.width()-first.x_pos())); + fill_n(first.x(), numToDo, val); + first+=numToDo; + n-=numToDo; + } + } +} +} // namespace std + +namespace boost { namespace gil { + +namespace detail { +/// struct to do std::fill +struct std_fill_t { + template + void operator()(It first, It last, const P& p_in) { + std::fill(first,last,p_in); + } +}; +/// std::fill for planar iterators +template +GIL_FORCEINLINE +void fill_aux(It first, It last, const P& p, mpl::true_) { + static_for_each(first,last,p,std_fill_t()); +} +/// std::fill for interleaved iterators +template +GIL_FORCEINLINE +void fill_aux(It first, It last, const P& p,mpl::false_) { + std::fill(first,last,p); +} +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsFillPixels +/// \brief std::fill for image views +template GIL_FORCEINLINE +void fill_pixels(const View& img_view, const Value& val) { + if (img_view.is_1d_traversable()) + detail::fill_aux(img_view.begin().x(), img_view.end().x(), + val,is_planar()); + else + for (std::ptrdiff_t y=0; y()); +} + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// destruct_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsDestructPixels destruct_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief invokes the destructor on every pixel of an image view + + +namespace detail { + +template GIL_FORCEINLINE +void destruct_range_impl(It first, It last, mpl::true_) { + typedef typename std::iterator_traits::value_type value_t; + if (boost::has_trivial_destructor::value) + return; + while (first!=last) { + first->~value_t(); + ++first; + } +} +template GIL_FORCEINLINE +void destruct_range_impl(It first, It last, mpl::false_) {} + +template GIL_FORCEINLINE +void destruct_range(It first, It last) { + destruct_range_impl(first,last,typename is_pointer::type()); +} + +struct std_destruct_t { + template void operator()(It first, It last) const { destruct_range(first,last); } +}; + +/// destruct for planar iterators +template +GIL_FORCEINLINE +void destruct_aux(It first, It last, mpl::true_) { + static_for_each(first,last,std_destruct_t()); +} +/// destruct for interleaved iterators +template +GIL_FORCEINLINE +void destruct_aux(It first, It last, mpl::false_) { + destruct_range(first,last); +} + +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsDestructPixels +/// \brief Invokes the in-place destructor on every pixel of the view +template GIL_FORCEINLINE +void destruct_pixels(const View& img_view) { + if (img_view.is_1d_traversable()) + detail::destruct_aux(img_view.begin().x(), img_view.end().x(), + is_planar()); + else + for (std::ptrdiff_t y=0; y()); +} + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// uninitialized_fill_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsUninitializedFillPixels uninitialized_fill_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief std::uninitialized_fill for image views + + +namespace detail { + +/// std::uninitialized_fill for planar iterators +/// If an exception is thrown destructs any in-place copy-constructed objects +template +GIL_FORCEINLINE +void uninitialized_fill_aux(It first, It last, + const P& p, mpl::true_) { + int channel=0; + try { + typedef typename std::iterator_traits::value_type pixel_t; + while (channel < num_channels::value) { + std::uninitialized_fill(dynamic_at_c(first,channel), dynamic_at_c(last,channel), + dynamic_at_c(p,channel)); + ++channel; + } + } catch (...) { + for (int c=0; c +GIL_FORCEINLINE +void uninitialized_fill_aux(It first, It last, + const P& p,mpl::false_) { + std::uninitialized_fill(first,last,p); +} + +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsUninitializedFillPixels +/// \brief std::uninitialized_fill for image views. +/// Does not support planar heterogeneous views. +/// If an exception is thrown destructs any in-place copy-constructed pixels +template +void uninitialized_fill_pixels(const View& img_view, const Value& val) { + if (img_view.is_1d_traversable()) + detail::uninitialized_fill_aux(img_view.begin().x(), img_view.end().x(), + val,is_planar()); + else { + typename View::y_coord_t y; + try { + for (y=0; y()); + } catch(...) { + for (typename View::y_coord_t y0=0; y0()); + throw; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// default_construct_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsDefaultConstructPixels default_construct_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief invokes the default constructor on every pixel of an image view + +namespace detail { + +template GIL_FORCEINLINE +void default_construct_range_impl(It first, It last, mpl::true_) { + typedef typename std::iterator_traits::value_type value_t; + It first1=first; + try { + while (first!=last) { + new (first) value_t(); + ++first; + } + } catch (...) { + destruct_range(first1,first); + throw; + } +} + +template GIL_FORCEINLINE +void default_construct_range_impl(It first, It last, mpl::false_) {} + +template GIL_FORCEINLINE +void default_construct_range(It first, It last) { default_construct_range_impl(first, last, typename is_pointer::type()); } + +/// uninitialized_default_construct for planar iterators +template +GIL_FORCEINLINE +void default_construct_aux(It first, It last, mpl::true_) { + int channel=0; + try { + typedef typename std::iterator_traits::value_type pixel_t; + while (channel < num_channels::value) { + default_construct_range(dynamic_at_c(first,channel), dynamic_at_c(last,channel)); + ++channel; + } + } catch (...) { + for (int c=0; c +GIL_FORCEINLINE +void default_construct_aux(It first, It last, mpl::false_) { + default_construct_range(first,last); +} + +template +struct has_trivial_pixel_constructor : public boost::has_trivial_constructor {}; +template +struct has_trivial_pixel_constructor : public boost::has_trivial_constructor::type> {}; + +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsDefaultConstructPixels +/// \brief Invokes the in-place default constructor on every pixel of the (uninitialized) view. +/// Does not support planar heterogeneous views. +/// If an exception is thrown destructs any in-place default-constructed pixels +template +void default_construct_pixels(const View& img_view) { + if (detail::has_trivial_pixel_constructor::value>::value) + return; + + if (img_view.is_1d_traversable()) + detail::default_construct_aux(img_view.begin().x(), img_view.end().x(), is_planar()); + else { + typename View::y_coord_t y; + try { + for (y=0; y()); + } catch(...) { + for (typename View::y_coord_t y0=0; y0()); + throw; + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// uninitialized_copy_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsUninitializedCopyPixels uninitialized_copy_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief std::uninitialized_copy for image views + +namespace detail { + +/// std::uninitialized_copy for pairs of planar iterators +template +GIL_FORCEINLINE +void uninitialized_copy_aux(It1 first1, It1 last1, + It2 first2, mpl::true_) { + int channel=0; + try { + typedef typename std::iterator_traits::value_type pixel_t; + while (channel < num_channels::value) { + std::uninitialized_copy(dynamic_at_c(first1,channel), dynamic_at_c(last1,channel), dynamic_at_c(first2,channel)); + ++channel; + } + } catch (...) { + It2 last2=first2; + std::advance(last2, std::distance(first1,last1)); + for (int c=0; c +GIL_FORCEINLINE +void uninitialized_copy_aux(It1 first1, It1 last1, + It2 first2,mpl::false_) { + std::uninitialized_copy(first1,last1,first2); +} +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsUninitializedCopyPixels +/// \brief std::uninitialized_copy for image views. +/// Does not support planar heterogeneous views. +/// If an exception is thrown destructs any in-place copy-constructed objects +template +void uninitialized_copy_pixels(const View1& view1, const View2& view2) { + typedef mpl::bool_::value && is_planar::value> is_planar; + assert(view1.dimensions()==view2.dimensions()); + if (view1.is_1d_traversable() && view2.is_1d_traversable()) + detail::uninitialized_copy_aux(view1.begin().x(), view1.end().x(), + view2.begin().x(), + is_planar()); + else { + typename View1::y_coord_t y; + try { + for (y=0; y +F for_each_pixel(const V& img, F fun) { + if (img.is_1d_traversable()) { + return std::for_each(img.begin().x(), img.end().x(), fun); + } else { + for (std::ptrdiff_t y=0; y +F for_each_pixel_position(const View& img, F fun) { + typename View::xy_locator loc=img.xy_at(0,0); + for (std::ptrdiff_t y=0; y +void generate_pixels(const View& v, F fun) { + if (v.is_1d_traversable()) { + std::generate(v.begin().x(), v.end().x(), fun); + } else { + for (std::ptrdiff_t y=0; y GIL_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2); + +namespace detail { + +template +struct equal_n_fn { + GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal(i1,i1+n, i2); } +}; + +/// Equal when both ranges are interleaved and of the same type. +/// GIL pixels are bitwise comparable, so memcmp is used. User-defined pixels that are not bitwise comparable need to provide an overload +template +struct equal_n_fn*, const pixel*> { + GIL_FORCEINLINE bool operator()(const pixel* i1, std::ptrdiff_t n, const pixel* i2) const { + return memcmp(i1, i2, n*sizeof(pixel))==0; + } +}; +template +struct equal_n_fn*, pixel*> : equal_n_fn*, const pixel*> {}; + +/// EqualPixels +/// Equal when both ranges are planar pointers of the same type. memcmp is invoked for each channel plane +/// User-defined channels that are not bitwise comparable need to provide an overload +template +struct equal_n_fn, planar_pixel_iterator > { + GIL_FORCEINLINE bool operator()(const planar_pixel_iterator i1, std::ptrdiff_t n, const planar_pixel_iterator i2) const { + ptrdiff_t numBytes=n*sizeof(typename std::iterator_traits::value_type); + + for (std::ptrdiff_t i=0; i::value; ++i) + if (memcmp(dynamic_at_c(i1,i), dynamic_at_c(i2,i), numBytes)!=0) + return false; + return true; + } +}; + + +/// Source range is delimited by image iterators +template // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept +struct equal_n_fn,I2> { + GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d i1, std::ptrdiff_t n, I2 i2) const { + gil_function_requires >(); + gil_function_requires >(); + while (n>0) { + std::ptrdiff_t num=std::min(n, i1.width()-i1.x_pos()); + if (!equal_n(i1.x(), num, i2)) + return false; + i1+=num; + i2+=num; + n-=num; + } + return true; + } +}; + +/// Destination range is delimited by image iterators +template // I Models PixelIteratorConcept, OL Models PixelLocatorConcept +struct equal_n_fn > { + GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, boost::gil::iterator_from_2d i2) const { + gil_function_requires >(); + gil_function_requires >(); + while (n>0) { + std::ptrdiff_t num=std::min(n,i2.width()-i2.x_pos()); + if (!equal_n(i1, num, i2.x())) + return false; + i1+=num; + i2+=num; + n-=num; + } + return true; + } +}; + +/// Both source and destination ranges are delimited by image iterators +template +struct equal_n_fn,boost::gil::iterator_from_2d > { + GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d i1, std::ptrdiff_t n, boost::gil::iterator_from_2d i2) const { + gil_function_requires >(); + gil_function_requires >(); + if (i1.x_pos()!=i2.x_pos() || i1.width()!=i2.width()) { + while(n-->0) { + if (*i1++!=*i2++) return false; + } + } + while (n>0) { + std::ptrdiff_t num=std::min(n,i2.width()-i2.x_pos()); + if (!equal_n(i1.x(), num, i2.x())) + return false; + i1+=num; + i2+=num; + n-=num; + } + return true; + } +}; +} // namespace detail + +template GIL_FORCEINLINE +bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2) { + return detail::equal_n_fn()(i1,n,i2); +} +} } // namespace boost::gil + +namespace std { +/// \ingroup STLOptimizations +/// \brief std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d +/// +/// Invoked when one calls std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d (which is +/// a 1D iterator over the pixels in an image). Attempts to demote the source and destination +/// iterators to simpler/faster types if the corresponding range is contiguous. +/// For contiguous images (i.e. images that have +/// no alignment gap at the end of each row) it is more efficient to use the underlying +/// pixel iterator that does not check for the end of rows. If the underlying pixel iterator +/// happens to be a fundamental planar/interleaved pointer, the call may further resolve +/// to memcmp. Otherwise it resolves to copying each row using the underlying pixel iterator +template GIL_FORCEINLINE +bool equal(boost::gil::iterator_from_2d first, boost::gil::iterator_from_2d last, boost::gil::iterator_from_2d first2) { + boost::gil::gil_function_requires >(); + boost::gil::gil_function_requires >(); + std::ptrdiff_t n=last-first; + if (first.is_1d_traversable()) { + if (first2.is_1d_traversable()) + return boost::gil::detail::equal_n_fn()(first.x(),n, first2.x()); + else + return boost::gil::detail::equal_n_fn >()(first.x(),n, first2); + } else { + if (first2.is_1d_traversable()) + return boost::gil::detail::equal_n_fn,typename Loc2::x_iterator>()(first,n, first2.x()); + else + return boost::gil::detail::equal_n_fn,boost::gil::iterator_from_2d >()(first,n,first2); + } +} +} // namespace std + +namespace boost { namespace gil { + +/// \ingroup ImageViewSTLAlgorithmsEqualPixels +/// \brief std::equal for image views +template GIL_FORCEINLINE +bool equal_pixels(const View1& v1, const View2& v2) { + assert(v1.dimensions()==v2.dimensions()); + return std::equal(v1.begin(),v1.end(),v2.begin()); // std::equal has overloads with GIL iterators for optimal performance +} + +////////////////////////////////////////////////////////////////////////////////////// +/// +/// transform_pixels +/// +////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewSTLAlgorithmsTransformPixels transform_pixels +/// \ingroup ImageViewSTLAlgorithms +/// \brief std::transform for image views + +/// \ingroup ImageViewSTLAlgorithmsTransformPixels +/// \brief std::transform for image views +template GIL_FORCEINLINE +F transform_pixels(const View1& src,const View2& dst, F fun) { + assert(src.dimensions()==dst.dimensions()); + for (std::ptrdiff_t y=0; y GIL_FORCEINLINE +F transform_pixels(const View1& src1, const View2& src2,const View3& dst, F fun) { + for (std::ptrdiff_t y=0; y GIL_FORCEINLINE +F transform_pixel_positions(const View1& src,const View2& dst, F fun) { + assert(src.dimensions()==dst.dimensions()); + typename View1::xy_locator loc=src.xy_at(0,0); + for (std::ptrdiff_t y=0; y GIL_FORCEINLINE +F transform_pixel_positions(const View1& src1,const View2& src2,const View3& dst, F fun) { + assert(src1.dimensions()==dst.dimensions()); + assert(src2.dimensions()==dst.dimensions()); + typename View1::xy_locator loc1=src1.xy_at(0,0); + typename View2::xy_locator loc2=src2.xy_at(0,0); + for (std::ptrdiff_t y=0; y +#include +#include "gil_config.hpp" +#include "bit_aligned_pixel_reference.hpp" +#include "pixel_iterator.hpp" + +namespace boost { namespace gil { + +/// \defgroup PixelIteratorNonAlignedPixelIterator bit_aligned_pixel_iterator +/// \ingroup PixelIteratorModel +/// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept + +//////////////////////////////////////////////////////////////////////////////////////// +/// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept +/// +/// An iterator over pixels that correspond to non-byte-aligned bit ranges. Examples of such pixels are single bit grayscale pixel, or a 6-bit RGB 222 pixel. +/// +/// \ingroup PixelIteratorNonAlignedPixelIterator PixelBasedModel + +template +struct bit_aligned_pixel_iterator : public iterator_facade, + typename NonAlignedPixelReference::value_type, + random_access_traversal_tag, + const NonAlignedPixelReference, + typename NonAlignedPixelReference::bit_range_t::difference_type> { +private: + typedef iterator_facade, + typename NonAlignedPixelReference::value_type, + random_access_traversal_tag, + const NonAlignedPixelReference, + typename NonAlignedPixelReference::bit_range_t::difference_type> parent_t; + template friend struct bit_aligned_pixel_iterator; + + typedef typename NonAlignedPixelReference::bit_range_t bit_range_t; +public: + typedef typename parent_t::difference_type difference_type; + typedef typename parent_t::reference reference; + + bit_aligned_pixel_iterator() {} + bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {} + bit_aligned_pixel_iterator& operator=(const bit_aligned_pixel_iterator& p) { _bit_range=p._bit_range; return *this; } + + template bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {} + + bit_aligned_pixel_iterator(reference* ref) : _bit_range(ref->bit_range()) {} + explicit bit_aligned_pixel_iterator(typename bit_range_t::byte_t* data, int bit_offset=0) : _bit_range(data,bit_offset) {} + + /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; } + + reference operator->() const { return **this; } + const bit_range_t& bit_range() const { return _bit_range; } + bit_range_t& bit_range() { return _bit_range; } +private: + bit_range_t _bit_range; + BOOST_STATIC_CONSTANT(int, bit_size = NonAlignedPixelReference::bit_size); + + friend class boost::iterator_core_access; + reference dereference() const { return NonAlignedPixelReference(_bit_range); } + void increment() { ++_bit_range; } + void decrement() { --_bit_range; } + void advance(difference_type d) { _bit_range.bit_advance(d*bit_size); } + + difference_type distance_to(const bit_aligned_pixel_iterator& it) const { return _bit_range.bit_distance_to(it._bit_range) / bit_size; } + bool equal(const bit_aligned_pixel_iterator& it) const { return _bit_range==it._bit_range; } +}; + +template +struct const_iterator_type > { + typedef bit_aligned_pixel_iterator type; +}; + +template +struct iterator_is_mutable > : public mpl::bool_ {}; + +template +struct is_iterator_adaptor > : public mpl::false_ {}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public is_planar {}; // == false + +///////////////////////////// +// MemoryBasedIteratorConcept +///////////////////////////// + +template +struct byte_to_memunit > : public mpl::int_<8> {}; + +template +inline std::ptrdiff_t memunit_step(const bit_aligned_pixel_iterator&) { + return NonAlignedPixelReference::bit_size; +} + +template +inline std::ptrdiff_t memunit_distance(const bit_aligned_pixel_iterator& p1, const bit_aligned_pixel_iterator& p2) { + return (p2.bit_range().current_byte() - p1.bit_range().current_byte())*8 + p2.bit_range().bit_offset() - p1.bit_range().bit_offset(); +} + +template +inline void memunit_advance(bit_aligned_pixel_iterator& p, std::ptrdiff_t diff) { + p.bit_range().bit_advance(diff); +} + +template +inline bit_aligned_pixel_iterator memunit_advanced(const bit_aligned_pixel_iterator& p, std::ptrdiff_t diff) { + bit_aligned_pixel_iterator ret=p; + memunit_advance(ret, diff); + return ret; +} + +template inline +NonAlignedPixelReference memunit_advanced_ref(bit_aligned_pixel_iterator it, std::ptrdiff_t diff) { + return *memunit_advanced(it,diff); +} +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef memory_based_step_iterator > type; +}; + +///////////////////////////// +// iterator_type_from_pixel +///////////////////////////// + +template +struct iterator_type_from_pixel,false,false,false> { + typedef bit_aligned_pixel_iterator > type; +}; + +template +struct iterator_type_from_pixel,false,false,true> { + typedef bit_aligned_pixel_iterator > type; +}; + +template +struct iterator_type_from_pixel,IsPlanar,IsStep,IsMutable> + : public iterator_type_from_pixel,IsPlanar,IsStep,IsMutable> {}; + +} } // namespace boost::gil + +namespace std { + +// It is important to provide an overload of uninitialized_copy for bit_aligned_pixel_iterator. The default STL implementation calls placement new, +// which is not defined for bit_aligned_pixel_iterator. +template +boost::gil::bit_aligned_pixel_iterator uninitialized_copy(boost::gil::bit_aligned_pixel_iterator first, + boost::gil::bit_aligned_pixel_iterator last, + boost::gil::bit_aligned_pixel_iterator dst) { + return std::copy(first,last,dst); +} + +} // namespace std +#endif diff --git a/thirdparty/boost/gil/bit_aligned_pixel_reference.hpp b/thirdparty/boost/gil/bit_aligned_pixel_reference.hpp new file mode 100644 index 0000000..6e8b079 --- /dev/null +++ b/thirdparty/boost/gil/bit_aligned_pixel_reference.hpp @@ -0,0 +1,302 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP +#define GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief A model of a heterogeneous pixel that is not byte aligned. Examples are bitmap (1-bit pixels) or 6-bit RGB (222) +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 28, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include "gil_config.hpp" +#include "pixel.hpp" +#include "channel.hpp" + +namespace boost { namespace gil { + +///////////////////////////// +// bit_range +// +// Represents a range of bits that can span multiple consecutive bytes. The range has a size fixed at compile time, but the offset is specified at run time. +///////////////////////////// + +template +class bit_range { +public: + typedef typename mpl::if_c::type byte_t; + typedef std::ptrdiff_t difference_type; + template friend class bit_range; +private: + byte_t* _current_byte; // the starting byte of the bit range + int _bit_offset; // offset from the beginning of the current byte. 0<=_bit_offset<=7 + +public: + bit_range() : _current_byte(NULL), _bit_offset(0) {} + bit_range(byte_t* current_byte, int bit_offset) : _current_byte(current_byte), _bit_offset(bit_offset) { assert(bit_offset>=0 && bit_offset<8); } + + bit_range(const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {} + template bit_range(const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {} + + bit_range& operator=(const bit_range& br) { _current_byte = br._current_byte; _bit_offset=br._bit_offset; return *this; } + bool operator==(const bit_range& br) const { return _current_byte==br._current_byte && _bit_offset==br._bit_offset; } + + bit_range& operator++() { + _current_byte += (_bit_offset+RangeSize) / 8; + _bit_offset = (_bit_offset+RangeSize) % 8; + return *this; + } + bit_range& operator--() { bit_advance(-RangeSize); return *this; } + + void bit_advance(difference_type num_bits) { + int new_offset = int(_bit_offset+num_bits); + _current_byte += new_offset / 8; + _bit_offset = new_offset % 8; + if (_bit_offset<0) { + _bit_offset+=8; + --_current_byte; + } + } + difference_type bit_distance_to(const bit_range& b) const { + return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset(); + } + byte_t* current_byte() const { return _current_byte; } + int bit_offset() const { return _bit_offset; } +}; + + +/// \defgroup ColorBaseModelNonAlignedPixel bit_aligned_pixel_reference +/// \ingroup ColorBaseModel +/// \brief A heterogeneous color base representing pixel that may not be byte aligned, i.e. it may correspond to a bit range that does not start/end at a byte boundary. Models ColorBaseConcept. + +/** +\defgroup PixelModelNonAlignedPixel bit_aligned_pixel_reference +\ingroup PixelModel +\brief A heterogeneous pixel reference used to represent non-byte-aligned pixels. Models PixelConcept + +Example: +\code +unsigned char data=0; + +// A mutable reference to a 6-bit BGR pixel in "123" format (1 bit for red, 2 bits for green, 3 bits for blue) +typedef const bit_aligned_pixel_reference, rgb_layout_t, true> rgb123_ref_t; + +// create the pixel reference at bit offset 2 +// (i.e. red = [2], green = [3,4], blue = [5,6,7] bits) +rgb123_ref_t ref(&data, 2); +get_color(ref, red_t()) = 1; +assert(data == 0x04); +get_color(ref, green_t()) = 3; +assert(data == 0x1C); +get_color(ref, blue_t()) = 7; +assert(data == 0xFC); +\endcode +*/ +/// \ingroup ColorBaseModelNonAlignedPixel PixelModelNonAlignedPixel PixelBasedModel +/// \brief Heterogeneous pixel reference corresponding to non-byte-aligned bit range. Models ColorBaseConcept, PixelConcept, PixelBasedConcept +template + typename Layout, + bool IsMutable> +struct bit_aligned_pixel_reference { + BOOST_STATIC_CONSTANT(int, bit_size = (mpl::accumulate, mpl::plus >::type::value)); + typedef bit_range bit_range_t; + typedef BitField bitfield_t; + typedef typename mpl::if_c::type data_ptr_t; + + typedef Layout layout_t; + + typedef typename packed_pixel_type::type value_type; + typedef const bit_aligned_pixel_reference reference; + typedef const bit_aligned_pixel_reference const_reference; + + BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable); + + bit_aligned_pixel_reference(){} + bit_aligned_pixel_reference(data_ptr_t data_ptr, int bit_offset) : _bit_range(data_ptr, bit_offset) {} + explicit bit_aligned_pixel_reference(const bit_range_t& bit_range) : _bit_range(bit_range) {} + template bit_aligned_pixel_reference(const bit_aligned_pixel_reference& p) : _bit_range(p._bit_range) {} + + // Grayscale references can be constructed from the channel reference + explicit bit_aligned_pixel_reference(const typename kth_element_type::type channel0) : _bit_range(static_cast(&channel0), channel0.first_bit()) { + BOOST_STATIC_ASSERT((num_channels::value==1)); + } + + // Construct from another compatible pixel type + bit_aligned_pixel_reference(const bit_aligned_pixel_reference& p) : _bit_range(p._bit_range) {} + template bit_aligned_pixel_reference(packed_pixel& p) : _bit_range(static_cast(&at_c<0>(p)), at_c<0>(p).first_bit()) { + check_compatible >(); + } + + const bit_aligned_pixel_reference& operator=(const bit_aligned_pixel_reference& p) const { static_copy(p,*this); return *this; } + template const bit_aligned_pixel_reference& operator=(const P& p) const { assign(p, mpl::bool_::value>()); return *this; } + + template bool operator==(const P& p) const { return equal(p, mpl::bool_::value>()); } + template bool operator!=(const P& p) const { return !(*this==p); } + + const bit_aligned_pixel_reference* operator->() const { return this; } + + const bit_range_t& bit_range() const { return _bit_range; } +private: + mutable bit_range_t _bit_range; + template friend struct bit_aligned_pixel_reference; + + template static void check_compatible() { gil_function_requires >(); } + + template void assign(const Pixel& p, mpl::true_) const { check_compatible(); static_copy(p,*this); } + template bool equal(const Pixel& p, mpl::true_) const { check_compatible(); return static_equal(*this,p); } + +private: + static void check_gray() { BOOST_STATIC_ASSERT((is_same::value)); } + template void assign(const Channel& chan, mpl::false_) const { check_gray(); at_c<0>(*this)=chan; } + template bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; } +}; + +///////////////////////////// +// ColorBasedConcept +///////////////////////////// + +template +struct kth_element_type, K> { +public: + typedef const packed_dynamic_channel_reference::type::value, IsMutable> type; +}; + +template +struct kth_element_reference_type, K> + : public kth_element_type, K> {}; + +template +struct kth_element_const_reference_type, K> + : public kth_element_type, K> {}; + + +namespace detail { + // returns sum of IntegralVector[0] ... IntegralVector[K-1] + template + struct sum_k : public mpl::plus, typename mpl::at_c::type > {}; + + template struct sum_k : public mpl::int_<0> {}; +} + +// at_c required by MutableColorBaseConcept +template inline +typename kth_element_reference_type,K>::type +at_c(const bit_aligned_pixel_reference& p) { + typedef bit_aligned_pixel_reference pixel_t; + typedef typename kth_element_reference_type::type channel_t; + typedef typename pixel_t::bit_range_t bit_range_t; + + bit_range_t bit_range(p.bit_range()); + bit_range.bit_advance(detail::sum_k::value); + + return channel_t(bit_range.current_byte(), bit_range.bit_offset()); +} + +///////////////////////////// +// PixelConcept +///////////////////////////// + +/// Metafunction predicate that flags bit_aligned_pixel_reference as a model of PixelConcept. Required by PixelConcept +template +struct is_pixel > : public mpl::true_{}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > { + typedef typename L::color_space_t type; +}; + +template +struct channel_mapping_type > { + typedef typename L::channel_mapping_t type; +}; + +template +struct is_planar > : mpl::false_ {}; + +///////////////////////////// +// pixel_reference_type +///////////////////////////// + +namespace detail { + // returns a vector containing K copies of the type T + template struct k_copies; + template struct k_copies<0,T> { + typedef mpl::vector0<> type; + }; + template struct k_copies : public mpl::push_back::type, T> {}; +} + +// Constructs a homogeneous bit_aligned_pixel_reference given a channel reference +template +struct pixel_reference_type, Layout, false, false> { +private: + typedef typename mpl::size::type size_t; + typedef typename detail::k_copies >::type channel_bit_sizes_t; +public: + typedef bit_aligned_pixel_reference type; +}; + +// Same but for the mutable case. We cannot combine the mutable and read-only cases because this triggers ambiguity +template +struct pixel_reference_type, Layout, false, true> { +private: + typedef typename mpl::size::type size_t; + typedef typename detail::k_copies >::type channel_bit_sizes_t; +public: + typedef bit_aligned_pixel_reference type; +}; + +} } // namespace boost::gil + +namespace std { +// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified. +// swap with 'left bias': +// - swap between proxy and anything +// - swap between value type and proxy +// - swap between proxy and proxy +// Having three overloads allows us to swap between different (but compatible) models of PixelConcept + +template inline +void swap(boost::gil::bit_aligned_pixel_reference x, R& y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +template inline +void swap(typename boost::gil::bit_aligned_pixel_reference::value_type& x, boost::gil::bit_aligned_pixel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +template inline +void swap(boost::gil::bit_aligned_pixel_reference x, boost::gil::bit_aligned_pixel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} +} // namespace std +#endif diff --git a/thirdparty/boost/gil/channel.hpp b/thirdparty/boost/gil/channel.hpp new file mode 100644 index 0000000..9051750 --- /dev/null +++ b/thirdparty/boost/gil/channel.hpp @@ -0,0 +1,643 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_CHANNEL_HPP +#define GIL_CHANNEL_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Channel utilities +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 6, 2007 +/// +/// Definitions of standard GIL channel models +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "gil_config.hpp" +#include "utilities.hpp" + +namespace boost { namespace gil { + + +/////////////////////////////////////////// +//// channel_traits +//// +//// \ingroup ChannelModel +//// \class channel_traits +//// \brief defines properties of channels, such as their range and associated types +//// +//// The channel traits must be defined for every model of ChannelConcept +//// Default traits are provided. For built-in types the default traits use +//// built-in pointer and reference and the channel range is the physical +//// range of the type. For classes, the default traits forward the associated types +//// and range to the class. +//// +/////////////////////////////////////////// + +namespace detail { + template struct channel_traits_impl; + + // channel traits for custom class + template + struct channel_traits_impl { + typedef typename T::value_type value_type; + typedef typename T::reference reference; + typedef typename T::pointer pointer; + typedef typename T::const_reference const_reference; + typedef typename T::const_pointer const_pointer; + BOOST_STATIC_CONSTANT(bool, is_mutable=T::is_mutable); + static value_type min_value() { return T::min_value(); } + static value_type max_value() { return T::max_value(); } + }; + + // channel traits implementation for built-in integral or floating point channel type + template + struct channel_traits_impl { + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef const T& const_reference; + typedef T const* const_pointer; + BOOST_STATIC_CONSTANT(bool, is_mutable=true); + static value_type min_value() { return (std::numeric_limits::min)(); } + static value_type max_value() { return (std::numeric_limits::max)(); } + }; + + // channel traits implementation for constant built-in scalar or floating point type + template + struct channel_traits_impl : public channel_traits_impl { + typedef const T& reference; + typedef const T* pointer; + BOOST_STATIC_CONSTANT(bool, is_mutable=false); + }; +} + +/** +\ingroup ChannelModel +\brief Traits for channels. Contains the following members: +\code +template +struct channel_traits { + typedef ... value_type; + typedef ... reference; + typedef ... pointer; + typedef ... const_reference; + typedef ... const_pointer; + + static const bool is_mutable; + static value_type min_value(); + static value_type max_value(); +}; +\endcode +*/ +template +struct channel_traits : public detail::channel_traits_impl::value> {}; + +// Channel traits for C++ reference type - remove the reference +template struct channel_traits< T&> : public channel_traits {}; + +// Channel traits for constant C++ reference type +template struct channel_traits : public channel_traits { + typedef typename channel_traits::const_reference reference; + typedef typename channel_traits::const_pointer pointer; + BOOST_STATIC_CONSTANT(bool, is_mutable=false); +}; + +/////////////////////////////////////////// +//// +//// scoped_channel_value +//// +/////////////////////////////////////////// + +/** +\defgroup ScopedChannelValue scoped_channel_value +\ingroup ChannelModel +\brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept + +Example: +\code +// Create a double channel with range [-0.5 .. 0.5] +struct double_minus_half { static double apply() { return -0.5; } }; +struct double_plus_half { static double apply() { return 0.5; } }; +typedef scoped_channel_value bits64custom_t; + +// channel_convert its maximum should map to the maximum +bits64custom_t x = channel_traits::max_value(); +assert(x == 0.5); +bits16 y = channel_convert(x); +assert(y == 65535); +\endcode +*/ + +/// \ingroup ScopedChannelValue +/// \brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept +template // classes with a static apply() function returning the minimum/maximum channel values +struct scoped_channel_value { + typedef scoped_channel_value value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef const value_type& const_reference; + typedef const value_type* const_pointer; + BOOST_STATIC_CONSTANT(bool, is_mutable=channel_traits::is_mutable); + + static value_type min_value() { return MinVal::apply(); } + static value_type max_value() { return MaxVal::apply(); } + + scoped_channel_value() {} + scoped_channel_value(const scoped_channel_value& c) : _value(c._value) {} + scoped_channel_value(BaseChannelValue val) : _value(val) {} + + scoped_channel_value& operator++() { ++_value; return *this; } + scoped_channel_value& operator--() { --_value; return *this; } + + scoped_channel_value operator++(int) { scoped_channel_value tmp=*this; this->operator++(); return tmp; } + scoped_channel_value operator--(int) { scoped_channel_value tmp=*this; this->operator--(); return tmp; } + + template scoped_channel_value& operator+=(Scalar2 v) { _value+=v; return *this; } + template scoped_channel_value& operator-=(Scalar2 v) { _value-=v; return *this; } + template scoped_channel_value& operator*=(Scalar2 v) { _value*=v; return *this; } + template scoped_channel_value& operator/=(Scalar2 v) { _value/=v; return *this; } + + scoped_channel_value& operator=(BaseChannelValue v) { _value=v; return *this; } + operator BaseChannelValue() const { return _value; } +private: + BaseChannelValue _value; +}; + +struct float_zero { static float apply() { return 0.0f; } }; +struct float_one { static float apply() { return 1.0f; } }; + + +/////////////////////////////////////////// +//// +//// Support for sub-byte channels. These are integral channels whose value is contained in a range of bits inside an integral type +//// +/////////////////////////////////////////// + +// It is necessary for packed channels to have their own value type. They cannot simply use an integral large enough to store the data. Here is why: +// - Any operation that requires returning the result by value will otherwise return the built-in integral type, which will have incorrect range +// That means that after getting the value of the channel we cannot properly do channel_convert, channel_invert, etc. +// - Two channels are declared compatible if they have the same value type. That means that a packed channel is incorrectly declared compatible with an integral type +namespace detail { + // returns the smallest fast unsigned integral type that has at least NumBits bits + template + struct min_fast_uint : public mpl::if_c< (NumBits<=8), + uint_least8_t, + typename mpl::if_c< (NumBits<=16), + uint_least16_t, + typename mpl::if_c< (NumBits<=32), + uint_least32_t, + uintmax_t + >::type + >::type + > {}; +} + +/** +\defgroup PackedChannelValueModel packed_channel_value +\ingroup ChannelModel +\brief Represents the value of an unsigned integral channel operating over a bit range. Models: ChannelValueConcept +Example: +\code +// A 4-bit unsigned integral channel. +typedef packed_channel_value<4> bits4; + +assert(channel_traits::min_value()==0); +assert(channel_traits::max_value()==15); +assert(sizeof(bits4)==1); +BOOST_STATIC_ASSERT((boost::is_integral::value)); +\endcode +*/ + +/// \ingroup PackedChannelValueModel +/// \brief The value of a subbyte channel. Models: ChannelValueConcept +template +class packed_channel_value { + static const std::size_t num_values = 1<::type integer_t; + + typedef packed_channel_value value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + static value_type min_value() { return value_type(0); } + static value_type max_value() { return value_type(num_values-1); } + BOOST_STATIC_CONSTANT(bool, is_mutable=true); + + packed_channel_value() {} + packed_channel_value(integer_t v) : _value(v % num_values) {} + packed_channel_value(const packed_channel_value& v) : _value(v._value) {} + template packed_channel_value(Scalar v) : _value(integer_t(v) % num_values) {} // suppress GCC implicit conversion warnings in channel regression file + + operator integer_t() const { return _value; } +private: + integer_t _value; +}; + +namespace detail { + +template +struct static_copy_bytes { + void operator()(const unsigned char* from, unsigned char* to) const { + *to = *from; + static_copy_bytes()(++from,++to); + } +}; + +template <> +struct static_copy_bytes<0> { + void operator()(const unsigned char* from, unsigned char* to) const {} +}; + +template +class packed_channel_reference_base { +protected: + typedef typename mpl::if_c::type data_ptr_t; +public: + data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range + + typedef packed_channel_value value_type; + typedef const Derived reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + BOOST_STATIC_CONSTANT(int, num_bits=NumBits); + BOOST_STATIC_CONSTANT(bool, is_mutable=Mutable); + + static value_type min_value() { return channel_traits::min_value(); } + static value_type max_value() { return channel_traits::max_value(); } + + typedef BitField bitfield_t; + typedef typename value_type::integer_t integer_t; + + packed_channel_reference_base(data_ptr_t data_ptr) : _data_ptr(data_ptr) {} + packed_channel_reference_base(const packed_channel_reference_base& ref) : _data_ptr(ref._data_ptr) {} + const Derived& operator=(integer_t v) const { set(v); return derived(); } + + const Derived& operator++() const { set(get()+1); return derived(); } + const Derived& operator--() const { set(get()-1); return derived(); } + + Derived operator++(int) const { Derived tmp=derived(); this->operator++(); return tmp; } + Derived operator--(int) const { Derived tmp=derived(); this->operator--(); return tmp; } + + template const Derived& operator+=(Scalar2 v) const { set(get()+v); return derived(); } + template const Derived& operator-=(Scalar2 v) const { set(get()-v); return derived(); } + template const Derived& operator*=(Scalar2 v) const { set(get()*v); return derived(); } + template const Derived& operator/=(Scalar2 v) const { set(get()/v); return derived(); } + + operator integer_t() const { return get(); } + data_ptr_t operator &() const {return _data_ptr;} +protected: + static const integer_t max_val = (1<(_data_ptr); } + void set_data(const bitfield_t& val) const { *static_cast< bitfield_t*>(_data_ptr) = val; } +#else + bitfield_t get_data() const { + bitfield_t ret; + static_copy_bytes()(gil_reinterpret_cast_c(_data_ptr),gil_reinterpret_cast(&ret)); + return ret; + } + void set_data(const bitfield_t& val) const { + static_copy_bytes()(gil_reinterpret_cast_c(&val),gil_reinterpret_cast(_data_ptr)); + } +#endif + +private: + void set(integer_t value) const { // can this be done faster?? + const integer_t num_values = max_val+1; + this->derived().set_unsafe(((value % num_values) + num_values) % num_values); + } + integer_t get() const { return derived().get(); } + const Derived& derived() const { return static_cast(*this); } +}; +} // namespace detail + +/** +\defgroup PackedChannelReferenceModel packed_channel_reference +\ingroup ChannelModel +\brief Represents a reference proxy to a channel operating over a bit range whose offset is fixed at compile time. Models ChannelConcept +Example: +\code +// Reference to a 2-bit channel starting at bit 1 (i.e. the second bit) +typedef const packed_channel_reference bits2_1_ref_t; + +uint16_t data=0; +bits2_1_ref_t channel_ref(&data); +channel_ref = channel_traits::max_value(); // == 3 +assert(data == 6); // == 3<<1 == 6 +\endcode +*/ + +template // true if the reference is mutable +class packed_channel_reference; + +template // true if the reference is mutable +class packed_dynamic_channel_reference; + +/// \ingroup PackedChannelReferenceModel +/// \brief A constant subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept +template +class packed_channel_reference + : public detail::packed_channel_reference_base,BitField,NumBits,false> { + typedef detail::packed_channel_reference_base,BitField,NumBits,false> parent_t; + friend class packed_channel_reference; + + static const BitField channel_mask = parent_t::max_val< const_reference; + typedef const packed_channel_reference mutable_reference; + typedef typename parent_t::integer_t integer_t; + + explicit packed_channel_reference(const void* data_ptr) : parent_t(data_ptr) {} + packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {} + packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr) {} + + unsigned first_bit() const { return FirstBit; } + + integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); } +}; + +/// \ingroup PackedChannelReferenceModel +/// \brief A mutable subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept +template +class packed_channel_reference + : public detail::packed_channel_reference_base,BitField,NumBits,true> { + typedef detail::packed_channel_reference_base,BitField,NumBits,true> parent_t; + friend class packed_channel_reference; + + static const BitField channel_mask = parent_t::max_val< const_reference; + typedef const packed_channel_reference mutable_reference; + typedef typename parent_t::integer_t integer_t; + + explicit packed_channel_reference(void* data_ptr) : parent_t(data_ptr) {} + packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {} + + const packed_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; } + const packed_channel_reference& operator=(const mutable_reference& ref) const { set_from_reference(ref.get_data()); return *this; } + const packed_channel_reference& operator=(const const_reference& ref) const { set_from_reference(ref.get_data()); return *this; } + + template + const packed_channel_reference& operator=(const packed_dynamic_channel_reference& ref) const { set_unsafe(ref.get()); return *this; } + + unsigned first_bit() const { return FirstBit; } + + integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); } + void set_unsafe(integer_t value) const { this->set_data((this->get_data() & ~channel_mask) | (value<set_data((this->get_data() & ~channel_mask) | (other_bits & channel_mask)); } +}; + +} } // namespace boost::gil + +namespace std { +// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified. +// swap with 'left bias': +// - swap between proxy and anything +// - swap between value type and proxy +// - swap between proxy and proxy + +/// \ingroup PackedChannelReferenceModel +/// \brief swap for packed_channel_reference +template inline +void swap(boost::gil::packed_channel_reference x, R& y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \ingroup PackedChannelReferenceModel +/// \brief swap for packed_channel_reference +template inline +void swap(typename boost::gil::packed_channel_reference::value_type& x, boost::gil::packed_channel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \ingroup PackedChannelReferenceModel +/// \brief swap for packed_channel_reference +template inline +void swap(boost::gil::packed_channel_reference x, boost::gil::packed_channel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} +} // namespace std + +namespace boost { namespace gil { + +/** +\defgroup PackedChannelDynamicReferenceModel packed_dynamic_channel_reference +\ingroup ChannelModel +\brief Represents a reference proxy to a channel operating over a bit range whose offset is specified at run time. Models ChannelConcept + +Example: +\code +// Reference to a 2-bit channel whose offset is specified at construction time +typedef const packed_dynamic_channel_reference bits2_dynamic_ref_t; + +uint16_t data=0; +bits2_dynamic_ref_t channel_ref(&data,1); +channel_ref = channel_traits::max_value(); // == 3 +assert(data == 6); // == (3<<1) == 6 +\endcode +*/ + +/// \brief Models a constant subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept +/// Same as packed_channel_reference, except that the offset is a runtime parameter +/// \ingroup PackedChannelDynamicReferenceModel +template +class packed_dynamic_channel_reference + : public detail::packed_channel_reference_base,BitField,NumBits,false> { + typedef detail::packed_channel_reference_base,BitField,NumBits,false> parent_t; + friend class packed_dynamic_channel_reference; + + unsigned _first_bit; // 0..7 + + void operator=(const packed_dynamic_channel_reference&); +public: + typedef const packed_dynamic_channel_reference const_reference; + typedef const packed_dynamic_channel_reference mutable_reference; + typedef typename parent_t::integer_t integer_t; + + packed_dynamic_channel_reference(const void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {} + packed_dynamic_channel_reference(const const_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {} + packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {} + + unsigned first_bit() const { return _first_bit; } + + integer_t get() const { + const BitField channel_mask = parent_t::max_val<<_first_bit; + return (this->get_data()&channel_mask) >> _first_bit; + } +}; + +/// \brief Models a mutable subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept +/// Same as packed_channel_reference, except that the offset is a runtime parameter +/// \ingroup PackedChannelDynamicReferenceModel +template +class packed_dynamic_channel_reference + : public detail::packed_channel_reference_base,BitField,NumBits,true> { + typedef detail::packed_channel_reference_base,BitField,NumBits,true> parent_t; + friend class packed_dynamic_channel_reference; + + unsigned _first_bit; + +public: + typedef const packed_dynamic_channel_reference const_reference; + typedef const packed_dynamic_channel_reference mutable_reference; + typedef typename parent_t::integer_t integer_t; + + packed_dynamic_channel_reference(void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {} + packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {} + + const packed_dynamic_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; } + const packed_dynamic_channel_reference& operator=(const mutable_reference& ref) const { set_unsafe(ref.get()); return *this; } + const packed_dynamic_channel_reference& operator=(const const_reference& ref) const { set_unsafe(ref.get()); return *this; } + + template + const packed_dynamic_channel_reference& operator=(const packed_channel_reference& ref) const + { set_unsafe(ref.get()); return *this; } + + unsigned first_bit() const { return _first_bit; } + + integer_t get() const { + const BitField channel_mask = parent_t::max_val<<_first_bit; + return (this->get_data()&channel_mask) >> _first_bit; + } + void set_unsafe(integer_t value) const { + const BitField channel_mask = parent_t::max_val<<_first_bit; + this->set_data((this->get_data() & ~channel_mask) | value<<_first_bit); + } +}; +} } // namespace boost::gil + +namespace std { +// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified. +// swap with 'left bias': +// - swap between proxy and anything +// - swap between value type and proxy +// - swap between proxy and proxy + + +/// \ingroup PackedChannelDynamicReferenceModel +/// \brief swap for packed_dynamic_channel_reference +template inline +void swap(boost::gil::packed_dynamic_channel_reference x, R& y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \ingroup PackedChannelDynamicReferenceModel +/// \brief swap for packed_dynamic_channel_reference +template inline +void swap(typename boost::gil::packed_dynamic_channel_reference::value_type& x, boost::gil::packed_dynamic_channel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \ingroup PackedChannelDynamicReferenceModel +/// \brief swap for packed_dynamic_channel_reference +template inline +void swap(boost::gil::packed_dynamic_channel_reference x, boost::gil::packed_dynamic_channel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} +} // namespace std + +namespace boost { namespace gil { +/////////////////////////////////////////// +//// +//// Built-in channel models +//// +/////////////////////////////////////////// + +/// \defgroup bits8 bits8 +/// \ingroup ChannelModel +/// \brief 8-bit unsigned integral channel type (typedef from uint8_t). Models ChannelValueConcept + +/// \ingroup bits8 +typedef uint8_t bits8; + +/// \defgroup bits16 bits16 +/// \ingroup ChannelModel +/// \brief 16-bit unsigned integral channel type (typedef from uint16_t). Models ChannelValueConcept + +/// \ingroup bits16 +typedef uint16_t bits16; + +/// \defgroup bits32 bits32 +/// \ingroup ChannelModel +/// \brief 32-bit unsigned integral channel type (typedef from uint32_t). Models ChannelValueConcept + +/// \ingroup bits32 +typedef uint32_t bits32; + +/// \defgroup bits8s bits8s +/// \ingroup ChannelModel +/// \brief 8-bit signed integral channel type (typedef from int8_t). Models ChannelValueConcept + +/// \ingroup bits8s +typedef int8_t bits8s; + +/// \defgroup bits16s bits16s +/// \ingroup ChannelModel +/// \brief 16-bit signed integral channel type (typedef from int16_t). Models ChannelValueConcept + +/// \ingroup bits16s +typedef int16_t bits16s; + +/// \defgroup bits32s bits32s +/// \ingroup ChannelModel +/// \brief 32-bit signed integral channel type (typedef from int32_t). Models ChannelValueConcept + +/// \ingroup bits32s +typedef int32_t bits32s; + +/// \defgroup bits32f bits32f +/// \ingroup ChannelModel +/// \brief 32-bit floating point channel type with range [0.0f ... 1.0f]. Models ChannelValueConcept + +/// \ingroup bits32f +typedef scoped_channel_value bits32f; + +} } // namespace boost::gil + +namespace boost { + +template +struct is_integral > : public mpl::true_ {}; + +template +struct is_integral > : public mpl::true_ {}; + +template +struct is_integral > : public mpl::true_ {}; + +template +struct is_integral > : public is_integral {}; + +} + +#endif diff --git a/thirdparty/boost/gil/channel_algorithm.hpp b/thirdparty/boost/gil/channel_algorithm.hpp new file mode 100644 index 0000000..965826d --- /dev/null +++ b/thirdparty/boost/gil/channel_algorithm.hpp @@ -0,0 +1,469 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_CHANNEL_ALGORITHM_HPP +#define GIL_CHANNEL_ALGORITHM_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Channel algorithms +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 6, 2007 +/// +/// Definitions of standard GIL 8-bit, 16-bit, 32-bit channels +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "gil_config.hpp" +#include "channel.hpp" +#include +#include +#include +#include + +namespace boost { namespace gil { + +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable: 4309) // disable truncation of constant value warning (using -1 to get the max value of an integral) +//#endif + +namespace detail { + +// some forward declarations +template struct channel_converter_unsigned_impl; +template struct channel_converter_unsigned_integral; +template struct channel_converter_unsigned_integral_impl; +template struct channel_converter_unsigned_integral_nondivisible; + +////////////////////////////////////// +//// unsigned_integral_max_value - given an unsigned integral channel type, returns its maximum value as an MPL integral constant +////////////////////////////////////// + + +template +struct unsigned_integral_max_value : public mpl::integral_c {}; + +template <> +struct unsigned_integral_max_value : public mpl::integral_c {}; +template <> +struct unsigned_integral_max_value : public mpl::integral_c {}; +template <> +struct unsigned_integral_max_value : public mpl::integral_c {}; + + +template +struct unsigned_integral_max_value > + : public mpl::integral_c::integer_t, (1< {}; + +////////////////////////////////////// +//// unsigned_integral_num_bits - given an unsigned integral channel type, returns the minimum number of bits needed to represent it +////////////////////////////////////// + +template +struct unsigned_integral_num_bits : public mpl::int_ {}; + +template +struct unsigned_integral_num_bits > + : public mpl::int_ {}; + +} // namespace detail + +/** +\defgroup ChannelConvertAlgorithm channel_convert +\brief Converting from one channel type to another +\ingroup ChannelAlgorithm + +Conversion is done as a simple linear mapping of one channel range to the other, +such that the minimum/maximum value of the source maps to the minimum/maximum value of the destination. +One implication of this is that the value 0 of signed channels may not be preserved! + +When creating new channel models, it is often a good idea to provide specializations for the channel conversion algorithms, for +example, for performance optimizations. If the new model is an integral type that can be signed, it is easier to define the conversion +only for the unsigned type (\p channel_converter_unsigned) and provide specializations of \p detail::channel_convert_to_unsigned +and \p detail::channel_convert_from_unsigned to convert between the signed and unsigned type. + +Example: +\code +// bits32f is a floating point channel with range [0.0f ... 1.0f] +bits32f src_channel = channel_traits::max_value(); +assert(src_channel == 1); + +// bits8 is 8-bit unsigned integral channel (typedef-ed from unsigned char) +bits8 dst_channel = channel_convert(src_channel); +assert(dst_channel == 255); // max value goes to max value +\endcode +*/ + +/** +\defgroup ChannelConvertUnsignedAlgorithm channel_converter_unsigned +\ingroup ChannelConvertAlgorithm +\brief Convert one unsigned/floating point channel to another. Converts both the channel type and range + @{ + */ + +////////////////////////////////////// +//// channel_converter_unsigned +////////////////////////////////////// + +template // Model ChannelValueConcept +struct channel_converter_unsigned + : public detail::channel_converter_unsigned_impl::value,is_integral::value> {}; + + +/// \brief Converting a channel to itself - identity operation +template struct channel_converter_unsigned : public detail::identity {}; + + +namespace detail { + +////////////////////////////////////// +//// channel_converter_unsigned_impl +////////////////////////////////////// + +/// \brief This is the default implementation. Performance specializatons are provided +template +struct channel_converter_unsigned_impl : public std::unary_function { + DstChannelV operator()(SrcChannelV src) const { + return DstChannelV(channel_traits::min_value() + + (src - channel_traits::min_value()) / channel_range() * channel_range()); + } +private: + template + static double channel_range() { + return double(channel_traits::max_value()) - double(channel_traits::min_value()); + } +}; + +// When both the source and the destination are integral channels, perform a faster conversion +template +struct channel_converter_unsigned_impl + : public channel_converter_unsigned_integral,unsigned_integral_max_value >::value > {}; + + +////////////////////////////////////// +//// channel_converter_unsigned_integral +////////////////////////////////////// + +template +struct channel_converter_unsigned_integral + : public channel_converter_unsigned_integral_impl::value % unsigned_integral_max_value::value) > {}; + +template +struct channel_converter_unsigned_integral + : public channel_converter_unsigned_integral_impl::value % unsigned_integral_max_value::value) > {}; + + +////////////////////////////////////// +//// channel_converter_unsigned_integral_impl +////////////////////////////////////// + +// Both source and destination are unsigned integral channels, +// the src max value is less than the dst max value, +// and the dst max value is divisible by the src max value +template +struct channel_converter_unsigned_integral_impl { + DstChannelV operator()(SrcChannelV src) const { + typedef typename unsigned_integral_max_value::value_type integer_t; + static const integer_t mul = unsigned_integral_max_value::value / unsigned_integral_max_value::value; + return DstChannelV(src * mul); + } +}; + +// Both source and destination are unsigned integral channels, +// the dst max value is less than (or equal to) the src max value, +// and the src max value is divisible by the dst max value +template +struct channel_converter_unsigned_integral_impl { + DstChannelV operator()(SrcChannelV src) const { + typedef typename unsigned_integral_max_value::value_type integer_t; + static const integer_t div = unsigned_integral_max_value::value / unsigned_integral_max_value::value; + static const integer_t div2 = div/2; + return DstChannelV((src + div2) / div); + } +}; + +// Prevent overflow for the largest integral type +template +struct channel_converter_unsigned_integral_impl { + DstChannelV operator()(uintmax_t src) const { + static const uintmax_t div = unsigned_integral_max_value::value / unsigned_integral_max_value::value; + static const uintmax_t div2 = div/2; + if (src > unsigned_integral_max_value::value - div2) + return unsigned_integral_max_value::value; + return DstChannelV((src + div2) / div); + } +}; + +// Both source and destination are unsigned integral channels, +// and the dst max value is not divisible by the src max value +// See if you can represent the expression (src * dst_max) / src_max in integral form +template +struct channel_converter_unsigned_integral_impl + : public channel_converter_unsigned_integral_nondivisible,unsigned_integral_num_bits >, + unsigned_integral_num_bits + >::value> {}; + + +// Both source and destination are unsigned integral channels, +// the src max value is less than the dst max value, +// and the dst max value is not divisible by the src max value +// The expression (src * dst_max) / src_max fits in an integer +template +struct channel_converter_unsigned_integral_nondivisible { + DstChannelV operator()(SrcChannelV src) const { + typedef typename detail::min_fast_uint::value+unsigned_integral_num_bits::value>::type integer_t; + return DstChannelV(integer_t(src * unsigned_integral_max_value::value) / unsigned_integral_max_value::value); + } +}; + +// Both source and destination are unsigned integral channels, +// the src max value is less than the dst max value, +// and the dst max value is not divisible by the src max value +// The expression (src * dst_max) / src_max cannot fit in an integer (overflows). Use a double +template +struct channel_converter_unsigned_integral_nondivisible { + DstChannelV operator()(SrcChannelV src) const { + static const double mul = unsigned_integral_max_value::value / double(unsigned_integral_max_value::value); + return DstChannelV(src * mul); + } +}; + + +// Both source and destination are unsigned integral channels, +// the dst max value is less than (or equal to) the src max value, +// and the src max value is not divisible by the dst max value +template +struct channel_converter_unsigned_integral_nondivisible { + DstChannelV operator()(SrcChannelV src) const { + typedef typename unsigned_integral_max_value::value_type integer_t; + + static const double div = unsigned_integral_max_value::value / double(unsigned_integral_max_value::value); + static const integer_t div2 = integer_t(div/2); + return DstChannelV((src + div2) / div); + } +}; + +} // namespace detail + +///////////////////////////////////////////////////// +/// bits32f conversion +///////////////////////////////////////////////////// + +template struct channel_converter_unsigned : public std::unary_function { + DstChannelV operator()(bits32f x) const { return DstChannelV(x*channel_traits::max_value()+0.5f); } +}; + +template struct channel_converter_unsigned : public std::unary_function { + bits32f operator()(SrcChannelV x) const { return bits32f(x/float(channel_traits::max_value())); } +}; + +template <> struct channel_converter_unsigned : public std::unary_function { + bits32f operator()(bits32f x) const { return x; } +}; + + +/// \brief 32 bit <-> float channel conversion +template <> struct channel_converter_unsigned : public std::unary_function { + bits32f operator()(bits32 x) const { + // unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of bits32 matches max_value of bits32f + if (x>=channel_traits::max_value()) return channel_traits::max_value(); + return float(x) / float(channel_traits::max_value()); + } +}; +/// \brief 32 bit <-> float channel conversion +template <> struct channel_converter_unsigned : public std::unary_function { + bits32 operator()(bits32f x) const { + // unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of bits32 matches max_value of bits32f + if (x>=channel_traits::max_value()) return channel_traits::max_value(); + return bits32(x * channel_traits::max_value() + 0.5f); + } +}; + +/// @} + +namespace detail { +// Converting from signed to unsigned integral channel. +// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type) +template // Model ChannelValueConcept +struct channel_convert_to_unsigned : public detail::identity { + typedef ChannelValue type; +}; + +template <> struct channel_convert_to_unsigned : public std::unary_function { + typedef bits8 type; + type operator()(bits8s val) const { return val+128; } +}; + +template <> struct channel_convert_to_unsigned : public std::unary_function { + typedef bits16 type; + type operator()(bits16s val) const { return val+32768; } +}; + +template <> struct channel_convert_to_unsigned : public std::unary_function { + typedef bits32 type; + type operator()(bits32s x) const { return static_cast(x+(1<<31)); } +}; + + +// Converting from unsigned to signed integral channel +// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type) +template // Model ChannelValueConcept +struct channel_convert_from_unsigned : public detail::identity { + typedef ChannelValue type; +}; + +template <> struct channel_convert_from_unsigned : public std::unary_function { + typedef bits8s type; + type operator()(bits8 val) const { return val-128; } +}; + +template <> struct channel_convert_from_unsigned : public std::unary_function { + typedef bits16s type; + type operator()(bits16 val) const { return val-32768; } +}; + +template <> struct channel_convert_from_unsigned : public std::unary_function { + typedef bits32s type; + type operator()(bits32 x) const { return static_cast(x-(1<<31)); } +}; + +} // namespace detail + +/// \ingroup ChannelConvertAlgorithm +/// \brief A unary function object converting between channel types +template // Model ChannelValueConcept +struct channel_converter : public std::unary_function { + DstChannelV operator()(SrcChannelV src) const { + typedef detail::channel_convert_to_unsigned to_unsigned; + typedef detail::channel_convert_from_unsigned from_unsigned; + typedef channel_converter_unsigned converter_unsigned; + return from_unsigned()(converter_unsigned()(to_unsigned()(src))); + } +}; + +/// \ingroup ChannelConvertAlgorithm +/// \brief Converting from one channel type to another. +template // Model ChannelConcept (could be channel references) +inline typename channel_traits::value_type channel_convert(SrcChannel src) { + return channel_converter::value_type, + typename channel_traits::value_type>()(src); +} + +/// \ingroup ChannelConvertAlgorithm +/// \brief Same as channel_converter, except it takes the destination channel by reference, which allows +/// us to move the templates from the class level to the method level. This is important when invoking it +/// on heterogeneous pixels. +struct default_channel_converter { + template + void operator()(const Ch1& src, Ch2& dst) const { + dst=channel_convert(src); + } +}; + +namespace detail { + // fast integer division by 255 + inline uint32_t div255(uint32_t in) { uint32_t tmp=in+128; return (tmp + (tmp>>8))>>8; } + + // fast integer divison by 32768 + inline uint32_t div32768(uint32_t in) { return (in+16384)>>15; } +} + +/** +\defgroup ChannelMultiplyAlgorithm channel_multiply +\ingroup ChannelAlgorithm +\brief Multiplying unsigned channel values of the same type. Performs scaled multiplication result = a * b / max_value + +Example: +\code +bits8 x=128; +bits8 y=128; +bits8 mul = channel_multiply(x,y); +assert(mul == 64); // 64 = 128 * 128 / 255 +\endcode +*/ +/// @{ + +/// \brief This is the default implementation. Performance specializatons are provided +template +struct channel_multiplier_unsigned : public std::binary_function { + ChannelValue operator()(ChannelValue a, ChannelValue b) const { + return ChannelValue(a / double(channel_traits::max_value()) * b); + } +}; + +/// \brief Specialization of channel_multiply for 8-bit unsigned channels +template<> struct channel_multiplier_unsigned : public std::binary_function { + bits8 operator()(bits8 a, bits8 b) const { return bits8(detail::div255(uint32_t(a) * uint32_t(b))); } +}; + +/// \brief Specialization of channel_multiply for 16-bit unsigned channels +template<> struct channel_multiplier_unsigned : public std::binary_function { + bits16 operator()(bits16 a, bits16 b) const { return bits16((uint32_t(a) * uint32_t(b))/65535); } +}; + +/// \brief Specialization of channel_multiply for float 0..1 channels +template<> struct channel_multiplier_unsigned : public std::binary_function { + bits32f operator()(bits32f a, bits32f b) const { return a*b; } +}; + +/// \brief A function object to multiply two channels. result = a * b / max_value +template +struct channel_multiplier : public std::binary_function { + ChannelValue operator()(ChannelValue a, ChannelValue b) const { + typedef detail::channel_convert_to_unsigned to_unsigned; + typedef detail::channel_convert_from_unsigned from_unsigned; + typedef channel_multiplier_unsigned multiplier_unsigned; + return from_unsigned()(multiplier_unsigned()(to_unsigned()(a), to_unsigned()(b))); + } +}; + +/// \brief A function multiplying two channels. result = a * b / max_value +template // Models ChannelConcept (could be a channel reference) +inline typename channel_traits::value_type channel_multiply(Channel a, Channel b) { + return channel_multiplier::value_type>()(a,b); +} +/// @} + +/** +\defgroup ChannelInvertAlgorithm channel_invert +\ingroup ChannelAlgorithm +\brief Returns the inverse of a channel. result = max_value - x + min_value + +Example: +\code +// bits8 == uint8_t == unsigned char +bits8 x=255; +bits8 inv = channel_invert(x); +assert(inv == 0); +\endcode +*/ + +/// \brief Default implementation. Provide overloads for performance +/// \ingroup ChannelInvertAlgorithm channel_invert +template // Models ChannelConcept (could be a channel reference) +inline typename channel_traits::value_type channel_invert(Channel x) { + return channel_traits::max_value()-x + channel_traits::min_value(); +} + +//#ifdef _MSC_VER +//#pragma warning(pop) +//#endif + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/cmyk.hpp b/thirdparty/boost/gil/cmyk.hpp new file mode 100644 index 0000000..e7e163e --- /dev/null +++ b/thirdparty/boost/gil/cmyk.hpp @@ -0,0 +1,66 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_CMYK_H +#define GIL_CMYK_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for CMYK color space and variants +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on October 10, 2007 +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include "metafunctions.hpp" +#include +#include + +namespace boost { namespace gil { + + +/// \addtogroup ColorNameModel +/// \{ + +/// \brief Cyan +struct cyan_t {}; + +/// \brief Magenta +struct magenta_t {}; + +/// \brief Yellow +struct yellow_t {}; + +/// \brief Black +struct black_t {}; +/// \} + +/// \ingroup ColorSpaceModel +typedef mpl::vector4 cmyk_t; + +/// \ingroup LayoutModel +typedef layout cmyk_layout_t; + +/// \ingroup ImageViewConstructors +/// \brief from raw CMYK planar data +template +inline typename type_from_x_iterator >::view_t +planar_cmyk_view(std::size_t width, std::size_t height, IC c, IC m, IC y, IC k, std::ptrdiff_t rowsize_in_bytes) { + typedef typename type_from_x_iterator >::view_t RView; + return RView(width, height, typename RView::locator(planar_pixel_iterator(c,m,y,k), rowsize_in_bytes)); +} + +} } // namespace gil + +#endif diff --git a/thirdparty/boost/gil/color_base.hpp b/thirdparty/boost/gil/color_base.hpp new file mode 100644 index 0000000..950f500 --- /dev/null +++ b/thirdparty/boost/gil/color_base.hpp @@ -0,0 +1,410 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_COLOR_BASE_HPP +#define GIL_COLOR_BASE_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel class and related utilities +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 6, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include + +#include "gil_config.hpp" +#include "utilities.hpp" +#include "gil_concept.hpp" + +namespace boost { namespace gil { + +// Forward-declare +template P* memunit_advanced(const P* p, std::ptrdiff_t diff); + +// Forward-declare semantic_at_c +template +typename disable_if,typename kth_semantic_element_reference_type::type>::type semantic_at_c(ColorBase& p); +template +typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p); + +// Forward declare element_reference_type +template struct element_reference_type; +template struct element_const_reference_type; +template struct kth_element_type; +template struct kth_element_type : public kth_element_type {}; +template struct kth_element_reference_type; +template struct kth_element_reference_type : public kth_element_reference_type {}; +template struct kth_element_const_reference_type; +template struct kth_element_const_reference_type : public kth_element_const_reference_type {}; + +namespace detail { + +template +struct mapping_transform + : public mpl::at >::type + >::type {}; + +/// \defgroup ColorBaseModelHomogeneous detail::homogeneous_color_base +/// \ingroup ColorBaseModel +/// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// If the element type models Regular, this class models HomogeneousColorBaseValueConcept. + + +/// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// \ingroup ColorBaseModelHomogeneous +template +struct homogeneous_color_base { +private: + Element _v0; +public: + typedef Layout layout_t; + typename element_reference_type::type at(mpl::int_<0>) { return _v0; } + typename element_const_reference_type::type at(mpl::int_<0>) const { return _v0; } + + homogeneous_color_base() {} + homogeneous_color_base(Element v) : _v0(v) {} + + // grayscale pixel values are convertible to channel type + operator Element () const { return _v0; } + + template homogeneous_color_base(const homogeneous_color_base& c) : _v0(at_c<0>(c)) {} +}; + + +/// \brief A homogeneous color base holding two color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// \ingroup ColorBaseModelHomogeneous +template +struct homogeneous_color_base { +private: + Element _v0, _v1; +public: + typedef Layout layout_t; + typename element_reference_type::type at(mpl::int_<0>) { return _v0; } + typename element_const_reference_type::type at(mpl::int_<0>) const { return _v0; } + typename element_reference_type::type at(mpl::int_<1>) { return _v1; } + typename element_const_reference_type::type at(mpl::int_<1>) const { return _v1; } + + homogeneous_color_base() {} + explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {} + homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {} + + template homogeneous_color_base(const homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)) {} + + // Support for l-value reference proxy copy construction + template homogeneous_color_base( homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)) {} + + // Support for planar_pixel_iterator construction and dereferencing + template homogeneous_color_base(P* p,bool) : + _v0(&semantic_at_c<0>(*p)), + _v1(&semantic_at_c<1>(*p)) {} + template Ref deref() const { + return Ref(*semantic_at_c<0>(*this), + *semantic_at_c<1>(*this)); } + + // Support for planar_pixel_reference offset constructor + template homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) + : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)), + _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {} + + // Support for planar_pixel_reference operator[] + Element at_c_dynamic(size_t i) const { + if (i==0) return _v0; + return _v1; + } +}; + +/// \brief A homogeneous color base holding three color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// \ingroup ColorBaseModelHomogeneous +template +struct homogeneous_color_base { +private: + Element _v0, _v1, _v2; +public: + typedef Layout layout_t; + typename element_reference_type::type at(mpl::int_<0>) { return _v0; } + typename element_const_reference_type::type at(mpl::int_<0>) const { return _v0; } + typename element_reference_type::type at(mpl::int_<1>) { return _v1; } + typename element_const_reference_type::type at(mpl::int_<1>) const { return _v1; } + typename element_reference_type::type at(mpl::int_<2>) { return _v2; } + typename element_const_reference_type::type at(mpl::int_<2>) const { return _v2; } + + homogeneous_color_base() {} + explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {} + homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {} + + template homogeneous_color_base(const homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)) {} + + // Support for l-value reference proxy copy construction + template homogeneous_color_base( homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)) {} + + // Support for planar_pixel_iterator construction and dereferencing + template homogeneous_color_base(P* p,bool) : + _v0(&semantic_at_c<0>(*p)), + _v1(&semantic_at_c<1>(*p)), + _v2(&semantic_at_c<2>(*p)) {} + template Ref deref() const { + return Ref(*semantic_at_c<0>(*this), + *semantic_at_c<1>(*this), + *semantic_at_c<2>(*this)); } + + // Support for planar_pixel_reference offset constructor + template homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) + : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)), + _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)), + _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {} + + // Support for planar_pixel_reference operator[] + Element at_c_dynamic(size_t i) const { + switch (i) { + case 0: return _v0; + case 1: return _v1; + } + return _v2; + } +}; + +/// \brief A homogeneous color base holding four color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// \ingroup ColorBaseModelHomogeneous +template +struct homogeneous_color_base { +private: + Element _v0, _v1, _v2, _v3; +public: + typedef Layout layout_t; + typename element_reference_type::type at(mpl::int_<0>) { return _v0; } + typename element_const_reference_type::type at(mpl::int_<0>) const { return _v0; } + typename element_reference_type::type at(mpl::int_<1>) { return _v1; } + typename element_const_reference_type::type at(mpl::int_<1>) const { return _v1; } + typename element_reference_type::type at(mpl::int_<2>) { return _v2; } + typename element_const_reference_type::type at(mpl::int_<2>) const { return _v2; } + typename element_reference_type::type at(mpl::int_<3>) { return _v3; } + typename element_const_reference_type::type at(mpl::int_<3>) const { return _v3; } + homogeneous_color_base() {} + explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {} + homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {} + + template homogeneous_color_base(const homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)), + _v3(at_c::value>(c)) {} + + // Support for l-value reference proxy copy construction + template homogeneous_color_base( homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)), + _v3(at_c::value>(c)) {} + + // Support for planar_pixel_iterator construction and dereferencing + template homogeneous_color_base(P* p,bool) : + _v0(&semantic_at_c<0>(*p)), + _v1(&semantic_at_c<1>(*p)), + _v2(&semantic_at_c<2>(*p)), + _v3(&semantic_at_c<3>(*p)) {} + + template Ref deref() const { + return Ref(*semantic_at_c<0>(*this), + *semantic_at_c<1>(*this), + *semantic_at_c<2>(*this), + *semantic_at_c<3>(*this)); } + + // Support for planar_pixel_reference offset constructor + template homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) + : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)), + _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)), + _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)), + _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {} + + // Support for planar_pixel_reference operator[] + Element at_c_dynamic(size_t i) const { + switch (i) { + case 0: return _v0; + case 1: return _v1; + case 2: return _v2; + } + return _v3; + } +}; + +/// \brief A homogeneous color base holding five color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept +/// \ingroup ColorBaseModelHomogeneous +template +struct homogeneous_color_base { +private: + Element _v0, _v1, _v2, _v3, _v4; +public: + typedef Layout layout_t; + typename element_reference_type::type at(mpl::int_<0>) { return _v0; } + typename element_const_reference_type::type at(mpl::int_<0>) const { return _v0; } + typename element_reference_type::type at(mpl::int_<1>) { return _v1; } + typename element_const_reference_type::type at(mpl::int_<1>) const { return _v1; } + typename element_reference_type::type at(mpl::int_<2>) { return _v2; } + typename element_const_reference_type::type at(mpl::int_<2>) const { return _v2; } + typename element_reference_type::type at(mpl::int_<3>) { return _v3; } + typename element_const_reference_type::type at(mpl::int_<3>) const { return _v3; } + typename element_reference_type::type at(mpl::int_<4>) { return _v4; } + typename element_const_reference_type::type at(mpl::int_<4>) const { return _v4; } + homogeneous_color_base() {} + explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {} + homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {} + + template homogeneous_color_base(const homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)), + _v3(at_c::value>(c)), + _v4(at_c::value>(c)) {} + + // Support for l-value reference proxy copy construction + template homogeneous_color_base( homogeneous_color_base& c) : + _v0(at_c::value>(c)), + _v1(at_c::value>(c)), + _v2(at_c::value>(c)), + _v3(at_c::value>(c)), + _v4(at_c::value>(c)) {} + + // Support for planar_pixel_iterator construction and dereferencing + template homogeneous_color_base(P* p,bool) : + _v0(&semantic_at_c<0>(*p)), + _v1(&semantic_at_c<1>(*p)), + _v2(&semantic_at_c<2>(*p)), + _v3(&semantic_at_c<3>(*p)), + _v4(&semantic_at_c<4>(*p)) {} + + template Ref deref() const { + return Ref(*semantic_at_c<0>(*this), + *semantic_at_c<1>(*this), + *semantic_at_c<2>(*this), + *semantic_at_c<3>(*this), + *semantic_at_c<4>(*this)); } + + // Support for planar_pixel_reference offset constructor + template homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) + : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)), + _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)), + _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)), + _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)), + _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {} + + // Support for planar_pixel_reference operator[] + Element at_c_dynamic(size_t i) const { + switch (i) { + case 0: return _v0; + case 1: return _v1; + case 2: return _v2; + case 3: return _v3; + } + return _v4; + } +}; + +// The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe +// -- there is no guarantee that the compiler won't add any padding between adjacent channels. +// Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs. +// This is because the color base structs must model the interleaved organization in memory. In other words, the client may +// have existing RGB image in the form "RGBRGBRGB..." and we must be able to represent it with an array of RGB color bases (i.e. RGB pixels) +// with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem. +// We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size +// of this channel is padded to 4 bytes, so an RGB pixel of it will be 4x3=12 bytes. The code below will still work properly. +// However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types. + +template +typename element_reference_type >::type +dynamic_at_c(homogeneous_color_base& cb, std::size_t i) { + assert(i(&cb))[i]; +} + +template +typename element_const_reference_type >::type +dynamic_at_c(const homogeneous_color_base& cb, std::size_t i) { + assert(i(&cb))[i]; +} + +template +typename element_reference_type >::type +dynamic_at_c(const homogeneous_color_base& cb, std::size_t i) { + assert(i +typename element_const_reference_type >::type +dynamic_at_c(const homogeneous_color_base& cb, std::size_t i) { + assert(i +struct kth_element_type, K> { + typedef Element type; +}; + +template +struct kth_element_reference_type, K> : public add_reference {}; + +template +struct kth_element_const_reference_type, K> : public add_reference::type> {}; + +/// \brief Provides mutable access to the K-th element, in physical order +/// \ingroup ColorBaseModelHomogeneous +template inline +typename add_reference::type +at_c( detail::homogeneous_color_base& p) { return p.at(mpl::int_()); } + +/// \brief Provides constant access to the K-th element, in physical order +/// \ingroup ColorBaseModelHomogeneous +template inline +typename add_reference::type>::type +at_c(const detail::homogeneous_color_base& p) { return p.at(mpl::int_()); } + +namespace detail { + struct swap_fn { + template void operator()(T& x, T& y) const { + using std::swap; + swap(x,y); + } + }; +} +template inline +void swap(detail::homogeneous_color_base& x, detail::homogeneous_color_base& y) { + static_for_each(x,y,detail::swap_fn()); +} + + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/color_base_algorithm.hpp b/thirdparty/boost/gil/color_base_algorithm.hpp new file mode 100644 index 0000000..00edca5 --- /dev/null +++ b/thirdparty/boost/gil/color_base_algorithm.hpp @@ -0,0 +1,696 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_COLOR_BASE_ALGORITHM_HPP +#define GIL_COLOR_BASE_ALGORITHM_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel related algorithms +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 16, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "utilities.hpp" + +namespace boost { namespace gil { + + +/////////////////////////////////////// +/// +/// size: Semantic channel size +/// +/////////////////////////////////////// + +/** +\defgroup ColorBaseAlgorithmSize size +\ingroup ColorBaseAlgorithm +\brief Returns an MPL integral type specifying the number of elements in a color base + +Example: +\code +BOOST_STATIC_ASSERT((size::value == 3)); +BOOST_STATIC_ASSERT((size::value == 4)); +\endcode +*/ + +/// \brief Returns an MPL integral type specifying the number of elements in a color base +/// \ingroup ColorBaseAlgorithmSize +template +struct size : public mpl::size {}; + +/////////////////////////////////////// +/// +/// semantic_at_c: Semantic channel accessors +/// +/////////////////////////////////////// + +/** +\defgroup ColorBaseAlgorithmSemanticAtC kth_semantic_element_type, kth_semantic_element_reference_type, kth_semantic_element_const_reference_type, semantic_at_c +\ingroup ColorBaseAlgorithm +\brief Support for accessing the elements of a color base by semantic index + +The semantic index of an element is the index of its color in the color space. Semantic indexing allows for proper pairing of elements of color bases +independent on their layout. For example, red is the first semantic element of a color base regardless of whether it has an RGB layout or a BGR layout. +All GIL color base algorithms taking multiple color bases use semantic indexing to access their elements. + +Example: +\code +// 16-bit BGR pixel, 4 bits for the blue, 3 bits for the green, 2 bits for the red channel and 7 unused bits +typedef packed_pixel_type, bgr_layout_t>::type bgr432_pixel_t; + +// A reference to its red channel. Although the red channel is the third, its semantic index is 0 in the RGB color space +typedef kth_semantic_element_reference_type::type red_channel_reference_t; + +// Initialize the pixel to black +bgr432_pixel_t red_pixel(0,0,0); + +// Set the red channel to 100% +red_channel_reference_t red_channel = semantic_at_c<0>(red_pixel); +red_channel = channel_traits::max_value(); + +\endcode +*/ +/// \brief Specifies the type of the K-th semantic element of a color base +/// \ingroup ColorBaseAlgorithmSemanticAtC +template struct kth_semantic_element_type { + BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c::type::value)); + typedef typename kth_element_type::type type; +}; + +/// \brief Specifies the return type of the mutable semantic_at_c(color_base); +/// \ingroup ColorBaseAlgorithmSemanticAtC +template struct kth_semantic_element_reference_type { + BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c::type::value)); + typedef typename kth_element_reference_type::type type; + static type get(ColorBase& cb) { return at_c(cb); } +}; + +/// \brief Specifies the return type of the constant semantic_at_c(color_base); +/// \ingroup ColorBaseAlgorithmSemanticAtC +template struct kth_semantic_element_const_reference_type { + BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c::type::value)); + typedef typename kth_element_const_reference_type::type type; + static type get(const ColorBase& cb) { return at_c(cb); } +}; + +/// \brief A mutable accessor to the K-th semantic element of a color base +/// \ingroup ColorBaseAlgorithmSemanticAtC +template inline +typename disable_if,typename kth_semantic_element_reference_type::type>::type +semantic_at_c(ColorBase& p) { + return kth_semantic_element_reference_type::get(p); +} + +/// \brief A constant accessor to the K-th semantic element of a color base +/// \ingroup ColorBaseAlgorithmSemanticAtC +template inline +typename kth_semantic_element_const_reference_type::type +semantic_at_c(const ColorBase& p) { + return kth_semantic_element_const_reference_type::get(p); +} + +/////////////////////////////////////// +/// +/// get_color: Named channel accessors +/// +/////////////////////////////////////// + +/** +\defgroup ColorBaseAlgorithmColor color_element_type, color_element_reference_type, color_element_const_reference_type, get_color, contains_color +\ingroup ColorBaseAlgorithm +\brief Support for accessing the elements of a color base by color name + +Example: A function that takes a generic pixel containing a red channel and sets it to 100%: + +\code +template +void set_red_to_max(Pixel& pixel) { + boost::function_requires >(); + BOOST_STATIC_ASSERT((contains_color::value)); + + typedef typename color_element_type::type red_channel_t; + get_color(pixel, red_t()) = channel_traits::max_value(); +} +\endcode +*/ + +/// \brief A predicate metafunction determining whether a given color base contains a given color +/// \ingroup ColorBaseAlgorithmColor +template +struct contains_color : public mpl::contains {}; + +template +struct color_index_type : public detail::type_to_index {}; + +/// \brief Specifies the type of the element associated with a given color tag +/// \ingroup ColorBaseAlgorithmColor +template +struct color_element_type : public kth_semantic_element_type::value> {}; + +/// \brief Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color()); +/// \ingroup ColorBaseAlgorithmColor +template +struct color_element_reference_type : public kth_semantic_element_reference_type::value> {}; + +/// \brief Specifies the return type of the constant element accessor by color name, get_color(color_base, Color()); +/// \ingroup ColorBaseAlgorithmColor +template +struct color_element_const_reference_type : public kth_semantic_element_const_reference_type::value> {}; + +/// \brief Mutable accessor to the element associated with a given color name +/// \ingroup ColorBaseAlgorithmColor +template +typename color_element_reference_type::type get_color(ColorBase& cb, Color=Color()) { + return color_element_reference_type::get(cb); +} + +/// \brief Constant accessor to the element associated with a given color name +/// \ingroup ColorBaseAlgorithmColor +template +typename color_element_const_reference_type::type get_color(const ColorBase& cb, Color=Color()) { + return color_element_const_reference_type::get(cb); +} + +/////////////////////////////////////// +/// +/// element_type, element_reference_type, element_const_reference_type: Support for homogeneous color bases +/// +/////////////////////////////////////// + +/** +\defgroup ColorBaseAlgorithmHomogeneous element_type, element_reference_type, element_const_reference_type +\ingroup ColorBaseAlgorithm +\brief Types for homogeneous color bases + +Example: +\code +typedef element_type::type element_t; +BOOST_STATIC_ASSERT((boost::is_same::value)); +\endcode +*/ +/// \brief Specifies the element type of a homogeneous color base +/// \ingroup ColorBaseAlgorithmHomogeneous +template +struct element_type : public kth_element_type {}; + +/// \brief Specifies the return type of the mutable element accessor at_c of a homogeneous color base +/// \ingroup ColorBaseAlgorithmHomogeneous +template +struct element_reference_type : public kth_element_reference_type {}; + +/// \brief Specifies the return type of the constant element accessor at_c of a homogeneous color base +/// \ingroup ColorBaseAlgorithmHomogeneous +template +struct element_const_reference_type : public kth_element_const_reference_type {}; + + +namespace detail { + +// compile-time recursion for per-element operations on color bases +template +struct element_recursion { + //static_equal + template + static bool static_equal(const P1& p1, const P2& p2) { + return element_recursion::static_equal(p1,p2) && + semantic_at_c(p1)==semantic_at_c(p2); + } + //static_copy + template + static void static_copy(const P1& p1, P2& p2) { + element_recursion::static_copy(p1,p2); + semantic_at_c(p2)=semantic_at_c(p1); + } + //static_fill + template + static void static_fill(P& p, T2 v) { + element_recursion::static_fill(p,v); + semantic_at_c(p)=v; + } + //static_generate + template + static void static_generate(Dst& dst, Op op) { + element_recursion::static_generate(dst,op); + semantic_at_c(dst)=op(); + } + //static_for_each with one source + template + static Op static_for_each(P1& p1, Op op) { + Op op2(element_recursion::static_for_each(p1,op)); + op2(semantic_at_c(p1)); + return op2; + } + template + static Op static_for_each(const P1& p1, Op op) { + Op op2(element_recursion::static_for_each(p1,op)); + op2(semantic_at_c(p1)); + return op2; + } + //static_for_each with two sources + template + static Op static_for_each(P1& p1, P2& p2, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,op)); + op2(semantic_at_c(p1), semantic_at_c(p2)); + return op2; + } + template + static Op static_for_each(P1& p1, const P2& p2, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,op)); + op2(semantic_at_c(p1), semantic_at_c(p2)); + return op2; + } + template + static Op static_for_each(const P1& p1, P2& p2, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,op)); + op2(semantic_at_c(p1), semantic_at_c(p2)); + return op2; + } + template + static Op static_for_each(const P1& p1, const P2& p2, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,op)); + op2(semantic_at_c(p1), semantic_at_c(p2)); + return op2; + } + //static_for_each with three sources + template + static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(P1& p1, P2& p2, const P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(P1& p1, const P2& p2, P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(P1& p1, const P2& p2, const P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(const P1& p1, P2& p2, P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(const P1& p1, P2& p2, const P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(const P1& p1, const P2& p2, P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + template + static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, Op op) { + Op op2(element_recursion::static_for_each(p1,p2,p3,op)); + op2(semantic_at_c(p1), semantic_at_c(p2), semantic_at_c(p3)); + return op2; + } + //static_transform with one source + template + static Op static_transform(P1& src, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src)); + return op2; + } + template + static Op static_transform(const P1& src, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src)); + return op2; + } + //static_transform with two sources + template + static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src1,src2,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src1), semantic_at_c(src2)); + return op2; + } + template + static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src1,src2,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src1), semantic_at_c(src2)); + return op2; + } + template + static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src1,src2,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src1), semantic_at_c(src2)); + return op2; + } + template + static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) { + Op op2(element_recursion::static_transform(src1,src2,dst,op)); + semantic_at_c(dst)=op2(semantic_at_c(src1), semantic_at_c(src2)); + return op2; + } +}; + +// Termination condition of the compile-time recursion for element operations on a color base +template<> struct element_recursion<0> { + //static_equal + template + static bool static_equal(const P1&, const P2&) { return true; } + //static_copy + template + static void static_copy(const P1&, const P2&) {} + //static_fill + template + static void static_fill(const P&, T2) {} + //static_generate + template + static void static_generate(const Dst&,Op){} + //static_for_each with one source + template + static Op static_for_each(const P1&,Op op){return op;} + //static_for_each with two sources + template + static Op static_for_each(const P1&,const P2&,Op op){return op;} + //static_for_each with three sources + template + static Op static_for_each(const P1&,const P2&,const P3&,Op op){return op;} + //static_transform with one source + template + static Op static_transform(const P1&,const Dst&,Op op){return op;} + //static_transform with two sources + template + static Op static_transform(const P1&,const P2&,const Dst&,Op op){return op;} +}; + +// std::min and std::max don't have the mutable overloads... +template inline const Q& mutable_min(const Q& x, const Q& y) { return x inline Q& mutable_min( Q& x, Q& y) { return x inline const Q& mutable_max(const Q& x, const Q& y) { return x inline Q& mutable_max( Q& x, Q& y) { return x +struct min_max_recur { + template static typename element_const_reference_type

            ::type max_(const P& p) { + return mutable_max(min_max_recur::max_(p),semantic_at_c(p)); + } + template static typename element_reference_type

            ::type max_( P& p) { + return mutable_max(min_max_recur::max_(p),semantic_at_c(p)); + } + template static typename element_const_reference_type

            ::type min_(const P& p) { + return mutable_min(min_max_recur::min_(p),semantic_at_c(p)); + } + template static typename element_reference_type

            ::type min_( P& p) { + return mutable_min(min_max_recur::min_(p),semantic_at_c(p)); + } +}; + +// termination condition of the compile-time recursion for min/max element +template <> +struct min_max_recur<1> { + template static typename element_const_reference_type

            ::type max_(const P& p) { return semantic_at_c<0>(p); } + template static typename element_reference_type

            ::type max_( P& p) { return semantic_at_c<0>(p); } + template static typename element_const_reference_type

            ::type min_(const P& p) { return semantic_at_c<0>(p); } + template static typename element_reference_type

            ::type min_( P& p) { return semantic_at_c<0>(p); } +}; +} // namespace detail + + +/** +\defgroup ColorBaseAlgorithmMinMax static_min, static_max +\ingroup ColorBaseAlgorithm +\brief Equivalents to std::min_element and std::max_element for homogeneous color bases + +Example: +\code +rgb8_pixel_t pixel(10,20,30); +assert(pixel[2] == 30); +static_max(pixel) = static_min(pixel); +assert(pixel[2] == 10); +\endcode +\{ +*/ + +template +GIL_FORCEINLINE +typename element_const_reference_type

            ::type static_max(const P& p) { return detail::min_max_recur::value>::max_(p); } + +template +GIL_FORCEINLINE +typename element_reference_type

            ::type static_max( P& p) { return detail::min_max_recur::value>::max_(p); } + +template +GIL_FORCEINLINE +typename element_const_reference_type

            ::type static_min(const P& p) { return detail::min_max_recur::value>::min_(p); } + +template +GIL_FORCEINLINE +typename element_reference_type

            ::type static_min( P& p) { return detail::min_max_recur::value>::min_(p); } +/// \} + +/** +\defgroup ColorBaseAlgorithmEqual static_equal +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::equal. Pairs the elements semantically + +Example: +\code +rgb8_pixel_t rgb_red(255,0,0); +bgr8_pixel_t bgr_red(0,0,255); +assert(rgb_red[0]==255 && bgr_red[0]==0); + +assert(static_equal(rgb_red,bgr_red)); +assert(rgb_red==bgr_red); // operator== invokes static_equal +\endcode +\{ +*/ + +template +GIL_FORCEINLINE +bool static_equal(const P1& p1, const P2& p2) { return detail::element_recursion::value>::static_equal(p1,p2); } + +/// \} + +/** +\defgroup ColorBaseAlgorithmCopy static_copy +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::copy. Pairs the elements semantically + +Example: +\code +rgb8_pixel_t rgb_red(255,0,0); +bgr8_pixel_t bgr_red; +static_copy(rgb_red, bgr_red); // same as bgr_red = rgb_red + +assert(rgb_red[0] == 255 && bgr_red[0] == 0); +assert(rgb_red == bgr_red); +\endcode +\{ +*/ + +template +GIL_FORCEINLINE +void static_copy(const Src& src, Dst& dst) { detail::element_recursion::value>::static_copy(src,dst); } + +/// \} + +/** +\defgroup ColorBaseAlgorithmFill static_fill +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::fill. + +Example: +\code +rgb8_pixel_t p; +static_fill(p, 10); +assert(p == rgb8_pixel_t(10,10,10)); +\endcode +\{ +*/ +template +GIL_FORCEINLINE +void static_fill(P& p, const V& v) { detail::element_recursion::value>::static_fill(p,v); } +/// \} + +/** +\defgroup ColorBaseAlgorithmGenerate static_generate +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::generate. + +Example: Set each channel of a pixel to its semantic index. The channels must be assignable from an integer. +\code +struct consecutive_fn { + int& _current; + consecutive_fn(int& start) : _current(start) {} + int operator()() { return _current++; } +}; +rgb8_pixel_t p; +int start=0; +static_generate(p, consecutive_fn(start)); +assert(p == rgb8_pixel_t(0,1,2)); +\endcode + +\{ +*/ + +template +GIL_FORCEINLINE +void static_generate(P1& dst,Op op) { detail::element_recursion::value>::static_generate(dst,op); } +/// \} + +/** +\defgroup ColorBaseAlgorithmTransform static_transform +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::transform. Pairs the elements semantically + +Example: Write a generic function that adds two pixels into a homogeneous result pixel. +\code +template +struct my_plus { + template + Result operator()(T1 f1, T2 f2) const { return f1+f2; } +}; + +template +void sum_channels(const Pixel1& p1, const Pixel2& p2, Pixel3& result) { + typedef typename channel_type::type result_channel_t; + static_transform(p1,p2,result,my_plus()); +} + +rgb8_pixel_t p1(1,2,3); +bgr8_pixel_t p2(3,2,1); +rgb8_pixel_t result; +sum_channels(p1,p2,result); +assert(result == rgb8_pixel_t(2,4,6)); +\endcode +\{ +*/ + +//static_transform with one source +template +GIL_FORCEINLINE +Op static_transform(Src& src,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(src,dst,op); } +template +GIL_FORCEINLINE +Op static_transform(const Src& src,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(src,dst,op); } +//static_transform with two sources +template +GIL_FORCEINLINE +Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(p2,p3,dst,op); } +template +GIL_FORCEINLINE +Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(p2,p3,dst,op); } +template +GIL_FORCEINLINE +Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(p2,p3,dst,op); } +template +GIL_FORCEINLINE +Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion::value>::static_transform(p2,p3,dst,op); } +/// \} + +/** +\defgroup ColorBaseAlgorithmForEach static_for_each +\ingroup ColorBaseAlgorithm +\brief Equivalent to std::for_each. Pairs the elements semantically + +Example: Use static_for_each to increment a planar pixel iterator +\code +struct increment { + template + void operator()(Incrementable& x) const { ++x; } +}; + +template +void increment_elements(ColorBase& cb) { + static_for_each(cb, increment()); +} + +bits8 red[2], green[2], blue[2]; +rgb8c_planar_ptr_t p1(red,green,blue); +rgb8c_planar_ptr_t p2=p1; +increment_elements(p1); +++p2; +assert(p1 == p2); +\endcode +\{ +*/ + +//static_for_each with one source +template +GIL_FORCEINLINE +Op static_for_each( P1& p1, Op op) { return detail::element_recursion::value>::static_for_each(p1,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1, Op op) { return detail::element_recursion::value>::static_for_each(p1,op); } +//static_for_each with two sources +template +GIL_FORCEINLINE +Op static_for_each(P1& p1, P2& p2, Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,op); } +template +GIL_FORCEINLINE +Op static_for_each(P1& p1,const P2& p2, Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1, P2& p2, Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1,const P2& p2, Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,op); } +//static_for_each with three sources +template +GIL_FORCEINLINE +Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +template +GIL_FORCEINLINE +Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion::value>::static_for_each(p1,p2,p3,op); } +///\} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/color_convert.hpp b/thirdparty/boost/gil/color_convert.hpp new file mode 100644 index 0000000..211c84d --- /dev/null +++ b/thirdparty/boost/gil/color_convert.hpp @@ -0,0 +1,314 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_COLOR_CONVERT_HPP +#define GIL_COLOR_CONVERT_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief GIL default color space conversions +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on January 30, 2007 +/// +/// Support for fast and simple color conversion. Accurate color conversion using color +/// profiles can be supplied separately in a dedicated module +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include "channel_algorithm.hpp" +#include "pixel.hpp" +#include "gray.hpp" +#include "rgb.hpp" +#include "rgba.hpp" +#include "cmyk.hpp" +#include "metafunctions.hpp" +#include "utilities.hpp" +#include "color_base_algorithm.hpp" + +namespace boost { namespace gil { + +// Forward-declare +template struct channel_type; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// COLOR SPACE CONVERSION +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \ingroup ColorConvert +/// \brief Color Convertion function object. To be specialized for every src/dst color space +template +struct default_color_converter_impl {}; + +/// \ingroup ColorConvert +/// \brief When the color space is the same, color convertion performs channel depth conversion +template +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + static_for_each(src,dst,default_channel_converter()); + } +}; + +namespace detail { + +/// red * .3 + green * .59 + blue * .11 + .5 + +// The default implementation of to_luminance uses float0..1 as the intermediate channel type +template +struct rgb_to_luminance_fn { + GrayChannelValue operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const { + return channel_convert( bits32f( + channel_convert(red )*0.30f + + channel_convert(green)*0.59f + + channel_convert(blue )*0.11f) ); + } +}; + +// performance specialization for unsigned char +template +struct rgb_to_luminance_fn { + GrayChannelValue operator()(uint8_t red, uint8_t green, uint8_t blue) const { + return channel_convert(uint8_t( + ((uint32_t(red )*4915 + uint32_t(green)*9667 + uint32_t(blue )*1802) + 8192) >> 14)); + } +}; + +template +typename channel_traits::value_type rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) { + return rgb_to_luminance_fn::value_type>()(red,green,blue); +} + +} // namespace detail + +/// \ingroup ColorConvert +/// \brief Gray to RGB +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + get_color(dst,red_t()) = + channel_convert::type>(get_color(src,gray_color_t())); + get_color(dst,green_t())= + channel_convert::type>(get_color(src,gray_color_t())); + get_color(dst,blue_t()) = + channel_convert::type>(get_color(src,gray_color_t())); + } +}; + +/// \ingroup ColorConvert +/// \brief Gray to CMYK +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + get_color(dst,cyan_t())= + channel_traits::type>::min_value(); + get_color(dst,magenta_t())= + channel_traits::type>::min_value(); + get_color(dst,yellow_t())= + channel_traits::type>::min_value(); + get_color(dst,black_t())= + channel_convert::type>(get_color(src,gray_color_t())); + } +}; + +/// \ingroup ColorConvert +/// \brief RGB to Gray +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + get_color(dst,gray_color_t()) = + detail::rgb_to_luminance::type>( + get_color(src,red_t()), get_color(src,green_t()), get_color(src,blue_t()) + ); + } +}; + + +/// \ingroup ColorConvert +/// \brief RGB to CMYK (not the fastest code in the world) +/// +/// k = min(1 - r, 1 - g, 1 - b) +/// c = (1 - r - k) / (1 - k) +/// m = (1 - g - k) / (1 - k) +/// y = (1 - b - k) / (1 - k) +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + typedef typename channel_type::type T2; + get_color(dst,cyan_t()) = channel_invert(channel_convert(get_color(src,red_t()))); // c = 1 - r + get_color(dst,magenta_t()) = channel_invert(channel_convert(get_color(src,green_t()))); // m = 1 - g + get_color(dst,yellow_t()) = channel_invert(channel_convert(get_color(src,blue_t()))); // y = 1 - b + get_color(dst,black_t()) = (std::min)(get_color(dst,cyan_t()), + (std::min)(get_color(dst,magenta_t()), + get_color(dst,yellow_t()))); // k = minimum(c, m, y) + T2 x = channel_traits::max_value()-get_color(dst,black_t()); // x = 1 - k + if (x>0.0001f) { + float x1 = channel_traits::max_value()/float(x); + get_color(dst,cyan_t()) = (T2)((get_color(dst,cyan_t()) - get_color(dst,black_t()))*x1); // c = (c - k) / x + get_color(dst,magenta_t()) = (T2)((get_color(dst,magenta_t()) - get_color(dst,black_t()))*x1); // m = (m - k) / x + get_color(dst,yellow_t()) = (T2)((get_color(dst,yellow_t()) - get_color(dst,black_t()))*x1); // y = (y - k) / x + } else { + get_color(dst,cyan_t())=get_color(dst,magenta_t())=get_color(dst,yellow_t())=0; + } + } +}; + +/// \ingroup ColorConvert +/// \brief CMYK to RGB (not the fastest code in the world) +/// +/// r = 1 - min(1, c*(1-k)+k) +/// g = 1 - min(1, m*(1-k)+k) +/// b = 1 - min(1, y*(1-k)+k) +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + typedef typename channel_type::type T1; + get_color(dst,red_t()) = + channel_convert::type>( + channel_invert( + (std::min)(channel_traits::max_value(), + T1(get_color(src,cyan_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t()))))); + get_color(dst,green_t())= + channel_convert::type>( + channel_invert( + (std::min)(channel_traits::max_value(), + T1(get_color(src,magenta_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t()))))); + get_color(dst,blue_t()) = + channel_convert::type>( + channel_invert( + (std::min)(channel_traits::max_value(), + T1(get_color(src,yellow_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t()))))); + } +}; + + +/// \ingroup ColorConvert +/// \brief CMYK to Gray +/// +/// gray = (1 - 0.212c - 0.715m - 0.0722y) * (1 - k) +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + get_color(dst,gray_color_t())= + channel_convert::type>( + channel_multiply( + channel_invert( + detail::rgb_to_luminance::type>( + get_color(src,cyan_t()), + get_color(src,magenta_t()), + get_color(src,yellow_t()) + ) + ), + channel_invert(get_color(src,black_t())))); + } +}; + +namespace detail { +template +typename channel_type::type alpha_or_max_impl(const Pixel& p, mpl::true_) { + return get_color(p,alpha_t()); +} +template +typename channel_type::type alpha_or_max_impl(const Pixel& , mpl::false_) { + return channel_traits::type>::max_value(); +} +} // namespace detail + +// Returns max_value if the pixel has no alpha channel. Otherwise returns the alpha. +template +typename channel_type::type alpha_or_max(const Pixel& p) { + return detail::alpha_or_max_impl(p, mpl::contains::type,alpha_t>()); +} + + +/// \ingroup ColorConvert +/// \brief Converting any pixel type to RGBA. Note: Supports homogeneous pixels only. +template +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + typedef typename channel_type::type T2; + pixel tmp; + default_color_converter_impl()(src,tmp); + get_color(dst,red_t()) =get_color(tmp,red_t()); + get_color(dst,green_t())=get_color(tmp,green_t()); + get_color(dst,blue_t()) =get_color(tmp,blue_t()); + get_color(dst,alpha_t())=channel_convert(alpha_or_max(src)); + } +}; + +/// \ingroup ColorConvert +/// \brief Converting RGBA to any pixel type. Note: Supports homogeneous pixels only. +/// +/// Done by multiplying the alpha to get to RGB, then converting the RGB to the target pixel type +/// Note: This may be slower if the compiler doesn't optimize out constructing/destructing a temporary RGB pixel. +/// Consider rewriting if performance is an issue +template +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + typedef typename channel_type::type T1; + default_color_converter_impl()( + pixel(channel_multiply(get_color(src,red_t()), get_color(src,alpha_t())), + channel_multiply(get_color(src,green_t()),get_color(src,alpha_t())), + channel_multiply(get_color(src,blue_t()), get_color(src,alpha_t()))) + ,dst); + } +}; + +/// \ingroup ColorConvert +/// \brief Unfortunately RGBA to RGBA must be explicitly provided - otherwise we get ambiguous specialization error. +template <> +struct default_color_converter_impl { + template + void operator()(const P1& src, P2& dst) const { + static_for_each(src,dst,default_channel_converter()); + } +}; + +/// @defgroup ColorConvert Color Space Converion +/// \ingroup ColorSpaces +/// \brief Support for conversion between pixels of different color spaces and channel depths + +/// \ingroup PixelAlgorithm ColorConvert +/// \brief class for color-converting one pixel to another +struct default_color_converter { + template + void operator()(const SrcP& src,DstP& dst) const { + typedef typename color_space_type::type SrcColorSpace; + typedef typename color_space_type::type DstColorSpace; + default_color_converter_impl()(src,dst); + } +}; + +/// \ingroup PixelAlgorithm +/// \brief helper function for converting one pixel to another using GIL default color-converters +/// where ScrP models HomogeneousPixelConcept +/// DstP models HomogeneousPixelValueConcept +template +inline void color_convert(const SrcP& src, DstP& dst) { + default_color_converter()(src,dst); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/deprecated.hpp b/thirdparty/boost/gil/deprecated.hpp new file mode 100644 index 0000000..32c4b5c --- /dev/null +++ b/thirdparty/boost/gil/deprecated.hpp @@ -0,0 +1,77 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DEPRECATED_HPP +#define GIL_DEPRECATED_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Deprecated names +/// This file is provided as a courtesy to ease upgrading GIL client code. +/// Please make sure your code compiles when this file is not included. +/// +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#define planar_ptr planar_pixel_iterator +#define planar_ref planar_pixel_reference +#define membased_2d_locator memory_based_2d_locator +#define pixel_step_iterator memory_based_step_iterator +#define pixel_image_iterator iterator_from_2d + +#define equal_channels static_equal +#define copy_channels static_copy +#define fill_channels static_fill +#define generate_channels static_generate +#define for_each_channel static_for_each +#define transform_channels static_transform +#define max_channel static_max +#define min_channel static_min + +#define semantic_channel semantic_at_c + +template +void resize_clobber_image(Img& img, const typename Img::point_t& new_dims) { + img.recreate(new_dims); +} + +template +void resize_clobber_image(Img& img, const typename Img::x_coord_t& width, const typename Img::y_coord_t& height) { + img.recreate(width,height); +} + +template typename T::x_coord_t get_width(const T& a) { return a.width(); } +template typename T::y_coord_t get_height(const T& a) { return a.height(); } +template typename T::point_t get_dimensions(const T& a) { return a.dimensions(); } +template std::size_t get_num_channels(const T& a) { return a.num_channels(); } + +#define GIL boost::gil +#define ADOBE_GIL_NAMESPACE_BEGIN namespace boost { namespace gil { +#define ADOBE_GIL_NAMESPACE_END } } + +#define ByteAdvancableIteratorConcept MemoryBasedIteratorConcept +#define byte_advance memunit_advance +#define byte_advanced memunit_advanced +#define byte_step memunit_step +#define byte_distance memunit_distance + +#define byte_addressable_step_iterator memory_based_step_iterator +#define byte_addressable_2d_locator memory_based_2d_locator + +// These are members of memory-based locators +//#define row_bytes row_size // commented out because row_bytes is commonly used +#define pix_bytestep pixel_size + +#endif diff --git a/thirdparty/boost/gil/device_n.hpp b/thirdparty/boost/gil/device_n.hpp new file mode 100644 index 0000000..f7f93fb --- /dev/null +++ b/thirdparty/boost/gil/device_n.hpp @@ -0,0 +1,96 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_DEVICE_N_H +#define GIL_DEVICE_N_H + + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for color space of N channels and variants +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on October 10, 2007 +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include +#include +#include + +namespace boost { namespace gil { + +/// \brief unnamed color +/// \ingroup ColorNameModel +template struct devicen_color_t {}; + +template struct devicen_t; + +/// \brief unnamed color space of one channel +/// \ingroup ColorSpaceModel +template <> struct devicen_t<1> : public mpl::vector1 > {}; + +/// \brief unnamed color space of two channels +/// \ingroup ColorSpaceModel +template <> struct devicen_t<2> : public mpl::vector2, devicen_color_t<1> > {}; + +/// \brief unnamed color space of three channels +/// \ingroup ColorSpaceModel +template <> struct devicen_t<3> : public mpl::vector3, devicen_color_t<1>, devicen_color_t<2> > {}; + +/// \brief unnamed color space of four channels +/// \ingroup ColorSpaceModel +template <> struct devicen_t<4> : public mpl::vector4, devicen_color_t<1>, devicen_color_t<2>, devicen_color_t<3> > {}; + +/// \brief unnamed color space of five channels +/// \ingroup ColorSpaceModel +template <> struct devicen_t<5> : public mpl::vector5, devicen_color_t<1>, devicen_color_t<2>, devicen_color_t<3>, devicen_color_t<4> > {}; + +/// \brief unnamed color layout of up to five channels +/// \ingroup LayoutModel +template struct devicen_layout_t : public layout > {}; + +/// \ingroup ImageViewConstructors +/// \brief from 2-channel planar data +template +inline typename type_from_x_iterator > >::view_t +planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, std::ptrdiff_t rowsize_in_bytes) { + return typename type_from_x_iterator > >::view_t(width, height, planar_pixel_iterator >(c0,c1), rowsize_in_bytes); +} + +/// \ingroup ImageViewConstructors +/// \brief from 3-channel planar data +template +inline typename type_from_x_iterator > >::view_t +planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, std::ptrdiff_t rowsize_in_bytes) { + return typename type_from_x_iterator > >::view_t(width, height, planar_pixel_iterator >(c0,c1,c2), rowsize_in_bytes); +} + +/// \ingroup ImageViewConstructors +/// \brief from 4-channel planar data +template +inline typename type_from_x_iterator > >::view_t +planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, IC c3, std::ptrdiff_t rowsize_in_bytes) { + return typename type_from_x_iterator > >::view_t(width, height, planar_pixel_iterator >(c0,c1,c2,c3), rowsize_in_bytes); +} + +/// \ingroup ImageViewConstructors +/// \brief from 5-channel planar data +template +inline typename type_from_x_iterator > >::view_t +planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, IC c3, IC c4, std::ptrdiff_t rowsize_in_bytes) { + return typename type_from_x_iterator > >::view_t(width, height, planar_pixel_iterator >(c0,c1,c2,c3,c4), rowsize_in_bytes); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/algorithm.hpp b/thirdparty/boost/gil/extension/dynamic_image/algorithm.hpp new file mode 100644 index 0000000..30c45bf --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/algorithm.hpp @@ -0,0 +1,173 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_ALGORITHM_HPP +#define GIL_DYNAMICIMAGE_ALGORITHM_HPP + +#include "../../algorithm.hpp" +#include "any_image.hpp" +#include + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Some basic STL-style algorithms when applied to runtime type specified image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 24, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace gil { + +namespace detail { + struct equal_pixels_fn : public binary_operation_obj { + template + GIL_FORCEINLINE bool apply_compatible(const V1& v1, const V2& v2) const { + return equal_pixels(v1,v2); + } + }; +} // namespace detail + +/// \ingroup ImageViewSTLAlgorithmsEqualPixels +template // Model MutableImageViewConcept +bool equal_pixels(const any_image_view& src, const View2& dst) { + return apply_operation(src,boost::bind(detail::equal_pixels_fn(), _1, dst)); +} + +/// \ingroup ImageViewSTLAlgorithmsEqualPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +bool equal_pixels(const View1& src, const any_image_view& dst) { + return apply_operation(dst,boost::bind(detail::equal_pixels_fn(), src, _1)); +} + +/// \ingroup ImageViewSTLAlgorithmsEqualPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +bool equal_pixels(const any_image_view& src, const any_image_view& dst) { + return apply_operation(src,dst,detail::equal_pixels_fn()); +} + +namespace detail { + struct copy_pixels_fn : public binary_operation_obj { + template + GIL_FORCEINLINE void apply_compatible(const View1& src, const View2& dst) const { + copy_pixels(src,dst); + } + }; +} + +/// \ingroup ImageViewSTLAlgorithmsCopyPixels +template // Model MutableImageViewConcept +void copy_pixels(const any_image_view& src, const View2& dst) { + apply_operation(src,boost::bind(detail::copy_pixels_fn(), _1, dst)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +void copy_pixels(const View1& src, const any_image_view& dst) { + apply_operation(dst,boost::bind(detail::copy_pixels_fn(), src, _1)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +void copy_pixels(const any_image_view& src, const any_image_view& dst) { + apply_operation(src,dst,detail::copy_pixels_fn()); +} + + + +//forward declaration for default_color_converter (see full definition in color_convert.hpp) +struct default_color_converter; + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model ColorConverterConcept +void copy_and_convert_pixels(const any_image_view& src, const View2& dst, CC cc) { + apply_operation(src,boost::bind(detail::copy_and_convert_pixels_fn(cc), _1, dst)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model MutableImageViewConcept +void copy_and_convert_pixels(const any_image_view& src, const View2& dst) { + apply_operation(src,boost::bind(detail::copy_and_convert_pixels_fn(), _1, dst)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model ColorConverterConcept +void copy_and_convert_pixels(const View1& src, const any_image_view& dst, CC cc) { + apply_operation(dst,boost::bind(detail::copy_and_convert_pixels_fn(cc), src, _1)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +void copy_and_convert_pixels(const View1& src, const any_image_view& dst) { + apply_operation(dst,boost::bind(detail::copy_and_convert_pixels_fn(), src, _1)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model ColorConverterConcept +void copy_and_convert_pixels(const any_image_view& src, const any_image_view& dst, CC cc) { + apply_operation(src,dst,detail::copy_and_convert_pixels_fn(cc)); +} + +/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels +template // Model MPL Random Access Container of models of MutableImageViewConcept +void copy_and_convert_pixels(const any_image_view& src, const any_image_view& dst) { + apply_operation(src,dst,detail::copy_and_convert_pixels_fn()); +} + +namespace detail { +template struct fill_pixels_fn1 { + template static void apply(const V& src, const Value& val) { fill_pixels(src,val); } +}; + +// copy_pixels invoked on incompatible images +template <> struct fill_pixels_fn1 { + template static void apply(const V& src, const Value& val) { throw std::bad_cast();} +}; + +template +struct fill_pixels_fn { + fill_pixels_fn(const Value& val) : _val(val) {} + + typedef void result_type; + template result_type operator()(const V& img_view) const { + fill_pixels_fn1::value>::apply(img_view,_val); + } + Value _val; +}; +} + +/// \ingroup ImageViewSTLAlgorithmsFillPixels +/// \brief fill_pixels for any image view. The pixel to fill with must be compatible with the current view +template +void fill_pixels(const any_image_view& img_view, const Value& val) { + apply_operation(img_view,detail::fill_pixels_fn(val)); +} + + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/any_image.hpp b/thirdparty/boost/gil/extension/dynamic_image/any_image.hpp new file mode 100644 index 0000000..41f45b2 --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/any_image.hpp @@ -0,0 +1,125 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_ANY_IMAGE_HPP +#define GIL_DYNAMICIMAGE_ANY_IMAGE_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for run-time instantiated images and image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "any_image_view.hpp" +#include "../../image.hpp" + +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable : 4244) // conversion from 'std::ptrdiff_t' to 'int', possible loss of data. even if we static-assert the two types are the same (on visual studio 8) +//#endif + +namespace boost { namespace gil { + +namespace detail { + template struct get_view_t { typedef typename T::view_t type; }; + template struct images_get_views_t : public mpl::transform > {}; + + template struct get_const_view_t { typedef typename T::const_view_t type; }; + template struct images_get_const_views_t : public mpl::transform > {}; + + struct recreate_image_fnobj { + typedef void result_type; + const point2& _dimensions; + unsigned _alignment; + + recreate_image_fnobj(const point2& dims, unsigned alignment) : _dimensions(dims), _alignment(alignment) {} + template result_type operator()(Image& img) const { img.recreate(_dimensions,_alignment); } + }; + + template // Models AnyViewConcept + struct any_image_get_view { + typedef AnyView result_type; + template result_type operator()( Image& img) const { return result_type(view(img)); } + }; + + template // Models AnyConstViewConcept + struct any_image_get_const_view { + typedef AnyConstView result_type; + template result_type operator()(const Image& img) const { return result_type(const_view(img)); } + }; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/// \ingroup ImageModel +/// \brief Represents a run-time specified image. Note it does NOT model ImageConcept +/// +/// Represents an image whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time. +/// It is the runtime equivalent of \p image. +/// Some of the requirements of ImageConcept, such as the \p value_type typedef cannot be fulfilled, since the language does not allow runtime type specification. +/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image does not fully model ImageConcept. +/// In particular, its \p view and \p const_view methods return \p any_image_view, which does not fully model ImageViewConcept. See \p any_image_view for more. +//////////////////////////////////////////////////////////////////////////////////////// +template +class any_image : public variant { + typedef variant parent_t; +public: + typedef any_image_view::type> const_view_t; + typedef any_image_view::type> view_t; + typedef std::ptrdiff_t x_coord_t; + typedef std::ptrdiff_t y_coord_t; + typedef point2 point_t; + + any_image() : parent_t() {} + template explicit any_image(const T& obj) : parent_t(obj) {} + template explicit any_image(T& obj, bool do_swap) : parent_t(obj,do_swap) {} + any_image(const any_image& v) : parent_t((const parent_t&)v) {} + + template any_image& operator=(const T& obj) { parent_t::operator=(obj); return *this; } + any_image& operator=(const any_image& v) { parent_t::operator=((const parent_t&)v); return *this;} + + void recreate(const point_t& dims, unsigned alignment=1) { apply_operation(*this,detail::recreate_image_fnobj(dims,alignment)); } + void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1) { recreate(point2(width,height),alignment); } + + std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); } + point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); } + x_coord_t width() const { return dimensions().x; } + y_coord_t height() const { return dimensions().y; } +}; + +///@{ +/// \name view, const_view +/// \brief Get an image view from a run-time instantiated image + +/// \ingroup ImageModel + +/// \brief Returns the non-constant-pixel view of any image. The returned view is any view. +template GIL_FORCEINLINE // Models ImageVectorConcept +typename any_image::view_t view(any_image& anyImage) { + return apply_operation(anyImage, detail::any_image_get_view::view_t>()); +} + +/// \brief Returns the constant-pixel view of any image. The returned view is any view. +template GIL_FORCEINLINE // Models ImageVectorConcept +typename any_image::const_view_t const_view(const any_image& anyImage) { + return apply_operation(anyImage, detail::any_image_get_const_view::const_view_t>()); +} +///@} + +} } // namespace boost::gil + +//#ifdef _MSC_VER +//#pragma warning(pop) +//#endif + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/any_image_view.hpp b/thirdparty/boost/gil/extension/dynamic_image/any_image_view.hpp new file mode 100644 index 0000000..20997fb --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/any_image_view.hpp @@ -0,0 +1,115 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_ANY_IMAGEVIEW_HPP +#define GIL_DYNAMICIMAGE_ANY_IMAGEVIEW_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for run-time instantiated image view +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "variant.hpp" +#include "../../image_view.hpp" +#include "../../image.hpp" + +namespace boost { namespace gil { + +namespace detail { + template struct get_const_t { typedef typename View::const_t type; }; + template struct views_get_const_t : public mpl::transform > {}; +} +template struct dynamic_xy_step_type; +template struct dynamic_xy_step_transposed_type; + +namespace detail { + struct any_type_get_num_channels { // works for both image_view and image + typedef int result_type; + template result_type operator()(const T& v) const { return num_channels::value; } + }; + struct any_type_get_dimensions { // works for both image_view and image + typedef point2 result_type; + template result_type operator()(const T& v) const { return v.dimensions(); } + }; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/// CLASS any_image_view +/// +/// \ingroup ImageViewModel +/// \brief Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, Note that this class does NOT model ImageViewConcept +/// +/// Represents a view whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time. +/// It is the runtime equivalent of \p image_view. +/// Some of the requirements of ImageViewConcept, such as the \p value_type typedef cannot be fulfilled, since the language does not allow runtime type specification. +/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept. +/// However, many algorithms provide overloads taking runtime specified views and thus in many cases \p any_image_view can be used in places taking a view. +/// +/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p apply_operation(runtime_view, algorithm_fn); +//////////////////////////////////////////////////////////////////////////////////////// +template +class any_image_view : public variant { + typedef variant parent_t; +public: + typedef any_image_view::type> const_t; + typedef std::ptrdiff_t x_coord_t; + typedef std::ptrdiff_t y_coord_t; + typedef point2 point_t; + + any_image_view() : parent_t() {} + template explicit any_image_view(const T& obj) : parent_t(obj) {} + any_image_view(const any_image_view& v) : parent_t((const parent_t&)v) {} + + template any_image_view& operator=(const T& obj) { parent_t::operator=(obj); return *this; } + any_image_view& operator=(const any_image_view& v) { parent_t::operator=((const parent_t&)v); return *this;} + + std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); } + point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); } + x_coord_t width() const { return dimensions().x; } + y_coord_t height() const { return dimensions().y; } +}; + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef any_image_view >::type> type; +}; + +///////////////////////////// +// HasDynamicYStepTypeConcept +///////////////////////////// + +template +struct dynamic_y_step_type > { + typedef any_image_view >::type> type; +}; + +template +struct dynamic_xy_step_type > { + typedef any_image_view >::type> type; +}; + +template +struct dynamic_xy_step_transposed_type > { + typedef any_image_view >::type> type; +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/apply_operation.hpp b/thirdparty/boost/gil/extension/dynamic_image/apply_operation.hpp new file mode 100644 index 0000000..6c95ea2 --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/apply_operation.hpp @@ -0,0 +1,61 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_APPLY_OPERATION_HPP +#define GIL_APPLY_OPERATION_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Implements apply_operation for variants. Optionally performs type reduction +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 4, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "apply_operation_base.hpp" +#include "variant.hpp" + +#ifndef GIL_REDUCE_CODE_BLOAT + +namespace boost { namespace gil { + +/// \ingroup Variant +/// \brief Invokes a generic mutable operation (represented as a unary function object) on a variant +template GIL_FORCEINLINE +typename UnaryOp::result_type apply_operation(variant& arg, UnaryOp op) { + return apply_operation_base(arg._bits, arg._index ,op); +} + +/// \ingroup Variant +/// \brief Invokes a generic constant operation (represented as a unary function object) on a variant +template GIL_FORCEINLINE +typename UnaryOp::result_type apply_operation(const variant& arg, UnaryOp op) { + return apply_operation_basec(arg._bits, arg._index ,op); +} + +/// \ingroup Variant +/// \brief Invokes a generic constant operation (represented as a binary function object) on two variants +template GIL_FORCEINLINE +typename BinaryOp::result_type apply_operation(const variant& arg1, const variant& arg2, BinaryOp op) { + return apply_operation_base(arg1._bits, arg1._index, arg2._bits, arg2._index, op); +} + +} } // namespace boost::gil + +#else + +#include "reduce.hpp" + +#endif + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/apply_operation_base.hpp b/thirdparty/boost/gil/extension/dynamic_image/apply_operation_base.hpp new file mode 100644 index 0000000..ee1782d --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/apply_operation_base.hpp @@ -0,0 +1,162 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_APPLY_OPERATION_BASE_HPP +#define GIL_APPLY_OPERATION_BASE_HPP + +#include "../../gil_config.hpp" +#include "../../utilities.hpp" +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Given an object with run-time specified type (denoted as an array of Bits, dynamic index, and a static set of Types) and a generic operation, +/// casts the object to its appropriate type and applies the operation +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on November 6, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace gil { + +/* +GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2): + + template <> struct apply_operation_fwd_fn<3> { + template + typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { + typedef typename mpl::begin::type T0; + typedef typename mpl::next::type T1; + typedef typename mpl::next::type T2; + switch (index) { + case 0: return op(reinterpret_cast::type&>(bits)); + case 1: return op(reinterpret_cast::type&>(bits)); + case 2: return op(reinterpret_cast::type&>(bits)); + } + throw; + } + + template + typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { + typedef typename mpl::begin::type T0; + typedef typename mpl::next::type T1; + typedef typename mpl::next::type T2; + switch (index) { + case 0: return op(reinterpret_cast::type&>(bits)); + case 1: return op(reinterpret_cast::type&>(bits)); + case 2: return op(reinterpret_cast::type&>(bits)); + } + throw; + } + }; +*/ + +#define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next::type +#define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast::type*>(&bits)); +#define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c::type*>(&bits)); + +#define GIL_APPLY_FWD_OP(z, N, text) \ + template <> struct apply_operation_fwd_fn { \ + template \ + typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \ + typedef typename mpl::begin::type \ + BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \ + T##N; \ + switch (index) { \ + BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \ + } \ + throw; \ + } \ + template \ + typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \ + typedef typename mpl::begin::type \ + BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \ + T##N; \ + switch (index) { \ + BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \ + } \ + throw; \ + } \ + }; + +#define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY) + +namespace detail { +template struct apply_operation_fwd_fn {}; + +// Create specializations of apply_operation_fn for each N 0..100 +GIL_GENERATE_APPLY_FWD_OPS(99) +} // namespace detail + +// unary application +template +typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) { + return detail::apply_operation_fwd_fn::value>().template applyc(bits,index,op); +} + +// unary application +template +typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) { + return detail::apply_operation_fwd_fn::value>().template apply(bits,index,op); +} + +namespace detail { + template + struct reduce_bind1 { + const T2& _t2; + mutable Op& _op; + + typedef typename Op::result_type result_type; + + reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {} + + template GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); } + }; + + template + struct reduce_bind2 { + const Bits1& _bits1; + std::size_t _index1; + mutable Op& _op; + + typedef typename Op::result_type result_type; + + reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {} + + template GIL_FORCEINLINE result_type operator()(const T2& t2) { + return apply_operation_basec(_bits1, _index1, reduce_bind1(t2, _op)); + } + }; +} // namespace detail + +// Binary application by applying on each dimension separately +template +static typename Op::result_type GIL_FORCEINLINE apply_operation_base(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { + return apply_operation_basec(bits2,index2,detail::reduce_bind2(bits1,index1,op)); +} + +#undef GIL_FWD_TYPEDEFS +#undef GIL_FWD_CASE +#undef GIL_FWD_CONST_CASE +#undef GIL_APPLY_FWD_OP +#undef GIL_GENERATE_APPLY_FWD_OPS +#undef BHS + +} } // namespace boost::gil + + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/dynamic_at_c.hpp b/thirdparty/boost/gil/extension/dynamic_image/dynamic_at_c.hpp new file mode 100644 index 0000000..9a87bc4 --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/dynamic_at_c.hpp @@ -0,0 +1,130 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DYNAMIC_AT_C_HPP +#define GIL_DYNAMIC_AT_C_HPP + +#include "../../gil_config.hpp" +#include +#include +#include +#include + + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Constructs for static-to-dynamic integer convesion +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 4, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace gil { + +#define GIL_AT_C_VALUE(z, N, text) mpl::at_c::type::value, +#define GIL_DYNAMIC_AT_C_LIMIT 226 // size of the maximum vector to handle + +#define GIL_AT_C_LOOKUP(z, NUM, text) \ + template \ + struct at_c_fn { \ + template inline \ + static ValueType apply(std::size_t index) { \ + static ValueType table[] = { \ + BOOST_PP_REPEAT(NUM, GIL_AT_C_VALUE, BOOST_PP_EMPTY) \ + }; \ + return table[index]; \ + } \ + }; + +namespace detail { + namespace at_c { + template struct at_c_fn; + BOOST_PP_REPEAT(GIL_DYNAMIC_AT_C_LIMIT, GIL_AT_C_LOOKUP, BOOST_PP_EMPTY) + + template struct at_c_impl; + + template <> + struct at_c_impl<0> { + template inline + static ValueType apply(std::size_t index) { + return at_c_fn<0,mpl::size::value>::template apply(index); + } + }; + + template <> + struct at_c_impl<1> { + template inline + static ValueType apply(std::size_t index) { + const std::size_t SIZE=mpl::size::value; + const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT; + switch (index / GIL_DYNAMIC_AT_C_LIMIT) { + case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply(index); + case 1: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT); + }; + throw; + } + }; + + template <> + struct at_c_impl<2> { + template inline + static ValueType apply(std::size_t index) { + const std::size_t SIZE=mpl::size::value; + const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT; + switch (index / GIL_DYNAMIC_AT_C_LIMIT) { + case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply(index); + case 1: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT); + case 2: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT*2); + }; + throw; + } + }; + + template <> + struct at_c_impl<3> { + template inline + static ValueType apply(std::size_t index) { + const std::size_t SIZE=mpl::size::value; + const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT; + switch (index / GIL_DYNAMIC_AT_C_LIMIT) { + case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply(index); + case 1: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT); + case 2: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT*2); + case 3: return at_c_fn::template apply(index - GIL_DYNAMIC_AT_C_LIMIT*3); + }; + throw; + } + }; + } +} + +//////////////////////////////////////////////////////////////////////////////////// +/// +/// \brief Given an MPL Random Access Sequence and a dynamic index n, returns the value of the n-th element +/// It constructs a lookup table at compile time +/// +//////////////////////////////////////////////////////////////////////////////////// + +template inline +ValueType at_c(std::size_t index) { + const std::size_t Size=mpl::size::value; + return detail::at_c::at_c_impl::template apply(index); +} + +#undef GIL_AT_C_VALUE +#undef GIL_DYNAMIC_AT_C_LIMIT +#undef GIL_AT_C_LOOKUP + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/dynamic_image_all.hpp b/thirdparty/boost/gil/extension/dynamic_image/dynamic_image_all.hpp new file mode 100644 index 0000000..9979a43 --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/dynamic_image_all.hpp @@ -0,0 +1,32 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_ALL_HPP +#define GIL_DYNAMICIMAGE_ALL_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Includes all of the GIL dynamic image extension files, for convenience +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 8, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "../../gil_all.hpp" +#include "algorithm.hpp" +#include "any_image.hpp" +#include "apply_operation.hpp" +#include "variant.hpp" +#include "image_view_factory.hpp" + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/image_view_factory.hpp b/thirdparty/boost/gil/extension/dynamic_image/image_view_factory.hpp new file mode 100644 index 0000000..1253f0b --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/image_view_factory.hpp @@ -0,0 +1,212 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_IMAGE_VIEWS_HPP +#define GIL_DYNAMICIMAGE_IMAGE_VIEWS_HPP + +/*! +/// \file +/// \brief Methods for constructing any image views from other any image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on January 31, 2007 +/// Extends image view factory to runtime type-specified views (any_image_view) +*/ + +#include "any_image_view.hpp" +#include "../../image_view_factory.hpp" + +namespace boost { namespace gil { + +namespace detail { +template struct flipped_up_down_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(flipped_up_down_view(src)); } +}; +template struct flipped_left_right_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(flipped_left_right_view(src)); } +}; +template struct rotated90cw_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(rotated90cw_view(src)); } +}; +template struct rotated90ccw_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(rotated90ccw_view(src)); } +}; +template struct tranposed_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(tranposed_view(src)); } +}; +template struct rotated180_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(rotated180_view(src)); } +}; +template struct subimage_view_fn { + typedef Result result_type; + subimage_view_fn(const point2& topleft, const point2& dimensions) : _topleft(topleft), _size2(dimensions) {} + point2 _topleft,_size2; + template result_type operator()(const View& src) const { return result_type(subimage_view(src,_topleft,_size2)); } +}; +template struct subsampled_view_fn { + typedef Result result_type; + subsampled_view_fn(const point2& step) : _step(step) {} + point2 _step; + template result_type operator()(const View& src) const { return result_type(subsampled_view(src,_step)); } +}; +template struct nth_channel_view_fn { + typedef Result result_type; + nth_channel_view_fn(int n) : _n(n) {} + int _n; + template result_type operator()(const View& src) const { return result_type(nth_channel_view(src,_n)); } +}; +template struct color_converted_view_fn { + typedef Result result_type; + template result_type operator()(const View& src) const { return result_type(color_converted_view(src)); } +}; +} // namespace detail + + +/// \ingroup ImageViewTransformationsFlipUD +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_y_step_type >::type flipped_up_down_view(const any_image_view& src) { + return apply_operation(src,detail::flipped_up_down_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformationsFlipLR +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_x_step_type >::type flipped_left_right_view(const any_image_view& src) { + return apply_operation(src,detail::flipped_left_right_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformationsTransposed +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_transposed_type >::type transposed_view(const any_image_view& src) { + return apply_operation(src,detail::tranposed_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformations90CW +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_transposed_type >::type rotated90cw_view(const any_image_view& src) { + return apply_operation(src,detail::rotated90cw_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformations90CCW +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_transposed_type >::type rotated90ccw_view(const any_image_view& src) { + return apply_operation(src,detail::rotated90ccw_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformations180 +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_type >::type rotated180_view(const any_image_view& src) { + return apply_operation(src,detail::rotated180_view_fn >::type>()); +} + +/// \ingroup ImageViewTransformationsSubimage +template inline // Models MPL Random Access Container of models of ImageViewConcept +any_image_view subimage_view(const any_image_view& src, const point2& topleft, const point2& dimensions) { + return apply_operation(src,detail::subimage_view_fn >(topleft,dimensions)); +} + +/// \ingroup ImageViewTransformationsSubimage +template inline // Models MPL Random Access Container of models of ImageViewConcept +any_image_view subimage_view(const any_image_view& src, int xMin, int yMin, int width, int height) { + return apply_operation(src,detail::subimage_view_fn >(point2(xMin,yMin),point2(width,height))); +} + +/// \ingroup ImageViewTransformationsSubsampled +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_type >::type subsampled_view(const any_image_view& src, const point2& step) { + return apply_operation(src,detail::subsampled_view_fn >::type>(step)); +} + +/// \ingroup ImageViewTransformationsSubsampled +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename dynamic_xy_step_type >::type subsampled_view(const any_image_view& src, int xStep, int yStep) { + return apply_operation(src,detail::subsampled_view_fn >::type>(point2(xStep,yStep))); +} + +namespace detail { + template struct get_nthchannel_type { typedef typename nth_channel_view_type::type type; }; + template struct views_get_nthchannel_type : public mpl::transform > {}; +} + +/// \ingroup ImageViewTransformationsNthChannel +/// \brief Given a runtime source image view, returns the type of a runtime image view over a single channel of the source view +template +struct nth_channel_view_type > { + typedef any_image_view::type> type; +}; + +/// \ingroup ImageViewTransformationsNthChannel +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename nth_channel_view_type >::type nth_channel_view(const any_image_view& src, int n) { + return apply_operation(src,detail::nth_channel_view_fn >::type>(n)); +} + +namespace detail { + template struct get_ccv_type : public color_converted_view_type {}; + template struct views_get_ccv_type : public mpl::transform > {}; +} + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief Returns the type of a runtime-specified view, color-converted to a given pixel type with user specified color converter +template +struct color_converted_view_type,DstP,CC> { + typedef any_image_view::type> type; +}; + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief overload of generic color_converted_view with user defined color-converter +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename color_converted_view_type, DstP, CC>::type color_converted_view(const any_image_view& src,CC cc) { + return apply_operation(src,detail::color_converted_view_fn, DstP, CC>::type >()); +} + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief Returns the type of a runtime-specified view, color-converted to a given pixel type with the default coor converter +template +struct color_converted_view_type,DstP> { + typedef any_image_view::type> type; +}; + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief overload of generic color_converted_view with the default color-converter +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename color_converted_view_type, DstP>::type color_converted_view(const any_image_view& src) { + return apply_operation(src,detail::color_converted_view_fn, DstP>::type >()); +} + + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief overload of generic color_converted_view with user defined color-converter +/// These are workarounds for GCC 3.4, which thinks color_converted_view is ambiguous with the same method for templated views (in gil/image_view_factory.hpp) +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename color_converted_view_type, DstP, CC>::type any_color_converted_view(const any_image_view& src,CC cc) { + return apply_operation(src,detail::color_converted_view_fn, DstP, CC>::type >()); +} + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief overload of generic color_converted_view with the default color-converter +/// These are workarounds for GCC 3.4, which thinks color_converted_view is ambiguous with the same method for templated views (in gil/image_view_factory.hpp) +template inline // Models MPL Random Access Container of models of ImageViewConcept +typename color_converted_view_type, DstP>::type any_color_converted_view(const any_image_view& src) { + return apply_operation(src,detail::color_converted_view_fn, DstP>::type >()); +} + +/// \} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/reduce.hpp b/thirdparty/boost/gil/extension/dynamic_image/reduce.hpp new file mode 100644 index 0000000..b1fbb2d --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/reduce.hpp @@ -0,0 +1,789 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_REDUCE_HPP +#define GIL_REDUCE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../metafunctions.hpp" +#include "../../typedefs.hpp" +#include "dynamic_at_c.hpp" + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Constructs for static-to-dynamic integer convesion +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 4, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + + +#ifdef GIL_REDUCE_CODE_BLOAT + + +// Max number of cases in the cross-expension of binary operation for it to be reduced as unary +#define GIL_BINARY_REDUCE_LIMIT 226 + +namespace boost { namespace mpl { + +/////////////////////////////////////////////////////// +/// Mapping vector - represents the mapping of one type vector to another +/// It is not a full-blown MPL Random Access Type sequence; just has at_c and size implemented +/// +/// SrcTypes, DstTypes: MPL Random Access Type Sequences +/// +/// Implements size and at_c to behave as if this is an MPL vector of integers +/////////////////////////////////////////////////////// + +template +struct mapping_vector {}; + +template +struct at_c, K> { + static const std::size_t value=size::value - order::type>::type::value +1; + typedef size_t type; +}; + +template +struct size > { + typedef typename size::type type; + static const std::size_t value=type::value; +}; + +/////////////////////////////////////////////////////// +/// copy_to_vector - copies a sequence (mpl::set) to vector. +/// +/// Temporary solution because I couldn't get mpl::copy to do this. +/// This is what I tried: +/// mpl::copy > >::type; +/// It works when SET is mpl::vector, but not when SET is mpl::set... +/////////////////////////////////////////////////////// + +namespace detail { + template + struct copy_to_vector_impl { + private: + typedef typename deref::type T; + typedef typename next::type next; + typedef typename copy_to_vector_impl::type rest; + public: + typedef typename push_front::type type; + }; + + template + struct copy_to_vector_impl { + typedef vector::type> type; + }; +} + +template +struct copy_to_vector { + typedef typename detail::copy_to_vector_impl::type, size::value>::type type; +}; + +template <> +struct copy_to_vector > { + typedef vector0<> type; +}; + +} } // boost::mpl + +namespace boost { namespace gil { + + +/////////////////////////////////////////////////////// +/// +/// unary_reduce, binary_reduce - given an MPL Random Access Sequence, +/// dynamically specified index to that container, the bits of an instance of the corresponding type and +/// a generic operation, invokes the operation on the given type +/// +/////////////////////////////////////////////////////// + + + + +/////////////////////////////////////////////////////// +/// +/// \brief Unary reduce. +/// +/// Given a set of types and an operation, reduces each type in the set (to reduced_t), then removes duplicates (to unique_t) +/// To apply the operation, first constructs a lookup table that maps each element from Types to its place in unique_t and uses it to map +/// the index to anther index (in map_index). Then invokes apply_operation_base on the unique types with the new index. +/// +/////////////////////////////////////////////////////// + +template +struct unary_reduce_impl { + typedef typename mpl::transform >::type reduced_t; + typedef typename mpl::copy, mpl::insert > >::type unique_t; + static const bool is_single=mpl::size::value==1; +}; + +template ::is_single> +struct unary_reduce : public unary_reduce_impl { + typedef typename unary_reduce_impl::reduced_t reduced_t; + typedef typename unary_reduce_impl::unique_t unique_t; + + static unsigned short inline map_index(std::size_t index) { + typedef typename mpl::mapping_vector indices_t; + return gil::at_c(index); + } + template GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) { + return apply_operation_basec(bits,map_index(index),op); + } + + template GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) { + return apply_operation_base(bits,map_index(index),op); + } +}; + +template +struct unary_reduce : public unary_reduce_impl { + typedef typename unary_reduce_impl::unique_t unique_t; + static unsigned short inline map_index(std::size_t index) { return 0; } + + template GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) { + return op(*gil_reinterpret_cast_c::type*>(&bits)); + } + + template GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) { + return op(*gil_reinterpret_cast::type*>(&bits)); + } +}; + + +/////////////////////////////////////////////////////// +/// +/// \brief Binary reduce. +/// +/// Given two sets of types, Types1 and Types2, first performs unary reduction on each. Then checks if the product of their sizes is above +/// the GIL_BINARY_REDUCE_LIMIT limit. If so, the operation is too complex to be binary-reduced and uses a specialization of binary_reduce_impl +/// to simply call the binary apply_operation_base (which performs two nested 1D apply operations) +/// If the operation is not too complex, uses the other specialization of binary_reduce_impl to create a cross-product of the input types +/// and performs unary reduction on the result (bin_reduced_t). To apply the binary operation, it simply invokes a unary apply_operation_base +/// on the reduced cross-product types +/// +/////////////////////////////////////////////////////// + +namespace detail { + struct pair_generator { + template struct apply { + typedef std::pair::type*, const typename mpl::at_c::type*> type; + }; + }; + + // When the types are not too large, applies reduce on their cross product + template + struct binary_reduce_impl { + //private: + typedef typename mpl::copy_to_vector::type vec1_types; + typedef typename mpl::copy_to_vector::type vec2_types; + + typedef mpl::cross_vector, pair_generator> BIN_TYPES; + typedef unary_reduce bin_reduced_t; + + static unsigned short inline map_index(std::size_t index1, std::size_t index2) { + unsigned short r1=Unary1::map_index(index1); + unsigned short r2=Unary2::map_index(index2); + return bin_reduced_t::map_index(r2*mpl::size::value + r1); + } + public: + typedef typename bin_reduced_t::unique_t unique_t; + + template + static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { + std::pair pr(&bits1, &bits2); + return apply_operation_basec(pr, map_index(index1,index2),op); + } + }; + + // When the types are large performs a double-dispatch. Binary reduction is not done. + template + struct binary_reduce_impl { + template + static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { + return apply_operation_base(bits1, index1, bits2, index2, op); + } + }; +} + + +template +struct binary_reduce { +//private: + typedef unary_reduce unary1_t; + typedef unary_reduce unary2_t; + + static const std::size_t CROSS_SIZE = mpl::size::value * + mpl::size::value; + + typedef detail::binary_reduce_implGIL_BINARY_REDUCE_LIMIT)> impl; +public: + template + static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { + return impl::apply(bits1,index1,bits2,index2,op); + } +}; + +template +GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant& arg, UnaryOp op) { + return unary_reduce::template apply(arg._bits, arg._index ,op); +} + +template +GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant& arg, UnaryOp op) { + return unary_reduce::template applyc(arg._bits, arg._index ,op); +} + +template +GIL_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant& arg1, const variant& arg2, BinaryOp op) { + return binary_reduce::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op); +} + +#undef GIL_BINARY_REDUCE_LIMIT + +} } // namespace gil + + +namespace boost { namespace mpl { +/////////////////////////////////////////////////////// +/// \brief Represents the virtual cross-product of the types generated from VecOfVecs. +/// \ingroup CrossVector +/// INPUT: +/// VecOfVecs - a vector of vector types. For example [ [A1,A2,A3], [B1,B2], [C1,C2,C3,C4] ] +/// Each element must be a non-empty mpl vector +/// TypeGen - a metafunction that generates a type from a vector of types, each of which can be +/// selected from the corresponding vector in VecOfVecs. For example, [A1, B2, C4] +/// +/// Represents the virtual cross-product of the types generated from VecOfVecs. +/// For example, [ TypeGen[A1,B1,C1], TypeGen[A2,B1,C1], TypeGen[A3,B1,C1], +/// TypeGen[A1,B2,C1], TypeGen[A2,B2,C1], TypeGen[A3,B2,C1], +/// TypeGen[A1,B1,C2], TypeGen[A2,B1,C2], TypeGen[A3,B1,C2], ... ] +/// +/// Models an immutable MPL Random Access Sequence +/// Traversal, random-access, etc, is defined, but mutable operations, +/// such as push_back and pop_front are not supported +/////////////////////////////////////////////////////// + +template +struct cross_vector {}; + +/// \brief Iterator of cross_vector +/// \ingroup CrossVectorIterator +template +struct cross_iterator { + typedef mpl::random_access_iterator_tag category; +}; + +/////////////////////////////////////////////////////// +/// Implementation of the iterator functions of cross vector +/////////////////////////////////////////////////////// + +/// \brief Dereferences a cross-vector iterator +/// \ingroup CrossVectorIterator +/// Creates a vector of the sizes of each type vector in VecOfVecs, then uses it as a basis +/// to represent the iterator's position K as a vector of indices. Extracts the corresponding type of +/// each input vector and passes the element types to the type generation function, which returns the dereferenced type +template +struct deref > { +private: + typedef typename detail::select_subvector_c::type DerefTypes; +public: + typedef typename TypeGen::template apply::type type; +}; + +/// \brief Increments a cross-vector iterator. +/// \ingroup CrossVectorIterator +template +struct next > { + typedef cross_iterator type; +}; + +/// \brief Decrements a cross-vector iterator. +/// \ingroup CrossVectorIterator +template +struct prior > { + typedef cross_iterator type; +}; + +/// \brief Advances a cross-vector iterator. +/// \ingroup CrossVectorIterator +template +struct advance, Distance > { + typedef cross_iterator type; +}; + +/// \brief Computes the distance between two cross-vector iterator-s. +/// \ingroup CrossVectorIterator +// (shortened the names of the template arguments - otherwise doxygen cannot parse this...) +template +struct distance, cross_iterator > { + typedef size_t type; +}; + +/////////////////////////////////////////////////////// +/// Implementation of cross vector +/////////////////////////////////////////////////////// +/// \brief Computes the size of a cross vector as the product of the sizes of all vectors in VecOfVecs +/// \ingroup CrossVector +template +struct size > { + typedef typename fold, times<_1, size<_2> > >::type type; + static const std::size_t value=type::value; +}; + +/// \brief Determines whether a cross vector is empty +/// \ingroup CrossVector +template +struct empty > { + typedef typename empty::type type; +}; + +/// \brief Returns the K-th element of a cross vector +/// \ingroup CrossVector +template +struct at, K> { +private: + typedef cross_iterator KthIterator; +public: + typedef typename deref::type type; +}; + +/// \brief Returns an iterator to the first element of a cross vector +/// \ingroup CrossVector +template +struct begin > { + typedef cross_iterator type; +}; + +/// \brief Returns an iterator to the last element of a cross vector +/// \ingroup CrossVector +template +struct end > { +private: + typedef cross_vector this_t; +public: + typedef cross_iterator::value> type; +}; + +/// \brief Returns the first element of a cross vector +/// \ingroup CrossVector +template +struct front > { +private: + typedef cross_vector this_t; +public: + typedef typename deref::type>::type type; +}; + +/// \brief Returns the last element of a cross vector +/// \ingroup CrossVector +template +struct back > { +private: + typedef cross_vector this_t; + typedef typename size::type size; + typedef typename minus >::type last_index; +public: + typedef typename at::type type; +}; + +/// \brief Transforms the elements of a cross vector +/// \ingroup CrossVector +template +struct transform, OPP > { + typedef typename lambda::type Op; + struct adapter { + template + struct apply { + typedef typename TypeGen::template apply::type orig_t; + typedef typename Op::template apply::type type; + }; + }; + typedef cross_vector type; +}; + +} } // boost::mpl + +namespace boost { namespace gil { + +template struct type_to_index; +template struct view_is_basic; +struct rgb_t; +struct lab_t; +struct hsb_t; +struct cmyk_t; +struct rgba_t; +struct error_t; + + +namespace detail { + //////////////////////////////////////////////////////// + //// + //// Generic reduce operation + //// + //////////////////////////////////////////////////////// + template + struct reduce { + typedef T type; + }; + + //////////////////////////////////////////////////////// + //// + //// Unary reduce_view operation. Splits into basic and non-basic views. + //// Algorithm-specific reduce should specialize for basic views + //// + //////////////////////////////////////////////////////// + + template + struct reduce_view_basic { + typedef View type; + }; + + template + struct reduce > + : public reduce_view_basic,view_is_basic >::value> {}; + + //////////////////////////////////////////////////////// + //// + //// Unary reduce_image operation. Splits into basic and non-basic images. + //// Algorithm-specific reduce should specialize for basic images + //// + //////////////////////////////////////////////////////// + + template + struct reduce_image_basic { + typedef Img type; + }; + + template + struct reduce > : public reduce_image_basic,image_is_basic >::value > {}; + + //////////////////////////////////////////////////////// + //// + //// Binary reduce_view operation. Splits into basic and non-basic views. + //// Algorithm-specific reduce should specialize for basic views + //// + //////////////////////////////////////////////////////// + + template + struct reduce_views_basic { + typedef std::pair type; + }; + + template + struct reduce*, const image_view*> > + : public reduce_views_basic,image_view, + mpl::and_ >, view_is_basic > >::value > + {}; + + + //////////////////////////////////////////////////////// + //// + //// Color space unary reduce operation. Reduce a color space to a base with the same number of channels + //// + //////////////////////////////////////////////////////// + + template + struct reduce_color_space { + typedef Cs type; + }; + + template <> struct reduce_color_space { typedef rgb_t type; }; + template <> struct reduce_color_space { typedef rgb_t type; }; + template <> struct reduce_color_space { typedef rgba_t type; }; + + /* + //////////////////////////////////////////////////////// + //// + //// Color space binary reduce operation. Given a source and destination color spaces, + //// returns a reduced source and destination color spaces that have the same mapping of channels + //// + //// Precondition: The two color spaces must be compatible (i.e. must have the same set of channels) + //////////////////////////////////////////////////////// + + template + struct type_vec_to_integer_impl { + typedef typename mpl::back::type last; + typedef typename mpl::pop_back::type rest; + static const int value = type_vec_to_integer_impl::value * Basis + last::value; + }; + + template + struct type_vec_to_integer_impl { + static const int value=0; + }; + + template + struct type_vec_to_integer { + static const int value = type_vec_to_integer_impl::value>::value; + }; + + // Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces + // The default version performs no reduction + template + struct reduce_color_spaces_impl { + typedef SrcColorSpace first_t; + typedef DstColorSpace second_t; + }; + + // 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb + template + struct reduce_color_spaces_impl { + typedef rgb_t first_t; + typedef rgb_t second_t; + }; + + // 210: RGB-bgr, bgr-RGB + template + struct reduce_color_spaces_impl { + typedef rgb_t first_t; + typedef bgr_t second_t; + }; + + // 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk + template + struct reduce_color_spaces_impl { + typedef rgba_t first_t; + typedef rgba_t second_t; + }; + + // 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA + template + struct reduce_color_spaces_impl { + typedef rgba_t first_t; + typedef abgr_t second_t; + }; + + // 1230: RGBA-argb, bgra-abgr + template + struct reduce_color_spaces_impl { + typedef rgba_t first_t; + typedef argb_t second_t; + }; + + // 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived) + template + struct reduce_color_spaces_impl { + typedef rgba_t first_t; + typedef bgra_t second_t; + }; + + // 3012: argb-RGBA, abgr-bgra + template + struct reduce_color_spaces_impl { + typedef argb_t first_t; + typedef rgba_t second_t; + }; + + // 0321: argb-abgr, abgr-argb + template + struct reduce_color_spaces_impl { + typedef argb_t first_t; + typedef abgr_t second_t; + }; + + template + struct reduce_color_spaces { + typedef typename channel_order::type src_order_t; + typedef typename channel_order::type dst_order_t; + typedef typename mpl::transform >::type mapping; + static const int mapping_val = type_vec_to_integer::value; + + typedef typename reduce_color_spaces_impl::first_t _first_t; + typedef typename reduce_color_spaces_impl::second_t _second_t; + typedef typename mpl::and_, mpl::not_< color_space_is_base<_second_t> > > swap_t; + public: + typedef typename mpl::if_::type first_t; + typedef typename mpl::if_::type second_t; + }; +*/ +// TODO: Use the old code for reduce_color_spaces above to do color layout reduction + template + struct reduce_color_layouts { + typedef SrcLayout first_t; + typedef DstLayout second_t; + }; + + //////////////////////////////////////////////////////// + //// + //// Reduce for copy_pixels + //// + //////////////////////////////////////////////////////// + + struct copy_pixels_fn; + + /* + // 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions + template + struct reduce_view_basic { + private: + typedef typename reduce_color_space::type Cs; // reduce the color space + typedef layout layout_t; + public: + typedef typename derived_view_type::type type; + }; +*/ + // Incompatible views cannot be used in copy_pixels - will throw std::bad_cast + template + struct reduce_copy_pixop_compat { + typedef error_t type; + }; + + // For compatible basic views, reduce their color spaces based on their channel mapping. + // Make the source immutable and the destination mutable (they should already be that way) + template + struct reduce_copy_pixop_compat { + typedef layout layout1; + typedef layout layout2; + + typedef typename reduce_color_layouts::first_t L1; + typedef typename reduce_color_layouts::second_t L2; + + typedef typename derived_view_type::type DV1; + typedef typename derived_view_type::type DV2; + + typedef std::pair type; + }; + + // The general 2D version branches into compatible and incompatible views + template + struct reduce_views_basic + : public reduce_copy_pixop_compat, view_is_mutable >::value > { + }; + + //////////////////////////////////////////////////////// + //// + //// Reduce for variant destructor (basic views have no destructor) + //// + //////////////////////////////////////////////////////// + + struct destructor_op; + template struct reduce_view_basic { typedef gray8_view_t type; }; + + //////////////////////////////////////////////////////// + //// + //// Reduce for get_dimensions (basic views and images have the same structure and the dimensions are contained at the beginning) + //// + //////////////////////////////////////////////////////// + + struct any_type_get_dimensions; + template struct reduce_view_basic { typedef gray8_view_t type; }; + template struct reduce_image_basic { typedef gray8_image_t type; }; + + //////////////////////////////////////////////////////// + //// + //// Reduce for get_num_channels (only color space matters) + //// + //////////////////////////////////////////////////////// + + struct any_type_get_num_channels; + template struct reduce_view_basic { + typedef typename View::color_space_t::base Cs; + typedef typename view_type::type>::type type; + }; + template struct reduce_image_basic { + typedef typename Img::color_space_t::base Cs; + typedef typename image_type::type>::type type; + }; + + //////////////////////////////////////////////////////// + //// + //// Reduce for resample_pixels (same as copy_pixels) + //// + //////////////////////////////////////////////////////// + + template struct resample_pixels_fn; + + template + struct reduce_view_basic, V, IsBasic> : public reduce_view_basic {}; + + template + struct reduce_views_basic, V1, V2, IsBasic> : public reduce_views_basic {}; + + //////////////////////////////////////////////////////// + //// + //// Reduce for copy_and_convert_pixels + //// (the only reduction could be made when views are compatible and have the same mapping, planarity and stepness) + //// + //////////////////////////////////////////////////////// + + + template class copy_and_convert_pixels_fn; + + // the only thing for 1D reduce is making them all mutable... + template + struct reduce_view_basic, View, IsBasic> + : public derived_view_type { + }; + + // For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy. + // In this case, reduce their common color space. In general make the first immutable and the second mutable + template + struct reduce_views_basic, V1, V2, AreBasic> { + typedef is_same Same; + + typedef reduce_color_space CsR; + typedef typename mpl::if_::type Cs1; + typedef typename mpl::if_::type Cs2; + + typedef typename derived_view_type, use_default, use_default, mpl::false_>::type DV1; + typedef typename derived_view_type, use_default, use_default, mpl::true_ >::type DV2; + + typedef std::pair type; + }; + + + //integral_image_generator + //resize_clobber_image_fnobj + //image_default_construct_fnobj + //fill_converted_pixels_fn + //bind(gil::detail::copy_pixels_fn(), _1, dst) + //bind(gil::detail::copy_pixels_fn(), src,_1) + + //bind(detail::copy_and_convert_pixels_fn(), _1, dst) + //bind(detail::copy_and_convert_pixels_fn(), src, _1) + //gil::detail::fill_pixels_fn(val) + + //detail::copy_construct_in_place_fn + //detail::equal_to_fn::base_t> + + //detail::any_image_get_view::view_t> + //detail::any_image_get_const_view::view_t> + //detail::flipped_up_down_view_fn > + //detail::flipped_left_right_view_fn::dynamic_step_t> + //detail::tranposed_view_fn::dynamic_step_t> + //detail::rotated90cw_view_fn::dynamic_step_t> + //detail::rotated90ccw_view_fn::dynamic_step_t> + //detail::rotated180_view_fn::dynamic_step_t> + //detail::subimage_view_fn > + //detail::subsampled_view_fn::dynamic_step_t> + //detail::nth_channel_view_fn > + //detail::color_converted_view_fn, DstP>::type > +} + +} } // namespace boost::gil + +#endif // GIL_REDUCE_CODE_BLOAT + + +#endif diff --git a/thirdparty/boost/gil/extension/dynamic_image/variant.hpp b/thirdparty/boost/gil/extension/dynamic_image/variant.hpp new file mode 100644 index 0000000..414818a --- /dev/null +++ b/thirdparty/boost/gil/extension/dynamic_image/variant.hpp @@ -0,0 +1,194 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_DYNAMICIMAGE_VARIANT_HPP +#define GIL_DYNAMICIMAGE_VARIANT_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for run-time instantiated types +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 18, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "../../gil_config.hpp" +#include "../../utilities.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace gil { + +namespace detail { + template struct type_to_index; + template struct reduce; + struct destructor_op { + typedef void result_type; + template result_type operator()(const T& t) const { t.~T(); } + }; + template void copy_construct_in_place(const T& t, Bits& bits); + template struct copy_construct_in_place_fn; +} +/** +\brief Represents a concrete instance of a run-time specified type from a set of types +\class variant +\ingroup Variant + +A concept is typically modeled by a collection of different types. They may be instantiations +of a templated type with different template parameters or even completely unrelated types. + +We call the type with which the concept is instantiated in a given place in the code "the concrete type". +The concrete type must be chosen at compile time, which sometimes is a severe limitation. +Consider, for example, having an image concept modeled by an image class templated over the color space. +It would be difficult to write a function that reads an image from file preserving its native color space, since the +type of the return value is only available at run time. It would be difficult to store images of different color +spaces in the same container or apply operations on them uniformly. + +The variant class addresses this deficiency. It allows for run-time instantiation of a class from a given set of allowed classes +specified at compile time. For example, the set of allowed classes may include 8-bit and 16-bit RGB and CMYK images. Such a variant +can be constructed with rgb8_image_t and then assigned a cmyk16_image_t. + +The variant has a templated constructor, which allows us to construct it with any concrete type instantiation. It can also perform a generic +operation on the concrete type via a call to apply_operation. The operation must be provided as a function object whose application +operator has a single parameter which can be instantiated with any of the allowed types of the variant. + +variant breaks down the instantiated type into a non-templated underlying base type and a unique instantiation +type identifier. In the most common implementation the concrete instantiation in stored 'in-place' - in 'bits_t'. +bits_t contains sufficient space to fit the largest of the instantiated objects. + +GIL's variant is similar to boost::variant in spirit (hence we borrow the name from there) but it differs in several ways from the current boost +implementation. Most notably, it does not take a variable number of template parameters but a single parameter defining the type enumeration. As +such it can be used more effectively in generic code. + +The Types parameter specifies the set of allowable types. It models MPL Random Access Container +*/ + +template // models MPL Random Access Container +class variant { + // size in bytes of the largest type in Types + static const std::size_t MAX_SIZE = mpl::fold, mpl::max > >::type::value; + static const std::size_t NUM_TYPES = mpl::size::value; +public: + typedef Types types_t; + + typedef struct { char data[MAX_SIZE]; } base_t; // empty space equal to the size of the largest type in Types + + // Default constructor - default construct the first type + variant() : _index(0) { new(&_bits) typename mpl::at_c::type(); } + virtual ~variant() { apply_operation(*this, detail::destructor_op()); } + + // Throws std::bad_cast if T is not in Types + template explicit variant(const T& obj){ _index=type_id(); if (_index==NUM_TYPES) throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); } + + // When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call + template explicit variant(T& obj, bool do_swap); + + template variant& operator=(const T& obj) { variant tmp(obj); swap(*this,tmp); return *this; } + variant& operator=(const variant& v) { variant tmp(v ); swap(*this,tmp); return *this; } + + variant(const variant& v) : _index(v._index) { apply_operation(v, detail::copy_construct_in_place_fn(_bits)); } + template void move_in(T& obj) { variant tmp(obj, true); swap(*this,tmp); } + + template friend bool operator==(const variant& x, const variant& y); + template friend bool operator!=(const variant& x, const variant& y); + + template static bool has_type() { return type_id()!=NUM_TYPES; } + + template const T& _dynamic_cast() const { if (!current_type_is()) throw std::bad_cast(); return *gil_reinterpret_cast_c(&_bits); } + template T& _dynamic_cast() { if (!current_type_is()) throw std::bad_cast(); return *gil_reinterpret_cast < T*>(&_bits); } + + template bool current_type_is() const { return type_id()==_index; } + +private: + template static std::size_t type_id() { return detail::type_to_index::value; } + + template friend void swap(variant& x, variant& y); + template friend typename UnaryOp::result_type apply_operation(variant& var, UnaryOp op); + template friend typename UnaryOp::result_type apply_operation(const variant& var, UnaryOp op); + template friend typename BinaryOp::result_type apply_operation(const variant& arg1, const variant& arg2, BinaryOp op); + + base_t _bits; + std::size_t _index; +}; + +namespace detail { + + template + void copy_construct_in_place(const T& t, Bits& bits) { + T& b=*gil_reinterpret_cast(&bits); + new(&b)T(t); // default-construct + } + + template + struct copy_construct_in_place_fn { + typedef void result_type; + Bits& _dst; + copy_construct_in_place_fn(Bits& dst) : _dst(dst) {} + + template void operator()(const T& src) const { copy_construct_in_place(src,_dst); } + }; + + template + struct equal_to_fn { + const Bits& _dst; + equal_to_fn(const Bits& dst) : _dst(dst) {} + + typedef bool result_type; + template result_type operator()(const T& x) const { + return x==*gil_reinterpret_cast_c(&_dst); + } + }; +} + +// When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call +template +template variant::variant(T& obj, bool do_swap) { + _index=type_id(); + if (_index==NUM_TYPES) throw std::bad_cast(); + + if (do_swap) { + new(&_bits) T(); // default construct + swap(obj, *gil_reinterpret_cast(&_bits)); + } else + detail::copy_construct_in_place(const_cast(obj), _bits); +} + +template +void swap(variant& x, variant& y) { + std::swap(x._bits,y._bits); + std::swap(x._index, y._index); +} + +template +inline bool operator==(const variant& x, const variant& y) { + return x._index==y._index && apply_operation(x,detail::equal_to_fn::base_t>(y._bits)); +} + +template +inline bool operator!=(const variant& x, const variant& y) { + return !(x==y); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/dynamic_io.hpp b/thirdparty/boost/gil/extension/io/dynamic_io.hpp new file mode 100644 index 0000000..5a913e1 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/dynamic_io.hpp @@ -0,0 +1,79 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_DYNAMIC_IO_H +#define GIL_DYNAMIC_IO_H + +/// \file +/// \brief Generic io functions for dealing with dynamic images +// +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated May 30, 2006 + +#include +#include +#include "../../gil_config.hpp" +#include "../dynamic_image/any_image.hpp" + +namespace boost { namespace gil { + +namespace detail { + +template +struct construct_matched_t { + template + static bool apply(any_image& im,Pred pred) { + if (pred.template apply::type>()) { + typename mpl::at_c::type x; + im.move_in(x); + return true; + } else return construct_matched_t::apply(im,pred); + } +}; +template <> +struct construct_matched_t<0> { + template + static bool apply(any_image&,Pred) {return false;} +}; + +// A function object that can be passed to apply_operation. +// Given a predicate IsSupported taking a view type and returning an MPL boolean, +// calls the apply method of OpClass with the view if the given view IsSupported, or throws an exception otherwise +template +class dynamic_io_fnobj { + OpClass* _op; + + template + void apply(const View& view,mpl::true_ ) {_op->apply(view);} + template + void apply(const View& view,mpl::false_) {io_error("dynamic_io: unsupported view type for the given file format");} +public: + dynamic_io_fnobj(OpClass* op) : _op(op) {} + + typedef void result_type; + + template + void operator()(const View& view) {apply(view,typename IsSupported::template apply::type());} +}; + +} // namespace detail + +/// \brief Within the any_image, constructs an image with the given dimensions +/// and a type that satisfies the given predicate +template +inline bool construct_matched(any_image& im,Pred pred) { + return detail::construct_matched_t::value>::apply(im,pred); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/io_error.hpp b/thirdparty/boost/gil/extension/io/io_error.hpp new file mode 100644 index 0000000..29e1842 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/io_error.hpp @@ -0,0 +1,51 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_IO_ERROR_H +#define GIL_IO_ERROR_H + +/// \file +/// \brief Handle input-output errors +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on May 30, 2006 + +#include +#include "../../gil_config.hpp" +#include + +namespace boost { namespace gil { + +inline void io_error(const char* descr) { throw std::ios_base::failure(descr); } +inline void io_error_if(bool expr, const char* descr="") { if (expr) io_error(descr); } + +namespace detail { + class file_mgr { + protected: + shared_ptr _fp; + + struct null_deleter { void operator()(void const*) const {} }; + file_mgr(FILE* file) : _fp(file, null_deleter()) {} + + file_mgr(const char* filename, const char* flags) { + FILE* fp; + io_error_if((fp=fopen(filename,flags))==NULL, "file_mgr: failed to open file"); + _fp=shared_ptr(fp,fclose); + } + + public: + FILE* get() { return _fp.get(); } + }; +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/jpeg_dynamic_io.hpp b/thirdparty/boost/gil/extension/io/jpeg_dynamic_io.hpp new file mode 100644 index 0000000..a996361 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/jpeg_dynamic_io.hpp @@ -0,0 +1,130 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_JPEG_DYNAMIC_IO_H +#define GIL_JPEG_DYNAMIC_IO_H + +/// \file +/// \brief Support for reading and writing JPEG files +/// Requires libjpeg +/// +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated June 10, 2006 + +#include +#include +#include +#include +#include "../dynamic_image/dynamic_image_all.hpp" +#include "io_error.hpp" + +#include "jpeg_io.hpp" +#include "jpeg_io_private.hpp" +#include "dynamic_io.hpp" + +namespace boost { namespace gil { + +namespace detail { + +struct jpeg_write_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class jpeg_writer_dynamic : public jpeg_writer { + int _quality; +public: + jpeg_writer_dynamic(FILE* file, int quality=100) : jpeg_writer(file) , _quality(quality) {} + jpeg_writer_dynamic(const char* filename, int quality=100) : jpeg_writer(filename), _quality(quality) {} + + template + void write_view(const any_image_view& runtime_view) { + dynamic_io_fnobj op(this); + apply_operation(runtime_view,op); + } +}; + +class jpeg_type_format_checker { + J_COLOR_SPACE _color_type; +public: + jpeg_type_format_checker(J_COLOR_SPACE color_type_in) : + _color_type(color_type_in) {} + template + bool apply() { + return jpeg_read_support::color_type==_color_type; + } +}; + +struct jpeg_read_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class jpeg_reader_dynamic : public jpeg_reader { +public: + jpeg_reader_dynamic(FILE* file) : jpeg_reader(file) {} + jpeg_reader_dynamic(const char* filename) : jpeg_reader(filename){} + + template + void read_image(any_image& im) { + if (!construct_matched(im,detail::jpeg_type_format_checker(_cinfo.out_color_space))) { + io_error("jpeg_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file"); + } else { + im.recreate(get_dimensions()); + dynamic_io_fnobj op(this); + apply_operation(view(im),op); + } + } +}; + +} // namespace detail + + +/// \ingroup JPEG_IO +/// \brief reads a JPEG image into a run-time instantiated image +/// Opens the given JPEG file name, selects the first type in Images whose color space and channel are compatible to those of the image file +/// and creates a new image of that type with the dimensions specified by the image file. +/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk. +template +inline void jpeg_read_image(const char* filename,any_image& im) { + detail::jpeg_reader_dynamic m(filename); + m.read_image(im); +} + +/// \ingroup JPEG_IO +/// \brief reads a JPEG image into a run-time instantiated image +template +inline void jpeg_read_image(const std::string& filename,any_image& im) { + jpeg_read_image(filename.c_str(),im); +} + +/// \ingroup JPEG_IO +/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name. +/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension +/// or if it fails to create the file. +template +inline void jpeg_write_view(const char* filename,const any_image_view& runtime_view) { + detail::jpeg_writer_dynamic m(filename); + m.write_view(runtime_view); +} + +/// \ingroup JPEG_IO +/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name. +template +inline void jpeg_write_view(const std::string& filename,const any_image_view& runtime_view) { + jpeg_write_view(filename.c_str(),runtime_view); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/jpeg_io.hpp b/thirdparty/boost/gil/extension/io/jpeg_io.hpp new file mode 100644 index 0000000..207afef --- /dev/null +++ b/thirdparty/boost/gil/extension/io/jpeg_io.hpp @@ -0,0 +1,202 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_JPEG_IO_H +#define GIL_JPEG_IO_H + +/// \file +/// \brief Support for reading and writing JPEG files +/// Requires libjpeg +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated September 24, 2006 + +#include +#include +#include +#include +#include +extern "C" { +#include +} +#include "io_error.hpp" +#include "jpeg_io_private.hpp" + +namespace boost { namespace gil { + +/// \ingroup JPEG_IO +/// \brief Determines whether the given view type is supported for reading +template +struct jpeg_read_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::jpeg_read_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type= + (detail::jpeg_read_support_private::type, + typename color_space_type::type>::color_type)); + BOOST_STATIC_CONSTANT(bool, value=is_supported); +}; + +/// \ingroup JPEG_IO +/// \brief Returns the width and height of the JPEG file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file +inline point2 jpeg_read_dimensions(const char* filename) { + detail::jpeg_reader m(filename); + return m.get_dimensions(); +} + +/// \ingroup JPEG_IO +/// \brief Returns the width and height of the JPEG file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file +inline point2 jpeg_read_dimensions(const std::string& filename) { + return jpeg_read_dimensions(filename.c_str()); +} + +/// \ingroup JPEG_IO +/// \brief Loads the image specified by the given jpeg image file name into the given view. +/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not +/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view. +template +inline void jpeg_read_view(const char* filename,const View& view) { + BOOST_STATIC_ASSERT(jpeg_read_support::is_supported); + + detail::jpeg_reader m(filename); + m.apply(view); +} + +/// \ingroup JPEG_IO +/// \brief Loads the image specified by the given jpeg image file name into the given view. +template +inline void jpeg_read_view(const std::string& filename,const View& view) { + jpeg_read_view(filename.c_str(),view); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it. +/// Triggers a compile assert if the image color space or channel depth are not supported by the JPEG library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not +/// compatible with the ones specified by Image +template +inline void jpeg_read_image(const char* filename,Image& im) { + BOOST_STATIC_ASSERT(jpeg_read_support::is_supported); + + detail::jpeg_reader m(filename); + m.read_image(im); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it. +template +inline void jpeg_read_image(const std::string& filename,Image& im) { + jpeg_read_image(filename.c_str(),im); +} + +/// \ingroup JPEG_IO +/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view. +/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view. +template +inline void jpeg_read_and_convert_view(const char* filename,const View& view,CC cc) { + detail::jpeg_reader_color_convert m(filename,cc); + m.apply(view); +} + +/// \ingroup JPEG_IO +/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view. +/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view. +template +inline void jpeg_read_and_convert_view(const char* filename,const View& view) { + detail::jpeg_reader_color_convert m(filename,default_color_converter()); + m.apply(view); +} + +/// \ingroup JPEG_IO +/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view. +template +inline void jpeg_read_and_convert_view(const std::string& filename,const View& view,CC cc) { + jpeg_read_and_convert_view(filename.c_str(),view); +} + +/// \ingroup JPEG_IO +/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view. +template +inline void jpeg_read_and_convert_view(const std::string& filename,const View& view) { + jpeg_read_and_convert_view(filename.c_str(),view); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid JPEG file +template +inline void jpeg_read_and_convert_image(const char* filename,Image& im,CC cc) { + detail::jpeg_reader_color_convert m(filename,cc); + m.read_image(im); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid JPEG file +template +inline void jpeg_read_and_convert_image(const char* filename,Image& im) { + detail::jpeg_reader_color_convert m(filename,default_color_converter()); + m.read_image(im); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it. +template +inline void jpeg_read_and_convert_image(const std::string& filename,Image& im,CC cc) { + jpeg_read_and_convert_image(filename.c_str(),im); +} + +/// \ingroup JPEG_IO +/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it. +template +inline void jpeg_read_and_convert_image(const std::string& filename,Image& im) { + jpeg_read_and_convert_image(filename.c_str(),im); +} + +/// \ingroup JPEG_IO +/// \brief Determines whether the given view type is supported for writing +template +struct jpeg_write_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::jpeg_write_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type= + (detail::jpeg_write_support_private::type, + typename color_space_type::type>::color_type)); + BOOST_STATIC_CONSTANT(bool, value=is_supported); +}; + +/// \ingroup JPEG_IO +/// \brief Saves the view to a jpeg file specified by the given jpeg image file name. +/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension. +/// Throws std::ios_base::failure if it fails to create the file. +template +inline void jpeg_write_view(const char* filename,const View& view,int quality=100) { + BOOST_STATIC_ASSERT(jpeg_write_support::is_supported); + + detail::jpeg_writer m(filename); + m.apply(view,quality); +} + +/// \ingroup JPEG_IO +/// \brief Saves the view to a jpeg file specified by the given jpeg image file name. +template +inline void jpeg_write_view(const std::string& filename,const View& view,int quality=100) { + jpeg_write_view(filename.c_str(),view,quality); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/jpeg_io_private.hpp b/thirdparty/boost/gil/extension/io/jpeg_io_private.hpp new file mode 100644 index 0000000..063e465 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/jpeg_io_private.hpp @@ -0,0 +1,225 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_JPEG_IO_PRIVATE_H +#define GIL_JPEG_IO_PRIVATE_H + +/// \file +/// \brief Internal support for reading and writing JPEG files +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated September 24, 2006 + +#include +#include +#include +#include "../../gil_all.hpp" +#include "io_error.hpp" + +namespace boost { namespace gil { + +namespace detail { + +// lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated? + +template +struct jpeg_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN); +}; +template <> +struct jpeg_read_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE); +}; +template <> +struct jpeg_read_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB); +}; +template <> +struct jpeg_read_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK); +}; +template +struct jpeg_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN); +}; +template <> +struct jpeg_write_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE); +}; +template <> +struct jpeg_write_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB); +}; +template <> +struct jpeg_write_support_private { + BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8); + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK); +}; + + +class jpeg_reader : public file_mgr { +protected: + jpeg_decompress_struct _cinfo; + jpeg_error_mgr _jerr; + + void init() { + _cinfo.err=jpeg_std_error(&_jerr); + jpeg_create_decompress(&_cinfo); + jpeg_stdio_src(&_cinfo,_fp.get()); + jpeg_read_header(&_cinfo,TRUE); + } +public: + jpeg_reader(FILE* file) : file_mgr(file) { init(); } + jpeg_reader(const char* filename) : file_mgr(filename, "rb") { init(); } + + ~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); } + + template + void apply(const View& view) { + jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state... + io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported"); + io_error_if(_cinfo.out_color_space!=jpeg_read_support_private::type, + typename color_space_type::type>::color_type, + "jpeg_reader::apply(): input view type does not match the image file"); + io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file"); + std::vector::type> > > row(view.width()); + JSAMPLE* row_address=(JSAMPLE*)&row.front(); + for(int y=0;y + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } + + point2 get_dimensions() const { + return point2(_cinfo.image_width,_cinfo.image_height); + } +}; + +// This code will be simplified... +template +class jpeg_reader_color_convert : public jpeg_reader { +private: + CC _cc; +public: + jpeg_reader_color_convert(FILE* file,CC cc_in) : jpeg_reader(file),_cc(cc_in) {} + jpeg_reader_color_convert(FILE* file) : jpeg_reader(file) {} + jpeg_reader_color_convert(const char* filename,CC cc_in) : jpeg_reader(filename),_cc(cc_in) {} + jpeg_reader_color_convert(const char* filename) : jpeg_reader(filename) {} + template + void apply(const View& view) { + jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state... + io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported"); + io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file"); + switch (_cinfo.out_color_space) { + case JCS_GRAYSCALE: { + std::vector row(view.width()); + JSAMPLE* row_address=(JSAMPLE*)&row.front(); + for(int y=0;y(_cc)); + } + break; + } + case JCS_RGB: { + std::vector row(view.width()); + JSAMPLE* row_address=(JSAMPLE*)&row.front(); + for(int y=0;y(_cc)); + } + break; + } + case JCS_CMYK: { + std::vector row(view.width()); + JSAMPLE* row_address=(JSAMPLE*)&row.front(); + for(int y=0;y(_cc)); + } + break; + } + default: + io_error("jpeg_reader_color_covert::apply(): unknown color type"); + } + jpeg_finish_decompress(&_cinfo); + } + template + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } +}; + +class jpeg_writer : public file_mgr { + jpeg_compress_struct _cinfo; + jpeg_error_mgr _jerr; + + void init() { + _cinfo.err=jpeg_std_error(&_jerr); + jpeg_create_compress(&_cinfo); + jpeg_stdio_dest(&_cinfo,_fp.get()); + } +public: + jpeg_writer(FILE* file) : file_mgr(file) { init(); } + jpeg_writer(const char* filename) : file_mgr(filename, "wb") { init(); } + ~jpeg_writer() { jpeg_destroy_compress(&_cinfo); } + + template + void apply(const View& view,int quality=100) { + _cinfo.image_width = (JDIMENSION)view.width(); + _cinfo.image_height = (JDIMENSION)view.height(); + _cinfo.input_components=num_channels::value; + _cinfo.in_color_space = jpeg_write_support_private::type, + typename color_space_type::type>::color_type; + jpeg_set_defaults(&_cinfo); + jpeg_set_quality(&_cinfo, quality, TRUE); + jpeg_start_compress(&_cinfo, TRUE); + std::vector::type> > > row(view.width()); + JSAMPLE* row_address=(JSAMPLE*)&row.front(); + for (int y=0;y void png_read_image(const char*,any_image&) +// template void png_read_image(FILE*,any_image&,std::size_t) +// template void png_write_view(const char*,const any_image_view&) +// template void png_write_view(FILE*,const any_image_view&) + + +#include +#include +#include +#include +#include "../dynamic_image/dynamic_image_all.hpp" +#include "io_error.hpp" +#include "png_io.hpp" +#include "png_io_private.hpp" +#include "dynamic_io.hpp" + +namespace boost { namespace gil { + +namespace detail { + +struct png_write_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class png_writer_dynamic : public png_writer { +public: + png_writer_dynamic(FILE* file ) : png_writer(file) {} + png_writer_dynamic(const char* filename) : png_writer(filename){} + + template + void write_view(const any_image_view& runtime_view) { + dynamic_io_fnobj op(this); + apply_operation(runtime_view,op); + } +}; + +class png_type_format_checker { + int _bit_depth; + int _color_type; +public: + png_type_format_checker(int bit_depth_in,int color_type_in) : + _bit_depth(bit_depth_in),_color_type(color_type_in) {} + template + bool apply() { + return png_read_support::bit_depth==_bit_depth && + png_read_support::color_type==_color_type; + } +}; + +struct png_read_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class png_reader_dynamic : public png_reader { +public: + png_reader_dynamic(FILE* file) : png_reader(file) {} + png_reader_dynamic(const char* filename) : png_reader(filename){} + + template + void read_image(any_image& im) { + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + png_get_IHDR(_png_ptr, _info_ptr, + &width, &height,&bit_depth,&color_type,&interlace_type, + int_p_NULL, int_p_NULL); + if (!construct_matched(im,png_type_format_checker(bit_depth,color_type))) { + io_error("png_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file"); + } else { + im.recreate(width,height); + dynamic_io_fnobj op(this); + apply_operation(view(im),op); + } + } +}; + +} // namespace detail + +/// \ingroup PNG_IO +/// \brief reads a PNG image into a run-time instantiated image +/// Opens the given png file name, selects the first type in Images whose color space and channel are compatible to those of the image file +/// and creates a new image of that type with the dimensions specified by the image file. +/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk. +template +inline void png_read_image(const char* filename,any_image& im) { + detail::png_reader_dynamic m(filename); + m.read_image(im); +} + +/// \ingroup PNG_IO +/// \brief reads a PNG image into a run-time instantiated image +template +inline void png_read_image(const std::string& filename,any_image& im) { + png_read_image(filename.c_str(),im); +} + +/// \ingroup PNG_IO +/// \brief Saves the currently instantiated view to a png file specified by the given png image file name. +/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension +/// or if it fails to create the file. +template +inline void png_write_view(const char* filename,const any_image_view& runtime_view) { + detail::png_writer_dynamic m(filename); + m.write_view(runtime_view); +} + +/// \ingroup PNG_IO +/// \brief Saves the currently instantiated view to a png file specified by the given png image file name. +template +inline void png_write_view(const std::string& filename,const any_image_view& runtime_view) { + png_write_view(filename.c_str(),runtime_view); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/png_io.hpp b/thirdparty/boost/gil/extension/io/png_io.hpp new file mode 100644 index 0000000..3ab02f9 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/png_io.hpp @@ -0,0 +1,214 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PNG_IO_H +#define GIL_PNG_IO_H + +/// \file +/// \brief Support for reading and writing PNG files +/// Requires libpng and zlib! +// +// We are currently providing the following functions: +// point2 png_read_dimensions(const char*) +// template void png_read_view(const char*,const View&) +// template void png_read_image(const char*,image&) +// template void png_write_view(const char*,const View&) +// template struct png_read_support; +// template struct png_write_support; +// +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated September 24, 2006 + +#include +#include +extern "C" { +#include "png.h" +} +#include +#include "../../gil_config.hpp" +#include "../../utilities.hpp" +#include "io_error.hpp" +#include "png_io_private.hpp" + +namespace boost { namespace gil { + +/// \ingroup PNG_IO +/// \brief Returns the width and height of the PNG file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file +inline point2 png_read_dimensions(const char *filename) { + detail::png_reader m(filename); + return m.get_dimensions(); +} + +/// \ingroup PNG_IO +/// \brief Returns the width and height of the PNG file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file +inline point2 png_read_dimensions(const std::string& filename) { + return png_read_dimensions(filename.c_str()); +} + +/// \ingroup PNG_IO +/// \brief Determines whether the given view type is supported for reading +template +struct png_read_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::png_read_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(int,bit_depth= + (detail::png_read_support_private::type, + typename color_space_type::type>::bit_depth)); + BOOST_STATIC_CONSTANT(int,color_type= + (detail::png_read_support_private::type, + typename color_space_type::type>::color_type)); + BOOST_STATIC_CONSTANT(bool, value=is_supported); +}; + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name into the given view. +/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not +/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view. +template +inline void png_read_view(const char* filename,const View& view) { + BOOST_STATIC_ASSERT(png_read_support::is_supported); + detail::png_reader m(filename); + m.apply(view); +} + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name into the given view. +template +inline void png_read_view(const std::string& filename,const View& view) { + png_read_view(filename.c_str(),view); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it. +/// Triggers a compile assert if the image color space or channel depth are not supported by the PNG library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not +/// compatible with the ones specified by Image +template +inline void png_read_image(const char* filename,Image& im) { + BOOST_STATIC_ASSERT(png_read_support::is_supported); + detail::png_reader m(filename); + m.read_image(im); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it. +template +inline void png_read_image(const std::string& filename,Image& im) { + png_read_image(filename.c_str(),im); +} + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name and color-converts it into the given view. +/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view. +template +inline void png_read_and_convert_view(const char* filename,const View& view,CC cc) { + detail::png_reader_color_convert m(filename,cc); + m.apply(view); +} + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name and color-converts it into the given view. +/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view. +template +inline void png_read_and_convert_view(const char* filename,const View& view) { + detail::png_reader_color_convert m(filename,default_color_converter()); + m.apply(view); +} + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name and color-converts it into the given view. +template +inline void png_read_and_convert_view(const std::string& filename,const View& view,CC cc) { + png_read_and_convert_view(filename.c_str(),view,cc); +} + +/// \ingroup PNG_IO +/// \brief Loads the image specified by the given png image file name and color-converts it into the given view. +template +inline void png_read_and_convert_view(const std::string& filename,const View& view) { + png_read_and_convert_view(filename.c_str(),view); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid PNG file +template +inline void png_read_and_convert_image(const char* filename,Image& im,CC cc) { + detail::png_reader_color_convert m(filename,cc); + m.read_image(im); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid PNG file +template +inline void png_read_and_convert_image(const char* filename,Image& im) { + detail::png_reader_color_convert m(filename,default_color_converter()); + m.read_image(im); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it. +template +inline void png_read_and_convert_image(const std::string& filename,Image& im,CC cc) { + png_read_and_convert_image(filename.c_str(),im,cc); +} + +/// \ingroup PNG_IO +/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it. +template +inline void png_read_and_convert_image(const std::string& filename,Image& im) { + png_read_and_convert_image(filename.c_str(),im); +} + +/// \ingroup PNG_IO +/// \brief Determines whether the given view type is supported for writing +template +struct png_write_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::png_write_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(int,bit_depth= + (detail::png_write_support_private::type, + typename color_space_type::type>::bit_depth)); + BOOST_STATIC_CONSTANT(int,color_type= + (detail::png_write_support_private::type, + typename color_space_type::type>::color_type)); + BOOST_STATIC_CONSTANT(bool, value=is_supported); +}; + +/// \ingroup PNG_IO +/// \brief Saves the view to a png file specified by the given png image file name. +/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension. +/// Throws std::ios_base::failure if it fails to create the file. +template +inline void png_write_view(const char* filename,const View& view) { + BOOST_STATIC_ASSERT(png_write_support::is_supported); + detail::png_writer m(filename); + m.apply(view); +} + +/// \ingroup PNG_IO +/// \brief Saves the view to a png file specified by the given png image file name. +template +inline void png_write_view(const std::string& filename,const View& view) { + png_write_view(filename.c_str(),view); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/png_io_private.hpp b/thirdparty/boost/gil/extension/io/png_io_private.hpp new file mode 100644 index 0000000..faa01c1 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/png_io_private.hpp @@ -0,0 +1,359 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_PNG_IO_PRIVATE_H +#define GIL_PNG_IO_PRIVATE_H + +/// \file +/// \brief Internal support for reading and writing PNG files +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated August 14, 2007 + +#include +#include +#include +#include "../../gil_all.hpp" +#include "io_error.hpp" + +namespace boost { namespace gil { + +namespace detail { + +static const size_t PNG_BYTES_TO_CHECK = 4; + +// lbourdev: These can be greatly simplified, for example: +template struct png_color_type {BOOST_STATIC_CONSTANT(int,color_type=0);}; +template<> struct png_color_type { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); }; +template<> struct png_color_type { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); }; +template<> struct png_color_type { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); }; + +template struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=false);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; +template <> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=true);}; + +template struct png_bit_depth {BOOST_STATIC_CONSTANT(int,bit_depth=sizeof(Channel)*8);}; + +template +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(int,bit_depth=0); + BOOST_STATIC_CONSTANT(int,color_type=0); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); +}; +template <> +struct png_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); +}; + +template +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(int,bit_depth=0); + BOOST_STATIC_CONSTANT(int,color_type=0); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); +}; +template <> +struct png_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); +}; + +class png_reader : public file_mgr { +protected: + png_structp _png_ptr; + png_infop _info_ptr; + + void init() { + char buf[PNG_BYTES_TO_CHECK]; + // read in some of the signature bytes + io_error_if(fread(buf, 1, PNG_BYTES_TO_CHECK, get()) != detail::PNG_BYTES_TO_CHECK, + "png_check_validity: fail to read file"); + // compare the first PNG_BYTES_TO_CHECK bytes of the signature. + io_error_if(png_sig_cmp((png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK)!=0, + "png_check_validity: invalid png file"); + + _png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); + io_error_if(_png_ptr==NULL,"png_get_file_size: fail to call png_create_write_struct()"); + // allocate/initialize the image information data + _info_ptr = png_create_info_struct(_png_ptr); + if (_info_ptr == NULL) { + png_destroy_read_struct(&_png_ptr,png_infopp_NULL,png_infopp_NULL); + io_error("png_get_file_size: fail to call png_create_info_struct()"); + } + if (setjmp(png_jmpbuf(_png_ptr))) { + //free all of the memory associated with the png_ptr and info_ptr + png_destroy_read_struct(&_png_ptr, &_info_ptr, png_infopp_NULL); + io_error("png_get_file_size: fail to call setjmp()"); + } + png_init_io(_png_ptr, get()); + png_set_sig_bytes(_png_ptr,PNG_BYTES_TO_CHECK); + png_read_info(_png_ptr, _info_ptr); + if (little_endian() && png_get_bit_depth(_png_ptr,_info_ptr)>8) + png_set_swap(_png_ptr); + } +public: + png_reader(FILE* file ) : file_mgr(file) { init(); } + png_reader(const char* filename) : file_mgr(filename, "rb") { init(); } + + ~png_reader() { + png_destroy_read_struct(&_png_ptr,&_info_ptr,png_infopp_NULL); + } + point2 get_dimensions() { + return point2(png_get_image_width(_png_ptr,_info_ptr), + png_get_image_height(_png_ptr,_info_ptr)); + } + template + void apply(const View& view) { + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + png_get_IHDR(_png_ptr, _info_ptr, + &width, &height,&bit_depth,&color_type,&interlace_type, + int_p_NULL, int_p_NULL); + io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height), + "png_read_view: input view size does not match PNG file size"); + + if(png_read_support_private::type, + typename color_space_type::type>::bit_depth!=bit_depth || + png_read_support_private::type, + typename color_space_type::type>::color_type!=color_type) + io_error("png_read_view: input view type is incompatible with the image type"); + + std::vector::type, + layout::type> > > row(width); + for(png_uint_32 y=0;y + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } +}; + +// This code will be simplified... +template +class png_reader_color_convert : public png_reader { +private: + CC _cc; +public: + png_reader_color_convert(FILE* file ,CC cc_in) : png_reader(file),_cc(cc_in) {} + png_reader_color_convert(FILE* file ) : png_reader(file) {} + png_reader_color_convert(const char* filename,CC cc_in) : png_reader(filename),_cc(cc_in) {} + png_reader_color_convert(const char* filename) : png_reader(filename) {} + template + void apply(const View& view) { + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + png_get_IHDR(_png_ptr, _info_ptr, + &width, &height,&bit_depth,&color_type,&interlace_type, + int_p_NULL, int_p_NULL); + io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height), + "png_reader_color_convert::apply(): input view size does not match PNG file size"); + switch (color_type) { + case PNG_COLOR_TYPE_GRAY: + switch (bit_depth) { + case 8: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + case 16: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth"); + } + break; + case PNG_COLOR_TYPE_RGB: + switch (bit_depth) { + case 8: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + case 16: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth"); + } + break; + case PNG_COLOR_TYPE_RGBA: + switch (bit_depth) { + case 8: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + case 16: { + std::vector row(width); + for(png_uint_32 y=0;y(_cc)); + } + break; + } + default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth"); + } + break; + default: io_error("png_reader_color_convert::apply(): unknown color type"); + } + png_read_end(_png_ptr,NULL); + } + template + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } +}; + + +class png_writer : public file_mgr { +protected: + png_structp _png_ptr; + png_infop _info_ptr; + + void init() { + _png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); + io_error_if(!_png_ptr,"png_write_initialize: fail to call png_create_write_struct()"); + _info_ptr = png_create_info_struct(_png_ptr); + if (!_info_ptr) { + png_destroy_write_struct(&_png_ptr,png_infopp_NULL); + io_error("png_write_initialize: fail to call png_create_info_struct()"); + } + if (setjmp(png_jmpbuf(_png_ptr))) { + png_destroy_write_struct(&_png_ptr, &_info_ptr); + io_error("png_write_initialize: fail to call setjmp(png_jmpbuf())"); + } + png_init_io(_png_ptr,get()); + } +public: + png_writer(FILE* file ) : file_mgr(file) { init(); } + png_writer(const char* filename) : file_mgr(filename, "wb") { init(); } + + ~png_writer() { + png_destroy_write_struct(&_png_ptr,&_info_ptr); + } + template + void apply(const View& view) { + png_set_IHDR(_png_ptr, _info_ptr, view.width(), view.height(), + png_write_support_private::type, + typename color_space_type::type>::bit_depth, + png_write_support_private::type, + typename color_space_type::type>::color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT); + png_write_info(_png_ptr,_info_ptr); + if (little_endian() && + png_write_support_private::type, + typename color_space_type::type>::bit_depth>8) + png_set_swap(_png_ptr); + std::vector::type, + layout::type> > > row(view.width()); + for(int y=0;y void tiff_read_image(const char*,any_image) +// template void tiff_write_view(const char*,any_image_view) +// + +#include +#include +#include "../dynamic_image/dynamic_image_all.hpp" +#include "io_error.hpp" +#include "tiff_io.hpp" +#include "dynamic_io.hpp" + +namespace boost { namespace gil { + +namespace detail { + +struct tiff_write_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class tiff_writer_dynamic : public tiff_writer { +public: + typedef void result_type; + tiff_writer_dynamic(const char* filename) : tiff_writer(filename) {} + + template + void write_view(const any_image_view& runtime_view) { + dynamic_io_fnobj op(this); + apply_operation(runtime_view,op); + } +}; + +class tiff_type_format_checker { + int _bit_depth; + int _color_type; +public: + tiff_type_format_checker(int bit_depth_in,int color_type_in) : + _bit_depth(bit_depth_in),_color_type(color_type_in) {} + template + bool apply() { + return tiff_read_support::bit_depth==_bit_depth && + tiff_read_support::color_type==_color_type; + } +}; + +struct tiff_read_is_supported { + template struct apply + : public mpl::bool_::is_supported> {}; +}; + +class tiff_reader_dynamic : public tiff_reader { +public: + tiff_reader_dynamic(const char* filename) : tiff_reader(filename) {} + + template + void read_image(any_image& im) { + int width,height; + unsigned short bps,photometric; + TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH,&width); + TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&height); + TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps); + TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric); + if (!construct_matched(im,tiff_type_format_checker(bps,photometric))) { + io_error("tiff_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file"); + } else { + im.recreate(width,height); + dynamic_io_fnobj op(this); + apply_operation(view(im),op); + } + } +}; + +} // namespace detail + +/// \ingroup TIFF_IO +/// \brief reads a TIFF image into a run-time instantiated image +/// Opens the given tiff file name, selects the first type in Images whose color space and channel are compatible to those of the image file +/// and creates a new image of that type with the dimensions specified by the image file. +/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk. +template +inline void tiff_read_image(const char* filename,any_image& im) { + detail::tiff_reader_dynamic m(filename); + m.read_image(im); +} + +/// \ingroup TIFF_IO +/// \brief reads a TIFF image into a run-time instantiated image +template +inline void tiff_read_image(const std::string& filename,any_image& im) { + tiff_read_image(filename.c_str(),im); +} + +/// \ingroup TIFF_IO +/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name. +/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension +/// or if it fails to create the file. +template +inline void tiff_write_view(const char* filename,const any_image_view& runtime_view) { + detail::tiff_writer_dynamic m(filename); + m.write_view(runtime_view); +} + +/// \ingroup TIFF_IO +/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name. +template +inline void tiff_write_view(const std::string& filename,const any_image_view& runtime_view) { + tiff_write_view(filename.c_str(),runtime_view); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/extension/io/tiff_io.hpp b/thirdparty/boost/gil/extension/io/tiff_io.hpp new file mode 100644 index 0000000..2195d00 --- /dev/null +++ b/thirdparty/boost/gil/extension/io/tiff_io.hpp @@ -0,0 +1,491 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_TIFF_IO_H +#define GIL_TIFF_IO_H + +/// \file +/// \brief Support for reading and writing TIFF files +/// Requires libtiff! +/// \author Hailin Jin and Lubomir Bourdev \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated September 24, 2006 + +#include +#include +#include +#include +#include +#include "../../gil_all.hpp" +#include "io_error.hpp" + +namespace boost { namespace gil { + +namespace detail { + +template +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(int,bit_depth=0); + BOOST_STATIC_CONSTANT(int,color_type=0); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=32); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_read_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=32); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; + +template +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=false); + BOOST_STATIC_CONSTANT(int,bit_depth=0); + BOOST_STATIC_CONSTANT(int,color_type=0); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=8); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=16); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=32); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); +}; +template <> +struct tiff_write_support_private { + BOOST_STATIC_CONSTANT(bool,is_supported=true); + BOOST_STATIC_CONSTANT(int,bit_depth=32); + BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); +}; + +class tiff_reader { +protected: + TIFF *_tp; +public: + tiff_reader(const char* filename) { + io_error_if((_tp=TIFFOpen(filename,"r"))==NULL, + "tiff_reader: fail to open file"); + } + ~tiff_reader() { TIFFClose(_tp); } + template + void apply(const View& view) { + unsigned short bps,photometric; + point2 dims=get_dimensions(); + io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1); + io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1); + io_error_if(dims!=view.dimensions(), + "tiff_read_view: input view size does not match TIFF file size"); + io_error_if(tiff_read_support_private::type, + typename color_space_type::type>::bit_depth!=bps || + tiff_read_support_private::type, + typename color_space_type::type>::color_type!=photometric, + "tiff_read_view: input view type is incompatible with the image type"); + std::size_t element_size=sizeof(pixel::type, + layout::type> >); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector::type, + layout::type> > > row(size_to_allocate); + for (int y=0;y get_dimensions() { + int w,h; + io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH, &w)!=1); + io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&h)!=1); + return point2(w,h); + } + + template + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } +}; + +// This code will be simplified... +template +class tiff_reader_color_convert : public tiff_reader { +private: + CC _cc; +public: + tiff_reader_color_convert(const char* filename) : + tiff_reader(filename) {} + tiff_reader_color_convert(const char* filename,CC cc_in) : + tiff_reader(filename),_cc(cc_in) {} + template + void apply(const View& view) { + point2 dims=get_dimensions(); + unsigned short bps,photometric; + io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1); + io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1); + io_error_if(dims!=view.dimensions(), + "tiff_reader_color_convert::apply(): input view size does not match TIFF file size"); + switch (photometric) { + case PHOTOMETRIC_MINISBLACK: { + switch (bps) { + case 8: { + std::size_t element_size=sizeof(gray8_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + case 16: { + std::size_t element_size=sizeof(gray16_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + case 32: { + std::size_t element_size=sizeof(gray32f_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + default: + io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth"); + } + break; + } + case PHOTOMETRIC_RGB: { + switch (bps) { + case 8: { + std::size_t element_size=sizeof(rgb8_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + case 16: { + std::size_t element_size=sizeof(rgb16_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + case 32: { + std::size_t element_size=sizeof(rgb32f_pixel_t); + std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), + (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); + std::vector row(size_to_allocate); + for (int y=0;y(_cc)); + } + break; + } + default: + io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth"); + } + break; + } + default: { + // reads an image in incompatible format via TIFFReadRGBAImage + rgba8_image_t rgbaImg(dims); + io_error_if(!TIFFReadRGBAImage(_tp, dims.x, dims.y, (uint32*)&gil::view(rgbaImg)(0,0), 0), + "tiff_reader_color_convert::unsupported image format"); + copy_and_convert_pixels(flipped_up_down_view(const_view(rgbaImg)), view, _cc); + } + } + } + template + void read_image(Image& im) { + im.recreate(get_dimensions()); + apply(view(im)); + } +}; + +class tiff_writer { +protected: + TIFF* _tp; +public: + tiff_writer(const char *filename) { + io_error_if((_tp=TIFFOpen(filename,"w"))==NULL, + "tiff_writer: fail to open file"); + } + ~tiff_writer() {TIFFClose(_tp);} + template + void apply(const View& view) { + io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGELENGTH, view.height())!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGEWIDTH, view.width())!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_PHOTOMETRIC, tiff_write_support_private::type, + typename color_space_type::type>::color_type)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_SAMPLESPERPIXEL,num_channels::value)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private::type, + typename color_space_type::type>::bit_depth)!=1); + io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1); + std::vector::type, + layout::type> > > row(view.width()); + for (int y=0;y +struct tiff_read_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::tiff_read_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(int,bit_depth= + (detail::tiff_read_support_private::type, + typename color_space_type::type>::bit_depth)); + BOOST_STATIC_CONSTANT(int,color_type= + (detail::tiff_read_support_private::type, + typename color_space_type::type>::color_type)); +}; + +/// \ingroup TIFF_IO +/// \brief Returns the width and height of the TIFF file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file +inline point2 tiff_read_dimensions(const char* filename) { + detail::tiff_reader m(filename); + return m.get_dimensions(); +} + +/// \ingroup TIFF_IO +/// \brief Returns the width and height of the TIFF file at the specified location. +/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file +inline point2 tiff_read_dimensions(const std::string& filename) { + return tiff_read_dimensions(filename.c_str()); +} + +/// \ingroup TIFF_IO +/// \brief Loads the image specified by the given tiff image file name into the given view. +/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not +/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view. +template +inline void tiff_read_view(const char* filename,const View& view) { + BOOST_STATIC_ASSERT(tiff_read_support::is_supported); + detail::tiff_reader m(filename); + m.apply(view); +} + +/// \ingroup TIFF_IO +/// \brief Loads the image specified by the given tiff image file name into the given view. +template +inline void tiff_read_view(const std::string& filename,const View& view) { + tiff_read_view(filename.c_str(),view); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it. +/// Triggers a compile assert if the image color space or channel depth are not supported by the TIFF library or by the I/O extension. +/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not +/// compatible with the ones specified by Image +template +void tiff_read_image(const char* filename,Image& im) { + BOOST_STATIC_ASSERT(tiff_read_support::is_supported); + detail::tiff_reader m(filename); + m.read_image(im); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it. +template +inline void tiff_read_image(const std::string& filename,Image& im) { + tiff_read_image(filename.c_str(),im); +} + +/// \ingroup TIFF_IO +/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. +/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view. +template +inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc) { + detail::tiff_reader_color_convert m(filename,cc); + m.apply(view); +} + +/// \ingroup TIFF_IO +/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. +/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view. +template +inline void tiff_read_and_convert_view(const char* filename,const View& view) { + detail::tiff_reader_color_convert m(filename,default_color_converter()); + m.apply(view); +} + +/// \ingroup TIFF_IO +/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. +template +inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc) { + tiff_read_and_convert_view(filename.c_str(),view,cc); +} + +/// \ingroup TIFF_IO +/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. +template +inline void tiff_read_and_convert_view(const std::string& filename,const View& view) { + tiff_read_and_convert_view(filename.c_str(),view); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid TIFF file +template +void tiff_read_and_convert_image(const char* filename,Image& im,CC cc) { + detail::tiff_reader_color_convert m(filename,cc); + m.read_image(im); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it. +/// Throws std::ios_base::failure if the file is not a valid TIFF file +template +void tiff_read_and_convert_image(const char* filename,Image& im) { + detail::tiff_reader_color_convert m(filename,default_color_converter()); + m.read_image(im); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it. +template +inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc) { + tiff_read_and_convert_image(filename.c_str(),im,cc); +} + +/// \ingroup TIFF_IO +/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it. +template +inline void tiff_read_and_convert_image(const std::string& filename,Image& im) { + tiff_read_and_convert_image(filename.c_str(),im); +} + +/// \ingroup TIFF_IO +/// \brief Determines whether the given view type is supported for writing +template +struct tiff_write_support { + BOOST_STATIC_CONSTANT(bool,is_supported= + (detail::tiff_write_support_private::type, + typename color_space_type::type>::is_supported)); + BOOST_STATIC_CONSTANT(int,bit_depth= + (detail::tiff_write_support_private::type, + typename color_space_type::type>::bit_depth)); + BOOST_STATIC_CONSTANT(int,color_type= + (detail::tiff_write_support_private::type, + typename color_space_type::type>::color_type)); + BOOST_STATIC_CONSTANT(bool, value=is_supported); +}; + +/// \ingroup TIFF_IO +/// \brief Saves the view to a tiff file specified by the given tiff image file name. +/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension. +/// Throws std::ios_base::failure if it fails to create the file. +template +inline void tiff_write_view(const char* filename,const View& view) { + BOOST_STATIC_ASSERT(tiff_write_support::is_supported); + detail::tiff_writer m(filename); + m.apply(view); +} + +/// \ingroup TIFF_IO +/// \brief Saves the view to a tiff file specified by the given tiff image file name. +template +inline void tiff_write_view(const std::string& filename,const View& view) { + tiff_write_view(filename.c_str(),view); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/gil_all.hpp b/thirdparty/boost/gil/gil_all.hpp new file mode 100644 index 0000000..cd336d7 --- /dev/null +++ b/thirdparty/boost/gil/gil_all.hpp @@ -0,0 +1,46 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_ALL_HPP +#define GIL_ALL_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Includes all GIL files for convenience +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "gil_config.hpp" +#include "channel_algorithm.hpp" +#include "algorithm.hpp" +#include "pixel.hpp" +#include "packed_pixel.hpp" +#include "planar_pixel_reference.hpp" +#include "planar_pixel_iterator.hpp" +#include "pixel_iterator_adaptor.hpp" +#include "step_iterator.hpp" +#include "iterator_from_2d.hpp" +#include "image.hpp" +#include "image_view_factory.hpp" +#include "typedefs.hpp" +#include "metafunctions.hpp" +#include "color_convert.hpp" +#include "device_n.hpp" +#include "virtual_locator.hpp" +#include "bit_aligned_pixel_iterator.hpp" +// Uncomment this line to help in porting your code from an older version of GIL +//#include "deprecated.hpp" + +#endif diff --git a/thirdparty/boost/gil/gil_concept.hpp b/thirdparty/boost/gil/gil_concept.hpp new file mode 100644 index 0000000..96a888d --- /dev/null +++ b/thirdparty/boost/gil/gil_concept.hpp @@ -0,0 +1,2187 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_CONCEPT_H +#define GIL_CONCEPT_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Concept check classes for GIL concepts +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include +#include +#include +#include +#include +#include + +namespace boost { namespace gil { +template struct channel_traits; +template struct is_pixel; +template +typename channel_traits::value_type channel_convert(srcT val); +template class point2; +template const T& axis_value(const point2& p); +template T& axis_value( point2& p); +template struct kth_element_type; +template struct kth_element_reference_type; +template struct kth_element_const_reference_type; +template struct kth_semantic_element_reference_type; +template struct kth_semantic_element_const_reference_type; +template struct size; +template struct element_type; +template struct channel_type; +template struct color_space_type; +template struct channel_mapping_type; +template struct is_planar; +template struct num_channels; + +template struct const_iterator_type; +template struct iterator_is_mutable; +template struct is_iterator_adaptor; +template struct iterator_adaptor_rebind; +template struct iterator_adaptor_get_base; + + +// forward-declare at_c +namespace detail { template struct homogeneous_color_base; } +template +typename add_reference::type at_c( detail::homogeneous_color_base& p); + +template +typename add_reference::type>::type at_c(const detail::homogeneous_color_base& p); + +#if !defined(_MSC_VER) || _MSC_VER > 1310 +template struct packed_pixel; +template +typename kth_element_reference_type, K>::type +at_c(packed_pixel& p); + +template +typename kth_element_const_reference_type,K>::type +at_c(const packed_pixel& p); + +template struct bit_aligned_pixel_reference; + +template inline +typename kth_element_reference_type, K>::type +at_c(const bit_aligned_pixel_reference& p); +#endif + +// Forward-declare semantic_at_c +template +typename disable_if,typename kth_semantic_element_reference_type::type>::type semantic_at_c(ColorBase& p); +template +typename kth_semantic_element_const_reference_type::type semantic_at_c(const ColorBase& p); + +template struct dynamic_x_step_type; +template struct dynamic_y_step_type; +template struct transposed_type; + +namespace detail { +template +void initialize_it(T& x) {} +} // namespace detail + +template +struct remove_const_and_reference : public remove_const::type> {}; + +#ifdef BOOST_GIL_USE_CONCEPT_CHECK + #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept); + template void gil_function_requires() { function_requires(); } +#else + #define GIL_CLASS_REQUIRE(T,NS,C) + template void gil_function_requires() {} +#endif + +/// \ingroup BasicConcepts +/** +\code +auto concept DefaultConstructible { + T::T(); +}; +\endcode +*/ +template +struct DefaultConstructible { + void constraints() { + function_requires >(); + } +}; + +/// \ingroup BasicConcepts +/** +\codeauto concept CopyConstructible { + T::T(T); + T::~T(); +}; +\endcode +*/ +template +struct CopyConstructible { + void constraints() { + function_requires >(); + } +}; + +/// \ingroup BasicConcepts +/** +\code +auto concept Assignable { + typename result_type; + result_type operator=(T&, U); +}; +\endcode +*/ +template +struct Assignable { + void constraints() { + function_requires >(); + } +}; +/// \ingroup BasicConcepts +/** +\code +auto concept EqualityComparable { + bool operator==(T x, T y); + bool operator!=(T x, T y) { return !(x==y); } +}; +\endcode +*/ +template +struct EqualityComparable { + void constraints() { + function_requires >(); + } +}; + +/// \ingroup BasicConcepts +/** +\code +concept SameType;// unspecified +\endcode +*/ + +template +struct SameType { + void constraints() { + BOOST_STATIC_ASSERT((boost::is_same::value_core)); + } +}; + +/// \ingroup BasicConcepts +/** +\code +auto concept Swappable { + void swap(T&,T&); +}; +\endcode +*/ +template +struct Swappable { + void constraints() { + using std::swap; + swap(x,y); + } + T x,y; +}; + +/// \ingroup BasicConcepts +/** +\code +auto concept Regular : DefaultConstructible, CopyConstructible, EqualityComparable, + Assignable, Swappable {}; +\endcode +*/ + +template +struct Regular { + void constraints() { + gil_function_requires< boost::DefaultConstructibleConcept >(); + gil_function_requires< boost::CopyConstructibleConcept >(); + gil_function_requires< boost::EqualityComparableConcept >(); // ==, != + gil_function_requires< boost::AssignableConcept >(); + gil_function_requires< Swappable >(); + } +}; + +/// \ingroup BasicConcepts +/** +\code +auto concept Metafunction { + typename type; +}; +\endcode +*/ +template +struct Metafunction { + void constraints() { + typedef typename T::type type; + } +}; +//////////////////////////////////////////////////////////////////////////////////////// +// +// POINT CONCEPTS +// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \brief N-dimensional point concept +/// \ingroup PointConcept +/** +\code +concept PointNDConcept : Regular { + // the type of a coordinate along each axis + template struct axis; where Metafunction; + + const size_t num_dimensions; + + // accessor/modifier of the value of each axis. + template const typename axis::type& T::axis_value() const; + template typename axis::type& T::axis_value(); +}; +\endcode +*/ + +template +struct PointNDConcept { + void constraints() { + gil_function_requires< Regular

            >(); + + typedef typename P::value_type value_type; + static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N); + typedef typename P::template axis<0>::coord_t FT; + typedef typename P::template axis::coord_t LT; + FT ft=gil::axis_value<0>(point); + axis_value<0>(point)=ft; + LT lt=axis_value(point); + axis_value(point)=lt; + + value_type v=point[0]; ignore_unused_variable_warning(v); + point[0]=point[0]; + } + P point; +}; + +/// \brief 2-dimensional point concept +/// \ingroup PointConcept +/** +\code +concept Point2DConcept : PointNDConcept { + where num_dimensions == 2; + where SameType::type, axis<1>::type>; + + typename value_type = axis<0>::type; + + const value_type& operator[](const T&, size_t i); + value_type& operator[]( T&, size_t i); + + value_type x,y; +}; +\endcode +*/ + +template +struct Point2DConcept { + void constraints() { + gil_function_requires< PointNDConcept

            >(); + BOOST_STATIC_ASSERT(P::num_dimensions == 2); + point.x=point.y; + point[0]=point[1]; + } + P point; +}; + +//////////////////////////////////////////////////////////////////////////////////////// +// +// ITERATOR MUTABILITY CONCEPTS +// +// Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time +// +//////////////////////////////////////////////////////////////////////////////////////// + +namespace detail { + template // Preconditions: TT Models boost_concepts::ForwardTraversalConcept + struct ForwardIteratorIsMutableConcept { + void constraints() { + *i++ = *i; // require postincrement and assignment + } + TT i; + }; + + template // Preconditions: TT Models boost::BidirectionalIteratorConcept + struct BidirectionalIteratorIsMutableConcept { + void constraints() { + gil_function_requires< ForwardIteratorIsMutableConcept >(); + *i-- = *i; // require postdecrement and assignment + } + TT i; + }; + + template // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept + struct RandomAccessIteratorIsMutableConcept { + void constraints() { + gil_function_requires< BidirectionalIteratorIsMutableConcept >(); + typename std::iterator_traits::difference_type n=0; ignore_unused_variable_warning(n); + i[n] = *i; // require element access and assignment + } + TT i; + }; +} // namespace detail + +//////////////////////////////////////////////////////////////////////////////////////// +// +// COLOR SPACE CONCEPTS +// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \brief Color space type concept +/// \ingroup ColorSpaceAndLayoutConcept +/** +\code +concept ColorSpaceConcept { + // An MPL Random Access Sequence, whose elements are color tags +}; +\endcode +*/ +template +struct ColorSpaceConcept { + void constraints() { + // An MPL Random Access Sequence, whose elements are color tags + } +}; + +template // Models ColorSpaceConcept +struct color_spaces_are_compatible : public is_same {}; + +/// \brief Two color spaces are compatible if they are the same +/// \ingroup ColorSpaceAndLayoutConcept +/** +\code +concept ColorSpacesCompatibleConcept { + where SameType; +}; +\endcode +*/ +template +struct ColorSpacesCompatibleConcept { + void constraints() { + BOOST_STATIC_ASSERT((color_spaces_are_compatible::value)); + } +}; + +/// \brief Channel mapping concept +/// \ingroup ColorSpaceAndLayoutConcept +/** +\code +concept ChannelMappingConcept { + // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation +}; +\endcode +*/ +template +struct ChannelMappingConcept { + void constraints() { + // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation + } +}; + + + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// Channel CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \ingroup ChannelConcept +/// \brief A channel is the building block of a color. Color is defined as a mixture of primary colors and a channel defines the degree to which each primary color is used in the mixture. +/** +For example, in the RGB color space, using 8-bit unsigned channels, the color red is defined as [255 0 0], which means maximum of Red, and no Green and Blue. + +Built-in scalar types, such as \p int and \p float, are valid GIL channels. In more complex scenarios, channels may be represented as bit ranges or even individual bits. +In such cases special classes are needed to represent the value and reference to a channel. + +Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges. + +\code +concept ChannelConcept : EqualityComparable { + typename value_type = T; // use channel_traits::value_type to access it + typename reference = T&; // use channel_traits::reference to access it + typename pointer = T*; // use channel_traits::pointer to access it + typename const_reference = const T&; // use channel_traits::const_reference to access it + typename const_pointer = const T*; // use channel_traits::const_pointer to access it + static const bool is_mutable; // use channel_traits::is_mutable to access it + + static T min_value(); // use channel_traits::min_value to access it + static T max_value(); // use channel_traits::min_value to access it +}; +\endcode +*/ +template +struct ChannelConcept { + void constraints() { + gil_function_requires< boost::EqualityComparableConcept >(); + + typedef typename channel_traits::value_type v; + typedef typename channel_traits::reference r; + typedef typename channel_traits::pointer p; + typedef typename channel_traits::const_reference cr; + typedef typename channel_traits::const_pointer cp; + + channel_traits::min_value(); + channel_traits::max_value(); + } + + T c; +}; + +namespace detail { + // Preconditions: T models ChannelConcept + template + struct ChannelIsMutableConcept { + void constraints() { + c=c; + using std::swap; + swap(c,c); + } + T c; + }; +} + +/// \brief A channel that allows for modifying its value +/// \ingroup ChannelConcept +/** +\code +concept MutableChannelConcept : Assignable, Swappable {}; +\endcode +*/ +template +struct MutableChannelConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \brief A channel that supports default construction. +/// \ingroup ChannelConcept +/** +\code +concept ChannelValueConcept : Regular {}; +\endcode +*/ +template +struct ChannelValueConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + + +/// \brief Predicate metafunction returning whether two channels are compatible +/// \ingroup ChannelAlgorithm +/// +/// Channels are considered compatible if their value types (ignoring constness and references) are the same. +/** +Example: + +\code +BOOST_STATIC_ASSERT((channels_are_compatible::value)); +\endcode +*/ +template // Models GIL Pixel +struct channels_are_compatible + : public is_same::value_type, typename channel_traits::value_type> {}; + +/// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same +/// \ingroup ChannelConcept +/** +\code +concept ChannelsCompatibleConcept { + where SameType; +}; +\endcode +*/ +template +struct ChannelsCompatibleConcept { + void constraints() { + BOOST_STATIC_ASSERT((channels_are_compatible::value)); + } +}; + +/// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels +/// +/// Convertibility is non-symmetric and implies that one channel can be converted to another. Conversion is explicit and often lossy operation. +/// \ingroup ChannelConcept +/** +\code +concept ChannelConvertibleConcept { + DstChannel channel_convert(const SrcChannel&); +}; +\endcode +*/ +template +struct ChannelConvertibleConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + dst=channel_convert(src); ignore_unused_variable_warning(dst); + } + SrcChannel src; + DstChannel dst; +}; + + + + + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// COLOR BASE CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \ingroup ColorBaseConcept +/// \brief A color base is a container of color elements (such as channels, channel references or channel pointers) +/** +The most common use of color base is in the implementation of a pixel, in which case the color +elements are channel values. The color base concept, however, can be used in other scenarios. For example, a planar pixel has channels that are not +contiguous in memory. Its reference is a proxy class that uses a color base whose elements are channel references. Its iterator uses a color base +whose elements are channel iterators. + +A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels). +There are two ways to index the elements of a color base: A physical index corresponds to the way they are ordered in memory, and +a semantic index corresponds to the way the elements are ordered in their color space. +For example, in the RGB color space the elements are ordered as {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element +in physical ordering is the blue element, whereas the first semantic element is the red one. +Models of \p ColorBaseConcept are required to provide the \p at_c(ColorBase) function, which allows for accessing the elements based on their +physical order. GIL provides a \p semantic_at_c(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns +the corresponding semantic element. + +\code +concept ColorBaseConcept : CopyConstructible, EqualityComparable { + // a GIL layout (the color space and element permutation) + typename layout_t; + + // The type of K-th element + template struct kth_element_type; where Metafunction; + + // The result of at_c + template struct kth_element_const_reference_type; where Metafunction; + + template kth_element_const_reference_type::type at_c(T); + + // Copy-constructible and equality comparable with other compatible color bases + template where { ColorBasesCompatibleConcept } + T::T(T2); + template where { ColorBasesCompatibleConcept } + bool operator==(const T&, const T2&); + template where { ColorBasesCompatibleConcept } + bool operator!=(const T&, const T2&); + +}; +\endcode +*/ + +template +struct ColorBaseConcept { + void constraints() { + gil_function_requires< CopyConstructible >(); + gil_function_requires< EqualityComparable >(); + + typedef typename ColorBase::layout_t::color_space_t color_space_t; + gil_function_requires >(); + + typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t; + // TODO: channel_mapping_t must be an MPL RandomAccessSequence + + static const std::size_t num_elements = size::value; + + typedef typename kth_element_type::type TN; + typedef typename kth_element_const_reference_type::type CR; + +#if !defined(_MSC_VER) || _MSC_VER > 1310 + CR cr=at_c(cb); ignore_unused_variable_warning(cr); +#endif + + // functions that work for every pixel (no need to require them) + semantic_at_c<0>(cb); + semantic_at_c(cb); + // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform() + } + + ColorBase cb; +}; + +/// \ingroup ColorBaseConcept +/// \brief Color base which allows for modifying its elements +/** + +\code +concept MutableColorBaseConcept : Assignable, Swappable { + template struct kth_element_reference_type; where Metafunction; + + template kth_element_reference_type::type>::type at_c(T); + + template where { ColorBasesCompatibleConcept } + T& operator=(T&, const T2&); +}; +\endcode +*/ +template +struct MutableColorBaseConcept { + void constraints() { + gil_function_requires< ColorBaseConcept >(); + gil_function_requires< Assignable >(); + gil_function_requires< Swappable >(); + + typedef typename kth_element_reference_type::type CR; + +#if !defined(_MSC_VER) || _MSC_VER > 1310 + CR r=at_c<0>(cb); + at_c<0>(cb)=r; +#endif + } + + ColorBase cb; +}; + +/// \ingroup ColorBaseConcept +/// \brief Color base that also has a default-constructor. Refines Regular +/** +\code +concept ColorBaseValueConcept : MutableColorBaseConcept, Regular { +}; +\endcode +*/ +template +struct ColorBaseValueConcept { + void constraints() { + gil_function_requires< MutableColorBaseConcept >(); + gil_function_requires< Regular >(); + } +}; + +/// \ingroup ColorBaseConcept +/// \brief Color base whose elements all have the same type +/** +\code +concept HomogeneousColorBaseConcept { + // For all K in [0 ... size::value-1): + // where SameType::type, kth_element_type::type>; + kth_element_const_reference_type::type dynamic_at_c(const CB&, std::size_t n) const; +}; +\endcode +*/ + +template +struct HomogeneousColorBaseConcept { + void constraints() { + gil_function_requires< ColorBaseConcept >(); + + static const std::size_t num_elements = size::value; + + typedef typename kth_element_type::type T0; + typedef typename kth_element_type::type TN; + + BOOST_STATIC_ASSERT((is_same::value)); // better than nothing + typedef typename kth_element_const_reference_type::type CR0; + CR0 e0=dynamic_at_c(cb,0); + } + ColorBase cb; +}; + +/// \ingroup ColorBaseConcept +/// \brief Homogeneous color base that allows for modifying its elements +/** + +\code +concept MutableHomogeneousColorBaseConcept : HomogeneousColorBaseConcept { + kth_element_reference_type::type dynamic_at_c(CB&, std::size_t n); +}; +\endcode +*/ + +template +struct MutableHomogeneousColorBaseConcept { + void constraints() { + gil_function_requires< ColorBaseConcept >(); + gil_function_requires< HomogeneousColorBaseConcept >(); + typedef typename kth_element_reference_type::type R0; + R0 x=dynamic_at_c(cb,0); + dynamic_at_c(cb,0) = dynamic_at_c(cb,0); + } + ColorBase cb; +}; + +/// \ingroup ColorBaseConcept +/// \brief Homogeneous color base that also has a default constructor. Refines Regular. +/** + +\code +concept HomogeneousColorBaseValueConcept : MutableHomogeneousColorBaseConcept, Regular { +}; +\endcode +*/ + +template +struct HomogeneousColorBaseValueConcept { + void constraints() { + gil_function_requires< MutableHomogeneousColorBaseConcept >(); + gil_function_requires< Regular >(); + } +}; + + +/// \ingroup ColorBaseConcept +/// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise. +/** + +\code +concept ColorBasesCompatibleConcept { + where SameType; + // also, for all K in [0 ... size::value): + // where Convertible::type, kth_semantic_element_type::type>; + // where Convertible::type, kth_semantic_element_type::type>; +}; +\endcode +*/ +template +struct ColorBasesCompatibleConcept { + void constraints() { + BOOST_STATIC_ASSERT((is_same::value)); +// typedef typename kth_semantic_element_type::type e1; +// typedef typename kth_semantic_element_type::type e2; +// "e1 is convertible to e2" + } +}; + + + + + + + + + + + + + + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// PIXEL CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \brief Concept for all pixel-based GIL constructs, such as pixels, iterators, locators, views and images whose value type is a pixel +/// \ingroup PixelBasedConcept +/** +\code +concept PixelBasedConcept { + typename color_space_type; + where Metafunction >; + where ColorSpaceConcept::type>; + typename channel_mapping_type; + where Metafunction >; + where ChannelMappingConcept::type>; + typename is_planar; + where Metafunction >; + where SameType::type, bool>; +}; +\endcode +*/ +template +struct PixelBasedConcept { + void constraints() { + typedef typename color_space_type

            ::type color_space_t; + gil_function_requires >(); + typedef typename channel_mapping_type

            ::type channel_mapping_t; + gil_function_requires >(); + + static const bool planar = is_planar

            ::type::value; ignore_unused_variable_warning(planar); + + + // This is not part of the concept, but should still work + static const std::size_t nc = num_channels

            ::value; + ignore_unused_variable_warning(nc); + } +}; + +/// \brief Concept for homogeneous pixel-based GIL constructs +/// \ingroup PixelBasedConcept +/** +\code +concept HomogeneousPixelBasedConcept { + typename channel_type; + where Metafunction >; + where ChannelConcept::type>; +}; +\endcode +*/ +template +struct HomogeneousPixelBasedConcept { + void constraints() { + gil_function_requires >(); + typedef typename channel_type

            ::type channel_t; + gil_function_requires >(); + } +}; + + +/// \brief Pixel concept - A color base whose elements are channels +/// \ingroup PixelConcept +/** +\code +concept PixelConcept : ColorBaseConcept

            , PixelBasedConcept

            { + where is_pixel

            ::type::value==true; + // where for each K [0..size

            ::value-1]: + // ChannelConcept >; + + typename P::value_type; where PixelValueConcept; + typename P::reference; where PixelConcept; + typename P::const_reference; where PixelConcept; + static const bool P::is_mutable; + + template where { PixelConcept } + P::P(P2); + template where { PixelConcept } + bool operator==(const P&, const P2&); + template where { PixelConcept } + bool operator!=(const P&, const P2&); +}; +\endcode +*/ + +template +struct PixelConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + + BOOST_STATIC_ASSERT((is_pixel

            ::value)); + static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable); + + typedef typename P::value_type value_type; +// gil_function_requires >(); + + typedef typename P::reference reference; + gil_function_requires::type> >(); + + typedef typename P::const_reference const_reference; + gil_function_requires::type> >(); + } +}; + + +/// \brief Pixel concept that allows for changing its channels +/// \ingroup PixelConcept +/** +\code +concept MutablePixelConcept : MutableColorBaseConcept

            { + where is_mutable==true; +}; +\endcode +*/ +template +struct MutablePixelConcept { + void constraints() { + gil_function_requires >(); + BOOST_STATIC_ASSERT(P::is_mutable); + } +}; +/// \brief Homogeneous pixel concept +/// \ingroup PixelConcept +/** +\code +concept HomogeneousPixelConcept : HomogeneousColorBaseConcept

            , HomogeneousPixelBasedConcept

            { + P::template element_const_reference_type

            ::type operator[](P p, std::size_t i) const { return dynamic_at_c(p,i); } +}; +\endcode +*/ +template +struct HomogeneousPixelConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + gil_function_requires >(); + p[0]; + } + P p; +}; + +/// \brief Homogeneous pixel concept that allows for changing its channels +/// \ingroup PixelConcept +/** +\code +concept MutableHomogeneousPixelConcept : MutableHomogeneousColorBaseConcept

            { + P::template element_reference_type

            ::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); } +}; +\endcode +*/ +template +struct MutableHomogeneousPixelConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + p[0]=p[0]; + } + P p; +}; + +/// \brief Pixel concept that is a Regular type +/// \ingroup PixelConcept +/** +\code +concept PixelValueConcept : Regular

            { + where SameType; +}; +\endcode +*/ +template +struct PixelValueConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \brief Homogeneous pixel concept that is a Regular type +/// \ingroup PixelConcept +/** +\code +concept HomogeneousPixelValueConcept : Regular

            { + where SameType; +}; +\endcode +*/ +template +struct HomogeneousPixelValueConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + BOOST_STATIC_ASSERT((is_same::value)); + } +}; + +namespace detail { + template + struct channels_are_pairwise_compatible : public + mpl::and_, + channels_are_compatible::type, + typename kth_semantic_element_reference_type::type> > {}; + + template + struct channels_are_pairwise_compatible : public mpl::true_ {}; +} + +/// \brief Returns whether two pixels are compatible +/// +/// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another. +/// \ingroup PixelAlgorithm +template // Models GIL Pixel +struct pixels_are_compatible + : public mpl::and_::type, + typename color_space_type::type>::type, + detail::channels_are_pairwise_compatible::value-1> > {}; + +/// \brief Concept for pixel compatibility +/// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another. +/// \ingroup PixelConcept +/** +\code +concept PixelsCompatibleConcept : ColorBasesCompatibleConcept { + // where for each K [0..size::value): + // ChannelsCompatibleConcept::type, kth_semantic_element_type::type>; +}; +\endcode +*/ +template // precondition: P1 and P2 model PixelConcept +struct PixelsCompatibleConcept { + void constraints() { + BOOST_STATIC_ASSERT((pixels_are_compatible::value)); + } +}; + +/// \brief Pixel convertible concept +/// +/// Convertibility is non-symmetric and implies that one pixel can be converted to another, approximating the color. Conversion is explicit and sometimes lossy. +/// \ingroup PixelConcept +/** +\code +template +concept PixelConvertibleConcept { + void color_convert(const SrcPixel&, DstPixel&); +}; +\endcode +*/ +template +struct PixelConvertibleConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + color_convert(src,dst); + } + SrcP src; + DstP dst; +}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// DEREFERENCE ADAPTOR CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \ingroup PixelDereferenceAdaptorConcept + +/// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator. +/// +/// This can perform an arbitrary computation, such as color conversion or table lookup +/** +\code +concept PixelDereferenceAdaptorConcept + : DefaultConstructibleConcept, CopyConstructibleConcept, AssignableConcept { + typename const_t; where PixelDereferenceAdaptorConcept; + typename value_type; where PixelValueConcept; + typename reference; // may be mutable + typename const_reference; // must not be mutable + static const bool D::is_mutable; + + where Convertible; +}; +\endcode +*/ + +template +struct PixelDereferenceAdaptorConcept { + void constraints() { + gil_function_requires< boost::UnaryFunctionConcept::type, + typename D::argument_type> >(); + gil_function_requires< boost::DefaultConstructibleConcept >(); + gil_function_requires< boost::CopyConstructibleConcept >(); + gil_function_requires< boost::AssignableConcept >(); + + gil_function_requires::type> >(); + + typedef typename D::const_t const_t; + gil_function_requires >(); + typedef typename D::value_type value_type; + gil_function_requires >(); + typedef typename D::reference reference; // == PixelConcept (if you remove const and reference) + typedef typename D::const_reference const_reference; // == PixelConcept (if you remove const and reference) + + const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable); + } + D d; +}; + +template +struct PixelDereferenceAdaptorArchetype : public std::unary_function { + typedef PixelDereferenceAdaptorArchetype const_t; + typedef typename remove_reference

            ::type value_type; + typedef typename add_reference

            ::type reference; + typedef reference const_reference; + static const bool is_mutable=false; + P operator()(P x) const { throw; } +}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// Pixel ITERATOR CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \brief Concept for iterators, locators and views that can define a type just like the given iterator/locator/view, except it supports runtime specified step along the X navigation +/// \ingroup PixelIteratorConcept +/** +\code +concept HasDynamicXStepTypeConcept { + typename dynamic_x_step_type; + where Metafunction >; +}; +\endcode +*/ +template +struct HasDynamicXStepTypeConcept { + void constraints() { + typedef typename dynamic_x_step_type::type type; + } +}; + +/// \brief Concept for locators and views that can define a type just like the given locator or view, except it supports runtime specified step along the Y navigation +/// \ingroup PixelLocatorConcept +/** +\code +concept HasDynamicYStepTypeConcept { + typename dynamic_y_step_type; + where Metafunction >; +}; +\endcode +*/ +template +struct HasDynamicYStepTypeConcept { + void constraints() { + typedef typename dynamic_y_step_type::type type; + } +}; + + +/// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped +/// \ingroup PixelLocatorConcept +/** +\code +concept HasTransposedTypeConcept { + typename transposed_type; + where Metafunction >; +}; +\endcode +*/ +template +struct HasTransposedTypeConcept { + void constraints() { + typedef typename transposed_type::type type; + } +}; + +/// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept +/// \ingroup PixelIteratorConcept +/// \brief STL iterator over pixels + +/// \ingroup PixelIteratorConceptPixelIterator +/// \brief An STL random access traversal iterator over a model of PixelConcept. +/** +GIL's iterators must also provide the following metafunctions: + - \p const_iterator_type: Returns a read-only equivalent of \p Iterator + - \p iterator_is_mutable: Returns whether the given iterator is read-only or mutable + - \p is_iterator_adaptor: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors. + + \code +concept PixelIteratorConcept : boost_concepts::RandomAccessTraversalConcept, PixelBasedConcept { + where PixelValueConcept; + typename const_iterator_type::type; + where PixelIteratorConcept::type>; + static const bool iterator_is_mutable::type::value; + static const bool is_iterator_adaptor::type::value; // is it an iterator adaptor +}; +\endcode +*/ +template +struct PixelIteratorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + + typedef typename std::iterator_traits::value_type value_type; + gil_function_requires >(); + + typedef typename const_iterator_type::type const_t; + static const bool is_mut = iterator_is_mutable::type::value; ignore_unused_variable_warning(is_mut); + + const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator + + check_base(typename is_iterator_adaptor::type()); + } + void check_base(mpl::false_) {} + void check_base(mpl::true_) { + typedef typename iterator_adaptor_get_base::type base_t; + gil_function_requires >(); + } + + Iterator it; +}; + +namespace detail { + template // Preconditions: Iterator Models PixelIteratorConcept + struct PixelIteratorIsMutableConcept { + void constraints() { + gil_function_requires >(); + typedef typename remove_reference::reference>::type ref; + typedef typename element_type::type channel_t; + gil_function_requires >(); + } + }; +} + +/// \brief Pixel iterator that allows for changing its pixel +/// \ingroup PixelIteratorConceptPixelIterator +/** +\code +concept MutablePixelIteratorConcept : MutableRandomAccessIteratorConcept {}; + +\endcode +*/ +template +struct MutablePixelIteratorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +namespace detail { + // Iterators that can be used as the base of memory_based_step_iterator require some additional functions + template // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept + struct RandomAccessIteratorIsMemoryBasedConcept { + void constraints() { + std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs); + it=memunit_advanced(it,3); + std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd); + memunit_advance(it,3); + // for performace you may also provide a customized implementation of memunit_advanced_ref + } + Iterator it; + }; +} + +/// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept +/// \ingroup PixelIteratorConcept +/// \brief Iterator that advances by a specified step + +/// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits) +/// \ingroup PixelIteratorConceptStepIterator +/** +\code +concept MemoryBasedIteratorConcept { + typename byte_to_memunit; where metafunction >; + std::ptrdiff_t memunit_step(const Iterator&); + std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&); + void memunit_advance(Iterator&, std::ptrdiff_t diff); + Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; } + Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); } +}; +\endcode +*/ +template +struct MemoryBasedIteratorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \brief Step iterator concept +/// +/// Step iterators are iterators that have a set_step method +/// \ingroup PixelIteratorConceptStepIterator +/** +\code +concept StepIteratorConcept { + template void Iterator::set_step(D step); +}; +\endcode +*/ +template +struct StepIteratorConcept { + void constraints() { + gil_function_requires >(); + it.set_step(0); + } + Iterator it; +}; + + +/// \brief Step iterator that allows for modifying its current value +/// +/// \ingroup PixelIteratorConceptStepIterator +/** +\code +concept MutableStepIteratorConcept : StepIteratorConcept {}; +\endcode +*/ +template +struct MutableStepIteratorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept +/// \ingroup PixelIteratorConcept +/// \brief Adaptor over another iterator + +/// \ingroup PixelIteratorConceptIteratorAdaptor +/// \brief Iterator adaptor is a forward iterator adapting another forward iterator. +/** +In addition to GIL iterator requirements, GIL iterator adaptors must provide the following metafunctions: + - \p is_iterator_adaptor: Returns \p mpl::true_ + - \p iterator_adaptor_get_base: Returns the base iterator type + - \p iterator_adaptor_rebind: Replaces the base iterator with the new one + +The adaptee can be obtained from the iterator via the "base()" method. + +\code +concept IteratorAdaptorConcept { + where SameType::type, mpl::true_>; + + typename iterator_adaptor_get_base; + where Metafunction >; + where boost_concepts::ForwardTraversalConcept::type>; + + typename another_iterator; + typename iterator_adaptor_rebind::type; + where boost_concepts::ForwardTraversalConcept; + where IteratorAdaptorConcept::type>; + + const iterator_adaptor_get_base::type& Iterator::base() const; +}; +\endcode +*/ +template +struct IteratorAdaptorConcept { + void constraints() { + gil_function_requires >(); + + typedef typename iterator_adaptor_get_base::type base_t; + gil_function_requires >(); + + BOOST_STATIC_ASSERT(is_iterator_adaptor::value); + typedef typename iterator_adaptor_rebind::type rebind_t; + + base_t base=it.base(); ignore_unused_variable_warning(base); + } + Iterator it; +}; + +/// \brief Iterator adaptor that is mutable +/// \ingroup PixelIteratorConceptIteratorAdaptor +/** +\code +concept MutableIteratorAdaptorConcept : IteratorAdaptorConcept {}; +\endcode +*/ +template +struct MutableIteratorAdaptorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// LOCATOR CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept +/// \ingroup PixelLocatorConcept +/// \brief N-dimensional locator + +/// \defgroup Locator2DConcept RandomAccess2DLocatorConcept +/// \ingroup PixelLocatorConcept +/// \brief 2-dimensional locator + +/// \defgroup PixelLocator2DConcept PixelLocatorConcept +/// \ingroup PixelLocatorConcept +/// \brief 2-dimensional locator over pixel data + +/// \ingroup LocatorNDConcept +/// \brief N-dimensional locator over immutable values +/** +\code +concept RandomAccessNDLocatorConcept { + typename value_type; // value over which the locator navigates + typename reference; // result of dereferencing + typename difference_type; where PointNDConcept; // return value of operator-. + typename const_t; // same as Loc, but operating over immutable values + typename cached_location_t; // type to store relative location (for efficient repeated access) + typename point_t = difference_type; + + static const size_t num_dimensions; // dimensionality of the locator + where num_dimensions = point_t::num_dimensions; + + // The difference_type and iterator type along each dimension. The iterators may only differ in + // difference_type. Their value_type must be the same as Loc::value_type + template struct axis { + typename coord_t = point_t::axis::coord_t; + typename iterator; where RandomAccessTraversalConcept; // iterator along D-th axis. + where iterator::value_type == value_type; + }; + + // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing + template struct add_deref { + typename type; where RandomAccessNDLocatorConcept; + static type make(const Loc& loc, const Deref& deref); + }; + + Loc& operator+=(Loc&, const difference_type&); + Loc& operator-=(Loc&, const difference_type&); + Loc operator+(const Loc&, const difference_type&); + Loc operator-(const Loc&, const difference_type&); + + reference operator*(const Loc&); + reference operator[](const Loc&, const difference_type&); + + // Storing relative location for faster repeated access and accessing it + cached_location_t Loc::cache_location(const difference_type&) const; + reference operator[](const Loc&,const cached_location_t&); + + // Accessing iterators along a given dimension at the current location or at a given offset + template axis::iterator& Loc::axis_iterator(); + template axis::iterator const& Loc::axis_iterator() const; + template axis::iterator Loc::axis_iterator(const difference_type&) const; +}; +\endcode +*/ +template +struct RandomAccessNDLocatorConcept { + void constraints() { + gil_function_requires< Regular >(); + + typedef typename Loc::value_type value_type; + typedef typename Loc::reference reference; // result of dereferencing + typedef typename Loc::difference_type difference_type; // result of operator-(pixel_locator, pixel_locator) + typedef typename Loc::cached_location_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access) + typedef typename Loc::const_t const_t; // same as this type, but over const values + typedef typename Loc::point_t point_t; // same as difference_type + static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N); + + typedef typename Loc::template axis<0>::iterator first_it_type; + typedef typename Loc::template axis::iterator last_it_type; + gil_function_requires >(); + gil_function_requires >(); + + // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator + gil_function_requires >(); + BOOST_STATIC_ASSERT(point_t::num_dimensions==N); + BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis<0>::coord_t>::value)); + BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis::coord_t>::value)); + + difference_type d; + loc+=d; + loc-=d; + loc=loc+d; + loc=loc-d; + reference r1=loc[d]; ignore_unused_variable_warning(r1); + reference r2=*loc; ignore_unused_variable_warning(r2); + cached_location_t cl=loc.cache_location(d); ignore_unused_variable_warning(cl); + reference r3=loc[d]; ignore_unused_variable_warning(r3); + + first_it_type fi=loc.template axis_iterator<0>(); + fi=loc.template axis_iterator<0>(d); + last_it_type li=loc.template axis_iterator(); + li=loc.template axis_iterator(d); + + typedef PixelDereferenceAdaptorArchetype deref_t; + typedef typename Loc::template add_deref::type dtype; + //gil_function_requires >(); // infinite recursion + } + Loc loc; +}; + +/// \ingroup Locator2DConcept +/// \brief 2-dimensional locator over immutable values +/** +\code +concept RandomAccess2DLocatorConcept { + where num_dimensions==2; + where Point2DConcept; + + typename x_iterator = axis<0>::iterator; + typename y_iterator = axis<1>::iterator; + typename x_coord_t = axis<0>::coord_t; + typename y_coord_t = axis<1>::coord_t; + + // Only available to locators that have dynamic step in Y + //Loc::Loc(const Loc& loc, y_coord_t); + + // Only available to locators that have dynamic step in X and Y + //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false); + + x_iterator& Loc::x(); + x_iterator const& Loc::x() const; + y_iterator& Loc::y(); + y_iterator const& Loc::y() const; + + x_iterator Loc::x_at(const difference_type&) const; + y_iterator Loc::y_at(const difference_type&) const; + Loc Loc::xy_at(const difference_type&) const; + + // x/y versions of all methods that can take difference type + x_iterator Loc::x_at(x_coord_t, y_coord_t) const; + y_iterator Loc::y_at(x_coord_t, y_coord_t) const; + Loc Loc::xy_at(x_coord_t, y_coord_t) const; + reference operator()(const Loc&, x_coord_t, y_coord_t); + cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const; + + bool Loc::is_1d_traversable(x_coord_t width) const; + y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const; +}; +\endcode +*/ +template +struct RandomAccess2DLocatorConcept { + void constraints() { + gil_function_requires >(); + BOOST_STATIC_ASSERT(Loc::num_dimensions==2); + + typedef typename dynamic_x_step_type::type dynamic_x_step_t; + typedef typename dynamic_y_step_type::type dynamic_y_step_t; + typedef typename transposed_type::type transposed_t; + + typedef typename Loc::cached_location_t cached_location_t; + gil_function_requires >(); + + typedef typename Loc::x_iterator x_iterator; + typedef typename Loc::y_iterator y_iterator; + typedef typename Loc::x_coord_t x_coord_t; + typedef typename Loc::y_coord_t y_coord_t; + + x_coord_t xd=0; ignore_unused_variable_warning(xd); + y_coord_t yd=0; ignore_unused_variable_warning(yd); + + typename Loc::difference_type d; + typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r); + + dynamic_x_step_t loc2(dynamic_x_step_t(), yd); + dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd); + + typedef typename dynamic_y_step_type::type>::type dynamic_xy_step_transposed_t; + dynamic_xy_step_transposed_t loc4(loc, xd,yd,true); + + bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous); + loc.y_distance_to(loc, xd); + + loc=loc.xy_at(d); + loc=loc.xy_at(xd,yd); + + x_iterator xit=loc.x_at(d); + xit=loc.x_at(xd,yd); + xit=loc.x(); + + y_iterator yit=loc.y_at(d); + yit=loc.y_at(xd,yd); + yit=loc.y(); + + cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl); + } + Loc loc; +}; + +/// \ingroup PixelLocator2DConcept +/// \brief GIL's 2-dimensional locator over immutable GIL pixels +/** +\code +concept PixelLocatorConcept { + where PixelValueConcept; + where PixelIteratorConcept; + where PixelIteratorConcept; + where x_coord_t == y_coord_t; + + typename coord_t = x_coord_t; +}; +\endcode +*/ +template +struct PixelLocatorConcept { + void constraints() { + gil_function_requires< RandomAccess2DLocatorConcept >(); + gil_function_requires< PixelIteratorConcept >(); + gil_function_requires< PixelIteratorConcept >(); + typedef typename Loc::coord_t coord_t; + BOOST_STATIC_ASSERT((is_same::value)); + } + Loc loc; +}; + +namespace detail { + template // preconditions: Loc Models RandomAccessNDLocatorConcept + struct RandomAccessNDLocatorIsMutableConcept { + void constraints() { + gil_function_requires::iterator> >(); + gil_function_requires::iterator> >(); + + typename Loc::difference_type d; initialize_it(d); + typename Loc::value_type v;initialize_it(v); + typename Loc::cached_location_t cl=loc.cache_location(d); + *loc=v; + loc[d]=v; + loc[cl]=v; + } + Loc loc; + }; + + template // preconditions: Loc Models RandomAccess2DLocatorConcept + struct RandomAccess2DLocatorIsMutableConcept { + void constraints() { + gil_function_requires >(); + typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd); + typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd); + typename Loc::value_type v; initialize_it(v); + loc(xd,yd)=v; + } + Loc loc; + }; +} + +/// \ingroup LocatorNDConcept +/// \brief N-dimensional locator over mutable pixels +/** +\code +concept MutableRandomAccessNDLocatorConcept { + where Mutable; +}; +\endcode +*/ +template +struct MutableRandomAccessNDLocatorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \ingroup Locator2DConcept +/// \brief 2-dimensional locator over mutable pixels +/** +\code +concept MutableRandomAccess2DLocatorConcept : MutableRandomAccessNDLocatorConcept {}; +\endcode +*/ +template +struct MutableRandomAccess2DLocatorConcept { + void constraints() { + gil_function_requires< RandomAccess2DLocatorConcept >(); + gil_function_requires >(); + } +}; + +/// \ingroup PixelLocator2DConcept +/// \brief GIL's 2-dimensional locator over mutable GIL pixels +/** +\code +concept MutablePixelLocatorConcept : MutableRandomAccess2DLocatorConcept {}; +\endcode +*/ +template +struct MutablePixelLocatorConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// IMAGE VIEW CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + +/// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept +/// \ingroup ImageViewConcept +/// \brief N-dimensional range + +/// \defgroup ImageView2DConcept ImageView2DConcept +/// \ingroup ImageViewConcept +/// \brief 2-dimensional range + +/// \defgroup PixelImageViewConcept ImageViewConcept +/// \ingroup ImageViewConcept +/// \brief 2-dimensional range over pixel data + +/// \ingroup ImageViewNDConcept +/// \brief N-dimensional view over immutable values +/** +\code +concept RandomAccessNDImageViewConcept { + typename value_type; + typename reference; // result of dereferencing + typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!) + typename const_t; where RandomAccessNDImageViewConcept; // same as View, but over immutable values + typename point_t; where PointNDConcept; // N-dimensional point + typename locator; where RandomAccessNDLocatorConcept; // N-dimensional locator. + typename iterator; where RandomAccessTraversalConcept; // 1-dimensional iterator over all values + typename reverse_iterator; where RandomAccessTraversalConcept; + typename size_type; // the return value of size() + + // Equivalent to RandomAccessNDLocatorConcept::axis + template struct axis { + typename coord_t = point_t::axis::coord_t; + typename iterator; where RandomAccessTraversalConcept; // iterator along D-th axis. + where SameType; + where SameType; + }; + + // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing + template struct add_deref { + typename type; where RandomAccessNDImageViewConcept; + static type make(const View& v, const Deref& deref); + }; + + static const size_t num_dimensions = point_t::num_dimensions; + + // Create from a locator at the top-left corner and dimensions + View::View(const locator&, const point_type&); + + size_type View::size() const; // total number of elements + reference operator[](View, const difference_type&) const; // 1-dimensional reference + iterator View::begin() const; + iterator View::end() const; + reverse_iterator View::rbegin() const; + reverse_iterator View::rend() const; + iterator View::at(const point_t&); + point_t View::dimensions() const; // number of elements along each dimension + bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values? + + // iterator along a given dimension starting at a given point + template View::axis::iterator View::axis_iterator(const point_t&) const; + + reference operator()(View,const point_t&) const; +}; +\endcode +*/ +template +struct RandomAccessNDImageViewConcept { + void constraints() { + gil_function_requires< Regular >(); + + typedef typename View::value_type value_type; + typedef typename View::reference reference; // result of dereferencing + typedef typename View::difference_type difference_type; // result of operator-(1d_iterator,1d_iterator) + typedef typename View::const_t const_t; // same as this type, but over const values + typedef typename View::point_t point_t; // N-dimensional point + typedef typename View::locator locator; // N-dimensional locator + typedef typename View::iterator iterator; + typedef typename View::reverse_iterator reverse_iterator; + typedef typename View::size_type size_type; + static const std::size_t N=View::num_dimensions; + + gil_function_requires >(); + gil_function_requires >(); + gil_function_requires >(); + + typedef typename View::template axis<0>::iterator first_it_type; + typedef typename View::template axis::iterator last_it_type; + gil_function_requires >(); + gil_function_requires >(); + +// BOOST_STATIC_ASSERT((typename std::iterator_traits::difference_type, typename point_t::template axis<0>::coord_t>::value)); +// BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis::coord_t>::value)); + + // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator + gil_function_requires >(); + BOOST_STATIC_ASSERT(point_t::num_dimensions==N); + BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis<0>::coord_t>::value)); + BOOST_STATIC_ASSERT((is_same::difference_type, typename point_t::template axis::coord_t>::value)); + + point_t p; + locator lc; + iterator it; + reverse_iterator rit; + difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d); + + View(p,lc); // view must be constructible from a locator and a point + + p=view.dimensions(); + lc=view.pixels(); + size_type sz=view.size(); ignore_unused_variable_warning(sz); + bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous); + + it=view.begin(); + it=view.end(); + rit=view.rbegin(); + rit=view.rend(); + + reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access + reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access + + // get 1-D iterator of any dimension at a given pixel location + first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi); + last_it_type li=view.template axis_iterator(p); ignore_unused_variable_warning(li); + + typedef PixelDereferenceAdaptorArchetype deref_t; + typedef typename View::template add_deref::type dtype; + } + View view; +}; + +/// \ingroup ImageView2DConcept +/// \brief 2-dimensional view over immutable values +/** +\code +concept RandomAccess2DImageViewConcept { + where num_dimensions==2; + + typename x_iterator = axis<0>::iterator; + typename y_iterator = axis<1>::iterator; + typename x_coord_t = axis<0>::coord_t; + typename y_coord_t = axis<1>::coord_t; + typename xy_locator = locator; + + x_coord_t View::width() const; + y_coord_t View::height() const; + + // X-navigation + x_iterator View::x_at(const point_t&) const; + x_iterator View::row_begin(y_coord_t) const; + x_iterator View::row_end (y_coord_t) const; + + // Y-navigation + y_iterator View::y_at(const point_t&) const; + y_iterator View::col_begin(x_coord_t) const; + y_iterator View::col_end (x_coord_t) const; + + // navigating in 2D + xy_locator View::xy_at(const point_t&) const; + + // (x,y) versions of all methods taking point_t + View::View(x_coord_t,y_coord_t,const locator&); + iterator View::at(x_coord_t,y_coord_t) const; + reference operator()(View,x_coord_t,y_coord_t) const; + xy_locator View::xy_at(x_coord_t,y_coord_t) const; + x_iterator View::x_at(x_coord_t,y_coord_t) const; + y_iterator View::y_at(x_coord_t,y_coord_t) const; +}; +\endcode +*/ +template +struct RandomAccess2DImageViewConcept { + void constraints() { + gil_function_requires >(); + BOOST_STATIC_ASSERT(View::num_dimensions==2); + + // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time + gil_function_requires >(); + + typedef typename dynamic_x_step_type::type dynamic_x_step_t; + typedef typename dynamic_y_step_type::type dynamic_y_step_t; + typedef typename transposed_type::type transposed_t; + + typedef typename View::x_iterator x_iterator; + typedef typename View::y_iterator y_iterator; + typedef typename View::x_coord_t x_coord_t; + typedef typename View::y_coord_t y_coord_t; + typedef typename View::xy_locator xy_locator; + + x_coord_t xd=0; ignore_unused_variable_warning(xd); + y_coord_t yd=0; ignore_unused_variable_warning(yd); + x_iterator xit; + y_iterator yit; + typename View::point_t d; + + View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator + + xy_locator lc=view.xy_at(xd,yd); + lc=view.xy_at(d); + + typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r); + xd=view.width(); + yd=view.height(); + + xit=view.x_at(d); + xit=view.x_at(xd,yd); + xit=view.row_begin(xd); + xit=view.row_end(xd); + + yit=view.y_at(d); + yit=view.y_at(xd,yd); + yit=view.col_begin(xd); + yit=view.col_end(xd); + } + View view; +}; + + +/// \ingroup PixelImageViewConcept +/// \brief GIL's 2-dimensional view over immutable GIL pixels +/** +\code +concept ImageViewConcept { + where PixelValueConcept; + where PixelIteratorConcept; + where PixelIteratorConcept; + where x_coord_t == y_coord_t; + + typename coord_t = x_coord_t; + + std::size_t View::num_channels() const; +}; +\endcode +*/ +template +struct ImageViewConcept { + void constraints() { + gil_function_requires >(); + + // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time + gil_function_requires >(); + + BOOST_STATIC_ASSERT((is_same::value)); + + typedef typename View::coord_t coord_t; // 1D difference type (same for all dimensions) + std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan); + } + View view; +}; + + +namespace detail { + template // Preconditions: View Models RandomAccessNDImageViewConcept + struct RandomAccessNDImageViewIsMutableConcept { + void constraints() { + gil_function_requires >(); + + gil_function_requires >(); + gil_function_requires >(); + gil_function_requires::iterator> >(); + gil_function_requires::iterator> >(); + + typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff); + typename View::point_t pt; + typename View::value_type v; initialize_it(v); + + view[diff]=v; + view(pt)=v; + } + View view; + }; + + template // preconditions: View Models RandomAccessNDImageViewConcept + struct RandomAccess2DImageViewIsMutableConcept { + void constraints() { + gil_function_requires >(); + typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd); + typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd); + typename View::value_type v; initialize_it(v); + view(xd,yd)=v; + } + View view; + }; + + template // preconditions: View Models ImageViewConcept + struct PixelImageViewIsMutableConcept { + void constraints() { + gil_function_requires >(); + } + }; +} + +/// \ingroup ImageViewNDConcept +/// \brief N-dimensional view over mutable values +/** +\code +concept MutableRandomAccessNDImageViewConcept { + where Mutable; +}; +\endcode +*/ +template +struct MutableRandomAccessNDImageViewConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \ingroup ImageView2DConcept +/// \brief 2-dimensional view over mutable values +/** +\code +concept MutableRandomAccess2DImageViewConcept : MutableRandomAccessNDImageViewConcept {}; +\endcode +*/ +template +struct MutableRandomAccess2DImageViewConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \ingroup PixelImageViewConcept +/// \brief GIL's 2-dimensional view over mutable GIL pixels +/** +\code +concept MutableImageViewConcept : MutableRandomAccess2DImageViewConcept {}; +\endcode +*/ +template +struct MutableImageViewConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + } +}; + +/// \brief Returns whether two views are compatible +/// +/// Views are compatible if their pixels are compatible. Compatible views can be assigned and copy constructed from one another. +template // Model ImageViewConcept +struct views_are_compatible : public pixels_are_compatible {}; + +/// \brief Views are compatible if they have the same color spaces and compatible channel values. Constness and layout are not important for compatibility +/// \ingroup ImageViewConcept +/** +\code +concept ViewsCompatibleConcept { + where PixelsCompatibleConcept; +}; +\endcode +*/ +template +struct ViewsCompatibleConcept { + void constraints() { + BOOST_STATIC_ASSERT((views_are_compatible::value)); + } +}; + + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// IMAGE CONCEPTS +/// +//////////////////////////////////////////////////////////////////////////////////////// + + +/// \ingroup ImageConcept +/// \brief N-dimensional container of values +/** +\code +concept RandomAccessNDImageConcept : Regular { + typename view_t; where MutableRandomAccessNDImageViewConcept; + typename const_view_t = view_t::const_t; + typename point_t = view_t::point_t; + typename value_type = view_t::value_type; + typename allocator_type; + + Img::Img(point_t dims, std::size_t alignment=1); + Img::Img(point_t dims, value_type fill_value, std::size_t alignment); + + void Img::recreate(point_t new_dims, std::size_t alignment=1); + void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment); + + const point_t& Img::dimensions() const; + const const_view_t& const_view(const Img&); + const view_t& view(Img&); +}; +\endcode +*/ +template +struct RandomAccessNDImageConcept { + void constraints() { + gil_function_requires >(); + + typedef typename Img::view_t view_t; + gil_function_requires >(); + + typedef typename Img::const_view_t const_view_t; + typedef typename Img::value_type pixel_t; + + typedef typename Img::point_t point_t; + gil_function_requires >(); + + const_view_t cv = const_view(img); ignore_unused_variable_warning(cv); + view_t v = view(img); ignore_unused_variable_warning(v); + + pixel_t fill_value; + point_t pt=img.dimensions(); + Img im1(pt); + Img im2(pt,1); + Img im3(pt,fill_value,1); + img.recreate(pt); + img.recreate(pt,1); + img.recreate(pt,fill_value,1); + } + Img img; +}; + + +/// \ingroup ImageConcept +/// \brief 2-dimensional container of values +/** +\code +concept RandomAccess2DImageConcept { + typename x_coord_t = const_view_t::x_coord_t; + typename y_coord_t = const_view_t::y_coord_t; + + Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=1); + Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment); + + x_coord_t Img::width() const; + y_coord_t Img::height() const; + + void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1); + void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment); +}; +\endcode +*/ +template +struct RandomAccess2DImageConcept { + void constraints() { + gil_function_requires >(); + typedef typename Img::x_coord_t x_coord_t; + typedef typename Img::y_coord_t y_coord_t; + typedef typename Img::value_type value_t; + + gil_function_requires >(); + + x_coord_t w=img.width(); + y_coord_t h=img.height(); + value_t fill_value; + Img im1(w,h); + Img im2(w,h,1); + Img im3(w,h,fill_value,1); + img.recreate(w,h); + img.recreate(w,h,1); + img.recreate(w,h,fill_value,1); + } + Img img; +}; + +/// \ingroup ImageConcept +/// \brief 2-dimensional image whose value type models PixelValueConcept +/** +\code +concept ImageConcept { + where MutableImageViewConcept; + typename coord_t = view_t::coord_t; +}; +\endcode +*/ +template +struct ImageConcept { + void constraints() { + gil_function_requires >(); + gil_function_requires >(); + typedef typename Img::coord_t coord_t; + BOOST_STATIC_ASSERT(num_channels::value == mpl::size::type>::value); + + BOOST_STATIC_ASSERT((is_same::value)); + BOOST_STATIC_ASSERT((is_same::value)); + } + Img img; +}; + + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/gil_config.hpp b/thirdparty/boost/gil/gil_config.hpp new file mode 100644 index 0000000..3922b52 --- /dev/null +++ b/thirdparty/boost/gil/gil_config.hpp @@ -0,0 +1,50 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_CONFIG_HPP +#define GIL_CONFIG_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief GIL configuration file +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include + +#define GIL_VERSION "2.1.2" + +#ifdef _DEBUG +# define GIL_FORCEINLINE inline +#else +#ifdef NDEBUG +#if defined(_MSC_VER) +# define GIL_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ > 3 +# define GIL_FORCEINLINE inline __attribute__ ((always_inline)) +#else +# define GIL_FORCEINLINE inline +#endif +#else +# define GIL_FORCEINLINE inline +#endif +#endif + +// Enable GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED if your platform supports dereferencing on non-word memory boundary. +// Enabling the flag results in performance improvement +#if !defined(__hpux) && !defined(sun) && !defined(__sun) && !defined(__osf__) + #define GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED +#endif + +#endif diff --git a/thirdparty/boost/gil/gray.hpp b/thirdparty/boost/gil/gray.hpp new file mode 100644 index 0000000..af32d29 --- /dev/null +++ b/thirdparty/boost/gil/gray.hpp @@ -0,0 +1,45 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_GRAY_H +#define GIL_GRAY_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for grayscale color space and variants +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on March 8, 2006 +//////////////////////////////////////////////////////////////////////////////////////// + +#include "gil_config.hpp" +#include "utilities.hpp" +#include +#include +#include + +namespace boost { namespace gil { + +/// \ingroup ColorNameModel +/// \brief Gray +struct gray_color_t {}; + +/// \ingroup ColorSpaceModel +typedef mpl::vector1 gray_t; + +/// \ingroup LayoutModel +typedef layout gray_layout_t; + +} } // namespace boost::gil + +#endif + diff --git a/thirdparty/boost/gil/image.hpp b/thirdparty/boost/gil/image.hpp new file mode 100644 index 0000000..7e72473 --- /dev/null +++ b/thirdparty/boost/gil/image.hpp @@ -0,0 +1,288 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_IMAGE_H +#define GIL_IMAGE_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Templated image +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "gil_config.hpp" +#include "image_view.hpp" +#include "metafunctions.hpp" +#include "algorithm.hpp" + +namespace boost { namespace gil { + +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable : 4244) // conversion from 'gil::image::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) +//#endif + +//////////////////////////////////////////////////////////////////////////////////////// +/// \ingroup ImageModel PixelBasedModel +/// \brief container interface over image view. Models ImageConcept, PixelBasedConcept +/// +/// A 2D container whose elements are pixels. It is templated over the pixel type, a boolean +/// indicating whether it should be planar, and an optional allocator. +/// +/// Note that its element type does not have to be a pixel. \p image can be instantiated with any Regular element, +/// in which case it models the weaker RandomAccess2DImageConcept and does not model PixelBasedConcept +/// +//////////////////////////////////////////////////////////////////////////////////////// + +template > +class image { +public: + typedef typename Alloc::template rebind::other allocator_type; + typedef typename view_type_from_pixel::type view_t; + typedef typename view_t::const_t const_view_t; + typedef typename view_t::point_t point_t; + typedef typename view_t::coord_t coord_t; + typedef typename view_t::value_type value_type; + typedef coord_t x_coord_t; + typedef coord_t y_coord_t; + + const point_t& dimensions() const { return _view.dimensions(); } + x_coord_t width() const { return _view.width(); } + y_coord_t height() const { return _view.height(); } + + explicit image(std::size_t alignment=0, + const Alloc alloc_in = Alloc()) : + _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {} + + // Create with dimensions and optional initial value and alignment + image(const point_t& dimensions, + std::size_t alignment=0, + const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { + allocate_and_default_construct(dimensions); + } + image(x_coord_t width, y_coord_t height, + std::size_t alignment=0, + const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { + allocate_and_default_construct(point_t(width,height)); + } + image(const point_t& dimensions, + const Pixel& p_in, + std::size_t alignment, + const Alloc alloc_in = Alloc()) : + _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { + allocate_and_fill(dimensions, p_in); + } + image(x_coord_t width, y_coord_t height, + const Pixel& p_in, + std::size_t alignment, + const Alloc alloc_in = Alloc()) : + _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { + allocate_and_fill(point_t(width,height),p_in); + } + + image(const image& img) : + _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) { + allocate_and_copy(img.dimensions(),img._view); + } + + template + image(const image& img) : + _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) { + allocate_and_copy(img.dimensions(),img._view); + } + image& operator=(const image& img) { + if (dimensions() == img.dimensions()) + copy_pixels(img._view,_view); + else { + image tmp(img); + swap(tmp); + } + return *this; + } + + template + image& operator=(const Img& img) { + if (dimensions() == img.dimensions()) + copy_pixels(img._view,_view); + else { + image tmp(img); + swap(tmp); + } + return *this; + } + + ~image() { + destruct_pixels(_view); + deallocate(_view.dimensions()); + } + + Alloc& allocator() { return _alloc; } + Alloc const& allocator() const { return _alloc; } + + void swap(image& img) { // required by MutableContainerConcept + using std::swap; + swap(_align_in_bytes, img._align_in_bytes); + swap(_memory, img._memory); + swap(_view, img._view); + swap(_alloc, img._alloc); + } + + void recreate(const point_t& dims, std::size_t alignment=0, const Alloc alloc_in = Alloc()) { + if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) { + image tmp(dims, alignment, alloc_in); + swap(tmp); + } + } + void recreate(x_coord_t width, y_coord_t height, std::size_t alignment=0, const Alloc alloc_in = Alloc()) { + recreate(point_t(width,height),alignment,alloc_in); + } + void recreate(const point_t& dims, + const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) { + if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) { + image tmp(dims, p_in, alignment, alloc_in); + swap(tmp); + } + } + void recreate(x_coord_t width, y_coord_t height, + const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) { + recreate(point_t(width,height),p_in,alignment,alloc_in); + } + + view_t _view; // contains pointer to the pixels, the image size and ways to navigate pixels +private: + unsigned char* _memory; + std::size_t _align_in_bytes; + allocator_type _alloc; + + void allocate_and_default_construct(const point_t& dimensions) { + try { + allocate_(dimensions,mpl::bool_()); + default_construct_pixels(_view); + } catch(...) { deallocate(dimensions); throw; } + } + + void allocate_and_fill(const point_t& dimensions, const Pixel& p_in) { + try { + allocate_(dimensions,mpl::bool_()); + uninitialized_fill_pixels(_view, p_in); + } catch(...) { deallocate(dimensions); throw; } + } + + template + void allocate_and_copy(const point_t& dimensions, const View& v) { + try { + allocate_(dimensions,mpl::bool_()); + uninitialized_copy_pixels(v,_view); + } catch(...) { deallocate(dimensions); throw; } + } + + void deallocate(const point_t& dimensions) { + if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions)); + } + + std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const { + std::size_t size_in_units = get_row_size_in_memunits(dimensions.x)*dimensions.y; + if (IsPlanar) + size_in_units = size_in_units*num_channels::value; + + // return the size rounded up to the nearest byte + return (size_in_units + byte_to_memunit::value - 1) / byte_to_memunit::value + + (_align_in_bytes>0 ? _align_in_bytes-1:0); // add extra padding in case we need to align the first image pixel + } + + std::size_t get_row_size_in_memunits(x_coord_t width) const { // number of units per row + std::size_t size_in_memunits = width*memunit_step(typename view_t::x_iterator()); + if (_align_in_bytes>0) { + std::size_t alignment_in_memunits=_align_in_bytes*byte_to_memunit::value; + return align(size_in_memunits, alignment_in_memunits); + } + return size_in_memunits; + } + + void allocate_(const point_t& dimensions, mpl::false_) { // if it throws and _memory!=0 the client must deallocate _memory + _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); + unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory; + _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),get_row_size_in_memunits(dimensions.x))); + } + + void allocate_(const point_t& dimensions, mpl::true_) { // if it throws and _memory!=0 the client must deallocate _memory + std::size_t row_size=get_row_size_in_memunits(dimensions.x); + std::size_t plane_size=row_size*dimensions.y; + _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); + unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory; + typename view_t::x_iterator first; + for (int i=0; i::value; ++i) { + dynamic_at_c(first,i) = (typename channel_type::type*)tmp; + memunit_advance(dynamic_at_c(first,i), plane_size*i); + } + _view=view_t(dimensions, typename view_t::locator(first, row_size)); + } +}; + +template +void swap(image& im1,image& im2) { + im1.swap(im2); +} + +template +bool operator==(const image& im1,const image& im2) { + if ((void*)(&im1)==(void*)(&im2)) return true; + if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false; + return equal_pixels(const_view(im1),const_view(im2)); +} +template +bool operator!=(const image& im1,const image& im2) {return !(im1==im2);} + +///@{ +/// \name view, const_view +/// \brief Get an image view from an image + +/// \ingroup ImageModel + +/// \brief Returns the non-constant-pixel view of an image +template inline +const typename image::view_t& view(image& img) { return img._view; } + +/// \brief Returns the constant-pixel view of an image +template inline +const typename image::const_view_t const_view(const image& img) { + return static_cast::const_view_t>(img._view); +} +///@} + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct channel_type > : public channel_type {}; + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public mpl::bool_ {}; + +//#ifdef _MSC_VER +//#pragma warning(pop) +//#endif + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/image_view.hpp b/thirdparty/boost/gil/image_view.hpp new file mode 100644 index 0000000..fb4e132 --- /dev/null +++ b/thirdparty/boost/gil/image_view.hpp @@ -0,0 +1,223 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_IMAGE_VIEW_H +#define GIL_IMAGE_VIEW_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief image view class +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "gil_config.hpp" +#include "iterator_from_2d.hpp" + +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable : 4244) // conversion from 'gil::image::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) +//#endif + +namespace boost { namespace gil { + +//////////////////////////////////////////////////////////////////////////////////////// +/// \class image_view +/// \ingroup ImageViewModel PixelBasedModel +/// \brief A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,PixelBasedConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept +/// +/// Image view consists of a pixel 2D locator (defining the mechanism for navigating in 2D) +/// and the image dimensions. +/// +/// Image views to images are what ranges are to STL containers. They are lightweight objects, +/// that don't own the pixels. It is the user's responsibility that the underlying data remains +/// valid for the lifetime of the image view. +/// +/// Similar to iterators and ranges, constness of views does not extend to constness of pixels. +/// A const \p image_view does not allow changing its location in memory (resizing, moving) but does +/// not prevent one from changing the pixels. The latter requires an image view whose value_type +/// is const. +/// +/// Images have interfaces consistent with STL 1D random access containers, so they can be used +/// directly in STL algorithms like: +/// \code +/// std::fill(img.begin(), img.end(), red_pixel); +/// \endcode +/// +/// In addition, horizontal, vertical and 2D random access iterators are provided. +/// +/// Note also that \p image_view does not require that its element type be a pixel. It could be +/// instantiated with a locator whose \p value_type models only \p Regular. In this case the image +/// view models the weaker RandomAccess2DImageViewConcept, and does not model PixelBasedConcept. +/// Many generic algorithms don't require the elements to be pixels. +/// +//////////////////////////////////////////////////////////////////////////////////////// +template // Models 2D Pixel Locator +class image_view { +public: + +// typedefs required by ConstRandomAccessNDImageViewConcept + static const std::size_t num_dimensions=2; + typedef typename Loc::value_type value_type; + typedef typename Loc::reference reference; // result of dereferencing + typedef typename Loc::coord_t coord_t; // 1D difference type (same for all dimensions) + typedef coord_t difference_type; // result of operator-(1d_iterator,1d_iterator) + typedef typename Loc::point_t point_t; + typedef Loc locator; + typedef image_view const_t; // same as this type, but over const values + template struct axis { + typedef typename Loc::template axis::coord_t coord_t; // difference_type along each dimension + typedef typename Loc::template axis::iterator iterator; // 1D iterator type along each dimension + }; + typedef iterator_from_2d iterator; // 1D iterator type for each pixel left-to-right inside top-to-bottom + typedef std::reverse_iterator reverse_iterator; + typedef std::size_t size_type; + +// typedefs required by ConstRandomAccess2DImageViewConcept + typedef locator xy_locator; + typedef typename xy_locator::x_iterator x_iterator; // pixel iterator along a row + typedef typename xy_locator::y_iterator y_iterator; // pixel iterator along a column + typedef typename xy_locator::x_coord_t x_coord_t; + typedef typename xy_locator::y_coord_t y_coord_t; + + template struct add_deref { + typedef image_view::type> type; + static type make(const image_view& iv, const Deref& d) { return type(iv.dimensions(), Loc::template add_deref::make(iv.pixels(),d)); } + }; + + image_view() : _dimensions(0,0) {} + template image_view(const View& iv) : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {} + + template image_view(const point_t& sz , const L2& loc) : _dimensions(sz), _pixels(loc) {} + template image_view(coord_t width, coord_t height, const L2& loc) : _dimensions(x_coord_t(width),y_coord_t(height)), _pixels(loc) {} + + template image_view& operator=(const View& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } + image_view& operator=(const image_view& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } + + template bool operator==(const View& v) const { return pixels()==v.pixels() && dimensions()==v.dimensions(); } + template bool operator!=(const View& v) const { return !(*this==v); } + + template friend void swap(image_view& x, image_view& y); + + const point_t& dimensions() const { return _dimensions; } + const locator& pixels() const { return _pixels; } + x_coord_t width() const { return dimensions().x; } + y_coord_t height() const { return dimensions().y; } + std::size_t num_channels() const { return gil::num_channels::value; } + bool is_1d_traversable() const { return _pixels.is_1d_traversable(width()); } + + //\{@ + /// \name 1D navigation + size_type size() const { return width()*height(); } + iterator begin() const { return iterator(_pixels,_dimensions.x); } + iterator end() const { return begin()+(difference_type)size(); } // potential performance problem! + reverse_iterator rbegin() const { return reverse_iterator(end()); } + reverse_iterator rend() const { return reverse_iterator(begin()); } + reference operator[](difference_type i) const { return begin()[i]; } // potential performance problem! + iterator at(difference_type i)const { return begin()+i; } + iterator at(const point_t& p) const { return begin()+p.y*width()+p.x; } + iterator at(x_coord_t x, y_coord_t y)const { return begin()+y*width()+x; } + + //\}@ + + //\{@ + /// \name 2-D navigation + reference operator()(const point_t& p) const { return _pixels(p.x,p.y); } + reference operator()(x_coord_t x, y_coord_t y)const { return _pixels(x,y); } + template typename axis::iterator axis_iterator(const point_t& p) const { return _pixels.axis_iterator(p); } + xy_locator xy_at(x_coord_t x, y_coord_t y) const { return _pixels+point_t(x_coord_t(x),y_coord_t(y)); } + locator xy_at(const point_t& p) const { return _pixels+p; } + //\}@ + + //\{@ + /// \name X navigation + x_iterator x_at(x_coord_t x, y_coord_t y) const { return _pixels.x_at(x,y); } + x_iterator x_at(const point_t& p) const { return _pixels.x_at(p); } + x_iterator row_begin(y_coord_t y) const { return x_at(0,y); } + x_iterator row_end(y_coord_t y) const { return x_at(width(),y); } + //\}@ + + //\{@ + /// \name Y navigation + y_iterator y_at(x_coord_t x, y_coord_t y) const { return xy_at(x,y).y(); } + y_iterator y_at(const point_t& p) const { return xy_at(p).y(); } + y_iterator col_begin(x_coord_t x) const { return y_at(x,0); } + y_iterator col_end(x_coord_t x) const { return y_at(x,height()); } + //\}@ + +private: + template friend class image_view; + + point_t _dimensions; + xy_locator _pixels; +}; + +template +inline void swap(image_view& x, image_view& y) { + using std::swap; + swap(x._dimensions,y._dimensions); + swap(x._pixels, y._pixels); // TODO: Extend further +} + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct channel_type > : public channel_type {}; + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public is_planar {}; + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef image_view::type> type; +}; + +///////////////////////////// +// HasDynamicYStepTypeConcept +///////////////////////////// + +template +struct dynamic_y_step_type > { + typedef image_view::type> type; +}; + +///////////////////////////// +// HasTransposedTypeConcept +///////////////////////////// + +template +struct transposed_type > { + typedef image_view::type> type; +}; + +} } // namespace boost::gil + +//#ifdef _MSC_VER +//#pragma warning(pop) +//#endif + +#endif diff --git a/thirdparty/boost/gil/image_view_factory.hpp b/thirdparty/boost/gil/image_view_factory.hpp new file mode 100644 index 0000000..e8e533a --- /dev/null +++ b/thirdparty/boost/gil/image_view_factory.hpp @@ -0,0 +1,537 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_IMAGE_VIEW_FACTORY_HPP +#define GIL_IMAGE_VIEW_FACTORY_HPP + +/*! +/// \file +/// \brief Methods for constructing image views from raw data or other image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on March 9, 2007 +/// Methods for creating shallow image views from raw pixel data or from other image views - +/// flipping horizontally or vertically, axis-aligned rotation, a subimage, subsampled +/// or n-th channel image view. Derived image views are shallow copies and are fast to construct. +*/ + +#include +#include +#include "gil_config.hpp" +#include "metafunctions.hpp" +#include "gray.hpp" +#include "color_convert.hpp" + +/// \defgroup ImageViewConstructors Image View From Raw Data +/// \ingroup ImageViewAlgorithm +/// \brief Methods for constructing image views from raw data and for getting raw data from views + +/// \defgroup ImageViewTransformations Image View Transformations +/// \ingroup ImageViewAlgorithm +/// \brief Methods for constructing one image view from another + +namespace boost { namespace gil { +struct default_color_converter; + +template struct dynamic_x_step_type; +template struct dynamic_y_step_type; +template struct transposed_type; + +/// \brief Returns the type of a view that has a dynamic step along both X and Y +/// \ingroup ImageViewTransformations +template +struct dynamic_xy_step_type : public dynamic_y_step_type::type> {}; + +/// \brief Returns the type of a transposed view that has a dynamic step along both X and Y +/// \ingroup ImageViewTransformations +template +struct dynamic_xy_step_transposed_type : public dynamic_xy_step_type::type> {}; + + +/// \ingroup ImageViewConstructors +/// \brief Constructing image views from raw interleaved pixel data +template +typename type_from_x_iterator::view_t +interleaved_view(std::size_t width, std::size_t height, + Iterator pixels, std::ptrdiff_t rowsize_in_bytes) { + typedef typename type_from_x_iterator::view_t RView; + return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes)); +} + +/// \ingroup ImageViewConstructors +/// \brief Constructing image views from raw interleaved pixel data +template +typename type_from_x_iterator::view_t +interleaved_view(point2 dim, + Iterator pixels, std::ptrdiff_t rowsize_in_bytes) { + typedef typename type_from_x_iterator::view_t RView; + return RView(dim, typename RView::locator(pixels, rowsize_in_bytes)); +} + +///////////////////////////// +// interleaved_view_get_raw_data, planar_view_get_raw_data - return pointers to the raw data (the channels) of a basic homogeneous view. +///////////////////////////// + +namespace detail { + template struct channel_pointer_type_impl; + + template struct channel_pointer_type_impl { + typedef typename channel_type::type* type; + }; + template struct channel_pointer_type_impl { + typedef const typename channel_type::type* type; + }; + + template struct channel_pointer_type + : public channel_pointer_type_impl::value> {}; +} // namespace detail + +/// \ingroup ImageViewConstructors +/// \brief Returns C pointer to the the channels of an interleaved homogeneous view. +template +typename detail::channel_pointer_type::type interleaved_view_get_raw_data(const HomogeneousView& view) { + BOOST_STATIC_ASSERT((!is_planar::value && view_is_basic::value)); + BOOST_STATIC_ASSERT((boost::is_pointer::value)); + + return &at_c<0>(view(0,0)); +} + +/// \ingroup ImageViewConstructors +/// \brief Returns C pointer to the the channels of a given color plane of a planar homogeneous view. +template +typename detail::channel_pointer_type::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) { + BOOST_STATIC_ASSERT((is_planar::value && view_is_basic::value)); + return dynamic_at_c(view.row_begin(0),plane_index); +} + + +/// \defgroup ImageViewTransformationsColorConvert color_converted_view +/// \ingroup ImageViewTransformations +/// \brief Color converted view of another view + +/// \ingroup ImageViewTransformationsColorConvert PixelDereferenceAdaptorModel +/// \brief Function object that given a source pixel, returns it converted to a given color space and channel depth. Models: PixelDereferenceAdaptorConcept +/// +/// Useful in constructing a color converted view over a given image view +template // const_reference to the source pixel and destination pixel value +class color_convert_deref_fn : public deref_base, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> { +private: + CC _cc; // color-converter +public: + color_convert_deref_fn() {} + color_convert_deref_fn(CC cc_in) : _cc(cc_in) {} + + DstP operator()(SrcConstRefP srcP) const { + DstP dstP; + _cc(srcP,dstP); + return dstP; + } +}; + +namespace detail { + // Add color converter upon dereferencing + template + struct _color_converted_view_type { + private: + typedef color_convert_deref_fn deref_t; + typedef typename SrcView::template add_deref add_ref_t; + public: + typedef typename add_ref_t::type type; + static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));} + }; + + // If the Src view has the same pixel type as the target, there is no need for color conversion + template + struct _color_converted_view_type { + typedef SrcView type; + static type make(const SrcView& sv,CC) {return sv;} + }; +} // namespace detail + + +/// \brief Returns the type of a view that does color conversion upon dereferencing its pixels +/// \ingroup ImageViewTransformationsColorConvert +template +struct color_converted_view_type : public detail::_color_converted_view_type { + GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)//why does it have to be mutable??? +}; + + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief view of a different color space with a user defined color-converter +template +inline typename color_converted_view_type::type color_converted_view(const View& src,CC cc) { + return color_converted_view_type::make(src,cc); +} + +/// \ingroup ImageViewTransformationsColorConvert +/// \brief overload of generic color_converted_view with the default color-converter +template +inline typename color_converted_view_type::type +color_converted_view(const View& src) { + return color_converted_view(src,default_color_converter()); +} + +/// \defgroup ImageViewTransformationsFlipUD flipped_up_down_view +/// \ingroup ImageViewTransformations +/// \brief view of a view flipped up-to-down + +/// \ingroup ImageViewTransformationsFlipUD +template +inline typename dynamic_y_step_type::type flipped_up_down_view(const View& src) { + typedef typename dynamic_y_step_type::type RView; + return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1)); +} + +/// \defgroup ImageViewTransformationsFlipLR flipped_left_right_view +/// \ingroup ImageViewTransformations +/// \brief view of a view flipped left-to-right + +/// \ingroup ImageViewTransformationsFlipLR +template +inline typename dynamic_x_step_type::type flipped_left_right_view(const View& src) { + typedef typename dynamic_x_step_type::type RView; + return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1)); +} + +/// \defgroup ImageViewTransformationsTransposed transposed_view +/// \ingroup ImageViewTransformations +/// \brief view of a view transposed + +/// \ingroup ImageViewTransformationsTransposed +template +inline typename dynamic_xy_step_transposed_type::type transposed_view(const View& src) { + typedef typename dynamic_xy_step_transposed_type::type RView; + return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true)); +} + +/// \defgroup ImageViewTransformations90CW rotated90cw_view +/// \ingroup ImageViewTransformations +/// \brief view of a view rotated 90 degrees clockwise + +/// \ingroup ImageViewTransformations90CW +template +inline typename dynamic_xy_step_transposed_type::type rotated90cw_view(const View& src) { + typedef typename dynamic_xy_step_transposed_type::type RView; + return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true)); +} + +/// \defgroup ImageViewTransformations90CCW rotated90ccw_view +/// \ingroup ImageViewTransformations +/// \brief view of a view rotated 90 degrees counter-clockwise + +/// \ingroup ImageViewTransformations90CCW +template +inline typename dynamic_xy_step_transposed_type::type rotated90ccw_view(const View& src) { + typedef typename dynamic_xy_step_transposed_type::type RView; + return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true)); +} + +/// \defgroup ImageViewTransformations180 rotated180_view +/// \ingroup ImageViewTransformations +/// \brief view of a view rotated 180 degrees + +/// \ingroup ImageViewTransformations180 +template +inline typename dynamic_xy_step_type::type rotated180_view(const View& src) { + typedef typename dynamic_xy_step_type::type RView; + return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1)); +} + +/// \defgroup ImageViewTransformationsSubimage subimage_view +/// \ingroup ImageViewTransformations +/// \brief view of an axis-aligned rectangular area within an image_view + +/// \ingroup ImageViewTransformationsSubimage +template +inline View subimage_view(const View& src, const typename View::point_t& topleft, const typename View::point_t& dimensions) { + return View(dimensions,src.xy_at(topleft)); +} + +/// \ingroup ImageViewTransformationsSubimage +template +inline View subimage_view(const View& src, int xMin, int yMin, int width, int height) { + return View(width,height,src.xy_at(xMin,yMin)); +} + +/// \defgroup ImageViewTransformationsSubsampled subsampled_view +/// \ingroup ImageViewTransformations +/// \brief view of a subsampled version of an image_view, stepping over a number of channels in X and number of rows in Y + +/// \ingroup ImageViewTransformationsSubsampled +template +inline typename dynamic_xy_step_type::type subsampled_view(const View& src, typename View::coord_t xStep, typename View::coord_t yStep) { + assert(xStep>0 && yStep>0); + typedef typename dynamic_xy_step_type::type RView; + return RView((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep, + typename RView::xy_locator(src.xy_at(0,0),xStep,yStep)); +} + +/// \ingroup ImageViewTransformationsSubsampled +template +inline typename dynamic_xy_step_type::type subsampled_view(const View& src, const typename View::point_t& step) { + return subsampled_view(src,step.x,step.y); +} + +/// \defgroup ImageViewTransformationsNthChannel nth_channel_view +/// \ingroup ImageViewTransformations +/// \brief single-channel (grayscale) view of the N-th channel of a given image_view + +namespace detail { + template struct __nth_channel_view_basic; + + // nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images + // or images with a step + template + struct __nth_channel_view_basic { + typedef typename view_type::type, gray_layout_t, false, true, view_is_mutable::value>::type type; + + static type make(const View& src, int n) { + typedef typename type::xy_locator locator_t; + typedef typename type::x_iterator x_iterator_t; + typedef typename iterator_adaptor_get_base::type x_iterator_base_t; + x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size()); + return type(src.dimensions(),locator_t(sit, src.pixels().row_size())); + } + }; + + // nth_channel_view when the channels are together in memory (true for simple grayscale or planar images) + template + struct __nth_channel_view_basic { + typedef typename view_type::type, gray_layout_t, false, false, view_is_mutable::value>::type type; + static type make(const View& src, int n) { + typedef typename type::x_iterator x_iterator_t; + return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size()); + } + }; + + template struct __nth_channel_view; + + // For basic (memory-based) views dispatch to __nth_channel_view_basic + template struct __nth_channel_view { + private: + typedef typename View::x_iterator src_x_iterator; + + // Determines whether the channels of a given pixel iterator are adjacent in memory. + // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not. + BOOST_STATIC_CONSTANT(bool, adjacent= + !iterator_is_step::value && + (is_planar::value || + num_channels::value==1)); + public: + typedef typename __nth_channel_view_basic::type type; + + static type make(const View& src, int n) { + return __nth_channel_view_basic::make(src,n); + } + }; + + /// \brief Function object that returns a grayscale reference of the N-th channel of a given reference. Models: PixelDereferenceAdaptorConcept. + /// \ingroup PixelDereferenceAdaptorModel + /// + /// If the input is a pixel value or constant reference, the function object is immutable. Otherwise it is mutable (and returns non-const reference to the n-th channel) + template // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference) + // Examples: pixel, pixel&, const pixel&, planar_pixel_reference, planar_pixel_reference + struct nth_channel_deref_fn { + BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference::value && pixel_reference_is_mutable::value); + private: + typedef typename remove_reference::type src_pixel_t; + typedef typename channel_type::type channel_t; + typedef typename src_pixel_t::const_reference const_ref_t; + typedef typename pixel_reference_type::type ref_t; + public: + typedef nth_channel_deref_fn const_t; + typedef typename pixel_value_type::type value_type; + typedef typename pixel_reference_type::type const_reference; + typedef SrcP argument_type; + typedef typename mpl::if_c::type reference; + typedef reference result_type; + + nth_channel_deref_fn(int n=0) : _n(n) {} + template nth_channel_deref_fn(const nth_channel_deref_fn

            & d) : _n(d._n) {} + + int _n; // the channel to use + + result_type operator()(argument_type srcP) const { + return result_type(srcP[_n]); + } + }; + + template struct __nth_channel_view { + private: + typedef nth_channel_deref_fn deref_t; + typedef typename View::template add_deref AD; + public: + typedef typename AD::type type; + static type make(const View& src, int n) { + return AD::make(src, deref_t(n)); + } + }; +} // namespace detail + +/// \brief Given a source image view type View, returns the type of an image view over a single channel of View +/// \ingroup ImageViewTransformationsNthChannel +/// +/// If the channels in the source view are adjacent in memory (such as planar non-step view or single-channel view) then the +/// return view is a single-channel non-step view. +/// If the channels are non-adjacent (interleaved and/or step view) then the return view is a single-channel step view. +template +struct nth_channel_view_type { +private: + GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept) + typedef detail::__nth_channel_view::value> VB; +public: + typedef typename VB::type type; + static type make(const View& src, int n) { return VB::make(src,n); } +}; + + +/// \ingroup ImageViewTransformationsNthChannel +template +typename nth_channel_view_type::type nth_channel_view(const View& src, int n) { + return nth_channel_view_type::make(src,n); +} + + + + + + + +/// \defgroup ImageViewTransformationsKthChannel kth_channel_view +/// \ingroup ImageViewTransformations +/// \brief single-channel (grayscale) view of the K-th channel of a given image_view. The channel index is a template parameter + +namespace detail { + template struct __kth_channel_view_basic; + + // kth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images + // or images with a step + template + struct __kth_channel_view_basic { + private: + typedef typename kth_element_type::type channel_t; + public: + typedef typename view_type::value>::type type; + + static type make(const View& src) { + typedef typename type::xy_locator locator_t; + typedef typename type::x_iterator x_iterator_t; + typedef typename iterator_adaptor_get_base::type x_iterator_base_t; + x_iterator_t sit(x_iterator_base_t(&at_c(src(0,0))),src.pixels().pixel_size()); + return type(src.dimensions(),locator_t(sit, src.pixels().row_size())); + } + }; + + // kth_channel_view when the channels are together in memory (true for simple grayscale or planar images) + template + struct __kth_channel_view_basic { + private: + typedef typename kth_element_type::type channel_t; + public: + typedef typename view_type::value>::type type; + static type make(const View& src) { + typedef typename type::x_iterator x_iterator_t; + return interleaved_view(src.width(),src.height(),(x_iterator_t)&at_c(src(0,0)), src.pixels().row_size()); + } + }; + + template struct __kth_channel_view; + + // For basic (memory-based) views dispatch to __kth_channel_view_basic + template struct __kth_channel_view { + private: + typedef typename View::x_iterator src_x_iterator; + + // Determines whether the channels of a given pixel iterator are adjacent in memory. + // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not. + BOOST_STATIC_CONSTANT(bool, adjacent= + !iterator_is_step::value && + (is_planar::value || + num_channels::value==1)); + public: + typedef typename __kth_channel_view_basic::type type; + + static type make(const View& src) { + return __kth_channel_view_basic::make(src); + } + }; + + /// \brief Function object that returns a grayscale reference of the K-th channel (specified as a template parameter) of a given reference. Models: PixelDereferenceAdaptorConcept. + /// \ingroup PixelDereferenceAdaptorModel + /// + /// If the input is a pixel value or constant reference, the function object is immutable. Otherwise it is mutable (and returns non-const reference to the k-th channel) + template // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference) + // Examples: pixel, pixel&, const pixel&, planar_pixel_reference, planar_pixel_reference + struct kth_channel_deref_fn { + BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference::value && pixel_reference_is_mutable::value); + private: + typedef typename remove_reference::type src_pixel_t; + typedef typename kth_element_type::type channel_t; + typedef typename src_pixel_t::const_reference const_ref_t; + typedef typename pixel_reference_type::type ref_t; + public: + typedef kth_channel_deref_fn const_t; + typedef typename pixel_value_type::type value_type; + typedef typename pixel_reference_type::type const_reference; + typedef SrcP argument_type; + typedef typename mpl::if_c::type reference; + typedef reference result_type; + + kth_channel_deref_fn() {} + template kth_channel_deref_fn(const kth_channel_deref_fn&) {} + + result_type operator()(argument_type srcP) const { + return result_type(at_c(srcP)); + } + }; + + template struct __kth_channel_view { + private: + typedef kth_channel_deref_fn deref_t; + typedef typename View::template add_deref AD; + public: + typedef typename AD::type type; + static type make(const View& src) { + return AD::make(src, deref_t()); + } + }; +} // namespace detail + +/// \brief Given a source image view type View, returns the type of an image view over a given channel of View. +/// \ingroup ImageViewTransformationsKthChannel +/// +/// If the channels in the source view are adjacent in memory (such as planar non-step view or single-channel view) then the +/// return view is a single-channel non-step view. +/// If the channels are non-adjacent (interleaved and/or step view) then the return view is a single-channel step view. +template +struct kth_channel_view_type { +private: + GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept) + typedef detail::__kth_channel_view::value> VB; +public: + typedef typename VB::type type; + static type make(const View& src) { return VB::make(src); } +}; + +/// \ingroup ImageViewTransformationsKthChannel +template +typename kth_channel_view_type::type kth_channel_view(const View& src) { + return kth_channel_view_type::make(src); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/iterator_from_2d.hpp b/thirdparty/boost/gil/iterator_from_2d.hpp new file mode 100644 index 0000000..cfb6344 --- /dev/null +++ b/thirdparty/boost/gil/iterator_from_2d.hpp @@ -0,0 +1,175 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_ITERATOR_FROM_2D_H +#define GIL_ITERATOR_FROM_2D_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel step iterator, pixel image iterator and pixel dereference iterator +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 18, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "gil_concept.hpp" +#include "gil_config.hpp" +#include "pixel_iterator.hpp" +#include "locator.hpp" + +namespace boost { namespace gil { + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// ITERATOR FROM 2D ADAPTOR +/// +//////////////////////////////////////////////////////////////////////////////////////// + + +/// \defgroup PixelIteratorModelFromLocator iterator_from_2d +/// \ingroup PixelIteratorModel +/// \brief An iterator over two-dimensional locator. Useful for iterating over the pixels of an image view. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept + + +/// \ingroup PixelIteratorModelFromLocator PixelBasedModel +/// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept +/// +/// Pixels are traversed from the top to the bottom row and from the left to the right +/// within each row + +template // Models PixelLocatorConcept +class iterator_from_2d : public iterator_facade, + typename Loc2::value_type, + random_access_traversal_tag, + typename Loc2::reference, + typename Loc2::coord_t> { + GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept) +public: + typedef iterator_facade, + typename Loc2::value_type, + random_access_traversal_tag, + typename Loc2::reference, + typename Loc2::coord_t> parent_t; + typedef typename parent_t::reference reference; + typedef typename parent_t::difference_type difference_type; + typedef typename Loc2::x_iterator x_iterator; + typedef typename Loc2::point_t point_t; + + std::ptrdiff_t width() const { return _width; } // number of pixels per image row + std::ptrdiff_t x_pos() const { return _coords.x; } // current x position + std::ptrdiff_t y_pos() const { return _coords.y; } // current y position + + /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { return *(*this+d); } + + bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row? + x_iterator& x() { return _p.x(); } + + iterator_from_2d(){} + iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {} + iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {} + template iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {} + +private: + template friend class iterator_from_2d; + friend class boost::iterator_core_access; + reference dereference() const { return *_p; } + void increment() { + ++_coords.x; + ++_p.x(); + if (_coords.x>=_width) { + _coords.x=0; + ++_coords.y; + _p+=point_t(-_width,1); + } + } + void decrement() { + --_coords.x; + --_p.x(); + if (_coords.x<0) { + _coords.x=_width-1; + --_coords.y; + _p+=point_t(_width,-1); + } + } + + GIL_FORCEINLINE void advance(difference_type d) { + if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed. + point_t delta; + if (_coords.x+d>=0) { // not going back to a previous row? + delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x; + delta.y=(_coords.x+(std::ptrdiff_t)d)/_width; + } else { + delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x; + delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width; + } + _p+=delta; + _coords.x+=delta.x; + _coords.y+=delta.y; + } + + difference_type distance_to(const iterator_from_2d& it) const { + if (_width==0) return 0; + return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x); + } + + bool equal(const iterator_from_2d& it) const { + assert(_width==it.width()); // they must belong to the same image + return _coords==it._coords && _p==it._p; + } + + point2 _coords; + std::ptrdiff_t _width; + Loc2 _p; +}; + +template // Models PixelLocatorConcept +struct const_iterator_type > { + typedef iterator_from_2d type; +}; + +template // Models PixelLocatorConcept +struct iterator_is_mutable > : public iterator_is_mutable {}; + + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef iterator_from_2d::type> type; +}; + + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template // Models PixelLocatorConcept +struct color_space_type > : public color_space_type {}; + +template // Models PixelLocatorConcept +struct channel_mapping_type > : public channel_mapping_type {}; + +template // Models PixelLocatorConcept +struct is_planar > : public is_planar {}; + +template // Models PixelLocatorConcept +struct channel_type > : public channel_type {}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/locator.hpp b/thirdparty/boost/gil/locator.hpp new file mode 100644 index 0000000..4132351 --- /dev/null +++ b/thirdparty/boost/gil/locator.hpp @@ -0,0 +1,362 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_LOCATOR_H +#define GIL_LOCATOR_H + + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel 2D locator +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n September 20, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "pixel_iterator.hpp" + +//////////////////////////////////////////////////////////////////////////////////////// +/// Pixel 2D LOCATOR +//////////////////////////////////////////////////////////////////////////////////////// + + +namespace boost { namespace gil { + +//forward declarations +template ptrdiff_t memunit_step(const P*); +template P* memunit_advanced(const P* p, ptrdiff_t diff); +template P& memunit_advanced_ref(P* p, ptrdiff_t diff); +template struct iterator_add_deref; +template class point2; +namespace detail { + // helper class specialized for each axis of pixel_2d_locator + template class locator_axis; +} +template struct dynamic_x_step_type; +template struct dynamic_y_step_type; + +template struct channel_type; +template struct color_space_type; +template struct channel_mapping_type; +template struct is_planar; +template struct num_channels; + +// The type of a locator or a view that has X and Y swapped. By default it is the same +template struct transposed_type { + typedef T type; +}; + +/// \class pixel_2d_locator_base +/// \brief base class for models of PixelLocatorConcept +/// \ingroup PixelLocatorModel PixelBasedModel +/// +/// Pixel locator is similar to a pixel iterator, but allows for 2D navigation of pixels within an image view. +/// It has a 2D difference_type and supports random access operations like: +/// \code +/// difference_type offset2(2,3); +/// locator+=offset2; +/// locator[offset2]=my_pixel; +/// \endcode +/// +/// In addition, each coordinate acts as a random-access iterator that can be modified separately: +/// "++locator.x()" or "locator.y()+=10" thereby moving the locator horizontally or vertically. +/// +/// It is called a locator because it doesn't implement the complete interface of a random access iterator. +/// For example, increment and decrement operations don't make sense (no way to specify dimension). +/// Also 2D difference between two locators cannot be computed without knowledge of the X position within the image. +/// +/// This base class provides most of the methods and typedefs needed to create a model of a locator. GIL provides two +/// locator models as subclasses of \p pixel_2d_locator_base. A memory-based locator, \p memory_based_2d_locator and a virtual +/// locator, \p virtual_2d_locator. +/// The minimum functionality a subclass must provide is this: +/// \code +/// class my_locator : public pixel_2d_locator_base { // supply the types for x-iterator and y-iterator +/// typedef ... const_t; // read-only locator +/// +/// template struct add_deref { +/// typedef ... type; // locator that invokes the Deref dereference object upon pixel access +/// static type make(const my_locator& loc, const Deref& d); +/// }; +/// +/// my_locator(); +/// my_locator(const my_locator& pl); +/// +/// // constructors with dynamic step in y (and x). Only valid for locators with dynamic steps +/// my_locator(const my_locator& loc, coord_t y_step); +/// my_locator(const my_locator& loc, coord_t x_step, coord_t y_step, bool transpose); +/// +/// bool operator==(const my_locator& p) const; +/// +/// // return _references_ to horizontal/vertical iterators. Advancing them moves this locator +/// x_iterator& x(); +/// y_iterator& y(); +/// x_iterator const& x() const; +/// y_iterator const& y() const; +/// +/// // return the vertical distance to another locator. Some models need the horizontal distance to compute it +/// y_coord_t y_distance_to(const my_locator& loc2, x_coord_t xDiff) const; +/// +/// // return true iff incrementing an x-iterator located at the last column will position it at the first +/// // column of the next row. Some models need the image width to determine that. +/// bool is_1d_traversable(x_coord_t width) const; +/// }; +/// \endcode +/// +/// Models may choose to override some of the functions in the base class with more efficient versions. +/// + +template // The concrete subclass, the X-iterator and the Y-iterator +class pixel_2d_locator_base { +public: + typedef XIterator x_iterator; + typedef YIterator y_iterator; + + // typedefs required by ConstRandomAccessNDLocatorConcept + static const std::size_t num_dimensions=2; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::reference reference; // result of dereferencing + typedef typename std::iterator_traits::difference_type coord_t; // 1D difference type (same for all dimensions) + typedef point2 difference_type; // result of operator-(locator,locator) + typedef difference_type point_t; + template struct axis { + typedef typename detail::locator_axis::coord_t coord_t; + typedef typename detail::locator_axis::iterator iterator; + }; + +// typedefs required by ConstRandomAccess2DLocatorConcept + typedef typename point_t::template axis<0>::coord_t x_coord_t; + typedef typename point_t::template axis<1>::coord_t y_coord_t; + + bool operator!=(const Loc& p) const { return !(concrete()==p); } + + x_iterator x_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.x(); } + x_iterator x_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.x(); } + y_iterator y_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.y(); } + y_iterator y_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.y(); } + Loc xy_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp; } + Loc xy_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp; } + + template typename axis::iterator& axis_iterator() { return detail::locator_axis()(concrete()); } + template typename axis::iterator const& axis_iterator() const { return detail::locator_axis()(concrete()); } + template typename axis::iterator axis_iterator(const point_t& p) const { return detail::locator_axis()(concrete(),p); } + + reference operator()(x_coord_t dx, y_coord_t dy) const { return *x_at(dx,dy); } + reference operator[](const difference_type& d) const { return *x_at(d.x,d.y); } + + reference operator*() const { return *concrete().x(); } + + Loc& operator+=(const difference_type& d) { concrete().x()+=d.x; concrete().y()+=d.y; return concrete(); } + Loc& operator-=(const difference_type& d) { concrete().x()-=d.x; concrete().y()-=d.y; return concrete(); } + + Loc operator+(const difference_type& d) const { return xy_at(d); } + Loc operator-(const difference_type& d) const { return xy_at(-d); } + + // Some locators can cache 2D coordinates for faster subsequent access. By default there is no caching + typedef difference_type cached_location_t; + cached_location_t cache_location(const difference_type& d) const { return d; } + cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return difference_type(dx,dy); } + +private: + Loc& concrete() { return (Loc&)*this; } + const Loc& concrete() const { return (const Loc&)*this; } + + template friend class pixel_2d_locator; +}; + +// helper classes for each axis of pixel_2d_locator_base +namespace detail { + template + class locator_axis<0,Loc> { + typedef typename Loc::point_t point_t; + public: + typedef typename point_t::template axis<0>::coord_t coord_t; + typedef typename Loc::x_iterator iterator; + + inline iterator& operator()( Loc& loc) const { return loc.x(); } + inline iterator const& operator()(const Loc& loc) const { return loc.x(); } + inline iterator operator()( Loc& loc, const point_t& d) const { return loc.x_at(d); } + inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.x_at(d); } + }; + + template + class locator_axis<1,Loc> { + typedef typename Loc::point_t point_t; + public: + typedef typename point_t::template axis<1>::coord_t coord_t; + typedef typename Loc::y_iterator iterator; + + inline iterator& operator()( Loc& loc) const { return loc.y(); } + inline iterator const& operator()(const Loc& loc) const { return loc.y(); } + inline iterator operator()( Loc& loc, const point_t& d) const { return loc.y_at(d); } + inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.y_at(d); } + }; +} + +template +struct channel_type > : public channel_type {}; + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public is_planar {}; + +/// \class memory_based_2d_locator +/// \brief Memory-based pixel locator. Models: PixelLocatorConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept +/// \ingroup PixelLocatorModel PixelBasedModel +/// +/// The class takes a step iterator as a parameter. The step iterator provides navigation along the vertical axis +/// while its base iterator provides horizontal navigation. +/// +/// Each instantiation is optimal in terms of size and efficiency. +/// For example, xy locator over interleaved rgb image results in a step iterator consisting of +/// one std::ptrdiff_t for the row size and one native pointer (8 bytes total). ++locator.x() resolves to pointer +/// increment. At the other extreme, a 2D navigation of the even pixels of a planar CMYK image results in a step +/// iterator consisting of one std::ptrdiff_t for the doubled row size, and one step iterator consisting of +/// one std::ptrdiff_t for the horizontal step of two and a CMYK planar_pixel_iterator consisting of 4 pointers (24 bytes). +/// In this case ++locator.x() results in four native pointer additions. +/// +/// Note also that \p memory_based_2d_locator does not require that its element type be a pixel. It could be +/// instantiated with an iterator whose \p value_type models only \p Regular. In this case the locator +/// models the weaker RandomAccess2DLocatorConcept, and does not model PixelBasedConcept. +/// Many generic algorithms don't require the elements to be pixels. +//////////////////////////////////////////////////////////////////////////////////////// + +template +class memory_based_2d_locator : public pixel_2d_locator_base, typename iterator_adaptor_get_base::type, StepIterator> { + typedef memory_based_2d_locator this_t; + GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept) +public: + typedef pixel_2d_locator_base, typename iterator_adaptor_get_base::type, StepIterator> parent_t; + typedef memory_based_2d_locator::type> const_t; // same as this type, but over const values + + typedef typename parent_t::coord_t coord_t; + typedef typename parent_t::x_coord_t x_coord_t; + typedef typename parent_t::y_coord_t y_coord_t; + typedef typename parent_t::x_iterator x_iterator; + typedef typename parent_t::y_iterator y_iterator; + typedef typename parent_t::difference_type difference_type; + typedef typename parent_t::reference reference; + + template struct add_deref { + typedef memory_based_2d_locator::type> type; + static type make(const memory_based_2d_locator& loc, const Deref& nderef) { + return type(iterator_add_deref::make(loc.y(),nderef)); + } + }; + + memory_based_2d_locator() {} + memory_based_2d_locator(const StepIterator& yit) : _p(yit) {} + template memory_based_2d_locator(const memory_based_2d_locator& loc, coord_t y_step) : _p(loc.x(), loc.row_size()*y_step) {} + template memory_based_2d_locator(const memory_based_2d_locator& loc, coord_t x_step, coord_t y_step, bool transpose=false) + : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step), + (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {} + + memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {} + template memory_based_2d_locator(const memory_based_2d_locator& pl) : _p(pl._p) {} + memory_based_2d_locator(const memory_based_2d_locator& pl) : _p(pl._p) {} + + bool operator==(const this_t& p) const { return _p==p._p; } + + x_iterator const& x() const { return _p.base(); } + y_iterator const& y() const { return _p; } + x_iterator& x() { return _p.base(); } + y_iterator& y() { return _p; } + + // These are faster versions of functions already provided in the superclass + x_iterator x_at (x_coord_t dx, y_coord_t dy) const { return memunit_advanced(x(), offset(dx,dy)); } + x_iterator x_at (const difference_type& d) const { return memunit_advanced(x(), offset(d.x,d.y)); } + this_t xy_at (x_coord_t dx, y_coord_t dy) const { return this_t(x_at( dx , dy ), row_size()); } + this_t xy_at (const difference_type& d) const { return this_t(x_at( d.x, d.y), row_size()); } + reference operator()(x_coord_t dx, y_coord_t dy) const { return memunit_advanced_ref(x(),offset(dx,dy)); } + reference operator[](const difference_type& d) const { return memunit_advanced_ref(x(),offset(d.x,d.y)); } + this_t& operator+=(const difference_type& d) { memunit_advance(x(),offset(d.x,d.y)); return *this; } + this_t& operator-=(const difference_type& d) { memunit_advance(x(),offset(-d.x,-d.y)); return *this; } + + // Memory-based locators can have 1D caching of 2D relative coordinates + typedef std::ptrdiff_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access) + cached_location_t cache_location(const difference_type& d) const { return offset(d.x,d.y); } + cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return offset(dx,dy); } + reference operator[](const cached_location_t& loc) const { return memunit_advanced_ref(x(),loc); } + + // Only make sense for memory-based locators + std::ptrdiff_t row_size() const { return memunit_step(y()); } // distance in mem units (bytes or bits) between adjacent rows + std::ptrdiff_t pixel_size() const { return memunit_step(x()); } // distance in mem units (bytes or bits) between adjacent pixels on the same row + + bool is_1d_traversable(x_coord_t width) const { return row_size()-pixel_size()*width==0; } // is there no gap at the end of each row? + + // Returns the vertical distance (it2.y-it1.y) between two x_iterators given the difference of their x positions + std::ptrdiff_t y_distance_to(const this_t& p2, x_coord_t xDiff) const { + std::ptrdiff_t rowDiff=memunit_distance(x(),p2.x())-pixel_size()*xDiff; + assert(( rowDiff % row_size())==0); + return rowDiff / row_size(); + } + +private: + template friend class memory_based_2d_locator; + std::ptrdiff_t offset(x_coord_t x, y_coord_t y) const { return y*row_size() + x*pixel_size(); } + StepIterator _p; +}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > : public color_space_type::parent_t> { +}; + +template +struct channel_mapping_type > : public channel_mapping_type::parent_t> { +}; + +template +struct is_planar > : public is_planar::parent_t> { +}; + +template +struct channel_type > : public channel_type::parent_t> { +}; + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +// Take the base iterator of SI (which is typically a step iterator) and change it to have a step in x +template +struct dynamic_x_step_type > { +private: + typedef typename iterator_adaptor_get_base::type base_iterator_t; + typedef typename dynamic_x_step_type::type base_iterator_step_t; + typedef typename iterator_adaptor_rebind::type dynamic_step_base_t; +public: + typedef memory_based_2d_locator type; +}; + +///////////////////////////// +// HasDynamicYStepTypeConcept +///////////////////////////// + +template +struct dynamic_y_step_type > { + typedef memory_based_2d_locator type; +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/metafunctions.hpp b/thirdparty/boost/gil/metafunctions.hpp new file mode 100644 index 0000000..714b4ba --- /dev/null +++ b/thirdparty/boost/gil/metafunctions.hpp @@ -0,0 +1,494 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_METAFUNCTIONS_HPP +#define GIL_METAFUNCTIONS_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief metafunctions that construct types or return type properties +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// +/// \date 2005-2007 \n Last updated on February 6, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "channel.hpp" + +namespace boost { namespace gil { + +// forward declarations +template struct pixel; +template struct packed_pixel; +template struct planar_pixel_reference; +template struct planar_pixel_iterator; +template class memory_based_step_iterator; +template class memory_based_2d_locator; +template class image_view; +template class image; +template struct channel_type; +template struct color_space_type; +template struct channel_mapping_type; +template struct is_iterator_adaptor; +template struct iterator_adaptor_get_base; +template struct bit_aligned_pixel_reference; + +////////////////////////////////////////////////// +/// +/// TYPE ANALYSIS METAFUNCTIONS +/// Predicate metafunctions determining properties of GIL types +/// +////////////////////////////////////////////////// + + +/// \defgroup GILIsBasic xxx_is_basic +/// \ingroup TypeAnalysis +/// \brief Determines if GIL constructs are basic. +/// Basic constructs are the ones that can be generated with the type +/// factory methods pixel_reference_type, iterator_type, locator_type, view_type and image_type +/// They can be mutable/immutable, planar/interleaved, step/nonstep. They must use GIL-provided models. + +/// \brief Determines if a given pixel reference is basic +/// Basic references must use gil::pixel& (if interleaved), gil::planar_pixel_reference (if planar). They must use the standard constness rules. +/// \ingroup GILIsBasic +template struct pixel_reference_is_basic : public mpl::false_ {}; +template struct pixel_reference_is_basic< pixel&> : public mpl::true_ {}; +template struct pixel_reference_is_basic&> : public mpl::true_ {}; +template struct pixel_reference_is_basic > : public mpl::true_ {}; +template struct pixel_reference_is_basic > : public mpl::true_ {}; + + +/// \brief Determines if a given pixel iterator is basic +/// Basic iterators must use gil::pixel (if interleaved), gil::planar_pixel_iterator (if planar) and gil::memory_based_step_iterator (if step). They must use the standard constness rules. +/// \ingroup GILIsBasic +template +struct iterator_is_basic : public mpl::false_ {}; +template // mutable interleaved +struct iterator_is_basic< pixel* > : public mpl::true_ {}; +template // immutable interleaved +struct iterator_is_basic* > : public mpl::true_ {}; +template // mutable planar +struct iterator_is_basic > : public mpl::true_ {}; +template // immutable planar +struct iterator_is_basic > : public mpl::true_ {}; +template // mutable interleaved step +struct iterator_is_basic*> > : public mpl::true_ {}; +template // immutable interleaved step +struct iterator_is_basic*> > : public mpl::true_ {}; +template // mutable planar step +struct iterator_is_basic > > : public mpl::true_ {}; +template // immutable planar step +struct iterator_is_basic > > : public mpl::true_ {}; + + +/// \ingroup GILIsBasic +/// \brief Determines if a given locator is basic. A basic locator is memory-based and has basic x_iterator and y_iterator +template struct locator_is_basic : public mpl::false_ {}; +template struct locator_is_basic > > : public iterator_is_basic {}; + +/// \ingroup GILIsBasic +/// \brief Basic views must be over basic locators +template struct view_is_basic : public mpl::false_ {}; +template struct view_is_basic > : public locator_is_basic {}; + +/// \ingroup GILIsBasic +/// \brief Basic images must use basic views and std::allocator of char +template struct image_is_basic : public mpl::false_ {}; +template struct image_is_basic > : public mpl::true_ {}; + + +/// \defgroup GILIsStep xxx_is_step +/// \ingroup TypeAnalysis +/// \brief Determines if the given iterator/locator/view has a step that could be set dynamically + +template struct iterator_is_step; +namespace detail { + template struct iterator_is_step_impl; + // iterator that has the same type as its dynamic_x_step_type must be a step iterator + template struct iterator_is_step_impl : public mpl::true_{}; + + // base iterator can never be a step iterator + template struct iterator_is_step_impl : public mpl::false_{}; + + // for an iterator adaptor, see if its base is step + template struct iterator_is_step_impl + : public iterator_is_step::type>{}; +} + +/// \ingroup GILIsStep +/// \brief Determines if the given iterator has a step that could be set dynamically +template struct iterator_is_step + : public detail::iterator_is_step_impl::type::value, + is_same::type>::value >{}; + +/// \ingroup GILIsStep +/// \brief Determines if the given locator has a horizontal step that could be set dynamically +template struct locator_is_step_in_x : public iterator_is_step {}; + +/// \ingroup GILIsStep +/// \brief Determines if the given locator has a vertical step that could be set dynamically +template struct locator_is_step_in_y : public iterator_is_step {}; + +/// \ingroup GILIsStep +/// \brief Determines if the given view has a horizontal step that could be set dynamically +template struct view_is_step_in_x : public locator_is_step_in_x {}; + +/// \ingroup GILIsStep +/// \brief Determines if the given view has a vertical step that could be set dynamically +template struct view_is_step_in_y : public locator_is_step_in_y {}; + +/// \brief Determines whether the given pixel reference is a proxy class or a native C++ reference +/// \ingroup TypeAnalysis +template +struct pixel_reference_is_proxy + : public mpl::not_::type, + typename remove_const_and_reference::type::value_type> > {}; + +/// \brief Given a model of a pixel, determines whether the model represents a pixel reference (as opposed to pixel value) +/// \ingroup TypeAnalysis +template +struct pixel_is_reference : public mpl::or_, pixel_reference_is_proxy > {}; + +/// \defgroup GILIsMutable xxx_is_mutable +/// \ingroup TypeAnalysis +/// \brief Determines if the given pixel reference/iterator/locator/view is mutable (i.e. its pixels can be changed) + +/// \ingroup GILIsMutable +/// \brief Determines if the given pixel reference is mutable (i.e. its channels can be changed) +/// +/// Note that built-in C++ references obey the const qualifier but reference proxy classes do not. +template struct pixel_reference_is_mutable : public mpl::bool_::type::is_mutable> {}; +template struct pixel_reference_is_mutable + : public mpl::and_, pixel_reference_is_mutable > {}; + +/// \ingroup GILIsMutable +/// \brief Determines if the given locator is mutable (i.e. its pixels can be changed) +template struct locator_is_mutable : public iterator_is_mutable {}; +/// \ingroup GILIsMutable +/// \brief Determines if the given view is mutable (i.e. its pixels can be changed) +template struct view_is_mutable : public iterator_is_mutable {}; + + +////////////////////////////////////////////////// +/// +/// TYPE FACTORY METAFUNCTIONS +/// Metafunctions returning GIL types from other GIL types +/// +////////////////////////////////////////////////// + +/// \defgroup TypeFactoryFromElements xxx_type +/// \ingroup TypeFactory +/// \brief Returns the type of a homogeneous GIL construct given its elements (channel, layout, whether it is planar, step, mutable, etc.) + +/// \defgroup TypeFactoryFromPixel xxx_type_from_pixel +/// \ingroup TypeFactory +/// \brief Returns the type of a GIL construct given its pixel type, whether it is planar, step, mutable, etc. + +/// \defgroup TypeFactoryDerived derived_xxx_type +/// \ingroup TypeFactory +/// \brief Returns the type of a homogeneous GIL construct given a related construct by changing some of its properties + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous pixel reference given the channel type, layout, whether it operates on planar data and whether it is mutable +template struct pixel_reference_type{}; +template struct pixel_reference_type { typedef pixel& type; }; +template struct pixel_reference_type { typedef const pixel& type; }; +template struct pixel_reference_type { typedef const planar_pixel_reference::reference,typename color_space_type::type> type; }; // TODO: Assert M=identity +template struct pixel_reference_type { typedef const planar_pixel_reference::const_reference,typename color_space_type::type> type; };// TODO: Assert M=identity + +/// \ingroup TypeFactoryFromPixel +/// \brief Returns the type of a pixel iterator given the pixel type, whether it operates on planar data, whether it is a step iterator, and whether it is mutable +template struct iterator_type_from_pixel{}; +template struct iterator_type_from_pixel { typedef Pixel* type; }; +template struct iterator_type_from_pixel { typedef const Pixel* type; }; +template struct iterator_type_from_pixel { + typedef planar_pixel_iterator::type>::pointer,typename color_space_type::type> type; +}; +template struct iterator_type_from_pixel { + typedef planar_pixel_iterator::type>::const_pointer,typename color_space_type::type> type; +}; +template struct iterator_type_from_pixel { + typedef memory_based_step_iterator::type> type; +}; + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous iterator given the channel type, layout, whether it operates on planar data, whether it is a step iterator, and whether it is mutable +template struct iterator_type{}; +template struct iterator_type { typedef pixel* type; }; +template struct iterator_type { typedef const pixel* type; }; +template struct iterator_type { typedef planar_pixel_iterator type; }; // TODO: Assert M=identity +template struct iterator_type { typedef planar_pixel_iterator type; }; // TODO: Assert M=identity +template struct iterator_type { + typedef memory_based_step_iterator::type> type; +}; + +/// \brief Given a pixel iterator defining access to pixels along a row, returns the types of the corresponding built-in step_iterator, xy_locator, image_view +/// \ingroup TypeFactory +template +struct type_from_x_iterator { + typedef memory_based_step_iterator step_iterator_t; + typedef memory_based_2d_locator xy_locator_t; + typedef image_view view_t; +}; + +namespace detail { + template + struct packed_channel_reference_type { + typedef const packed_channel_reference type; + }; + + template + class packed_channel_references_vector_type { + // If ChannelBitSizesVector is mpl::vector + // Then first_bits_vector will be mpl::vector + typedef typename mpl::accumulate >, + mpl::push_back, mpl::_2> > >::type first_bits_vector; + public: + typedef typename mpl::transform::type, ChannelBitSizesVector, + packed_channel_reference_type >::type type; + }; + +} + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a packed pixel given its bitfield type, the bit size of its channels and its layout. +/// +/// A packed pixel has channels that cover bit ranges but itself is byte aligned. RGB565 pixel is an example. +/// +/// The size of ChannelBitSizeVector must equal the number of channels in the given layout +/// The sum of bit sizes for all channels must be less than or equal to the number of bits in BitField (and cannot exceed 64). +/// If it is less than the number of bits in BitField, the last bits will be unused. +template +struct packed_pixel_type { + typedef packed_pixel::type, Layout> type; +}; + +/// \defgroup TypeFactoryPacked packed_image_type,bit_aligned_image_type +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of an image whose channels are not byte-aligned. +/// +/// A packed image is an image whose pixels are byte aligned, such as "rgb565".
            +/// A bit-aligned image is an image whose pixels are not byte aligned, such as "rgb222".
            +/// +/// The sum of the bit sizes of all channels cannot exceed 64. + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of an interleaved packed image: an image whose channels may not be byte-aligned, but whose pixels are byte aligned. +template > +struct packed_image_type { + typedef image::type,false,Alloc> type; +}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a single-channel image given its bitfield type, the bit size of its channel and its layout +template > +struct packed_image1_type : public packed_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a two channel image given its bitfield type, the bit size of its channels and its layout +template > +struct packed_image2_type : public packed_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a three channel image given its bitfield type, the bit size of its channels and its layout +template > +struct packed_image3_type : public packed_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a four channel image given its bitfield type, the bit size of its channels and its layout +template > +struct packed_image4_type : public packed_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a five channel image given its bitfield type, the bit size of its channels and its layout +template > +struct packed_image5_type : public packed_image_type, Layout, Alloc> {}; + + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a packed image whose pixels may not be byte aligned. For example, an "rgb222" image is bit-aligned because its pixel spans six bits. +/// +/// Note that the alignment parameter in the constructor of bit-aligned images is in bit units. For example, if you want to construct a bit-aligned +/// image whose rows are byte-aligned, use 8 as the alignment parameter, not 1. + +template > +struct bit_aligned_image_type { +private: + BOOST_STATIC_CONSTANT(int, bit_size = (mpl::accumulate, mpl::plus >::type::value)); + typedef typename detail::min_fast_uint::type bitfield_t; + typedef const bit_aligned_pixel_reference bit_alignedref_t; +public: + typedef image type; +}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a single-channel bit-aligned image given the bit size of its channel and its layout +template > +struct bit_aligned_image1_type : public bit_aligned_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a two channel bit-aligned image given the bit size of its channels and its layout +template > +struct bit_aligned_image2_type : public bit_aligned_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a three channel bit-aligned image given the bit size of its channels and its layout +template > +struct bit_aligned_image3_type : public bit_aligned_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a four channel bit-aligned image given the bit size of its channels and its layout +template > +struct bit_aligned_image4_type : public bit_aligned_image_type, Layout, Alloc> {}; + +/// \ingroup TypeFactoryPacked +/// \brief Returns the type of a five channel bit-aligned image given the bit size of its channels and its layout +template > +struct bit_aligned_image5_type : public bit_aligned_image_type, Layout, Alloc> {}; + + + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous pixel given the channel type and layout +template +struct pixel_value_type { + typedef pixel type; // by default use gil::pixel. Specializations are provided for +}; + +// Specializations for packed channels +template +struct pixel_value_type< packed_dynamic_channel_reference,Layout> : + public packed_pixel_type, Layout> {}; +template +struct pixel_value_type,Layout> : + public packed_pixel_type, Layout> {}; + +template +struct pixel_value_type< packed_channel_reference,Layout> : + public packed_pixel_type, Layout> {}; +template +struct pixel_value_type,Layout> : + public packed_pixel_type, Layout> {}; + +template +struct pixel_value_type,Layout> : + public packed_pixel_type::type, mpl::vector1_c, Layout> {}; + + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous locator given the channel type, layout, whether it operates on planar data and whether it has a step horizontally +template +struct locator_type { + typedef typename type_from_x_iterator::type>::xy_locator_type type; +}; + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous view given the channel type, layout, whether it operates on planar data and whether it has a step horizontally +template +struct view_type { + typedef typename type_from_x_iterator::type>::view_t type; +}; + +/// \ingroup TypeFactoryFromElements +/// \brief Returns the type of a homogeneous image given the channel type, layout, and whether it operates on planar data +template > +struct image_type { + typedef image, IsPlanar, Alloc> type; +}; + +/// \ingroup TypeFactoryFromPixel +/// \brief Returns the type of a view the pixel type, whether it operates on planar data and whether it has a step horizontally +template +struct view_type_from_pixel { + typedef typename type_from_x_iterator::type>::view_t type; +}; + + +/// \brief Constructs a pixel reference type from a source pixel reference type by changing some of the properties. +/// \ingroup TypeFactoryDerived +/// Use use_default for the properties of the source view that you want to keep +template +class derived_pixel_reference_type { + typedef typename remove_reference::type pixel_t; + typedef typename mpl::if_, typename channel_type::type, T >::type channel_t; + typedef typename mpl::if_, + layout::type, typename channel_mapping_type::type>, L>::type layout_t; + static const bool mut =mpl::if_, pixel_reference_is_mutable, IsMutable>::type::value; + static const bool planar=mpl::if_, is_planar, IsPlanar>::type::value; +public: + typedef typename pixel_reference_type::type type; +}; + +/// \brief Constructs a pixel iterator type from a source pixel iterator type by changing some of the properties. +/// \ingroup TypeFactoryDerived +/// Use use_default for the properties of the source view that you want to keep +template +class derived_iterator_type { + typedef typename mpl::if_, typename channel_type::type, T >::type channel_t; + typedef typename mpl::if_, + layout::type, typename channel_mapping_type::type>, L>::type layout_t; + + static const bool mut =mpl::if_, iterator_is_mutable, IsMutable>::type::value; + static const bool planar=mpl::if_, is_planar, IsPlanar>::type::value; + static const bool step =mpl::if_, iterator_is_step, IsStep>::type::value; +public: + typedef typename iterator_type::type type; +}; + +/// \brief Constructs an image view type from a source view type by changing some of the properties. +/// \ingroup TypeFactoryDerived +/// Use use_default for the properties of the source view that you want to keep +template +class derived_view_type { + typedef typename mpl::if_, typename channel_type::type, T>::type channel_t; + typedef typename mpl::if_, + layout::type, typename channel_mapping_type::type>, L>::type layout_t; + static const bool mut =mpl::if_, view_is_mutable, IsMutable>::type::value; + static const bool planar=mpl::if_, is_planar, IsPlanar>::type::value; + static const bool step =mpl::if_, view_is_step_in_x,StepX>::type::value; +public: + typedef typename view_type::type type; +}; + +/// \brief Constructs a homogeneous image type from a source image type by changing some of the properties. +/// \ingroup TypeFactoryDerived +/// Use use_default for the properties of the source image that you want to keep +template +class derived_image_type { + typedef typename mpl::if_, typename channel_type::type, T >::type channel_t; + typedef typename mpl::if_, + layout::type, typename channel_mapping_type::type>, L>::type layout_t; + static const bool planar=mpl::if_, is_planar, IsPlanar>::type::value; +public: + typedef typename image_type::type type; +}; + + + + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/packed_pixel.hpp b/thirdparty/boost/gil/packed_pixel.hpp new file mode 100644 index 0000000..428b2fb --- /dev/null +++ b/thirdparty/boost/gil/packed_pixel.hpp @@ -0,0 +1,193 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PACKED_PIXEL_H +#define GIL_PACKED_PIXEL_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief A model of a heterogeneous pixel whose channels are bit ranges. For example 16-bit RGB in '565' format +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 28, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include "gil_config.hpp" +#include "pixel.hpp" + +namespace boost { namespace gil { + +/// \defgroup ColorBaseModelPackedPixel packed_pixel +/// \ingroup ColorBaseModel +/// \brief A heterogeneous color base whose elements are reference proxies to channels in a pixel. Models ColorBaseValueConcept. This class is used to model packed pixels, such as 16-bit packed RGB. + +/** +\defgroup PixelModelPackedPixel packed_pixel +\ingroup PixelModel +\brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept + +Example: +\code +typedef packed_pixel_type, rgb_layout_t>::type rgb565_pixel_t; +BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2)); + +rgb565_pixel_t r565; +get_color(r565,red_t()) = 31; +get_color(r565,green_t()) = 63; +get_color(r565,blue_t()) = 31; +assert(r565 == rgb565_pixel_t((uint16_t)0xFFFF)); +\endcode +*/ + +/// \ingroup ColorBaseModelPackedPixel PixelModelPackedPixel PixelBasedModel +/// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept +/// Typical use for this is a model of a packed pixel (like 565 RGB) +template // Layout defining the color space and ordering of the channels. Example value: rgb_layout_t +struct packed_pixel { + BitField _bitfield; + + typedef Layout layout_t; + typedef packed_pixel value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits::type>::is_mutable); + + packed_pixel(){} + explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {} + + // Construct from another compatible pixel type + packed_pixel(const packed_pixel& p) : _bitfield(p._bitfield) {} + template packed_pixel(const P& p, typename enable_if_c::value>::type* d=0) { check_compatible

            (); static_copy(p,*this); } + packed_pixel(int chan0, int chan1) : _bitfield(0) { + BOOST_STATIC_ASSERT((num_channels::value==2)); + at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; + } + packed_pixel(int chan0, int chan1, int chan2) : _bitfield(0) { + BOOST_STATIC_ASSERT((num_channels::value==3)); + at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; + } + packed_pixel(int chan0, int chan1, int chan2, int chan3) : _bitfield(0) { + BOOST_STATIC_ASSERT((num_channels::value==4)); + at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3; + } + packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4) : _bitfield(0) { + BOOST_STATIC_ASSERT((num_channels::value==5)); + at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3; at_c<3>(*this)=chan4; + } + + packed_pixel& operator=(const packed_pixel& p) { _bitfield=p._bitfield; return *this; } + + template packed_pixel& operator=(const P& p) { assign(p, mpl::bool_::value>()); return *this; } + template bool operator==(const P& p) const { return equal(p, mpl::bool_::value>()); } + + template bool operator!=(const P& p) const { return !(*this==p); } + +private: + template static void check_compatible() { gil_function_requires >(); } + template void assign(const Pixel& p, mpl::true_) { check_compatible(); static_copy(p,*this); } + template bool equal(const Pixel& p, mpl::true_) const { check_compatible(); return static_equal(*this,p); } + +// Support for assignment/equality comparison of a channel with a grayscale pixel + static void check_gray() { BOOST_STATIC_ASSERT((is_same::value)); } + template void assign(const Channel& chan, mpl::false_) { check_gray(); at_c<0>(*this)=chan; } + template bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; } +public: + packed_pixel& operator= (int chan) { check_gray(); at_c<0>(*this)=chan; return *this; } + bool operator==(int chan) const { check_gray(); return at_c<0>(*this)==chan; } +}; + +///////////////////////////// +// ColorBasedConcept +///////////////////////////// + +template +struct kth_element_type,K> : public mpl::at_c {}; + +template +struct kth_element_reference_type,K> : public mpl::at_c {}; + +template +struct kth_element_const_reference_type,K> { + typedef typename channel_traits::type>::const_reference type; +}; + +template inline +typename kth_element_reference_type, K>::type +at_c(packed_pixel& p) { + return typename kth_element_reference_type, K>::type(&p._bitfield); +} + +template inline +typename kth_element_const_reference_type, K>::type +at_c(const packed_pixel& p) { + return typename kth_element_const_reference_type, K>::type(&p._bitfield); +} + +///////////////////////////// +// PixelConcept +///////////////////////////// + +// Metafunction predicate that flags packed_pixel as a model of PixelConcept. Required by PixelConcept +template +struct is_pixel > : public mpl::true_{}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > { + typedef typename Layout::color_space_t type; +}; + +template +struct channel_mapping_type > { + typedef typename Layout::channel_mapping_t type; +}; + +template +struct is_planar > : mpl::false_ {}; + + +//////////////////////////////////////////////////////////////////////////////// +/// +/// Support for interleaved iterators over packed pixel +/// +//////////////////////////////////////////////////////////////////////////////// + +/// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to packed_pixel +/// \ingroup PixelIteratorModel +/// \brief Iterators over interleaved pixels. +/// The pointer packed_pixel* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept + +template +struct iterator_is_mutable*> : public mpl::bool_::is_mutable> {}; +template +struct iterator_is_mutable*> : public mpl::false_ {}; + + + +} } // namespace boost::gil + +namespace boost { + template + struct has_trivial_constructor > : public has_trivial_constructor

            {}; +} +#endif diff --git a/thirdparty/boost/gil/pixel.hpp b/thirdparty/boost/gil/pixel.hpp new file mode 100644 index 0000000..ba2e04b --- /dev/null +++ b/thirdparty/boost/gil/pixel.hpp @@ -0,0 +1,212 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_PIXEL_H +#define GIL_PIXEL_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel class and related utilities +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 28, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "gil_config.hpp" +#include "color_base.hpp" +#include "gil_concept.hpp" +#include "channel.hpp" +#include "metafunctions.hpp" +#include "utilities.hpp" +#include "color_base_algorithm.hpp" + +namespace boost { namespace gil { + +// Forward-declare gray_t +struct gray_color_t; +typedef mpl::vector1 gray_t; +template struct color_space_type; +template struct channel_mapping_type; +template struct channel_type; +template struct is_planar; + +template struct color_space_type : public color_space_type {}; +template struct channel_mapping_type : public channel_mapping_type {}; +template struct channel_type : public channel_type {}; +template struct is_planar : public is_planar {}; + + +template struct is_pixel : public mpl::false_{}; +template struct is_pixel : public is_pixel {}; + +/// \ingroup PixelBasedAlgorithm +/// \brief Returns the number of channels of a pixel-based GIL construct +template +struct num_channels : public mpl::size::type> {}; + +/** +\addtogroup PixelBasedAlgorithm + +Example: +\code +BOOST_STATIC_ASSERT((num_channels::value==3)); +BOOST_STATIC_ASSERT((num_channels::value==4)); + +BOOST_STATIC_ASSERT((is_planar::value)); +BOOST_STATIC_ASSERT((is_same::type, rgb_t>::value)); +BOOST_STATIC_ASSERT((is_same::type, + channel_mapping_type::type>::value)); +BOOST_STATIC_ASSERT((is_same::type, bits8>::value)); +\endcode +*/ + +/// \defgroup ColorBaseModelPixel pixel +/// \ingroup ColorBaseModel +/// \brief A homogeneous color base whose element is a channel value. Models HomogeneousColorBaseValueConcept + +/// \defgroup PixelModelPixel pixel +/// \ingroup PixelModel +/// \brief A homogeneous pixel value. Models HomogeneousPixelValueConcept + +/// \ingroup PixelModelPixel ColorBaseModelPixel PixelBasedModel +/// \brief Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept, PixelValueConcept, HomogeneousPixelBasedConcept +/// +/// A pixel is a set of channels defining the color at a given point in an image. Conceptually, a pixel is little more than a color base whose elements +/// model \p ChannelConcept. The class \p pixel defines a simple, homogeneous pixel value. It is used to store +/// the value of a color. The built-in C++ references to \p pixel, \p pixel& and \p const \p pixel& are used to represent a reference to a pixel +/// inside an interleaved image view (a view in which all channels are together in memory). Similarly, built-in pointer types \p pixel* and \p const \p pixel* +/// are used as the standard iterator over a row of interleaved homogeneous pixels. +/// +/// Since \p pixel inherits the properties of color base, assigning, equality comparison and copy-construcion are allowed between compatible pixels. +/// This means that an 8-bit RGB pixel may be assigned to an 8-bit BGR pixel, or to an 8-bit planar reference. The channels are properly paired semantically. +/// +/// The single-channel (grayscale) instantiation of the class pixel, (i.e. \p pixel) is also convertible to/from a channel value. +/// This allows grayscale pixels to be used in simpler expressions like *gray_pix1 = *gray_pix2 instead of more complicated at_c<0>(gray_pix1) = at_c<0>(gray_pix2) +/// or get_color(gray_pix1) = get_color(gray_pix2) + +template // = mpl::range_c > +struct pixel : public detail::homogeneous_color_base::value> { +private: + typedef ChannelValue channel_t; + typedef detail::homogeneous_color_base::value> parent_t; +public: + typedef pixel value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits::is_mutable); + + pixel(){} + explicit pixel(channel_t v) : parent_t(v) {} // sets all channels to v + pixel(channel_t v0, channel_t v1) : parent_t(v0,v1) {} + pixel(channel_t v0, channel_t v1, channel_t v2) : parent_t(v0,v1,v2) {} + pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3) : parent_t(v0,v1,v2,v3) {} + pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3, channel_t v4) : parent_t(v0,v1,v2,v3,v4) {} + pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3, channel_t v4, channel_t v5) : parent_t(v0,v1,v2,v3,v4,v5) {} + + pixel(const pixel& p) : parent_t(p) {} + pixel& operator=(const pixel& p) { static_copy(p,*this); return *this; } + + // Construct from another compatible pixel type + template pixel(const Pixel& p, typename enable_if_c::value>::type* dummy = 0) : parent_t(p) { + check_compatible(); + } + + template pixel& operator=(const P& p) { assign(p, mpl::bool_::value>()); return *this; } + template bool operator==(const P& p) const { return equal(p, mpl::bool_::value>()); } + + template bool operator!=(const P& p) const { return !(*this==p); } + + // homogeneous pixels have operator[] + typename channel_traits::reference operator[](std::size_t i) { return dynamic_at_c(*this,i); } + typename channel_traits::const_reference operator[](std::size_t i) const { return dynamic_at_c(*this,i); } +private: + template void assign(const Pixel& p, mpl::true_) { check_compatible(); static_copy(p,*this); } + template bool equal(const Pixel& p, mpl::true_) const { check_compatible(); return static_equal(*this,p); } + + template void check_compatible() const { gil_function_requires >(); } + +// Support for assignment/equality comparison of a channel with a grayscale pixel + +private: + static void check_gray() { BOOST_STATIC_ASSERT((is_same::value)); } + template void assign(const Channel& chan, mpl::false_) { check_gray(); at_c<0>(*this)=chan; } + template bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; } +public: + pixel& operator= (channel_t chan) { check_gray(); at_c<0>(*this)=chan; return *this; } + bool operator==(channel_t chan) const { check_gray(); return at_c<0>(*this)==chan; } +}; + +///////////////////////////// +// ColorBasedConcept +///////////////////////////// + +template +struct kth_element_type, K> { + typedef ChannelValue type; +}; + +template +struct kth_element_reference_type, K> { + typedef typename channel_traits::reference type; +}; + +template +struct kth_element_reference_type, K> { + typedef typename channel_traits::const_reference type; +}; + +template +struct kth_element_const_reference_type, K> { + typedef typename channel_traits::const_reference type; +}; + +///////////////////////////// +// PixelConcept +///////////////////////////// + +template +struct is_pixel > : public mpl::true_{}; + +///////////////////////////// +// HomogeneousPixelBasedConcept +///////////////////////////// + +template +struct color_space_type > { + typedef typename Layout::color_space_t type; +}; + +template +struct channel_mapping_type > { + typedef typename Layout::channel_mapping_t type; +}; + +template +struct is_planar > : public mpl::false_ {}; + +template +struct channel_type > { + typedef ChannelValue type; +}; + +} } // namespace boost::gil + +namespace boost { + template + struct has_trivial_constructor > : public has_trivial_constructor {}; +} +#endif diff --git a/thirdparty/boost/gil/pixel_iterator.hpp b/thirdparty/boost/gil/pixel_iterator.hpp new file mode 100644 index 0000000..b0d0dd0 --- /dev/null +++ b/thirdparty/boost/gil/pixel_iterator.hpp @@ -0,0 +1,156 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PIXEL_ITERATOR_H +#define GIL_PIXEL_ITERATOR_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel iterator support +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n May 16, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "utilities.hpp" +#include "pixel.hpp" + +namespace boost { namespace gil { + +//forwarded declaration (as this file is included in step_iterator.hpp) +template +class memory_based_step_iterator; + +template struct dynamic_x_step_type; + +/// \brief metafunction predicate determining whether the given iterator is a plain one or an adaptor over another iterator. +/// Examples of adaptors are the step iterator and the dereference iterator adaptor. +template +struct is_iterator_adaptor : public mpl::false_{}; + +/// \brief returns the base iterator for a given iterator adaptor. Provide an specialization when introducing new iterator adaptors +template +struct iterator_adaptor_get_base; + +/// \brief Changes the base iterator of an iterator adaptor. Provide an specialization when introducing new iterator adaptors +template +struct iterator_adaptor_rebind; + +/// \brief Returns the type of an iterator just like the input iterator, except operating over immutable values +template +struct const_iterator_type; + +// The default implementation when the iterator is a C pointer is to use the standard constness semantics +template struct const_iterator_type< T*> { typedef const T* type; }; +template struct const_iterator_type { typedef const T* type; }; + +/// \brief Metafunction predicate returning whether the given iterator allows for changing its values +/// \ingroup GILIsMutable +template +struct iterator_is_mutable{}; + +// The default implementation when the iterator is a C pointer is to use the standard constness semantics +template struct iterator_is_mutable< T*> : public mpl::true_{}; +template struct iterator_is_mutable : public mpl::false_{}; + +/// \defgroup PixelIteratorModelInterleavedPtr C pointer to a pixel +/// \ingroup PixelIteratorModel +/// \brief Iterators over interleaved pixels. +/// A C pointer to a model of PixelValueConcept is used as an iterator over interleaved pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept + + + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +/// \ingroup PixelIteratorModelInterleavedPtr +template +struct dynamic_x_step_type { + typedef memory_based_step_iterator type; +}; + +/// \ingroup PixelIteratorModelInterleavedPtr +template +struct dynamic_x_step_type { + typedef memory_based_step_iterator type; +}; + + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template struct color_space_type< Pixel*> : public color_space_type {}; +template struct color_space_type : public color_space_type {}; + +template struct channel_mapping_type< Pixel*> : public channel_mapping_type {}; +template struct channel_mapping_type : public channel_mapping_type {}; + +template struct is_planar< Pixel*> : public is_planar {}; +template struct is_planar : public is_planar {}; + +///////////////////////////// +// HomogeneousPixelBasedConcept +///////////////////////////// + +template struct channel_type : public channel_type {}; +template struct channel_type : public channel_type {}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// Support for pixel iterator movement measured in memory units (bytes or bits) as opposed to pixel type. \n +/// Necessary to handle image row alignment and channel plane alignment. +/// +//////////////////////////////////////////////////////////////////////////////////////// + +///////////////////////////// +// MemoryBasedIteratorConcept +///////////////////////////// + +template +struct byte_to_memunit : public mpl::int_<1> {}; + +template +inline std::ptrdiff_t memunit_step(const P*) { return sizeof(P); } + +template +inline std::ptrdiff_t memunit_distance(const P* p1, const P* p2) { + return (gil_reinterpret_cast_c(p2)-gil_reinterpret_cast_c(p1)); +} + +template +inline void memunit_advance(P* &p, std::ptrdiff_t diff) { + p=(P*)((unsigned char*)(p)+diff); +} + +template +inline P* memunit_advanced(const P* p, std::ptrdiff_t diff) { + return (P*)((char*)(p)+diff); +} + +// memunit_advanced_ref +// (shortcut to advancing a pointer by a given number of memunits and taking the reference in case the compiler is not smart enough) + +template +inline P& memunit_advanced_ref(P* p, std::ptrdiff_t diff) { + return *memunit_advanced(p,diff); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/pixel_iterator_adaptor.hpp b/thirdparty/boost/gil/pixel_iterator_adaptor.hpp new file mode 100644 index 0000000..b0d477a --- /dev/null +++ b/thirdparty/boost/gil/pixel_iterator_adaptor.hpp @@ -0,0 +1,208 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PIXEL_ITERATOR_ADAPTOR_H +#define GIL_PIXEL_ITERATOR_ADAPTOR_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel step iterator, pixel image iterator and pixel dereference iterator +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 16, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "pixel_iterator.hpp" + +namespace boost { namespace gil { + + +/// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor +/// \ingroup PixelIteratorModel +/// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept + + +/// \ingroup PixelIteratorModelDerefPtr PixelBasedModel +/// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept + +template // Models Returns the result of dereferencing a given iterator of type Iterator +class dereference_iterator_adaptor : public iterator_adaptor, + Iterator, + typename DFn::value_type, + use_default, + typename DFn::reference, + use_default> { + DFn _deref_fn; +public: + typedef iterator_adaptor, + Iterator, + typename DFn::value_type, + use_default, + typename DFn::reference, + use_default> parent_t; + typedef typename DFn::result_type reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef DFn dereference_fn; + + dereference_iterator_adaptor() {} + template + dereference_iterator_adaptor(const dereference_iterator_adaptor& dit) : parent_t(dit.base()), _deref_fn(dit._deref_fn) {} + dereference_iterator_adaptor(Iterator it, DFn deref_fn=DFn()) : parent_t(it), _deref_fn(deref_fn) {} + template + dereference_iterator_adaptor(const dereference_iterator_adaptor& it) : parent_t(it.base()), _deref_fn(it._deref_fn) {} + /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { return *(*this+d);} + + // although iterator_adaptor defines these, the default implementation computes distance and compares for zero. + // it is often faster to just apply the relation operator to the base + bool operator> (const dereference_iterator_adaptor& p) const { return this->base_reference()> p.base_reference(); } + bool operator< (const dereference_iterator_adaptor& p) const { return this->base_reference()< p.base_reference(); } + bool operator>=(const dereference_iterator_adaptor& p) const { return this->base_reference()>=p.base_reference(); } + bool operator<=(const dereference_iterator_adaptor& p) const { return this->base_reference()<=p.base_reference(); } + bool operator==(const dereference_iterator_adaptor& p) const { return this->base_reference()==p.base_reference(); } + bool operator!=(const dereference_iterator_adaptor& p) const { return this->base_reference()!=p.base_reference(); } + + Iterator& base() { return this->base_reference(); } + const Iterator& base() const { return this->base_reference(); } + const DFn& deref_fn() const { return _deref_fn; } +private: + template + friend class dereference_iterator_adaptor; + friend class boost::iterator_core_access; + + reference dereference() const { return _deref_fn(*(this->base_reference())); } +}; + +template +struct const_iterator_type > { + typedef dereference_iterator_adaptor::type,typename DFn::const_t> type; +}; + +template +struct iterator_is_mutable > : public mpl::bool_ {}; + + +template +struct is_iterator_adaptor > : public mpl::true_{}; + +template +struct iterator_adaptor_get_base > { + typedef I type; +}; + +template +struct iterator_adaptor_rebind,NewBaseIterator> { + typedef dereference_iterator_adaptor type; +}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public is_planar {}; + +template +struct channel_type > : public channel_type {}; + + +///////////////////////////// +// MemoryBasedIteratorConcept +///////////////////////////// + +template +struct byte_to_memunit > : public byte_to_memunit {}; + +template +inline typename std::iterator_traits::difference_type +memunit_step(const dereference_iterator_adaptor& p) { + return memunit_step(p.base()); +} + +template +inline typename std::iterator_traits::difference_type +memunit_distance(const dereference_iterator_adaptor& p1, + const dereference_iterator_adaptor& p2) { + return memunit_distance(p1.base(),p2.base()); +} + +template +inline void memunit_advance(dereference_iterator_adaptor& p, + typename std::iterator_traits::difference_type diff) { + memunit_advance(p.base(), diff); +} + +template +inline dereference_iterator_adaptor +memunit_advanced(const dereference_iterator_adaptor& p, + typename std::iterator_traits::difference_type diff) { + return dereference_iterator_adaptor(memunit_advanced(p.base(), diff), p.deref_fn()); +} + + +template +inline +typename std::iterator_traits >::reference +memunit_advanced_ref(const dereference_iterator_adaptor& p, + typename std::iterator_traits::difference_type diff) { + return *memunit_advanced(p, diff); +} + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef dereference_iterator_adaptor::type,DFn> type; +}; + +/// \brief Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor upon dereferencing +/// \ingroup PixelIteratorModelDerefPtr +template +struct iterator_add_deref { + GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) + + typedef dereference_iterator_adaptor type; + + static type make(const Iterator& it, const Deref& d) { return type(it,d); } +}; + +/// \ingroup PixelIteratorModelDerefPtr +/// \brief For dereference iterator adaptors, compose the new function object after the old one +template +struct iterator_add_deref,Deref> { +// GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) + + typedef dereference_iterator_adaptor > type; + + static type make(const dereference_iterator_adaptor& it, const Deref& d) { + return type(it.base(),deref_compose(d,it.deref_fn())); + } +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/planar_pixel_iterator.hpp b/thirdparty/boost/gil/planar_pixel_iterator.hpp new file mode 100644 index 0000000..34acab1 --- /dev/null +++ b/thirdparty/boost/gil/planar_pixel_iterator.hpp @@ -0,0 +1,227 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PLANAR_PTR_H +#define GIL_PLANAR_PTR_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief planar pixel pointer class +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "gil_config.hpp" +#include "pixel.hpp" +#include "step_iterator.hpp" + +namespace boost { namespace gil { + +//forward declaration (as this file is included in planar_pixel_reference.hpp) +template +struct planar_pixel_reference; + +/// \defgroup ColorBaseModelPlanarPtr planar_pixel_iterator +/// \ingroup ColorBaseModel +/// \brief A homogeneous color base whose element is a channel iterator. Models HomogeneousColorBaseValueConcept +/// This class is used as an iterator to a planar pixel. + +/// \defgroup PixelIteratorModelPlanarPtr planar_pixel_iterator +/// \ingroup PixelIteratorModel +/// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept + +//////////////////////////////////////////////////////////////////////////////////////// +/// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept +/// +/// Planar pixels have channel data that is not consecutive in memory. +/// To abstract this we use classes to represent references and pointers to planar pixels. +/// +/// \ingroup PixelIteratorModelPlanarPtr ColorBaseModelPlanarPtr PixelBasedModel +template +struct planar_pixel_iterator : public iterator_facade, + pixel::value_type,layout >, + random_access_traversal_tag, + const planar_pixel_reference::reference,ColorSpace> >, + public detail::homogeneous_color_base,mpl::size::value > { +private: + typedef iterator_facade, + pixel::value_type,layout >, + random_access_traversal_tag, + const planar_pixel_reference::reference,ColorSpace> > parent_t; + typedef detail::homogeneous_color_base,mpl::size::value> color_base_parent_t; + typedef typename std::iterator_traits::value_type channel_t; +public: + typedef typename parent_t::value_type value_type; + typedef typename parent_t::reference reference; + typedef typename parent_t::difference_type difference_type; + + planar_pixel_iterator() : color_base_parent_t(0) {} + planar_pixel_iterator(bool) {} // constructor that does not fill with zero (for performance) + + planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1) : color_base_parent_t(v0,v1) {} + planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2) : color_base_parent_t(v0,v1,v2) {} + planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3) : color_base_parent_t(v0,v1,v2,v3) {} + planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3, const ChannelPtr& v4) : color_base_parent_t(v0,v1,v2,v3,v4) {} + + template + planar_pixel_iterator(const planar_pixel_iterator& ptr) : color_base_parent_t(ptr) {} + + + /// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references. + /// That allow constructs like pointer = &value or pointer = &reference + /// Since we should not override operator& that's the best we can do. + template + planar_pixel_iterator(P* pix) : color_base_parent_t(pix, true) { + function_requires >(); + } + + struct address_of { template T* operator()(T& t) { return &t; } }; + template + planar_pixel_iterator& operator=(P* pix) { + function_requires >(); + static_transform(*pix,*this, address_of()); + + // PERFORMANCE_CHECK: Compare to this: + //this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>(); + //this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>(); + //this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>(); + return *this; + } + + /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));} + + reference operator->() const { return **this; } + + // PERFORMANCE_CHECK: Remove? + bool operator< (const planar_pixel_iterator& ptr) const { return at_c<0>(*this)< at_c<0>(ptr); } + bool operator!=(const planar_pixel_iterator& ptr) const { return at_c<0>(*this)!=at_c<0>(ptr); } +private: + friend class boost::iterator_core_access; + + void increment() { static_transform(*this,*this,detail::inc()); } + void decrement() { static_transform(*this,*this,detail::dec()); } + void advance(ptrdiff_t d) { static_transform(*this,*this,std::bind2nd(detail::plus_asymmetric(),d)); } + reference dereference() const { return this->template deref(); } + + ptrdiff_t distance_to(const planar_pixel_iterator& it) const { return at_c<0>(it)-at_c<0>(*this); } + bool equal(const planar_pixel_iterator& it) const { return at_c<0>(*this)==at_c<0>(it); } +}; + +namespace detail { + template struct channel_iterator_is_mutable : public mpl::true_ {}; + template struct channel_iterator_is_mutable : public mpl::false_ {}; +} + +template +struct const_iterator_type > { +private: + typedef typename std::iterator_traits::value_type channel_t; +public: + typedef planar_pixel_iterator::const_pointer,C> type; +}; + +// The default implementation when the iterator is a C pointer is to use the standard constness semantics +template +struct iterator_is_mutable > : public detail::channel_iterator_is_mutable {}; + +///////////////////////////// +// ColorBasedConcept +///////////////////////////// + +template +struct kth_element_type, K> { + typedef IC type; +}; + +template +struct kth_element_reference_type, K> : public add_reference {}; + +template +struct kth_element_const_reference_type, K> : public add_reference::type> {}; + +///////////////////////////// +// HomogeneousPixelBasedConcept +///////////////////////////// + +template +struct color_space_type > { + typedef C type; +}; + +template +struct channel_mapping_type > : public channel_mapping_type::value_type> {}; + +template +struct is_planar > : public mpl::true_ {}; + +template +struct channel_type > { + typedef typename std::iterator_traits::value_type type; +}; + +///////////////////////////// +// MemoryBasedIteratorConcept +///////////////////////////// + +template +inline std::ptrdiff_t memunit_step(const planar_pixel_iterator&) { return sizeof(typename std::iterator_traits::value_type); } + +template +inline std::ptrdiff_t memunit_distance(const planar_pixel_iterator& p1, const planar_pixel_iterator& p2) { + return memunit_distance(at_c<0>(p1),at_c<0>(p2)); +} + +template +struct memunit_advance_fn { + memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {} + IC operator()(const IC& p) const { return memunit_advanced(p,_diff); } + + std::ptrdiff_t _diff; +}; + +template +inline void memunit_advance(planar_pixel_iterator& p, std::ptrdiff_t diff) { + static_transform(p, p, memunit_advance_fn(diff)); +} + +template +inline planar_pixel_iterator memunit_advanced(const planar_pixel_iterator& p, std::ptrdiff_t diff) { + planar_pixel_iterator ret=p; + memunit_advance(ret, diff); + return ret; +} + +template +inline planar_pixel_reference::reference,ColorSpace> + memunit_advanced_ref(const planar_pixel_iterator& ptr, std::ptrdiff_t diff) { + return planar_pixel_reference::reference,ColorSpace>(ptr, diff); +} + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef memory_based_step_iterator > type; +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/planar_pixel_reference.hpp b/thirdparty/boost/gil/planar_pixel_reference.hpp new file mode 100644 index 0000000..fb09450 --- /dev/null +++ b/thirdparty/boost/gil/planar_pixel_reference.hpp @@ -0,0 +1,186 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_PLANAR_REF_H +#define GIL_PLANAR_REF_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief planar pixel reference class +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 28, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include "gil_concept.hpp" +#include "color_base.hpp" +#include "channel.hpp" +#include "pixel.hpp" +#include "planar_pixel_iterator.hpp" + +namespace boost { namespace gil { + +/// \defgroup ColorBaseModelPlanarRef planar_pixel_reference +/// \ingroup ColorBaseModel +/// \brief A homogeneous color base whose element is a channel reference. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept. +/// This class is used as a reference proxy to a planar pixel. + +/// \defgroup PixelModelPlanarRef planar_pixel_reference +/// \ingroup PixelModel +/// \brief A reference proxy to a planar pixel. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept. + + +/// \ingroup PixelModelPlanarRef ColorBaseModelPlanarRef PixelBasedModel +/// \brief A reference proxy to a planar pixel. Models: HomogeneousColorBaseConcept, HomogeneousPixelConcept +/// +/// A reference to a planar pixel is a proxy class containing references to each of the corresponding channels. +/// +template // ChannelReference is a channel reference (const or mutable) +struct planar_pixel_reference + : public detail::homogeneous_color_base,mpl::size::value> { + typedef detail::homogeneous_color_base,mpl::size::value> parent_t; +private: + // These three are only defined for homogeneous pixels + typedef typename channel_traits::value_type channel_t; + typedef typename channel_traits::const_reference channel_const_reference; +public: + BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits::is_mutable); + typedef pixel > value_type; + typedef planar_pixel_reference reference; + typedef planar_pixel_reference const_reference; + + planar_pixel_reference(ChannelReference v0, ChannelReference v1) : parent_t(v0,v1) {} + planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2) : parent_t(v0,v1,v2) {} + planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3) : parent_t(v0,v1,v2,v3) {} + planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4) : parent_t(v0,v1,v2,v3,v4) {} + planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4, ChannelReference v5) : parent_t(v0,v1,v2,v3,v4,v5) {} + + template planar_pixel_reference(const P& p) : parent_t(p) { check_compatible

            ();} + + // PERFORMANCE_CHECK: Is this constructor necessary? + template + planar_pixel_reference(pixel >& p) : parent_t(p) { check_compatible > >();} + + // Construct at offset from a given location + template planar_pixel_reference(const planar_pixel_iterator& p, std::ptrdiff_t diff) : parent_t(p,diff) {} + + const planar_pixel_reference& operator=(const planar_pixel_reference& p) const { static_copy(p,*this); return *this; } + template const planar_pixel_reference& operator=(const P& p) const { check_compatible

            (); static_copy(p,*this); return *this; } + + template bool operator==(const P& p) const { check_compatible

            (); return static_equal(*this,p); } + template bool operator!=(const P& p) const { return !(*this==p); } + + ChannelReference operator[](std::size_t i) const { return this->at_c_dynamic(i); } + + const planar_pixel_reference* operator->() const { return this; } +private: + template static void check_compatible() { gil_function_requires >(); } +}; + +///////////////////////////// +// ColorBasedConcept +///////////////////////////// + +template +struct kth_element_type, K> { + typedef ChannelReference type; +}; + +template +struct kth_element_reference_type, K> { + typedef ChannelReference type; +}; + +template +struct kth_element_const_reference_type, K> + : public add_reference::type> +{ +// typedef typename channel_traits::const_reference type; +}; + +///////////////////////////// +// PixelConcept +///////////////////////////// + +/// \brief Metafunction predicate that flags planar_pixel_reference as a model of PixelConcept. Required by PixelConcept +/// \ingroup PixelModelPlanarRef +template +struct is_pixel< planar_pixel_reference > : public mpl::true_{}; + +///////////////////////////// +// HomogeneousPixelBasedConcept +///////////////////////////// + +/// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept +/// \ingroup PixelModelPlanarRef +template +struct color_space_type > { + typedef ColorSpace type; +}; + +/// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept +/// \ingroup PixelModelPlanarRef +template +struct channel_mapping_type > { + typedef typename layout::channel_mapping_t type; +}; + +/// \brief Specifies that planar_pixel_reference represents a planar construct. Required by PixelBasedConcept +/// \ingroup PixelModelPlanarRef +template +struct is_planar > : mpl::true_ {}; + +/// \brief Specifies the color space type of a planar pixel reference. Required by HomogeneousPixelBasedConcept +/// \ingroup PixelModelPlanarRef +template +struct channel_type > { + typedef typename channel_traits::value_type type; +}; + +} } // namespace boost::gil + +namespace std { +// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified. +// swap with 'left bias': +// - swap between proxy and anything +// - swap between value type and proxy +// - swap between proxy and proxy +// Having three overloads allows us to swap between different (but compatible) models of PixelConcept + +/// \brief swap for planar_pixel_reference +/// \ingroup PixelModelPlanarRef +template inline +void swap(boost::gil::planar_pixel_reference x, R& y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \brief swap for planar_pixel_reference +/// \ingroup PixelModelPlanarRef +template inline +void swap(typename boost::gil::planar_pixel_reference::value_type& x, boost::gil::planar_pixel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} + + +/// \brief swap for planar_pixel_reference +/// \ingroup PixelModelPlanarRef +template inline +void swap(boost::gil::planar_pixel_reference x, boost::gil::planar_pixel_reference y) { + boost::gil::swap_proxy::value_type>(x,y); +} +} // namespace std + +#endif diff --git a/thirdparty/boost/gil/position_iterator.hpp b/thirdparty/boost/gil/position_iterator.hpp new file mode 100644 index 0000000..f2c780b --- /dev/null +++ b/thirdparty/boost/gil/position_iterator.hpp @@ -0,0 +1,121 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_POSITION_ITERATOR_HPP +#define GIL_POSITION_ITERATOR_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Locator for virtual image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "locator.hpp" + +namespace boost { namespace gil { + +/// \defgroup PixelIteratorModelVirtual position_iterator +/// \ingroup PixelIteratorModel +/// \brief An iterator that remembers its current X,Y position and invokes a function object with it upon dereferencing. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept. Used to create virtual image views. + + +/// \brief An iterator that remembers its current X,Y position and invokes a function object with it upon dereferencing. Models PixelIteratorConcept. Used to create virtual image views. +/// Models: StepIteratorConcept, PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept +/// \ingroup PixelIteratorModelVirtual PixelBasedModel +template // the dimension to advance along +struct position_iterator : public iterator_facade, + typename Deref::value_type, + random_access_traversal_tag, + typename Deref::reference, + typename Deref::argument_type::template axis::coord_t> { + typedef iterator_facade, + typename Deref::value_type, + random_access_traversal_tag, + typename Deref::reference, + typename Deref::argument_type::template axis::coord_t> parent_t; + typedef typename parent_t::difference_type difference_type; + typedef typename parent_t::reference reference; + typedef typename Deref::argument_type point_t; + + position_iterator() {} + position_iterator(const point_t& p, const point_t& step, const Deref& d) : _p(p), _step(step), _d(d) {} + + position_iterator(const position_iterator& p) : _p(p._p), _step(p._step), _d(p._d) {} + template position_iterator(const position_iterator& p) : _p(p._p), _step(p._step), _d(p._d) {} + position_iterator& operator=(const position_iterator& p) { _p=p._p; _d=p._d; _step=p._step; return *this; } + + const point_t& pos() const { return _p; } + const point_t& step() const { return _step; } + const Deref& deref_fn() const { return _d; } + + void set_step(difference_type s) { _step[Dim]=s; } + /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { point_t p=_p; p[Dim]+=d*_step[Dim]; return _d(p); } + +private: + point_t _p, _step; + Deref _d; + + template friend struct position_iterator; + friend class boost::iterator_core_access; + reference dereference() const { return _d(_p); } + void increment() { _p[Dim]+=_step[Dim]; } + void decrement() { _p[Dim]-=_step[Dim]; } + void advance(difference_type d) { _p[Dim]+=d*_step[Dim]; } + + difference_type distance_to(const position_iterator& it) const { return (it._p[Dim]-_p[Dim])/_step[Dim]; } + bool equal(const position_iterator& it) const { return _p==it._p; } +}; + +template +struct const_iterator_type > { + typedef position_iterator type; +}; + +template +struct iterator_is_mutable > : public mpl::bool_ { +}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public mpl::false_ {}; + +template +struct channel_type > : public channel_type {}; + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef position_iterator type; +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/rgb.hpp b/thirdparty/boost/gil/rgb.hpp new file mode 100644 index 0000000..843e1ce --- /dev/null +++ b/thirdparty/boost/gil/rgb.hpp @@ -0,0 +1,70 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_RGB_H +#define GIL_RGB_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for RGB color space and variants +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on October 10, 2007 +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "gil_config.hpp" +#include "metafunctions.hpp" +#include "planar_pixel_iterator.hpp" + +namespace boost { namespace gil { + +/// \addtogroup ColorNameModel +/// \{ + +/// \brief Red +struct red_t {}; + +/// \brief Green +struct green_t {}; + +/// \brief Blue +struct blue_t {}; +/// \} + +/// \ingroup ColorSpaceModel +typedef mpl::vector3 rgb_t; + +/// \ingroup LayoutModel +typedef layout rgb_layout_t; +/// \ingroup LayoutModel +typedef layout > bgr_layout_t; + +/// \ingroup ImageViewConstructors +/// \brief from raw RGB planar data +template +inline +typename type_from_x_iterator >::view_t +planar_rgb_view(std::size_t width, std::size_t height, + IC r, IC g, IC b, + std::ptrdiff_t rowsize_in_bytes) { + typedef typename type_from_x_iterator >::view_t RView; + return RView(width, height, + typename RView::locator(planar_pixel_iterator(r,g,b), + rowsize_in_bytes)); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/rgba.hpp b/thirdparty/boost/gil/rgba.hpp new file mode 100644 index 0000000..b2a832d --- /dev/null +++ b/thirdparty/boost/gil/rgba.hpp @@ -0,0 +1,63 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ +/*************************************************************************************************/ + +#ifndef GIL_RGBA_H +#define GIL_RGBA_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for RGBA color space and variants +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on October 10, 2007 +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "gil_config.hpp" +#include +#include "rgb.hpp" +#include "planar_pixel_iterator.hpp" + +namespace boost { namespace gil { + +/// \ingroup ColorNameModel +/// \brief Alpha +struct alpha_t {}; + +/// \ingroup ColorSpaceModel +typedef mpl::vector4 rgba_t; + +/// \ingroup LayoutModel +typedef layout rgba_layout_t; +/// \ingroup LayoutModel +typedef layout > bgra_layout_t; +/// \ingroup LayoutModel +typedef layout > argb_layout_t; +/// \ingroup LayoutModel +typedef layout > abgr_layout_t; + +/// \ingroup ImageViewConstructors +/// \brief from raw RGBA planar data +template +inline +typename type_from_x_iterator >::view_t +planar_rgba_view(std::size_t width, std::size_t height, + IC r, IC g, IC b, IC a, + std::ptrdiff_t rowsize_in_bytes) { + typedef typename type_from_x_iterator >::view_t RView; + return RView(width, height, + typename RView::locator(planar_pixel_iterator(r,g,b,a), + rowsize_in_bytes)); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/step_iterator.hpp b/thirdparty/boost/gil/step_iterator.hpp new file mode 100644 index 0000000..a84812d --- /dev/null +++ b/thirdparty/boost/gil/step_iterator.hpp @@ -0,0 +1,320 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_STEP_ITERATOR_H +#define GIL_STEP_ITERATOR_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief pixel step iterator +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 18, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "gil_config.hpp" +#include "utilities.hpp" +#include "pixel_iterator.hpp" +#include "pixel_iterator_adaptor.hpp" + +namespace boost { namespace gil { + +/// \defgroup PixelIteratorModelStepPtr step iterators +/// \ingroup PixelIteratorModel +/// \brief Iterators that allow for specifying the step between two adjacent values + + +namespace detail { + +/// \ingroup PixelIteratorModelStepPtr +/// \brief An adaptor over an existing iterator that changes the step unit +/// +/// (i.e. distance(it,it+1)) by a given predicate. Instead of calling base's +/// operators ++, --, +=, -=, etc. the adaptor is using the passed policy object SFn +/// for advancing and for computing the distance between iterators. + +template // A policy object that can compute the distance between two iterators of type Iterator + // and can advance an iterator of type Iterator a given number of Iterator's units +class step_iterator_adaptor : public iterator_adaptor { +public: + typedef iterator_adaptor parent_t; + typedef typename std::iterator_traits::difference_type base_difference_type; + typedef typename SFn::difference_type difference_type; + typedef typename std::iterator_traits::reference reference; + + step_iterator_adaptor() {} + step_iterator_adaptor(const Iterator& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {} + + difference_type step() const { return _step_fn.step(); } + +protected: + SFn _step_fn; +private: + friend class boost::iterator_core_access; + + void increment() { _step_fn.advance(this->base_reference(),1); } + void decrement() { _step_fn.advance(this->base_reference(),-1); } + void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); } + difference_type distance_to(const step_iterator_adaptor& it) const { return _step_fn.difference(this->base_reference(),it.base_reference()); } +}; + +// although iterator_adaptor defines these, the default implementation computes distance and compares for zero. +// it is often faster to just apply the relation operator to the base +template inline +bool operator>(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.step()>0 ? p1.base()> p2.base() : p1.base()< p2.base(); +} + +template inline +bool operator<(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.step()>0 ? p1.base()< p2.base() : p1.base()> p2.base(); +} + +template inline +bool operator>=(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.step()>0 ? p1.base()>=p2.base() : p1.base()<=p2.base(); +} + +template inline +bool operator<=(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.step()>0 ? p1.base()<=p2.base() : p1.base()>=p2.base(); +} + +template inline +bool operator==(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.base()==p2.base(); +} + +template inline +bool operator!=(const step_iterator_adaptor& p1, const step_iterator_adaptor& p2) { + return p1.base()!=p2.base(); +} + +} // namespace detail + +//////////////////////////////////////////////////////////////////////////////////////// +/// MEMORY-BASED STEP ITERATOR +//////////////////////////////////////////////////////////////////////////////////////// + +/// \class memory_based_step_iterator +/// \ingroup PixelIteratorModelStepPtr PixelBasedModel +/// \brief Iterator with dynamically specified step in memory units (bytes or bits). Models StepIteratorConcept, IteratorAdaptorConcept, MemoryBasedIteratorConcept, PixelIteratorConcept, HasDynamicXStepTypeConcept +/// +/// A refinement of step_iterator_adaptor that uses a dynamic parameter for the step +/// which is specified in memory units, such as bytes or bits +/// +/// Pixel step iterators are used to provide iteration over non-adjacent pixels. +/// Common use is a vertical traversal, where the step is the row stride. +/// +/// Another application is as a sub-channel view. For example, a red intensity image over +/// interleaved RGB data would use a step iterator adaptor with step sizeof(channel_t)*3 +/// In the latter example the step size could be fixed at compile time for efficiency. +/// Compile-time fixed step can be implemented by providing a step function object that takes the step as a template +//////////////////////////////////////////////////////////////////////////////////////// + +/// \ingroup PixelIteratorModelStepPtr +/// \brief function object that returns the memory unit distance between two iterators and advances a given iterator a given number of mem units (bytes or bits) +template +struct memunit_step_fn { + typedef std::ptrdiff_t difference_type; + + memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {} + + difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; } + void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); } + difference_type step() const { return _step; } + + void set_step(std::ptrdiff_t step) { _step=step; } +private: + GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept) + difference_type _step; +}; + +template +class memory_based_step_iterator : public detail::step_iterator_adaptor, + Iterator, + memunit_step_fn > { + GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept) +public: + typedef detail::step_iterator_adaptor, + Iterator, + memunit_step_fn > parent_t; + typedef typename parent_t::reference reference; + typedef typename parent_t::difference_type difference_type; + typedef Iterator x_iterator; + + memory_based_step_iterator() : parent_t(Iterator()) {} + memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn(memunit_step)) {} + template + memory_based_step_iterator(const memory_based_step_iterator& it) + : parent_t(it.base(), memunit_step_fn(it.step())) {} + + /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference + /// We require our own reference because it is registered in iterator_traits + reference operator[](difference_type d) const { return *(*this+d); } + + void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); } + + x_iterator& base() { return parent_t::base_reference(); } + x_iterator const& base() const { return parent_t::base_reference(); } +}; + +template +struct const_iterator_type > { + typedef memory_based_step_iterator::type> type; +}; + +template +struct iterator_is_mutable > : public iterator_is_mutable {}; + + +///////////////////////////// +// IteratorAdaptorConcept +///////////////////////////// + +template +struct is_iterator_adaptor > : public mpl::true_{}; + +template +struct iterator_adaptor_get_base > { + typedef Iterator type; +}; + +template +struct iterator_adaptor_rebind,NewBaseIterator> { + typedef memory_based_step_iterator type; +}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct color_space_type > : public color_space_type {}; + +template +struct channel_mapping_type > : public channel_mapping_type {}; + +template +struct is_planar > : public is_planar {}; + +template +struct channel_type > : public channel_type {}; + +///////////////////////////// +// MemoryBasedIteratorConcept +///////////////////////////// +template +struct byte_to_memunit > : public byte_to_memunit {}; + +template +inline std::ptrdiff_t memunit_step(const memory_based_step_iterator& p) { return p.step(); } + +template +inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator& p1, + const memory_based_step_iterator& p2) { + return memunit_distance(p1.base(),p2.base()); +} + +template +inline void memunit_advance(memory_based_step_iterator& p, + std::ptrdiff_t diff) { + memunit_advance(p.base(), diff); +} + +template +inline memory_based_step_iterator +memunit_advanced(const memory_based_step_iterator& p, + std::ptrdiff_t diff) { + return memory_based_step_iterator(memunit_advanced(p.base(), diff),p.step()); +} + +template +inline typename std::iterator_traits::reference +memunit_advanced_ref(const memory_based_step_iterator& p, + std::ptrdiff_t diff) { + return memunit_advanced_ref(p.base(), diff); +} + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef memory_based_step_iterator type; +}; + +// For step iterators, pass the function object to the base +template +struct iterator_add_deref,Deref> { + GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) + + typedef memory_based_step_iterator::type> type; + + static type make(const memory_based_step_iterator& it, const Deref& d) { return type(iterator_add_deref::make(it.base(),d),it.step()); } +}; + +//////////////////////////////////////////////////////////////////////////////////////// +/// make_step_iterator +//////////////////////////////////////////////////////////////////////////////////////// + +template typename dynamic_x_step_type::type make_step_iterator(const I& it, std::ptrdiff_t step); + +namespace detail { + +// if the iterator is a plain base iterator (non-adaptor), wraps it in memory_based_step_iterator +template +typename dynamic_x_step_type::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::false_) { + return memory_based_step_iterator(it, step); +} + +// If the iterator is compound, put the step in its base +template +typename dynamic_x_step_type::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::true_) { + return make_step_iterator(it.base(), step); +} + +// If the iterator is memory_based_step_iterator, change the step +template +memory_based_step_iterator make_step_iterator_impl(const memory_based_step_iterator& it, std::ptrdiff_t step, mpl::true_) { + return memory_based_step_iterator(it.base(), step); +} +} + +/// \brief Constructs a step iterator from a base iterator and a step. +/// +/// To construct a step iterator from a given iterator Iterator and a given step, if Iterator does not +/// already have a dynamic step, we wrap it in a memory_based_step_iterator. Otherwise we +/// do a compile-time traversal of the chain of iterator adaptors to locate the step iterator +/// and then set it step to the new one. +/// +/// The step iterator of Iterator is not always memory_based_step_iterator. For example, Iterator may +/// already be a memory_based_step_iterator, in which case it will be inefficient to stack them; +/// we can obtain the same result by multiplying their steps. Note that for Iterator to be a +/// step iterator it does not necessarily have to have the form memory_based_step_iterator. +/// The step iterator can be wrapped inside another iterator. Also, it may not have the +/// type memory_based_step_iterator, but it could be a user-provided type. +template // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept +typename dynamic_x_step_type::type make_step_iterator(const I& it, std::ptrdiff_t step) { + return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor::type()); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/typedefs.hpp b/thirdparty/boost/gil/typedefs.hpp new file mode 100644 index 0000000..d3d233f --- /dev/null +++ b/thirdparty/boost/gil/typedefs.hpp @@ -0,0 +1,196 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_TYPEDEFS_H +#define GIL_TYPEDEFS_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Useful typedefs +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on March 8, 2006 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "gil_config.hpp" +#include +#include "gray.hpp" +#include "rgb.hpp" +#include "rgba.hpp" +#include "cmyk.hpp" +#include "device_n.hpp" +#include + +// CS = 'bgr' LAYOUT='bgr_layout_t' +#define GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,LAYOUT) \ + template struct pixel; \ + template struct planar_pixel_reference; \ + template struct planar_pixel_iterator; \ + template class memory_based_step_iterator; \ + template class point2; \ + template class memory_based_2d_locator; \ + template class image_view; \ + template class image; \ + typedef pixel CS##T##_pixel_t; \ + typedef const pixel CS##T##c_pixel_t; \ + typedef pixel& CS##T##_ref_t; \ + typedef const pixel& CS##T##c_ref_t; \ + typedef CS##T##_pixel_t* CS##T##_ptr_t; \ + typedef CS##T##c_pixel_t* CS##T##c_ptr_t; \ + typedef memory_based_step_iterator CS##T##_step_ptr_t; \ + typedef memory_based_step_iterator CS##T##c_step_ptr_t; \ + typedef memory_based_2d_locator > CS##T##_loc_t; \ + typedef memory_based_2d_locator > CS##T##c_loc_t; \ + typedef memory_based_2d_locator > CS##T##_step_loc_t; \ + typedef memory_based_2d_locator > CS##T##c_step_loc_t; \ + typedef image_view CS##T##_view_t; \ + typedef image_view CS##T##c_view_t; \ + typedef image_view CS##T##_step_view_t; \ + typedef image_view CS##T##c_step_view_t; \ + typedef image > CS##T##_image_t; + +// CS = 'bgr' CS_FULL = 'rgb_t' LAYOUT='bgr_layout_t' +#define GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(T,CS,CS_FULL,LAYOUT) \ + GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,LAYOUT) \ + typedef planar_pixel_reference CS##T##_planar_ref_t; \ + typedef planar_pixel_reference CS##T##c_planar_ref_t; \ + typedef planar_pixel_iterator CS##T##_planar_ptr_t; \ + typedef planar_pixel_iterator CS##T##c_planar_ptr_t; \ + typedef memory_based_step_iterator CS##T##_planar_step_ptr_t; \ + typedef memory_based_step_iterator CS##T##c_planar_step_ptr_t; \ + typedef memory_based_2d_locator > CS##T##_planar_loc_t; \ + typedef memory_based_2d_locator > CS##T##c_planar_loc_t; \ + typedef memory_based_2d_locator > CS##T##_planar_step_loc_t; \ + typedef memory_based_2d_locator > CS##T##c_planar_step_loc_t; \ + typedef image_view CS##T##_planar_view_t; \ + typedef image_view CS##T##c_planar_view_t; \ + typedef image_view CS##T##_planar_step_view_t; \ + typedef image_view CS##T##c_planar_step_view_t;\ + typedef image > CS##T##_planar_image_t; + +#define GIL_DEFINE_BASE_TYPEDEFS(T,CS) \ + GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,CS##_layout_t) + +#define GIL_DEFINE_ALL_TYPEDEFS(T,CS) \ + GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(T,CS,CS##_t,CS##_layout_t) + +namespace boost { namespace gil { + +// forward declarations +template struct scoped_channel_value; +struct float_zero; +struct float_one; +typedef scoped_channel_value bits32f; +typedef uint8_t bits8; +typedef uint16_t bits16; +typedef uint32_t bits32; +typedef int8_t bits8s; +typedef int16_t bits16s; +typedef int32_t bits32s; + +GIL_DEFINE_BASE_TYPEDEFS(8, gray) +GIL_DEFINE_BASE_TYPEDEFS(8s, gray) +GIL_DEFINE_BASE_TYPEDEFS(16, gray) +GIL_DEFINE_BASE_TYPEDEFS(16s,gray) +GIL_DEFINE_BASE_TYPEDEFS(32 ,gray) +GIL_DEFINE_BASE_TYPEDEFS(32s,gray) +GIL_DEFINE_BASE_TYPEDEFS(32f,gray) +GIL_DEFINE_BASE_TYPEDEFS(8, bgr) +GIL_DEFINE_BASE_TYPEDEFS(8s, bgr) +GIL_DEFINE_BASE_TYPEDEFS(16, bgr) +GIL_DEFINE_BASE_TYPEDEFS(16s,bgr) +GIL_DEFINE_BASE_TYPEDEFS(32 ,bgr) +GIL_DEFINE_BASE_TYPEDEFS(32s,bgr) +GIL_DEFINE_BASE_TYPEDEFS(32f,bgr) +GIL_DEFINE_BASE_TYPEDEFS(8, argb) +GIL_DEFINE_BASE_TYPEDEFS(8s, argb) +GIL_DEFINE_BASE_TYPEDEFS(16, argb) +GIL_DEFINE_BASE_TYPEDEFS(16s,argb) +GIL_DEFINE_BASE_TYPEDEFS(32, argb) +GIL_DEFINE_BASE_TYPEDEFS(32s,argb) +GIL_DEFINE_BASE_TYPEDEFS(32f,argb) +GIL_DEFINE_BASE_TYPEDEFS(8, abgr) +GIL_DEFINE_BASE_TYPEDEFS(8s, abgr) +GIL_DEFINE_BASE_TYPEDEFS(16, abgr) +GIL_DEFINE_BASE_TYPEDEFS(16s,abgr) +GIL_DEFINE_BASE_TYPEDEFS(32 ,abgr) +GIL_DEFINE_BASE_TYPEDEFS(32s,abgr) +GIL_DEFINE_BASE_TYPEDEFS(32f,abgr) +GIL_DEFINE_BASE_TYPEDEFS(8, bgra) +GIL_DEFINE_BASE_TYPEDEFS(8s, bgra) +GIL_DEFINE_BASE_TYPEDEFS(16, bgra) +GIL_DEFINE_BASE_TYPEDEFS(16s,bgra) +GIL_DEFINE_BASE_TYPEDEFS(32 ,bgra) +GIL_DEFINE_BASE_TYPEDEFS(32s,bgra) +GIL_DEFINE_BASE_TYPEDEFS(32f,bgra) + +GIL_DEFINE_ALL_TYPEDEFS(8, rgb) +GIL_DEFINE_ALL_TYPEDEFS(8s, rgb) +GIL_DEFINE_ALL_TYPEDEFS(16, rgb) +GIL_DEFINE_ALL_TYPEDEFS(16s,rgb) +GIL_DEFINE_ALL_TYPEDEFS(32 ,rgb) +GIL_DEFINE_ALL_TYPEDEFS(32s,rgb) +GIL_DEFINE_ALL_TYPEDEFS(32f,rgb) +GIL_DEFINE_ALL_TYPEDEFS(8, rgba) +GIL_DEFINE_ALL_TYPEDEFS(8s, rgba) +GIL_DEFINE_ALL_TYPEDEFS(16, rgba) +GIL_DEFINE_ALL_TYPEDEFS(16s,rgba) +GIL_DEFINE_ALL_TYPEDEFS(32 ,rgba) +GIL_DEFINE_ALL_TYPEDEFS(32s,rgba) +GIL_DEFINE_ALL_TYPEDEFS(32f,rgba) +GIL_DEFINE_ALL_TYPEDEFS(8, cmyk) +GIL_DEFINE_ALL_TYPEDEFS(8s, cmyk) +GIL_DEFINE_ALL_TYPEDEFS(16, cmyk) +GIL_DEFINE_ALL_TYPEDEFS(16s,cmyk) +GIL_DEFINE_ALL_TYPEDEFS(32 ,cmyk) +GIL_DEFINE_ALL_TYPEDEFS(32s,cmyk) +GIL_DEFINE_ALL_TYPEDEFS(32f,cmyk) + + +template struct devicen_t; +template struct devicen_layout_t; +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev2n, devicen_t<2>, devicen_layout_t<2>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev2n, devicen_t<2>, devicen_layout_t<2>) + +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev3n, devicen_t<3>, devicen_layout_t<3>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev3n, devicen_t<3>, devicen_layout_t<3>) + +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev4n, devicen_t<4>, devicen_layout_t<4>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev4n, devicen_t<4>, devicen_layout_t<4>) + +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev5n, devicen_t<5>, devicen_layout_t<5>) +GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev5n, devicen_t<5>, devicen_layout_t<5>) + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/utilities.hpp b/thirdparty/boost/gil/utilities.hpp new file mode 100644 index 0000000..38df8da --- /dev/null +++ b/thirdparty/boost/gil/utilities.hpp @@ -0,0 +1,331 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_UTILITIES_H +#define GIL_UTILITIES_H + +#include "gil_config.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Various utilities not specific to the image library. Some are non-standard STL extensions or generic iterator adaptors +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on September 18, 2007 +/// +/// +//////////////////////////////////////////////////////////////////////////////////////// + +namespace boost { namespace gil { + +/** +\addtogroup PointModel + +Example: +\code +point2 p(3,2); +assert((p[0] == p.x) && (p[1] == p.y)); +assert(axis_value<0>(p) == 3); +assert(axis_value<1>(p) == 2); +\endcode +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// CLASS point2 +/// +/// \brief 2D point both axes of which have the same dimension type +/// \ingroup PointModel +/// Models: Point2DConcept +/// +//////////////////////////////////////////////////////////////////////////////////////// + +template +class point2 { +public: + typedef T value_type; + template struct axis { typedef value_type coord_t; }; + static const std::size_t num_dimensions=2; + + point2() : x(0), y(0) {} + point2(T newX, T newY) : x(newX), y(newY) {} + point2(const point2& p) : x(p.x), y(p.y) {} + ~point2() {} + + point2& operator=(const point2& p) { x=p.x; y=p.y; return *this; } + + point2 operator<<(std::ptrdiff_t shift) const { return point2(x<>(std::ptrdiff_t shift) const { return point2(x>>shift,y>>shift); } + point2& operator+=(const point2& p) { x+=p.x; y+=p.y; return *this; } + point2& operator-=(const point2& p) { x-=p.x; y-=p.y; return *this; } + point2& operator/=(double t) { x/=t; y/=t; return *this; } + + const T& operator[](std::size_t i) const { return this->*mem_array[i]; } + T& operator[](std::size_t i) { return this->*mem_array[i]; } + + T x,y; +private: + // this static array of pointers to member variables makes operator[] safe and doesn't seem to exhibit any performance penalty + static T point2::* const mem_array[num_dimensions]; +}; + +template +T point2::* const point2::mem_array[point2::num_dimensions] = { &point2::x, &point2::y }; + +/// \ingroup PointModel +template GIL_FORCEINLINE +bool operator==(const point2& p1, const point2& p2) { return (p1.x==p2.x && p1.y==p2.y); } +/// \ingroup PointModel +template GIL_FORCEINLINE +bool operator!=(const point2& p1, const point2& p2) { return p1.x!=p2.x || p1.y!=p2.y; } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator+(const point2& p1, const point2& p2) { return point2(p1.x+p2.x,p1.y+p2.y); } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator-(const point2& p) { return point2(-p.x,-p.y); } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator-(const point2& p1, const point2& p2) { return point2(p1.x-p2.x,p1.y-p2.y); } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator/(const point2& p, double t) { return t==0 ? point2(0,0):point2(p.x/t,p.y/t); } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator*(const point2& p, std::ptrdiff_t t) { return point2(p.x*t,p.y*t); } +/// \ingroup PointModel +template GIL_FORCEINLINE +point2 operator*(std::ptrdiff_t t, const point2& p) { return point2(p.x*t,p.y*t); } + +/// \ingroup PointModel +template GIL_FORCEINLINE +const T& axis_value(const point2& p) { return p[K]; } + +/// \ingroup PointModel +template GIL_FORCEINLINE + T& axis_value( point2& p) { return p[K]; } + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// Rounding of real numbers / points to integers / integer points +/// +//////////////////////////////////////////////////////////////////////////////////////// + +inline std::ptrdiff_t iround(float x ) { return static_cast(x + (x < 0.0f ? -0.5f : 0.5f)); } +inline std::ptrdiff_t iround(double x) { return static_cast(x + (x < 0.0 ? -0.5 : 0.5)); } +inline std::ptrdiff_t ifloor(float x ) { return static_cast(std::floor(x)); } +inline std::ptrdiff_t ifloor(double x) { return static_cast(std::floor(x)); } +inline std::ptrdiff_t iceil(float x ) { return static_cast(std::ceil(x)); } +inline std::ptrdiff_t iceil(double x) { return static_cast(std::ceil(x)); } + +/** +\addtogroup PointAlgorithm + +Example: +\code +assert(iround(point2(3.1, 3.9)) == point2(3,4)); +\endcode +*/ + +/// \ingroup PointAlgorithm +inline point2 iround(const point2& p) { return point2(iround(p.x),iround(p.y)); } +/// \ingroup PointAlgorithm +inline point2 iround(const point2& p) { return point2(iround(p.x),iround(p.y)); } +/// \ingroup PointAlgorithm +inline point2 ifloor(const point2& p) { return point2(ifloor(p.x),ifloor(p.y)); } +/// \ingroup PointAlgorithm +inline point2 ifloor(const point2& p) { return point2(ifloor(p.x),ifloor(p.y)); } +/// \ingroup PointAlgorithm +inline point2 iceil (const point2& p) { return point2(iceil(p.x), iceil(p.y)); } +/// \ingroup PointAlgorithm +inline point2 iceil (const point2& p) { return point2(iceil(p.x), iceil(p.y)); } + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// computing size with alignment +/// +//////////////////////////////////////////////////////////////////////////////////////// + +template +inline T align(T val, std::size_t alignment) { + return val+(alignment - val%alignment)%alignment; +} + +/// \brief Helper base class for pixel dereference adaptors. +/// \ingroup PixelDereferenceAdaptorModel +/// +template +struct deref_base : public std::unary_function { + typedef ConstT const_t; + typedef Value value_type; + typedef Reference reference; + typedef ConstReference const_reference; + BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable); +}; + +/// \brief Composes two dereference function objects. Similar to std::unary_compose but needs to pull some typedefs from the component types. Models: PixelDereferenceAdaptorConcept +/// \ingroup PixelDereferenceAdaptorModel +/// +template +class deref_compose : public deref_base< + deref_compose, + typename D1::value_type, typename D1::reference, typename D1::const_reference, + typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable> +{ +public: + D1 _fn1; + D2 _fn2; + + typedef typename D2::argument_type argument_type; + typedef typename D1::result_type result_type; + + deref_compose() {} + deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {} + deref_compose(const deref_compose& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {} + template deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {} + + result_type operator()(argument_type x) const { return _fn1(_fn2(x)); } + result_type operator()(argument_type x) { return _fn1(_fn2(x)); } +}; + +// reinterpret_cast is implementation-defined. Static cast is not. +template GIL_FORCEINLINE + OutPtr gil_reinterpret_cast( In* p) { return static_cast(static_cast(p)); } + +template GIL_FORCEINLINE +const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast(static_cast(p)); } + +namespace detail { + +//////////////////////////////////////////////////////////////////////////////////////// +/// +/// \brief copy_n taken from SGI STL. +/// +//////////////////////////////////////////////////////////////////////////////////////// + +template +std::pair _copy_n(InputIter first, Size count, + OutputIter result, + std::input_iterator_tag) { + for ( ; count > 0; --count) { + *result = *first; + ++first; + ++result; + } + return std::pair(first, result); +} + +template +inline std::pair +_copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) { + RAIter last = first + count; + return std::pair(last, std::copy(first, last, result)); +} + +template +inline std::pair +_copy_n(InputIter first, Size count, OutputIter result) { + return _copy_n(first, count, result, typename std::iterator_traits::iterator_category()); +} + +template +inline std::pair +copy_n(InputIter first, Size count, OutputIter result) { + return detail::_copy_n(first, count, result); +} + +/// \brief identity taken from SGI STL. +template +struct identity : public std::unary_function { + const T& operator()(const T& val) const { return val; } +}; + +/*************************************************************************************************/ + +/// \brief plus function object whose arguments may be of different type. +template +struct plus_asymmetric : public std::binary_function { + T1 operator()(T1 f1, T2 f2) const { + return f1+f2; + } +}; + +/*************************************************************************************************/ + +/// \brief operator++ wrapped in a function object +template +struct inc : public std::unary_function { + T operator()(T x) const { return ++x; } +}; + +/*************************************************************************************************/ + +/// \brief operator-- wrapped in a function object +template +struct dec : public std::unary_function { + T operator()(T x) const { return --x; } +}; + +/// \brief Returns the index corresponding to the first occurrance of a given given type in +// a given MPL RandomAccessSequence (or size if the type is not present) +template +struct type_to_index + : public mpl::distance::type, + typename mpl::find::type>::type {}; +} // namespace detail + + + +/// \ingroup ColorSpaceAndLayoutModel +/// \brief Represents a color space and ordering of channels in memory +template ::value> > +struct layout { + typedef ColorSpace color_space_t; + typedef ChannelMapping channel_mapping_t; +}; + +/// \brief A version of swap that also works with reference proxy objects +template // where value_type == value_type == Value +void swap_proxy(T1& left, T2& right) { + Value tmp = left; + left = right; + right = tmp; +} + +/// \brief Run-time detection of whether the underlying architecture is little endian +inline bool little_endian() { + short tester = 0x0001; + return *(char*)&tester!=0; +} +/// \brief Run-time detection of whether the underlying architecture is big endian +inline bool big_endian() { + return !little_endian(); +} + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/gil/virtual_locator.hpp b/thirdparty/boost/gil/virtual_locator.hpp new file mode 100644 index 0000000..782a4a5 --- /dev/null +++ b/thirdparty/boost/gil/virtual_locator.hpp @@ -0,0 +1,136 @@ +/* + Copyright 2005-2007 Adobe Systems Incorporated + + 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://opensource.adobe.com/gil for most recent version including documentation. +*/ + +/*************************************************************************************************/ + +#ifndef GIL_VIRTUAL_LOCATOR_HPP +#define GIL_VIRTUAL_LOCATOR_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Locator for virtual image views +/// \author Lubomir Bourdev and Hailin Jin \n +/// Adobe Systems Incorporated +/// \date 2005-2007 \n Last updated on February 12, 2007 +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "position_iterator.hpp" + +namespace boost { namespace gil { + +/// \brief A 2D locator over a virtual image. Upon dereferencing, invokes a given function object passing it its coordinates. Models: PixelLocatorConcept, HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, HasTransposedTypeConcept +/// \ingroup PixelLocatorModel PixelBasedModel +/// +template // A function object that given a point returns a reference. Models PixelDereferenceAdaptorConcept +class virtual_2d_locator : public pixel_2d_locator_base, position_iterator, position_iterator > { + typedef virtual_2d_locator this_t; +public: + typedef pixel_2d_locator_base, position_iterator, position_iterator > parent_t; + typedef virtual_2d_locator const_t; + + typedef Deref deref_fn_t; + typedef typename parent_t::point_t point_t; + + typedef typename parent_t::coord_t coord_t; + typedef typename parent_t::x_coord_t x_coord_t; + typedef typename parent_t::y_coord_t y_coord_t; + typedef typename parent_t::x_iterator x_iterator; + typedef typename parent_t::y_iterator y_iterator; + + template struct add_deref { + typedef virtual_2d_locator,IsTransposed > type; + static type make(const virtual_2d_locator& loc, const NewDeref& nderef) { + return type(loc.pos(), loc.step(), deref_compose(nderef,loc.deref_fn())); + } + }; + + virtual_2d_locator(const point_t& p=point_t(0,0), const point_t& step=point_t(1,1), const deref_fn_t& d=deref_fn_t()) : _p(p,step,d) {} + template virtual_2d_locator(const virtual_2d_locator& loc, coord_t y_step) + : _p(loc.pos(), point_t(loc.step().x,loc.step().y*y_step), loc.deref_fn()) {} + template virtual_2d_locator(const virtual_2d_locator& loc, coord_t x_step, coord_t y_step, bool transpose=false) + : _p(loc.pos(), transpose ? + point_t(loc.step().x*y_step,loc.step().y*x_step) : + point_t(loc.step().x*x_step,loc.step().y*y_step), loc.deref_fn()) { assert(transpose==(IsTransposed!=TR));} + + template virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {} + virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {} + + bool operator==(const this_t& p) const { return _p==p._p; } + + x_iterator& x() { return *gil_reinterpret_cast(this); } + y_iterator& y() { return _p; } + x_iterator const& x() const { return *gil_reinterpret_cast_c(this); } + y_iterator const& y() const { return _p; } + + // Returns the y distance between two x_iterators given the difference of their x positions + y_coord_t y_distance_to(const this_t& it2, x_coord_t xDiff) const { return (it2.pos()[1-IsTransposed] - pos()[1-IsTransposed])/step()[1-IsTransposed]; } + bool is_1d_traversable(x_coord_t) const { return false; } // is there no gap at the end of each row? I.e. can we use x_iterator to visit every pixel instead of nested loops? + + // Methods specific for virtual 2D locator + const point_t& pos() const { return _p.pos(); } + const point_t& step() const { return _p.step(); } + const deref_fn_t& deref_fn() const { return _p.deref_fn(); } +private: + template friend class virtual_2d_locator; + y_iterator _p; // contains the current position, the step and the dereference object +}; + +///////////////////////////// +// PixelBasedConcept +///////////////////////////// + +template +struct channel_type > : public channel_type::parent_t> { +}; + +template +struct color_space_type > : public color_space_type::parent_t> { +}; + +template +struct channel_mapping_type > : public channel_mapping_type::parent_t> { +}; + +template +struct is_planar > : public is_planar::parent_t> { +}; + +///////////////////////////// +// HasDynamicXStepTypeConcept +///////////////////////////// + +template +struct dynamic_x_step_type > { + typedef virtual_2d_locator type; +}; + +///////////////////////////// +// HasDynamicYStepTypeConcept +///////////////////////////// + +template +struct dynamic_y_step_type > { + typedef virtual_2d_locator type; +}; + +///////////////////////////// +// HasTransposedTypeConcept +///////////////////////////// + +template +struct transposed_type > { + typedef virtual_2d_locator type; +}; + +} } // namespace boost::gil + +#endif diff --git a/thirdparty/boost/graph/adj_list_serialize.hpp b/thirdparty/boost/graph/adj_list_serialize.hpp new file mode 100644 index 0000000..a9c5f1c --- /dev/null +++ b/thirdparty/boost/graph/adj_list_serialize.hpp @@ -0,0 +1,114 @@ +//======================================================================= +// Copyright 2005 Jeremy G. Siek +// Authors: Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef ADJ_LIST_SERIALIZE_HPP +#define ADJ_LIST_SERIALIZE_HPP + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { + +namespace serialization { + +// Turn off tracking for adjacency_list. It's not polymorphic, and we +// need to do this to enable saving of non-const adjacency lists. +template +struct tracking_level > { + typedef mpl::integral_c_tag tag; + typedef mpl::int_ type; + BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); +}; + +template +inline void save( + Archive & ar, + const boost::adjacency_list &graph, + const unsigned int /* file_version */ +){ + typedef adjacency_list Graph; + typedef typename graph_traits::vertex_descriptor Vertex; + + int V = num_vertices(graph); + int E = num_edges(graph); + ar << BOOST_SERIALIZATION_NVP(V); + ar << BOOST_SERIALIZATION_NVP(E); + + // assign indices to vertices + std::map indices; + int num = 0; + typename graph_traits::vertex_iterator vi; + for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi) { + indices[*vi] = num++; + ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, *vi) ); + } + + // write edges + typename graph_traits::edge_iterator ei; + for (ei = edges(graph).first; ei != edges(graph).second; ++ei){ + ar << serialization::make_nvp("u" , indices[source(*ei,graph)]); + ar << serialization::make_nvp("v" , indices[target(*ei,graph)]); + ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, *ei) ); + } +} + + +template +inline void load( + Archive & ar, + boost::adjacency_list &graph, + const unsigned int /* file_version */ +){ + typedef adjacency_list Graph; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; + + unsigned int V; + ar >> BOOST_SERIALIZATION_NVP(V); + unsigned int E; + ar >> BOOST_SERIALIZATION_NVP(E); + + std::vector verts(V); + int i = 0; + while(V-- > 0){ + Vertex v = add_vertex(graph); + verts[i++] = v; + ar >> serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) ); + } + while(E-- > 0){ + int u; int v; + ar >> BOOST_SERIALIZATION_NVP(u); + ar >> BOOST_SERIALIZATION_NVP(v); + Edge e; bool inserted; + tie(e,inserted) = add_edge(verts[u], verts[v], graph); + ar >> serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) ); + } +} + +template +inline void serialize( + Archive & ar, + boost::adjacency_list &graph, + const unsigned int file_version +){ + boost::serialization::split_free(ar, graph, file_version); +} + +}//serialization +}//boost + + +#endif // ADJ_LIST_SERIALIZE_HPP diff --git a/thirdparty/boost/graph/adjacency_iterator.hpp b/thirdparty/boost/graph/adjacency_iterator.hpp new file mode 100644 index 0000000..8eb24dd --- /dev/null +++ b/thirdparty/boost/graph/adjacency_iterator.hpp @@ -0,0 +1,102 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_ADJACENCY_ITERATOR_HPP +#define BOOST_ADJACENCY_ITERATOR_HPP + +#include +#include + +namespace boost +{ + + template + struct adjacency_iterator + : iterator_adaptor< + adjacency_iterator + , OutEdgeIter + , Vertex + , use_default + , Vertex + , Difference + > + { + typedef iterator_adaptor< + adjacency_iterator + , OutEdgeIter + , Vertex + , use_default + , Vertex + , Difference + > super_t; + + inline adjacency_iterator() {} + inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { } + + inline Vertex + dereference() const + { return target(*this->base(), *m_g); } + + const Graph* m_g; + }; + + template ::vertex_descriptor, + class OutEdgeIter=typename graph_traits::out_edge_iterator> + class adjacency_iterator_generator + { + typedef typename boost::detail::iterator_traits + ::difference_type difference_type; + public: + typedef adjacency_iterator type; + }; + + template + struct inv_adjacency_iterator + : iterator_adaptor< + inv_adjacency_iterator + , InEdgeIter + , Vertex + , use_default + , Vertex + , Difference + > + { + typedef iterator_adaptor< + inv_adjacency_iterator + , InEdgeIter + , Vertex + , use_default + , Vertex + , Difference + > super_t; + + inline inv_adjacency_iterator() { } + inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { } + + inline Vertex + dereference() const + { return source(*this->base(), *m_g); } + + const Graph* m_g; + }; + + template ::vertex_descriptor, + class InEdgeIter = typename graph_traits::in_edge_iterator> + class inv_adjacency_iterator_generator { + typedef typename boost::detail::iterator_traits + ::difference_type difference_type; + public: + typedef inv_adjacency_iterator type; + }; + +} // namespace boost + +#endif // BOOST_DETAIL_ADJACENCY_ITERATOR_HPP diff --git a/thirdparty/boost/graph/adjacency_list.hpp b/thirdparty/boost/graph/adjacency_list.hpp new file mode 100644 index 0000000..d75550d --- /dev/null +++ b/thirdparty/boost/graph/adjacency_list.hpp @@ -0,0 +1,564 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP +#define BOOST_GRAPH_ADJACENCY_LIST_HPP + + +#include + +#include +#include +#include + +#if !defined BOOST_NO_HASH +# ifdef BOOST_HASH_SET_HEADER +# include BOOST_HASH_SET_HEADER +# else +# include +# endif +#endif + +#if !defined BOOST_NO_SLIST +# ifdef BOOST_SLIST_HEADER +# include BOOST_SLIST_HEADER +# else +# include +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + //=========================================================================== + // Selectors for the VertexList and EdgeList template parameters of + // adjacency_list, and the container_gen traits class which is used + // to map the selectors to the container type used to implement the + // graph. + // + // The main container_gen traits class uses partial specialization, + // so we also include a workaround. + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#if !defined BOOST_NO_SLIST + struct slistS {}; +#endif + + struct vecS { }; + struct listS { }; + struct setS { }; + struct multisetS { }; + struct mapS { }; +#if !defined BOOST_NO_HASH + struct hash_mapS { }; + struct hash_setS { }; +#endif + + template + struct container_gen { }; + + template + struct container_gen { + typedef std::list type; + }; +#if !defined BOOST_NO_SLIST + template + struct container_gen { + typedef BOOST_STD_EXTENSION_NAMESPACE::slist type; + }; +#endif + template + struct container_gen { + typedef std::vector type; + }; + + template + struct container_gen { + typedef std::set type; + }; + + template + struct container_gen { + typedef std::set type; + }; + + template + struct container_gen { + typedef std::multiset type; + }; + +#if !defined BOOST_NO_HASH + template + struct container_gen { + typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set type; + }; + + template + struct container_gen { + typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set type; + }; +#endif + +#else // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#if !defined BOOST_NO_SLIST + struct slistS { + template + struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::slist type; }; + }; +#endif + + struct vecS { + template + struct bind_ { typedef std::vector type; }; + }; + + struct listS { + template + struct bind_ { typedef std::list type; }; + }; + + struct setS { + template + struct bind_ { typedef std::set > type; }; + }; + + struct multisetS { + template + struct bind_ { typedef std::multiset > type; }; + }; + +#if !defined BOOST_NO_HASH + struct hash_setS { + template + struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set > type; }; + }; +#endif + + struct mapS { + template + struct bind_ { typedef std::set > type; }; + }; + +#if !defined BOOST_NO_HASH + struct hash_mapS { + template + struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set > type; }; + }; +#endif + + template struct container_selector { + typedef vecS type; + }; + +#define BOOST_CONTAINER_SELECTOR(NAME) \ + template <> struct container_selector { \ + typedef NAME type; \ + } + + BOOST_CONTAINER_SELECTOR(vecS); + BOOST_CONTAINER_SELECTOR(listS); + BOOST_CONTAINER_SELECTOR(mapS); + BOOST_CONTAINER_SELECTOR(setS); + BOOST_CONTAINER_SELECTOR(multisetS); +#if !defined BOOST_NO_HASH + BOOST_CONTAINER_SELECTOR(hash_mapS); +#endif +#if !defined BOOST_NO_SLIST + BOOST_CONTAINER_SELECTOR(slistS); +#endif + + template + struct container_gen { + typedef typename container_selector::type Select; + typedef typename Select:: template bind_::type type; + }; + +#endif // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct parallel_edge_traits { }; + + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; }; + + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; }; + +#if !defined BOOST_NO_SLIST + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; }; +#endif + + template <> + struct parallel_edge_traits { + typedef disallow_parallel_edge_tag type; }; + + template <> + struct parallel_edge_traits { + typedef allow_parallel_edge_tag type; }; + +#if !defined BOOST_NO_HASH + template <> + struct parallel_edge_traits { + typedef disallow_parallel_edge_tag type; + }; +#endif + + // mapS is obsolete, replaced with setS + template <> + struct parallel_edge_traits { + typedef disallow_parallel_edge_tag type; }; + +#if !defined BOOST_NO_HASH + template <> + struct parallel_edge_traits { + typedef disallow_parallel_edge_tag type; + }; +#endif + + namespace detail { + template struct is_random_access { + enum { value = false}; + typedef mpl::false_ type; + }; + template <> + struct is_random_access { + enum { value = true }; + typedef mpl::true_ type; + }; + + } // namespace detail + + + + //=========================================================================== + // The adjacency_list_traits class, which provides a way to access + // some of the associated types of an adjacency_list type without + // having to first create the adjacency_list type. This is useful + // when trying to create interior vertex or edge properties who's + // value type is a vertex or edge descriptor. + + template + struct adjacency_list_traits + { + typedef typename detail::is_random_access::type + is_rand_access; + typedef typename DirectedS::is_bidir_t is_bidir; + typedef typename DirectedS::is_directed_t is_directed; + + typedef typename mpl::if_::type + >::type directed_category; + + typedef typename parallel_edge_traits::type + edge_parallel_category; + + typedef void* vertex_ptr; + typedef typename mpl::if_::type vertex_descriptor; + typedef detail::edge_desc_impl + edge_descriptor; + + typedef std::size_t vertices_size_type; + + private: + // Logic to figure out the edges_size_type + struct dummy {}; + typedef typename container_gen::type EdgeContainer; + typedef typename DirectedS::is_bidir_t BidirectionalT; + typedef typename DirectedS::is_directed_t DirectedT; + typedef typename mpl::and_::type >::type on_edge_storage; + public: + typedef typename mpl::if_::type edges_size_type; + + }; + +} // namespace boost + +#include + +namespace boost { + + //=========================================================================== + // The adjacency_list class. + // + + template + class adjacency_list + : public detail::adj_list_gen< + adjacency_list, + VertexListS, OutEdgeListS, DirectedS, +#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) + typename detail::retag_property_list::type, + typename detail::retag_property_list::type, +#else + VertexProperty, EdgeProperty, +#endif + GraphProperty, EdgeListS>::type + { +#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) + typedef typename detail::retag_property_list::retagged + maybe_vertex_bundled; + + typedef typename detail::retag_property_list::retagged + maybe_edge_bundled; +#endif + + public: +#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) + typedef typename detail::retag_property_list::type + vertex_property_type; + typedef typename detail::retag_property_list::type + edge_property_type; + + // The types that are actually bundled + typedef typename mpl::if_c<(is_same::value), + no_vertex_bundle, + maybe_vertex_bundled>::type vertex_bundled; + typedef typename mpl::if_c<(is_same::value), + no_edge_bundle, + maybe_edge_bundled>::type edge_bundled; +#else + typedef VertexProperty vertex_property_type; + typedef EdgeProperty edge_property_type; + typedef no_vertex_bundle vertex_bundled; + typedef no_edge_bundle edge_bundled; +#endif + + private: + typedef adjacency_list self; + typedef typename detail::adj_list_gen< + self, VertexListS, OutEdgeListS, DirectedS, + vertex_property_type, edge_property_type, GraphProperty, EdgeListS + >::type Base; + + public: + typedef typename Base::stored_vertex stored_vertex; + typedef typename Base::vertices_size_type vertices_size_type; + typedef typename Base::edges_size_type edges_size_type; + typedef typename Base::degree_size_type degree_size_type; + typedef typename Base::vertex_descriptor vertex_descriptor; + typedef typename Base::edge_descriptor edge_descriptor; + typedef OutEdgeListS out_edge_list_selector; + typedef VertexListS vertex_list_selector; + typedef DirectedS directed_selector; + typedef EdgeListS edge_list_selector; + + typedef GraphProperty graph_property_type; + + inline adjacency_list(const GraphProperty& p = GraphProperty()) + : m_property(p) { } + + inline adjacency_list(const adjacency_list& x) + : Base(x), m_property(x.m_property) { } + + inline adjacency_list& operator=(const adjacency_list& x) { + // TBD: probably should give the strong guarantee + if (&x != this) { + Base::operator=(x); + m_property = x.m_property; + } + return *this; + } + + // Required by Mutable Graph + inline adjacency_list(vertices_size_type num_vertices, + const GraphProperty& p = GraphProperty()) + : Base(num_vertices), m_property(p) { } + +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300 + // Required by Iterator Constructible Graph + template + inline adjacency_list(EdgeIterator first, EdgeIterator last, + vertices_size_type n, + edges_size_type = 0, + const GraphProperty& p = GraphProperty()) + : Base(n, first, last), m_property(p) { } + + template + inline adjacency_list(EdgeIterator first, EdgeIterator last, + EdgePropertyIterator ep_iter, + vertices_size_type n, + edges_size_type = 0, + const GraphProperty& p = GraphProperty()) + : Base(n, first, last, ep_iter), m_property(p) { } +#endif + + void swap(adjacency_list& x) { + // Is there a more efficient way to do this? + adjacency_list tmp(x); + x = *this; + *this = tmp; + } + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + // Directly access a vertex or edge bundle + vertex_bundled& operator[](vertex_descriptor v) + { return get(vertex_bundle, *this)[v]; } + + const vertex_bundled& operator[](vertex_descriptor v) const + { return get(vertex_bundle, *this)[v]; } + + edge_bundled& operator[](edge_descriptor e) + { return get(edge_bundle, *this)[e]; } + + const edge_bundled& operator[](edge_descriptor e) const + { return get(edge_bundle, *this)[e]; } +#endif + + // protected: (would be protected if friends were more portable) + GraphProperty m_property; + }; + + template + inline void + set_property(adjacency_list& g, Tag, + const Value& value) { + get_property_value(g.m_property, Tag()) = value;; + } + + template + inline + typename graph_property, Tag>::type& + get_property(adjacency_list& g, Tag) { + return get_property_value(g.m_property, Tag()); + } + + template + inline + const + typename graph_property, Tag>::type& + get_property(const adjacency_list& g, Tag) { + return get_property_value(g.m_property, Tag()); + } + + // dwa 09/25/00 - needed to be more explicit so reverse_graph would work. + template + inline Vertex + source(const detail::edge_base& e, + const adjacency_list&) + { + return e.m_source; + } + + template + inline Vertex + target(const detail::edge_base& e, + const adjacency_list&) + { + return e.m_target; + } + + // Support for bundled properties +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + inline + typename property_map, T Bundle::*>::type + get(T Bundle::* p, adjacency_list& g) + { + typedef typename property_map, T Bundle::*>::type + result_type; + return result_type(&g, p); + } + + template + inline + typename property_map, T Bundle::*>::const_type + get(T Bundle::* p, adjacency_list const & g) + { + typedef typename property_map, T Bundle::*>::const_type + result_type; + return result_type(&g, p); + } + + template + inline T + get(T Bundle::* p, adjacency_list const & g, const Key& key) + { + return get(get(p, g), key); + } + + template + inline void + put(T Bundle::* p, adjacency_list& g, const Key& key, const T& value) + { + put(get(p, g), key, value); + } + +#endif + + +} // namespace boost + + +#endif // BOOST_GRAPH_ADJACENCY_LIST_HPP diff --git a/thirdparty/boost/graph/adjacency_list_io.hpp b/thirdparty/boost/graph/adjacency_list_io.hpp new file mode 100644 index 0000000..16b0dee --- /dev/null +++ b/thirdparty/boost/graph/adjacency_list_io.hpp @@ -0,0 +1,408 @@ +//======================================================================= +// Copyright 2001 Universite Joseph Fourier, Grenoble. +// Author: François Faure +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_ADJACENCY_LIST_IO_HPP +#define BOOST_GRAPH_ADJACENCY_LIST_IO_HPP + +#include +#include +#include +#include + +// Method read to parse an adjacency list from an input stream. Examples: +// cin >> read( G ); +// cin >> read( G, NodePropertySubset(), EdgepropertySubset() ); +// +// Method write to print an adjacency list to an output stream. Examples: +// cout << write( G ); +// cout << write( G, NodePropertySubset(), EdgepropertySubset() ); + +namespace boost { + +/* outline + - basic property input + - get property subset + - graph parser + - property printer + - graph printer + - user methods +*/ + +//=========================================================================== +// basic property input + +template +std::istream& operator >> ( std::istream& in, property& p ) +{ + in >> p.m_value >> *(static_cast(&p)); // houpla !! + return in; +} + +template +std::istream& operator >> ( std::istream& in, property& p ) +{ + in >> p.m_value; + return in; +} + +inline std::istream& operator >> ( std::istream& in, no_property& ) +{ + return in; +} + +// basic property input +//=========================================================================== +// get property subsets + +// get a single property tagged Stag +template +void get +( property& p, const V& v, Stag s ) +{ + get( *(static_cast(&p)),v,s ); +} + +template +void get +( property& p, const V& v, Stag ) +{ + p.m_value = v; +} + +// get a subset of properties tagged Stag +template +void getSubset +( property& p, const property& s ) +{ + get( p, s.m_value, Stag() ); + getSubset( p, Snext(s) ); +} + +template +void getSubset +( property& p, const property& s) +{ + get( p, s.m_value, Stag() ); +} + +inline void getSubset +( no_property& p, const no_property& s ) +{ +} + +#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) +template +void getSubset(T& p, const U& s) +{ + p = s; +} + +template +void getSubset(T&, const no_property&) +{ +} + + +#endif + +// get property subset +//=========================================================================== +// graph parser +typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState; + +template +struct GraphParser +{ + + typedef Graph_t Graph; + + GraphParser( Graph* g ): graph(g) + {} + + GraphParser& operator () ( std::istream& in ) + { + typedef typename graph_traits::vertex_descriptor Vertex; + std::vector nodes; + + GraphParserState state = PARSE_VERTEX; + + unsigned int numLine = 1; + char c; + while ( in.get(c) ) + { + if( c== '#' ) skip(in); + else if( c== 'n' ) state = PARSE_NUM_NODES; + else if( c== 'v' ) state = PARSE_VERTEX; + else if( c== 'e' ) state = PARSE_EDGE; + else if( c== '\n' ) numLine++; + else if( !std::isspace(c) ){ + in.putback(c); + if( state == PARSE_VERTEX ){ + VertexPropertySubset readProp; + if( in >> readProp ) + { + VertexProperty vp; + getSubset( vp, readProp ); + nodes.push_back( add_vertex(vp, *graph) ); + } + else + std::cerr<<"read vertex, parse error at line"<> source >> target; + if( in >> readProp ) + { + EdgeProperty ep; + getSubset( ep, readProp ); + add_edge(nodes[source], nodes[target], ep, *graph); + } + else + std::cerr<<"read edge, parse error at line"<> n ){ + for( int i=0; i +struct PropertyPrinter +{ + typedef typename Property::value_type Value; + typedef typename Property::tag_type Tag; + typedef typename Property::next_type Next; + + PropertyPrinter( const Graph& g ):graph(&g){} + + template + PropertyPrinter& operator () ( std::ostream& out, Iterator it ) + { + typename property_map::type ps = get(Tag(), *graph); + out << ps[ *it ] <<" "; + PropertyPrinter print(*graph); + print(out, it); + return (*this); + } +private: + const Graph* graph; +}; +#else +template +struct PropertyPrinter +{ + PropertyPrinter( const Graph& g ):graph(&g){} + + template + PropertyPrinter& operator () ( std::ostream& out, Iterator it ) + { + out << (*graph)[ *it ] <<" "; + return (*this); + } +private: + const Graph* graph; +}; + +template +struct PropertyPrinter > +{ + PropertyPrinter( const Graph& g ):graph(&g){} + + template + PropertyPrinter& operator () ( std::ostream& out, Iterator it ) + { + typename property_map::type ps = get(Tag(), *graph); + out << ps[ *it ] <<" "; + PropertyPrinter print(*graph); + print(out, it); + return (*this); + } +private: + const Graph* graph; +}; +#endif + +template +struct PropertyPrinter +{ + PropertyPrinter( const Graph& ){} + + template + PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; } +}; + +// property printer +//========================================================================= +// graph printer + +template +struct EdgePrinter +{ + + typedef Graph_t Graph; + typedef typename graph_traits::vertex_descriptor Vertex; + + EdgePrinter( const Graph& g ) + : graph(g) + {} + + const EdgePrinter& operator () ( std::ostream& out ) const + { + // assign indices to vertices + std::map indices; + int num = 0; + typename graph_traits::vertex_iterator vi; + for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){ + indices[*vi] = num++; + } + + // write edges + PropertyPrinter print_Edge(graph); + out << "e" << std::endl; + typename graph_traits::edge_iterator ei; + for (ei = edges(graph).first; ei != edges(graph).second; ++ei){ + out << indices[source(*ei,graph)] << " " << indices[target(*ei,graph)] << " "; + print_Edge(out,ei); + out << std::endl; + } + out << std::endl; + return (*this); + } + +protected: + + const Graph& graph; + +}; + +template +struct GraphPrinter: public EdgePrinter +{ + GraphPrinter( const Graph& g ) + : EdgePrinter(g) + {} + + const GraphPrinter& operator () ( std::ostream& out ) const + { + PropertyPrinter printNode(this->graph); + out << "v"<::vertex_iterator vi; + for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){ + printNode(out,vi); + out << std::endl; + } + + EdgePrinter::operator ()( out ); + return (*this); + } +}; + +template +struct GraphPrinter + : public EdgePrinter +{ + GraphPrinter( const Graph& g ) + : EdgePrinter(g) + {} + + const GraphPrinter& operator () ( std::ostream& out ) const + { + out << "n "<< num_vertices(this->graph) << std::endl; + EdgePrinter::operator ()( out ); + return (*this); + } +}; + +// graph printer +//========================================================================= +// user methods + +/// input stream for reading a graph +template +std::istream& operator >> ( std::istream& in, GraphParser gp ) +{ + gp(in); + return in; +} + +/// graph parser for given subsets of internal vertex and edge properties +template +GraphParser,VP,EP,VPS,EPS> +read( adjacency_list& g, VPS vps, EPS eps ) +{ + return GraphParser,VP,EP,VPS,EPS>(&g); +} + +/// graph parser for all internal vertex and edge properties +template +GraphParser,VP,EP,VP,EP> +read( adjacency_list& g ) +{ + return GraphParser,VP,EP,VP,EP>(&g); +} + + +/// output stream for writing a graph +template +std::ostream& operator << ( std::ostream& out, const GraphPrinter& gp ) +{ + gp(out); + return out; +} + +/// write the graph with given property subsets +template +GraphPrinter,VPS,EPS> +write( const adjacency_list& g, VPS, EPS ) +{ + return GraphPrinter,VPS,EPS>(g); +} + +/// write the graph with all internal vertex and edge properties +template +GraphPrinter,VP,EP> +write( const adjacency_list& g ) +{ + return GraphPrinter,VP,EP>(g); +} + +// user methods +//========================================================================= +}// boost +#endif diff --git a/thirdparty/boost/graph/adjacency_matrix.hpp b/thirdparty/boost/graph/adjacency_matrix.hpp new file mode 100644 index 0000000..a97b32b --- /dev/null +++ b/thirdparty/boost/graph/adjacency_matrix.hpp @@ -0,0 +1,1278 @@ +//======================================================================= +// Copyright 2001 University of Notre Dame. +// Copyright 2006 Trustees of Indiana University +// Authors: Jeremy G. Siek and Douglas Gregor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_ADJACENCY_MATRIX_HPP +#define BOOST_ADJACENCY_MATRIX_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + namespace detail { + + template + class matrix_edge_desc_impl : public edge_desc_impl + { + typedef edge_desc_impl Base; + public: + matrix_edge_desc_impl() { } + matrix_edge_desc_impl(bool exists, Vertex s, Vertex d, + const void* ep = 0) + : Base(s, d, ep), m_exists(exists) { } + bool exists() const { return m_exists; } + private: + bool m_exists; + }; + + struct does_edge_exist { + template + bool operator()(const Edge& e) const { return e.exists(); } + }; + + template + bool get_edge_exists(const std::pair& stored_edge, int) { + return stored_edge.first; + } + template + void set_edge_exists( + std::pair& stored_edge, + bool flag, + int + ) { + stored_edge.first = flag; + } + + template + bool get_edge_exists(const EdgeProxy& edge_proxy, ...) { + return edge_proxy; + } + template + EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) { + edge_proxy = flag; + return edge_proxy; // just to avoid never used warning + } + + + + template + const EdgeProperty& + get_property(const std::pair& stored_edge) { + return stored_edge.second; + } + template + EdgeProperty& + get_property(std::pair& stored_edge) { + return stored_edge.second; + } + + template + inline void + set_property(std::pair& stored_edge, + const EdgeProperty& ep, int) { + stored_edge.second = ep; + } + + inline const no_property& get_property(const char&) { + static no_property s_prop; + return s_prop; + } + inline no_property& get_property(char&) { + static no_property s_prop; + return s_prop; + } + template + inline void + set_property(EdgeProxy, const EdgeProperty&, ...) {} + + //======================================================================= + // Directed Out Edge Iterator + + template < + typename VertexDescriptor, typename MatrixIter + , typename VerticesSizeType, typename EdgeDescriptor + > + struct dir_adj_matrix_out_edge_iter + : iterator_adaptor< + dir_adj_matrix_out_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > + { + typedef iterator_adaptor< + dir_adj_matrix_out_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > super_t; + + dir_adj_matrix_out_edge_iter() { } + + dir_adj_matrix_out_edge_iter( + const MatrixIter& i + , const VertexDescriptor& src + , const VerticesSizeType& n + ) + : super_t(i), m_src(src), m_targ(0), m_n(n) + { } + + void increment() { + ++this->base_reference(); + ++m_targ; + } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, + &get_property(*this->base())); + } + VertexDescriptor m_src, m_targ; + VerticesSizeType m_n; + }; + + //======================================================================= + // Directed In Edge Iterator + + template < + typename VertexDescriptor, typename MatrixIter + , typename VerticesSizeType, typename EdgeDescriptor + > + struct dir_adj_matrix_in_edge_iter + : iterator_adaptor< + dir_adj_matrix_in_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > + { + typedef iterator_adaptor< + dir_adj_matrix_in_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > super_t; + + dir_adj_matrix_in_edge_iter() { } + + dir_adj_matrix_in_edge_iter( + const MatrixIter& i + , const MatrixIter& last + , const VertexDescriptor& tgt + , const VerticesSizeType& n + ) + : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n) + { } + + void increment() { + if (VerticesSizeType(m_last - this->base_reference()) >= m_n) { + this->base_reference() += m_n; + ++m_src; + } else { + this->base_reference() = m_last; + } + } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, + &get_property(*this->base())); + } + MatrixIter m_last; + VertexDescriptor m_src, m_targ; + VerticesSizeType m_n; + }; + + //======================================================================= + // Undirected Out Edge Iterator + + template < + typename VertexDescriptor, typename MatrixIter + , typename VerticesSizeType, typename EdgeDescriptor + > + struct undir_adj_matrix_out_edge_iter + : iterator_adaptor< + undir_adj_matrix_out_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > + { + typedef iterator_adaptor< + undir_adj_matrix_out_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > super_t; + + undir_adj_matrix_out_edge_iter() { } + + undir_adj_matrix_out_edge_iter( + const MatrixIter& i + , const VertexDescriptor& src + , const VerticesSizeType& n + ) + : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) + {} + + void increment() + { + if (m_targ < m_src) // first half + { + ++this->base_reference(); + } + else if (m_targ < m_n - 1) + { // second half + ++m_inc; + this->base_reference() += m_inc; + } + else + { // past-the-end + this->base_reference() += m_n - m_src; + } + ++m_targ; + } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor( + get_edge_exists(*this->base(), 0), m_src, m_targ + , &get_property(*this->base()) + ); + } + + VertexDescriptor m_src, m_inc, m_targ; + VerticesSizeType m_n; + }; + + //======================================================================= + // Undirected In Edge Iterator + + template < + typename VertexDescriptor, typename MatrixIter + , typename VerticesSizeType, typename EdgeDescriptor + > + struct undir_adj_matrix_in_edge_iter + : iterator_adaptor< + undir_adj_matrix_in_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > + { + typedef iterator_adaptor< + undir_adj_matrix_in_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > super_t; + + undir_adj_matrix_in_edge_iter() { } + + undir_adj_matrix_in_edge_iter( + const MatrixIter& i + , const VertexDescriptor& src + , const VerticesSizeType& n + ) + : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) + {} + + void increment() + { + if (m_targ < m_src) // first half + { + ++this->base_reference(); + } + else if (m_targ < m_n - 1) + { // second half + ++m_inc; + this->base_reference() += m_inc; + } + else + { // past-the-end + this->base_reference() += m_n - m_src; + } + ++m_targ; + } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor( + get_edge_exists(*this->base(), 0), m_targ, m_src + , &get_property(*this->base()) + ); + } + + VertexDescriptor m_src, m_inc, m_targ; + VerticesSizeType m_n; + }; + + //======================================================================= + // Edge Iterator + + template + struct adj_matrix_edge_iter + : iterator_adaptor< + adj_matrix_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > + { + typedef iterator_adaptor< + adj_matrix_edge_iter + , MatrixIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , std::ptrdiff_t + > super_t; + + adj_matrix_edge_iter() { } + + adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, const VerticesSizeType& n) + : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) { } + + void increment() + { + increment_dispatch(this->base_reference(), Directed()); + } + + void increment_dispatch(MatrixIter& i, directedS) + { + ++i; + if (m_targ == m_n - 1) + { + m_targ = 0; + ++m_src; + } + else + { + ++m_targ; + } + } + + void increment_dispatch(MatrixIter& i, undirectedS) + { + ++i; + if (m_targ == m_src) + { + m_targ = 0; + ++m_src; + } + else + { + ++m_targ; + } + } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor( + get_edge_exists( + *this->base(), 0), m_src, m_targ, &get_property(*this->base()) + ); + } + + MatrixIter m_start; + VerticesSizeType m_src, m_targ, m_n; + }; + + } // namespace detail + + //========================================================================= + // Adjacency Matrix Traits + template + class adjacency_matrix_traits { + typedef typename Directed::is_directed_t is_directed; + public: + // The bidirectionalS tag is not allowed with the adjacency_matrix + // graph type. Instead, use directedS, which also provides the + // functionality required for a Bidirectional Graph (in_edges, + // in_degree, etc.). +#if !defined(_MSC_VER) || _MSC_VER > 1300 + BOOST_STATIC_ASSERT(type_traits::ice_not<(is_same::value)>::value); +#endif + + typedef typename mpl::if_::type + directed_category; + + typedef disallow_parallel_edge_tag edge_parallel_category; + + typedef std::size_t vertex_descriptor; + + typedef detail::matrix_edge_desc_impl edge_descriptor; + }; + + struct adjacency_matrix_class_tag { }; + + struct adj_matrix_traversal_tag : + public virtual adjacency_matrix_tag, + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag { }; + + //========================================================================= + // Adjacency Matrix Class + template > + class adjacency_matrix { + typedef adjacency_matrix self; + typedef adjacency_matrix_traits Traits; + + public: +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + // The bidirectionalS tag is not allowed with the adjacency_matrix + // graph type. Instead, use directedS, which also provides the + // functionality required for a Bidirectional Graph (in_edges, + // in_degree, etc.). + BOOST_STATIC_ASSERT(!(is_same::value)); +#endif + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + typedef typename detail::retag_property_list::type + vertex_property_type; + typedef typename detail::retag_property_list::type + edge_property_type; + + private: + typedef typename detail::retag_property_list::retagged + maybe_vertex_bundled; + + typedef typename detail::retag_property_list::retagged + maybe_edge_bundled; + + public: + // The types that are actually bundled + typedef typename mpl::if_c<(is_same::value), + no_vertex_bundle, + maybe_vertex_bundled>::type vertex_bundled; + typedef typename mpl::if_c<(is_same::value), + no_edge_bundle, + maybe_edge_bundled>::type edge_bundled; +#else + typedef EdgeProperty edge_property_type; + typedef VertexProperty vertex_property_type; + typedef no_vertex_bundle vertex_bundled; + typedef no_edge_bundle edge_bundled; +#endif + + public: // should be private + typedef typename mpl::if_::type, + std::pair, char>::type StoredEdge; +#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) || defined(BOOST_NO_STD_ALLOCATOR) + typedef std::vector Matrix; +#else + // This causes internal compiler error for MSVC + typedef typename Allocator::template rebind::other Alloc; + typedef std::vector Matrix; +#endif + typedef typename Matrix::iterator MatrixIter; + typedef typename Matrix::size_type size_type; + public: + // Graph concept required types + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef adj_matrix_traversal_tag traversal_category; + + static vertex_descriptor null_vertex() + { + return (std::numeric_limits::max)(); + } + + //private: if friends worked, these would be private + + typedef detail::dir_adj_matrix_out_edge_iter< + vertex_descriptor, MatrixIter, size_type, edge_descriptor + > DirOutEdgeIter; + + typedef detail::undir_adj_matrix_out_edge_iter< + vertex_descriptor, MatrixIter, size_type, edge_descriptor + > UnDirOutEdgeIter; + + typedef typename mpl::if_< + typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter + >::type unfiltered_out_edge_iter; + + typedef detail::dir_adj_matrix_in_edge_iter< + vertex_descriptor, MatrixIter, size_type, edge_descriptor + > DirInEdgeIter; + + typedef detail::undir_adj_matrix_in_edge_iter< + vertex_descriptor, MatrixIter, size_type, edge_descriptor + > UnDirInEdgeIter; + + typedef typename mpl::if_< + typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter + >::type unfiltered_in_edge_iter; + + typedef detail::adj_matrix_edge_iter< + Directed, MatrixIter, size_type, edge_descriptor + > unfiltered_edge_iter; + + public: + + // IncidenceGraph concept required types + typedef filter_iterator + out_edge_iterator; + + typedef size_type degree_size_type; + + // BidirectionalGraph required types + typedef filter_iterator + in_edge_iterator; + + // AdjacencyGraph required types + typedef typename adjacency_iterator_generator::type adjacency_iterator; + + // VertexListGraph required types + typedef size_type vertices_size_type; + typedef integer_range VertexList; + typedef typename VertexList::iterator vertex_iterator; + + // EdgeListGraph required types + typedef size_type edges_size_type; + typedef filter_iterator< + detail::does_edge_exist, unfiltered_edge_iter + > edge_iterator; + + // PropertyGraph required types + typedef adjacency_matrix_class_tag graph_tag; + + // Constructor required by MutableGraph + adjacency_matrix(vertices_size_type n_vertices) + : m_matrix(Directed::is_directed ? + (n_vertices * n_vertices) + : (n_vertices * (n_vertices + 1) / 2)), + m_vertex_set(0, n_vertices), + m_vertex_properties(n_vertices), + m_num_edges(0) { } + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + // Directly access a vertex or edge bundle + vertex_bundled& operator[](vertex_descriptor v) + { return get(vertex_bundle, *this)[v]; } + + const vertex_bundled& operator[](vertex_descriptor v) const + { return get(vertex_bundle, *this)[v]; } + + edge_bundled& operator[](edge_descriptor e) + { return get(edge_bundle, *this)[e]; } + + const edge_bundled& operator[](edge_descriptor e) const + { return get(edge_bundle, *this)[e]; } +#endif + + //private: if friends worked, these would be private + + typename Matrix::const_reference + get_edge(vertex_descriptor u, vertex_descriptor v) const { + if (Directed::is_directed) + return m_matrix[u * m_vertex_set.size() + v]; + else { + if (v > u) + std::swap(u, v); + return m_matrix[u * (u + 1)/2 + v]; + } + } + typename Matrix::reference + get_edge(vertex_descriptor u, vertex_descriptor v) { + if (Directed::is_directed) + return m_matrix[u * m_vertex_set.size() + v]; + else { + if (v > u) + std::swap(u, v); + return m_matrix[u * (u + 1)/2 + v]; + } + } + + Matrix m_matrix; + VertexList m_vertex_set; + std::vector m_vertex_properties; + size_type m_num_edges; + }; + + //========================================================================= + // Functions required by the AdjacencyMatrix concept + + template + std::pair::edge_descriptor, + bool> + edge(typename adjacency_matrix::vertex_descriptor u, + typename adjacency_matrix::vertex_descriptor v, + const adjacency_matrix& g) + { + bool exists = detail::get_edge_exists(g.get_edge(u,v), 0); + typename adjacency_matrix::edge_descriptor + e(exists, u, v, &detail::get_property(g.get_edge(u,v))); + return std::make_pair(e, exists); + } + + //========================================================================= + // Functions required by the IncidenceGraph concept + + // O(1) + template + std::pair::out_edge_iterator, + typename adjacency_matrix::out_edge_iterator> + out_edges + (typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + typename Graph::vertices_size_type offset = u * g.m_vertex_set.size(); + typename Graph::MatrixIter f = g.m_matrix.begin() + offset; + typename Graph::MatrixIter l = f + g.m_vertex_set.size(); + typename Graph::unfiltered_out_edge_iter + first(f, u, g.m_vertex_set.size()) + , last(l, u, g.m_vertex_set.size()); + detail::does_edge_exist pred; + typedef typename Graph::out_edge_iterator out_edge_iterator; + return std::make_pair(out_edge_iterator(pred, first, last), + out_edge_iterator(pred, last, last)); + } + + // O(1) + template + std::pair< + typename adjacency_matrix::out_edge_iterator, + typename adjacency_matrix::out_edge_iterator> + out_edges + (typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + typename Graph::vertices_size_type offset = u * (u + 1) / 2; + typename Graph::MatrixIter f = g.m_matrix.begin() + offset; + typename Graph::MatrixIter l = g.m_matrix.end(); + + typename Graph::unfiltered_out_edge_iter + first(f, u, g.m_vertex_set.size()) + , last(l, u, g.m_vertex_set.size()); + + detail::does_edge_exist pred; + typedef typename Graph::out_edge_iterator out_edge_iterator; + return std::make_pair(out_edge_iterator(pred, first, last), + out_edge_iterator(pred, last, last)); + } + + // O(N) + template + typename adjacency_matrix::degree_size_type + out_degree(typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g) + { + typename adjacency_matrix::degree_size_type n = 0; + typename adjacency_matrix::out_edge_iterator f, l; + for (tie(f, l) = out_edges(u, g); f != l; ++f) + ++n; + return n; + } + + // O(1) + template + typename adjacency_matrix::vertex_descriptor + source(const detail::matrix_edge_desc_impl& e, + const adjacency_matrix&) + { + return e.m_source; + } + + // O(1) + template + typename adjacency_matrix::vertex_descriptor + target(const detail::matrix_edge_desc_impl& e, + const adjacency_matrix&) + { + return e.m_target; + } + + //========================================================================= + // Functions required by the BidirectionalGraph concept + + // O(1) + template + std::pair::in_edge_iterator, + typename adjacency_matrix::in_edge_iterator> + in_edges + (typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + typename Graph::MatrixIter f = g.m_matrix.begin() + u; + typename Graph::MatrixIter l = g.m_matrix.end(); + typename Graph::unfiltered_in_edge_iter + first(f, l, u, g.m_vertex_set.size()) + , last(l, l, u, g.m_vertex_set.size()); + detail::does_edge_exist pred; + typedef typename Graph::in_edge_iterator in_edge_iterator; + return std::make_pair(in_edge_iterator(pred, first, last), + in_edge_iterator(pred, last, last)); + } + + // O(1) + template + std::pair< + typename adjacency_matrix::in_edge_iterator, + typename adjacency_matrix::in_edge_iterator> + in_edges + (typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + typename Graph::vertices_size_type offset = u * (u + 1) / 2; + typename Graph::MatrixIter f = g.m_matrix.begin() + offset; + typename Graph::MatrixIter l = g.m_matrix.end(); + + typename Graph::unfiltered_in_edge_iter + first(f, u, g.m_vertex_set.size()) + , last(l, u, g.m_vertex_set.size()); + + detail::does_edge_exist pred; + typedef typename Graph::in_edge_iterator in_edge_iterator; + return std::make_pair(in_edge_iterator(pred, first, last), + in_edge_iterator(pred, last, last)); + } + + // O(N) + template + typename adjacency_matrix::degree_size_type + in_degree(typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g) + { + typename adjacency_matrix::degree_size_type n = 0; + typename adjacency_matrix::in_edge_iterator f, l; + for (tie(f, l) = in_edges(u, g); f != l; ++f) + ++n; + return n; + } + + //========================================================================= + // Functions required by the AdjacencyGraph concept + + template + std::pair::adjacency_iterator, + typename adjacency_matrix::adjacency_iterator> + adjacent_vertices + (typename adjacency_matrix::vertex_descriptor u, + const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + const Graph& cg = static_cast(g_); + Graph& g = const_cast(cg); + typedef typename Graph::adjacency_iterator adjacency_iterator; + typename Graph::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + return std::make_pair(adjacency_iterator(first, &g), + adjacency_iterator(last, &g)); + } + + //========================================================================= + // Functions required by the VertexListGraph concept + + template + std::pair::vertex_iterator, + typename adjacency_matrix::vertex_iterator> + vertices(const adjacency_matrix& g_) { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end()); + } + + template + typename adjacency_matrix::vertices_size_type + num_vertices(const adjacency_matrix& g) { + return g.m_vertex_set.size(); + } + + //========================================================================= + // Functions required by the EdgeListGraph concept + + template + std::pair::edge_iterator, + typename adjacency_matrix::edge_iterator> + edges(const adjacency_matrix& g_) + { + typedef adjacency_matrix Graph; + Graph& g = const_cast(g_); + + typename Graph::unfiltered_edge_iter + first(g.m_matrix.begin(), g.m_matrix.begin(), + g.m_vertex_set.size()), + last(g.m_matrix.end(), g.m_matrix.begin(), + g.m_vertex_set.size()); + detail::does_edge_exist pred; + typedef typename Graph::edge_iterator edge_iterator; + return std::make_pair(edge_iterator(pred, first, last), + edge_iterator(pred, last, last)); + } + + // O(1) + template + typename adjacency_matrix::edges_size_type + num_edges(const adjacency_matrix& g) + { + return g.m_num_edges; + } + + //========================================================================= + // Functions required by the MutableGraph concept + + // O(1) + template + std::pair::edge_descriptor, bool> + add_edge(typename adjacency_matrix::vertex_descriptor u, + typename adjacency_matrix::vertex_descriptor v, + const EP& ep, + adjacency_matrix& g) + { + typedef typename adjacency_matrix::edge_descriptor + edge_descriptor; + if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) { + ++(g.m_num_edges); + detail::set_property(g.get_edge(u,v), ep, 0); + detail::set_edge_exists(g.get_edge(u,v), true, 0); + return std::make_pair + (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), + true); + } else + return std::make_pair + (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), + false); + } + // O(1) + template + std::pair::edge_descriptor, bool> + add_edge(typename adjacency_matrix::vertex_descriptor u, + typename adjacency_matrix::vertex_descriptor v, + adjacency_matrix& g) + { + EP ep; + return add_edge(u, v, ep, g); + } + + // O(1) + template + void + remove_edge(typename adjacency_matrix::vertex_descriptor u, + typename adjacency_matrix::vertex_descriptor v, + adjacency_matrix& g) + { + --(g.m_num_edges); + detail::set_edge_exists(g.get_edge(u,v), false, 0); + } + + // O(1) + template + void + remove_edge(typename adjacency_matrix::edge_descriptor e, + adjacency_matrix& g) + { + remove_edge(source(e, g), target(e, g), g); + } + + + template + inline typename adjacency_matrix::vertex_descriptor + add_vertex(adjacency_matrix& g) { + // UNDER CONSTRUCTION + assert(false); + return *vertices(g).first; + } + + template + inline typename adjacency_matrix::vertex_descriptor + add_vertex(const VP& vp, adjacency_matrix& g) { + // UNDER CONSTRUCTION + assert(false); + return *vertices(g).first; + } + + template + inline void + remove_vertex(typename adjacency_matrix::vertex_descriptor u, + adjacency_matrix& g) + { + // UNDER CONSTRUCTION + assert(false); + } + + // O(V) + template + void + clear_vertex + (typename adjacency_matrix::vertex_descriptor u, + adjacency_matrix& g) + { + typename adjacency_matrix::vertex_iterator + vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + remove_edge(u, *vi, g); + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + remove_edge(*vi, u, g); + } + + // O(V) + template + void + clear_vertex + (typename adjacency_matrix::vertex_descriptor u, + adjacency_matrix& g) + { + typename adjacency_matrix::vertex_iterator + vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + remove_edge(u, *vi, g); + } + + //========================================================================= + // Vertex Property Map + + template + class adj_matrix_vertex_property_map + : public put_get_helper > + { + public: + typedef T value_type; + typedef R reference; + typedef Vertex key_type; + typedef boost::lvalue_property_map_tag category; + adj_matrix_vertex_property_map() { } + adj_matrix_vertex_property_map(GraphPtr g) : m_g(g) { } + inline reference operator[](key_type v) const { + return get_property_value(m_g->m_vertex_properties[v], Tag()); + } + GraphPtr m_g; + }; + + template + struct adj_matrix_vertex_id_map + : public boost::put_get_helper > + { + typedef Vertex value_type; + typedef Vertex reference; + typedef Vertex key_type; + typedef boost::readable_property_map_tag category; + adj_matrix_vertex_id_map() { } + template + inline adj_matrix_vertex_id_map(const Graph&) { } + inline value_type operator[](key_type v) const { return v; } + }; + + namespace detail { + + struct adj_matrix_any_vertex_pa { + template + struct bind_ { + typedef typename property_value::type Value; + typedef typename boost::graph_traits::vertex_descriptor Vertex; + + typedef adj_matrix_vertex_property_map type; + typedef adj_matrix_vertex_property_map const_type; + }; + }; + struct adj_matrix_id_vertex_pa { + template + struct bind_ { + typedef typename Graph::vertex_descriptor Vertex; + typedef adj_matrix_vertex_id_map type; + typedef adj_matrix_vertex_id_map const_type; + }; + }; + + template + struct adj_matrix_choose_vertex_pa_helper { + typedef adj_matrix_any_vertex_pa type; + }; + template <> + struct adj_matrix_choose_vertex_pa_helper { + typedef adj_matrix_id_vertex_pa type; + }; + + template + struct adj_matrix_choose_vertex_pa { + typedef typename adj_matrix_choose_vertex_pa_helper::type Helper; + typedef typename Helper::template bind_ Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + + struct adj_matrix_vertex_property_selector { + template + struct bind_ { + typedef adj_matrix_choose_vertex_pa Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + }; + + } // namespace detail + + template <> + struct vertex_property_selector { + typedef detail::adj_matrix_vertex_property_selector type; + }; + + //========================================================================= + // Edge Property Map + + + template + class adj_matrix_edge_property_map + : public put_get_helper > + { + public: + typedef T value_type; + typedef R reference; + typedef detail::matrix_edge_desc_impl key_type; + typedef boost::lvalue_property_map_tag category; + inline reference operator[](key_type e) const { + Property& p = *(Property*)e.get_property(); + return get_property_value(p, Tag()); + } + }; + struct adj_matrix_edge_property_selector { + template + struct bind_ { + typedef typename property_value::type T; + typedef typename Graph::vertex_descriptor Vertex; + typedef adj_matrix_edge_property_map type; + typedef adj_matrix_edge_property_map const_type; + }; + }; + template <> + struct edge_property_selector { + typedef adj_matrix_edge_property_selector type; + }; + + //========================================================================= + // Functions required by PropertyGraph + + namespace detail { + + template + typename boost::property_map, + Property>::type + get_dispatch(adjacency_matrix& g, Property, + vertex_property_tag) + { + typedef adjacency_matrix Graph; + typedef typename boost::property_map, + Property>::type PA; + return PA(&g); + } + template + typename boost::property_map, + Property>::type + get_dispatch(adjacency_matrix&, Property, + edge_property_tag) + { + typedef typename boost::property_map, + Property>::type PA; + return PA(); + } + template + typename boost::property_map, + Property>::const_type + get_dispatch(const adjacency_matrix& g, Property, + vertex_property_tag) + { + typedef adjacency_matrix Graph; + typedef typename boost::property_map, + Property>::const_type PA; + return PA(&g); + } + template + typename boost::property_map, + Property>::const_type + get_dispatch(const adjacency_matrix&, Property, + edge_property_tag) + { + typedef typename boost::property_map, + Property>::const_type PA; + return PA(); + } + + } // namespace detail + + template + inline + typename property_map, Property>::type + get(Property p, adjacency_matrix& g) + { + typedef typename property_kind::type Kind; + return detail::get_dispatch(g, p, Kind()); + } + + template + inline + typename property_map, Property>::const_type + get(Property p, const adjacency_matrix& g) + { + typedef typename property_kind::type Kind; + return detail::get_dispatch(g, p, Kind()); + } + + template + inline + typename property_traits< + typename property_map, Property>::const_type + >::value_type + get(Property p, const adjacency_matrix& g, + const Key& key) + { + return get(get(p, g), key); + } + + template + inline void + put(Property p, adjacency_matrix& g, + const Key& key, const Value& value) + { + typedef adjacency_matrix Graph; + typedef typename boost::property_map::type Map; + Map pmap = get(p, g); + put(pmap, key, value); + } + + //========================================================================= + // Other Functions + + template + typename adjacency_matrix::vertex_descriptor + vertex(typename adjacency_matrix::vertices_size_type n, + const adjacency_matrix& g) + { + return n; + } + + // Support for bundled properties +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + inline + typename property_map, + T Bundle::*>::type + get(T Bundle::* p, adjacency_matrix& g) + { + typedef typename property_map, + T Bundle::*>::type + result_type; + return result_type(&g, p); + } + + template + inline + typename property_map, + T Bundle::*>::const_type + get(T Bundle::* p, adjacency_matrix const & g) + { + typedef typename property_map, + T Bundle::*>::const_type + result_type; + return result_type(&g, p); + } + + template + inline T + get(T Bundle::* p, adjacency_matrix const & g, + const Key& key) + { + return get(get(p, g), key); + } + + template + inline void + put(T Bundle::* p, adjacency_matrix& g, + const Key& key, const T& value) + { + put(get(p, g), key, value); + } + +#endif + +} // namespace boost + +#endif // BOOST_ADJACENCY_MATRIX_HPP diff --git a/thirdparty/boost/graph/astar_search.hpp b/thirdparty/boost/graph/astar_search.hpp new file mode 100644 index 0000000..aa8b490 --- /dev/null +++ b/thirdparty/boost/graph/astar_search.hpp @@ -0,0 +1,407 @@ + + +// +//======================================================================= +// Copyright (c) 2004 Kristopher Beevers +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_GRAPH_ASTAR_SEARCH_HPP +#define BOOST_GRAPH_ASTAR_SEARCH_HPP + + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { + + + template + struct AStarHeuristicConcept { + void constraints() + { + function_requires< CopyConstructibleConcept >(); + h(u); + } + Heuristic h; + typename graph_traits::vertex_descriptor u; + }; + + + template + class astar_heuristic : public std::unary_function< + typename graph_traits::vertex_descriptor, CostType> + { + public: + typedef typename graph_traits::vertex_descriptor Vertex; + astar_heuristic() {} + CostType operator()(Vertex u) { return static_cast(0); } + }; + + + + template + struct AStarVisitorConcept { + void constraints() + { + function_requires< CopyConstructibleConcept >(); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.black_target(e, g); + vis.finish_vertex(u, g); + } + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + + template + class astar_visitor : public bfs_visitor { + public: + astar_visitor() {} + astar_visitor(Visitors vis) + : bfs_visitor(vis) {} + + template + void edge_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); + } + template + void edge_not_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + } + private: + template + void tree_edge(Edge e, Graph& g) {} + template + void non_tree_edge(Edge e, Graph& g) {} + }; + template + astar_visitor + make_astar_visitor(Visitors vis) { + return astar_visitor(vis); + } + typedef astar_visitor<> default_astar_visitor; + + + namespace detail { + + template + struct astar_bfs_visitor + { + + typedef typename property_traits::value_type C; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typedef typename property_traits::value_type distance_type; + + astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis, + UpdatableQueue& Q, PredecessorMap p, + CostMap c, DistanceMap d, WeightMap w, + ColorMap col, BinaryFunction combine, + BinaryPredicate compare, C zero) + : m_h(h), m_vis(vis), m_Q(Q), m_predecessor(p), m_cost(c), + m_distance(d), m_weight(w), m_color(col), + m_combine(combine), m_compare(compare), m_zero(zero) {} + + + template + void initialize_vertex(Vertex u, Graph& g) { + m_vis.initialize_vertex(u, g); + } + template + void discover_vertex(Vertex u, Graph& g) { + m_vis.discover_vertex(u, g); + } + template + void examine_vertex(Vertex u, Graph& g) { + m_vis.examine_vertex(u, g); + } + template + void finish_vertex(Vertex u, Graph& g) { + m_vis.finish_vertex(u, g); + } + template + void examine_edge(Edge e, Graph& g) { + if (m_compare(get(m_weight, e), m_zero)) + throw negative_edge(); + m_vis.examine_edge(e, g); + } + template + void non_tree_edge(Edge, Graph&) {} + + + + template + void tree_edge(Edge e, Graph& g) { + m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + + if(m_decreased) { + m_vis.edge_relaxed(e, g); + put(m_cost, target(e, g), + m_combine(get(m_distance, target(e, g)), + m_h(target(e, g)))); + } else + m_vis.edge_not_relaxed(e, g); + } + + + template + void gray_target(Edge e, Graph& g) { + distance_type old_distance = get(m_distance, target(e, g)); + + m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + + /* On x86 Linux with optimization, we sometimes get into a + horrible case where m_decreased is true but the distance hasn't + actually changed. This occurs when the comparison inside + relax() occurs with the 80-bit precision of the x87 floating + point unit, but the difference is lost when the resulting + values are written back to lower-precision memory (e.g., a + double). With the eager Dijkstra's implementation, this results + in looping. */ + if(m_decreased && old_distance != get(m_distance, target(e, g))) { + put(m_cost, target(e, g), + m_combine(get(m_distance, target(e, g)), + m_h(target(e, g)))); + m_Q.update(target(e, g)); + m_vis.edge_relaxed(e, g); + } else + m_vis.edge_not_relaxed(e, g); + } + + + template + void black_target(Edge e, Graph& g) { + distance_type old_distance = get(m_distance, target(e, g)); + + m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + + /* See comment in gray_target */ + if(m_decreased && old_distance != get(m_distance, target(e, g))) { + m_vis.edge_relaxed(e, g); + put(m_cost, target(e, g), + m_combine(get(m_distance, target(e, g)), + m_h(target(e, g)))); + m_Q.push(target(e, g)); + put(m_color, target(e, g), Color::gray()); + m_vis.black_target(e, g); + } else + m_vis.edge_not_relaxed(e, g); + } + + + + AStarHeuristic m_h; + UniformCostVisitor m_vis; + UpdatableQueue& m_Q; + PredecessorMap m_predecessor; + CostMap m_cost; + DistanceMap m_distance; + WeightMap m_weight; + ColorMap m_color; + BinaryFunction m_combine; + BinaryPredicate m_compare; + bool m_decreased; + C m_zero; + + }; + + } // namespace detail + + + + template + inline void + astar_search_no_init + (VertexListGraph &g, + typename graph_traits::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, + PredecessorMap predecessor, CostMap cost, + DistanceMap distance, WeightMap weight, + ColorMap color, VertexIndexMap index_map, + CompareFunction compare, CombineFunction combine, + CostInf inf, CostZero zero) + { + typedef indirect_cmp IndirectCmp; + IndirectCmp icmp(cost, compare); + + typedef typename graph_traits::vertex_descriptor + Vertex; + typedef mutable_queue, + IndirectCmp, VertexIndexMap> + MutableQueue; + MutableQueue Q(num_vertices(g), icmp, index_map); + + detail::astar_bfs_visitor + bfs_vis(h, vis, Q, predecessor, cost, distance, weight, + color, combine, compare, zero); + + breadth_first_visit(g, s, Q, bfs_vis, color); + } + + + // Non-named parameter interface + template + inline void + astar_search + (VertexListGraph &g, + typename graph_traits::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, + PredecessorMap predecessor, CostMap cost, + DistanceMap distance, WeightMap weight, + VertexIndexMap index_map, ColorMap color, + CompareFunction compare, CombineFunction combine, + CostInf inf, CostZero zero) + { + + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + put(color, *ui, Color::white()); + put(distance, *ui, inf); + put(cost, *ui, inf); + put(predecessor, *ui, *ui); + vis.initialize_vertex(*ui, g); + } + put(distance, s, zero); + put(cost, s, h(s)); + + astar_search_no_init + (g, s, h, vis, predecessor, cost, distance, weight, + color, index_map, compare, combine, inf, zero); + + } + + + + namespace detail { + template + inline void + astar_dispatch2 + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + AStarHeuristic h, CostMap cost, DistanceMap distance, + WeightMap weight, IndexMap index_map, ColorMap color, + const Params& params) + { + dummy_property_map p_map; + typedef typename property_traits::value_type C; + astar_search + (g, s, h, + choose_param(get_param(params, graph_visitor), + make_astar_visitor(null_visitor())), + choose_param(get_param(params, vertex_predecessor), p_map), + cost, distance, weight, index_map, color, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_inf_t()), + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION ()), + choose_param(get_param(params, distance_zero_t()), + C())); + } + + template + inline void + astar_dispatch1 + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + AStarHeuristic h, CostMap cost, DistanceMap distance, + WeightMap weight, IndexMap index_map, ColorMap color, + const Params& params) + { + typedef typename property_traits::value_type D; + typename std::vector::size_type + n = is_default_param(distance) ? num_vertices(g) : 1; + std::vector distance_map(n); + n = is_default_param(cost) ? num_vertices(g) : 1; + std::vector cost_map(n); + std::vector color_map(num_vertices(g)); + default_color_type c = white_color; + + detail::astar_dispatch2 + (g, s, h, + choose_param(cost, make_iterator_property_map + (cost_map.begin(), index_map, + cost_map[0])), + choose_param(distance, make_iterator_property_map + (distance_map.begin(), index_map, + distance_map[0])), + weight, index_map, + choose_param(color, make_iterator_property_map + (color_map.begin(), index_map, c)), + params); + } + } // namespace detail + + + // Named parameter interface + template + void + astar_search + (VertexListGraph &g, + typename graph_traits::vertex_descriptor s, + AStarHeuristic h, const bgl_named_params& params) + { + + detail::astar_dispatch1 + (g, s, h, + get_param(params, vertex_rank), + get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + get_param(params, vertex_color), + params); + + } + +} // namespace boost + +#endif // BOOST_GRAPH_ASTAR_SEARCH_HPP diff --git a/thirdparty/boost/graph/bandwidth.hpp b/thirdparty/boost/graph/bandwidth.hpp new file mode 100644 index 0000000..97fd2c6 --- /dev/null +++ b/thirdparty/boost/graph/bandwidth.hpp @@ -0,0 +1,83 @@ +// Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002 +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_BANDWIDTH_HPP +#define BOOST_GRAPH_BANDWIDTH_HPP + +#include // for std::min and std::max +#include +#include +#include + +namespace boost { + + template + typename graph_traits::vertices_size_type + ith_bandwidth(typename graph_traits::vertex_descriptor i, + const Graph& g, + VertexIndexMap index) + { + BOOST_USING_STD_MAX(); + typedef typename graph_traits::vertices_size_type size_type; + size_type b = 0; + typename graph_traits::out_edge_iterator e, end; + for (tie(e, end) = out_edges(i, g); e != end; ++e) { + int f_i = get(index, i); + int f_j = get(index, target(*e, g)); + using namespace std; // to call abs() unqualified + if(f_i > f_j) + b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, size_type(f_i - f_j)); + } + return b; + } + + template + typename graph_traits::vertices_size_type + ith_bandwidth(typename graph_traits::vertex_descriptor i, + const Graph& g) + { + return ith_bandwidth(i, g, get(vertex_index, g)); + } + + template + typename graph_traits::vertices_size_type + bandwidth(const Graph& g, VertexIndexMap index) + { + BOOST_USING_STD_MAX(); + typename graph_traits::vertices_size_type b = 0; + typename graph_traits::vertex_iterator i, end; + for (tie(i, end) = vertices(g); i != end; ++i) + b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, ith_bandwidth(*i, g, index)); + return b; + } + + template + typename graph_traits::vertices_size_type + bandwidth(const Graph& g) + { + return bandwidth(g, get(vertex_index, g)); + } + + template + typename graph_traits::vertices_size_type + edgesum(const Graph& g, VertexIndexMap index_map) + { + typedef typename graph_traits::vertices_size_type size_type; + typedef typename detail::numeric_traits::difference_type diff_t; + size_type sum = 0; + typename graph_traits::edge_iterator i, end; + for (tie(i, end) = edges(g); i != end; ++i) { + diff_t f_u = get(index_map, source(*i, g)); + diff_t f_v = get(index_map, target(*i, g)); + using namespace std; // to call abs() unqualified + sum += abs(f_u - f_v); + } + return sum; + } + +} // namespace boost + +#endif // BOOST_GRAPH_BANDWIDTH_HPP diff --git a/thirdparty/boost/graph/bc_clustering.hpp b/thirdparty/boost/graph/bc_clustering.hpp new file mode 100644 index 0000000..b84e7de --- /dev/null +++ b/thirdparty/boost/graph/bc_clustering.hpp @@ -0,0 +1,164 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP +#define BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + +/** Threshold termination function for the betweenness centrality + * clustering algorithm. + */ +template +struct bc_clustering_threshold +{ + typedef T centrality_type; + + /// Terminate clustering when maximum absolute edge centrality is + /// below the given threshold. + explicit bc_clustering_threshold(T threshold) + : threshold(threshold), dividend(1.0) {} + + /** + * Terminate clustering when the maximum edge centrality is below + * the given threshold. + * + * @param threshold the threshold value + * + * @param g the graph on which the threshold will be calculated + * + * @param normalize when true, the threshold is compared against the + * normalized edge centrality based on the input graph; otherwise, + * the threshold is compared against the absolute edge centrality. + */ + template + bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true) + : threshold(threshold), dividend(1.0) + { + if (normalize) { + typename graph_traits::vertices_size_type n = num_vertices(g); + dividend = T((n - 1) * (n - 2)) / T(2); + } + } + + /** Returns true when the given maximum edge centrality (potentially + * normalized) falls below the threshold. + */ + template + bool operator()(T max_centrality, Edge, const Graph&) + { + return (max_centrality / dividend) < threshold; + } + + protected: + T threshold; + T dividend; +}; + +/** Graph clustering based on edge betweenness centrality. + * + * This algorithm implements graph clustering based on edge + * betweenness centrality. It is an iterative algorithm, where in each + * step it compute the edge betweenness centrality (via @ref + * brandes_betweenness_centrality) and removes the edge with the + * maximum betweenness centrality. The @p done function object + * determines when the algorithm terminates (the edge found when the + * algorithm terminates will not be removed). + * + * @param g The graph on which clustering will be performed. The type + * of this parameter (@c MutableGraph) must be a model of the + * VertexListGraph, IncidenceGraph, EdgeListGraph, and Mutable Graph + * concepts. + * + * @param done The function object that indicates termination of the + * algorithm. It must be a ternary function object thats accepts the + * maximum centrality, the descriptor of the edge that will be + * removed, and the graph @p g. + * + * @param edge_centrality (UTIL/OUT) The property map that will store + * the betweenness centrality for each edge. When the algorithm + * terminates, it will contain the edge centralities for the + * graph. The type of this property map must model the + * ReadWritePropertyMap concept. Defaults to an @c + * iterator_property_map whose value type is + * @c Done::centrality_type and using @c get(edge_index, g) for the + * index map. + * + * @param vertex_index (IN) The property map that maps vertices to + * indices in the range @c [0, num_vertices(g)). This type of this + * property map must model the ReadablePropertyMap concept and its + * value type must be an integral type. Defaults to + * @c get(vertex_index, g). + */ +template +void +betweenness_centrality_clustering(MutableGraph& g, Done done, + EdgeCentralityMap edge_centrality, + VertexIndexMap vertex_index) +{ + typedef typename property_traits::value_type + centrality_type; + typedef typename graph_traits::edge_iterator edge_iterator; + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::vertices_size_type + vertices_size_type; + + if (edges(g).first == edges(g).second) return; + + // Function object that compares the centrality of edges + indirect_cmp > + cmp(edge_centrality); + + bool is_done; + do { + brandes_betweenness_centrality(g, + edge_centrality_map(edge_centrality) + .vertex_index_map(vertex_index)); + edge_descriptor e = *max_element(edges(g).first, edges(g).second, cmp); + is_done = done(get(edge_centrality, e), e, g); + if (!is_done) remove_edge(e, g); + } while (!is_done && edges(g).first != edges(g).second); +} + +/** + * \overload + */ +template +void +betweenness_centrality_clustering(MutableGraph& g, Done done, + EdgeCentralityMap edge_centrality) +{ + betweenness_centrality_clustering(g, done, edge_centrality, + get(vertex_index, g)); +} + +/** + * \overload + */ +template +void +betweenness_centrality_clustering(MutableGraph& g, Done done) +{ + typedef typename Done::centrality_type centrality_type; + std::vector edge_centrality(num_edges(g)); + betweenness_centrality_clustering(g, done, + make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)), + get(vertex_index, g)); +} + +} // end namespace boost + +#endif // BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP diff --git a/thirdparty/boost/graph/bellman_ford_shortest_paths.hpp b/thirdparty/boost/graph/bellman_ford_shortest_paths.hpp new file mode 100644 index 0000000..91ba9d1 --- /dev/null +++ b/thirdparty/boost/graph/bellman_ford_shortest_paths.hpp @@ -0,0 +1,241 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the 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 implements the function + + template + bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, + const bgl_named_params& params) + + */ + + +#ifndef BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP +#define BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + struct BellmanFordVisitorConcept { + void constraints() { + function_requires< CopyConstructibleConcept >(); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.edge_minimized(e, g); + vis.edge_not_minimized(e, g); + } + Visitor vis; + Graph g; + typename graph_traits::edge_descriptor e; + }; + + template + class bellman_visitor { + public: + bellman_visitor() { } + bellman_visitor(Visitors vis) : m_vis(vis) { } + + template + void examine_edge(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, on_examine_edge()); + } + template + void edge_relaxed(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, on_edge_relaxed()); + } + template + void edge_not_relaxed(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, on_edge_not_relaxed()); + } + template + void edge_minimized(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, on_edge_minimized()); + } + template + void edge_not_minimized(Edge u, Graph& g) { + invoke_visitors(m_vis, u, g, on_edge_not_minimized()); + } + protected: + Visitors m_vis; + }; + template + bellman_visitor + make_bellman_visitor(Visitors vis) { + return bellman_visitor(vis); + } + typedef bellman_visitor<> default_bellman_visitor; + + template + bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, + WeightMap weight, + PredecessorMap pred, + DistanceMap distance, + BinaryFunction combine, + BinaryPredicate compare, + BellmanFordVisitor v) + { + function_requires >(); + typedef graph_traits GTraits; + typedef typename GTraits::edge_descriptor Edge; + typedef typename GTraits::vertex_descriptor Vertex; + function_requires >(); + function_requires >(); + typedef typename property_traits::value_type D_value; + typedef typename property_traits::value_type W_value; + + typename GTraits::edge_iterator i, end; + + for (Size k = 0; k < N; ++k) { + bool at_least_one_edge_relaxed = false; + for (tie(i, end) = edges(g); i != end; ++i) { + v.examine_edge(*i, g); + if (relax(*i, g, weight, pred, distance, combine, compare)) { + at_least_one_edge_relaxed = true; + v.edge_relaxed(*i, g); + } else + v.edge_not_relaxed(*i, g); + } + if (!at_least_one_edge_relaxed) + break; + } + + for (tie(i, end) = edges(g); i != end; ++i) + if (compare(combine(get(distance, source(*i, g)), get(weight, *i)), + get(distance, target(*i,g)))) + { + v.edge_not_minimized(*i, g); + return false; + } else + v.edge_minimized(*i, g); + + return true; + } + + namespace detail { + + template + bool + bellman_dispatch2 + (VertexAndEdgeListGraph& g, + typename graph_traits::vertex_descriptor s, + Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, + const bgl_named_params& params) + { + typedef typename property_traits::value_type D; + bellman_visitor<> null_vis; + typedef typename property_traits::value_type weight_type; + typename graph_traits::vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + put(distance, *v, (std::numeric_limits::max)()); + put(pred, *v, *v); + } + put(distance, s, weight_type(0)); + return bellman_ford_shortest_paths + (g, N, weight, pred, distance, + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, graph_visitor), + null_vis) + ); + } + + template + bool + bellman_dispatch2 + (VertexAndEdgeListGraph& g, + detail::error_property_not_found, + Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, + const bgl_named_params& params) + { + typedef typename property_traits::value_type D; + bellman_visitor<> null_vis; + return bellman_ford_shortest_paths + (g, N, weight, pred, distance, + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, graph_visitor), + null_vis) + ); + } + + template + bool bellman_dispatch(EdgeListGraph& g, Size N, + WeightMap weight, DistanceMap distance, + const bgl_named_params& params) + { + dummy_property_map dummy_pred; + return + detail::bellman_dispatch2 + (g, + get_param(params, root_vertex_t()), + N, weight, + choose_param(get_param(params, vertex_predecessor), dummy_pred), + distance, + params); + } + } // namespace detail + + template + bool bellman_ford_shortest_paths + (EdgeListGraph& g, Size N, + const bgl_named_params& params) + { + return detail::bellman_dispatch + (g, N, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + params); + } + + template + bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N) + { + bgl_named_params params(0); + return bellman_ford_shortest_paths(g, N, params); + } + + template + bool bellman_ford_shortest_paths + (VertexAndEdgeListGraph& g, + const bgl_named_params& params) + { + function_requires >(); + return detail::bellman_dispatch + (g, num_vertices(g), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + params); + } +} // namespace boost + +#endif // BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP diff --git a/thirdparty/boost/graph/betweenness_centrality.hpp b/thirdparty/boost/graph/betweenness_centrality.hpp new file mode 100644 index 0000000..6896155 --- /dev/null +++ b/thirdparty/boost/graph/betweenness_centrality.hpp @@ -0,0 +1,597 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP +#define BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace detail { namespace graph { + + /** + * Customized visitor passed to Dijkstra's algorithm by Brandes' + * betweenness centrality algorithm. This visitor is responsible for + * keeping track of the order in which vertices are discovered, the + * predecessors on the shortest path(s) to a vertex, and the number + * of shortest paths. + */ + template + struct brandes_dijkstra_visitor : public bfs_visitor<> + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + brandes_dijkstra_visitor(std::stack& ordered_vertices, + WeightMap weight, + IncomingMap incoming, + DistanceMap distance, + PathCountMap path_count) + : ordered_vertices(ordered_vertices), weight(weight), + incoming(incoming), distance(distance), + path_count(path_count) + { } + + /** + * Whenever an edge e = (v, w) is relaxed, the incoming edge list + * for w is set to {(v, w)} and the shortest path count of w is set to + * the number of paths that reach {v}. + */ + void edge_relaxed(edge_descriptor e, const Graph& g) + { + vertex_descriptor v = source(e, g), w = target(e, g); + incoming[w].clear(); + incoming[w].push_back(e); + put(path_count, w, get(path_count, v)); + } + + /** + * If an edge e = (v, w) was not relaxed, it may still be the case + * that we've found more equally-short paths, so include {(v, w)} in the + * incoming edges of w and add all of the shortest paths to v to the + * shortest path count of w. + */ + void edge_not_relaxed(edge_descriptor e, const Graph& g) + { + typedef typename property_traits::value_type weight_type; + typedef typename property_traits::value_type distance_type; + vertex_descriptor v = source(e, g), w = target(e, g); + distance_type d_v = get(distance, v), d_w = get(distance, w); + weight_type w_e = get(weight, e); + + closed_plus combine; + if (d_w == combine(d_v, w_e)) { + put(path_count, w, get(path_count, w) + get(path_count, v)); + incoming[w].push_back(e); + } + } + + /// Keep track of vertices as they are reached + void examine_vertex(vertex_descriptor w, const Graph&) + { + ordered_vertices.push(w); + } + + private: + std::stack& ordered_vertices; + WeightMap weight; + IncomingMap incoming; + DistanceMap distance; + PathCountMap path_count; + }; + + /** + * Function object that calls Dijkstra's shortest paths algorithm + * using the Dijkstra visitor for the Brandes betweenness centrality + * algorithm. + */ + template + struct brandes_dijkstra_shortest_paths + { + brandes_dijkstra_shortest_paths(WeightMap weight_map) + : weight_map(weight_map) { } + + template + void + operator()(Graph& g, + typename graph_traits::vertex_descriptor s, + std::stack::vertex_descriptor>& ov, + IncomingMap incoming, + DistanceMap distance, + PathCountMap path_count, + VertexIndexMap vertex_index) + { + typedef brandes_dijkstra_visitor visitor_type; + visitor_type visitor(ov, weight_map, incoming, distance, path_count); + + dijkstra_shortest_paths(g, s, + boost::weight_map(weight_map) + .vertex_index_map(vertex_index) + .distance_map(distance) + .visitor(visitor)); + } + + private: + WeightMap weight_map; + }; + + /** + * Function object that invokes breadth-first search for the + * unweighted form of the Brandes betweenness centrality algorithm. + */ + struct brandes_unweighted_shortest_paths + { + /** + * Customized visitor passed to breadth-first search, which + * records predecessor and the number of shortest paths to each + * vertex. + */ + template + struct visitor_type : public bfs_visitor<> + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + + visitor_type(IncomingMap incoming, DistanceMap distance, + PathCountMap path_count, + std::stack& ordered_vertices) + : incoming(incoming), distance(distance), + path_count(path_count), ordered_vertices(ordered_vertices) { } + + /// Keep track of vertices as they are reached + void examine_vertex(vertex_descriptor v, Graph&) + { + ordered_vertices.push(v); + } + + /** + * Whenever an edge e = (v, w) is labelled a tree edge, the + * incoming edge list for w is set to {(v, w)} and the shortest + * path count of w is set to the number of paths that reach {v}. + */ + void tree_edge(edge_descriptor e, Graph& g) + { + vertex_descriptor v = source(e, g); + vertex_descriptor w = target(e, g); + put(distance, w, get(distance, v) + 1); + + put(path_count, w, get(path_count, v)); + incoming[w].push_back(e); + } + + /** + * If an edge e = (v, w) is not a tree edge, it may still be the + * case that we've found more equally-short paths, so include (v, w) + * in the incoming edge list of w and add all of the shortest + * paths to v to the shortest path count of w. + */ + void non_tree_edge(edge_descriptor e, Graph& g) + { + vertex_descriptor v = source(e, g); + vertex_descriptor w = target(e, g); + if (get(distance, w) == get(distance, v) + 1) { + put(path_count, w, get(path_count, w) + get(path_count, v)); + incoming[w].push_back(e); + } + } + + private: + IncomingMap incoming; + DistanceMap distance; + PathCountMap path_count; + std::stack& ordered_vertices; + }; + + template + void + operator()(Graph& g, + typename graph_traits::vertex_descriptor s, + std::stack::vertex_descriptor>& ov, + IncomingMap incoming, + DistanceMap distance, + PathCountMap path_count, + VertexIndexMap vertex_index) + { + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + + visitor_type + visitor(incoming, distance, path_count, ov); + + std::vector + colors(num_vertices(g), color_traits::white()); + boost::queue Q; + breadth_first_visit(g, s, Q, visitor, + make_iterator_property_map(colors.begin(), + vertex_index)); + } + }; + + // When the edge centrality map is a dummy property map, no + // initialization is needed. + template + inline void + init_centrality_map(std::pair, dummy_property_map) { } + + // When we have a real edge centrality map, initialize all of the + // centralities to zero. + template + void + init_centrality_map(std::pair keys, Centrality centrality_map) + { + typedef typename property_traits::value_type + centrality_type; + while (keys.first != keys.second) { + put(centrality_map, *keys.first, centrality_type(0)); + ++keys.first; + } + } + + // When the edge centrality map is a dummy property map, no update + // is performed. + template + inline void + update_centrality(dummy_property_map, const Key&, const T&) { } + + // When we have a real edge centrality map, add the value to the map + template + inline void + update_centrality(CentralityMap centrality_map, Key k, const T& x) + { put(centrality_map, k, get(centrality_map, k) + x); } + + template + inline void + divide_centrality_by_two(std::pair, dummy_property_map) {} + + template + inline void + divide_centrality_by_two(std::pair keys, + CentralityMap centrality_map) + { + typename property_traits::value_type two(2); + while (keys.first != keys.second) { + put(centrality_map, *keys.first, get(centrality_map, *keys.first) / two); + ++keys.first; + } + } + + template + void + brandes_betweenness_centrality_impl(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index, + ShortestPaths shortest_paths) + { + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits::edge_iterator edge_iterator; + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + + // Initialize centrality + init_centrality_map(vertices(g), centrality); + init_centrality_map(edges(g), edge_centrality_map); + + std::stack ordered_vertices; + vertex_iterator s, s_end; + for (tie(s, s_end) = vertices(g); s != s_end; ++s) { + // Initialize for this iteration + vertex_iterator w, w_end; + for (tie(w, w_end) = vertices(g); w != w_end; ++w) { + incoming[*w].clear(); + put(path_count, *w, 0); + put(dependency, *w, 0); + } + put(path_count, *s, 1); + + // Execute the shortest paths algorithm. This will be either + // Dijkstra's algorithm or a customized breadth-first search, + // depending on whether the graph is weighted or unweighted. + shortest_paths(g, *s, ordered_vertices, incoming, distance, + path_count, vertex_index); + + while (!ordered_vertices.empty()) { + vertex_descriptor w = ordered_vertices.top(); + ordered_vertices.pop(); + + typedef typename property_traits::value_type + incoming_type; + typedef typename incoming_type::iterator incoming_iterator; + typedef typename property_traits::value_type + dependency_type; + + for (incoming_iterator vw = incoming[w].begin(); + vw != incoming[w].end(); ++vw) { + vertex_descriptor v = source(*vw, g); + dependency_type factor = dependency_type(get(path_count, v)) + / dependency_type(get(path_count, w)); + factor *= (dependency_type(1) + get(dependency, w)); + put(dependency, v, get(dependency, v) + factor); + update_centrality(edge_centrality_map, *vw, factor); + } + + if (w != *s) { + update_centrality(centrality, w, get(dependency, w)); + } + } + } + + typedef typename graph_traits::directed_category directed_category; + const bool is_undirected = + is_convertible::value; + if (is_undirected) { + divide_centrality_by_two(vertices(g), centrality); + divide_centrality_by_two(edges(g), edge_centrality_map); + } + } + +} } // end namespace detail::graph + +template +void +brandes_betweenness_centrality(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index) +{ + detail::graph::brandes_unweighted_shortest_paths shortest_paths; + + detail::graph::brandes_betweenness_centrality_impl(g, centrality, + edge_centrality_map, + incoming, distance, + dependency, path_count, + vertex_index, + shortest_paths); +} + +template +void +brandes_betweenness_centrality(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index, + WeightMap weight_map) +{ + detail::graph::brandes_dijkstra_shortest_paths + shortest_paths(weight_map); + + detail::graph::brandes_betweenness_centrality_impl(g, centrality, + edge_centrality_map, + incoming, distance, + dependency, path_count, + vertex_index, + shortest_paths); +} + +namespace detail { namespace graph { + template + void + brandes_betweenness_centrality_dispatch2(const Graph& g, + CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, + WeightMap weight_map, + VertexIndexMap vertex_index) + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename mpl::if_c<(is_same::value), + EdgeCentralityMap, + CentralityMap>::type a_centrality_map; + typedef typename property_traits::value_type + centrality_type; + + typename graph_traits::vertices_size_type V = num_vertices(g); + + std::vector > incoming(V); + std::vector distance(V); + std::vector dependency(V); + std::vector path_count(V); + + brandes_betweenness_centrality( + g, centrality, edge_centrality_map, + make_iterator_property_map(incoming.begin(), vertex_index), + make_iterator_property_map(distance.begin(), vertex_index), + make_iterator_property_map(dependency.begin(), vertex_index), + make_iterator_property_map(path_count.begin(), vertex_index), + vertex_index, + weight_map); + } + + + template + void + brandes_betweenness_centrality_dispatch2(const Graph& g, + CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, + VertexIndexMap vertex_index) + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename mpl::if_c<(is_same::value), + EdgeCentralityMap, + CentralityMap>::type a_centrality_map; + typedef typename property_traits::value_type + centrality_type; + + typename graph_traits::vertices_size_type V = num_vertices(g); + + std::vector > incoming(V); + std::vector distance(V); + std::vector dependency(V); + std::vector path_count(V); + + brandes_betweenness_centrality( + g, centrality, edge_centrality_map, + make_iterator_property_map(incoming.begin(), vertex_index), + make_iterator_property_map(distance.begin(), vertex_index), + make_iterator_property_map(dependency.begin(), vertex_index), + make_iterator_property_map(path_count.begin(), vertex_index), + vertex_index); + } + + template + struct brandes_betweenness_centrality_dispatch1 + { + template + static void + run(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index, + WeightMap weight_map) + { + brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map, + weight_map, vertex_index); + } + }; + + template<> + struct brandes_betweenness_centrality_dispatch1 + { + template + static void + run(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index, + error_property_not_found) + { + brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map, + vertex_index); + } + }; + +} } // end namespace detail::graph + +template +void +brandes_betweenness_centrality(const Graph& g, + const bgl_named_params& params) +{ + typedef bgl_named_params named_params; + + typedef typename property_value::type ew; + detail::graph::brandes_betweenness_centrality_dispatch1::run( + g, + choose_param(get_param(params, vertex_centrality), + dummy_property_map()), + choose_param(get_param(params, edge_centrality), + dummy_property_map()), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + get_param(params, edge_weight)); +} + +template +void +brandes_betweenness_centrality(const Graph& g, CentralityMap centrality) +{ + detail::graph::brandes_betweenness_centrality_dispatch2( + g, centrality, dummy_property_map(), get(vertex_index, g)); +} + +template +void +brandes_betweenness_centrality(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map) +{ + detail::graph::brandes_betweenness_centrality_dispatch2( + g, centrality, edge_centrality_map, get(vertex_index, g)); +} + +/** + * Converts "absolute" betweenness centrality (as computed by the + * brandes_betweenness_centrality algorithm) in the centrality map + * into "relative" centrality. The result is placed back into the + * given centrality map. + */ +template +void +relative_betweenness_centrality(const Graph& g, CentralityMap centrality) +{ + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename property_traits::value_type centrality_type; + + typename graph_traits::vertices_size_type n = num_vertices(g); + centrality_type factor = centrality_type(2)/centrality_type(n*n - 3*n + 2); + vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + put(centrality, *v, factor * get(centrality, *v)); + } +} + +// Compute the central point dominance of a graph. +template +typename property_traits::value_type +central_point_dominance(const Graph& g, CentralityMap centrality) +{ + using std::max; + + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename property_traits::value_type centrality_type; + + typename graph_traits::vertices_size_type n = num_vertices(g); + + // Find max centrality + centrality_type max_centrality(0); + vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + max_centrality = (max)(max_centrality, get(centrality, *v)); + } + + // Compute central point dominance + centrality_type sum(0); + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + sum += (max_centrality - get(centrality, *v)); + } + return sum/(n-1); +} + +} // end namespace boost + +#endif // BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP diff --git a/thirdparty/boost/graph/biconnected_components.hpp b/thirdparty/boost/graph/biconnected_components.hpp new file mode 100644 index 0000000..ca9d8bf --- /dev/null +++ b/thirdparty/boost/graph/biconnected_components.hpp @@ -0,0 +1,415 @@ +// Copyright (c) Jeremy Siek 2001 +// Copyright (c) Douglas Gregor 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) + +// NOTE: this final is generated by libs/graph/doc/biconnected_components.w + +#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP +#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP + +#include +#include +#include // for std::min and std::max +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace detail + { + template + struct biconnected_components_visitor : public dfs_visitor<> + { + biconnected_components_visitor + (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm, + std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred, + OutputIterator out, Stack& S, DFSVisitor vis) + : comp(comp), c(c), dtm(dtm), dfs_time(dfs_time), lowpt(lowpt), + pred(pred), out(out), S(S), vis(vis) { } + + template + void initialize_vertex(const Vertex& u, Graph& g) + { + vis.initialize_vertex(u, g); + } + + template + void start_vertex(const Vertex& u, Graph& g) + { + put(pred, u, u); + vis.start_vertex(u, g); + } + + template + void discover_vertex(const Vertex& u, Graph& g) + { + put(dtm, u, ++dfs_time); + put(lowpt, u, get(dtm, u)); + vis.discover_vertex(u, g); + } + + template + void examine_edge(const Edge& e, Graph& g) + { + vis.examine_edge(e, g); + } + + template + void tree_edge(const Edge& e, Graph& g) + { + S.push(e); + put(pred, target(e, g), source(e, g)); + vis.tree_edge(e, g); + } + + template + void back_edge(const Edge& e, Graph& g) + { + BOOST_USING_STD_MIN(); + + if ( target(e, g) != get(pred, source(e, g)) ) { + S.push(e); + put(lowpt, source(e, g), + min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, source(e, g)), + get(dtm, target(e, g)))); + vis.back_edge(e, g); + } + } + + template + void forward_or_cross_edge(const Edge& e, Graph& g) + { + vis.forward_or_cross_edge(e, g); + } + + template + void finish_vertex(const Vertex& u, Graph& g) + { + BOOST_USING_STD_MIN(); + Vertex parent = get(pred, u); + const std::size_t dtm_of_dubious_parent = get(dtm, parent); + bool is_art_point = false; + if ( dtm_of_dubious_parent > get(dtm, u) ) { + parent = get(pred, parent); + is_art_point = true; + put(pred, get(pred, u), u); + put(pred, u, parent); + } + + if ( parent == u ) { // at top + if ( get(dtm, u) + 1 == dtm_of_dubious_parent ) + is_art_point = false; + } else { + put(lowpt, parent, + min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), + get(lowpt, u))); + + if (get(lowpt, u) >= get(dtm, parent)) { + if ( get(dtm, parent) > get(dtm, get(pred, parent)) ) { + put(pred, u, get(pred, parent)); + put(pred, parent, u); + } + + while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) { + put(comp, S.top(), c); + S.pop(); + } + put(comp, S.top(), c); + S.pop(); + ++c; + if ( S.empty() ) { + put(pred, u, parent); + put(pred, parent, u); + } + } + } + if ( is_art_point ) + *out++ = u; + vis.finish_vertex(u, g); + } + + ComponentMap comp; + std::size_t& c; + DiscoverTimeMap dtm; + std::size_t& dfs_time; + LowPointMap lowpt; + PredecessorMap pred; + OutputIterator out; + Stack& S; + DFSVisitor vis; + }; + + template + std::pair + biconnected_components_impl(const Graph & g, ComponentMap comp, + OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm, + LowPointMap lowpt, PredecessorMap pred, DFSVisitor dfs_vis) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + + std::size_t num_components = 0; + std::size_t dfs_time = 0; + std::stack S; + + biconnected_components_visitor, + DFSVisitor> + vis(comp, num_components, dtm, dfs_time, lowpt, pred, out, + S, dfs_vis); + + depth_first_search(g, visitor(vis).vertex_index_map(index_map)); + + return std::pair(num_components, vis.out); + } + + template + struct bicomp_dispatch3 + { + template + static std::pair apply (const Graph & g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, LowPointMap lowpt, + const bgl_named_params& params, PredecessorMap pred) + { + return biconnected_components_impl + (g, comp, out, index_map, dtm, lowpt, pred, + choose_param(get_param(params, graph_visitor), + make_dfs_visitor(null_visitor()))); + } + }; + + template <> + struct bicomp_dispatch3 + { + template + static std::pair apply (const Graph & g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, LowPointMap lowpt, + const bgl_named_params& params, + error_property_not_found) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + std::vector pred(num_vertices(g)); + vertex_t vert = graph_traits::null_vertex(); + + return biconnected_components_impl + (g, comp, out, index_map, dtm, lowpt, + make_iterator_property_map(pred.begin(), index_map, vert), + choose_param(get_param(params, graph_visitor), + make_dfs_visitor(null_visitor()))); + } + }; + + template + struct bicomp_dispatch2 + { + template + static std::pair apply (const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, const bgl_named_params& params, + LowPointMap lowpt) + { + typedef typename property_value< bgl_named_params, + vertex_predecessor_t>::type dispatch_type; + + return bicomp_dispatch3::apply + (g, comp, out, index_map, dtm, lowpt, params, + get_param(params, vertex_predecessor)); + } + }; + + + template <> + struct bicomp_dispatch2 + { + template + static std::pair apply (const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, const bgl_named_params& params, + error_property_not_found) + { + typedef typename graph_traits::vertices_size_type + vertices_size_type; + std::vector lowpt(num_vertices(g)); + vertices_size_type vst(0); + + typedef typename property_value< bgl_named_params, + vertex_predecessor_t>::type dispatch_type; + + return bicomp_dispatch3::apply + (g, comp, out, index_map, dtm, + make_iterator_property_map(lowpt.begin(), index_map, vst), + params, get_param(params, vertex_predecessor)); + } + }; + + template + struct bicomp_dispatch1 + { + template + static std::pair apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + const bgl_named_params& params, DiscoverTimeMap dtm) + { + typedef typename property_value< bgl_named_params, + vertex_lowpoint_t>::type dispatch_type; + + return bicomp_dispatch2::apply + (g, comp, out, index_map, dtm, params, + get_param(params, vertex_lowpoint)); + } + }; + + template <> + struct bicomp_dispatch1 + { + template + static std::pair apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + const bgl_named_params& params, error_property_not_found) + { + typedef typename graph_traits::vertices_size_type + vertices_size_type; + std::vector discover_time(num_vertices(g)); + vertices_size_type vst(0); + + typedef typename property_value< bgl_named_params, + vertex_lowpoint_t>::type dispatch_type; + + return bicomp_dispatch2::apply + (g, comp, out, index_map, + make_iterator_property_map(discover_time.begin(), index_map, vst), + params, get_param(params, vertex_lowpoint)); + } + }; + + } + + template + std::pair + biconnected_components(const Graph& g, ComponentMap comp, + OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt) + { + typedef detail::error_property_not_found dispatch_type; + + return detail::bicomp_dispatch3::apply + (g, comp, out, + get(vertex_index, g), + dtm, lowpt, + bgl_named_params(0), + detail::error_property_not_found()); + } + + template + std::pair + biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, + const bgl_named_params& params) + { + typedef typename property_value< bgl_named_params, + vertex_discover_time_t>::type dispatch_type; + + return detail::bicomp_dispatch1::apply(g, comp, out, + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + params, get_param(params, vertex_discover_time)); + } + + template < typename Graph, typename ComponentMap, typename OutputIterator> + std::pair + biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out) + { + return biconnected_components(g, comp, out, + bgl_named_params(0)); + } + + namespace graph_detail { + struct dummy_output_iterator + { + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void pointer; + typedef void difference_type; + + struct reference { + template + reference& operator=(const T&) { return *this; } + }; + + reference operator*() const { return reference(); } + dummy_output_iterator& operator++() { return *this; } + dummy_output_iterator operator++(int) { return *this; } + }; + } // end namespace graph_detail + + template + std::size_t + biconnected_components(const Graph& g, ComponentMap comp, + const bgl_named_params& params) + { + return biconnected_components(g, comp, + graph_detail::dummy_output_iterator(), params).first; + } + + template + std::size_t + biconnected_components(const Graph& g, ComponentMap comp) + { + return biconnected_components(g, comp, + graph_detail::dummy_output_iterator()).first; + } + + template + OutputIterator + articulation_points(const Graph& g, OutputIterator out, + const bgl_named_params& params) + { + return biconnected_components(g, dummy_property_map(), out, + params).second; + } + + template + OutputIterator + articulation_points(const Graph& g, OutputIterator out) + { + return biconnected_components(g, dummy_property_map(), out, + bgl_named_params(0)).second; + } + +} // namespace boost + +#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */ diff --git a/thirdparty/boost/graph/boyer_myrvold_planar_test.hpp b/thirdparty/boost/graph/boyer_myrvold_planar_test.hpp new file mode 100644 index 0000000..899ef3c --- /dev/null +++ b/thirdparty/boost/graph/boyer_myrvold_planar_test.hpp @@ -0,0 +1,322 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef __BOYER_MYRVOLD_PLANAR_TEST_HPP__ +#define __BOYER_MYRVOLD_PLANAR_TEST_HPP__ + +#include +#include +#include +#include + + +namespace boost +{ + + struct no_kuratowski_subgraph_isolation {}; + struct no_planar_embedding {}; + + namespace boyer_myrvold_params + { + + BOOST_PARAMETER_KEYWORD(tag, graph) + BOOST_PARAMETER_KEYWORD(tag, embedding) + BOOST_PARAMETER_KEYWORD(tag, kuratowski_subgraph) + BOOST_PARAMETER_KEYWORD(tag, vertex_index_map) + BOOST_PARAMETER_KEYWORD(tag, edge_index_map) + + typedef parameter::parameters< parameter::required, + tag::embedding, + tag::kuratowski_subgraph, + tag::vertex_index_map, + tag::edge_index_map + > boyer_myrvold_params_t; + + namespace core + { + + template + bool dispatched_boyer_myrvold(ArgumentPack const& args, + mpl::true_, + mpl::true_ + ) + { + //Dispatch for no planar embedding, no kuratowski subgraph isolation + + typedef typename remove_const + < + typename remove_reference + < typename parameter::binding + < ArgumentPack, tag::graph>::type + >::type + >::type graph_t; + + typedef typename parameter::binding + < ArgumentPack, + tag::vertex_index_map, + typename property_map + < typename remove_reference::type, + vertex_index_t>::const_type + >::type vertex_index_map_t; + + boyer_myrvold_impl + + planarity_tester(args[graph], + args[vertex_index_map | + get(vertex_index, args[graph]) + ] + ); + + return planarity_tester.is_planar() ? true : false; + } + + + + template + bool dispatched_boyer_myrvold(ArgumentPack const& args, + mpl::true_, + mpl::false_ + ) + { + //Dispatch for no planar embedding, kuratowski subgraph isolation + typedef typename remove_const + < + typename remove_reference + < typename parameter::binding + < ArgumentPack, tag::graph>::type + >::type + >::type graph_t; + + typedef typename parameter::binding + < ArgumentPack, + tag::vertex_index_map, + typename property_map::type + >::type vertex_index_map_t; + + boyer_myrvold_impl + + planarity_tester(args[graph], + args[vertex_index_map | + get(vertex_index, args[graph]) + ] + ); + + if (planarity_tester.is_planar()) + return true; + else + { + planarity_tester.extract_kuratowski_subgraph + (args[kuratowski_subgraph], + args[edge_index_map|get(edge_index, args[graph])] + ); + return false; + } + } + + + + + template + bool dispatched_boyer_myrvold(ArgumentPack const& args, + mpl::false_, + mpl::true_ + ) + { + //Dispatch for planar embedding, no kuratowski subgraph isolation + typedef typename remove_const + < + typename remove_reference + < typename parameter::binding + < ArgumentPack, tag::graph>::type + >::type + >::type graph_t; + + typedef typename parameter::binding + < ArgumentPack, + tag::vertex_index_map, + typename property_map::type + >::type vertex_index_map_t; + + boyer_myrvold_impl + + planarity_tester(args[graph], + args[vertex_index_map | + get(vertex_index, args[graph]) + ] + ); + + if (planarity_tester.is_planar()) + { + planarity_tester.make_edge_permutation(args[embedding]); + return true; + } + else + return false; + } + + + + template + bool dispatched_boyer_myrvold(ArgumentPack const& args, + mpl::false_, + mpl::false_ + ) + { + //Dispatch for planar embedding, kuratowski subgraph isolation + typedef typename remove_const + < + typename remove_reference + < typename parameter::binding + < ArgumentPack, tag::graph>::type + >::type + >::type graph_t; + + typedef typename parameter::binding + < ArgumentPack, + tag::vertex_index_map, + typename property_map::type + >::type vertex_index_map_t; + + boyer_myrvold_impl + + planarity_tester(args[graph], + args[vertex_index_map | + get(vertex_index, args[graph]) + ] + ); + + if (planarity_tester.is_planar()) + { + planarity_tester.make_edge_permutation(args[embedding]); + return true; + } + else + { + planarity_tester.extract_kuratowski_subgraph + (args[kuratowski_subgraph], + args[edge_index_map | get(edge_index, args[graph])] + ); + return false; + } + } + + + + + template + bool boyer_myrvold_planarity_test(ArgumentPack const& args) + { + + typedef typename parameter::binding + < ArgumentPack, + tag::kuratowski_subgraph, + const no_kuratowski_subgraph_isolation& + >::type + kuratowski_arg_t; + + typedef typename parameter::binding + < ArgumentPack, + tag::embedding, + const no_planar_embedding& + >::type + embedding_arg_t; + + return dispatched_boyer_myrvold + (args, + boost::is_same + (), + boost::is_same + () + ); + } + + + + } //namespace core + + } //namespace boyer_myrvold_params + + + template + bool boyer_myrvold_planarity_test(A0 const& arg0) + { + return boyer_myrvold_params::core::boyer_myrvold_planarity_test + (boyer_myrvold_params::boyer_myrvold_params_t()(arg0)); + } + + template + // bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) + bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) + { + return boyer_myrvold_params::core::boyer_myrvold_planarity_test + (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1)); + } + + template + bool boyer_myrvold_planarity_test(A0 const& arg0, + A1 const& arg1, + A2 const& arg2 + ) + { + return boyer_myrvold_params::core::boyer_myrvold_planarity_test + (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2)); + } + + template + bool boyer_myrvold_planarity_test(A0 const& arg0, + A1 const& arg1, + A2 const& arg2, + A3 const& arg3 + ) + { + return boyer_myrvold_params::core::boyer_myrvold_planarity_test + (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2,arg3)); + } + + template + bool boyer_myrvold_planarity_test(A0 const& arg0, + A1 const& arg1, + A2 const& arg2, + A3 const& arg3, + A4 const& arg4 + ) + { + return boyer_myrvold_params::core::boyer_myrvold_planarity_test + (boyer_myrvold_params::boyer_myrvold_params_t() + (arg0,arg1,arg2,arg3,arg4) + ); + } + + +} + +#endif //__BOYER_MYRVOLD_PLANAR_TEST_HPP__ diff --git a/thirdparty/boost/graph/breadth_first_search.hpp b/thirdparty/boost/graph/breadth_first_search.hpp new file mode 100644 index 0000000..b9c95c5 --- /dev/null +++ b/thirdparty/boost/graph/breadth_first_search.hpp @@ -0,0 +1,293 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP +#define BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP + +/* + Breadth First Search Algorithm (Cormen, Leiserson, and Rivest p. 470) +*/ +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + struct BFSVisitorConcept { + void constraints() { + function_requires< CopyConstructibleConcept >(); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.tree_edge(e, g); + vis.non_tree_edge(e, g); + vis.gray_target(e, g); + vis.black_target(e, g); + vis.finish_vertex(u, g); + } + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + + template + void breadth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor s, + Buffer& Q, BFSVisitor vis, ColorMap color) + { + function_requires< IncidenceGraphConcept >(); + typedef graph_traits GTraits; + typedef typename GTraits::vertex_descriptor Vertex; + typedef typename GTraits::edge_descriptor Edge; + function_requires< BFSVisitorConcept >(); + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename GTraits::out_edge_iterator ei, ei_end; + + put(color, s, Color::gray()); vis.discover_vertex(s, g); + Q.push(s); + while (! Q.empty()) { + Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g); + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + Vertex v = target(*ei, g); vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { vis.tree_edge(*ei, g); + put(color, v, Color::gray()); vis.discover_vertex(v, g); + Q.push(v); + } else { vis.non_tree_edge(*ei, g); + if (v_color == Color::gray()) vis.gray_target(*ei, g); + else vis.black_target(*ei, g); + } + } // end for + put(color, u, Color::black()); vis.finish_vertex(u, g); + } // end while + } // breadth_first_visit + + + template + void breadth_first_search + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + Buffer& Q, BFSVisitor vis, ColorMap color) + { + // Initialization + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename boost::graph_traits::vertex_iterator i, i_end; + for (tie(i, i_end) = vertices(g); i != i_end; ++i) { + vis.initialize_vertex(*i, g); + put(color, *i, Color::white()); + } + breadth_first_visit(g, s, Q, vis, color); + } + + + template + class bfs_visitor { + public: + bfs_visitor() { } + bfs_visitor(Visitors vis) : m_vis(vis) { } + + template + void initialize_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); + } + template + void discover_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); + } + template + void examine_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex()); + } + template + void examine_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, ::boost::on_examine_edge()); + } + template + void tree_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, ::boost::on_tree_edge()); + } + template + void non_tree_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge()); + } + template + void gray_target(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, ::boost::on_gray_target()); + } + template + void black_target(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, ::boost::on_black_target()); + } + template + void finish_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); + } + + BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs) + BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs) + BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs) + BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs) + BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs) + BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs) + BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs) + BOOST_GRAPH_EVENT_STUB(on_black_target,bfs) + BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs) + + protected: + Visitors m_vis; + }; + template + bfs_visitor + make_bfs_visitor(Visitors vis) { + return bfs_visitor(vis); + } + typedef bfs_visitor<> default_bfs_visitor; + + + namespace detail { + + template + void bfs_helper + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + ColorMap color, + BFSVisitor vis, + const bgl_named_params& params) + { + typedef graph_traits Traits; + // Buffer default + typedef typename Traits::vertex_descriptor Vertex; + typedef boost::queue queue_t; + queue_t Q; + detail::wrap_ref Qref(Q); + breadth_first_search + (g, s, + choose_param(get_param(params, buffer_param_t()), Qref).ref, + vis, color); + } + + //------------------------------------------------------------------------- + // Choose between default color and color parameters. Using + // function dispatching so that we don't require vertex index if + // the color default is not being used. + + template + struct bfs_dispatch { + template + static void apply + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params, + ColorMap color) + { + bfs_helper + (g, s, color, + choose_param(get_param(params, graph_visitor), + make_bfs_visitor(null_visitor())), + params); + } + }; + + template <> + struct bfs_dispatch { + template + static void apply + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params, + detail::error_property_not_found) + { + std::vector color_vec(num_vertices(g)); + default_color_type c = white_color; + null_visitor null_vis; + + bfs_helper + (g, s, + make_iterator_property_map + (color_vec.begin(), + choose_const_pmap(get_param(params, vertex_index), + g, vertex_index), c), + choose_param(get_param(params, graph_visitor), + make_bfs_visitor(null_vis)), + params); + } + }; + + } // namespace detail + + + // Named Parameter Variant + template + void breadth_first_search + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // The graph is passed by *const* reference so that graph adaptors + // (temporaries) can be passed into this function. However, the + // graph is not really const since we may write to property maps + // of the graph. + VertexListGraph& ng = const_cast(g); + typedef typename property_value< bgl_named_params, + vertex_color_t>::type C; + detail::bfs_dispatch::apply(ng, s, params, + get_param(params, vertex_color)); + } + + + // This version does not initialize colors, user has to. + + template + void breadth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // The graph is passed by *const* reference so that graph adaptors + // (temporaries) can be passed into this function. However, the + // graph is not really const since we may write to property maps + // of the graph. + IncidenceGraph& ng = const_cast(g); + + typedef graph_traits Traits; + // Buffer default + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef boost::queue queue_t; + queue_t Q; + detail::wrap_ref Qref(Q); + + breadth_first_visit + (ng, s, + choose_param(get_param(params, buffer_param_t()), Qref).ref, + choose_param(get_param(params, graph_visitor), + make_bfs_visitor(null_visitor())), + choose_pmap(get_param(params, vertex_color), ng, vertex_color) + ); + } + +} // namespace boost + +#endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP + diff --git a/thirdparty/boost/graph/chrobak_payne_drawing.hpp b/thirdparty/boost/graph/chrobak_payne_drawing.hpp new file mode 100644 index 0000000..872b7b8 --- /dev/null +++ b/thirdparty/boost/graph/chrobak_payne_drawing.hpp @@ -0,0 +1,270 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= + +#ifndef __CHROBAK_PAYNE_DRAWING_HPP__ +#define __CHROBAK_PAYNE_DRAWING_HPP__ + +#include +#include +#include +#include //for next and prior +#include +#include + + +namespace boost +{ + + namespace graph { namespace detail + { + + template + void accumulate_offsets(typename graph_traits::vertex_descriptor v, + std::size_t offset, + const Graph& g, + VertexTo1DCoordMap x, + VertexTo1DCoordMap delta_x, + VertexToVertexMap left, + VertexToVertexMap right) + { + if (v != graph_traits::null_vertex()) + { + x[v] += delta_x[v] + offset; + accumulate_offsets(left[v], x[v], g, x, delta_x, left, right); + accumulate_offsets(right[v], x[v], g, x, delta_x, left, right); + } + } + + } /*namespace detail*/ } /*namespace graph*/ + + + + + + template + void chrobak_payne_straight_line_drawing(const Graph& g, + PlanarEmbedding embedding, + ForwardIterator ordering_begin, + ForwardIterator ordering_end, + GridPositionMap drawing, + VertexIndexMap vm + ) + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename PlanarEmbedding::value_type::const_iterator + edge_permutation_iterator_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef std::vector vertex_vector_t; + typedef std::vector vsize_vector_t; + typedef std::vector bool_vector_t; + typedef boost::iterator_property_map + + vertex_to_vertex_map_t; + typedef boost::iterator_property_map + + vertex_to_vsize_map_t; + typedef boost::iterator_property_map + + vertex_to_bool_map_t; + + vertex_vector_t left_vector(num_vertices(g), + graph_traits::null_vertex() + ); + vertex_vector_t right_vector(num_vertices(g), + graph_traits::null_vertex() + ); + vsize_vector_t seen_as_right_vector(num_vertices(g), 0); + vsize_vector_t seen_vector(num_vertices(g), 0); + vsize_vector_t delta_x_vector(num_vertices(g),0); + vsize_vector_t y_vector(num_vertices(g)); + vsize_vector_t x_vector(num_vertices(g),0); + bool_vector_t installed_vector(num_vertices(g),false); + + vertex_to_vertex_map_t left(left_vector.begin(), vm); + vertex_to_vertex_map_t right(right_vector.begin(), vm); + vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm); + vertex_to_vsize_map_t seen(seen_vector.begin(), vm); + vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm); + vertex_to_vsize_map_t y(y_vector.begin(), vm); + vertex_to_vsize_map_t x(x_vector.begin(), vm); + vertex_to_bool_map_t installed(installed_vector.begin(), vm); + + v_size_t timestamp = 1; + vertex_vector_t installed_neighbors; + + ForwardIterator itr = ordering_begin; + vertex_t v1 = *itr; ++itr; + vertex_t v2 = *itr; ++itr; + vertex_t v3 = *itr; ++itr; + + delta_x[v2] = 1; + delta_x[v3] = 1; + + y[v1] = 0; + y[v2] = 0; + y[v3] = 1; + + right[v1] = v3; + right[v3] = v2; + + installed[v1] = installed[v2] = installed[v3] = true; + + for(ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr) + { + vertex_t v = *itr; + + // First, find the leftmost and rightmost neighbor of v on the outer + // cycle of the embedding. + // Note: since we're moving clockwise through the edges adjacent to v, + // we're actually moving from right to left among v's neighbors on the + // outer face (since v will be installed above them all) looking for + // the leftmost and rightmost installed neigbhors + + vertex_t leftmost = graph_traits::null_vertex(); + vertex_t rightmost = graph_traits::null_vertex(); + + installed_neighbors.clear(); + + vertex_t prev_vertex = graph_traits::null_vertex(); + edge_permutation_iterator_t pi, pi_end; + pi_end = embedding[v].end(); + for(pi = embedding[v].begin(); pi != pi_end; ++pi) + { + vertex_t curr_vertex = source(*pi,g) == v ? + target(*pi,g) : source(*pi,g); + + // Skip any self-loops or parallel edges + if (curr_vertex == v || curr_vertex == prev_vertex) + continue; + + if (installed[curr_vertex]) + { + seen[curr_vertex] = timestamp; + + if (right[curr_vertex] != graph_traits::null_vertex()) + { + seen_as_right[right[curr_vertex]] = timestamp; + } + installed_neighbors.push_back(curr_vertex); + } + + prev_vertex = curr_vertex; + } + + typename vertex_vector_t::iterator vi, vi_end; + vi_end = installed_neighbors.end(); + for(vi = installed_neighbors.begin(); vi != vi_end; ++vi) + { + if (right[*vi] == graph_traits::null_vertex() || + seen[right[*vi]] != timestamp + ) + rightmost = *vi; + if (seen_as_right[*vi] != timestamp) + leftmost = *vi; + } + + ++timestamp; + + //stretch gaps + ++delta_x[right[leftmost]]; + ++delta_x[rightmost]; + + //adjust offsets + std::size_t delta_p_q = 0; + vertex_t stopping_vertex = right[rightmost]; + for(vertex_t temp = right[leftmost]; temp != stopping_vertex; + temp = right[temp] + ) + { + delta_p_q += delta_x[temp]; + } + + delta_x[v] = (y[rightmost] - y[leftmost] + delta_p_q)/2; + y[v] = (y[rightmost] + y[leftmost] + delta_p_q)/2; + delta_x[rightmost] = delta_p_q - delta_x[v]; + + bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost; + if (!leftmost_and_rightmost_adjacent) + delta_x[right[leftmost]] -= delta_x[v]; + + //install v + if (!leftmost_and_rightmost_adjacent) + { + left[v] = right[leftmost]; + vertex_t next_to_rightmost; + for(vertex_t temp = leftmost; temp != rightmost; + temp = right[temp] + ) + { + next_to_rightmost = temp; + } + + right[next_to_rightmost] = graph_traits::null_vertex(); + } + else + { + left[v] = graph_traits::null_vertex(); + } + + right[leftmost] = v; + right[v] = rightmost; + installed[v] = true; + + } + + graph::detail::accumulate_offsets + (*ordering_begin,0,g,x,delta_x,left,right); + + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_t v(*vi); + drawing[v].x = x[v]; + drawing[v].y = y[v]; + } + + } + + + + + template + inline void chrobak_payne_straight_line_drawing(const Graph& g, + PlanarEmbedding embedding, + ForwardIterator ord_begin, + ForwardIterator ord_end, + GridPositionMap drawing + ) + { + chrobak_payne_straight_line_drawing(g, + embedding, + ord_begin, + ord_end, + drawing, + get(vertex_index,g) + ); + } + + + + +} // namespace boost + +#endif //__CHROBAK_PAYNE_DRAWING_HPP__ diff --git a/thirdparty/boost/graph/circle_layout.hpp b/thirdparty/boost/graph/circle_layout.hpp new file mode 100644 index 0000000..5b6f05d --- /dev/null +++ b/thirdparty/boost/graph/circle_layout.hpp @@ -0,0 +1,55 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_CIRCLE_LAYOUT_HPP +#define BOOST_GRAPH_CIRCLE_LAYOUT_HPP +#include +#include +#include + +namespace boost { + /** + * \brief Layout the graph with the vertices at the points of a regular + * n-polygon. + * + * The distance from the center of the polygon to each point is + * determined by the @p radius parameter. The @p position parameter + * must be an Lvalue Property Map whose value type is a class type + * containing @c x and @c y members that will be set to the @c x and + * @c y coordinates. + */ + template + void + circle_graph_layout(const VertexListGraph& g, PositionMap position, + Radius radius) + { + const double pi = 3.14159; + +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sin; + using std::cos; +#endif // BOOST_NO_STDC_NAMESPACE + + typedef typename graph_traits::vertices_size_type + vertices_size_type; + + vertices_size_type n = num_vertices(g); + + typedef typename graph_traits::vertex_iterator + vertex_iterator; + + vertices_size_type i = 0; + for(std::pair v = vertices(g); + v.first != v.second; ++v.first, ++i) { + position[*v.first].x = radius * cos(i * 2 * pi / n); + position[*v.first].y = radius * sin(i * 2 * pi / n); + } + } +} // end namespace boost + +#endif // BOOST_GRAPH_CIRCLE_LAYOUT_HPP diff --git a/thirdparty/boost/graph/compressed_sparse_row_graph.hpp b/thirdparty/boost/graph/compressed_sparse_row_graph.hpp new file mode 100644 index 0000000..df809dd --- /dev/null +++ b/thirdparty/boost/graph/compressed_sparse_row_graph.hpp @@ -0,0 +1,801 @@ +// Copyright 2005-2006 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine + +// Compressed sparse row graph type + +#ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP +#define BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_GRAPH_NO_BUNDLED_PROPERTIES +# error The Compressed Sparse Row graph only supports bundled properties. +# error You will need a compiler that conforms better to the C++ standard. +#endif + +namespace boost { + +// A tag type indicating that the graph in question is a compressed +// sparse row graph. This is an internal detail of the BGL. +struct csr_graph_tag; + +/**************************************************************************** + * Local helper macros to reduce typing and clutter later on. * + ****************************************************************************/ +#define BOOST_CSR_GRAPH_TEMPLATE_PARMS \ + typename Directed, typename VertexProperty, typename EdgeProperty, \ + typename GraphProperty, typename Vertex, typename EdgeIndex +#define BOOST_CSR_GRAPH_TYPE \ + compressed_sparse_row_graph + +// Forward declaration of CSR edge descriptor type, needed to pass to +// indexed_edge_properties. +template +class csr_edge_descriptor; + +/** Compressed sparse row graph. + * + * Vertex and EdgeIndex should be unsigned integral types and should + * specialize numeric_limits. + */ +template +class compressed_sparse_row_graph + : public detail::indexed_vertex_properties, + public detail::indexed_edge_properties > + +{ + typedef detail::indexed_vertex_properties + inherited_vertex_properties; + + typedef detail::indexed_edge_properties > + inherited_edge_properties; + + public: + // For Property Graph + typedef GraphProperty graph_property_type; + + protected: + template + void + maybe_reserve_edge_list_storage(InputIterator, InputIterator, + std::input_iterator_tag) + { + // Do nothing: we have no idea how much storage to reserve. + } + + template + void + maybe_reserve_edge_list_storage(InputIterator first, InputIterator last, + std::forward_iterator_tag) + { + using std::distance; + typename std::iterator_traits::difference_type n = + distance(first, last); + m_column.reserve(n); + inherited_edge_properties::reserve(n); + } + + public: + /* At this time, the compressed sparse row graph can only be used to + * create a directed graph. In the future, bidirectional and + * undirected CSR graphs will also be supported. + */ + BOOST_STATIC_ASSERT((is_same::value)); + + // Concept requirements: + // For Graph + typedef Vertex vertex_descriptor; + typedef csr_edge_descriptor edge_descriptor; + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; + + class traversal_category: public incidence_graph_tag, + public adjacency_graph_tag, + public vertex_list_graph_tag, + public edge_list_graph_tag {}; + + static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } + + // For VertexListGraph + typedef counting_iterator vertex_iterator; + typedef Vertex vertices_size_type; + + // For EdgeListGraph + typedef EdgeIndex edges_size_type; + + // For IncidenceGraph + class out_edge_iterator; + typedef EdgeIndex degree_size_type; + + // For AdjacencyGraph + typedef typename std::vector::const_iterator adjacency_iterator; + + // For EdgeListGraph + class edge_iterator; + + // For BidirectionalGraph (not implemented) + typedef void in_edge_iterator; + + // For internal use + typedef csr_graph_tag graph_tag; + + // Constructors + + // Default constructor: an empty graph. + compressed_sparse_row_graph() + : m_rowstart(1, EdgeIndex(0)), m_column(0), m_property(), + m_last_source(0) {} + + // From number of vertices and sorted list of edges + template + compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, + vertices_size_type numverts, + edges_size_type numedges = 0, + const GraphProperty& prop = GraphProperty()) + : inherited_vertex_properties(numverts), m_rowstart(numverts + 1), + m_column(0), m_property(prop), m_last_source(numverts) + { + // Reserving storage in advance can save us lots of time and + // memory, but it can only be done if we have forward iterators or + // the user has supplied the number of edges. + if (numedges == 0) { + typedef typename std::iterator_traits::iterator_category + category; + maybe_reserve_edge_list_storage(edge_begin, edge_end, category()); + } else { + m_column.reserve(numedges); + } + + EdgeIndex current_edge = 0; + Vertex current_vertex_plus_one = 1; + m_rowstart[0] = 0; + for (InputIterator ei = edge_begin; ei != edge_end; ++ei) { + Vertex src = ei->first; + Vertex tgt = ei->second; + for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + m_column.push_back(tgt); + ++current_edge; + } + + // The remaining vertices have no edges + for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + + // Default-construct properties for edges + inherited_edge_properties::resize(m_column.size()); + } + + // From number of vertices and sorted list of edges + template + compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, + EdgePropertyIterator ep_iter, + vertices_size_type numverts, + edges_size_type numedges = 0, + const GraphProperty& prop = GraphProperty()) + : inherited_vertex_properties(numverts), m_rowstart(numverts + 1), + m_column(0), m_property(prop), m_last_source(numverts) + { + // Reserving storage in advance can save us lots of time and + // memory, but it can only be done if we have forward iterators or + // the user has supplied the number of edges. + if (numedges == 0) { + typedef typename std::iterator_traits::iterator_category + category; + maybe_reserve_edge_list_storage(edge_begin, edge_end, category()); + } else { + m_column.reserve(numedges); + } + + EdgeIndex current_edge = 0; + Vertex current_vertex_plus_one = 1; + m_rowstart[0] = 0; + for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) { + Vertex src = ei->first; + Vertex tgt = ei->second; + for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + m_column.push_back(tgt); + inherited_edge_properties::push_back(*ep_iter); + ++current_edge; + } + + // The remaining vertices have no edges + for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + } + + // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function + template + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, + edges_size_type numedges) + : m_property(), m_last_source(0) + { + assign(g, vi, numverts, numedges); + } + + // Requires VertexListGraph and EdgeListGraph + template + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) + : m_property(), m_last_source(0) + { + assign(g, vi, num_vertices(g), num_edges(g)); + } + + // Requires vertex index map plus requirements of previous constructor + template + explicit compressed_sparse_row_graph(const Graph& g) + : m_property(), m_last_source(0) + { + assign(g, get(vertex_index, g), num_vertices(g), num_edges(g)); + } + + // From any graph (slow and uses a lot of memory) + // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function + // Internal helper function + template + void + assign(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) + { + inherited_vertex_properties::resize(numverts); + m_rowstart.resize(numverts + 1); + m_column.resize(numedges); + EdgeIndex current_edge = 0; + typedef typename boost::graph_traits::vertex_descriptor g_vertex; + typedef typename boost::graph_traits::edge_descriptor g_edge; + typedef typename boost::graph_traits::out_edge_iterator + g_out_edge_iter; + + for (Vertex i = 0; i != numverts; ++i) { + m_rowstart[i] = current_edge; + g_vertex v = vertex(i, g); + EdgeIndex num_edges_before_this_vertex = current_edge; + g_out_edge_iter ei, ei_end; + for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { + m_column[current_edge++] = get(vi, target(*ei, g)); + } + std::sort(m_column.begin() + num_edges_before_this_vertex, + m_column.begin() + current_edge); + } + m_rowstart[numverts] = current_edge; + m_last_source = numverts; + } + + // Requires the above, plus VertexListGraph and EdgeListGraph + template + void assign(const Graph& g, const VertexIndexMap& vi) + { + assign(g, vi, num_vertices(g), num_edges(g)); + } + + // Requires the above, plus a vertex_index map. + template + void assign(const Graph& g) + { + assign(g, get(vertex_index, g), num_vertices(g), num_edges(g)); + } + + using inherited_vertex_properties::operator[]; + using inherited_edge_properties::operator[]; + + // private: non-portable, requires friend templates + inherited_vertex_properties& vertex_properties() {return *this;} + const inherited_vertex_properties& vertex_properties() const {return *this;} + inherited_edge_properties& edge_properties() { return *this; } + const inherited_edge_properties& edge_properties() const { return *this; } + + std::vector m_rowstart; + std::vector m_column; + GraphProperty m_property; + Vertex m_last_source; // Last source of added edge, plus one +}; + +template +class csr_edge_descriptor +{ + public: + Vertex src; + EdgeIndex idx; + + csr_edge_descriptor(Vertex src, EdgeIndex idx): src(src), idx(idx) {} + csr_edge_descriptor(): src(0), idx(0) {} + + bool operator==(const csr_edge_descriptor& e) const {return idx == e.idx;} + bool operator!=(const csr_edge_descriptor& e) const {return idx != e.idx;} + bool operator<(const csr_edge_descriptor& e) const {return idx < e.idx;} + bool operator>(const csr_edge_descriptor& e) const {return idx > e.idx;} + bool operator<=(const csr_edge_descriptor& e) const {return idx <= e.idx;} + bool operator>=(const csr_edge_descriptor& e) const {return idx >= e.idx;} +}; + +// Construction functions +template +inline Vertex +add_vertex(BOOST_CSR_GRAPH_TYPE& g) { + Vertex old_num_verts_plus_one = g.m_rowstart.size(); + g.m_rowstart.push_back(EdgeIndex(0)); + g.vertex_properties().resize(num_vertices(g)); + return old_num_verts_plus_one - 1; +} + +template +inline Vertex +add_vertices(typename BOOST_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_CSR_GRAPH_TYPE& g) { + Vertex old_num_verts_plus_one = g.m_rowstart.size(); + g.m_rowstart.resize(old_num_verts_plus_one + count, EdgeIndex(0)); + g.vertex_properties().resize(num_vertices(g)); + return old_num_verts_plus_one - 1; +} + +// This function requires that (src, tgt) be lexicographically at least as +// large as the largest edge in the graph so far +template +inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor +add_edge(Vertex src, Vertex tgt, BOOST_CSR_GRAPH_TYPE& g) { + assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) && + src < num_vertices(g)); + EdgeIndex num_edges_orig = g.m_column.size(); + for (; g.m_last_source <= src; ++g.m_last_source) + g.m_rowstart[g.m_last_source] = num_edges_orig; + g.m_rowstart[src + 1] = num_edges_orig + 1; + g.m_column.push_back(tgt); + typedef typename BOOST_CSR_GRAPH_TYPE::edge_push_back_type push_back_type; + g.edge_properties().push_back(push_back_type()); + return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig); +} + +// This function requires that (src, tgt) be lexicographically at least as +// large as the largest edge in the graph so far +template +inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor +add_edge(Vertex src, Vertex tgt, + typename BOOST_CSR_GRAPH_TYPE::edge_bundled const& p, + BOOST_CSR_GRAPH_TYPE& g) { + assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) && + src < num_vertices(g)); + EdgeIndex num_edges_orig = g.m_column.size(); + for (; g.m_last_source <= src; ++g.m_last_source) + g.m_rowstart[g.m_last_source] = num_edges_orig; + g.m_rowstart[src + 1] = num_edges_orig + 1; + g.m_column.push_back(tgt); + g.edge_properties().push_back(p); + return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig); +} + + +// From VertexListGraph +template +inline Vertex +num_vertices(const BOOST_CSR_GRAPH_TYPE& g) { + return g.m_rowstart.size() - 1; +} + +template +std::pair, counting_iterator > +inline vertices(const BOOST_CSR_GRAPH_TYPE& g) { + return std::make_pair(counting_iterator(0), + counting_iterator(num_vertices(g))); +} + +// From IncidenceGraph +template +class BOOST_CSR_GRAPH_TYPE::out_edge_iterator + : public iterator_facade::fast> +{ + public: + typedef typename int_t::fast difference_type; + + out_edge_iterator() {} + // Implicit copy constructor OK + explicit out_edge_iterator(edge_descriptor edge) : m_edge(edge) { } + + private: + // iterator_facade requirements + const edge_descriptor& dereference() const { return m_edge; } + + bool equal(const out_edge_iterator& other) const + { return m_edge == other.m_edge; } + + void increment() { ++m_edge.idx; } + void decrement() { ++m_edge.idx; } + void advance(difference_type n) { m_edge.idx += n; } + + difference_type distance_to(const out_edge_iterator& other) const + { return other.m_edge.idx - m_edge.idx; } + + edge_descriptor m_edge; + + friend class iterator_core_access; +}; + +template +inline Vertex +source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, + const BOOST_CSR_GRAPH_TYPE&) +{ + return e.src; +} + +template +inline Vertex +target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, + const BOOST_CSR_GRAPH_TYPE& g) +{ + return g.m_column[e.idx]; +} + +template +inline std::pair +out_edges(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed; + typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it; + EdgeIndex v_row_start = g.m_rowstart[v]; + EdgeIndex next_row_start = g.m_rowstart[v + 1]; + return std::make_pair(it(ed(v, v_row_start)), + it(ed(v, (std::max)(v_row_start, next_row_start)))); +} + +template +inline EdgeIndex +out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) +{ + EdgeIndex v_row_start = g.m_rowstart[v]; + EdgeIndex next_row_start = g.m_rowstart[v + 1]; + return (std::max)(v_row_start, next_row_start) - v_row_start; +} + +// From AdjacencyGraph +template +inline std::pair +adjacent_vertices(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) +{ + EdgeIndex v_row_start = g.m_rowstart[v]; + EdgeIndex next_row_start = g.m_rowstart[v + 1]; + return std::make_pair(g.m_column.begin() + v_row_start, + g.m_column.begin() + + (std::max)(v_row_start, next_row_start)); +} + +// Extra, common functions +template +inline typename graph_traits::vertex_descriptor +vertex(typename graph_traits::vertex_descriptor i, + const BOOST_CSR_GRAPH_TYPE&) +{ + return i; +} + +// Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i)) +// time +template +inline std::pair +edge_range(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename std::vector::const_iterator adj_iter; + typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; + typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edge_desc; + std::pair raw_adjacencies = adjacent_vertices(i, g); + std::pair adjacencies = + std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j); + EdgeIndex idx_begin = adjacencies.first - g.m_column.begin(); + EdgeIndex idx_end = adjacencies.second - g.m_column.begin(); + return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)), + out_edge_iter(edge_desc(i, idx_end))); +} + +template +inline std::pair +edge(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; + std::pair range = edge_range(i, j, g); + if (range.first == range.second) + return std::make_pair(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(), + false); + else + return std::make_pair(*range.first, true); +} + +// Find an edge given its index in the graph +template +inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor +edge_from_index(EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename std::vector::const_iterator row_start_iter; + assert (idx < num_edges(g)); + row_start_iter src_plus_1 = + std::upper_bound(g.m_rowstart.begin(), + g.m_rowstart.begin() + g.m_last_source + 1, + idx); + // Get last source whose rowstart is at most idx + // upper_bound returns this position plus 1 + Vertex src = (src_plus_1 - g.m_rowstart.begin()) - 1; + return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx); +} + +// From EdgeListGraph +template +class BOOST_CSR_GRAPH_TYPE::edge_iterator +{ + public: + typedef std::forward_iterator_tag iterator_category; + typedef edge_descriptor value_type; + + typedef const edge_descriptor* pointer; + + typedef edge_descriptor reference; + typedef typename int_t::fast difference_type; + + edge_iterator() : rowstart_array(0), current_edge(), end_of_this_vertex(0) {} + + edge_iterator(const compressed_sparse_row_graph& graph, + edge_descriptor current_edge, + EdgeIndex end_of_this_vertex) + : rowstart_array(&graph.m_rowstart[0]), current_edge(current_edge), + end_of_this_vertex(end_of_this_vertex) {} + + // From InputIterator + reference operator*() const { return current_edge; } + pointer operator->() const { return ¤t_edge; } + + bool operator==(const edge_iterator& o) const { + return current_edge == o.current_edge; + } + bool operator!=(const edge_iterator& o) const { + return current_edge != o.current_edge; + } + + edge_iterator& operator++() { + ++current_edge.idx; + while (current_edge.idx == end_of_this_vertex) { + ++current_edge.src; + end_of_this_vertex = rowstart_array[current_edge.src + 1]; + } + return *this; + } + + edge_iterator operator++(int) { + edge_iterator temp = *this; + ++*this; + return temp; + } + + private: + const EdgeIndex* rowstart_array; + edge_descriptor current_edge; + EdgeIndex end_of_this_vertex; +}; + +template +inline EdgeIndex +num_edges(const BOOST_CSR_GRAPH_TYPE& g) +{ + return g.m_column.size(); +} + +template +std::pair +edges(const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei; + typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc; + if (g.m_rowstart.size() == 1 || g.m_column.empty()) { + return std::make_pair(ei(), ei()); + } else { + // Find the first vertex that has outgoing edges + Vertex src = 0; + while (g.m_rowstart[src + 1] == 0) ++src; + return std::make_pair(ei(g, edgedesc(src, 0), g.m_rowstart[src + 1]), + ei(g, edgedesc(num_vertices(g), g.m_column.size()), 0)); + } +} + +// For Property Graph + +// Graph properties +template +inline void +set_property(BOOST_CSR_GRAPH_TYPE& g, Tag, const Value& value) +{ + get_property_value(g.m_property, Tag()) = value; +} + +template +inline +typename graph_property::type& +get_property(BOOST_CSR_GRAPH_TYPE& g, Tag) +{ + return get_property_value(g.m_property, Tag()); +} + +template +inline +const +typename graph_property::type& +get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag) +{ + return get_property_value(g.m_property, Tag()); +} + +// Add edge_index property map +template +struct csr_edge_index_map +{ + typedef Index value_type; + typedef Index reference; + typedef Descriptor key_type; + typedef readable_property_map_tag category; +}; + +template +inline Index +get(const csr_edge_index_map&, + const typename csr_edge_index_map::key_type& key) +{ + return key.idx; +} + +// Doing the right thing here (by unifying with vertex_index_t and +// edge_index_t) breaks GCC. +template +struct property_map +{ +private: + typedef identity_property_map vertex_index_type; + typedef typename graph_traits::edge_descriptor + edge_descriptor; + typedef csr_edge_index_map edge_index_type; + + typedef typename mpl::if_, + edge_index_type, + detail::error_property_not_found>::type + edge_or_none; + +public: + typedef typename mpl::if_, + vertex_index_type, + edge_or_none>::type type; + + typedef type const_type; +}; + +template +inline identity_property_map +get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&) +{ + return identity_property_map(); +} + +template +inline Vertex +get(vertex_index_t, + const BOOST_CSR_GRAPH_TYPE&, Vertex v) +{ + return v; +} + +template +inline typename property_map::const_type +get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&) +{ + typedef typename property_map::const_type + result_type; + return result_type(); +} + +template +inline EdgeIndex +get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, + typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e) +{ + return e.idx; +} + +// Support for bundled properties +template +struct property_map +{ +private: + typedef graph_traits traits; + typedef VertexProperty vertex_bundled; + typedef EdgeProperty edge_bundled; + typedef typename mpl::if_c<(detail::is_vertex_bundle::value), + typename traits::vertex_descriptor, + typename traits::edge_descriptor>::type + descriptor; + +public: + typedef bundle_property_map + type; + typedef bundle_property_map const_type; +}; + +template +inline +typename property_map::type +get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename property_map::type + result_type; + return result_type(&g, p); +} + +template +inline +typename property_map::const_type +get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g) +{ + typedef typename property_map::const_type + result_type; + return result_type(&g, p); +} + +template +inline T +get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g, + const Key& key) +{ + return get(get(p, g), key); +} + +template +inline void +put(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g, + const Key& key, const T& value) +{ + put(get(p, g), key, value); +} + +#undef BOOST_CSR_GRAPH_TYPE +#undef BOOST_CSR_GRAPH_TEMPLATE_PARMS + +} // end namespace boost + +#endif // BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP diff --git a/thirdparty/boost/graph/connected_components.hpp b/thirdparty/boost/graph/connected_components.hpp new file mode 100644 index 0000000..c4395a1 --- /dev/null +++ b/thirdparty/boost/graph/connected_components.hpp @@ -0,0 +1,101 @@ +// +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_CONNECTED_COMPONENTS_HPP +#define BOOST_GRAPH_CONNECTED_COMPONENTS_HPP + +#include +#include +#include +#include + +#include + +namespace boost { + + namespace detail { + + // This visitor is used both in the connected_components algorithm + // and in the kosaraju strong components algorithm during the + // second DFS traversal. + template + class components_recorder : public dfs_visitor<> + { + typedef typename property_traits::value_type comp_type; + public: + components_recorder(ComponentsMap c, + comp_type& c_count) + : m_component(c), m_count(c_count) {} + + template + void start_vertex(Vertex, Graph&) { + if (m_count == (std::numeric_limits::max)()) + m_count = 0; // start counting components at zero + else + ++m_count; + } + template + void discover_vertex(Vertex u, Graph&) { + put(m_component, u, m_count); + } + protected: + ComponentsMap m_component; + comp_type& m_count; + }; + + } // namespace detail + + // This function computes the connected components of an undirected + // graph using a single application of depth first search. + + template + inline typename property_traits::value_type + connected_components(const Graph& g, ComponentMap c, + const bgl_named_params& params) + { + if (num_vertices(g) == 0) return 0; + + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< WritablePropertyMapConcept >(); + typedef typename boost::graph_traits::directed_category directed; + BOOST_STATIC_ASSERT((boost::is_same::value)); + + typedef typename property_traits::value_type comp_type; + // c_count initialized to "nil" (with nil represented by (max)()) + comp_type c_count((std::numeric_limits::max)()); + detail::components_recorder vis(c, c_count); + depth_first_search(g, params.visitor(vis)); + return c_count + 1; + } + + template + inline typename property_traits::value_type + connected_components(const Graph& g, ComponentMap c) + { + if (num_vertices(g) == 0) return 0; + + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< WritablePropertyMapConcept >(); + typedef typename boost::graph_traits::directed_category directed; + BOOST_STATIC_ASSERT((boost::is_same::value)); + + typedef typename property_traits::value_type comp_type; + // c_count initialized to "nil" (with nil represented by (max)()) + comp_type c_count((std::numeric_limits::max)()); + detail::components_recorder vis(c, c_count); + depth_first_search(g, visitor(vis)); + return c_count + 1; + } + + +} // namespace boost + + +#endif // BOOST_GRAPH_CONNECTED_COMPONENTS_HPP diff --git a/thirdparty/boost/graph/copy.hpp b/thirdparty/boost/graph/copy.hpp new file mode 100644 index 0000000..11b65b5 --- /dev/null +++ b/thirdparty/boost/graph/copy.hpp @@ -0,0 +1,450 @@ +// +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Jeremy G. Siek, Lie-Quan Lee, Andrew Lumsdaine +// +// Distributed under the 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 implements the following functions: + + + template + void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out) + + template + void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, + const bgl_named_params& params) + + + template + typename graph_traits::vertex_descriptor + copy_component(IncidenceGraph& g_in, + typename graph_traits::vertex_descriptor src, + MutableGraph& g_out) + + template + typename graph_traits::vertex_descriptor + copy_component(IncidenceGraph& g_in, + typename graph_traits::vertex_descriptor src, + MutableGraph& g_out, + const bgl_named_params& params) + */ + + +#ifndef BOOST_GRAPH_COPY_HPP +#define BOOST_GRAPH_COPY_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + namespace detail { + + // Default edge and vertex property copiers + + template + struct edge_copier { + edge_copier(const Graph1& g1, Graph2& g2) + : edge_all_map1(get(edge_all, g1)), + edge_all_map2(get(edge_all, g2)) { } + + template + void operator()(const Edge1& e1, Edge2& e2) const { + put(edge_all_map2, e2, get(edge_all_map1, e1)); + } + typename property_map::const_type edge_all_map1; + mutable typename property_map::type edge_all_map2; + }; + template + inline edge_copier + make_edge_copier(const Graph1& g1, Graph2& g2) + { + return edge_copier(g1, g2); + } + + template + struct vertex_copier { + vertex_copier(const Graph1& g1, Graph2& g2) + : vertex_all_map1(get(vertex_all, g1)), + vertex_all_map2(get(vertex_all, g2)) { } + + template + void operator()(const Vertex1& v1, Vertex2& v2) const { + put(vertex_all_map2, v2, get(vertex_all_map1, v1)); + } + typename property_map::const_type vertex_all_map1; + mutable typename property_map::type + vertex_all_map2; + }; + template + inline vertex_copier + make_vertex_copier(const Graph1& g1, Graph2& g2) + { + return vertex_copier(g1, g2); + } + + // Copy all the vertices and edges of graph g_in into graph g_out. + // The copy_vertex and copy_edge function objects control how vertex + // and edge properties are copied. + + template + struct copy_graph_impl { }; + + template <> struct copy_graph_impl<0> + { + template + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, IndexMap) + { + typename graph_traits::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { + typename graph_traits::vertex_descriptor + new_v = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + typename graph_traits::edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) { + typename graph_traits::edge_descriptor new_e; + bool inserted; + tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)), + get(orig2copy, target(*ei, g_in)), + g_out); + copy_edge(*ei, new_e); + } + } + }; + + // for directed graphs + template <> struct copy_graph_impl<1> + { + template + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, IndexMap) + { + typename graph_traits::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { + typename graph_traits::vertex_descriptor + new_v = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { + typename graph_traits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) { + typename graph_traits::edge_descriptor new_e; + bool inserted; + tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)), + get(orig2copy, target(*ei, g_in)), + g_out); + copy_edge(*ei, new_e); + } + } + } + }; + + // for undirected graphs + template <> struct copy_graph_impl<2> + { + template + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, + IndexMap index_map) + { + typedef color_traits Color; + std::vector + color(num_vertices(g_in), Color::white()); + typename graph_traits::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { + typename graph_traits::vertex_descriptor + new_v = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { + typename graph_traits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) { + typename graph_traits::edge_descriptor new_e; + bool inserted; + if (color[get(index_map, target(*ei, g_in))] == Color::white()) { + tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei,g_in)), + get(orig2copy, target(*ei,g_in)), + g_out); + copy_edge(*ei, new_e); + } + } + color[get(index_map, *vi)] = Color::black(); + } + } + }; + + template + struct choose_graph_copy { + typedef typename Graph::traversal_category Trv; + typedef typename Graph::directed_category Dr; + enum { algo = + (is_convertible::value + && is_convertible::value) + ? 0 : is_convertible::value ? 1 : 2 }; + typedef copy_graph_impl type; + }; + + //------------------------------------------------------------------------- + struct choose_copier_parameter { + template + struct bind_ { + typedef const P& result_type; + static result_type apply(const P& p, const G1&, G2&) + { return p; } + }; + }; + struct choose_default_edge_copier { + template + struct bind_ { + typedef edge_copier result_type; + static result_type apply(const P&, const G1& g1, G2& g2) { + return result_type(g1, g2); + } + }; + }; + template + struct choose_edge_copy { + typedef choose_copier_parameter type; + }; + template <> + struct choose_edge_copy { + typedef choose_default_edge_copier type; + }; + template + struct choose_edge_copier_helper { + typedef typename choose_edge_copy::type Selector; + typedef typename Selector:: template bind_ Bind; + typedef Bind type; + typedef typename Bind::result_type result_type; + }; + template + typename detail::choose_edge_copier_helper::result_type + choose_edge_copier(const Param& params, const G1& g_in, G2& g_out) + { + typedef typename + detail::choose_edge_copier_helper::type Choice; + return Choice::apply(params, g_in, g_out); + } + + + struct choose_default_vertex_copier { + template + struct bind_ { + typedef vertex_copier result_type; + static result_type apply(const P&, const G1& g1, G2& g2) { + return result_type(g1, g2); + } + }; + }; + template + struct choose_vertex_copy { + typedef choose_copier_parameter type; + }; + template <> + struct choose_vertex_copy { + typedef choose_default_vertex_copier type; + }; + template + struct choose_vertex_copier_helper { + typedef typename choose_vertex_copy::type Selector; + typedef typename Selector:: template bind_ Bind; + typedef Bind type; + typedef typename Bind::result_type result_type; + }; + template + typename detail::choose_vertex_copier_helper::result_type + choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out) + { + typedef typename + detail::choose_vertex_copier_helper::type Choice; + return Choice::apply(params, g_in, g_out); + } + + } // namespace detail + + + template + void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out) + { + if (num_vertices(g_in) == 0) + return; + typedef typename graph_traits::vertex_descriptor vertex_t; + std::vector orig2copy(num_vertices(g_in)); + typedef typename detail::choose_graph_copy::type + copy_impl; + copy_impl::apply + (g_in, g_out, + detail::make_vertex_copier(g_in, g_out), + detail::make_edge_copier(g_in, g_out), + make_iterator_property_map(orig2copy.begin(), + get(vertex_index, g_in), orig2copy[0]), + get(vertex_index, g_in) + ); + } + + template + void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, + const bgl_named_params& params) + { + typename std::vector::size_type n; + n = is_default_param(get_param(params, orig_to_copy_t())) + ? num_vertices(g_in) : 1; + if (n == 0) + return; + std::vector::vertex_descriptor> + orig2copy(n); + + typedef typename detail::choose_graph_copy::type + copy_impl; + copy_impl::apply + (g_in, g_out, + detail::choose_vertex_copier(get_param(params, vertex_copy_t()), + g_in, g_out), + detail::choose_edge_copier(get_param(params, edge_copy_t()), + g_in, g_out), + choose_param(get_param(params, orig_to_copy_t()), + make_iterator_property_map + (orig2copy.begin(), + choose_const_pmap(get_param(params, vertex_index), + g_in, vertex_index), orig2copy[0])), + choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index) + ); + } + + namespace detail { + + template + struct graph_copy_visitor : public bfs_visitor<> + { + graph_copy_visitor(NewGraph& graph, Copy2OrigIndexMap c, + CopyVertex cv, CopyEdge ce) + : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { } + + template + void examine_vertex(Vertex u, const Graph& g_in) const { + typename graph_traits::vertex_descriptor + new_u = add_vertex(g_out); + put(orig2copy, u, new_u); + copy_vertex(u, new_u); + } + + template + void examine_edge(Edge e, const Graph& g_in) const { + typename graph_traits::edge_descriptor new_e; + bool inserted; + tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)), + get(orig2copy, target(e, g_in)), + g_out); + copy_edge(e, new_e); + } + private: + NewGraph& g_out; + Copy2OrigIndexMap orig2copy; + CopyVertex copy_vertex; + CopyEdge copy_edge; + }; + + template + typename graph_traits::vertex_descriptor + copy_component_impl + (const Graph& g_in, + typename graph_traits::vertex_descriptor src, + MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, + const Params& params) + { + graph_copy_visitor vis(g_out, orig2copy, copy_vertex, copy_edge); + breadth_first_search(g_in, src, params.visitor(vis)); + return get(orig2copy, src); + } + + } // namespace detail + + + // Copy all the vertices and edges of graph g_in that are reachable + // from the source vertex into graph g_out. Return the vertex + // in g_out that matches the source vertex of g_in. + template + typename graph_traits::vertex_descriptor + copy_component(IncidenceGraph& g_in, + typename graph_traits::vertex_descriptor src, + MutableGraph& g_out, + const bgl_named_params& params) + { + typename std::vector::size_type n; + n = is_default_param(get_param(params, orig_to_copy_t())) + ? num_vertices(g_in) : 1; + std::vector::vertex_descriptor> + orig2copy(n); + + return detail::copy_component_impl + (g_in, src, g_out, + detail::choose_vertex_copier(get_param(params, vertex_copy_t()), + g_in, g_out), + detail::choose_edge_copier(get_param(params, edge_copy_t()), + g_in, g_out), + choose_param(get_param(params, orig_to_copy_t()), + make_iterator_property_map + (orig2copy.begin(), + choose_pmap(get_param(params, vertex_index), + g_in, vertex_index), orig2copy[0])), + params + ); + } + + template + typename graph_traits::vertex_descriptor + copy_component(IncidenceGraph& g_in, + typename graph_traits::vertex_descriptor src, + MutableGraph& g_out) + { + std::vector::vertex_descriptor> + orig2copy(num_vertices(g_in)); + + return detail::copy_component_impl + (g_in, src, g_out, + make_vertex_copier(g_in, g_out), + make_edge_copier(g_in, g_out), + make_iterator_property_map(orig2copy.begin(), + get(vertex_index, g_in), orig2copy[0]), + bgl_named_params('x') // dummy param object + ); + } + +} // namespace boost + +#endif // BOOST_GRAPH_COPY_HPP diff --git a/thirdparty/boost/graph/create_condensation_graph.hpp b/thirdparty/boost/graph/create_condensation_graph.hpp new file mode 100644 index 0000000..92ab0c3 --- /dev/null +++ b/thirdparty/boost/graph/create_condensation_graph.hpp @@ -0,0 +1,83 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_CREATE_CONDENSATION_GRAPH_HPP +#define BOOST_CREATE_CONDENSATION_GRAPH_HPP + +#include +#include + +namespace boost { + + template + void create_condensation_graph(const Graph& g, + const ComponentLists& components, + ComponentNumberMap component_number, + CondensationGraph& cg, + EdgeMultiplicityMap edge_mult_map) + { + typedef typename graph_traits::vertex_descriptor vertex; + typedef typename graph_traits::vertices_size_type size_type; + typedef typename graph_traits::vertex_descriptor + cg_vertex; + std::vector to_cg_vertex(components.size()); + for (size_type s = 0; s < components.size(); ++s) + to_cg_vertex[s] = add_vertex(cg); + + for (size_type si = 0; si < components.size(); ++si) { + cg_vertex s = to_cg_vertex[si]; + std::vector adj; + for (size_type i = 0; i < components[si].size(); ++i) { + vertex u = components[s][i]; + typename graph_traits::adjacency_iterator v, v_end; + for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { + cg_vertex t = to_cg_vertex[component_number[*v]]; + if (s != t) // Avoid loops in the condensation graph + adj.push_back(t); + } + } + std::sort(adj.begin(), adj.end()); + if (! adj.empty()) { + size_type i = 0; + cg_vertex t = adj[i]; + typename graph_traits::edge_descriptor e; + bool inserted; + tie(e, inserted) = add_edge(s, t, cg); + put(edge_mult_map, e, 1); + ++i; + while (i < adj.size()) { + if (adj[i] == t) + put(edge_mult_map, e, get(edge_mult_map, e) + 1); + else { + t = adj[i]; + tie(e, inserted) = add_edge(s, t, cg); + put(edge_mult_map, e, 1); + } + ++i; + } + } + } + } + + template + void create_condensation_graph(const Graph& g, + const ComponentLists& components, + ComponentNumberMap component_number, + CondensationGraph& cg) + { + create_condensation_graph(g, components, component_number, cg, + dummy_property_map()); + } + +} // namespace boost + +#endif // BOOST_CREATE_CONDENSATION_GRAPH_HPP diff --git a/thirdparty/boost/graph/cuthill_mckee_ordering.hpp b/thirdparty/boost/graph/cuthill_mckee_ordering.hpp new file mode 100644 index 0000000..efb9cf0 --- /dev/null +++ b/thirdparty/boost/graph/cuthill_mckee_ordering.hpp @@ -0,0 +1,190 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2004, 2005 Trustees of Indiana University +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, +// Doug Gregor, D. Kevin McGrath +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_CUTHILL_MCKEE_HPP +#define BOOST_GRAPH_CUTHILL_MCKEE_HPP + +#include +#include +#include + + +/* + (Reverse) Cuthill-McKee Algorithm for matrix reordering +*/ + +namespace boost { + + namespace detail { + + + + template < typename OutputIterator, typename Buffer, typename DegreeMap > + class bfs_rcm_visitor:public default_bfs_visitor + { + public: + bfs_rcm_visitor(OutputIterator *iter, Buffer *b, DegreeMap deg): + permutation(iter), Qptr(b), degree(deg) { } + template + void examine_vertex(Vertex u, Graph&) { + *(*permutation)++ = u; + index_begin = Qptr->size(); + } + template + void finish_vertex(Vertex, Graph&) { + using std::sort; + + typedef typename property_traits::value_type ds_type; + + typedef indirect_cmp > Compare; + Compare comp(degree); + + sort(Qptr->begin()+index_begin, Qptr->end(), comp); + } + protected: + OutputIterator *permutation; + int index_begin; + Buffer *Qptr; + DegreeMap degree; + }; + + } // namespace detail + + + // Reverse Cuthill-McKee algorithm with a given starting Vertex. + // + // If user provides a reverse iterator, this will be a reverse-cuthill-mckee + // algorithm, otherwise it will be a standard CM algorithm + + template + OutputIterator + cuthill_mckee_ordering(const Graph& g, + std::deque< typename + graph_traits::vertex_descriptor > vertex_queue, + OutputIterator permutation, + ColorMap color, DegreeMap degree) + { + + //create queue, visitor...don't forget namespaces! + typedef typename property_traits::value_type ds_type; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename boost::sparse::sparse_ordering_queue queue; + typedef typename detail::bfs_rcm_visitor Visitor; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + + queue Q; + + //create a bfs_rcm_visitor as defined above + Visitor vis(&permutation, &Q, degree); + + typename graph_traits::vertex_iterator ui, ui_end; + + // Copy degree to pseudo_degree + // initialize the color map + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){ + put(color, *ui, Color::white()); + } + + + while( !vertex_queue.empty() ) { + Vertex s = vertex_queue.front(); + vertex_queue.pop_front(); + + //call BFS with visitor + breadth_first_visit(g, s, Q, vis, color); + } + return permutation; + } + + + // This is the case where only a single starting vertex is supplied. + template + OutputIterator + cuthill_mckee_ordering(const Graph& g, + typename graph_traits::vertex_descriptor s, + OutputIterator permutation, + ColorMap color, DegreeMap degree) + { + + std::deque< typename graph_traits::vertex_descriptor > vertex_queue; + vertex_queue.push_front( s ); + + return cuthill_mckee_ordering(g, vertex_queue, permutation, color, degree); + + } + + + // This is the version of CM which selects its own starting vertex + template < class Graph, class OutputIterator, + class ColorMap, class DegreeMap> + OutputIterator + cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, + ColorMap color, DegreeMap degree) + { + if (vertices(G).first == vertices(G).second) + return permutation; + + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits::vertex_iterator VerIter; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + std::deque vertex_queue; + + // Mark everything white + BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white()); + + // Find one vertex from each connected component + BGL_FORALL_VERTICES_T(v, G, Graph) { + if (get(color, v) == Color::white()) { + depth_first_visit(G, v, dfs_visitor<>(), color); + vertex_queue.push_back(v); + } + } + + // Find starting nodes for all vertices + // TBD: How to do this with a directed graph? + for (typename std::deque::iterator i = vertex_queue.begin(); + i != vertex_queue.end(); ++i) + *i = find_starting_node(G, *i, color, degree); + + return cuthill_mckee_ordering(G, vertex_queue, permutation, + color, degree); + } + + template + OutputIterator + cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, + VertexIndexMap index_map) + { + if (vertices(G).first == vertices(G).second) + return permutation; + + typedef out_degree_property_map DegreeMap; + std::vector colors(num_vertices(G)); + return cuthill_mckee_ordering(G, permutation, + make_iterator_property_map(&colors[0], + index_map, + colors[0]), + make_out_degree_map(G)); + } + + template + inline OutputIterator + cuthill_mckee_ordering(const Graph& G, OutputIterator permutation) + { return cuthill_mckee_ordering(G, permutation, get(vertex_index, G)); } +} // namespace boost + + +#endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP diff --git a/thirdparty/boost/graph/dag_shortest_paths.hpp b/thirdparty/boost/graph/dag_shortest_paths.hpp new file mode 100644 index 0000000..3473300 --- /dev/null +++ b/thirdparty/boost/graph/dag_shortest_paths.hpp @@ -0,0 +1,157 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP +#define BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP + +#include +#include + +// single-source shortest paths for a Directed Acyclic Graph (DAG) + +namespace boost { + + // Initalize distances and call depth first search + template + inline void + dag_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, + PredecessorMap pred, + DijkstraVisitor vis, Compare compare, Combine combine, + DistInf inf, DistZero zero) + { + typedef typename graph_traits::vertex_descriptor Vertex; + std::vector rev_topo_order; + rev_topo_order.reserve(num_vertices(g)); + + // Call 'depth_first_visit', not 'topological_sort', because we don't + // want to traverse the entire graph, only vertices reachable from 's', + // and 'topological_sort' will traverse everything. The logic below + // is the same as for 'topological_sort', only we call 'depth_first_visit' + // and 'topological_sort' calls 'depth_first_search'. + topo_sort_visitor > > + topo_visitor(std::back_inserter(rev_topo_order)); + depth_first_visit(g, s, topo_visitor, color); + + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + put(distance, *ui, inf); + put(pred, *ui, *ui); + } + + put(distance, s, zero); + vis.discover_vertex(s, g); + typename std::vector::reverse_iterator i; + for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) { + Vertex u = *i; + vis.examine_vertex(u, g); + typename graph_traits::out_edge_iterator e, e_end; + for (tie(e, e_end) = out_edges(u, g); e != e_end; ++e) { + vis.discover_vertex(target(*e, g), g); + bool decreased = relax(*e, g, weight, pred, distance, + combine, compare); + if (decreased) + vis.edge_relaxed(*e, g); + else + vis.edge_not_relaxed(*e, g); + } + vis.finish_vertex(u, g); + } + } + + namespace detail { + + // Defaults are the same as Dijkstra's algorithm + + // Handle Distance Compare, Combine, Inf and Zero defaults + template + inline void + dag_sp_dispatch2 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, + DijkstraVisitor vis, const Params& params) + { + typedef typename property_traits::value_type D; + dummy_property_map p_map; + dag_shortest_paths + (g, s, distance, weight, color, + choose_param(get_param(params, vertex_predecessor), p_map), + vis, + choose_param(get_param(params, distance_compare_t()), std::less()), + choose_param(get_param(params, distance_combine_t()), closed_plus()), + choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits::max)()), + choose_param(get_param(params, distance_zero_t()), + D())); + } + + // Handle DistanceMap and ColorMap defaults + template + inline void + dag_sp_dispatch1 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, + DijkstraVisitor vis, const Params& params) + { + typedef typename property_traits::value_type T; + typename std::vector::size_type n; + n = is_default_param(distance) ? num_vertices(g) : 1; + std::vector distance_map(n); + n = is_default_param(color) ? num_vertices(g) : 1; + std::vector color_map(n); + + dag_sp_dispatch2 + (g, s, + choose_param(distance, + make_iterator_property_map(distance_map.begin(), id, + distance_map[0])), + weight, + choose_param(color, + make_iterator_property_map(color_map.begin(), id, + color_map[0])), + id, vis, params); + } + + } // namespace detail + + template + inline void + dag_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // assert that the graph is directed... + null_visitor null_vis; + detail::dag_sp_dispatch1 + (g, s, + get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + get_param(params, vertex_color), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + choose_param(get_param(params, graph_visitor), + make_dijkstra_visitor(null_vis)), + params); + } + +} // namespace boost + +#endif // BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP diff --git a/thirdparty/boost/graph/depth_first_search.hpp b/thirdparty/boost/graph/depth_first_search.hpp new file mode 100644 index 0000000..423af7b --- /dev/null +++ b/thirdparty/boost/graph/depth_first_search.hpp @@ -0,0 +1,365 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2003 Bruce Barr +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +// Nonrecursive implementation of depth_first_visit_impl submitted by +// Bruce Barr, schmoost yahoo.com, May/June 2003. +#ifndef BOOST_GRAPH_RECURSIVE_DFS_HPP +#define BOOST_GRAPH_RECURSIVE_DFS_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost { + + template + class DFSVisitorConcept { + public: + void constraints() { + function_requires< CopyConstructibleConcept >(); + vis.initialize_vertex(u, g); + vis.start_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_edge(e, g); + vis.tree_edge(e, g); + vis.back_edge(e, g); + vis.forward_or_cross_edge(e, g); + vis.finish_vertex(u, g); + } + private: + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + namespace detail { + + struct nontruth2 { + template + bool operator()(const T&, const T2&) const { return false; } + }; + + +// Define BOOST_RECURSIVE_DFS to use older, recursive version. +// It is retained for a while in order to perform performance +// comparison. +#ifndef BOOST_RECURSIVE_DFS + + // If the vertex u and the iterators ei and ei_end are thought of as the + // context of the algorithm, each push and pop from the stack could + // be thought of as a context shift. + // Each pass through "while (ei != ei_end)" may refer to the out-edges of + // an entirely different vertex, because the context of the algorithm + // shifts every time a white adjacent vertex is discovered. + // The corresponding context shift back from the adjacent vertex occurs + // after all of its out-edges have been examined. + // + // See http://lists.boost.org/MailArchives/boost/msg48752.php for FAQ. + + template + void depth_first_visit_impl + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, + ColorMap color, TerminatorFunc func = TerminatorFunc()) + { + function_requires >(); + function_requires >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type ColorValue; + function_requires< ColorValueConcept >(); + typedef color_traits Color; + typedef typename graph_traits::out_edge_iterator Iter; + typedef std::pair > VertexInfo; + + Iter ei, ei_end; + std::vector stack; + + // Possible optimization for vector + //stack.reserve(num_vertices(g)); + + typedef typename unwrap_reference::type TF; + + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + tie(ei, ei_end) = out_edges(u, g); + // Variable is needed to workaround a borland bug. + TF& fn = static_cast(func); + if (fn(u, g)) { + // If this vertex terminates the search, we push empty range + stack.push_back(std::make_pair(u, std::make_pair(ei_end, ei_end))); + } else { + stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end))); + } + while (!stack.empty()) { + VertexInfo& back = stack.back(); + u = back.first; + tie(ei, ei_end) = back.second; + stack.pop_back(); + while (ei != ei_end) { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { + vis.tree_edge(*ei, g); + stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end))); + u = v; + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + tie(ei, ei_end) = out_edges(u, g); + if (fn(u, g)) { + ei = ei_end; + } + } else if (v_color == Color::gray()) { + vis.back_edge(*ei, g); + ++ei; + } else { + vis.forward_or_cross_edge(*ei, g); + ++ei; + } + } + put(color, u, Color::black()); + vis.finish_vertex(u, g); + } + } + +#else // BOOST_RECURSIVE_DFS is defined + + template + void depth_first_visit_impl + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, // pass-by-reference here, important! + ColorMap color, TerminatorFunc func) + { + function_requires >(); + function_requires >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type ColorValue; + function_requires< ColorValueConcept >(); + typedef color_traits Color; + typename graph_traits::out_edge_iterator ei, ei_end; + + put(color, u, Color::gray()); vis.discover_vertex(u, g); + + typedef typename unwrap_reference::type TF; + // Variable is needed to workaround a borland bug. + TF& fn = static_cast(func); + if (!fn(u, g)) + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + Vertex v = target(*ei, g); vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { vis.tree_edge(*ei, g); + depth_first_visit_impl(g, v, vis, color, func); + } else if (v_color == Color::gray()) vis.back_edge(*ei, g); + else vis.forward_or_cross_edge(*ei, g); + } + put(color, u, Color::black()); vis.finish_vertex(u, g); + } + +#endif + + } // namespace detail + + template + void + depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color, + typename graph_traits::vertex_descriptor start_vertex) + { + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires >(); + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + put(color, *ui, Color::white()); vis.initialize_vertex(*ui, g); + } + + if (start_vertex != implicit_cast(*vertices(g).first)){ vis.start_vertex(start_vertex, g); + detail::depth_first_visit_impl(g, start_vertex, vis, color, + detail::nontruth2()); + } + + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + ColorValue u_color = get(color, *ui); + if (u_color == Color::white()) { vis.start_vertex(*ui, g); + detail::depth_first_visit_impl(g, *ui, vis, color, detail::nontruth2()); + } + } + } + + template + void + depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color) + { + if (vertices(g).first == vertices(g).second) + return; + + depth_first_search(g, vis, color, *vertices(g).first); + } + + namespace detail { + template + struct dfs_dispatch { + + template + static void + apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params&, + ColorMap color) + { + depth_first_search(g, vis, color, start_vertex); + } + }; + + template <> + struct dfs_dispatch { + template + static void + apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params& params, + detail::error_property_not_found) + { + std::vector color_vec(num_vertices(g)); + default_color_type c = white_color; // avoid warning about un-init + depth_first_search + (g, vis, make_iterator_property_map + (color_vec.begin(), + choose_const_pmap(get_param(params, vertex_index), + g, vertex_index), c), + start_vertex); + } + }; + } // namespace detail + + + template + class dfs_visitor { + public: + dfs_visitor() { } + dfs_visitor(Visitors vis) : m_vis(vis) { } + + template + void initialize_vertex(Vertex u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); + } + template + void start_vertex(Vertex u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_start_vertex()); + } + template + void discover_vertex(Vertex u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); + } + template + void examine_edge(Edge u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_examine_edge()); + } + template + void tree_edge(Edge u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_tree_edge()); + } + template + void back_edge(Edge u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_back_edge()); + } + template + void forward_or_cross_edge(Edge u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); + } + template + void finish_vertex(Vertex u, const Graph& g) { + invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); + } + + BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,dfs) + BOOST_GRAPH_EVENT_STUB(on_start_vertex,dfs) + BOOST_GRAPH_EVENT_STUB(on_discover_vertex,dfs) + BOOST_GRAPH_EVENT_STUB(on_examine_edge,dfs) + BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs) + BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs) + BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs) + BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs) + + protected: + Visitors m_vis; + }; + template + dfs_visitor + make_dfs_visitor(Visitors vis) { + return dfs_visitor(vis); + } + typedef dfs_visitor<> default_dfs_visitor; + + + // Named Parameter Variant + template + void + depth_first_search(const VertexListGraph& g, + const bgl_named_params& params) + { + typedef typename property_value< bgl_named_params, + vertex_color_t>::type C; + if (vertices(g).first == vertices(g).second) + return; + detail::dfs_dispatch::apply + (g, + choose_param(get_param(params, graph_visitor), + make_dfs_visitor(null_visitor())), + choose_param(get_param(params, root_vertex_t()), + *vertices(g).first), + params, + get_param(params, vertex_color) + ); + } + + template + void depth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor vis, ColorMap color) + { + vis.start_vertex(u, g); + detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2()); + } + + template + void depth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc()) + { + vis.start_vertex(u, g); + detail::depth_first_visit_impl(g, u, vis, color, func); + } + + +} // namespace boost + + +#endif diff --git a/thirdparty/boost/graph/detail/adj_list_edge_iterator.hpp b/thirdparty/boost/graph/detail/adj_list_edge_iterator.hpp new file mode 100644 index 0000000..ad3ebe1 --- /dev/null +++ b/thirdparty/boost/graph/detail/adj_list_edge_iterator.hpp @@ -0,0 +1,117 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP +#define BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP + +#include +#include +#include + +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) +# define BOOST_GRAPH_NO_OPTIONAL +#endif + +#ifdef BOOST_GRAPH_NO_OPTIONAL +# define BOOST_GRAPH_MEMBER . +#else +# define BOOST_GRAPH_MEMBER -> +# include +#endif // ndef BOOST_GRAPH_NO_OPTIONAL + +namespace boost { + + namespace detail { + + template + class adj_list_edge_iterator { + typedef adj_list_edge_iterator self; + public: + typedef std::forward_iterator_tag iterator_category; + typedef typename OutEdgeIterator::value_type value_type; + typedef typename OutEdgeIterator::reference reference; + typedef typename OutEdgeIterator::pointer pointer; + typedef typename OutEdgeIterator::difference_type difference_type; + typedef difference_type distance_type; + + inline adj_list_edge_iterator() {} + + inline adj_list_edge_iterator(const self& x) + : vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd), + edges(x.edges), m_g(x.m_g) { } + + template + inline adj_list_edge_iterator(VertexIterator b, + VertexIterator c, + VertexIterator e, + const G& g) + : vBegin(b), vCurr(c), vEnd(e), m_g(&g) { + if ( vCurr != vEnd ) { + while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) + ++vCurr; + if ( vCurr != vEnd ) + edges = out_edges(*vCurr, *m_g); + } + } + + /*Note: + In the directed graph cases, it is fine. + For undirected graphs, one edge go through twice. + */ + inline self& operator++() { + ++edges BOOST_GRAPH_MEMBER first; + if (edges BOOST_GRAPH_MEMBER first == edges BOOST_GRAPH_MEMBER second) + { + ++vCurr; + while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) + ++vCurr; + if ( vCurr != vEnd ) + edges = out_edges(*vCurr, *m_g); + } + return *this; + } + inline self operator++(int) { + self tmp = *this; + ++(*this); + return tmp; + } + inline value_type operator*() const + { return *edges BOOST_GRAPH_MEMBER first; } + inline bool operator==(const self& x) const { + return vCurr == x.vCurr + && (vCurr == vEnd + || edges BOOST_GRAPH_MEMBER first == x.edges BOOST_GRAPH_MEMBER first); + } + inline bool operator!=(const self& x) const { + return vCurr != x.vCurr + || (vCurr != vEnd + && edges BOOST_GRAPH_MEMBER first != x.edges BOOST_GRAPH_MEMBER first); + } + protected: + VertexIterator vBegin; + VertexIterator vCurr; + VertexIterator vEnd; + +#ifdef BOOST_GRAPH_NO_OPTIONAL + std::pair edges; +#else + boost::optional > + edges; +#endif // ndef BOOST_GRAPH_NO_OPTIONAL + const Graph* m_g; + }; + + } // namespace detail + +} + +#undef BOOST_GRAPH_MEMBER + +#endif // BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP diff --git a/thirdparty/boost/graph/detail/adjacency_list.hpp b/thirdparty/boost/graph/detail/adjacency_list.hpp new file mode 100644 index 0000000..1871d57 --- /dev/null +++ b/thirdparty/boost/graph/detail/adjacency_list.hpp @@ -0,0 +1,2844 @@ +// -*- c++ -*- +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP +#define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP + +#include // for vertex_map in copy_impl +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Symbol truncation problems with MSVC, trying to shorten names. +#define stored_edge se_ +#define stored_edge_property sep_ +#define stored_edge_iter sei_ + +/* + Outline for this file: + + out_edge_iterator and in_edge_iterator implementation + edge_iterator for undirected graph + stored edge types (these object live in the out-edge/in-edge lists) + directed edges helper class + directed graph helper class + undirected graph helper class + bidirectional graph helper class + bidirectional graph helper class (without edge properties) + bidirectional graph helper class (with edge properties) + adjacency_list helper class + adj_list_impl class + vec_adj_list_impl class + adj_list_gen class + vertex property map + edge property map + + + Note: it would be nice to merge some of the undirected and + bidirectional code... it is awful similar. + */ + + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# define Graph Graph_ +#endif + +namespace boost { + + namespace detail { + + template + struct directed_category_traits { + typedef directed_tag directed_category; + }; + + template <> + struct directed_category_traits { + typedef directed_tag directed_category; + }; + template <> + struct directed_category_traits { + typedef undirected_tag directed_category; + }; + template <> + struct directed_category_traits { + typedef bidirectional_tag directed_category; + }; + + template + struct target_is { + target_is(const Vertex& v) : m_target(v) { } + template + bool operator()(const StoredEdge& e) const { + return e.get_target() == m_target; + } + Vertex m_target; + }; + + // O(E/V) + template + void erase_from_incidence_list(EdgeList& el, vertex_descriptor v, + allow_parallel_edge_tag) + { + boost::graph_detail::erase_if(el, detail::target_is(v)); + } + // O(log(E/V)) + template + void erase_from_incidence_list(EdgeList& el, vertex_descriptor v, + disallow_parallel_edge_tag) + { + typedef typename EdgeList::value_type StoredEdge; + el.erase(StoredEdge(v)); + } + + //========================================================================= + // Out-Edge and In-Edge Iterator Implementation + + template + struct out_edge_iter + : iterator_adaptor< + out_edge_iter + , BaseIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > + { + typedef iterator_adaptor< + out_edge_iter + , BaseIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > super_t; + + inline out_edge_iter() { } + inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src) + : super_t(i), m_src(src) { } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor(m_src, (*this->base()).get_target(), + &(*this->base()).get_property()); + } + VertexDescriptor m_src; + }; + + template + struct in_edge_iter + : iterator_adaptor< + in_edge_iter + , BaseIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > + { + typedef iterator_adaptor< + in_edge_iter + , BaseIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > super_t; + + inline in_edge_iter() { } + inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src) + : super_t(i), m_src(src) { } + + inline EdgeDescriptor + dereference() const + { + return EdgeDescriptor((*this->base()).get_target(), m_src, + &this->base()->get_property()); + } + VertexDescriptor m_src; + }; + + //========================================================================= + // Undirected Edge Iterator Implementation + + template + struct undirected_edge_iter + : iterator_adaptor< + undirected_edge_iter + , EdgeIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > + { + typedef iterator_adaptor< + undirected_edge_iter + , EdgeIter + , EdgeDescriptor + , use_default + , EdgeDescriptor + , Difference + > super_t; + + undirected_edge_iter() {} + + explicit undirected_edge_iter(EdgeIter i) + : super_t(i) {} + + inline EdgeDescriptor + dereference() const { + return EdgeDescriptor( + (*this->base()).m_source + , (*this->base()).m_target + , &this->base()->get_property()); + } + }; + + //========================================================================= + // Edge Storage Types (stored in the out-edge/in-edge lists) + + template + class stored_edge + : public boost::equality_comparable1< stored_edge, + boost::less_than_comparable1< stored_edge > > + { + public: + typedef no_property property_type; + inline stored_edge() { } + inline stored_edge(Vertex target, const no_property& = no_property()) + : m_target(target) { } + // Need to write this explicitly so stored_edge_property can + // invoke Base::operator= (at least, for SGI MIPSPro compiler) + inline stored_edge& operator=(const stored_edge& x) { + m_target = x.m_target; + return *this; + } + inline Vertex& get_target() const { return m_target; } + inline const no_property& get_property() const { return s_prop; } + inline bool operator==(const stored_edge& x) const + { return m_target == x.get_target(); } + inline bool operator<(const stored_edge& x) const + { return m_target < x.get_target(); } + //protected: need to add hash<> as a friend + static no_property s_prop; + // Sometimes target not used as key in the set, and in that case + // it is ok to change the target. + mutable Vertex m_target; + }; + template + no_property stored_edge::s_prop; + + template + class stored_edge_property : public stored_edge { + typedef stored_edge_property self; + typedef stored_edge Base; + public: + typedef Property property_type; + inline stored_edge_property() { } + inline stored_edge_property(Vertex target, + const Property& p = Property()) + : stored_edge(target), m_property(new Property(p)) { } + stored_edge_property(const self& x) + : Base(x), m_property(const_cast(x).m_property) { } + self& operator=(const self& x) { + Base::operator=(x); + m_property = const_cast(x).m_property; + return *this; + } + inline Property& get_property() { return *m_property; } + inline const Property& get_property() const { return *m_property; } + protected: + // Holding the property by-value causes edge-descriptor + // invalidation for add_edge() with EdgeList=vecS. Instead we + // hold a pointer to the property. std::auto_ptr is not + // a perfect fit for the job, but it is darn close. + std::auto_ptr m_property; + }; + + + template + class stored_edge_iter + : public stored_edge + { + public: + typedef Property property_type; + inline stored_edge_iter() { } + inline stored_edge_iter(Vertex v) + : stored_edge(v) { } + inline stored_edge_iter(Vertex v, Iter i, void* = 0) + : stored_edge(v), m_iter(i) { } + inline Property& get_property() { return m_iter->get_property(); } + inline const Property& get_property() const { + return m_iter->get_property(); + } + inline Iter get_iter() const { return m_iter; } + protected: + Iter m_iter; + }; + + // For when the EdgeList is a std::vector. + // Want to make the iterator stable, so use an offset + // instead of an iterator into a std::vector + template + class stored_ra_edge_iter + : public stored_edge + { + typedef typename EdgeVec::iterator Iter; + public: + typedef Property property_type; + inline stored_ra_edge_iter() { } + inline stored_ra_edge_iter(Vertex v, Iter i = Iter(), + EdgeVec* edge_vec = 0) + : stored_edge(v), m_i(i - edge_vec->begin()), m_vec(edge_vec){ } + inline Property& get_property() { return (*m_vec)[m_i].get_property(); } + inline const Property& get_property() const { + return (*m_vec)[m_i].get_property(); + } + inline Iter get_iter() const { return m_vec->begin() + m_i; } + protected: + std::size_t m_i; + EdgeVec* m_vec; + }; + + } // namespace detail + + template + const typename property_value::type& + get(Tag property_tag, + const detail::stored_edge_property& e) + { + return get_property_value(e.get_property(), property_tag); + } + + template + const typename property_value::type& + get(Tag property_tag, + const detail::stored_edge_iter& e) + { + return get_property_value(e.get_property(), property_tag); + } + + template + const typename property_value::type& + get(Tag property_tag, + const detail::stored_ra_edge_iter& e) + { + return get_property_value(e.get_property(), property_tag); + } + + //========================================================================= + // Directed Edges Helper Class + + namespace detail { + + // O(E/V) + template + inline void + remove_directed_edge_dispatch(edge_descriptor, EdgeList& el, + StoredProperty& p) + { + for (typename EdgeList::iterator i = el.begin(); + i != el.end(); ++i) + if (&(*i).get_property() == &p) { + el.erase(i); + return; + } + } + + template + inline void + remove_directed_edge_if_dispatch(incidence_iterator first, + incidence_iterator last, + EdgeList& el, Predicate pred, + boost::allow_parallel_edge_tag) + { + // remove_if + while (first != last && !pred(*first)) + ++first; + incidence_iterator i = first; + if (first != last) + for (; i != last; ++i) + if (!pred(*i)) { + *first.base() = *i.base(); + ++first; + } + el.erase(first.base(), el.end()); + } + template + inline void + remove_directed_edge_if_dispatch(incidence_iterator first, + incidence_iterator last, + EdgeList& el, + Predicate pred, + boost::disallow_parallel_edge_tag) + { + for (incidence_iterator next = first; + first != last; first = next) { + ++next; + if (pred(*first)) + el.erase( first.base() ); + } + } + + template + inline void + undirected_remove_out_edge_if_dispatch(Graph& g, + incidence_iterator first, + incidence_iterator last, + EdgeList& el, Predicate pred, + boost::allow_parallel_edge_tag) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + // remove_if + while (first != last && !pred(*first)) + ++first; + incidence_iterator i = first; + bool self_loop_removed = false; + if (first != last) + for (; i != last; ++i) { + if (self_loop_removed) { + /* With self loops, the descriptor will show up + * twice. The first time it will be removed, and now it + * will be skipped. + */ + self_loop_removed = false; + } + else if (!pred(*i)) { + *first.base() = *i.base(); + ++first; + } else { + if (source(*i, g) == target(*i, g)) self_loop_removed = true; + else { + // Remove the edge from the target + detail::remove_directed_edge_dispatch + (*i, + g.out_edge_list(target(*i, g)), + *(PropT*)(*i).get_property()); + } + + // Erase the edge property + g.m_edges.erase( (*i.base()).get_iter() ); + } + } + el.erase(first.base(), el.end()); + } + template + inline void + undirected_remove_out_edge_if_dispatch(Graph& g, + incidence_iterator first, + incidence_iterator last, + EdgeList& el, + Predicate pred, + boost::disallow_parallel_edge_tag) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + for (incidence_iterator next = first; + first != last; first = next) { + ++next; + if (pred(*first)) { + if (source(*first, g) != target(*first, g)) { + // Remove the edge from the target + detail::remove_directed_edge_dispatch + (*first, + g.out_edge_list(target(*first, g)), + *(PropT*)(*first).get_property()); + } + + // Erase the edge property + g.m_edges.erase( (*first.base()).get_iter() ); + + // Erase the edge in the source + el.erase( first.base() ); + } + } + } + + // O(E/V) + template + inline void + remove_directed_edge_dispatch(edge_descriptor e, EdgeList& el, + no_property&) + { + for (typename EdgeList::iterator i = el.begin(); + i != el.end(); ++i) + if ((*i).get_target() == e.m_target) { + el.erase(i); + return; + } + } + + } // namespace detail + + template + struct directed_edges_helper { + + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. + + // O(E/V) + inline void + remove_edge(typename Config::edge_descriptor e) + { + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(*this); + typename Config::OutEdgeList& el = g.out_edge_list(source(e, g)); + typedef typename Config::OutEdgeList::value_type::property_type PType; + detail::remove_directed_edge_dispatch(e, el, + *(PType*)e.get_property()); + } + + // O(1) + inline void + remove_edge(typename Config::out_edge_iterator iter) + { + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(*this); + typename Config::edge_descriptor e = *iter; + typename Config::OutEdgeList& el = g.out_edge_list(source(e, g)); + el.erase(iter.base()); + } + + }; + + // O(1) + template + inline std::pair + edges(const directed_edges_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast(g_); + graph_type& g = const_cast(cg); + return std::make_pair( edge_iterator(g.vertex_set().begin(), + g.vertex_set().begin(), + g.vertex_set().end(), g), + edge_iterator(g.vertex_set().begin(), + g.vertex_set().end(), + g.vertex_set().end(), g) ); + } + + //========================================================================= + // Directed Graph Helper Class + + struct adj_list_dir_traversal_tag : + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag { }; + + template + struct directed_graph_helper + : public directed_edges_helper { + typedef typename Config::edge_descriptor edge_descriptor; + typedef adj_list_dir_traversal_tag traversal_category; + }; + + // O(E/V) + template + inline void + remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat()); + } + + template + inline void + remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, + directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typename Config::out_edge_iterator first, last; + tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category edge_parallel_category; + detail::remove_directed_edge_if_dispatch + (first, last, g.out_edge_list(u), pred, edge_parallel_category()); + } + + template + inline void + remove_edge_if(Predicate pred, directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + + typename Config::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + remove_out_edge_if(*vi, pred, g); + } + + template + inline void + remove_edge(EdgeOrIter e_or_iter, directed_graph_helper& g_) + { + g_.remove_edge(e_or_iter); + } + + // O(V + E) for allow_parallel_edges + // O(V * log(E/V)) for disallow_parallel_edges + template + inline void + clear_vertex(typename Config::vertex_descriptor u, + directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + typename Config::vertex_iterator vi, viend; + for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) + detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat()); + g.out_edge_list(u).clear(); + // clear() should be a req of Sequence and AssociativeContainer, + // or maybe just Container + } + + template + inline void + clear_out_edges(typename Config::vertex_descriptor u, + directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + g.out_edge_list(u).clear(); + // clear() should be a req of Sequence and AssociativeContainer, + // or maybe just Container + } + + // O(V), could do better... + template + inline typename Config::edges_size_type + num_edges(const directed_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast(g_); + typename Config::edges_size_type num_e = 0; + typename Config::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + num_e += out_degree(*vi, g); + return num_e; + } + // O(1) for allow_parallel_edge_tag + // O(log(E/V)) for disallow_parallel_edge_tag + template + inline std::pair::edge_descriptor, bool> + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + directed_graph_helper& g_) + { + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::graph_type graph_type; + typedef typename Config::StoredEdge StoredEdge; + graph_type& g = static_cast(g_); + typename Config::OutEdgeList::iterator i; + bool inserted; + boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), + StoredEdge(v, p)); + return std::make_pair(edge_descriptor(u, v, &(*i).get_property()), + inserted); + } + // Did not use default argument here because that + // causes Visual C++ to get confused. + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + directed_graph_helper& g_) + { + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); + } + //========================================================================= + // Undirected Graph Helper Class + + template + struct undirected_graph_helper; + + struct undir_adj_list_traversal_tag : + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag, + public virtual bidirectional_graph_tag { }; + + namespace detail { + + // using class with specialization for dispatch is a VC++ workaround. + template + struct remove_undirected_edge_dispatch { + + // O(E/V) + template + static void + apply(edge_descriptor e, + undirected_graph_helper& g_, + StoredProperty& p) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + + typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g)); + typename Config::OutEdgeList::iterator out_i = out_el.begin(); + for (; out_i != out_el.end(); ++out_i) + if (&(*out_i).get_property() == &p) { + out_el.erase(out_i); + break; + } + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + typename Config::OutEdgeList::iterator in_i = in_el.begin(); + for (; in_i != in_el.end(); ++in_i) + if (&(*in_i).get_property() == &p) { + g.m_edges.erase((*in_i).get_iter()); + in_el.erase(in_i); + return; + } + } + }; + + template <> + struct remove_undirected_edge_dispatch { + // O(E/V) + template + static void + apply(edge_descriptor e, + undirected_graph_helper& g_, + no_property&) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + no_property* p = (no_property*)e.get_property(); + typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g)); + typename Config::OutEdgeList::iterator out_i = out_el.begin(); + for (; out_i != out_el.end(); ++out_i) + if (&(*out_i).get_property() == p) { + out_el.erase(out_i); + break; + } + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + typename Config::OutEdgeList::iterator in_i = in_el.begin(); + for (; in_i != in_el.end(); ++in_i) + if (&(*in_i).get_property() == p) { + g.m_edges.erase((*in_i).get_iter()); + in_el.erase(in_i); + return; + } + } + }; + + // O(E/V) + template + inline void + remove_edge_and_property(Graph& g, EdgeList& el, Vertex v, + boost::allow_parallel_edge_tag cat) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename EdgeList::value_type StoredEdge; + typename EdgeList::iterator i = el.begin(), end = el.end(); + for (; i != end; ++i) + if ((*i).get_target() == v) + g.m_edges.erase((*i).get_iter()); + detail::erase_from_incidence_list(el, v, cat); + } + // O(log(E/V)) + template + inline void + remove_edge_and_property(Graph& g, EdgeList& el, Vertex v, + boost::disallow_parallel_edge_tag) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename EdgeList::value_type StoredEdge; + typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end(); + if (i != end) { + g.m_edges.erase((*i).get_iter()); + el.erase(i); + } + } + + } // namespace detail + + template + struct list_edge // short name due to VC++ truncation and linker problems + : public boost::detail::edge_base + { + typedef EdgeProperty property_type; + typedef boost::detail::edge_base Base; + list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty()) + : Base(u, v), m_property(p) { } + EdgeProperty& get_property() { return m_property; } + const EdgeProperty& get_property() const { return m_property; } + // the following methods should never be used, but are needed + // to make SGI MIPSpro C++ happy + list_edge() { } + bool operator==(const list_edge&) const { return false; } + bool operator<(const list_edge&) const { return false; } + EdgeProperty m_property; + }; + + template + struct undirected_graph_helper { + + typedef undir_adj_list_traversal_tag traversal_category; + + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. + + // O(E/V) + inline void + remove_edge(typename Config::edge_descriptor e) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::OutEdgeList::value_type::property_type PType; + detail::remove_undirected_edge_dispatch::apply + (e, *this, *(PType*)e.get_property()); + } + // O(E/V) + inline void + remove_edge(typename Config::out_edge_iterator iter) + { + this->remove_edge(*iter); + } + }; + + // Had to make these non-members to avoid accidental instantiation + // on SGI MIPSpro C++ + template + inline typename C::InEdgeList& + in_edge_list(undirected_graph_helper&, + typename C::vertex_descriptor v) + { + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_out_edges; + } + template + inline const typename C::InEdgeList& + in_edge_list(const undirected_graph_helper&, + typename C::vertex_descriptor v) { + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_out_edges; + } + + // O(E/V) + template + inline void + remove_edge(EdgeOrIter e, undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + g_.remove_edge(e); + } + + // O(E/V) or O(log(E/V)) + template + void + remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typedef typename Config::edge_parallel_category Cat; + detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); + detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat()); + } + + template + void + remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, + undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast(g_); + typename Config::out_edge_iterator first, last; + tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category Cat; + detail::undirected_remove_out_edge_if_dispatch + (g, first, last, g.out_edge_list(u), pred, Cat()); + } + template + void + remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred, + undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + remove_out_edge_if(u, pred, g_); + } + + // O(E/V * E) or O(log(E/V) * E) + template + void + remove_edge_if(Predicate pred, undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typename Config::edge_iterator ei, ei_end, next; + tie(ei, ei_end) = edges(g); + for (next = ei; ei != ei_end; ei = next) { + ++next; + if (pred(*ei)) + remove_edge(*ei, g); + } + } + + // O(1) + template + inline std::pair + edges(const undirected_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast(g_); + graph_type& g = const_cast(cg); + return std::make_pair( edge_iterator(g.m_edges.begin()), + edge_iterator(g.m_edges.end()) ); + } + // O(1) + template + inline typename Config::edges_size_type + num_edges(const undirected_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast(g_); + return g.m_edges.size(); + } + // O(E/V * E/V) + template + inline void + clear_vertex(typename Config::vertex_descriptor u, + undirected_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator + ei = el.begin(), ei_end = el.end(); + for (; ei != ei_end; ++ei) { + detail::erase_from_incidence_list + (g.out_edge_list((*ei).get_target()), u, Cat()); + g.m_edges.erase((*ei).get_iter()); + } + g.out_edge_list(u).clear(); + } + // O(1) for allow_parallel_edge_tag + // O(log(E/V)) for disallow_parallel_edge_tag + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + undirected_graph_helper& g_) + { + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + + bool inserted; + typename Config::EdgeContainer::value_type e(u, v, p); + typename Config::EdgeContainer::iterator p_iter + = graph_detail::push(g.m_edges, e).first; + + typename Config::OutEdgeList::iterator i; + boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), + StoredEdge(v, p_iter, &g.m_edges)); + if (inserted) { + boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges)); + return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()), + true); + } else { + g.m_edges.erase(p_iter); + return std::make_pair + (edge_descriptor(u, v, &i->get_iter()->get_property()), false); + } + } + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + undirected_graph_helper& g_) + { + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); + } + + // O(1) + template + inline typename Config::degree_size_type + degree(typename Config::vertex_descriptor u, + const undirected_graph_helper& g_) + { + typedef typename Config::graph_type Graph; + const Graph& g = static_cast(g_); + return out_degree(u, g); + } + + template + inline std::pair + in_edges(typename Config::vertex_descriptor u, + const undirected_graph_helper& g_) + { + typedef typename Config::graph_type Graph; + const Graph& cg = static_cast(g_); + Graph& g = const_cast(cg); + typedef typename Config::in_edge_iterator in_edge_iterator; + return + std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u), + in_edge_iterator(g.out_edge_list(u).end(), u)); + } + + template + inline typename Config::degree_size_type + in_degree(typename Config::vertex_descriptor u, + const undirected_graph_helper& g_) + { return degree(u, g_); } + + //========================================================================= + // Bidirectional Graph Helper Class + + struct bidir_adj_list_traversal_tag : + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag, + public virtual bidirectional_graph_tag { }; + + template + struct bidirectional_graph_helper + : public directed_edges_helper { + typedef bidir_adj_list_traversal_tag traversal_category; + }; + + // Had to make these non-members to avoid accidental instantiation + // on SGI MIPSpro C++ + template + inline typename C::InEdgeList& + in_edge_list(bidirectional_graph_helper&, + typename C::vertex_descriptor v) + { + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_in_edges; + } + template + inline const typename C::InEdgeList& + in_edge_list(const bidirectional_graph_helper&, + typename C::vertex_descriptor v) { + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_in_edges; + } + + template + inline void + remove_edge_if(Predicate pred, bidirectional_graph_helper& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typename Config::edge_iterator ei, ei_end, next; + tie(ei, ei_end) = edges(g); + for (next = ei; ei != ei_end; ei = next) { + ++next; + if (pred(*ei)) + remove_edge(*ei, g); + } + } + + template + inline std::pair + in_edges(typename Config::vertex_descriptor u, + const bidirectional_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + const graph_type& cg = static_cast(g_); + graph_type& g = const_cast(cg); + typedef typename Config::in_edge_iterator in_edge_iterator; + return + std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u), + in_edge_iterator(in_edge_list(g, u).end(), u)); + } + + // O(1) + template + inline std::pair + edges(const bidirectional_graph_helper& g_) + { + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast(g_); + graph_type& g = const_cast(cg); + return std::make_pair( edge_iterator(g.m_edges.begin()), + edge_iterator(g.m_edges.end()) ); + } + + //========================================================================= + // Bidirectional Graph Helper Class (with edge properties) + + + template + struct bidirectional_graph_helper_with_property + : public bidirectional_graph_helper + { + typedef typename Config::graph_type graph_type; + typedef typename Config::out_edge_iterator out_edge_iterator; + + std::pair + get_parallel_edge_sublist(typename Config::edge_descriptor e, + const graph_type& g, + void*) + { return out_edges(source(e, g), g); } + + std::pair + get_parallel_edge_sublist(typename Config::edge_descriptor e, + const graph_type& g, + setS*) + { return edge_range(source(e, g), target(e, g), g); } + + std::pair + get_parallel_edge_sublist(typename Config::edge_descriptor e, + const graph_type& g, + multisetS*) + { return edge_range(source(e, g), target(e, g), g); } + +#if !defined BOOST_NO_HASH + std::pair + get_parallel_edge_sublist(typename Config::edge_descriptor e, + const graph_type& g, + hash_setS*) + { return edge_range(source(e, g), target(e, g), g); } +#endif + + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. + + // O(E/V) or O(log(E/V)) + void + remove_edge(typename Config::edge_descriptor e) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + graph_type& g = static_cast(*this); + + typedef typename Config::edgelist_selector OutEdgeListS; + + std::pair rng = + get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0)); + rng.first = std::find(rng.first, rng.second, e); + assert(rng.first != rng.second); + remove_edge(rng.first); + } + + inline void + remove_edge(typename Config::out_edge_iterator iter) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(*this); + typename Config::edge_descriptor e = *iter; + typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g)); + typename Config::InEdgeList& iel = in_edge_list(g, target(e, g)); + typedef typename Config::OutEdgeList::value_type::property_type PType; + PType& p = *(PType*)e.get_property(); + detail::remove_directed_edge_dispatch(*iter, iel, p); + g.m_edges.erase(iter.base()->get_iter()); + oel.erase(iter.base()); + } + }; + + // O(E/V) for allow_parallel_edge_tag + // O(log(E/V)) for disallow_parallel_edge_tag + template + inline void + remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typedef typename Config::edge_parallel_category Cat; + detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); + detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat()); + } + + // O(E/V) or O(log(E/V)) + template + inline void + remove_edge(EdgeOrIter e, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + g_.remove_edge(e); + } + + template + inline void + remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast(g_); + + typedef typename Config::EdgeIter EdgeIter; + typedef std::vector Garbage; + Garbage garbage; + + // First remove the edges from the targets' in-edge lists and + // from the graph's edge set list. + typename Config::out_edge_iterator out_i, out_end; + for (tie(out_i, out_end) = out_edges(u, g); out_i != out_end; ++out_i) + if (pred(*out_i)) { + detail::remove_directed_edge_dispatch + (*out_i, in_edge_list(g, target(*out_i, g)), + *(PropT*)(*out_i).get_property()); + // Put in garbage to delete later. Will need the properties + // for the remove_if of the out-edges. + garbage.push_back((*out_i.base()).get_iter()); + } + + // Now remove the edges from this out-edge list. + typename Config::out_edge_iterator first, last; + tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category Cat; + detail::remove_directed_edge_if_dispatch + (first, last, g.out_edge_list(u), pred, Cat()); + + // Now delete the edge properties from the g.m_edges list + for (typename Garbage::iterator i = garbage.begin(); + i != garbage.end(); ++i) + g.m_edges.erase(*i); + } + template + inline void + remove_in_edge_if(typename Config::vertex_descriptor v, Predicate pred, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast(g_); + + typedef typename Config::EdgeIter EdgeIter; + typedef std::vector Garbage; + Garbage garbage; + + // First remove the edges from the sources' out-edge lists and + // from the graph's edge set list. + typename Config::in_edge_iterator in_i, in_end; + for (tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + if (pred(*in_i)) { + typename Config::vertex_descriptor u = source(*in_i, g); + detail::remove_directed_edge_dispatch + (*in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property()); + // Put in garbage to delete later. Will need the properties + // for the remove_if of the out-edges. + garbage.push_back((*in_i.base()).get_iter()); + } + // Now remove the edges from this in-edge list. + typename Config::in_edge_iterator first, last; + tie(first, last) = in_edges(v, g); + typedef typename Config::edge_parallel_category Cat; + detail::remove_directed_edge_if_dispatch + (first, last, in_edge_list(g, v), pred, Cat()); + + // Now delete the edge properties from the g.m_edges list + for (typename Garbage::iterator i = garbage.begin(); + i != garbage.end(); ++i) + g.m_edges.erase(*i); + } + + // O(1) + template + inline typename Config::edges_size_type + num_edges(const bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast(g_); + return g.m_edges.size(); + } + // O(E/V * E/V) for allow_parallel_edge_tag + // O(E/V * log(E/V)) for disallow_parallel_edge_tag + template + inline void + clear_vertex(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator + ei = el.begin(), ei_end = el.end(); + for (; ei != ei_end; ++ei) { + detail::erase_from_incidence_list + (in_edge_list(g, (*ei).get_target()), u, Cat()); + g.m_edges.erase((*ei).get_iter()); + } + typename Config::InEdgeList& in_el = in_edge_list(g, u); + typename Config::InEdgeList::iterator + in_ei = in_el.begin(), in_ei_end = in_el.end(); + for (; in_ei != in_ei_end; ++in_ei) { + detail::erase_from_incidence_list + (g.out_edge_list((*in_ei).get_target()), u, Cat()); + g.m_edges.erase((*in_ei).get_iter()); + } + g.out_edge_list(u).clear(); + in_edge_list(g, u).clear(); + } + + template + inline void + clear_out_edges(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator + ei = el.begin(), ei_end = el.end(); + for (; ei != ei_end; ++ei) { + detail::erase_from_incidence_list + (in_edge_list(g, (*ei).get_target()), u, Cat()); + g.m_edges.erase((*ei).get_iter()); + } + g.out_edge_list(u).clear(); + } + + template + inline void + clear_in_edges(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast(g_); + typename Config::InEdgeList& in_el = in_edge_list(g, u); + typename Config::InEdgeList::iterator + in_ei = in_el.begin(), in_ei_end = in_el.end(); + for (; in_ei != in_ei_end; ++in_ei) { + detail::erase_from_incidence_list + (g.out_edge_list((*in_ei).get_target()), u, Cat()); + g.m_edges.erase((*in_ei).get_iter()); + } + in_edge_list(g, u).clear(); + } + + // O(1) for allow_parallel_edge_tag + // O(log(E/V)) for disallow_parallel_edge_tag + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast(g_); + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::StoredEdge StoredEdge; + bool inserted; + typename Config::EdgeContainer::value_type e(u, v, p); + typename Config::EdgeContainer::iterator p_iter + = graph_detail::push(g.m_edges, e).first; + typename Config::OutEdgeList::iterator i; + boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), + StoredEdge(v, p_iter, &g.m_edges)); + if (inserted) { + boost::graph_detail::push(in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges)); + return std::make_pair(edge_descriptor(u, v, &p_iter->m_property), + true); + } else { + g.m_edges.erase(p_iter); + return std::make_pair(edge_descriptor(u, v, + &i->get_iter()->get_property()), + false); + } + } + + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + bidirectional_graph_helper_with_property& g_) + { + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); + } + // O(1) + template + inline typename Config::degree_size_type + degree(typename Config::vertex_descriptor u, + const bidirectional_graph_helper_with_property& g_) + { + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast(g_); + return in_degree(u, g) + out_degree(u, g); + } + + //========================================================================= + // Adjacency List Helper Class + + template + struct adj_list_helper : public Base + { + typedef typename Config::graph_type AdjList; + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::out_edge_iterator out_edge_iterator; + typedef typename Config::in_edge_iterator in_edge_iterator; + typedef typename Config::adjacency_iterator adjacency_iterator; + typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; + typedef typename Config::vertex_iterator vertex_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::directed_category directed_category; + typedef typename Config::edge_parallel_category edge_parallel_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::edge_property_type edge_property_type; + + typedef typename Config::global_edgelist_selector + global_edgelist_selector; + + // protected: + + // The edge_dispatch() functions should be static, but + // Borland gets confused about constness. + + // O(E/V) + inline std::pair + edge_dispatch(const AdjList& g, + vertex_descriptor u, vertex_descriptor v, + boost::allow_parallel_edge_tag) const + { + bool found; + const typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::const_iterator + i = std::find_if(el.begin(), el.end(), + detail::target_is(v)); + found = (i != g.out_edge_list(u).end()); + if (found) + return std::make_pair(edge_descriptor(u, v, &(*i).get_property()), + true); + else + return std::make_pair(edge_descriptor(u, v, 0), false); + } + // O(log(E/V)) + inline std::pair + edge_dispatch(const AdjList& g, + vertex_descriptor u, vertex_descriptor v, + boost::disallow_parallel_edge_tag) const + { + bool found; + /* According to the standard, this should be iterator, not const_iterator, + but the VC++ std::set::find() const returns const_iterator. + And since iterator should be convertible to const_iterator, the + following should work everywhere. -Jeremy */ + typename Config::OutEdgeList::const_iterator + i = g.out_edge_list(u).find(StoredEdge(v)), + end = g.out_edge_list(u).end(); + found = (i != end); + if (found) + return std::make_pair(edge_descriptor(u, v, &(*i).get_property()), + true); + else + return std::make_pair(edge_descriptor(u, v, 0), false); + } + }; + + template + inline std::pair + adjacent_vertices(typename Config::vertex_descriptor u, + const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast(g_); + AdjList& g = const_cast(cg); + typedef typename Config::adjacency_iterator adjacency_iterator; + typename Config::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + return std::make_pair(adjacency_iterator(first, &g), + adjacency_iterator(last, &g)); + } + template + inline std::pair + inv_adjacent_vertices(typename Config::vertex_descriptor u, + const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast(g_); + AdjList& g = const_cast(cg); + typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; + typename Config::in_edge_iterator first, last; + boost::tie(first, last) = in_edges(u, g); + return std::make_pair(inv_adjacency_iterator(first, &g), + inv_adjacency_iterator(last, &g)); + } + template + inline std::pair + out_edges(typename Config::vertex_descriptor u, + const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + typedef typename Config::out_edge_iterator out_edge_iterator; + const AdjList& cg = static_cast(g_); + AdjList& g = const_cast(cg); + return + std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u), + out_edge_iterator(g.out_edge_list(u).end(), u)); + } + template + inline std::pair + vertices(const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast(g_); + AdjList& g = const_cast(cg); + return std::make_pair( g.vertex_set().begin(), g.vertex_set().end() ); + } + template + inline typename Config::vertices_size_type + num_vertices(const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + const AdjList& g = static_cast(g_); + return g.vertex_set().size(); + } + template + inline typename Config::degree_size_type + out_degree(typename Config::vertex_descriptor u, + const adj_list_helper& g_) + { + typedef typename Config::graph_type AdjList; + const AdjList& g = static_cast(g_); + return g.out_edge_list(u).size(); + } + template + inline std::pair + edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const adj_list_helper& g_) + { + typedef typename Config::graph_type Graph; + typedef typename Config::edge_parallel_category Cat; + const Graph& g = static_cast(g_); + return g_.edge_dispatch(g, u, v, Cat()); + } + template + inline std::pair + edge_range(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const adj_list_helper& g_) + { + typedef typename Config::graph_type Graph; + typedef typename Config::StoredEdge StoredEdge; + const Graph& cg = static_cast(g_); + Graph& g = const_cast(cg); + typedef typename Config::out_edge_iterator out_edge_iterator; + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator first, last; + typename Config::EdgeContainer fake_edge_container; + tie(first, last) = + std::equal_range(el.begin(), el.end(), + StoredEdge(v, fake_edge_container.end(), + &fake_edge_container)); + return std::make_pair(out_edge_iterator(first, u), + out_edge_iterator(last, u)); + } + + template + inline typename Config::degree_size_type + in_degree(typename Config::vertex_descriptor u, + const directed_edges_helper& g_) + { + typedef typename Config::graph_type Graph; + const Graph& cg = static_cast(g_); + Graph& g = const_cast(cg); + return in_edge_list(g, u).size(); + } + + namespace detail { + template + inline + typename boost::property_map::type + get_dispatch(adj_list_helper&, Property, + boost::edge_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::type PA; + return PA(); + } + template + inline + typename boost::property_map::const_type + get_dispatch(const adj_list_helper&, Property, + boost::edge_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::const_type PA; + return PA(); + } + + template + inline + typename boost::property_map::type + get_dispatch(adj_list_helper& g, Property, + boost::vertex_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::type PA; + return PA(&static_cast(g)); + } + template + inline + typename boost::property_map::const_type + get_dispatch(const adj_list_helper& g, Property, + boost::vertex_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::const_type PA; + const Graph& cg = static_cast(g); + return PA(&cg); + } + + } // namespace detail + + // Implementation of the PropertyGraph interface + template + inline + typename boost::property_map::type + get(Property p, adj_list_helper& g) { + typedef typename property_kind::type Kind; + return detail::get_dispatch(g, p, Kind()); + } + template + inline + typename boost::property_map::const_type + get(Property p, const adj_list_helper& g) { + typedef typename property_kind::type Kind; + return detail::get_dispatch(g, p, Kind()); + } + + template + inline + typename boost::property_traits< + typename boost::property_map::type + >::reference + get(Property p, adj_list_helper& g, const Key& key) { + return get(get(p, g), key); + } + + template + inline + typename boost::property_traits< + typename boost::property_map::const_type + >::reference + get(Property p, const adj_list_helper& g, const Key& key) { + return get(get(p, g), key); + } + + template + inline void + put(Property p, adj_list_helper& g, + const Key& key, const Value& value) + { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::type Map; + Map pmap = get(p, static_cast(g)); + put(pmap, key, value); + } + + + //========================================================================= + // Generalize Adjacency List Implementation + + struct adj_list_tag { }; + + template + class adj_list_impl + : public adj_list_helper + { + typedef typename Config::OutEdgeList OutEdgeList; + typedef typename Config::InEdgeList InEdgeList; + typedef typename Config::StoredVertexList StoredVertexList; + public: + typedef typename Config::stored_vertex stored_vertex; + typedef typename Config::EdgeContainer EdgeContainer; + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::vertex_iterator vertex_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::edge_parallel_category edge_parallel_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::edge_property_type edge_property_type; + typedef adj_list_tag graph_tag; + + static vertex_descriptor null_vertex() + { + return 0; + } + + inline adj_list_impl() { } + + inline adj_list_impl(const adj_list_impl& x) { + copy_impl(x); + } + inline adj_list_impl& operator=(const adj_list_impl& x) { + this->clear(); + copy_impl(x); + return *this; + } + inline void clear() { + for (typename StoredVertexList::iterator i = m_vertices.begin(); + i != m_vertices.end(); ++i) + delete (stored_vertex*)*i; + m_vertices.clear(); + m_edges.clear(); + } + inline adj_list_impl(vertices_size_type num_vertices) { + for (vertices_size_type i = 0; i < num_vertices; ++i) + add_vertex(static_cast(*this)); + } + template + inline adj_list_impl(vertices_size_type num_vertices, + EdgeIterator first, EdgeIterator last) + { + vertex_descriptor* v = new vertex_descriptor[num_vertices]; + for (vertices_size_type i = 0; i < num_vertices; ++i) + v[i] = add_vertex(static_cast(*this)); + + while (first != last) { + add_edge(v[(*first).first], v[(*first).second], *this); + ++first; + } + delete [] v; + } + template + inline adj_list_impl(vertices_size_type num_vertices, + EdgeIterator first, EdgeIterator last, + EdgePropertyIterator ep_iter) + { + vertex_descriptor* v = new vertex_descriptor[num_vertices]; + for (vertices_size_type i = 0; i < num_vertices; ++i) + v[i] = add_vertex(static_cast(*this)); + + while (first != last) { + add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this); + ++first; + ++ep_iter; + } + delete [] v; + } + ~adj_list_impl() { + for (typename StoredVertexList::iterator i = m_vertices.begin(); + i != m_vertices.end(); ++i) + delete (stored_vertex*)*i; + } + // protected: + inline OutEdgeList& out_edge_list(vertex_descriptor v) { + stored_vertex* sv = (stored_vertex*)v; + return sv->m_out_edges; + } + inline const OutEdgeList& out_edge_list(vertex_descriptor v) const { + stored_vertex* sv = (stored_vertex*)v; + return sv->m_out_edges; + } + inline StoredVertexList& vertex_set() { return m_vertices; } + inline const StoredVertexList& vertex_set() const { return m_vertices; } + + inline void copy_impl(const adj_list_impl& x_) + { + const Derived& x = static_cast(x_); + + // Would be better to have a constant time way to get from + // vertices in x to the corresponding vertices in *this. + std::map vertex_map; + + // Copy the stored vertex objects by adding each vertex + // and copying its property object. + vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) { + stored_vertex* v = (stored_vertex*)add_vertex(*this); + v->m_property = ((stored_vertex*)*vi)->m_property; + vertex_map[(stored_vertex*)*vi] = v; + } + // Copy the edges by adding each edge and copying its + // property object. + edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) { + edge_descriptor e; + bool inserted; + vertex_descriptor s = source(*ei,x), t = target(*ei,x); + tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s], + vertex_map[(stored_vertex*)t], *this); + *((edge_property_type*)e.m_eproperty) + = *((edge_property_type*)(*ei).m_eproperty); + } + } + + + typename Config::EdgeContainer m_edges; + StoredVertexList m_vertices; + }; + + // O(1) + template + inline typename Config::vertex_descriptor + add_vertex(adj_list_impl& g_) + { + Derived& g = static_cast(g_); + typedef typename Config::stored_vertex stored_vertex; + stored_vertex* v = new stored_vertex; + typename Config::StoredVertexList::iterator pos; + bool inserted; + boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v); + v->m_position = pos; + return v; + } + // O(1) + template + inline typename Config::vertex_descriptor + add_vertex(const typename Config::vertex_property_type& p, + adj_list_impl& g_) + { + Derived& g = static_cast(g_); + typedef typename Config::stored_vertex stored_vertex; + stored_vertex* v = new stored_vertex(p); + typename Config::StoredVertexList::iterator pos; + bool inserted; + boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v); + v->m_position = pos; + return v; + } + // O(1) + template + inline void remove_vertex(typename Config::vertex_descriptor u, + adj_list_impl& g_) + { + typedef typename Config::stored_vertex stored_vertex; + Derived& g = static_cast(g_); + stored_vertex* su = (stored_vertex*)u; + g.m_vertices.erase(su->m_position); + delete su; + } + // O(V) + template + inline typename Config::vertex_descriptor + vertex(typename Config::vertices_size_type n, + const adj_list_impl& g_) + { + const Derived& g = static_cast(g_); + typename Config::vertex_iterator i = vertices(g).first; + while (n--) ++i; // std::advance(i, n); (not VC++ portable) + return *i; + } + + //========================================================================= + // Vector-Backbone Adjacency List Implementation + + namespace detail { + + template + inline void + remove_vertex_dispatch(Graph& g, vertex_descriptor u, + boost::directed_tag) + { + typedef typename Graph::edge_parallel_category edge_parallel_category; + g.m_vertices.erase(g.m_vertices.begin() + u); + vertex_descriptor V = num_vertices(g); + if (u != V) { + for (vertex_descriptor v = 0; v < V; ++v) + reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category()); + } + } + + template + inline void + remove_vertex_dispatch(Graph& g, vertex_descriptor u, + boost::undirected_tag) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Graph::edge_parallel_category edge_parallel_category; + g.m_vertices.erase(g.m_vertices.begin() + u); + vertex_descriptor V = num_vertices(g); + for (vertex_descriptor v = 0; v < V; ++v) + reindex_edge_list(g.out_edge_list(v), u, + edge_parallel_category()); + typedef typename Graph::EdgeContainer Container; + typedef typename Container::iterator Iter; + Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end(); + for (; ei != ei_end; ++ei) { + if (ei->m_source > u) + --ei->m_source; + if (ei->m_target > u) + --ei->m_target; + } + } + template + inline void + remove_vertex_dispatch(Graph& g, vertex_descriptor u, + boost::bidirectional_tag) + { + typedef typename Graph::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same::value)); + + typedef typename Graph::edge_parallel_category edge_parallel_category; + g.m_vertices.erase(g.m_vertices.begin() + u); + vertex_descriptor V = num_vertices(g); + vertex_descriptor v; + if (u != V) { + for (v = 0; v < V; ++v) + reindex_edge_list(g.out_edge_list(v), u, + edge_parallel_category()); + for (v = 0; v < V; ++v) + reindex_edge_list(in_edge_list(g, v), u, + edge_parallel_category()); + + typedef typename Graph::EdgeContainer Container; + typedef typename Container::iterator Iter; + Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end(); + for (; ei != ei_end; ++ei) { + if (ei->m_source > u) + --ei->m_source; + if (ei->m_target > u) + --ei->m_target; + } + } + } + + template + inline void + reindex_edge_list(EdgeList& el, vertex_descriptor u, + boost::allow_parallel_edge_tag) + { + typename EdgeList::iterator ei = el.begin(), e_end = el.end(); + for (; ei != e_end; ++ei) + if ((*ei).get_target() > u) + --(*ei).get_target(); + } + template + inline void + reindex_edge_list(EdgeList& el, vertex_descriptor u, + boost::disallow_parallel_edge_tag) + { + typename EdgeList::iterator ei = el.begin(), e_end = el.end(); + while (ei != e_end) { + typename EdgeList::value_type ce = *ei; + ++ei; + if (ce.get_target() > u) { + el.erase(ce); + --ce.get_target(); + el.insert(ce); + } + } + } + } // namespace detail + + struct vec_adj_list_tag { }; + + template + class vec_adj_list_impl + : public adj_list_helper + { + typedef typename Config::OutEdgeList OutEdgeList; + typedef typename Config::InEdgeList InEdgeList; + typedef typename Config::StoredVertexList StoredVertexList; + public: + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::out_edge_iterator out_edge_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::directed_category directed_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::stored_vertex stored_vertex; + typedef typename Config::EdgeContainer EdgeContainer; + typedef typename Config::edge_property_type edge_property_type; + typedef vec_adj_list_tag graph_tag; + + static vertex_descriptor null_vertex() + { + return (std::numeric_limits::max)(); + } + + inline vec_adj_list_impl() { } + + inline vec_adj_list_impl(const vec_adj_list_impl& x) { + copy_impl(x); + } + inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) { + this->clear(); + copy_impl(x); + return *this; + } + inline void clear() { + m_vertices.clear(); + m_edges.clear(); + } + + inline vec_adj_list_impl(vertices_size_type _num_vertices) + : m_vertices(_num_vertices) { } + + template + inline vec_adj_list_impl(vertices_size_type num_vertices, + EdgeIterator first, EdgeIterator last) + : m_vertices(num_vertices) + { + while (first != last) { + add_edge((*first).first, (*first).second, + static_cast(*this)); + ++first; + } + } + template + inline vec_adj_list_impl(vertices_size_type num_vertices, + EdgeIterator first, EdgeIterator last, + EdgePropertyIterator ep_iter) + : m_vertices(num_vertices) + { + while (first != last) { + add_edge((*first).first, (*first).second, *ep_iter, + static_cast(*this)); + ++first; + ++ep_iter; + } + } + + // protected: + inline boost::integer_range vertex_set() const { + return boost::integer_range(0, m_vertices.size()); + } + inline OutEdgeList& out_edge_list(vertex_descriptor v) { + return m_vertices[v].m_out_edges; + } + inline const OutEdgeList& out_edge_list(vertex_descriptor v) const { + return m_vertices[v].m_out_edges; + } + inline void copy_impl(const vec_adj_list_impl& x_) + { + const Graph& x = static_cast(x_); + // Copy the stored vertex objects by adding each vertex + // and copying its property object. + for (vertices_size_type i = 0; i < num_vertices(x); ++i) { + vertex_descriptor v = add_vertex(*this); + m_vertices[v].m_property = x.m_vertices[i].m_property; + } + // Copy the edges by adding each edge and copying its + // property object. + edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) { + edge_descriptor e; + bool inserted; + tie(e, inserted) = add_edge(source(*ei,x), target(*ei,x) , *this); + *((edge_property_type*)e.m_eproperty) + = *((edge_property_type*)(*ei).m_eproperty); + } + } + typename Config::EdgeContainer m_edges; + StoredVertexList m_vertices; + }; + // Had to make these non-members to avoid accidental instantiation + // on SGI MIPSpro C++ + template + inline typename C::InEdgeList& + in_edge_list(vec_adj_list_impl& g, + typename C::vertex_descriptor v) { + return g.m_vertices[v].m_in_edges; + } + template + inline const typename C::InEdgeList& + in_edge_list(const vec_adj_list_impl& g, + typename C::vertex_descriptor v) { + return g.m_vertices[v].m_in_edges; + } + + // O(1) + template + inline typename Config::vertex_descriptor + add_vertex(vec_adj_list_impl& g_) { + Graph& g = static_cast(g_); + g.m_vertices.resize(g.m_vertices.size() + 1); + return g.m_vertices.size() - 1; + } + + template + inline typename Config::vertex_descriptor + add_vertex(const typename Config::vertex_property_type& p, + vec_adj_list_impl& g_) { + Graph& g = static_cast(g_); + typedef typename Config::stored_vertex stored_vertex; + g.m_vertices.push_back(stored_vertex(p)); + return g.m_vertices.size() - 1; + } + + // Here we override the directed_graph_helper add_edge() function + // so that the number of vertices is automatically changed if + // either u or v is greater than the number of vertices. + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + vec_adj_list_impl& g_) + { + BOOST_USING_STD_MAX(); + typename Config::vertex_descriptor x = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v); + if (x >= num_vertices(g_)) + g_.m_vertices.resize(x + 1); + adj_list_helper& g = g_; + return add_edge(u, v, p, g); + } + template + inline std::pair + add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + vec_adj_list_impl& g_) + { + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); + } + + + // O(V + E) + template + inline void remove_vertex(typename Config::vertex_descriptor v, + vec_adj_list_impl& g_) + { + typedef typename Config::directed_category Cat; + Graph& g = static_cast(g_); + detail::remove_vertex_dispatch(g, v, Cat()); + } + // O(1) + template + inline typename Config::vertex_descriptor + vertex(typename Config::vertices_size_type n, + const vec_adj_list_impl&) + { + return n; + } + + + namespace detail { + + //========================================================================= + // Adjacency List Generator + + template + struct adj_list_gen + { + typedef typename detail::is_random_access::type + is_rand_access; + typedef typename has_property::type has_edge_property; + typedef typename DirectedS::is_directed_t DirectedT; + typedef typename DirectedS::is_bidir_t BidirectionalT; + + struct config + { + typedef OutEdgeListS edgelist_selector; + typedef EdgeListS global_edgelist_selector; + + typedef Graph graph_type; + typedef EdgeProperty edge_property_type; + typedef VertexProperty vertex_property_type; + typedef GraphProperty graph_property_type; + typedef std::size_t vertices_size_type; + + typedef adjacency_list_traits + Traits; + + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + + typedef void* vertex_ptr; + + // need to reorganize this to avoid instantiating stuff + // that doesn't get used -JGS + + // VertexList and vertex_iterator + typedef typename container_gen::type SeqVertexList; + typedef boost::integer_range RandVertexList; + typedef typename mpl::if_::type VertexList; + + typedef typename VertexList::iterator vertex_iterator; + + // EdgeContainer and StoredEdge + + typedef typename container_gen >::type EdgeContainer; + + typedef typename mpl::and_::type >::type on_edge_storage; + + typedef typename mpl::if_::type edges_size_type; + + typedef typename EdgeContainer::iterator EdgeIter; + + typedef typename detail::is_random_access::type is_edge_ra; + + typedef typename mpl::if_, + typename mpl::if_, + stored_edge_iter + >::type + >::type StoredEdge; + + // Adjacency Types + + typedef typename container_gen::type + OutEdgeList; + typedef typename OutEdgeList::size_type degree_size_type; + typedef typename OutEdgeList::iterator OutEdgeIter; + + typedef boost::detail::iterator_traits OutEdgeIterTraits; + typedef typename OutEdgeIterTraits::iterator_category OutEdgeIterCat; + typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff; + + typedef out_edge_iter< + OutEdgeIter, vertex_descriptor, edge_descriptor, OutEdgeIterDiff + > out_edge_iterator; + + typedef typename adjacency_iterator_generator::type adjacency_iterator; + + typedef OutEdgeList InEdgeList; + typedef OutEdgeIter InEdgeIter; + typedef OutEdgeIterCat InEdgeIterCat; + typedef OutEdgeIterDiff InEdgeIterDiff; + + typedef in_edge_iter< + InEdgeIter, vertex_descriptor, edge_descriptor, InEdgeIterDiff + > in_edge_iterator; + + typedef typename inv_adjacency_iterator_generator::type inv_adjacency_iterator; + + // Edge Iterator + + typedef boost::detail::iterator_traits EdgeIterTraits; + typedef typename EdgeIterTraits::iterator_category EdgeIterCat; + typedef typename EdgeIterTraits::difference_type EdgeIterDiff; + + typedef undirected_edge_iter< + EdgeIter + , edge_descriptor + , EdgeIterDiff + > UndirectedEdgeIter; // also used for bidirectional + + typedef adj_list_edge_iterator DirectedEdgeIter; + + typedef typename mpl::if_::type edge_iterator; + + // stored_vertex and StoredVertexList + typedef typename container_gen::type + SeqStoredVertexList; + struct seq_stored_vertex { + seq_stored_vertex() { } + seq_stored_vertex(const VertexProperty& p) : m_property(p) { } + OutEdgeList m_out_edges; + VertexProperty m_property; + typename SeqStoredVertexList::iterator m_position; + }; + struct bidir_seq_stored_vertex { + bidir_seq_stored_vertex() { } + bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { } + OutEdgeList m_out_edges; + InEdgeList m_in_edges; + VertexProperty m_property; + typename SeqStoredVertexList::iterator m_position; + }; + struct rand_stored_vertex { + rand_stored_vertex() { } + rand_stored_vertex(const VertexProperty& p) : m_property(p) { } + OutEdgeList m_out_edges; + VertexProperty m_property; + }; + struct bidir_rand_stored_vertex { + bidir_rand_stored_vertex() { } + bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { } + OutEdgeList m_out_edges; + InEdgeList m_in_edges; + VertexProperty m_property; + }; + typedef typename mpl::if_::type, + typename mpl::if_::type + >::type StoredVertex; + struct stored_vertex : public StoredVertex { + stored_vertex() { } + stored_vertex(const VertexProperty& p) : StoredVertex(p) { } + }; + + typedef typename container_gen::type + RandStoredVertexList; + typedef typename mpl::if_< is_rand_access, + RandStoredVertexList, SeqStoredVertexList>::type StoredVertexList; + }; // end of config + + + typedef typename mpl::if_, + typename mpl::if_, + undirected_graph_helper + >::type + >::type DirectedHelper; + + typedef typename mpl::if_, + adj_list_impl + >::type type; + + }; + + } // namespace detail + + //========================================================================= + // Vertex Property Maps + + template + struct adj_list_vertex_property_map + : public boost::put_get_helper< + Reference, + adj_list_vertex_property_map + > + { + typedef typename Graph::stored_vertex StoredVertex; + typedef ValueType value_type; + typedef Reference reference; + typedef typename Graph::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + inline adj_list_vertex_property_map() { } + inline adj_list_vertex_property_map(const Graph*) { } + inline Reference operator[](key_type v) const { + StoredVertex* sv = (StoredVertex*)v; + return get_property_value(sv->m_property, Tag()); + } + inline Reference operator()(key_type v) const { + return this->operator[](v); + } + }; + + template + struct adj_list_vertex_all_properties_map + : public boost::put_get_helper + > + { + typedef typename Graph::stored_vertex StoredVertex; + typedef Property value_type; + typedef PropRef reference; + typedef typename Graph::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + inline adj_list_vertex_all_properties_map() { } + inline adj_list_vertex_all_properties_map(const Graph*) { } + inline PropRef operator[](key_type v) const { + StoredVertex* sv = (StoredVertex*)v; + return sv->m_property; + } + inline PropRef operator()(key_type v) const { + return this->operator[](v); + } + }; + + template + struct vec_adj_list_vertex_property_map + : public boost::put_get_helper< + Reference, + vec_adj_list_vertex_property_map + > + { + typedef ValueType value_type; + typedef Reference reference; + typedef typename boost::graph_traits::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + vec_adj_list_vertex_property_map() { } + vec_adj_list_vertex_property_map(GraphPtr g) : m_g(g) { } + inline Reference operator[](key_type v) const { + return get_property_value(m_g->m_vertices[v].m_property, Tag()); + } + inline Reference operator()(key_type v) const { + return this->operator[](v); + } + GraphPtr m_g; + }; + + template + struct vec_adj_list_vertex_all_properties_map + : public boost::put_get_helper + > + { + typedef Property value_type; + typedef PropertyRef reference; + typedef typename boost::graph_traits::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + vec_adj_list_vertex_all_properties_map() { } + vec_adj_list_vertex_all_properties_map(GraphPtr g) : m_g(g) { } + inline PropertyRef operator[](key_type v) const { + return m_g->m_vertices[v].m_property; + } + inline PropertyRef operator()(key_type v) const { + return this->operator[](v); + } + GraphPtr m_g; + }; + + struct adj_list_any_vertex_pa { + template + struct bind_ { + typedef typename property_value::type value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef adj_list_vertex_property_map + type; + typedef adj_list_vertex_property_map + const_type; + }; + }; + struct adj_list_all_vertex_pa { + template + struct bind_ { + typedef typename Graph::vertex_descriptor Vertex; + typedef adj_list_vertex_all_properties_map type; + typedef adj_list_vertex_all_properties_map const_type; + }; + }; + + template + struct vec_adj_list_vertex_id_map + : public boost::put_get_helper< + Vertex, vec_adj_list_vertex_id_map + > + { + typedef Vertex value_type; + typedef Vertex key_type; + typedef Vertex reference; + typedef boost::readable_property_map_tag category; + inline vec_adj_list_vertex_id_map() { } + template + inline vec_adj_list_vertex_id_map(const Graph&) { } + inline value_type operator[](key_type v) const { return v; } + inline value_type operator()(key_type v) const { return v; } + }; + + struct vec_adj_list_any_vertex_pa { + template + struct bind_ { + typedef typename property_value::type value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef vec_adj_list_vertex_property_map + type; + typedef vec_adj_list_vertex_property_map + const_type; + }; + }; + struct vec_adj_list_id_vertex_pa { + template + struct bind_ { + typedef typename Graph::vertex_descriptor Vertex; + typedef vec_adj_list_vertex_id_map type; + typedef vec_adj_list_vertex_id_map const_type; + }; + }; + struct vec_adj_list_all_vertex_pa { + template + struct bind_ { + typedef typename Graph::vertex_descriptor Vertex; + typedef vec_adj_list_vertex_all_properties_map + type; + typedef vec_adj_list_vertex_all_properties_map + const_type; + }; + }; + namespace detail { + template + struct adj_list_choose_vertex_pa_helper { + typedef adj_list_any_vertex_pa type; + }; + template <> + struct adj_list_choose_vertex_pa_helper { + typedef adj_list_all_vertex_pa type; + }; + template + struct adj_list_choose_vertex_pa { + typedef typename adj_list_choose_vertex_pa_helper::type Helper; + typedef typename Helper::template bind_ Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + + + template + struct vec_adj_list_choose_vertex_pa_helper { + typedef vec_adj_list_any_vertex_pa type; + }; + template <> + struct vec_adj_list_choose_vertex_pa_helper { + typedef vec_adj_list_id_vertex_pa type; + }; + template <> + struct vec_adj_list_choose_vertex_pa_helper { + typedef vec_adj_list_all_vertex_pa type; + }; + template + struct vec_adj_list_choose_vertex_pa { + typedef typename vec_adj_list_choose_vertex_pa_helper::type Helper; + typedef typename Helper::template bind_ Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + } // namespace detail + + //========================================================================= + // Edge Property Map + + template + struct adj_list_edge_property_map + : public put_get_helper< + Ref, + adj_list_edge_property_map + > + { + typedef Value value_type; + typedef Ref reference; + typedef detail::edge_desc_impl key_type; + typedef boost::lvalue_property_map_tag category; + inline Ref operator[](key_type e) const { + Property& p = *(Property*)e.get_property(); + return get_property_value(p, Tag()); + } + inline Ref operator()(key_type e) const { + return this->operator[](e); + } + }; + + template + struct adj_list_edge_all_properties_map + : public put_get_helper + > + { + typedef Property value_type; + typedef PropRef reference; + typedef detail::edge_desc_impl key_type; + typedef boost::lvalue_property_map_tag category; + inline PropRef operator[](key_type e) const { + return *(PropPtr)e.get_property(); + } + inline PropRef operator()(key_type e) const { + return this->operator[](e); + } + }; + + // Edge Property Maps + + namespace detail { + struct adj_list_any_edge_pmap { + template + struct bind_ { + typedef typename property_value::type value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef adj_list_edge_property_map + type; + typedef adj_list_edge_property_map + const_type; + }; + }; + struct adj_list_all_edge_pmap { + template + struct bind_ { + typedef adj_list_edge_all_properties_map + type; + typedef adj_list_edge_all_properties_map + const_type; + }; + }; + + template + struct adj_list_choose_edge_pmap_helper { + typedef adj_list_any_edge_pmap type; + }; + template <> + struct adj_list_choose_edge_pmap_helper { + typedef adj_list_all_edge_pmap type; + }; + template + struct adj_list_choose_edge_pmap { + typedef typename adj_list_choose_edge_pmap_helper::type Helper; + typedef typename Helper::template bind_ Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + struct adj_list_edge_property_selector { + template + struct bind_ { + typedef adj_list_choose_edge_pmap Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + }; + } // namespace detail + + template <> + struct edge_property_selector { + typedef detail::adj_list_edge_property_selector type; + }; + template <> + struct edge_property_selector { + typedef detail::adj_list_edge_property_selector type; + }; + + // Vertex Property Maps + + struct adj_list_vertex_property_selector { + template + struct bind_ { + typedef detail::adj_list_choose_vertex_pa Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + }; + template <> + struct vertex_property_selector { + typedef adj_list_vertex_property_selector type; + }; + + struct vec_adj_list_vertex_property_selector { + template + struct bind_ { + typedef detail::vec_adj_list_choose_vertex_pa Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + }; + template <> + struct vertex_property_selector { + typedef vec_adj_list_vertex_property_selector type; + }; + +} // namespace boost + +#if !defined(BOOST_NO_HASH) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +namespace BOOST_STD_EXTENSION_NAMESPACE { + + #if BOOST_WORKAROUND( _STLPORT_VERSION, >= 0x500 ) + // STLport 5 already defines a hash specialization. + #else + template <> + struct hash< void* > // Need this when vertex_descriptor=void* + { + std::size_t + operator()(void* v) const { return (std::size_t)v; } + }; + #endif + + template + struct hash< boost::detail::stored_edge > + { + std::size_t + operator()(const boost::detail::stored_edge& e) const + { + return hash()(e.m_target); + } + }; + + template + struct hash< boost::detail::stored_edge_property > + { + std::size_t + operator()(const boost::detail::stored_edge_property& e) const + { + return hash()(e.m_target); + } + }; + + template + struct hash< boost::detail::stored_edge_iter > + { + std::size_t + operator()(const boost::detail::stored_edge_iter& e) const + { + return hash()(e.m_target); + } + }; + +} +#endif + + +#undef stored_edge +#undef stored_edge_property +#undef stored_edge_iter + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +#undef Graph +#endif + +#endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT + +/* + Implementation Notes: + + Many of the public interface functions in this file would have been + more conveniently implemented as inline friend functions. + However there are a few compiler bugs that make that approach + non-portable. + + 1. g++ inline friend in namespace bug + 2. g++ using clause doesn't work with inline friends + 3. VC++ doesn't have Koenig lookup + + For these reasons, the functions were all written as non-inline free + functions, and static cast was used to convert from the helper + class to the adjacency_list derived class. + + Looking back, it might have been better to write out all functions + in terms of the adjacency_list, and then use a tag to dispatch + to the various helpers instead of using inheritance. + + */ diff --git a/thirdparty/boost/graph/detail/array_binary_tree.hpp b/thirdparty/boost/graph/detail/array_binary_tree.hpp new file mode 100644 index 0000000..9eb2020 --- /dev/null +++ b/thirdparty/boost/graph/detail/array_binary_tree.hpp @@ -0,0 +1,182 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef ADSTL_ARRAY_BINARY_TREE_HPP +#define ADSTL_ARRAY_BINARY_TREE_HPP + +#include +#include +#include + +namespace adstl { + /* + Note: array_binary_tree is a completey balanced binary tree + */ + +#if !defined BOOST_NO_STD_ITERATOR_TRAITS + template +#else + template +#endif +class array_binary_tree_node { +public: + typedef array_binary_tree_node ArrayBinaryTreeNode; + typedef RandomAccessIterator rep_iterator; +#if !defined BOOST_NO_STD_ITERATOR_TRAITS + typedef typename std::iterator_traits::difference_type + difference_type; + typedef typename std::iterator_traits::value_type + value_type; +#else + typedef int difference_type; + typedef ValueType value_type; +#endif + typedef difference_type size_type; + + struct children_type { + struct iterator + : boost::iterator + { // replace with iterator_adaptor implementation -JGS + + inline iterator() : i(0), n(0) { } + inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } + inline iterator& operator=(const iterator& x) { + r = x.r; i = x.i; n = x.n; + /*egcs generate a warning*/ + id = x.id; + return *this; + } + inline iterator(rep_iterator rr, + size_type ii, + size_type nn, + const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } + inline array_binary_tree_node operator*() { + return ArrayBinaryTreeNode(r, i, n, id); } + inline iterator& operator++() { ++i; return *this; } + inline iterator operator++(int) + { iterator t = *this; ++(*this); return t; } + inline bool operator==(const iterator& x) const { return i == x.i; } + inline bool operator!=(const iterator& x) const + { return !(*this == x); } + rep_iterator r; + size_type i; + size_type n; + ID id; + }; + inline children_type() : i(0), n(0) { } + inline children_type(const children_type& x) + : r(x.r), i(x.i), n(x.n), id(x.id) { } + inline children_type& operator=(const children_type& x) { + r = x.r; i = x.i; n = x.n; + /*egcs generate a warning*/ + id = x.id; + return *this; + } + inline children_type(rep_iterator rr, + size_type ii, + size_type nn, + const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } + inline iterator begin() { return iterator(r, 2 * i + 1, n, id); } + inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); } + inline size_type size() const { + size_type c = 2 * i + 1; + size_type s; + if (c + 1 < n) s = 2; + else if (c < n) s = 1; + else s = 0; + return s; + } + rep_iterator r; + size_type i; + size_type n; + ID id; + }; + inline array_binary_tree_node() : i(0), n(0) { } + inline array_binary_tree_node(const array_binary_tree_node& x) + : r(x.r), i(x.i), n(x.n), id(x.id) { } + inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) { + r = x.r; + i = x.i; + n = x.n; + /*egcs generate a warning*/ + id = x.id; + return *this; + } + inline array_binary_tree_node(rep_iterator start, + rep_iterator end, + rep_iterator pos, const ID& _id) + : r(start), i(pos - start), n(end - start), id(_id) { } + inline array_binary_tree_node(rep_iterator rr, + size_type ii, + size_type nn, const ID& _id) + : r(rr), i(ii), n(nn), id(_id) { } + inline value_type& value() { return *(r + i); } + inline const value_type& value() const { return *(r + i); } + inline ArrayBinaryTreeNode parent() const { + return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id); + } + inline bool has_parent() const { return i != 0; } + inline children_type children() { return children_type(r, i, n, id); } + /* + inline void swap(array_binary_tree_node x) { + value_type tmp = x.value(); + x.value() = value(); + value() = tmp; + i = x.i; + } + */ + template + inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) { + using boost::get; + + value_type tmp = x.value(); + + /*swap external data*/ + edata[ get(id, tmp) ] = i; + edata[ get(id, value()) ] = x.i; + + x.value() = value(); + value() = tmp; + i = x.i; + } + inline const children_type children() const { + return children_type(r, i, n); + } + inline size_type index() const { return i; } + rep_iterator r; + size_type i; + size_type n; + ID id; +}; + +template > +struct compare_array_node { + typedef typename RandomAccessContainer::value_type value_type; + compare_array_node(const Compare& x) : comp(x) {} + compare_array_node(const compare_array_node& x) : comp(x.comp) {} + + template< class node_type > + inline bool operator()(const node_type& x, const node_type& y) { + return comp(x.value(), y.value()); + } + + template< class node_type > + inline bool operator()(const node_type& x, const node_type& y) const { + return comp(x.value(), y.value()); + } + Compare comp; +}; + + +} /* namespace adstl */ + +#endif /* ADSTL_ARRAY_BINARY_TREE_H */ diff --git a/thirdparty/boost/graph/detail/connected_components.hpp b/thirdparty/boost/graph/detail/connected_components.hpp new file mode 100644 index 0000000..ae63aea --- /dev/null +++ b/thirdparty/boost/graph/detail/connected_components.hpp @@ -0,0 +1,208 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP +#define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP + +#if defined(__sgi) && !defined(__GNUC__) +#pragma set woff 1234 +#endif + +#include + +namespace boost { + + namespace detail { + + //========================================================================= + // Implementation details of connected_components + + // This is used both in the connected_components algorithm and in + // the kosaraju strong components algorithm during the second DFS + // traversal. + template + class components_recorder : public DFSVisitor + { + typedef typename property_traits::value_type comp_type; + public: + components_recorder(ComponentsPA c, + comp_type& c_count, + DFSVisitor v) + : DFSVisitor(v), m_component(c), m_count(c_count) {} + + template + void start_vertex(Vertex u, Graph& g) { + ++m_count; + DFSVisitor::start_vertex(u, g); + } + template + void discover_vertex(Vertex u, Graph& g) { + put(m_component, u, m_count); + DFSVisitor::discover_vertex(u, g); + } + protected: + ComponentsPA m_component; + comp_type& m_count; + }; + + template + class time_recorder : public DFSVisitor + { + public: + time_recorder(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v) + : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) {} + + template + void discover_vertex(Vertex u, Graph& g) { + put(m_discover_time, u, ++m_t); + DFSVisitor::discover_vertex(u, g); + } + template + void finish_vertex(Vertex u, Graph& g) { + put(m_finish_time, u, ++m_t); + DFSVisitor::discover_vertex(u, g); + } + protected: + DiscoverTimeMap m_discover_time; + FinishTimeMap m_finish_time; + TimeT m_t; + }; + template + time_recorder + record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis) + { + return time_recorder + (d, f, t, vis); + } + + //========================================================================= + // Implementation detail of dynamic_components + + + //------------------------------------------------------------------------- + // Helper functions for the component_index class + + // Record the representative vertices in the header array. + // Representative vertices now point to the component number. + + template + inline void + build_components_header(Parent p, + OutputIterator header, + Integer num_nodes) + { + Parent component = p; + Integer component_num = 0; + for (Integer v = 0; v != num_nodes; ++v) + if (p[v] == v) { + *header++ = v; + component[v] = component_num++; + } + } + + + // Pushes x onto the front of the list. The list is represented in + // an array. + template + inline void push_front(Next next, T& head, V x) + { + T tmp = head; + head = x; + next[x] = tmp; + } + + + // Create a linked list of the vertices in each component + // by reusing the representative array. + template + void + link_components(Parent1 component, Parent2 header, + Integer num_nodes, Integer num_components) + { + // Make the non-representative vertices point to their component + Parent1 representative = component; + for (Integer v = 0; v != num_nodes; ++v) + if (component[v] >= num_components || header[component[v]] != v) + component[v] = component[representative[v]]; + + // initialize the "head" of the lists to "NULL" + std::fill_n(header, num_components, num_nodes); + + // Add each vertex to the linked list for its component + Parent1 next = component; + for (Integer k = 0; k != num_nodes; ++k) + push_front(next, header[component[k]], k); + } + + + + template + void + construct_component_index(IndexContainer& index, HeaderContainer& header) + { + build_components_header(index.begin(), + std::back_inserter(header), + index.end() - index.begin()); + + link_components(index.begin(), header.begin(), + index.end() - index.begin(), + header.end() - header.begin()); + } + + + + template + class component_iterator + : boost::forward_iterator_helper< + component_iterator, + Integer, Distance,Integer*, Integer&> + { + public: + typedef component_iterator self; + + IndexIterator next; + Integer node; + + typedef std::forward_iterator_tag iterator_category; + typedef Integer value_type; + typedef Integer& reference; + typedef Integer* pointer; + typedef Distance difference_type; + + component_iterator() {} + component_iterator(IndexIterator x, Integer i) + : next(x), node(i) {} + Integer operator*() const { + return node; + } + self& operator++() { + node = next[node]; + return *this; + } + }; + + template + inline bool + operator==(const component_iterator& x, + const component_iterator& y) + { + return x.node == y.node; + } + + } // namespace detail + +} // namespace detail + +#if defined(__sgi) && !defined(__GNUC__) +#pragma reset woff 1234 +#endif + +#endif diff --git a/thirdparty/boost/graph/detail/edge.hpp b/thirdparty/boost/graph/detail/edge.hpp new file mode 100644 index 0000000..48274ec --- /dev/null +++ b/thirdparty/boost/graph/detail/edge.hpp @@ -0,0 +1,124 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_DETAIL_EDGE_HPP +#define BOOST_GRAPH_DETAIL_EDGE_HPP + +#if __GNUC__ < 3 +#include +#else +#include +#endif + +namespace boost { + + namespace detail { + + template + struct edge_base + { + inline edge_base() {} + inline edge_base(Vertex s, Vertex d) + : m_source(s), m_target(d) { } + Vertex m_source; + Vertex m_target; + }; + + template + class edge_desc_impl : public edge_base { + typedef edge_desc_impl self; + typedef edge_base Base; + public: + typedef void property_type; + + inline edge_desc_impl() : m_eproperty(0) {} + + inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug) + : Base(s,d), m_eproperty(const_cast(eplug)) { } + + property_type* get_property() { return m_eproperty; } + const property_type* get_property() const { return m_eproperty; } + + // protected: + property_type* m_eproperty; + }; + + template + inline bool + operator==(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return a.get_property() == b.get_property(); + } + template + inline bool + operator!=(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return ! (a.get_property() == b.get_property()); + } + + // Order edges according to the address of their property object + template + inline bool + operator<(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return a.get_property() < b.get_property(); + } + template + inline bool + operator<=(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return a.get_property() <= b.get_property(); + } + template + inline bool + operator>(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return a.get_property() > b.get_property(); + } + template + inline bool + operator>=(const detail::edge_desc_impl& a, + const detail::edge_desc_impl& b) + { + return a.get_property() >= b.get_property(); + } + + } //namespace detail + +} // namespace boost + +namespace std { + +#if __GNUC__ < 3 + template + std::ostream& + operator<<(std::ostream& os, const boost::detail::edge_desc_impl& e) + { + return os << "(" << e.m_source << "," << e.m_target << ")"; + } +#else + template + std::basic_ostream& + operator<<(std::basic_ostream& os, + const boost::detail::edge_desc_impl& e) + { + return os << "(" << e.m_source << "," << e.m_target << ")"; + } +#endif + +} + + +#endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP diff --git a/thirdparty/boost/graph/detail/incidence_iterator.hpp b/thirdparty/boost/graph/detail/incidence_iterator.hpp new file mode 100644 index 0000000..df73807 --- /dev/null +++ b/thirdparty/boost/graph/detail/incidence_iterator.hpp @@ -0,0 +1,79 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP +#define BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP + +#include +#include + +// OBSOLETE + +namespace boost { + + namespace detail { + // EdgeDir tags + struct in_edge_tag { }; + struct out_edge_tag { }; + + template + struct bidir_incidence_iterator { + typedef bidir_incidence_iterator self; + typedef Edge edge_type; + typedef typename Edge::property_type EdgeProperty; + public: + typedef int difference_type; + typedef std::forward_iterator_tag iterator_category; + typedef edge_type reference; + typedef edge_type value_type; + typedef value_type* pointer; + inline bidir_incidence_iterator() {} + inline bidir_incidence_iterator(Iterator1D ii, Vertex src) + : i(ii), _src(src) { } + + inline self& operator++() { ++i; return *this; } + inline self operator++(int) { self tmp = *this; ++(*this); return tmp; } + + inline reference operator*() const { + return deref_helper(EdgeDir()); + } + inline self* operator->() { return this; } + + Iterator1D& iter() { return i; } + const Iterator1D& iter() const { return i; } + + Iterator1D i; + Vertex _src; + protected: + inline reference deref_helper(out_edge_tag) const { + return edge_type( _src, (*i).get_target(), &(*i).get_property() ); + } + inline reference deref_helper(in_edge_tag) const { + return edge_type((*i).get_target(), _src, &(*i).get_property() ); + } + }; + + template + inline bool operator==(const bidir_incidence_iterator& x, + const bidir_incidence_iterator& y) + { + return x.i == y.i; + } + template + inline bool operator!=(const bidir_incidence_iterator& x, + const bidir_incidence_iterator& y) + { + return x.i != y.i; + } + + + } +} +#endif diff --git a/thirdparty/boost/graph/detail/incremental_components.hpp b/thirdparty/boost/graph/detail/incremental_components.hpp new file mode 100644 index 0000000..00c2119 --- /dev/null +++ b/thirdparty/boost/graph/detail/incremental_components.hpp @@ -0,0 +1,141 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP +#define BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP + +#include +#include + +namespace boost { + + namespace detail { + + //========================================================================= + // Implementation detail of incremental_components + + + //------------------------------------------------------------------------- + // Helper functions for the component_index class + + // Record the representative vertices in the header array. + // Representative vertices now point to the component number. + + template + inline void + build_components_header(Parent p, + OutputIterator header, + Integer num_nodes) + { + Parent component = p; + Integer component_num = 0; + for (Integer v = 0; v != num_nodes; ++v) + if (p[v] == v) { + *header++ = v; + component[v] = component_num++; + } + } + + + // Pushes x onto the front of the list. The list is represented in + // an array. + template + inline void array_push_front(Next next, T& head, V x) + { + T tmp = head; + head = x; + next[x] = tmp; + } + + + // Create a linked list of the vertices in each component + // by reusing the representative array. + template + void + link_components(Parent1 component, Parent2 header, + Integer num_nodes, Integer num_components) + { + // Make the non-representative vertices point to their component + Parent1 representative = component; + for (Integer v = 0; v != num_nodes; ++v) + if (component[v] >= num_components + || header[component[v]] != v) + component[v] = component[representative[v]]; + + // initialize the "head" of the lists to "NULL" + std::fill_n(header, num_components, num_nodes); + + // Add each vertex to the linked list for its component + Parent1 next = component; + for (Integer k = 0; k != num_nodes; ++k) + array_push_front(next, header[component[k]], k); + } + + + + template + void + construct_component_index(IndexContainer& index, HeaderContainer& header) + { + typedef typename IndexContainer::value_type Integer; + build_components_header(index.begin(), + std::back_inserter(header), + Integer(index.end() - index.begin())); + + link_components(index.begin(), header.begin(), + Integer(index.end() - index.begin()), + Integer(header.end() - header.begin())); + } + + + + template + class component_iterator + : boost::forward_iterator_helper< + component_iterator, + Integer, Distance,Integer*, Integer&> + { + public: + typedef component_iterator self; + + IndexIterator next; + Integer node; + + typedef std::forward_iterator_tag iterator_category; + typedef Integer value_type; + typedef Integer& reference; + typedef Integer* pointer; + typedef Distance difference_type; + + component_iterator() {} + component_iterator(IndexIterator x, Integer i) + : next(x), node(i) {} + Integer operator*() const { + return node; + } + self& operator++() { + node = next[node]; + return *this; + } + }; + + template + inline bool + operator==(const component_iterator& x, + const component_iterator& y) + { + return x.node == y.node; + } + + } // namespace detail + +} // namespace detail + +#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP diff --git a/thirdparty/boost/graph/detail/indexed_properties.hpp b/thirdparty/boost/graph/detail/indexed_properties.hpp new file mode 100644 index 0000000..53fcb14 --- /dev/null +++ b/thirdparty/boost/graph/detail/indexed_properties.hpp @@ -0,0 +1,180 @@ +// Copyright 2005 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine + +// Indexed properties -- used for CSR and CSR-like graphs + +#ifndef BOOST_GRAPH_INDEXED_PROPERTIES_HPP +#define BOOST_GRAPH_INDEXED_PROPERTIES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace detail { + +template +class indexed_vertex_properties +{ +public: + typedef no_property vertex_property_type; + typedef Property vertex_bundled; + + // Directly access a vertex or edge bundle + Property& operator[](Descriptor v) + { return m_vertex_properties[get(vertex_index, derived(), v)]; } + + const Property& operator[](Descriptor v) const + { return m_vertex_properties[get(vertex_index, derived(), v)]; } + +protected: + // Default-construct with no property values + indexed_vertex_properties() {} + + // Initialize with n default-constructed property values + indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) { } + +public: + // Resize the properties vector + void resize(std::size_t n) + { + m_vertex_properties.resize(n); + } + + // Reserve space in the vector of properties + void reserve(std::size_t n) + { + m_vertex_properties.reserve(n); + } + + // Add a new property value to the back + void push_back(const Property& prop) + { + m_vertex_properties.push_back(prop); + } + + // Access to the derived object + Derived& derived() { return *static_cast(this); } + + const Derived& derived() const + { return *static_cast(this); } + +public: // should be private, but friend templates not portable + std::vector m_vertex_properties; +}; + +template +class indexed_vertex_properties +{ + struct secret {}; + + public: + typedef no_property vertex_property_type; + typedef void vertex_bundled; + + secret operator[](secret) { return secret(); } + + protected: + // All operations do nothing. + indexed_vertex_properties() { } + indexed_vertex_properties(std::size_t) { } + +public: + void resize(std::size_t) { } + void reserve(std::size_t) { } +}; + +template +class indexed_edge_properties +{ +public: + typedef no_property edge_property_type; + typedef Property edge_bundled; + typedef Property edge_push_back_type; + + // Directly access a edge or edge bundle + Property& operator[](Descriptor v) + { return m_edge_properties[get(edge_index, derived(), v)]; } + + const Property& operator[](Descriptor v) const + { return m_edge_properties[get(edge_index, derived(), v)]; } + +protected: + // Default-construct with no property values + indexed_edge_properties() {} + + // Initialize with n default-constructed property values + indexed_edge_properties(std::size_t n) : m_edge_properties(n) { } + + // Resize the properties vector + void resize(std::size_t n) + { + m_edge_properties.resize(n); + } + + // Reserve space in the vector of properties + void reserve(std::size_t n) + { + m_edge_properties.reserve(n); + } + + public: + // Add a new property value to the back + void push_back(const Property& prop) + { + m_edge_properties.push_back(prop); + } + + private: + // Access to the derived object + Derived& derived() { return *static_cast(this); } + + const Derived& derived() const + { return *static_cast(this); } + +public: // should be private, but friend templates not portable + std::vector m_edge_properties; +}; + +template +class indexed_edge_properties +{ + struct secret {}; + + public: + typedef no_property edge_property_type; + typedef void edge_bundled; + typedef void* edge_push_back_type; + + secret operator[](secret) { return secret(); } + + protected: + // All operations do nothing. + indexed_edge_properties() { } + indexed_edge_properties(std::size_t) { } + void resize(std::size_t) { } + void reserve(std::size_t) { } + + public: + void push_back(const edge_push_back_type&) { } +}; + +} +} + +#endif // BOOST_GRAPH_INDEXED_PROPERTIES_HPP diff --git a/thirdparty/boost/graph/detail/is_same.hpp b/thirdparty/boost/graph/detail/is_same.hpp new file mode 100644 index 0000000..1212319 --- /dev/null +++ b/thirdparty/boost/graph/detail/is_same.hpp @@ -0,0 +1,40 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_DETAIL_IS_SAME_HPP +#define BOOST_GRAPH_DETAIL_IS_SAME_HPP + +#include + +namespace boost { + struct false_tag; + struct true_tag; + + namespace graph_detail { + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct is_same { + typedef boost::false_tag is_same_tag; + }; + template + struct is_same { + typedef boost::true_tag is_same_tag; + }; +#else + template + struct is_same { + enum { Unum = U::num, Vnum = V::num }; + typedef typename mpl::if_c< (Unum == Vnum), + boost::true_tag, boost::false_tag>::type is_same_tag; + }; +#endif + } // namespace graph_detail +} // namespace boost + +#endif diff --git a/thirdparty/boost/graph/detail/list_base.hpp b/thirdparty/boost/graph/detail/list_base.hpp new file mode 100644 index 0000000..7acd7d9 --- /dev/null +++ b/thirdparty/boost/graph/detail/list_base.hpp @@ -0,0 +1,220 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_LIST_BASE_HPP +#define BOOST_LIST_BASE_HPP + +#include + +// Perhaps this should go through formal review, and move to . + +/* + An alternate interface idea: + Extend the std::list functionality by creating remove/insert + functions that do not require the container object! + */ + +namespace boost { + namespace detail { + + //========================================================================= + // Linked-List Generic Implementation Functions + + template + inline Node + slist_insert_after(Node pos, Node x, + Next next) + { + next(x) = next(pos); + next(pos) = x; + return x; + } + + // return next(pos) or next(next(pos)) ? + template + inline Node + slist_remove_after(Node pos, + Next next) + { + Node n = next(pos); + next(pos) = next(n); + return n; + } + + template + inline Node + slist_remove_range(Node before_first, Node last, + Next next) + { + next(before_first) = last; + return last; + } + + template + inline Node + slist_previous(Node head, Node x, Node nil, + Next next) + { + while (head != nil && next(head) != x) + head = next(head); + return head; + } + + template + inline void + slist_splice_after(Node pos, Node before_first, Node before_last, + Next next) + { + if (pos != before_first && pos != before_last) { + Node first = next(before_first); + Node after = next(pos); + next(before_first) = next(before_last); + next(pos) = first; + next(before_last) = after; + } + } + + template + inline Node + slist_reverse(Node node, Node nil, + Next next) + { + Node result = node; + node = next(node); + next(result) = nil; + while(node) { + Node next = next(node); + next(node) = result; + result = node; + node = next; + } + return result; + } + + template + inline std::size_t + slist_size(Node head, Node nil, + Next next) + { + std::size_t s = 0; + for ( ; head != nil; head = next(head)) + ++s; + return s; + } + + template + class slist_iterator_policies + { + public: + explicit slist_iterator_policies(const Next& n, const Data& d) + : m_next(n), m_data(d) { } + + template + Reference dereference(type, const Node& x) const + { return m_data(x); } + + template + void increment(Node& x) const + { x = m_next(x); } + + template + bool equal(Node& x, Node& y) const + { return x == y; } + + protected: + Next m_next; + Data m_data; + }; + + //=========================================================================== + // Doubly-Linked List Generic Implementation Functions + + template + inline void + dlist_insert_before(Node pos, Node x, + Next next, Prev prev) + { + next(x) = pos; + prev(x) = prev(pos); + next(prev(pos)) = x; + prev(pos) = x; + } + + template + void + dlist_remove(Node pos, + Next next, Prev prev) + { + Node next_node = next(pos); + Node prev_node = prev(pos); + next(prev_node) = next_node; + prev(next_node) = prev_node; + } + + // This deletes every node in the list except the + // sentinel node. + template + inline void + dlist_clear(Node sentinel, Delete del) + { + Node i, tmp; + i = next(sentinel); + while (i != sentinel) { + tmp = i; + i = next(i); + del(tmp); + } + } + + template + inline bool + dlist_empty(Node dummy) + { + return next(dummy) == dummy; + } + + template + void + dlist_transfer(Node pos, Node first, Node last, + Next next, Prev prev) + { + if (pos != last) { + // Remove [first,last) from its old position + next(prev(last)) = pos; + next(prev(first)) = last; + next(prev(pos)) = first; + + // Splice [first,last) into its new position + Node tmp = prev(pos); + prev(pos) = prev(last); + prev(last) = prev(first); + prev(first) = tmp; + } + } + + template + class dlist_iterator_policies + : public slist_iterator_policies + { + typedef slist_iterator_policies Base; + public: + template + void decrement(Node& x) const + { x = m_prev(x); } + + dlist_iterator_policies(Next n, Prev p, Data d) + : Base(n,d), m_prev(p) { } + protected: + Prev m_prev; + }; + + } // namespace detail +} // namespace boost + +#endif // BOOST_LIST_BASE_HPP diff --git a/thirdparty/boost/graph/detail/permutation.hpp b/thirdparty/boost/graph/detail/permutation.hpp new file mode 100644 index 0000000..ab28848 --- /dev/null +++ b/thirdparty/boost/graph/detail/permutation.hpp @@ -0,0 +1,205 @@ +// (C) Copyright Jeremy Siek 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) + +#ifndef BOOST_PERMUTATION_HPP +#define BOOST_PERMUTATION_HPP + +#include +#include +#include +#include +#include + +namespace boost { + +template +void permute_serial(Iter1 permuter, Iter1 last, Iter2 result) +{ +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + typedef std::ptrdiff_t D: +#else + typedef typename std::iterator_traits::difference_type D; +#endif + + D n = 0; + while (permuter != last) { + std::swap(result[n], result[*permuter]); + ++n; + ++permuter; + } +} + +template +void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result) +{ +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + typedef std::ptrdiff_t i = 0; +#else + typename std::iterator_traits::difference_type i = 0; +#endif + for (; first != last; ++first, ++i) + result[p[i]] = *first; +} + +namespace detail { + +template +void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T) +{ + D i = 0, pi, n = last - first, cycle_start; + T tmp; + std::vector visited(n, false); + + while (i != n) { // continue until all elements have been processed + cycle_start = i; + tmp = first[i]; + do { // walk around a cycle + pi = p[i]; + visited[pi] = true; + std::swap(tmp, first[pi]); + i = pi; + } while (i != cycle_start); + + // find the next cycle + for (i = 0; i < n; ++i) + if (visited[i] == false) + break; + } +} + +} // namespace detail + +template +void permute(RandIter first, RandIter last, RandIterPerm p) +{ + detail::permute_helper(first, last, p, last - first, *first); +} + + +// Knuth 1.3.3, Vol. 1 p 176 +// modified for zero-based arrays +// time complexity? +// +// WARNING: T must be a signed integer! +template +void invert_permutation(PermIter X, PermIter Xend) +{ +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + typedef std::ptrdiff_t T: +#else + typedef typename std::iterator_traits::value_type T; +#endif + T n = Xend - X; + T m = n; + T j = -1; + + while (m > 0) { + T i = X[m-1] + 1; + if (i > 0) { + do { + X[m-1] = j - 1; + j = -m; + m = i; + i = X[m-1] + 1; + } while (i > 0); + i = j; + } + X[m-1] = -i - 1; + --m; + } +} + +// Takes a "normal" permutation array (and its inverse), and turns it +// into a BLAS-style permutation array (which can be thought of as a +// serialized permutation). +template +inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p) +{ +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + typedef std::ptrdiff_t P1; + typedef std::ptrdiff_t P2; + typedef std::ptrdiff_t D; +#else + typedef typename std::iterator_traits::value_type P1; + typedef typename std::iterator_traits::value_type P2; + typedef typename std::iterator_traits::difference_type D; +#endif + D n = q_end - q; + for (D i = 0; i < n; ++i) { + P1 qi = q[i]; + P2 qii = q_inv[i]; + *p++ = qii; + std::swap(q[i], q[qii]); + std::swap(q_inv[i], q_inv[qi]); + } +} + +// Not used anymore, leaving it here for future reference. +template +void merge_sort(Iter first, Iter last, Compare cmp) +{ + if (first + 1 < last) { + Iter mid = first + (last - first)/2; + merge_sort(first, mid, cmp); + merge_sort(mid, last, cmp); + std::inplace_merge(first, mid, last, cmp); + } +} + + +// time: N log N + 3N + ? +// space: 2N +template +inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) +{ + typedef typename std::iterator_traits::value_type P; + typedef typename std::iterator_traits::difference_type D; + D n = last - first; + std::vector q(n); + for (D i = 0; i < n; ++i) + q[i] = i; + std::sort(make_shadow_iter(first, q.begin()), + make_shadow_iter(last, q.end()), + shadow_cmp(cmp)); + invert_permutation(q.begin(), q.end()); + std::copy(q.begin(), q.end(), p); +} + +template +inline void sortp(Iter first, Iter last, IterP p, Cmp cmp) +{ + typedef typename std::iterator_traits::value_type P; + sortp(first, last, p, cmp, std::allocator

            ()); +} + +template +inline void sortp(Iter first, Iter last, IterP p) +{ + typedef typename std::iterator_traits::value_type T; + typedef typename std::iterator_traits::value_type P; + sortp(first, last, p, std::less(), std::allocator

            ()); +} + +template +inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) +{ + typedef typename std::iterator_traits::value_type P; + typedef typename std::iterator_traits::difference_type D; + D n = last - first; + std::vector q(n), q_inv(n); + for (D i = 0; i < n; ++i) + q_inv[i] = i; + std::sort(make_shadow_iter(first, q_inv.begin()), + make_shadow_iter(last, q_inv.end()), + shadow_cmp(cmp)); + std::copy(q_inv, q_inv.end(), q.begin()); + invert_permutation(q.begin(), q.end()); + serialize_permutation(q.begin(), q.end(), q_inv.end(), p); +} + + +} // namespace boost + +#endif // BOOST_PERMUTATION_HPP diff --git a/thirdparty/boost/graph/detail/read_graphviz_spirit.hpp b/thirdparty/boost/graph/detail/read_graphviz_spirit.hpp new file mode 100644 index 0000000..0a621d5 --- /dev/null +++ b/thirdparty/boost/graph/detail/read_graphviz_spirit.hpp @@ -0,0 +1,610 @@ +// Copyright 2004-5 Trustees of Indiana University + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// +// read_graphviz_spirit.hpp - +// Initialize a model of the BGL's MutableGraph concept and an associated +// collection of property maps using a graph expressed in the GraphViz +// DOT Language. +// +// Based on the grammar found at: +// http://www.graphviz.org/cvs/doc/info/lang.html +// +// See documentation for this code at: +// http://www.boost.org/libs/graph/doc/read-graphviz.html +// + +// Author: Ronald Garcia +// + +#ifndef BOOST_READ_GRAPHVIZ_SPIRIT_HPP +#define BOOST_READ_GRAPHVIZ_SPIRIT_HPP + +// Phoenix/Spirit set these limits to 3, but I need more. +#define PHOENIX_LIMIT 6 +#define BOOST_SPIRIT_CLOSURE_LIMIT 6 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for std::exception +#include +#include +#include +#include +#include +#include + +namespace phoenix { +// Workaround: std::map::operator[] uses a different return type than all +// other standard containers. Phoenix doesn't account for that. +template +struct binary_operator, T1> +{ + typedef typename std::map::mapped_type& result_type; + static result_type eval(std::map& container, T1 const& index) + { return container[index]; } +}; +} // namespace phoenix + +namespace boost { +namespace detail { +namespace graph { + + +///////////////////////////////////////////////////////////////////////////// +// Application-specific type definitions +///////////////////////////////////////////////////////////////////////////// + +typedef std::set edges_t; +typedef std::set nodes_t; +typedef std::set ids_t; +typedef std::map edge_map_t; +typedef std::map node_map_t; +typedef std::map props_t; +typedef std::map subgraph_props_t; +typedef boost::function2 actor_t; +typedef std::vector edge_stack_t; +typedef std::map subgraph_nodes_t; +typedef std::map subgraph_edges_t; + + + +///////////////////////////////////////////////////////////////////////////// +// Stack frames used by semantic actions +///////////////////////////////////////////////////////////////////////////// +struct id_closure : boost::spirit::closure { + member1 name; +}; + + +struct node_id_closure : boost::spirit::closure { + member1 name; +}; + +struct attr_list_closure : boost::spirit::closure { + member1 prop_actor; +}; + +struct property_closure : boost::spirit::closure { + member1 key; + member2 value; +}; + +struct data_stmt_closure : boost::spirit::closure { + member1 sources; + member2 dests; + member3 edge_stack; + member4 saw_node; + member5 active_node; +}; + +struct subgraph_closure : boost::spirit::closure { + member1 nodes; + member2 edges; + member3 name; +}; + +///////////////////////////////////////////////////////////////////////////// +// Grammar and Actions for the DOT Language +///////////////////////////////////////////////////////////////////////////// + +// Grammar for a dot file. +struct dot_grammar : public boost::spirit::grammar { + mutate_graph& graph_; + explicit dot_grammar(mutate_graph& graph) : graph_(graph) { } + + template + struct definition { + + definition(dot_grammar const& self) : self(self), subgraph_depth(0), + keyword_p("0-9a-zA-Z_") { + using namespace boost::spirit; + using namespace phoenix; + + // RG - Future Work + // - Handle multi-line strings using \ line continuation + // - Make keywords case insensitive + ID + = ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))] + | real_p + | lexeme_d[confix_p('"', *c_escape_ch_p, '"')] + | comment_nest_p('<', '>') + )[ID.name = construct_(arg1,arg2)] + ; + + a_list + = list_p( ID[(a_list.key = arg1), + (a_list.value = "true") + ] + >> !( ch_p('=') + >> ID[a_list.value = arg1]) + [phoenix::bind(&definition::call_prop_actor) + (var(*this),a_list.key,a_list.value)],!ch_p(',')); + + attr_list = +(ch_p('[') >> !a_list >> ch_p(']')); + + // RG - disregard port id's for now. + port_location + = (ch_p(':') >> ID) + | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')')) + ; + + port_angle = ch_p('@') >> ID; + + port + = port_location >> (!port_angle) + | port_angle >> (!port_location); + + + node_id + = ( ID[node_id.name = arg1] >> (!port) ) + [phoenix::bind(&definition::memoize_node)(var(*this))]; + + graph_stmt + = (ID[graph_stmt.key = arg1] >> + ch_p('=') >> + ID[graph_stmt.value = arg1]) + [phoenix::bind(&definition::call_graph_prop) + (var(*this),graph_stmt.key,graph_stmt.value)] + ; // Graph property. + + attr_stmt + = (as_lower_d[keyword_p("graph")] + >> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop) + (var(*this),arg1,arg2)))) + | (as_lower_d[keyword_p("node")] + >> attr_list(actor_t(phoenix::bind(&definition::default_node_prop) + (var(*this),arg1,arg2)))) + | (as_lower_d[keyword_p("edge")] + >> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop) + (var(*this),arg1,arg2)))) + ; + + // edge_head is set depending on the graph type (directed/undirected) + edgeop = ch_p('-') >> ch_p(boost::ref(edge_head)); + + edgeRHS + = +( edgeop[(data_stmt.sources = data_stmt.dests), + (data_stmt.dests = construct_())] + >> ( subgraph[data_stmt.dests = arg1] + | node_id[phoenix::bind(&definition::insert_node) + (var(*this),data_stmt.dests,arg1)] + ) + [phoenix::bind(&definition::activate_edge) + (var(*this),data_stmt.sources,data_stmt.dests, + var(edges), var(default_edge_props))] + ); + + + // To avoid backtracking, edge, node, and subgraph statements are + // processed as one nonterminal. + data_stmt + = ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs + (data_stmt.saw_node = false)] + | node_id[(phoenix::bind(&definition::insert_node) + (var(*this),data_stmt.dests,arg1)), + (data_stmt.saw_node = true), +#ifdef BOOST_GRAPH_DEBUG + (std::cout << val("AcTive Node: ") << arg1 << "\n"), +#endif // BOOST_GRAPH_DEBUG + (data_stmt.active_node = arg1)] + ) >> if_p(edgeRHS)[ + !attr_list( + actor_t(phoenix::bind(&definition::edge_prop) + (var(*this),arg1,arg2))) + ].else_p[ + if_p(data_stmt.saw_node)[ + !attr_list( + actor_t(phoenix::bind(&definition::node_prop) + (var(*this),arg1,arg2))) + ] // otherwise it's a subgraph, nothing more to do. + ]; + + + stmt + = graph_stmt + | attr_stmt + | data_stmt + ; + + stmt_list = *( stmt >> !ch_p(';') ); + + subgraph + = !( as_lower_d[keyword_p("subgraph")] + >> (!ID[(subgraph.name = arg1), + (subgraph.nodes = (var(subgraph_nodes))[arg1]), + (subgraph.edges = (var(subgraph_edges))[arg1])]) + ) + >> ch_p('{')[++var(subgraph_depth)] + >> stmt_list + >> ch_p('}')[--var(subgraph_depth)] + [(var(subgraph_nodes))[subgraph.name] = subgraph.nodes] + [(var(subgraph_edges))[subgraph.name] = subgraph.edges] + + | as_lower_d[keyword_p("subgraph")] + >> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]), + (subgraph.edges = (var(subgraph_edges))[arg1])] + ; + + the_grammar + = (!as_lower_d[keyword_p("strict")]) + >> ( as_lower_d[keyword_p("graph")][ + (var(edge_head) = '-'), + (phoenix::bind(&definition::check_undirected)(var(*this)))] + | as_lower_d[keyword_p("digraph")][ + (var(edge_head) = '>'), + (phoenix::bind(&definition::check_directed)(var(*this)))] + ) + >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}'); + + } // definition() + + typedef boost::spirit::rule rule_t; + + rule_t const& start() const { return the_grammar; } + + + // + // Semantic actions + // + + void check_undirected() { + if(self.graph_.is_directed()) + throw boost::undirected_graph_error(); + } + + void check_directed() { + if(!self.graph_.is_directed()) + throw boost::directed_graph_error(); + } + + void memoize_node() { + id_t const& node = node_id.name(); + props_t& node_props = default_node_props; + + if(nodes.find(node) == nodes.end()) { + nodes.insert(node); + self.graph_.do_add_vertex(node); + + node_map.insert(std::make_pair(node,ids_t())); + +#ifdef BOOST_GRAPH_DEBUG + std::cout << "Add new node " << node << std::endl; +#endif // BOOST_GRAPH_DEBUG + // Set the default properties for this edge + // RG: Here I would actually set the properties + for(props_t::iterator i = node_props.begin(); + i != node_props.end(); ++i) { + set_node_property(node,i->first,i->second); + } + if(subgraph_depth > 0) { + subgraph.nodes().insert(node); + // Set the subgraph's default properties as well + props_t& props = subgraph_node_props[subgraph.name()]; + for(props_t::iterator i = props.begin(); i != props.end(); ++i) { + set_node_property(node,i->first,i->second); + } + } + } else { +#ifdef BOOST_GRAPH_DEBUG + std::cout << "See node " << node << std::endl; +#endif // BOOST_GRAPH_DEBUG + } + } + + void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges, + props_t& edge_props) { + edge_stack_t& edge_stack = data_stmt.edge_stack(); + for(nodes_t::iterator i = sources.begin(); i != sources.end(); ++i) { + for(nodes_t::iterator j = dests.begin(); j != dests.end(); ++j) { + // Create the edge and push onto the edge stack. +#ifdef BOOST_GRAPH_DEBUG + std::cout << "Edge " << *i << " to " << *j << std::endl; +#endif // BOOST_GRAPH_DEBUG + + edge_t edge = edge_t::new_edge(); + edge_stack.push_back(edge); + edges.insert(edge); + edge_map.insert(std::make_pair(edge,ids_t())); + + // Add the real edge. + self.graph_.do_add_edge(edge, *i, *j); + + // Set the default properties for this edge + for(props_t::iterator k = edge_props.begin(); + k != edge_props.end(); ++k) { + set_edge_property(edge,k->first,k->second); + } + if(subgraph_depth > 0) { + subgraph.edges().insert(edge); + // Set the subgraph's default properties as well + props_t& props = subgraph_edge_props[subgraph.name()]; + for(props_t::iterator k = props.begin(); k != props.end(); ++k) { + set_edge_property(edge,k->first,k->second); + } + } + } + } + } + + // node_prop - Assign the property for the current active node. + void node_prop(id_t const& key, id_t const& value) { + node_t& active_object = data_stmt.active_node(); + set_node_property(active_object, key, value); + } + + // edge_prop - Assign the property for the current active edges. + void edge_prop(id_t const& key, id_t const& value) { + edge_stack_t const& active_edges_ = data_stmt.edge_stack(); + for (edge_stack_t::const_iterator i = active_edges_.begin(); + i != active_edges_.end(); ++i) { + set_edge_property(*i,key,value); + } + } + + // default_graph_prop - Store as a graph property. + void default_graph_prop(id_t const& key, id_t const& value) { +#ifdef BOOST_GRAPH_DEBUG + std::cout << key << " = " << value << std::endl; +#endif // BOOST_GRAPH_DEBUG + self.graph_.set_graph_property(key, value); + } + + // default_node_prop - declare default properties for any future new nodes + void default_node_prop(id_t const& key, id_t const& value) { + nodes_t& nodes_ = + subgraph_depth == 0 ? nodes : subgraph.nodes(); + props_t& node_props_ = + subgraph_depth == 0 ? + default_node_props : + subgraph_node_props[subgraph.name()]; + + // add this to the selected list of default node properties. + node_props_[key] = value; + // for each node, set its property to default-constructed value + // if it hasn't been set already. + // set the dynamic property map value + for(nodes_t::iterator i = nodes_.begin(); i != nodes_.end(); ++i) + if(node_map[*i].find(key) == node_map[*i].end()) { + set_node_property(*i,key,id_t()); + } + } + + // default_edge_prop - declare default properties for any future new edges + void default_edge_prop(id_t const& key, id_t const& value) { + edges_t& edges_ = + subgraph_depth == 0 ? edges : subgraph.edges(); + props_t& edge_props_ = + subgraph_depth == 0 ? + default_edge_props : + subgraph_edge_props[subgraph.name()]; + + // add this to the list of default edge properties. + edge_props_[key] = value; + // for each edge, set its property to be empty string + // set the dynamic property map value + for(edges_t::iterator i = edges_.begin(); i != edges_.end(); ++i) + if(edge_map[*i].find(key) == edge_map[*i].end()) + set_edge_property(*i,key,id_t()); + } + + // helper function + void insert_node(nodes_t& nodes, id_t const& name) { + nodes.insert(name); + } + + void call_prop_actor(std::string const& lhs, std::string const& rhs) { + actor_t& actor = attr_list.prop_actor(); + // If first and last characters of the rhs are double-quotes, + // remove them. + if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"') + actor(lhs, rhs.substr(1, rhs.size()-2)); + else + actor(lhs,rhs); + } + + void call_graph_prop(std::string const& lhs, std::string const& rhs) { + // If first and last characters of the rhs are double-quotes, + // remove them. + if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"') + this->default_graph_prop(lhs, rhs.substr(1, rhs.size()-2)); + else + this->default_graph_prop(lhs,rhs); + } + + void set_node_property(node_t const& node, id_t const& key, + id_t const& value) { + + // Add the property key to the "set" table to avoid default overwrite + node_map[node].insert(key); + // Set the user's property map + self.graph_.set_node_property(key, node, value); +#ifdef BOOST_GRAPH_DEBUG + // Tell the world + std::cout << node << ": " << key << " = " << value << std::endl; +#endif // BOOST_GRAPH_DEBUG + } + + void set_edge_property(edge_t const& edge, id_t const& key, + id_t const& value) { + + // Add the property key to the "set" table to avoid default overwrite + edge_map[edge].insert(key); + // Set the user's property map + self.graph_.set_edge_property(key, edge, value); +#ifdef BOOST_GRAPH_DEBUG + // Tell the world +#if 0 // RG - edge representation changed, + std::cout << "(" << edge.first << "," << edge.second << "): " +#else + std::cout << "an edge: " +#endif // 0 + << key << " = " << value << std::endl; +#endif // BOOST_GRAPH_DEBUG + } + + // Variables explicitly initialized + dot_grammar const& self; + // if subgraph_depth > 0, then we're processing a subgraph. + int subgraph_depth; + + // Keywords; + const boost::spirit::distinct_parser<> keyword_p; + // + // rules that make up the grammar + // + boost::spirit::rule ID; + boost::spirit::rule a_list; + boost::spirit::rule attr_list; + rule_t port_location; + rule_t port_angle; + rule_t port; + boost::spirit::rule node_id; + boost::spirit::rule graph_stmt; + rule_t attr_stmt; + boost::spirit::rule data_stmt; + boost::spirit::rule subgraph; + rule_t edgeop; + rule_t edgeRHS; + rule_t stmt; + rule_t stmt_list; + rule_t the_grammar; + + + // The grammar uses edge_head to dynamically set the syntax for edges + // directed graphs: edge_head = '>', and so edgeop = "->" + // undirected graphs: edge_head = '-', and so edgeop = "--" + char edge_head; + + + // + // Support data structures + // + + nodes_t nodes; // list of node names seen + edges_t edges; // list of edges seen + node_map_t node_map; // remember the properties set for each node + edge_map_t edge_map; // remember the properties set for each edge + + subgraph_nodes_t subgraph_nodes; // per-subgraph lists of nodes + subgraph_edges_t subgraph_edges; // per-subgraph lists of edges + + props_t default_node_props; // global default node properties + props_t default_edge_props; // global default edge properties + subgraph_props_t subgraph_node_props; // per-subgraph default node properties + subgraph_props_t subgraph_edge_props; // per-subgraph default edge properties + }; // struct definition +}; // struct dot_grammar + + + +// +// dot_skipper - GraphViz whitespace and comment skipper +// +struct dot_skipper : public boost::spirit::grammar +{ + dot_skipper() {} + + template + struct definition + { + definition(dot_skipper const& /*self*/) { + using namespace boost::spirit; + using namespace phoenix; + // comment forms + skip = eol_p >> comment_p("#") + | space_p + | comment_p("//") +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) + | confix_p(str_p("/*") ,*anychar_p, str_p("*/")) +#else + | confix_p("/*" ,*anychar_p, "*/") +#endif + ; + +#ifdef BOOST_SPIRIT_DEBUG + BOOST_SPIRIT_DEBUG_RULE(skip); +#endif + } + + boost::spirit::rule skip; + boost::spirit::rule const& + start() const { return skip; } + }; // definition +}; // dot_skipper + +} // namespace graph +} // namespace detail + +template +bool read_graphviz(MultiPassIterator begin, MultiPassIterator end, + MutableGraph& graph, dynamic_properties& dp, + std::string const& node_id = "node_id") { + using namespace boost; + using namespace boost::spirit; + + typedef MultiPassIterator iterator_t; + typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper> + iter_policy_t; + typedef scanner_policies scanner_policies_t; + typedef scanner scanner_t; + + ::boost::detail::graph::mutate_graph_impl + m_graph(graph, dp, node_id); + + ::boost::detail::graph::dot_grammar p(m_graph); + ::boost::detail::graph::dot_skipper skip_p; + + iter_policy_t iter_policy(skip_p); + scanner_policies_t policies(iter_policy); + + scanner_t scan(begin, end, policies); + + return p.parse(scan); +} + +} // namespace boost + +#endif // BOOST_READ_GRAPHVIZ_SPIRIT_HPP diff --git a/thirdparty/boost/graph/detail/self_avoiding_walk.hpp b/thirdparty/boost/graph/detail/self_avoiding_walk.hpp new file mode 100644 index 0000000..1ecb904 --- /dev/null +++ b/thirdparty/boost/graph/detail/self_avoiding_walk.hpp @@ -0,0 +1,418 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_SELF_AVOIDING_WALK_HPP +#define BOOST_SELF_AVOIDING_WALK_HPP + +/* + This file defines necessary components for SAW. + + mesh language: (defined by myself to clearify what is what) + A triangle in mesh is called an triangle. + An edge in mesh is called an line. + A vertex in mesh is called a point. + + A triangular mesh corresponds to a graph in which a vertex is a + triangle and an edge(u, v) stands for triangle u and triangle v + share an line. + + After this point, a vertex always refers to vertex in graph, + therefore it is a traingle in mesh. + + */ + +#include +#include +#include +#include + +#define SAW_SENTINAL -1 + +namespace boost { + + template + struct triple { + T1 first; + T2 second; + T3 third; + triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {} + triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {} + }; + + typedef triple Triple; + + /* Define a vertex property which has a triangle inside. Triangle is + represented by a triple. */ + struct triangle_tag { enum { num = 100 }; }; + typedef property triangle_property; + + /* Define an edge property with a line. A line is represented by a + pair. This is not required for SAW though. + */ + struct line_tag { enum { num = 101 }; }; + template struct line_property + : public property > { }; + + /*Precondition: Points in a Triangle are in order */ + template + inline void get_sharing(const Triangle& a, const Triangle& b, Line& l) + { + l.first = SAW_SENTINAL; + l.second = SAW_SENTINAL; + + if ( a.first == b.first ) { + l.first = a.first; + if ( a.second == b.second || a.second == b.third ) + l.second = a.second; + else if ( a.third == b.second || a.third == b.third ) + l.second = a.third; + + } else if ( a.first == b.second ) { + l.first = a.first; + if ( a.second == b.third ) + l.second = a.second; + else if ( a.third == b.third ) + l.second = a.third; + + } else if ( a.first == b.third ) { + l.first = a.first; + + + } else if ( a.second == b.first ) { + l.first = a.second; + if ( a.third == b.second || a.third == b.third ) + l.second = a.third; + + } else if ( a.second == b.second ) { + l.first = a.second; + if ( a.third == b.third ) + l.second = a.third; + + } else if ( a.second == b.third ) { + l.first = a.second; + + + } else if ( a.third == b.first + || a.third == b.second + || a.third == b.third ) + l.first = a.third; + + /*Make it in order*/ + if ( l.first > l.second ) { + typename Line::first_type i = l.first; + l.first = l.second; + l.second = i; + } + + } + + template + struct get_vertex_sharing { + typedef std::pair Pair; + get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {} + inline Line operator()(const Vertex& u, const Vertex& v) const { + Line l; + get_sharing(td[u], td[v], l); + return l; + } + inline Line operator()(const Pair& u, const Vertex& v) const { + Line l; + get_sharing(td[u.first], td[v], l); + return l; + } + inline Line operator()(const Pair& u, const Pair& v) const { + Line l; + get_sharing(td[u.first], td[v.first], l); + return l; + } + TriangleDecorator td; + }; + + /* HList has to be a handle of data holder so that pass-by-value is + * in right logic. + * + * The element of HList is a pair of vertex and line. (remember a + * line is a pair of two ints.). That indicates the walk w from + * current vertex is across line. (If the first of line is -1, it is + * a point though. + */ + template < class TriangleDecorator, class HList, class IteratorD> + class SAW_visitor + : public bfs_visitor<>, public dfs_visitor<> + { + typedef typename boost::property_traits::value_type iter; + /*use boost shared_ptr*/ + typedef typename HList::element_type::value_type::second_type Line; + public: + + typedef tree_edge_tag category; + + inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia) + : td(_td), hlist(_hlist), iter_d(ia) {} + + template + inline void start_vertex(Vertex v, Graph&) { + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + hlist->push_front(std::make_pair(v, l1)); + iter_d[v] = hlist->begin(); + } + + /*Several symbols: + w(i): i-th triangle in walk w + w(i) |- w(i+1): w enter w(i+1) from w(i) over a line + w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point + w(i) -> w(i+1): w enter w(i+1) from w(i) + w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1) + */ + template + bool tree_edge(Edge e, Graph& G) { + using std::make_pair; + typedef typename boost::graph_traits::vertex_descriptor Vertex; + Vertex tau = target(e, G); + Vertex i = source(e, G); + + get_vertex_sharing get_sharing_line(td); + + Line tau_i = get_sharing_line(tau, i); + + iter w_end = hlist->end(); + + iter w_i = iter_d[i]; + + iter w_i_m_1 = w_i; + iter w_i_p_1 = w_i; + + /*---------------------------------------------------------- + * true false + *========================================================== + *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null + *---------------------------------------------------------- + *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet + *---------------------------------------------------------- + */ + + bool a = false, b = false; + + --w_i_m_1; + ++w_i_p_1; + b = ( w_i->second.first != SAW_SENTINAL ); + + if ( w_i_m_1 != w_end ) { + a = ( w_i_m_1->second.first != SAW_SENTINAL ); + } + + if ( a ) { + + if ( b ) { + /*Case 1: + + w(i-1) |- w(i) |- w(i+1) + */ + Line l1 = get_sharing_line(*w_i_m_1, tau); + + iter w_i_m_2 = w_i_m_1; + --w_i_m_2; + + bool c = true; + + if ( w_i_m_2 != w_end ) { + c = w_i_m_2->second != l1; + } + + if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */ + /*extension: w(i-1) -> tau |- w(i) */ + w_i_m_1->second = l1; + /*insert(pos, const T&) is to insert before pos*/ + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + + } else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */ + /*must be w(i-2) ~> w(i-1) */ + + bool d = true; + //need to handle the case when w_i_p_1 is null + Line l3 = get_sharing_line(*w_i_p_1, tau); + if ( w_i_p_1 != w_end ) + d = w_i_p_1->second != l3; + if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3)); + } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */ + /*must be w(1+1) ~> w(i+2) */ + Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1); + if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */ + /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */ + w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + w_i->second = w_i_m_1->second; + w_i_m_1->second = l5; + iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1); + hlist->erase(w_i_m_1); + } else { + /*mesh is tetrahedral*/ + // dont know what that means. + ; + } + } + + } + } else { + /*Case 2: + + w(i-1) |- w(i) ~> w(1+1) + */ + + if ( w_i->second.second == tau_i.first + || w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + Line l1 = get_sharing_line(*w_i_p_1, tau); + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/ + Line l1 = get_sharing_line(*w_i_m_1, tau); + bool c = true; + iter w_i_m_2 = w_i_m_1; + --w_i_m_2; + if ( w_i_m_2 != w_end ) + c = l1 != w_i_m_2->second; + if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/ + /*extension: w(i-1) -> tau |- w(i)*/ + w_i_m_1->second = l1; + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/ + /*must be w(i-2)~>w(i-1)*/ + /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/ + w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + w_i->second = w_i_m_1->second; + w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1); + iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1); + hlist->erase(w_i_m_1); + } + + } + + } + + } else { + + if ( b ) { + /*Case 3: + + w(i-1) ~> w(i) |- w(i+1) + */ + bool c = false; + if ( w_i_m_1 != w_end ) + c = ( w_i_m_1->second.second == tau_i.first) + || ( w_i_m_1->second.second == tau_i.second); + + if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/ + /* extension: w(i-1) -> tau |- w(i) */ + if ( w_i_m_1 != w_end ) + w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } else { + bool d = true; + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + if ( w_i_p_1 != w_end ) { + l1 = get_sharing_line(*w_i_p_1, tau); + d = l1 != w_i_p_1->second; + } + if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } else { + /*must be w(i+1) ~> w(i+2)*/ + /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */ + iter w_i_p_2 = w_i_p_1; + ++w_i_p_2; + + w_i_p_1->second = w_i->second; + iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i)); + hlist->erase(w_i); + Line l2 = get_sharing_line(*w_i_p_2, tau); + iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2)); + } + } + + } else { + /*Case 4: + + w(i-1) ~> w(i) ~> w(i+1) + + */ + bool c = false; + if ( w_i_m_1 != w_end ) { + c = (w_i_m_1->second.second == tau_i.first) + || (w_i_m_1->second.second == tau_i.second); + } + if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */ + /*extension: w(i-1) -> tau |- w(i) */ + if ( w_i_m_1 != w_end ) + w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } else { + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + if ( w_i_p_1 != w_end ) + l1 = get_sharing_line(*w_i_p_1, tau); + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } + } + + } + + return true; + } + + protected: + TriangleDecorator td; /*a decorator for vertex*/ + HList hlist; + /*This must be a handle of list to record the SAW + The element type of the list is pair + */ + + IteratorD iter_d; + /*Problem statement: Need a fast access to w for triangle i. + *Possible solution: mantain an array to record. + iter_d[i] will return an iterator + which points to w(i), where i is a vertex + representing triangle i. + */ + }; + + template + inline + SAW_visitor + visit_SAW(Triangle t, HList hl, Iterator i) { + return SAW_visitor(t, hl, i); + } + + template + inline + SAW_visitor< random_access_iterator_property_map, + HList, random_access_iterator_property_map > + visit_SAW_ptr(Tri* t, HList hl, Iter* i) { + typedef random_access_iterator_property_map TriD; + typedef random_access_iterator_property_map IterD; + return SAW_visitor(t, hl, i); + } + + // should also have combo's of pointers, and also const :( + +} + +#endif /*BOOST_SAW_H*/ diff --git a/thirdparty/boost/graph/detail/set_adaptor.hpp b/thirdparty/boost/graph/detail/set_adaptor.hpp new file mode 100644 index 0000000..403593d --- /dev/null +++ b/thirdparty/boost/graph/detail/set_adaptor.hpp @@ -0,0 +1,117 @@ +// (C) Copyright Jeremy Siek 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) + +#ifndef BOOST_SET_ADAPTOR_HPP +#define BOOST_SET_ADAPTOR_HPP + +#include + +namespace boost { + + template + bool set_contains(const std::set& s, const T& x) { + return s.find(x) != s.end(); + } + + template + bool set_equal(const std::set& x, + const std::set& y) + { + return x == y; + } + + // Not the same as lexicographical_compare_3way applied to std::set. + // this is equivalent semantically to bitset::operator<() + template + int set_lex_order(const std::set& x, + const std::set& y) + { + typename std::set::iterator + xi = x.begin(), yi = y.begin(), xend = x.end(), yend = y.end(); + for (; xi != xend && yi != yend; ++xi, ++yi) { + if (*xi < *yi) + return 1; + else if (*yi < *xi) + return -1; + } + if (xi == xend) + return (yi == yend) ? 0 : -1; + else + return 1; + } + + template + void set_clear(std::set& x) { + x.clear(); + } + + template + bool set_empty(const std::set& x) { + return x.empty(); + } + + template + void set_insert(std::set& x, const T& a) { + x.insert(a); + } + + template + void set_remove(std::set& x, const T& a) { + x.erase(a); + } + + template + void set_intersect(const std::set& x, + const std::set& y, + std::set& z) + { + z.clear(); + std::set_intersection(x.begin(), x.end(), + y.begin(), y.end(), + std::inserter(z)); + } + + template + void set_union(const std::set& x, + const std::set& y, + std::set& z) + { + z.clear(); + std::set_union(x.begin(), x.end(), + y.begin(), y.end(), + std::inserter(z)); + } + + template + void set_difference(const std::set& x, + const std::set& y, + std::set& z) + { + z.clear(); + std::set_difference(x.begin(), x.end(), + y.begin(), y.end(), + std::inserter(z, z.begin())); + } + + template + bool set_subset(const std::set& x, + const std::set& y) + { + return std::includes(x.begin(), x.end(), y.begin(), y.end()); + } + + // Shit, can't implement this without knowing the size of the + // universe. + template + void set_compliment(const std::set& x, + std::set& z) + { + z.clear(); + + } + +} // namespace boost + +#endif // BOOST_SET_ADAPTOR_HPP diff --git a/thirdparty/boost/graph/detail/shadow_iterator.hpp b/thirdparty/boost/graph/detail/shadow_iterator.hpp new file mode 100644 index 0000000..4ad2da3 --- /dev/null +++ b/thirdparty/boost/graph/detail/shadow_iterator.hpp @@ -0,0 +1,139 @@ +// (C) Copyright Jeremy Siek 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) + +#ifndef BOOST_SHADOW_ITERATOR_HPP +#define BOOST_SHADOW_ITERATOR_HPP + +#include +#include + +namespace boost { + + namespace detail { + + template + class shadow_proxy + : boost::operators< shadow_proxy > + { + typedef shadow_proxy self; + public: + inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { } + inline shadow_proxy(const self& x) : a(x.a), b(x.b) { } + template + inline shadow_proxy(Self x) : a(x.a), b(x.b) { } + inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; } + inline self& operator++() { ++a; return *this; } + inline self& operator--() { --a; return *this; } + inline self& operator+=(const self& x) { a += x.a; return *this; } + inline self& operator-=(const self& x) { a -= x.a; return *this; } + inline self& operator*=(const self& x) { a *= x.a; return *this; } + inline self& operator/=(const self& x) { a /= x.a; return *this; } + inline self& operator%=(const self& x) { return *this; } // JGS + inline self& operator&=(const self& x) { return *this; } // JGS + inline self& operator|=(const self& x) { return *this; } // JGS + inline self& operator^=(const self& x) { return *this; } // JGS + inline friend D operator-(const self& x, const self& y) { + return x.a - y.a; + } + inline bool operator==(const self& x) const { return a == x.a; } + inline bool operator<(const self& x) const { return a < x.a; } + // protected: + A a; + B b; + }; + + struct shadow_iterator_policies + { + template + void initialize(const iter_pair&) { } + + template + typename Iter::reference dereference(const Iter& i) const { + typedef typename Iter::reference R; + return R(*i.base().first, *i.base().second); + } + template + bool equal(const Iter& p1, const Iter& p2) const { + return p1.base().first == p2.base().first; + } + template + void increment(Iter& i) { ++i.base().first; ++i.base().second; } + + template + void decrement(Iter& i) { --i.base().first; --i.base().second; } + + template + bool less(const Iter& x, const Iter& y) const { + return x.base().first < y.base().first; + } + template + typename Iter::difference_type + distance(const Iter& x, const Iter& y) const { + return y.base().first - x.base().first; + } + template + void advance(Iter& p, D n) { p.base().first += n; p.base().second += n; } + }; + + } // namespace detail + + template + struct shadow_iterator_generator { + + // To use the iterator_adaptor we can't derive from + // random_access_iterator because we don't have a real reference. + // However, we want the STL algorithms to treat the shadow + // iterator like a random access iterator. + struct shadow_iterator_tag : public std::input_iterator_tag { + operator std::random_access_iterator_tag() { + return std::random_access_iterator_tag(); + }; + }; + typedef typename std::iterator_traits::value_type Aval; + typedef typename std::iterator_traits::value_type Bval; + typedef typename std::iterator_traits::reference Aref; + typedef typename std::iterator_traits::reference Bref; + typedef typename std::iterator_traits::difference_type D; + typedef detail::shadow_proxy V; + typedef detail::shadow_proxy R; + typedef iterator_adaptor< std::pair, + detail::shadow_iterator_policies, + V, R, V*, shadow_iterator_tag, + D> type; + }; + + // short cut for creating a shadow iterator + template + inline typename shadow_iterator_generator::type + make_shadow_iter(IterA a, IterB b) { + typedef typename shadow_iterator_generator::type Iter; + return Iter(std::make_pair(a,b)); + } + + template + struct shadow_cmp { + inline shadow_cmp(const Cmp& c) : cmp(c) { } + template + inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const + { + return cmp(x.a, y.a); + } + Cmp cmp; + }; + +} // namespace boost + +namespace std { + template + void swap(boost::detail::shadow_proxy x, + boost::detail::shadow_proxy y) + { + std::swap(x.a, y.a); + std::swap(x.b, y.b); + } +} + +#endif // BOOST_SHADOW_ITERATOR_HPP diff --git a/thirdparty/boost/graph/detail/sparse_ordering.hpp b/thirdparty/boost/graph/detail/sparse_ordering.hpp new file mode 100644 index 0000000..a9c99bc --- /dev/null +++ b/thirdparty/boost/graph/detail/sparse_ordering.hpp @@ -0,0 +1,198 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2004, 2005 Trustees of Indiana University +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, +// Doug Gregor, D. Kevin McGrath +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//=======================================================================// +#ifndef BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP +#define BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + namespace sparse { + + // rcm_queue + // + // This is a custom queue type used in the + // *_ordering algorithms. + // In addition to the normal queue operations, the + // rcm_queue provides: + // + // int eccentricity() const; + // value_type spouse() const; + // + + // yes, it's a bad name...but it works, so use it + template < class Vertex, class DegreeMap, + class Container = std::deque > + class rcm_queue : public std::queue { + typedef std::queue base; + public: + typedef typename base::value_type value_type; + typedef typename base::size_type size_type; + + /* SGI queue has not had a contructor queue(const Container&) */ + inline rcm_queue(DegreeMap deg) + : _size(0), Qsize(1), eccen(-1), degree(deg) { } + + inline void pop() { + if ( !_size ) + Qsize = base::size(); + + base::pop(); + if ( _size == Qsize-1 ) { + _size = 0; + ++eccen; + } else + ++_size; + + } + + inline value_type& front() { + value_type& u = base::front(); + if ( _size == 0 ) + w = u; + else if (get(degree,u) < get(degree,w) ) + w = u; + return u; + } + + inline const value_type& front() const { + const value_type& u = base::front(); + if ( _size == 0 ) + w = u; + else if (get(degree,u) < get(degree,w) ) + w = u; + return u; + } + + inline value_type& top() { return front(); } + inline const value_type& top() const { return front(); } + + inline size_type size() const { return base::size(); } + + inline size_type eccentricity() const { return eccen; } + inline value_type spouse() const { return w; } + + protected: + size_type _size; + size_type Qsize; + int eccen; + mutable value_type w; + DegreeMap degree; + }; + + + template > + class sparse_ordering_queue : public boost::queue{ + public: + typedef typename Sequence::iterator iterator; + typedef typename Sequence::reverse_iterator reverse_iterator; + typedef queue base; + typedef typename Sequence::size_type size_type; + + inline iterator begin() { return this->c.begin(); } + inline reverse_iterator rbegin() { return this->c.rbegin(); } + inline iterator end() { return this->c.end(); } + inline reverse_iterator rend() { return this->c.rend(); } + inline Tp &operator[](int n) { return this->c[n]; } + inline size_type size() {return this->c.size(); } + protected: + //nothing + }; + + } // namespace sparse + + // Compute Pseudo peripheral + // + // To compute an approximated peripheral for a given vertex. + // Used in king_ordering algorithm. + // + template + Vertex + pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc, + ColorMap color, DegreeMap degree) + { + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + sparse::rcm_queue Q(degree); + + typename boost::graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + if (get(color, *ui) != Color::red()) put(color, *ui, Color::white()); + breadth_first_visit(G, u, buffer(Q).color_map(color)); + + ecc = Q.eccentricity(); + return Q.spouse(); + } + + // Find a good starting node + // + // This is to find a good starting node for the + // king_ordering algorithm. "good" is in the sense + // of the ordering generated by RCM. + // + template + Vertex find_starting_node(Graph& G, Vertex r, Color color, Degree degree) + { + Vertex x, y; + int eccen_r, eccen_x; + + x = pseudo_peripheral_pair(G, r, eccen_r, color, degree); + y = pseudo_peripheral_pair(G, x, eccen_x, color, degree); + + while (eccen_x > eccen_r) { + r = x; + eccen_r = eccen_x; + x = y; + y = pseudo_peripheral_pair(G, x, eccen_x, color, degree); + } + return x; + } + +template +class out_degree_property_map + : public put_get_helper::degree_size_type, + out_degree_property_map > +{ +public: + typedef typename graph_traits::vertex_descriptor key_type; + typedef typename graph_traits::degree_size_type value_type; + typedef value_type reference; + typedef readable_property_map_tag category; + out_degree_property_map(const Graph& g) : m_g(g) { } + value_type operator[](const key_type& v) const { + return out_degree(v, m_g); + } +private: + const Graph& m_g; +}; +template +inline out_degree_property_map +make_out_degree_map(const Graph& g) { + return out_degree_property_map(g); +} + +} // namespace boost + + +#endif // BOOST_GRAPH_KING_HPP diff --git a/thirdparty/boost/graph/dijkstra_shortest_paths.hpp b/thirdparty/boost/graph/dijkstra_shortest_paths.hpp new file mode 100644 index 0000000..5f0adba --- /dev/null +++ b/thirdparty/boost/graph/dijkstra_shortest_paths.hpp @@ -0,0 +1,347 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_DIJKSTRA_HPP +#define BOOST_GRAPH_DIJKSTRA_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING +# include +#endif // BOOST_GRAPH_DIJKSTRA_TESTING + +namespace boost { + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + static bool dijkstra_relaxed_heap = true; +#endif + + template + struct DijkstraVisitorConcept { + void constraints() { + function_requires< CopyConstructibleConcept >(); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.finish_vertex(u, g); + } + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + template + class dijkstra_visitor : public bfs_visitor { + public: + dijkstra_visitor() { } + dijkstra_visitor(Visitors vis) + : bfs_visitor(vis) { } + + template + void edge_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); + } + template + void edge_not_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + } + private: + template + void tree_edge(Edge u, Graph& g) { } + }; + template + dijkstra_visitor + make_dijkstra_visitor(Visitors vis) { + return dijkstra_visitor(vis); + } + typedef dijkstra_visitor<> default_dijkstra_visitor; + + namespace detail { + + template + struct dijkstra_bfs_visitor + { + typedef typename property_traits::value_type D; + + dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q, + WeightMap w, PredecessorMap p, DistanceMap d, + BinaryFunction combine, BinaryPredicate compare, + D zero) + : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d), + m_combine(combine), m_compare(compare), m_zero(zero) { } + + template + void tree_edge(Edge e, Graph& g) { + m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + if (m_decreased) + m_vis.edge_relaxed(e, g); + else + m_vis.edge_not_relaxed(e, g); + } + template + void gray_target(Edge e, Graph& g) { + m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + if (m_decreased) { + m_Q.update(target(e, g)); + m_vis.edge_relaxed(e, g); + } else + m_vis.edge_not_relaxed(e, g); + } + + template + void initialize_vertex(Vertex u, Graph& g) { } + template + void non_tree_edge(Edge, Graph&) { } + template + void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); } + template + void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); } + template + void examine_edge(Edge e, Graph& g) { + if (m_compare(get(m_weight, e), m_zero)) + throw negative_edge(); + m_vis.examine_edge(e, g); + } + template + void black_target(Edge, Graph&) { } + template + void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); } + + UniformCostVisitor m_vis; + UpdatableQueue& m_Q; + WeightMap m_weight; + PredecessorMap m_predecessor; + DistanceMap m_distance; + BinaryFunction m_combine; + BinaryPredicate m_compare; + bool m_decreased; + D m_zero; + }; + + } // namespace detail + + // Call breadth first search with default color map. + template + inline void + dijkstra_shortest_paths_no_init + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis) + { + std::vector color(num_vertices(g)); + default_color_type c = white_color; + dijkstra_shortest_paths_no_init( g, s, predecessor, distance, weight, + index_map, compare, combine, zero, vis, + make_iterator_property_map(&color[0], index_map, c)); + } + + // Call breadth first search + template + inline void + dijkstra_shortest_paths_no_init + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + typedef indirect_cmp IndirectCmp; + IndirectCmp icmp(distance, compare); + + typedef typename graph_traits::vertex_descriptor Vertex; + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + if (!dijkstra_relaxed_heap) { + typedef mutable_queue, IndirectCmp, IndexMap> + MutableQueue; + + MutableQueue Q(num_vertices(g), icmp, index_map); + + detail::dijkstra_bfs_visitor + bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); + + breadth_first_visit(g, s, Q, bfs_vis, color); + return; + } +#endif // BOOST_GRAPH_DIJKSTRA_TESTING + + typedef relaxed_heap MutableQueue; + + MutableQueue Q(num_vertices(g), icmp, index_map); + + detail::dijkstra_bfs_visitor + bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); + + breadth_first_visit(g, s, Q, bfs_vis, color); + } + + // Initialize distances and call breadth first search with default color map + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis) + { + std::vector color(num_vertices(g)); + default_color_type c = white_color; + dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map, + compare, combine, inf, zero, vis, + make_iterator_property_map(&color[0], index_map, + c)); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + vis.initialize_vertex(*ui, g); + put(distance, *ui, inf); + put(predecessor, *ui, *ui); + put(color, *ui, Color::white()); + } + put(distance, s, zero); + + dijkstra_shortest_paths_no_init(g, s, predecessor, distance, weight, + index_map, compare, combine, zero, vis, color); + } + + namespace detail { + + // Handle defaults for PredecessorMap and + // Distance Compare, Combine, Inf and Zero + template + inline void + dijkstra_dispatch2 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params, ColorMap color) + { + // Default for predecessor map + dummy_property_map p_map; + + typedef typename property_traits::value_type D; + dijkstra_shortest_paths + (g, s, + choose_param(get_param(params, vertex_predecessor), p_map), + distance, weight, index_map, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits::max)()), + choose_param(get_param(params, distance_zero_t()), + D()), + choose_param(get_param(params, graph_visitor), + make_dijkstra_visitor(null_visitor())), + color); + } + + template + inline void + dijkstra_dispatch1 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params, ColorMap color) + { + // Default for distance map + typedef typename property_traits::value_type D; + typename std::vector::size_type + n = is_default_param(distance) ? num_vertices(g) : 1; + std::vector distance_map(n); + + // Default for color map + typename std::vector::size_type + m = is_default_param(color) ? num_vertices(g) : 1; + std::vector color_map(m); + + detail::dijkstra_dispatch2 + (g, s, choose_param(distance, make_iterator_property_map + (distance_map.begin(), index_map, + distance_map[0])), + weight, index_map, params, + choose_param(color, make_iterator_property_map + (color_map.begin(), index_map, + color_map[0]))); + } + } // namespace detail + + // Named Parameter Variant + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // Default for edge weight and vertex index map is to ask for them + // from the graph. Default for the visitor is null_visitor. + detail::dijkstra_dispatch1 + (g, s, + get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + params, + get_param(params, vertex_color)); + } + +} // namespace boost + +#endif // BOOST_GRAPH_DIJKSTRA_HPP diff --git a/thirdparty/boost/graph/dominator_tree.hpp b/thirdparty/boost/graph/dominator_tree.hpp new file mode 100644 index 0000000..2c4277f --- /dev/null +++ b/thirdparty/boost/graph/dominator_tree.hpp @@ -0,0 +1,488 @@ +//======================================================================= +// Copyright (C) 2005 Jong Soo Park +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// Dominator tree computation +#ifndef BOOST_GRAPH_DOMINATOR_HPP +#define BOOST_GRAPH_DOMINATOR_HPP + +#include +#include +#include +#include + +namespace boost { + namespace detail { + /** + * An extended time_stamper which also records vertices for each dfs number + */ + template + class time_stamper_with_vertex_vector + : public base_visitor< + time_stamper_with_vertex_vector > + { + public : + typedef Tag event_filter; + time_stamper_with_vertex_vector(TimeMap timeMap, VertexVector& v, + TimeT& t) + : timeStamper_(timeMap, t), v_(v) { } + + template + void + operator()(const typename property_traits::key_type& v, + const Graph& g) + { + timeStamper_(v, g); + v_[timeStamper_.m_time] = v; + } + + private : + time_stamper timeStamper_; + VertexVector& v_; + }; + + /** + * A convenient way to create a time_stamper_with_vertex_vector + */ + template + time_stamper_with_vertex_vector + stamp_times_with_vertex_vector(TimeMap timeMap, VertexVector& v, TimeT& t, + Tag) + { + return time_stamper_with_vertex_vector(timeMap, v, t); + } + + template + class dominator_visitor + { + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::vertices_size_type VerticesSizeType; + + public : + /** + * @param g [in] the target graph of the dominator tree + * @param entry [in] the entry node of g + * @param domTreePredMap [out] the immediate dominator map + * (parent map in dominator tree) + */ + dominator_visitor(const Graph& g, const Vertex& entry, + DomTreePredMap domTreePredMap) + : semi_(num_vertices(g)), + ancestor_(num_vertices(g), graph_traits::null_vertex()), + samedom_(ancestor_), + best_(semi_), + semiMap_(make_iterator_property_map(semi_.begin(), + get(vertex_index, g))), + ancestorMap_(make_iterator_property_map(ancestor_.begin(), + get(vertex_index, g))), + bestMap_(make_iterator_property_map(best_.begin(), + get(vertex_index, g))), + buckets_(num_vertices(g)), + bucketMap_(make_iterator_property_map(buckets_.begin(), + get(vertex_index, g))), + entry_(entry), + domTreePredMap_(domTreePredMap), + samedomMap(make_iterator_property_map(samedom_.begin(), + get(vertex_index, g))) + { + } + + void + operator()(const Vertex& n, const TimeMap& dfnumMap, + const PredMap& parentMap, const Graph& g) + { + if (n == entry_) return; + + const VerticesSizeType numOfVertices = num_vertices(g); + const Vertex p(get(parentMap, n)); + Vertex s(p); + + // 1. Calculate the semidominator of n, + // based on the semidominator thm. + // * Semidominator thm. : To find the semidominator of a node n, + // consider all predecessors v of n in the CFG (Control Flow Graph). + // - If v is a proper ancestor of n in the spanning tree + // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n) + // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n)) + // then for each u that is an ancestor of v (or u = v), + // Let semi(u) be a candidate for semi(n) + // of all these candidates, the one with lowest dfnum is + // the semidominator of n. + + // For each predecessor of n + typename graph_traits::in_edge_iterator inItr, inEnd; + for (tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; ++inItr) + { + const Vertex v = source(*inItr, g); + // To deal with unreachable nodes + if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices) + continue; + + Vertex s2; + if (get(dfnumMap, v) <= get(dfnumMap, n)) + s2 = v; + else + s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap)); + + if (get(dfnumMap, s2) < get(dfnumMap, s)) + s = s2; + } + put(semiMap_, n, s); + + // 2. Calculation of n's dominator is deferred until + // the path from s to n has been linked into the forest + get(bucketMap_, s).push_back(n); + get(ancestorMap_, n) = p; + get(bestMap_, n) = n; + + // 3. Now that the path from p to v has been linked into + // the spanning forest, these lines calculate the dominator of v, + // based on the dominator thm., or else defer the calculation + // until y's dominator is known + // * Dominator thm. : On the spanning-tree path below semi(n) and + // above or including n, let y be the node + // with the smallest-numbered semidominator. Then, + // + // idom(n) = semi(n) if semi(y)=semi(n) or + // idom(y) if semi(y) != semi(n) + typename std::deque::iterator buckItr; + for (buckItr = get(bucketMap_, p).begin(); + buckItr != get(bucketMap_, p).end(); + ++buckItr) + { + const Vertex v(*buckItr); + const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap)); + if (get(semiMap_, y) == get(semiMap_, v)) + put(domTreePredMap_, v, p); + else + put(samedomMap, v, y); + } + + get(bucketMap_, p).clear(); + } + + protected : + + /** + * Evaluate function in Tarjan's path compression + */ + const Vertex + ancestor_with_lowest_semi_(const Vertex& v, const TimeMap& dfnumMap) + { + const Vertex a(get(ancestorMap_, v)); + + if (get(ancestorMap_, a) != graph_traits::null_vertex()) + { + const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); + + put(ancestorMap_, v, get(ancestorMap_, a)); + + if (get(dfnumMap, get(semiMap_, b)) < + get(dfnumMap, get(semiMap_, get(bestMap_, v)))) + put(bestMap_, v, b); + } + + return get(bestMap_, v); + } + + std::vector semi_, ancestor_, samedom_, best_; + PredMap semiMap_, ancestorMap_, bestMap_; + std::vector< std::deque > buckets_; + + iterator_property_map >::iterator, + IndexMap> bucketMap_; + + const Vertex& entry_; + DomTreePredMap domTreePredMap_; + + public : + + PredMap samedomMap; + }; + + } // namespace detail + + /** + * @brief Build dominator tree using Lengauer-Tarjan algorithm. + * It takes O((V+E)log(V+E)) time. + * + * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding + * indexMap. + * If dfs has already run before, + * this function would be good for saving computations. + * @pre Unreachable nodes must be masked as + * graph_traits::null_vertex in parentMap. + * @pre Unreachable nodes must be masked as + * (std::numeric_limits::max)() in dfnumMap. + * + * @param domTreePredMap [out] : immediate dominator map (parent map + * in dom. tree) + * + * @note reference Appel. p. 452~453. algorithm 19.9, 19.10. + * + * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis + */ + template + void + lengauer_tarjan_dominator_tree_without_dfs + (const Graph& g, + const typename graph_traits::vertex_descriptor& entry, + const IndexMap& indexMap, + TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum, + DomTreePredMap domTreePredMap) + { + // Typedefs and concept check + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::vertices_size_type VerticesSizeType; + + function_requires< BidirectionalGraphConcept >(); + + const VerticesSizeType numOfVertices = num_vertices(g); + if (numOfVertices == 0) return; + + // 1. Visit each vertex in reverse post order and calculate sdom. + detail::dominator_visitor + visitor(g, entry, domTreePredMap); + + VerticesSizeType i; + for (i = 0; i < numOfVertices; ++i) + { + const Vertex u(verticesByDFNum[numOfVertices - 1 - i]); + if (u != graph_traits::null_vertex()) + visitor(u, dfnumMap, parentMap, g); + } + + // 2. Now all the deferred dominator calculations, + // based on the second clause of the dominator thm., are performed + for (i = 0; i < numOfVertices; ++i) + { + const Vertex n(verticesByDFNum[i]); + + if (n == entry || n == graph_traits::null_vertex()) + continue; + + Vertex u = get(visitor.samedomMap, n); + if (u != graph_traits::null_vertex()) + { + put(domTreePredMap, n, get(domTreePredMap, u)); + } + } + } + + /** + * Unlike lengauer_tarjan_dominator_tree_without_dfs, + * dfs is run in this function and + * the result is written to dfnumMap, parentMap, vertices. + * + * If the result of dfs required after this algorithm, + * this function can eliminate the need of rerunning dfs. + */ + template + void + lengauer_tarjan_dominator_tree + (const Graph& g, + const typename graph_traits::vertex_descriptor& entry, + const IndexMap& indexMap, + TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum, + DomTreePredMap domTreePredMap) + { + // Typedefs and concept check + typedef typename graph_traits::vertices_size_type VerticesSizeType; + + function_requires< BidirectionalGraphConcept >(); + + // 1. Depth first visit + const VerticesSizeType numOfVertices = num_vertices(g); + if (numOfVertices == 0) return; + + VerticesSizeType time = + (std::numeric_limits::max)(); + std::vector + colors(numOfVertices, color_traits::white()); + depth_first_visit + (g, entry, + make_dfs_visitor + (make_pair(record_predecessors(parentMap, on_tree_edge()), + detail::stamp_times_with_vertex_vector + (dfnumMap, verticesByDFNum, time, on_discover_vertex()))), + make_iterator_property_map(colors.begin(), indexMap)); + + // 2. Run main algorithm. + lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap, + parentMap, verticesByDFNum, + domTreePredMap); + } + + /** + * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum + * internally. + * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum), + * this function would be more convenient one. + */ + template + void + lengauer_tarjan_dominator_tree + (const Graph& g, + const typename graph_traits::vertex_descriptor& entry, + DomTreePredMap domTreePredMap) + { + // typedefs + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::vertices_size_type VerticesSizeType; + typedef typename property_map::const_type IndexMap; + typedef + iterator_property_map::iterator, + IndexMap> TimeMap; + typedef + iterator_property_map::iterator, IndexMap> + PredMap; + + // Make property maps + const VerticesSizeType numOfVertices = num_vertices(g); + if (numOfVertices == 0) return; + + const IndexMap indexMap = get(vertex_index, g); + + std::vector dfnum(numOfVertices, 0); + TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap)); + + std::vector parent(numOfVertices, + graph_traits::null_vertex()); + PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap)); + + std::vector verticesByDFNum(parent); + + // Run main algorithm + lengauer_tarjan_dominator_tree(g, entry, + indexMap, dfnumMap, parentMap, + verticesByDFNum, domTreePredMap); + } + + /** + * Muchnick. p. 182, 184 + * + * using iterative bit vector analysis + */ + template + void + iterative_bit_vector_dominator_tree + (const Graph& g, + const typename graph_traits::vertex_descriptor& entry, + const IndexMap& indexMap, + DomTreePredMap domTreePredMap) + { + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::vertex_iterator vertexItr; + typedef typename graph_traits::vertices_size_type VerticesSizeType; + typedef + iterator_property_map >::iterator, + IndexMap> vertexSetMap; + + function_requires >(); + + // 1. Finding dominator + // 1.1. Initialize + const VerticesSizeType numOfVertices = num_vertices(g); + if (numOfVertices == 0) return; + + vertexItr vi, viend; + tie(vi, viend) = vertices(g); + const std::set N(vi, viend); + + bool change = true; + + std::vector< std::set > dom(numOfVertices, N); + vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap)); + get(domMap, entry).clear(); + get(domMap, entry).insert(entry); + + while (change) + { + change = false; + for (tie(vi, viend) = vertices(g); vi != viend; ++vi) + { + if (*vi == entry) continue; + + std::set T(N); + + typename graph_traits::in_edge_iterator inItr, inEnd; + for (tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; ++inItr) + { + const Vertex p = source(*inItr, g); + + std::set tempSet; + std::set_intersection(T.begin(), T.end(), + get(domMap, p).begin(), + get(domMap, p).end(), + std::inserter(tempSet, tempSet.begin())); + T.swap(tempSet); + } + + T.insert(*vi); + if (T != get(domMap, *vi)) + { + change = true; + get(domMap, *vi).swap(T); + } + } // end of for (tie(vi, viend) = vertices(g) + } // end of while(change) + + // 2. Build dominator tree + for (tie(vi, viend) = vertices(g); vi != viend; ++vi) + get(domMap, *vi).erase(*vi); + + Graph domTree(numOfVertices); + + for (tie(vi, viend) = vertices(g); vi != viend; ++vi) + { + if (*vi == entry) continue; + + // We have to iterate through copied dominator set + const std::set tempSet(get(domMap, *vi)); + typename std::set::const_iterator s; + for (s = tempSet.begin(); s != tempSet.end(); ++s) + { + typename std::set::iterator t; + for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end(); ) + { + typename std::set::iterator old_t = t; + ++t; // Done early because t may become invalid + if (*old_t == *s) continue; + if (get(domMap, *s).find(*old_t) != get(domMap, *s).end()) + get(domMap, *vi).erase(old_t); + } + } + } + + for (tie(vi, viend) = vertices(g); vi != viend; ++vi) + { + if (*vi != entry && get(domMap, *vi).size() == 1) + { + Vertex temp = *get(domMap, *vi).begin(); + put(domTreePredMap, *vi, temp); + } + } + } + + template + void + iterative_bit_vector_dominator_tree + (const Graph& g, + const typename graph_traits::vertex_descriptor& entry, + DomTreePredMap domTreePredMap) + { + typename property_map::const_type + indexMap = get(vertex_index, g); + + iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap); + } +} // namespace boost + +#endif // BOOST_GRAPH_DOMINATOR_HPP diff --git a/thirdparty/boost/graph/edge_connectivity.hpp b/thirdparty/boost/graph/edge_connectivity.hpp new file mode 100644 index 0000000..730842c --- /dev/null +++ b/thirdparty/boost/graph/edge_connectivity.hpp @@ -0,0 +1,181 @@ +//======================================================================= +// Copyright 2000 University of Notre Dame. +// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_EDGE_CONNECTIVITY +#define BOOST_EDGE_CONNECTIVITY + +// WARNING: not-yet fully tested! + +#include +#include +#include +#include +#include + +namespace boost { + + namespace detail { + + template + inline + std::pair::vertex_descriptor, + typename graph_traits::degree_size_type> + min_degree_vertex(Graph& g) + { + typedef graph_traits Traits; + typename Traits::vertex_descriptor p; + typedef typename Traits::degree_size_type size_type; + size_type delta = (std::numeric_limits::max)(); + + typename Traits::vertex_iterator i, iend; + for (tie(i, iend) = vertices(g); i != iend; ++i) + if (degree(*i, g) < delta) { + delta = degree(*i, g); + p = *i; + } + return std::make_pair(p, delta); + } + + template + void neighbors(const Graph& g, + typename graph_traits::vertex_descriptor u, + OutputIterator result) + { + typename graph_traits::adjacency_iterator ai, aend; + for (tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai) + *result++ = *ai; + } + + template + void neighbors(const Graph& g, + VertexIterator first, VertexIterator last, + OutputIterator result) + { + for (; first != last; ++first) + neighbors(g, *first, result); + } + + } // namespace detail + + // O(m n) + template + typename graph_traits::degree_size_type + edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set) + { + //------------------------------------------------------------------------- + // Type Definitions + typedef graph_traits Traits; + typedef typename Traits::vertex_iterator vertex_iterator; + typedef typename Traits::edge_iterator edge_iterator; + typedef typename Traits::out_edge_iterator out_edge_iterator; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::degree_size_type degree_size_type; + typedef color_traits Color; + + typedef adjacency_list_traits Tr; + typedef typename Tr::edge_descriptor Tr_edge_desc; + typedef adjacency_list > > > + FlowGraph; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + //------------------------------------------------------------------------- + // Variable Declarations + vertex_descriptor u, v, p, k; + edge_descriptor e1, e2; + bool inserted; + vertex_iterator vi, vi_end; + edge_iterator ei, ei_end; + degree_size_type delta, alpha_star, alpha_S_k; + std::set S, neighbor_S; + std::vector S_star, non_neighbor_S; + std::vector color(num_vertices(g)); + std::vector pred(num_vertices(g)); + + //------------------------------------------------------------------------- + // Create a network flow graph out of the undirected graph + FlowGraph flow_g(num_vertices(g)); + + typename property_map::type + cap = get(edge_capacity, flow_g); + typename property_map::type + res_cap = get(edge_residual_capacity, flow_g); + typename property_map::type + rev_edge = get(edge_reverse, flow_g); + + for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { + u = source(*ei, g), v = target(*ei, g); + tie(e1, inserted) = add_edge(u, v, flow_g); + cap[e1] = 1; + tie(e2, inserted) = add_edge(v, u, flow_g); + cap[e2] = 1; // not sure about this + rev_edge[e1] = e2; + rev_edge[e2] = e1; + } + + //------------------------------------------------------------------------- + // The Algorithm + + tie(p, delta) = detail::min_degree_vertex(g); + S_star.push_back(p); + alpha_star = delta; + S.insert(p); + neighbor_S.insert(p); + detail::neighbors(g, S.begin(), S.end(), + std::inserter(neighbor_S, neighbor_S.begin())); + + std::set_difference(vertices(g).first, vertices(g).second, + neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(non_neighbor_S)); + + while (!non_neighbor_S.empty()) { // at most n - 1 times + k = non_neighbor_S.front(); + + alpha_S_k = edmunds_karp_max_flow + (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); + + if (alpha_S_k < alpha_star) { + alpha_star = alpha_S_k; + S_star.clear(); + for (tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) + if (color[*vi] != Color::white()) + S_star.push_back(*vi); + } + S.insert(k); + neighbor_S.insert(k); + detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); + non_neighbor_S.clear(); + std::set_difference(vertices(g).first, vertices(g).second, + neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(non_neighbor_S)); + } + //------------------------------------------------------------------------- + // Compute edges of the cut [S*, ~S*] + std::vector in_S_star(num_vertices(g), false); + typename std::vector::iterator si; + for (si = S_star.begin(); si != S_star.end(); ++si) + in_S_star[*si] = true; + + degree_size_type c = 0; + for (si = S_star.begin(); si != S_star.end(); ++si) { + out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) + if (!in_S_star[target(*ei, g)]) { + *disconnecting_set++ = *ei; + ++c; + } + } + return c; + } + +} // namespace boost + +#endif // BOOST_EDGE_CONNECTIVITY diff --git a/thirdparty/boost/graph/edge_list.hpp b/thirdparty/boost/graph/edge_list.hpp new file mode 100644 index 0000000..a9d6c61 --- /dev/null +++ b/thirdparty/boost/graph/edge_list.hpp @@ -0,0 +1,304 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_GRAPH_EDGE_LIST_HPP +#define BOOST_GRAPH_EDGE_LIST_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + // + // The edge_list class is an EdgeListGraph module that is constructed + // from a pair of iterators whose value type is a pair of vertex + // descriptors. + // + // For example: + // + // typedef std::pair E; + // list elist; + // ... + // typedef edge_list::iterator> Graph; + // Graph g(elist.begin(), elist.end()); + // + // If the iterators are random access, then Graph::edge_descriptor + // is of Integral type, otherwise it is a struct, though it is + // convertible to an Integral type. + // + + struct edge_list_tag { }; + + // The implementation class for edge_list. + template + class edge_list_impl + { + public: + typedef D edge_id; + typedef T Vpair; + typedef typename Vpair::first_type V; + typedef V vertex_descriptor; + typedef edge_list_tag graph_tag; + typedef void edge_property_type; + + struct edge_descriptor + { + edge_descriptor() { } + edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { } + operator edge_id() { return _id; } + EdgeIter _ptr; + edge_id _id; + }; + typedef edge_descriptor E; + + struct edge_iterator + { + typedef edge_iterator self; + typedef E value_type; + typedef E& reference; + typedef E* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::input_iterator_tag iterator_category; + edge_iterator() { } + edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { } + E operator*() { return E(_iter, _i); } + self& operator++() { ++_iter; ++_i; return *this; } + self operator++(int) { self t = *this; ++(*this); return t; } + bool operator==(const self& x) { return _iter == x._iter; } + bool operator!=(const self& x) { return _iter != x._iter; } + EdgeIter _iter; + edge_id _i; + }; + typedef void out_edge_iterator; + typedef void in_edge_iterator; + typedef void adjacency_iterator; + typedef void vertex_iterator; + }; + + template + std::pair::edge_iterator, + typename edge_list_impl::edge_iterator> + edges(const edge_list_impl& g_) { + const G& g = static_cast(g_); + typedef typename edge_list_impl::edge_iterator edge_iterator; + return std::make_pair(edge_iterator(g._first), edge_iterator(g._last)); + } + template + typename edge_list_impl::vertex_descriptor + source(typename edge_list_impl::edge_descriptor e, + const edge_list_impl&) { + return (*e._ptr).first; + } + template + typename edge_list_impl::vertex_descriptor + target(typename edge_list_impl::edge_descriptor e, + const edge_list_impl&) { + return (*e._ptr).second; + } + + template + class el_edge_property_map + : public put_get_helper >{ + public: + typedef E key_type; + typedef D value_type; + typedef D reference; + typedef readable_property_map_tag category; + + value_type operator[](key_type e) const { + return e._i; + } + }; + struct edge_list_edge_property_selector { + template + struct bind_ { + typedef el_edge_property_map type; + typedef type const_type; + }; + }; + template <> + struct edge_property_selector { + typedef edge_list_edge_property_selector type; + }; + + template + typename property_map< edge_list_impl, edge_index_t>::type + get(edge_index_t, const edge_list_impl&) { + typedef typename property_map< edge_list_impl, + edge_index_t>::type EdgeIndexMap; + return EdgeIndexMap(); + } + + template + inline D + get(edge_index_t, const edge_list_impl&, + typename edge_list_impl::edge_descriptor e) { + return e._i; + } + + // A specialized implementation for when the iterators are random access. + + struct edge_list_ra_tag { }; + + template + class edge_list_impl_ra + { + public: + typedef D edge_id; + typedef T Vpair; + typedef typename Vpair::first_type V; + typedef edge_list_ra_tag graph_tag; + typedef void edge_property_type; + + typedef edge_id edge_descriptor; + typedef V vertex_descriptor; + typedef typename boost::integer_range::iterator edge_iterator; + typedef void out_edge_iterator; + typedef void in_edge_iterator; + typedef void adjacency_iterator; + typedef void vertex_iterator; + }; + + template + std::pair::edge_iterator, + typename edge_list_impl_ra::edge_iterator> + edges(const edge_list_impl_ra& g_) + { + const G& g = static_cast(g_); + typedef typename edge_list_impl_ra::edge_iterator edge_iterator; + return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first)); + } + template + typename edge_list_impl_ra::vertex_descriptor + source(typename edge_list_impl_ra::edge_descriptor e, + const edge_list_impl_ra& g_) + { + const G& g = static_cast(g_); + return g._first[e].first; + } + template + typename edge_list_impl_ra::vertex_descriptor + target(typename edge_list_impl_ra::edge_descriptor e, + const edge_list_impl_ra& g_) + { + const G& g = static_cast(g_); + return g._first[e].second; + } + template + class el_ra_edge_property_map + : public put_get_helper >{ + public: + typedef E key_type; + typedef E value_type; + typedef E reference; + typedef readable_property_map_tag category; + + value_type operator[](key_type e) const { + return e; + } + }; + struct edge_list_ra_edge_property_selector { + template + struct bind_ { + typedef el_ra_edge_property_map type; + typedef type const_type; + }; + }; + template <> + struct edge_property_selector { + typedef edge_list_ra_edge_property_selector type; + }; + template + inline + typename property_map< edge_list_impl_ra, edge_index_t>::type + get(edge_index_t, const edge_list_impl_ra&) { + typedef typename property_map< edge_list_impl_ra, + edge_index_t>::type EdgeIndexMap; + return EdgeIndexMap(); + } + + template + inline D + get(edge_index_t, const edge_list_impl_ra&, + typename edge_list_impl_ra::edge_descriptor e) { + return e; + } + + + // Some helper classes for determining if the iterators are random access + template + struct is_random { + enum { RET = false }; + typedef mpl::false_ type; + }; + template <> + struct is_random { + enum { RET = true }; typedef mpl::true_ type; + }; + + // The edge_list class conditionally inherits from one of the + // above two classes. + + template ::value_type, + class D = typename std::iterator_traits::difference_type, + class Cat = typename std::iterator_traits::iterator_category> +#else + class T, + class D, + class Cat> +#endif + class edge_list + : public mpl::if_< typename is_random::type, + edge_list_impl_ra< edge_list, EdgeIter,T,D>, + edge_list_impl< edge_list, EdgeIter,T,D> + >::type + { + public: + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; + typedef edge_list_graph_tag traversal_category; + typedef std::size_t edges_size_type; + typedef std::size_t vertices_size_type; + typedef std::size_t degree_size_type; + edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) { + m_num_edges = std::distance(first, last); + } + edge_list(EdgeIter first, EdgeIter last, edges_size_type E) + : _first(first), _last(last), m_num_edges(E) { } + + EdgeIter _first, _last; + edges_size_type m_num_edges; + }; + + template + std::size_t num_edges(const edge_list& el) { + return el.m_num_edges; + } + +#ifndef BOOST_NO_STD_ITERATOR_TRAITS + template + inline edge_list + make_edge_list(EdgeIter first, EdgeIter last) + { + return edge_list(first, last); + } +#endif + +} /* namespace boost */ + +#endif /* BOOST_GRAPH_EDGE_LIST_HPP */ diff --git a/thirdparty/boost/graph/edmunds_karp_max_flow.hpp b/thirdparty/boost/graph/edmunds_karp_max_flow.hpp new file mode 100644 index 0000000..40d888a --- /dev/null +++ b/thirdparty/boost/graph/edmunds_karp_max_flow.hpp @@ -0,0 +1,250 @@ +//======================================================================= +// Copyright 2000 University of Notre Dame. +// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef EDMUNDS_KARP_MAX_FLOW_HPP +#define EDMUNDS_KARP_MAX_FLOW_HPP + +#include +#include +#include // for std::min and std::max +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + // The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti, + // Orlin. I think this is the same as or very similar to the original + // Edmunds-Karp algorithm. This solves the maximum flow problem. + + namespace detail { + + template + filtered_graph > + residual_graph(Graph& g, ResCapMap residual_capacity) { + return filtered_graph > + (g, is_residual_edge(residual_capacity)); + } + + template + inline void + augment(Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + PredEdgeMap p, + ResCapMap residual_capacity, + RevEdgeMap reverse_edge) + { + typename graph_traits::edge_descriptor e; + typename graph_traits::vertex_descriptor u; + typedef typename property_traits::value_type FlowValue; + + // find minimum residual capacity along the augmenting path + FlowValue delta = (std::numeric_limits::max)(); + e = p[sink]; + do { + BOOST_USING_STD_MIN(); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]); + u = source(e, g); + e = p[u]; + } while (u != src); + + // push delta units of flow along the augmenting path + e = p[sink]; + do { + residual_capacity[e] -= delta; + residual_capacity[reverse_edge[e]] += delta; + u = source(e, g); + e = p[u]; + } while (u != src); + } + + } // namespace detail + + template + typename property_traits::value_type + edmunds_karp_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + CapacityEdgeMap cap, + ResidualCapacityEdgeMap res, + ReverseEdgeMap rev, + ColorMap color, + PredEdgeMap pred) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + typename graph_traits::vertex_iterator u_iter, u_end; + typename graph_traits::out_edge_iterator ei, e_end; + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + res[*ei] = cap[*ei]; + + color[sink] = Color::gray(); + while (color[sink] != Color::white()) { + boost::queue Q; + breadth_first_search + (detail::residual_graph(g, res), src, Q, + make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())), + color); + if (color[sink] != Color::white()) + detail::augment(g, src, sink, pred, res, rev); + } // while + + typename property_traits::value_type flow = 0; + for (tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei) + flow += (cap[*ei] - res[*ei]); + return flow; + } // edmunds_karp_max_flow() + + namespace detail { + //------------------------------------------------------------------------- + // Handle default for color property map + + // use of class here is a VC++ workaround + template + struct edmunds_karp_dispatch2 { + template + static typename edge_capacity_value::type + apply + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + PredMap pred, + const bgl_named_params& params, + ColorMap color) + { + return edmunds_karp_max_flow + (g, src, sink, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + color, pred); + } + }; + template<> + struct edmunds_karp_dispatch2 { + template + static typename edge_capacity_value::type + apply + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + PredMap pred, + const bgl_named_params& params, + detail::error_property_not_found) + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::vertices_size_type size_type; + size_type n = is_default_param(get_param(params, vertex_color)) ? + num_vertices(g) : 1; + std::vector color_vec(n); + return edmunds_karp_max_flow + (g, src, sink, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + make_iterator_property_map(color_vec.begin(), choose_const_pmap + (get_param(params, vertex_index), + g, vertex_index), color_vec[0]), + pred); + } + }; + + //------------------------------------------------------------------------- + // Handle default for predecessor property map + + // use of class here is a VC++ workaround + template + struct edmunds_karp_dispatch1 { + template + static typename edge_capacity_value::type + apply(Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + const bgl_named_params& params, + PredMap pred) + { + typedef typename property_value< bgl_named_params, vertex_color_t>::type C; + return edmunds_karp_dispatch2::apply + (g, src, sink, pred, params, get_param(params, vertex_color)); + } + }; + template<> + struct edmunds_karp_dispatch1 { + + template + static typename edge_capacity_value::type + apply + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + const bgl_named_params& params, + detail::error_property_not_found) + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::vertices_size_type size_type; + size_type n = is_default_param(get_param(params, vertex_predecessor)) ? + num_vertices(g) : 1; + std::vector pred_vec(n); + + typedef typename property_value< bgl_named_params, vertex_color_t>::type C; + return edmunds_karp_dispatch2::apply + (g, src, sink, + make_iterator_property_map(pred_vec.begin(), choose_const_pmap + (get_param(params, vertex_index), + g, vertex_index), pred_vec[0]), + params, + get_param(params, vertex_color)); + } + }; + + } // namespace detail + + template + typename detail::edge_capacity_value::type + edmunds_karp_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + const bgl_named_params& params) + { + typedef typename property_value< bgl_named_params, vertex_predecessor_t>::type Pred; + return detail::edmunds_karp_dispatch1::apply + (g, src, sink, params, get_param(params, vertex_predecessor)); + } + + template + typename property_traits< + typename property_map::const_type + >::value_type + edmunds_karp_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink) + { + bgl_named_params params(0); + return edmunds_karp_max_flow(g, src, sink, params); + } + +} // namespace boost + +#endif // EDMUNDS_KARP_MAX_FLOW_HPP diff --git a/thirdparty/boost/graph/erdos_renyi_generator.hpp b/thirdparty/boost/graph/erdos_renyi_generator.hpp new file mode 100644 index 0000000..bc86116 --- /dev/null +++ b/thirdparty/boost/graph/erdos_renyi_generator.hpp @@ -0,0 +1,228 @@ +// Copyright 2004, 2005 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP +#define BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + class erdos_renyi_iterator + { + typedef typename graph_traits::directed_category directed_category; + typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef typename graph_traits::edges_size_type edges_size_type; + + BOOST_STATIC_CONSTANT + (bool, + is_undirected = (is_base_and_derived::value + || is_same::value)); + + public: + typedef std::input_iterator_tag iterator_category; + typedef std::pair value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef void difference_type; + + erdos_renyi_iterator() : gen(), n(0), edges(0), allow_self_loops(false) {} + erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, + double fraction = 0.0, bool allow_self_loops = false) + : gen(&gen), n(n), edges(edges_size_type(fraction * n * n)), + allow_self_loops(allow_self_loops) + { + if (is_undirected) edges = edges / 2; + next(); + } + + erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, + edges_size_type m, bool allow_self_loops = false) + : gen(&gen), n(n), edges(m), + allow_self_loops(allow_self_loops) + { + next(); + } + + reference operator*() const { return current; } + pointer operator->() const { return ¤t; } + + erdos_renyi_iterator& operator++() + { + --edges; + next(); + return *this; + } + + erdos_renyi_iterator operator++(int) + { + erdos_renyi_iterator temp(*this); + ++(*this); + return temp; + } + + bool operator==(const erdos_renyi_iterator& other) const + { return edges == other.edges; } + + bool operator!=(const erdos_renyi_iterator& other) const + { return !(*this == other); } + + private: + void next() + { + uniform_int rand_vertex(0, n-1); + current.first = rand_vertex(*gen); + do { + current.second = rand_vertex(*gen); + } while (current.first == current.second && !allow_self_loops); + } + + RandomGenerator* gen; + vertices_size_type n; + edges_size_type edges; + bool allow_self_loops; + value_type current; + }; + + template + class sorted_erdos_renyi_iterator + { + typedef typename graph_traits::directed_category directed_category; + typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef typename graph_traits::edges_size_type edges_size_type; + + BOOST_STATIC_CONSTANT + (bool, + is_undirected = (is_base_and_derived::value + || is_same::value)); + + public: + typedef std::input_iterator_tag iterator_category; + typedef std::pair value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef void difference_type; + + sorted_erdos_renyi_iterator() + : gen(), rand_vertex(0.5), n(0), allow_self_loops(false), + src((std::numeric_limits::max)()), tgt(0), prob(0) {} + sorted_erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, + double prob = 0.0, + bool allow_self_loops = false) + : gen(), + // The "1.0 - prob" in the next line is to work around a Boost.Random + // (and TR1) bug in the specification of geometric_distribution. It + // should be replaced by "prob" when the issue is fixed. + rand_vertex(1.0 - prob), + n(n), allow_self_loops(allow_self_loops), src(0), tgt(0), prob(prob) + { + this->gen.reset(new uniform_01(gen)); + + if (prob == 0.0) {src = (std::numeric_limits::max)(); return;} + next(); + } + + reference operator*() const { return current; } + pointer operator->() const { return ¤t; } + + sorted_erdos_renyi_iterator& operator++() + { + next(); + return *this; + } + + sorted_erdos_renyi_iterator operator++(int) + { + sorted_erdos_renyi_iterator temp(*this); + ++(*this); + return temp; + } + + bool operator==(const sorted_erdos_renyi_iterator& other) const + { return src == other.src && tgt == other.tgt; } + + bool operator!=(const sorted_erdos_renyi_iterator& other) const + { return !(*this == other); } + + private: + void next() + { + using std::sqrt; + using std::floor; + + // In order to get the edges from the generator in sorted order, one + // effective (but slow) procedure would be to use a + // bernoulli_distribution for each legal (src, tgt) pair. Because of the + // O(n^2) cost of that, a geometric distribution is used. The geometric + // distribution tells how many times the bernoulli_distribution would + // need to be run until it returns true. Thus, this distribution can be + // used to step through the edges which are actually present. Everything + // beyond "tgt += increment" is done to effectively convert linear + // indexing (the partial sums of the geometric distribution output) into + // graph edges. + assert (src != (std::numeric_limits::max)()); + vertices_size_type increment = rand_vertex(*gen); + tgt += increment; + if (is_undirected) { + // Update src and tgt based on position of tgt + // Basically, we want the greatest src_increment such that (in \bbQ): + // src_increment * (src + allow_self_loops + src_increment - 1/2) <= tgt + // The result of the LHS of this, evaluated with the computed + // src_increment, is then subtracted from tgt + double src_minus_half = (src + allow_self_loops) - 0.5; + double disc = src_minus_half * src_minus_half + 2 * tgt; + double src_increment_fp = floor(sqrt(disc) - src_minus_half); + vertices_size_type src_increment = vertices_size_type(src_increment_fp); + if (src + src_increment >= n) { + src = n; + } else { + tgt -= (src + allow_self_loops) * src_increment + + src_increment * (src_increment - 1) / 2; + src += src_increment; + } + } else { + // Number of out edge positions possible from each vertex in this graph + vertices_size_type possible_out_edges = n - (allow_self_loops ? 0 : 1); + src += (std::min)(n - src, tgt / possible_out_edges); + tgt %= possible_out_edges; + } + // Set end of graph code so (src, tgt) will be the same as for the end + // sorted_erdos_renyi_iterator + if (src >= n) {src = (std::numeric_limits::max)(); tgt = 0;} + // Copy (src, tgt) into current + current.first = src; + current.second = tgt; + // Adjust for (src, src) edge being forbidden + if (!allow_self_loops && tgt >= src) ++current.second; + } + + shared_ptr > gen; + geometric_distribution rand_vertex; + vertices_size_type n; + bool allow_self_loops; + vertices_size_type src, tgt; + value_type current; + double prob; + }; + +} // end namespace boost + +#endif // BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP diff --git a/thirdparty/boost/graph/exception.hpp b/thirdparty/boost/graph/exception.hpp new file mode 100644 index 0000000..f3432fc --- /dev/null +++ b/thirdparty/boost/graph/exception.hpp @@ -0,0 +1,44 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_EXCEPTION_HPP +#define BOOST_GRAPH_EXCEPTION_HPP + +#include +#include + +namespace boost { + + struct bad_graph : public std::invalid_argument { + bad_graph(const std::string& what_arg) + : std::invalid_argument(what_arg) { } + }; + + struct not_a_dag : public bad_graph { + not_a_dag() + : bad_graph("The graph must be a DAG.") { } + }; + + struct negative_edge : public bad_graph { + negative_edge() + : bad_graph("The graph may not contain an edge with negative weight."){ } + }; + + struct negative_cycle : public bad_graph { + negative_cycle() + : bad_graph("The graph may not contain negative cycles.") { } + }; + struct not_connected : public bad_graph { + not_connected() + : bad_graph("The graph must be connected.") { } + }; + +} // namespace boost + +#endif // BOOST_GRAPH_EXCEPTION_HPP diff --git a/thirdparty/boost/graph/filtered_graph.hpp b/thirdparty/boost/graph/filtered_graph.hpp new file mode 100644 index 0000000..ff00815 --- /dev/null +++ b/thirdparty/boost/graph/filtered_graph.hpp @@ -0,0 +1,507 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_FILTERED_GRAPH_HPP +#define BOOST_FILTERED_GRAPH_HPP + +#include +#include +#include +#include + +namespace boost { + + //========================================================================= + // Some predicate classes. + + struct keep_all { + template + bool operator()(const T&) const { return true; } + }; + + // Keep residual edges (used in maximum-flow algorithms). + template + struct is_residual_edge { + is_residual_edge() { } + is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) { } + template + bool operator()(const Edge& e) const { + return 0 < get(m_rcap, e); + } + ResidualCapacityEdgeMap m_rcap; + }; + + template + struct is_in_subset { + is_in_subset() : m_s(0) { } + is_in_subset(const Set& s) : m_s(&s) { } + + template + bool operator()(const Elt& x) const { + return set_contains(*m_s, x); + } + const Set* m_s; + }; + + template + struct is_not_in_subset { + is_not_in_subset() : m_s(0) { } + is_not_in_subset(const Set& s) : m_s(&s) { } + + template + bool operator()(const Elt& x) const { + return !set_contains(*m_s, x); + } + const Set* m_s; + }; + + namespace detail { + + template + struct out_edge_predicate { + out_edge_predicate() { } + out_edge_predicate(EdgePredicate ep, VertexPredicate vp, + const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } + + template + bool operator()(const Edge& e) const { + return m_edge_pred(e) && m_vertex_pred(target(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; + }; + + template + struct in_edge_predicate { + in_edge_predicate() { } + in_edge_predicate(EdgePredicate ep, VertexPredicate vp, + const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } + + template + bool operator()(const Edge& e) const { + return m_edge_pred(e) && m_vertex_pred(source(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; + }; + + template + struct edge_predicate { + edge_predicate() { } + edge_predicate(EdgePredicate ep, VertexPredicate vp, + const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } + + template + bool operator()(const Edge& e) const { + return m_edge_pred(e) + && m_vertex_pred(source(e, *m_g)) && m_vertex_pred(target(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; + }; + + } // namespace detail + + + //=========================================================================== + // Filtered Graph + + struct filtered_graph_tag { }; + + // This base class is a stupid hack to change overload resolution + // rules for the source and target functions so that they are a + // worse match than the source and target functions defined for + // pairs in graph_traits.hpp. I feel dirty. -JGS + template + struct filtered_graph_base { + typedef graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + filtered_graph_base(const G& g) : m_g(g) { } + //protected: + const G& m_g; + }; + + template + class filtered_graph : public filtered_graph_base { + typedef filtered_graph_base Base; + typedef graph_traits Traits; + typedef filtered_graph self; + public: + typedef Graph graph_type; + typedef detail::out_edge_predicate OutEdgePred; + typedef detail::in_edge_predicate InEdgePred; + typedef detail::edge_predicate EdgePred; + + // Constructors + filtered_graph(const Graph& g, EdgePredicate ep) + : Base(g), m_edge_pred(ep) { } + + filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) + : Base(g), m_edge_pred(ep), m_vertex_pred(vp) { } + + // Graph requirements + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::traversal_category traversal_category; + + // IncidenceGraph requirements + typedef filter_iterator< + OutEdgePred, typename Traits::out_edge_iterator + > out_edge_iterator; + + typedef typename Traits::degree_size_type degree_size_type; + + // AdjacencyGraph requirements + typedef typename adjacency_iterator_generator::type adjacency_iterator; + + // BidirectionalGraph requirements + typedef filter_iterator< + InEdgePred, typename Traits::in_edge_iterator + > in_edge_iterator; + + // VertexListGraph requirements + typedef filter_iterator< + VertexPredicate, typename Traits::vertex_iterator + > vertex_iterator; + typedef typename Traits::vertices_size_type vertices_size_type; + + // EdgeListGraph requirements + typedef filter_iterator< + EdgePred, typename Traits::edge_iterator + > edge_iterator; + typedef typename Traits::edges_size_type edges_size_type; + + typedef typename ::boost::edge_property_type::type edge_property_type; + typedef typename ::boost::vertex_property_type::type vertex_property_type; + typedef filtered_graph_tag graph_tag; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + // Bundled properties support + template + typename graph::detail::bundled_result::type& + operator[](Descriptor x) + { return const_cast(this->m_g)[x]; } + + template + typename graph::detail::bundled_result::type const& + operator[](Descriptor x) const + { return this->m_g[x]; } +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + + static vertex_descriptor null_vertex() + { + return Graph::null_vertex(); + } + + //private: + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + }; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct vertex_bundle_type > + : vertex_bundle_type { }; + + template + struct edge_bundle_type > + : edge_bundle_type { }; +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + + //=========================================================================== + // Non-member functions for the Filtered Edge Graph + + // Helper functions + template + inline filtered_graph + make_filtered_graph(Graph& g, EdgePredicate ep) { + return filtered_graph(g, ep); + } + template + inline filtered_graph + make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp) { + return filtered_graph(g, ep, vp); + } + + template + inline filtered_graph + make_filtered_graph(const Graph& g, EdgePredicate ep) { + return filtered_graph(g, ep); + } + template + inline filtered_graph + make_filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) { + return filtered_graph(g, ep, vp); + } + + template + std::pair::vertex_iterator, + typename filtered_graph::vertex_iterator> + vertices(const filtered_graph& g) + { + typedef filtered_graph Graph; + typename graph_traits::vertex_iterator f, l; + tie(f, l) = vertices(g.m_g); + typedef typename Graph::vertex_iterator iter; + return std::make_pair(iter(g.m_vertex_pred, f, l), + iter(g.m_vertex_pred, l, l)); + } + + template + std::pair::edge_iterator, + typename filtered_graph::edge_iterator> + edges(const filtered_graph& g) + { + typedef filtered_graph Graph; + typename Graph::EdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); + typename graph_traits::edge_iterator f, l; + tie(f, l) = edges(g.m_g); + typedef typename Graph::edge_iterator iter; + return std::make_pair(iter(pred, f, l), iter(pred, l, l)); + } + + // An alternative for num_vertices() and num_edges() would be to + // count the number in the filtered graph. This is problematic + // because of the interaction with the vertex indices... they would + // no longer go from 0 to num_vertices(), which would cause trouble + // for algorithms allocating property storage in an array. We could + // try to create a mapping to new recalibrated indices, but I don't + // see an efficient way to do this. + // + // However, the current solution is still unsatisfactory because + // the following semantic constraints no longer hold: + // tie(vi, viend) = vertices(g); + // assert(std::distance(vi, viend) == num_vertices(g)); + + template + typename filtered_graph::vertices_size_type + num_vertices(const filtered_graph& g) { + return num_vertices(g.m_g); + } + + template + typename filtered_graph::edges_size_type + num_edges(const filtered_graph& g) { + return num_edges(g.m_g); + } + + template + typename filtered_graph_base::vertex_descriptor + source(typename filtered_graph_base::edge_descriptor e, + const filtered_graph_base& g) + { + return source(e, g.m_g); + } + + template + typename filtered_graph_base::vertex_descriptor + target(typename filtered_graph_base::edge_descriptor e, + const filtered_graph_base& g) + { + return target(e, g.m_g); + } + + template + std::pair::out_edge_iterator, + typename filtered_graph::out_edge_iterator> + out_edges(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + typedef filtered_graph Graph; + typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); + typedef typename Graph::out_edge_iterator iter; + typename graph_traits::out_edge_iterator f, l; + tie(f, l) = out_edges(u, g.m_g); + return std::make_pair(iter(pred, f, l), iter(pred, l, l)); + } + + template + typename filtered_graph::degree_size_type + out_degree(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + typename filtered_graph::degree_size_type n = 0; + typename filtered_graph::out_edge_iterator f, l; + for (tie(f, l) = out_edges(u, g); f != l; ++f) + ++n; + return n; + } + + template + std::pair::adjacency_iterator, + typename filtered_graph::adjacency_iterator> + adjacent_vertices(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + typedef filtered_graph Graph; + typedef typename Graph::adjacency_iterator adjacency_iterator; + typename Graph::out_edge_iterator f, l; + tie(f, l) = out_edges(u, g); + return std::make_pair(adjacency_iterator(f, const_cast(&g)), + adjacency_iterator(l, const_cast(&g))); + } + + template + std::pair::in_edge_iterator, + typename filtered_graph::in_edge_iterator> + in_edges(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + typedef filtered_graph Graph; + typename Graph::InEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); + typedef typename Graph::in_edge_iterator iter; + typename graph_traits::in_edge_iterator f, l; + tie(f, l) = in_edges(u, g.m_g); + return std::make_pair(iter(pred, f, l), iter(pred, l, l)); + } + + template + typename filtered_graph::degree_size_type + in_degree(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + typename filtered_graph::degree_size_type n = 0; + typename filtered_graph::in_edge_iterator f, l; + for (tie(f, l) = in_edges(u, g); f != l; ++f) + ++n; + return n; + } + + template + std::pair::edge_descriptor, bool> + edge(typename filtered_graph::vertex_descriptor u, + typename filtered_graph::vertex_descriptor v, + const filtered_graph& g) + { + typename graph_traits::edge_descriptor e; + bool exists; + tie(e, exists) = edge(u, v, g.m_g); + return std::make_pair(e, exists && g.m_edge_pred(e)); + } + + template + std::pair::out_edge_iterator, + typename filtered_graph::out_edge_iterator> + edge_range(typename filtered_graph::vertex_descriptor u, + typename filtered_graph::vertex_descriptor v, + const filtered_graph& g) + { + typedef filtered_graph Graph; + typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); + typedef typename Graph::out_edge_iterator iter; + typename graph_traits::out_edge_iterator f, l; + tie(f, l) = edge_range(u, v, g.m_g); + return std::make_pair(iter(pred, f, l), iter(pred, l, l)); + } + + + //=========================================================================== + // Property map + + namespace detail { + struct filtered_graph_property_selector { + template + struct bind_ { + typedef typename FilteredGraph::graph_type Graph; + typedef property_map Map; + typedef typename Map::type type; + typedef typename Map::const_type const_type; + }; + }; + } // namespace detail + + template <> + struct vertex_property_selector { + typedef detail::filtered_graph_property_selector type; + }; + template <> + struct edge_property_selector { + typedef detail::filtered_graph_property_selector type; + }; + + template + typename property_map::type + get(Property p, filtered_graph& g) + { + return get(p, const_cast(g.m_g)); + } + + template + typename property_map::const_type + get(Property p, const filtered_graph& g) + { + return get(p, (const G&)g.m_g); + } + + template + typename property_map_value::type + get(Property p, const filtered_graph& g, const Key& k) + { + return get(p, (const G&)g.m_g, k); + } + + template + void + put(Property p, const filtered_graph& g, const Key& k, + const Value& val) + { + put(p, const_cast(g.m_g), k, val); + } + + //=========================================================================== + // Some filtered subgraph specializations + + template + struct vertex_subset_filter { + typedef filtered_graph > type; + }; + template + inline typename vertex_subset_filter::type + make_vertex_subset_filter(Graph& g, const Set& s) { + typedef typename vertex_subset_filter::type Filter; + is_in_subset p(s); + return Filter(g, keep_all(), p); + } + + template + struct vertex_subset_compliment_filter { + typedef filtered_graph > type; + }; + template + inline typename vertex_subset_compliment_filter::type + make_vertex_subset_compliment_filter(Graph& g, const Set& s) { + typedef typename vertex_subset_compliment_filter::type Filter; + is_not_in_subset p(s); + return Filter(g, keep_all(), p); + } + + +} // namespace boost + + +#endif // BOOST_FILTERED_GRAPH_HPP diff --git a/thirdparty/boost/graph/floyd_warshall_shortest.hpp b/thirdparty/boost/graph/floyd_warshall_shortest.hpp new file mode 100644 index 0000000..27a6d40 --- /dev/null +++ b/thirdparty/boost/graph/floyd_warshall_shortest.hpp @@ -0,0 +1,251 @@ +// Copyright 2002 Rensselaer Polytechnic Institute + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Lauren Foutz +// Scott Hill + +/* + This file implements the functions + + template + bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d, + const bgl_named_params& params) + + AND + + template + bool floyd_warshall_all_pairs_shortest_paths( + const VertexAndEdgeListGraph& g, DistanceMatrix& d, + const bgl_named_params& params) +*/ + + +#ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP +#define BOOST_GRAPH_FLOYD_WARSHALL_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace detail { + template + T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare) + { + if (compare(x, y)) return x; + else return y; + } + + template + bool floyd_warshall_dispatch(const VertexListGraph& g, + DistanceMatrix& d, const BinaryPredicate &compare, + const BinaryFunction &combine, const Infinity& inf, + const Zero& zero) + { + typename graph_traits::vertex_iterator + i, lasti, j, lastj, k, lastk; + + + for (tie(k, lastk) = vertices(g); k != lastk; k++) + for (tie(i, lasti) = vertices(g); i != lasti; i++) + for (tie(j, lastj) = vertices(g); j != lastj; j++) + { + d[*i][*j] = + detail::min_with_compare(d[*i][*j], + combine(d[*i][*k], d[*k][*j]), + compare); + } + + + for (tie(i, lasti) = vertices(g); i != lasti; i++) + if (compare(d[*i][*i], zero)) + return false; + return true; + } + } + + template + bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d, + const BinaryPredicate& compare, + const BinaryFunction& combine, const Infinity& inf, + const Zero& zero) + { + function_requires >(); + + return detail::floyd_warshall_dispatch(g, d, compare, combine, + inf, zero); + } + + + + template + bool floyd_warshall_all_pairs_shortest_paths( + const VertexAndEdgeListGraph& g, + DistanceMatrix& d, const WeightMap& w, + const BinaryPredicate& compare, const BinaryFunction& combine, + const Infinity& inf, const Zero& zero) + { + function_requires >(); + function_requires >(); + function_requires >(); + + typename graph_traits::vertex_iterator + firstv, lastv, firstv2, lastv2; + typename graph_traits::edge_iterator first, last; + + + for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + for(tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; firstv2++) + d[*firstv][*firstv2] = inf; + + + for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + d[*firstv][*firstv] = zero; + + + for(tie(first, last) = edges(g); first != last; first++) + { + if (d[source(*first, g)][target(*first, g)] != inf) { + d[source(*first, g)][target(*first, g)] = + detail::min_with_compare( + get(w, *first), + d[source(*first, g)][target(*first, g)], + compare); + } else + d[source(*first, g)][target(*first, g)] = get(w, *first); + } + + bool is_undirected = is_same::directed_category, + undirected_tag>::value; + if (is_undirected) + { + for(tie(first, last) = edges(g); first != last; first++) + { + if (d[target(*first, g)][source(*first, g)] != inf) + d[target(*first, g)][source(*first, g)] = + detail::min_with_compare( + get(w, *first), + d[target(*first, g)][source(*first, g)], + compare); + else + d[target(*first, g)][source(*first, g)] = get(w, *first); + } + } + + + return detail::floyd_warshall_dispatch(g, d, compare, combine, + inf, zero); + } + + + namespace detail { + template + bool floyd_warshall_init_dispatch(const VertexListGraph& g, + DistanceMatrix& d, WeightMap w, + const bgl_named_params& params) + { + typedef typename property_traits::value_type WM; + + return floyd_warshall_initialized_all_pairs_shortest_paths(g, d, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_inf_t()), + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()), + choose_param(get_param(params, distance_zero_t()), + WM())); + } + + + + template + bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g, + DistanceMatrix& d, WeightMap w, + const bgl_named_params& params) + { + typedef typename property_traits::value_type WM; + + return floyd_warshall_all_pairs_shortest_paths(g, d, w, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_inf_t()), + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()), + choose_param(get_param(params, distance_zero_t()), + WM())); + } + + + } // namespace detail + + + + template + bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d, + const bgl_named_params& params) + { + return detail::floyd_warshall_init_dispatch(g, d, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + params); + } + + template + bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d) + { + bgl_named_params params(0); + return detail::floyd_warshall_init_dispatch(g, d, + get(edge_weight, g), params); + } + + + + + template + bool floyd_warshall_all_pairs_shortest_paths( + const VertexAndEdgeListGraph& g, DistanceMatrix& d, + const bgl_named_params& params) + { + return detail::floyd_warshall_noninit_dispatch(g, d, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + params); + } + + template + bool floyd_warshall_all_pairs_shortest_paths( + const VertexAndEdgeListGraph& g, DistanceMatrix& d) + { + bgl_named_params params(0); + return detail::floyd_warshall_noninit_dispatch(g, d, + get(edge_weight, g), params); + } + + +} // namespace boost + +#endif + diff --git a/thirdparty/boost/graph/fruchterman_reingold.hpp b/thirdparty/boost/graph/fruchterman_reingold.hpp new file mode 100644 index 0000000..6f07a6a --- /dev/null +++ b/thirdparty/boost/graph/fruchterman_reingold.hpp @@ -0,0 +1,420 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP +#define BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP + +#include +#include +#include +#include +#include +#include +#include // for std::min and std::max + +namespace boost { + +struct square_distance_attractive_force { + template + T + operator()(typename graph_traits::edge_descriptor, + T k, + T d, + const Graph&) const + { + return d * d / k; + } +}; + +struct square_distance_repulsive_force { + template + T + operator()(typename graph_traits::vertex_descriptor, + typename graph_traits::vertex_descriptor, + T k, + T d, + const Graph&) const + { + return k * k / d; + } +}; + +template +struct linear_cooling { + typedef T result_type; + + linear_cooling(std::size_t iterations) + : temp(T(iterations) / T(10)), step(0.1) { } + + linear_cooling(std::size_t iterations, T temp) + : temp(temp), step(temp / T(iterations)) { } + + T operator()() + { + T old_temp = temp; + temp -= step; + if (temp < T(0)) temp = T(0); + return old_temp; + } + + private: + T temp; + T step; +}; + +struct all_force_pairs +{ + template + void operator()(const Graph& g, ApplyForce apply_force) + { + typedef typename graph_traits::vertex_iterator vertex_iterator; + vertex_iterator v, end; + for (tie(v, end) = vertices(g); v != end; ++v) { + vertex_iterator u = v; + for (++u; u != end; ++u) { + apply_force(*u, *v); + apply_force(*v, *u); + } + } + } +}; + +template +struct grid_force_pairs +{ + template + explicit + grid_force_pairs(Dim width, Dim height, PositionMap position, const Graph& g) + : width(width), height(height), position(position) + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + two_k = Dim(2) * sqrt(width*height / num_vertices(g)); + } + + template + void operator()(const Graph& g, ApplyForce apply_force) + { + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef std::list bucket_t; + typedef std::vector buckets_t; + + std::size_t columns = std::size_t(width / two_k + Dim(1)); + std::size_t rows = std::size_t(height / two_k + Dim(1)); + buckets_t buckets(rows * columns); + vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + std::size_t column = std::size_t((position[*v].x + width / 2) / two_k); + std::size_t row = std::size_t((position[*v].y + height / 2) / two_k); + + if (column >= columns) column = columns - 1; + if (row >= rows) row = rows - 1; + buckets[row * columns + column].push_back(*v); + } + + for (std::size_t row = 0; row < rows; ++row) + for (std::size_t column = 0; column < columns; ++column) { + bucket_t& bucket = buckets[row * columns + column]; + typedef typename bucket_t::iterator bucket_iterator; + for (bucket_iterator u = bucket.begin(); u != bucket.end(); ++u) { + // Repulse vertices in this bucket + bucket_iterator v = u; + for (++v; v != bucket.end(); ++v) { + apply_force(*u, *v); + apply_force(*v, *u); + } + + std::size_t adj_start_row = row == 0? 0 : row - 1; + std::size_t adj_end_row = row == rows - 1? row : row + 1; + std::size_t adj_start_column = column == 0? 0 : column - 1; + std::size_t adj_end_column = column == columns - 1? column : column + 1; + for (std::size_t other_row = adj_start_row; other_row <= adj_end_row; + ++other_row) + for (std::size_t other_column = adj_start_column; + other_column <= adj_end_column; ++other_column) + if (other_row != row || other_column != column) { + // Repulse vertices in this bucket + bucket_t& other_bucket + = buckets[other_row * columns + other_column]; + for (v = other_bucket.begin(); v != other_bucket.end(); ++v) + apply_force(*u, *v); + } + } + } + } + + private: + Dim width; + Dim height; + PositionMap position; + Dim two_k; +}; + +template +inline grid_force_pairs +make_grid_force_pairs(Dim width, Dim height, const PositionMap& position, + const Graph& g) +{ return grid_force_pairs(width, height, position, g); } + +template +void +scale_graph(const Graph& g, PositionMap position, + Dim left, Dim top, Dim right, Dim bottom) +{ + if (num_vertices(g) == 0) return; + + if (bottom > top) { + using std::swap; + swap(bottom, top); + } + + typedef typename graph_traits::vertex_iterator vertex_iterator; + + // Find min/max ranges + Dim minX = position[*vertices(g).first].x, maxX = minX; + Dim minY = position[*vertices(g).first].y, maxY = minY; + vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + minX = min BOOST_PREVENT_MACRO_SUBSTITUTION (minX, position[*vi].x); + maxX = max BOOST_PREVENT_MACRO_SUBSTITUTION (maxX, position[*vi].x); + minY = min BOOST_PREVENT_MACRO_SUBSTITUTION (minY, position[*vi].y); + maxY = max BOOST_PREVENT_MACRO_SUBSTITUTION (maxY, position[*vi].y); + } + + // Scale to bounding box provided + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { + position[*vi].x = ((position[*vi].x - minX) / (maxX - minX)) + * (right - left) + left; + position[*vi].y = ((position[*vi].y - minY) / (maxY - minY)) + * (top - bottom) + bottom; + } +} + +namespace detail { + template + struct fr_apply_force + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + + fr_apply_force(const PositionMap& position, + const DisplacementMap& displacement, + RepulsiveForce repulsive_force, Dim k, const Graph& g) + : position(position), displacement(displacement), + repulsive_force(repulsive_force), k(k), g(g) + { } + + void operator()(vertex_descriptor u, vertex_descriptor v) + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + if (u != v) { + Dim delta_x = position[v].x - position[u].x; + Dim delta_y = position[v].y - position[u].y; + Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y); + Dim fr = repulsive_force(u, v, k, dist, g); + displacement[v].x += delta_x / dist * fr; + displacement[v].y += delta_y / dist * fr; + } + } + + private: + PositionMap position; + DisplacementMap displacement; + RepulsiveForce repulsive_force; + Dim k; + const Graph& g; + }; + +} // end namespace detail + +template +void +fruchterman_reingold_force_directed_layout + (const Graph& g, + PositionMap position, + Dim width, + Dim height, + AttractiveForce attractive_force, + RepulsiveForce repulsive_force, + ForcePairs force_pairs, + Cooling cool, + DisplacementMap displacement) +{ + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_iterator edge_iterator; + +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + + Dim area = width * height; + // assume positions are initialized randomly + Dim k = sqrt(area / num_vertices(g)); + + detail::fr_apply_force + apply_force(position, displacement, repulsive_force, k, g); + + Dim temp = cool(); + if (temp) do { + // Calculate repulsive forces + vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + displacement[*v].x = 0; + displacement[*v].y = 0; + } + force_pairs(g, apply_force); + + // Calculate attractive forces + edge_iterator e, e_end; + for (tie(e, e_end) = edges(g); e != e_end; ++e) { + vertex_descriptor v = source(*e, g); + vertex_descriptor u = target(*e, g); + Dim delta_x = position[v].x - position[u].x; + Dim delta_y = position[v].y - position[u].y; + Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y); + Dim fa = attractive_force(*e, k, dist, g); + + displacement[v].x -= delta_x / dist * fa; + displacement[v].y -= delta_y / dist * fa; + displacement[u].x += delta_x / dist * fa; + displacement[u].y += delta_y / dist * fa; + } + + // Update positions + for (tie(v, v_end) = vertices(g); v != v_end; ++v) { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + Dim disp_size = sqrt(displacement[*v].x * displacement[*v].x + + displacement[*v].y * displacement[*v].y); + position[*v].x += displacement[*v].x / disp_size + * min BOOST_PREVENT_MACRO_SUBSTITUTION (disp_size, temp); + position[*v].y += displacement[*v].y / disp_size + * min BOOST_PREVENT_MACRO_SUBSTITUTION (disp_size, temp); + position[*v].x = min BOOST_PREVENT_MACRO_SUBSTITUTION + (width / 2, + max BOOST_PREVENT_MACRO_SUBSTITUTION(-width / 2, + position[*v].x)); + position[*v].y = min BOOST_PREVENT_MACRO_SUBSTITUTION + (height / 2, + max BOOST_PREVENT_MACRO_SUBSTITUTION(-height / 2, + position[*v].y)); + } + } while (temp = cool()); +} + +namespace detail { + template + struct fr_force_directed_layout + { + template + static void + run(const Graph& g, + PositionMap position, + Dim width, + Dim height, + AttractiveForce attractive_force, + RepulsiveForce repulsive_force, + ForcePairs force_pairs, + Cooling cool, + DisplacementMap displacement, + const bgl_named_params&) + { + fruchterman_reingold_force_directed_layout + (g, position, width, height, attractive_force, repulsive_force, + force_pairs, cool, displacement); + } + }; + + template<> + struct fr_force_directed_layout + { + template + static void + run(const Graph& g, + PositionMap position, + Dim width, + Dim height, + AttractiveForce attractive_force, + RepulsiveForce repulsive_force, + ForcePairs force_pairs, + Cooling cool, + error_property_not_found, + const bgl_named_params& params) + { + std::vector > displacements(num_vertices(g)); + fruchterman_reingold_force_directed_layout + (g, position, width, height, attractive_force, repulsive_force, + force_pairs, cool, + make_iterator_property_map + (displacements.begin(), + choose_const_pmap(get_param(params, vertex_index), g, + vertex_index), + simple_point())); + } + }; + +} // end namespace detail + +template +void +fruchterman_reingold_force_directed_layout + (const Graph& g, + PositionMap position, + Dim width, + Dim height, + const bgl_named_params& params) +{ + typedef typename property_value, + vertex_displacement_t>::type D; + + detail::fr_force_directed_layout::run + (g, position, width, height, + choose_param(get_param(params, attractive_force_t()), + square_distance_attractive_force()), + choose_param(get_param(params, repulsive_force_t()), + square_distance_repulsive_force()), + choose_param(get_param(params, force_pairs_t()), + make_grid_force_pairs(width, height, position, g)), + choose_param(get_param(params, cooling_t()), + linear_cooling(100)), + get_param(params, vertex_displacement_t()), + params); +} + +template +void +fruchterman_reingold_force_directed_layout(const Graph& g, + PositionMap position, + Dim width, + Dim height) +{ + fruchterman_reingold_force_directed_layout + (g, position, width, height, + attractive_force(square_distance_attractive_force())); +} + +} // end namespace boost + +#endif // BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP diff --git a/thirdparty/boost/graph/graph_archetypes.hpp b/thirdparty/boost/graph/graph_archetypes.hpp new file mode 100644 index 0000000..2d5197a --- /dev/null +++ b/thirdparty/boost/graph/graph_archetypes.hpp @@ -0,0 +1,290 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_ARCHETYPES_HPP +#define BOOST_GRAPH_ARCHETYPES_HPP + +#include +#include + +namespace boost { // should use a different namespace for this + + namespace detail { + struct null_graph_archetype : public null_archetype<> { + struct traversal_category { }; + }; + } + + //=========================================================================== + template + struct incidence_graph_archetype : public Base + { + typedef typename Base::traversal_category base_trav_cat; + struct traversal_category + : public incidence_graph_tag, public base_trav_cat { }; +#if 0 + typedef immutable_graph_tag mutability_category; +#endif + typedef Vertex vertex_descriptor; + typedef unsigned int degree_size_type; + typedef unsigned int vertices_size_type; + typedef unsigned int edges_size_type; + struct edge_descriptor { + edge_descriptor() { } + edge_descriptor(const detail::dummy_constructor&) { } + bool operator==(const edge_descriptor&) const { return false; } + bool operator!=(const edge_descriptor&) const { return false; } + }; + typedef input_iterator_archetype out_edge_iterator; + + typedef Directed directed_category; + typedef ParallelCategory edge_parallel_category; + + typedef void adjacency_iterator; + typedef void in_edge_iterator; + typedef void vertex_iterator; + typedef void edge_iterator; + }; + template + V source(const typename incidence_graph_archetype::edge_descriptor&, + const incidence_graph_archetype& ) + { + return V(static_object::get()); + } + template + V target(const typename incidence_graph_archetype::edge_descriptor&, + const incidence_graph_archetype& ) + { + return V(static_object::get()); + } + + template + std::pair::out_edge_iterator, + typename incidence_graph_archetype::out_edge_iterator> + out_edges(const V&, const incidence_graph_archetype& ) + { + typedef typename incidence_graph_archetype::out_edge_iterator Iter; + return std::make_pair(Iter(), Iter()); + } + + template + typename incidence_graph_archetype::degree_size_type + out_degree(const V&, const incidence_graph_archetype& ) + { + return 0; + } + + //=========================================================================== + template + struct adjacency_graph_archetype : public Base + { + typedef typename Base::traversal_category base_trav_cat; + struct traversal_category + : public adjacency_graph_tag, public base_trav_cat { }; + typedef Vertex vertex_descriptor; + typedef unsigned int degree_size_type; + typedef unsigned int vertices_size_type; + typedef unsigned int edges_size_type; + typedef void edge_descriptor; + typedef input_iterator_archetype adjacency_iterator; + + typedef Directed directed_category; + typedef ParallelCategory edge_parallel_category; + + typedef void in_edge_iterator; + typedef void out_edge_iterator; + typedef void vertex_iterator; + typedef void edge_iterator; + }; + + template + std::pair::adjacency_iterator, + typename adjacency_graph_archetype::adjacency_iterator> + adjacent_vertices(const V&, const adjacency_graph_archetype& ) + { + typedef typename adjacency_graph_archetype::adjacency_iterator Iter; + return std::make_pair(Iter(), Iter()); + } + + template + typename adjacency_graph_archetype::degree_size_type + out_degree(const V&, const adjacency_graph_archetype& ) + { + return 0; + } + + //=========================================================================== + template + struct vertex_list_graph_archetype : public Base + { + typedef incidence_graph_archetype + Incidence; + typedef adjacency_graph_archetype + Adjacency; + + typedef typename Base::traversal_category base_trav_cat; + struct traversal_category + : public vertex_list_graph_tag, public base_trav_cat { }; +#if 0 + typedef immutable_graph_tag mutability_category; +#endif + typedef Vertex vertex_descriptor; + typedef unsigned int degree_size_type; + typedef typename Incidence::edge_descriptor edge_descriptor; + typedef typename Incidence::out_edge_iterator out_edge_iterator; + typedef typename Adjacency::adjacency_iterator adjacency_iterator; + + typedef input_iterator_archetype vertex_iterator; + typedef unsigned int vertices_size_type; + typedef unsigned int edges_size_type; + + typedef Directed directed_category; + typedef ParallelCategory edge_parallel_category; + + typedef void in_edge_iterator; + typedef void edge_iterator; + }; + + template + std::pair::vertex_iterator, + typename vertex_list_graph_archetype::vertex_iterator> + vertices(const vertex_list_graph_archetype& ) + { + typedef typename vertex_list_graph_archetype::vertex_iterator Iter; + return std::make_pair(Iter(), Iter()); + } + + template + typename vertex_list_graph_archetype::vertices_size_type + num_vertices(const vertex_list_graph_archetype& ) + { + return 0; + } + + // ambiguously inherited from incidence graph and adjacency graph + template + typename vertex_list_graph_archetype::degree_size_type + out_degree(const V&, const vertex_list_graph_archetype& ) + { + return 0; + } + + //=========================================================================== + + struct property_graph_archetype_tag { }; + + template + struct property_graph_archetype : public GraphArchetype + { + typedef property_graph_archetype_tag graph_tag; + typedef ValueArch vertex_property_type; + typedef ValueArch edge_property_type; + }; + + struct choose_edge_property_map_archetype { + template + struct bind_ { + typedef mutable_lvalue_property_map_archetype + type; + typedef lvalue_property_map_archetype + const_type; + }; + }; + template <> + struct edge_property_selector { + typedef choose_edge_property_map_archetype type; + }; + + struct choose_vertex_property_map_archetype { + template + struct bind_ { + typedef mutable_lvalue_property_map_archetype + type; + typedef lvalue_property_map_archetype + const_type; + }; + }; + + template <> + struct vertex_property_selector { + typedef choose_vertex_property_map_archetype type; + }; + + template + typename property_map, P>::type + get(P, property_graph_archetype&) { + typename property_map, P>::type pmap; + return pmap; + } + + template + typename property_map, P>::const_type + get(P, const property_graph_archetype&) { + typename property_map, P>::const_type pmap; + return pmap; + } + + template + typename property_traits, P>::const_type>::value_type + get(P p, const property_graph_archetype& g, K k) { + return get( get(p, g), k); + } + + template + void + put(P p, property_graph_archetype& g, + const Key& key, const V& value) + { + typedef typename boost::property_map, P>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); + } + + struct color_value_archetype { + color_value_archetype() { } + color_value_archetype(detail::dummy_constructor) { } + bool operator==(const color_value_archetype& ) const { return true; } + bool operator!=(const color_value_archetype& ) const { return true; } + }; + template <> + struct color_traits { + static color_value_archetype white() + { + return color_value_archetype + (static_object::get()); + } + static color_value_archetype gray() + { + return color_value_archetype + (static_object::get()); + } + static color_value_archetype black() + { + return color_value_archetype + (static_object::get()); + } + }; + + template + class buffer_archetype { + public: + void push(const T&) {} + void pop() {} + T& top() { return static_object::get(); } + const T& top() const { return static_object::get(); } + bool empty() const { return true; } + }; + +} // namespace boost + + +#endif // BOOST_GRAPH_ARCHETYPES_HPP diff --git a/thirdparty/boost/graph/graph_as_tree.hpp b/thirdparty/boost/graph/graph_as_tree.hpp new file mode 100644 index 0000000..f5273b1 --- /dev/null +++ b/thirdparty/boost/graph/graph_as_tree.hpp @@ -0,0 +1,154 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP +#define BOOST_GRAPH_GRAPH_AS_TREE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + class graph_as_tree_base + { + typedef Derived Tree; + public: + typedef Node node_descriptor; + typedef ChIt children_iterator; + + graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { } + + friend Node root(const Tree& t) { return t._root; } + + template + friend std::pair + children(N n, const Tree& t) { return adjacent_vertices(n, t._g); } + + template + friend Node parent(N n, const Tree& t) { + return boost::get(t.parent_pa(), n); + } + + Graph& _g; + Node _root; + }; + + struct graph_as_tree_tag { }; + + template ::vertex_descriptor +#endif + , class ChIt +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + = typename graph_traits::adjacency_iterator +#endif + > + class graph_as_tree + : public graph_as_tree_base > + { + typedef graph_as_tree self; + typedef graph_as_tree_base super; + public: + graph_as_tree(Graph& g, Node root) : super(g, root) { } + + graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) { + breadth_first_search(g, root, + visitor(make_bfs_visitor + (record_predecessors(p, boost::on_tree_edge())))); + } + ParentMap parent_pa() const { return _p; } + typedef graph_as_tree_tag graph_tag; // for property_map + protected: + ParentMap _p; + }; + + + namespace detail { + + struct graph_as_tree_vertex_property_selector { + template + struct bind_ { + typedef typename GraphAsTree::base_type Graph; + typedef property_map PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; + }; + + struct graph_as_tree_edge_property_selector { + template + struct bind_ { + typedef typename GraphAsTree::base_type Graph; + typedef property_map PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; + }; + + } // namespace detail + + template <> + struct vertex_property_selector { + typedef detail::graph_as_tree_vertex_property_selector type; + }; + + template <> + struct edge_property_selector { + typedef detail::graph_as_tree_edge_property_selector type; + }; + + template + typename property_map::type + get(Property p, graph_as_tree& g) + { + return get(p, g._g); + } + + template + typename property_map::const_type + get(Property p, const graph_as_tree& g) + { + const Graph& gref = g._g; // in case GRef is non-const + return get(p, gref); + } + + template + typename property_traits< + typename property_map::const_type + >::value_type + get(Property p, const graph_as_tree& g, const Key& k) + { + return get(p, g._g, k); + } + + template + void + put(Property p, const graph_as_tree& g, const Key& k, + const Value& val) + { + put(p, g._g, k, val); + } + +} // namespace boost + +#endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP diff --git a/thirdparty/boost/graph/graph_concepts.hpp b/thirdparty/boost/graph/graph_concepts.hpp new file mode 100644 index 0000000..9b3868f --- /dev/null +++ b/thirdparty/boost/graph/graph_concepts.hpp @@ -0,0 +1,510 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_CONCEPTS_HPP +#define BOOST_GRAPH_CONCEPTS_HPP + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost +{ +// dwa 2003/7/11 -- This clearly shouldn't be necessary, but if +// you want to use vector_as_graph, it is! I'm sure the graph +// library leaves these out all over the place. Probably a +// redesign involving specializing a template with a static +// member function is in order :( +// +// It is needed in order to allow us to write using boost::vertices as +// needed for ADL when using vector_as_graph below. +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ + && !BOOST_WORKAROUND(__GNUC__, <= 2) \ + && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK +#endif + +#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK +template +typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); +#endif + + namespace concepts { + BOOST_concept(MultiPassInputIterator,(T)) { + BOOST_CONCEPT_USAGE(MultiPassInputIterator) { + BOOST_CONCEPT_ASSERT((InputIterator)); + } + }; + + BOOST_concept(Graph,(G)) + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::directed_category directed_category; + typedef typename graph_traits::edge_parallel_category + edge_parallel_category; + + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(Graph) + { + BOOST_CONCEPT_ASSERT((DefaultConstructible)); + BOOST_CONCEPT_ASSERT((EqualityComparable)); + BOOST_CONCEPT_ASSERT((Assignable)); + } + G g; + }; + + BOOST_concept(IncidenceGraph,(G)) + : Graph + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::out_edge_iterator + out_edge_iterator; + + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(IncidenceGraph) { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); + BOOST_CONCEPT_ASSERT((DefaultConstructible)); + BOOST_CONCEPT_ASSERT((EqualityComparable)); + BOOST_CONCEPT_ASSERT((Assignable)); + BOOST_CONCEPT_ASSERT((Convertible)); + + p = out_edges(u, g); + n = out_degree(u, g); + e = *p.first; + u = source(e, g); + v = target(e, g); + const_constraints(g); + } + void const_constraints(const G& cg) { + p = out_edges(u, cg); + n = out_degree(u, cg); + e = *p.first; + u = source(e, cg); + v = target(e, cg); + } + std::pair p; + typename graph_traits::vertex_descriptor u, v; + typename graph_traits::edge_descriptor e; + typename graph_traits::degree_size_type n; + G g; + }; + + BOOST_concept(BidirectionalGraph,(G)) + : IncidenceGraph + { + typedef typename graph_traits::in_edge_iterator + in_edge_iterator; + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(BidirectionalGraph) { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); + BOOST_CONCEPT_ASSERT((Convertible)); + + p = in_edges(v, g); + n = in_degree(v, g); + e = *p.first; + const_constraints(g); + } + void const_constraints(const G& cg) { + p = in_edges(v, cg); + n = in_degree(v, cg); + e = *p.first; + } + std::pair p; + typename graph_traits::vertex_descriptor v; + typename graph_traits::edge_descriptor e; + typename graph_traits::degree_size_type n; + G g; + }; + + BOOST_concept(AdjacencyGraph,(G)) + : Graph + { + typedef typename graph_traits::adjacency_iterator + adjacency_iterator; + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(AdjacencyGraph) { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); + BOOST_CONCEPT_ASSERT((Convertible)); + + p = adjacent_vertices(v, g); + v = *p.first; + const_constraints(g); + } + void const_constraints(const G& cg) { + p = adjacent_vertices(v, cg); + } + std::pair p; + typename graph_traits::vertex_descriptor v; + G g; + }; + + BOOST_concept(VertexListGraph,(G)) + : Graph + { + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(VertexListGraph) { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); + BOOST_CONCEPT_ASSERT((Convertible)); + +#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK + // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if + // you want to use vector_as_graph, it is! I'm sure the graph + // library leaves these out all over the place. Probably a + // redesign involving specializing a template with a static + // member function is in order :( + using boost::vertices; +#endif + p = vertices(g); + v = *p.first; + const_constraints(g); + } + void const_constraints(const G& cg) { +#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK + // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if + // you want to use vector_as_graph, it is! I'm sure the graph + // library leaves these out all over the place. Probably a + // redesign involving specializing a template with a static + // member function is in order :( + using boost::vertices; +#endif + + p = vertices(cg); + v = *p.first; + V = num_vertices(cg); + } + std::pair p; + typename graph_traits::vertex_descriptor v; + G g; + vertices_size_type V; + }; + + BOOST_concept(EdgeListGraph,(G)) + : Graph + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::edge_iterator edge_iterator; + typedef typename graph_traits::edges_size_type edges_size_type; + typedef typename graph_traits::traversal_category + traversal_category; + + BOOST_CONCEPT_USAGE(EdgeListGraph) { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); + BOOST_CONCEPT_ASSERT((DefaultConstructible)); + BOOST_CONCEPT_ASSERT((EqualityComparable)); + BOOST_CONCEPT_ASSERT((Assignable)); + BOOST_CONCEPT_ASSERT((Convertible)); + + p = edges(g); + e = *p.first; + u = source(e, g); + v = target(e, g); + const_constraints(g); + } + void const_constraints(const G& cg) { + p = edges(cg); + E = num_edges(cg); + e = *p.first; + u = source(e, cg); + v = target(e, cg); + } + std::pair p; + typename graph_traits::vertex_descriptor u, v; + typename graph_traits::edge_descriptor e; + edges_size_type E; + G g; + }; + + BOOST_concept(VertexAndEdgeListGraph,(G)) + : VertexListGraph + , EdgeListGraph + { + }; + + // Where to put the requirement for this constructor? + // G g(n_vertices); + // Not in mutable graph, then LEDA graph's can't be models of + // MutableGraph. + + BOOST_concept(EdgeMutableGraph,(G)) + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + + BOOST_CONCEPT_USAGE(EdgeMutableGraph) { + p = add_edge(u, v, g); + remove_edge(u, v, g); + remove_edge(e, g); + clear_vertex(v, g); + } + G g; + edge_descriptor e; + std::pair p; + typename graph_traits::vertex_descriptor u, v; + }; + + BOOST_concept(VertexMutableGraph,(G)) + { + + BOOST_CONCEPT_USAGE(VertexMutableGraph) { + v = add_vertex(g); + remove_vertex(v, g); + } + G g; + typename graph_traits::vertex_descriptor u, v; + }; + + BOOST_concept(MutableGraph,(G)) + : EdgeMutableGraph + , VertexMutableGraph + { + }; + + template + struct dummy_edge_predicate { + bool operator()(const edge_descriptor&) const { + return false; + } + }; + + BOOST_concept(MutableIncidenceGraph,(G)) + : MutableGraph + { + BOOST_CONCEPT_USAGE(MutableIncidenceGraph) { + remove_edge(iter, g); + remove_out_edge_if(u, p, g); + } + G g; + typedef typename graph_traits::edge_descriptor edge_descriptor; + dummy_edge_predicate p; + typename boost::graph_traits::vertex_descriptor u; + typename boost::graph_traits::out_edge_iterator iter; + }; + + BOOST_concept(MutableBidirectionalGraph,(G)) + : MutableIncidenceGraph + { + BOOST_CONCEPT_USAGE(MutableBidirectionalGraph) + { + remove_in_edge_if(u, p, g); + } + G g; + typedef typename graph_traits::edge_descriptor edge_descriptor; + dummy_edge_predicate p; + typename boost::graph_traits::vertex_descriptor u; + }; + + BOOST_concept(MutableEdgeListGraph,(G)) + : EdgeMutableGraph + { + BOOST_CONCEPT_USAGE(MutableEdgeListGraph) { + remove_edge_if(p, g); + } + G g; + typedef typename graph_traits::edge_descriptor edge_descriptor; + dummy_edge_predicate p; + }; + + BOOST_concept(VertexMutablePropertyGraph,(G)) + : VertexMutableGraph + { + BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) { + v = add_vertex(vp, g); + } + G g; + typename graph_traits::vertex_descriptor v; + typename vertex_property::type vp; + }; + + BOOST_concept(EdgeMutablePropertyGraph,(G)) + : EdgeMutableGraph + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + + BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) { + p = add_edge(u, v, ep, g); + } + G g; + std::pair p; + typename graph_traits::vertex_descriptor u, v; + typename edge_property::type ep; + }; + + BOOST_concept(AdjacencyMatrix,(G)) + : Graph + { + typedef typename graph_traits::edge_descriptor edge_descriptor; + + BOOST_CONCEPT_USAGE(AdjacencyMatrix) { + p = edge(u, v, g); + const_constraints(g); + } + void const_constraints(const G& cg) { + p = edge(u, v, cg); + } + typename graph_traits::vertex_descriptor u, v; + std::pair p; + G g; + }; + + BOOST_concept(ReadablePropertyGraph,(G)(X)(Property)) + : Graph + { + typedef typename property_map::const_type const_Map; + + BOOST_CONCEPT_USAGE(ReadablePropertyGraph) + { + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept)); + + const_constraints(g); + } + void const_constraints(const G& cg) { + const_Map pmap = get(Property(), cg); + pval = get(Property(), cg, x); + ignore_unused_variable_warning(pmap); + } + G g; + X x; + typename property_traits::value_type pval; + }; + + BOOST_concept(PropertyGraph,(G)(X)(Property)) + : ReadablePropertyGraph + { + typedef typename property_map::type Map; + BOOST_CONCEPT_USAGE(PropertyGraph) { + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept)); + + Map pmap = get(Property(), g); + pval = get(Property(), g, x); + put(Property(), g, x, pval); + ignore_unused_variable_warning(pmap); + } + G g; + X x; + typename property_traits::value_type pval; + }; + + BOOST_concept(LvaluePropertyGraph,(G)(X)(Property)) + : ReadablePropertyGraph + { + typedef typename property_map::type Map; + typedef typename property_map::const_type const_Map; + + BOOST_CONCEPT_USAGE(LvaluePropertyGraph) { + BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept)); + + pval = get(Property(), g, x); + put(Property(), g, x, pval); + } + G g; + X x; + typename property_traits::value_type pval; + }; + + // This needs to move out of the graph library + BOOST_concept(Buffer,(B)) + { + BOOST_CONCEPT_USAGE(Buffer) { + b.push(t); + b.pop(); + typename B::value_type& v = b.top(); + const_constraints(b); + ignore_unused_variable_warning(v); + } + void const_constraints(const B& cb) { + const typename B::value_type& v = cb.top(); + n = cb.size(); + bool e = cb.empty(); + ignore_unused_variable_warning(v); + ignore_unused_variable_warning(e); + } + typename B::size_type n; + typename B::value_type t; + B b; + }; + + BOOST_concept(ColorValue,(C)) + : EqualityComparable + , DefaultConstructible + { + BOOST_CONCEPT_USAGE(ColorValue) { + c = color_traits::white(); + c = color_traits::gray(); + c = color_traits::black(); + } + C c; + }; + + BOOST_concept(BasicMatrix,(M)(I)(V)) + { + BOOST_CONCEPT_USAGE(BasicMatrix) { + V& elt = A[i][j]; + const_constraints(A); + ignore_unused_variable_warning(elt); + } + void const_constraints(const M& cA) { + const V& elt = cA[i][j]; + ignore_unused_variable_warning(elt); + } + M A; + I i, j; + }; + + } // end namespace concepts + + using boost::concepts::MultiPassInputIteratorConcept; + using boost::concepts::GraphConcept; + using boost::concepts::IncidenceGraphConcept; + using boost::concepts::BidirectionalGraphConcept; + using boost::concepts::AdjacencyGraphConcept; + using boost::concepts::VertexListGraphConcept; + using boost::concepts::EdgeListGraphConcept; + using boost::concepts::VertexAndEdgeListGraphConcept; + using boost::concepts::EdgeMutableGraphConcept; + using boost::concepts::VertexMutableGraphConcept; + using boost::concepts::MutableGraphConcept; + using boost::concepts::MutableIncidenceGraphConcept; + using boost::concepts::MutableBidirectionalGraphConcept; + using boost::concepts::MutableEdgeListGraphConcept; + using boost::concepts::VertexMutablePropertyGraphConcept; + using boost::concepts::EdgeMutablePropertyGraphConcept; + using boost::concepts::AdjacencyMatrixConcept; + using boost::concepts::ReadablePropertyGraphConcept; + using boost::concepts::PropertyGraphConcept; + using boost::concepts::LvaluePropertyGraphConcept; + using boost::concepts::BufferConcept; + using boost::concepts::ColorValueConcept; + using boost::concepts::BasicMatrixConcept; +} // namespace boost + +#include + +#endif /* BOOST_GRAPH_CONCEPTS_H */ diff --git a/thirdparty/boost/graph/graph_selectors.hpp b/thirdparty/boost/graph/graph_selectors.hpp new file mode 100644 index 0000000..aeb7bf9 --- /dev/null +++ b/thirdparty/boost/graph/graph_selectors.hpp @@ -0,0 +1,38 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_SELECTORS_HPP +#define BOOST_GRAPH_SELECTORS_HPP + +#include + +namespace boost { + + //=========================================================================== + // Selectors for the Directed template parameter of adjacency_list + // and adjacency_matrix. + + struct directedS { enum { is_directed = true, is_bidir = false }; + typedef mpl::true_ is_directed_t; + typedef mpl::false_ is_bidir_t; + }; + struct undirectedS { + enum { is_directed = false, is_bidir = false }; + typedef mpl::false_ is_directed_t; + typedef mpl::false_ is_bidir_t; + }; + struct bidirectionalS { + enum { is_directed = true, is_bidir = true }; + typedef mpl::true_ is_directed_t; + typedef mpl::true_ is_bidir_t; + }; + +} // namespace boost + +#endif // BOOST_GRAPH_SELECTORS_HPP diff --git a/thirdparty/boost/graph/graph_test.hpp b/thirdparty/boost/graph/graph_test.hpp new file mode 100644 index 0000000..3dc2a64 --- /dev/null +++ b/thirdparty/boost/graph/graph_test.hpp @@ -0,0 +1,382 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_TEST_HPP +#define BOOST_GRAPH_TEST_HPP + +#include +#include +#include +#include +#include +#include +#include // for connects + + +// UNDER CONSTRUCTION + +namespace boost { + + template + struct graph_test + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename graph_traits::degree_size_type deg_size_t; + typedef typename graph_traits::edges_size_type e_size_t; + typedef typename graph_traits::out_edge_iterator out_edge_iter; + typedef typename property_map::type index_map_t; + typedef iterator_property_map::iterator, + index_map_t,vertex_t,vertex_t&> IsoMap; + + struct ignore_vertex { + ignore_vertex() { } + ignore_vertex(vertex_t v) : v(v) { } + bool operator()(vertex_t x) const { return x != v; } + vertex_t v; + }; + struct ignore_edge { + ignore_edge() { } + ignore_edge(edge_t e) : e(e) { } + bool operator()(edge_t x) const { return x != e; } + edge_t e; + }; + struct ignore_edges { + ignore_edges(vertex_t s, vertex_t t, const Graph& g) + : s(s), t(t), g(g) { } + bool operator()(edge_t x) const { + return !(source(x, g) == s && target(x, g) == t); + } + vertex_t s; vertex_t t; const Graph& g; + }; + + //========================================================================= + // Traversal Operations + + void test_incidence_graph + (const std::vector& vertex_set, + const std::vector< std::pair >& edge_set, + const Graph& g) + { + typedef typename std::vector::const_iterator vertex_iter; + typedef typename std::vector< std::pair > + ::const_iterator edge_iter; + typedef typename graph_traits::out_edge_iterator out_edge_iter; + + for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) { + vertex_t u = *ui; + std::vector adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->first == u) + adj.push_back(e->second); + + std::pair p = out_edges(u, g); + BOOST_CHECK(out_degree(u, g) == adj.size()); + BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) + == out_degree(u, g)); + for (; p.first != p.second; ++p.first) { + edge_t e = *p.first; + BOOST_CHECK(source(e, g) == u); + BOOST_CHECK(container_contains(adj, target(e, g)) == true); + } + } + } + + void test_bidirectional_graph + (const std::vector& vertex_set, + const std::vector< std::pair >& edge_set, + const Graph& g) + { + typedef typename std::vector::const_iterator vertex_iter; + typedef typename std::vector< std::pair > + ::const_iterator edge_iter; + typedef typename graph_traits::in_edge_iterator in_edge_iter; + + for (vertex_iter vi = vertex_set.begin(); vi != vertex_set.end(); ++vi) { + vertex_t v = *vi; + std::vector inv_adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->second == v) + inv_adj.push_back(e->first); + + std::pair p = in_edges(v, g); + BOOST_CHECK(in_degree(v, g) == inv_adj.size()); + BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) + == in_degree(v, g)); + for (; p.first != p.second; ++p.first) { + edge_t e = *p.first; + BOOST_CHECK(target(e, g) == v); + BOOST_CHECK(container_contains(inv_adj, source(e, g)) == true); + } + } + } + + void test_adjacency_graph + (const std::vector& vertex_set, + const std::vector< std::pair >& edge_set, + const Graph& g) + { + typedef typename std::vector::const_iterator vertex_iter; + typedef typename std::vector > + ::const_iterator edge_iter; + typedef typename graph_traits::adjacency_iterator adj_iter; + + for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) { + vertex_t u = *ui; + std::vector adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->first == u) + adj.push_back(e->second); + + std::pair p = adjacent_vertices(u, g); + BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) == adj.size()); + for (; p.first != p.second; ++p.first) { + vertex_t v = *p.first; + BOOST_CHECK(container_contains(adj, v) == true); + } + } + } + + void test_vertex_list_graph + (const std::vector& vertex_set, const Graph& g) + { + typedef typename graph_traits::vertex_iterator v_iter; + std::pair p = vertices(g); + BOOST_CHECK(num_vertices(g) == vertex_set.size()); + v_size_t n = std::distance(p.first, p.second); + BOOST_CHECK(n == num_vertices(g)); + for (; p.first != p.second; ++p.first) { + vertex_t v = *p.first; + BOOST_CHECK(container_contains(vertex_set, v) == true); + } + } + + void test_edge_list_graph + (const std::vector& vertex_set, + const std::vector< std::pair >& edge_set, + const Graph& g) + { + typedef typename graph_traits::edge_iterator e_iter; + std::pair p = edges(g); + BOOST_CHECK(num_edges(g) == edge_set.size()); + e_size_t m = std::distance(p.first, p.second); + BOOST_CHECK(m == num_edges(g)); + for (; p.first != p.second; ++p.first) { + edge_t e = *p.first; + BOOST_CHECK(any_if(edge_set, connects(source(e, g), target(e, g), g))); + BOOST_CHECK(container_contains(vertex_set, source(e, g)) == true); + BOOST_CHECK(container_contains(vertex_set, target(e, g)) == true); + } + } + + void test_adjacency_matrix + (const std::vector& vertex_set, + const std::vector< std::pair >& edge_set, + const Graph& g) + { + std::pair p; + for (typename std::vector > + ::const_iterator i = edge_set.begin(); + i != edge_set.end(); ++i) { + p = edge(i->first, i->second, g); + BOOST_CHECK(p.second == true); + BOOST_CHECK(source(p.first, g) == i->first); + BOOST_CHECK(target(p.first, g) == i->second); + } + typename std::vector::const_iterator j, k; + for (j = vertex_set.begin(); j != vertex_set.end(); ++j) + for (k = vertex_set.begin(); k != vertex_set.end(); ++k) { + p = edge(*j, *k, g); + if (p.second == true) + BOOST_CHECK(any_if(edge_set, + connects(source(p.first, g), target(p.first, g), g)) == true); + } + } + + //========================================================================= + // Mutating Operations + + void test_add_vertex(Graph& g) + { + Graph cpy; + std::vector iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + assert((verify_isomorphism(g, cpy, iso_map))); + + vertex_t v = add_vertex(g); + + BOOST_CHECK(num_vertices(g) == num_vertices(cpy) + 1); + + BOOST_CHECK(out_degree(v, g) == 0); + + // Make sure the rest of the graph stayed the same + BOOST_CHECK((verify_isomorphism + (make_filtered_graph(g, keep_all(), ignore_vertex(v)), cpy, + iso_map))); + } + + void test_add_edge(vertex_t u, vertex_t v, Graph& g) + { + Graph cpy; + std::vector iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + bool parallel_edge_exists = container_contains(adjacent_vertices(u, g), v); + + std::pair p = add_edge(u, v, g); + edge_t e = p.first; + bool added = p.second; + + if (is_undirected(g) && u == v) // self edge + BOOST_CHECK(added == false); + else if (parallel_edge_exists) + BOOST_CHECK(allows_parallel_edges(g) && added == true + || !allows_parallel_edges(g) && added == false); + else + BOOST_CHECK(added == true); + + if (p.second == true) { // edge added + BOOST_CHECK(num_edges(g) == num_edges(cpy) + 1); + + BOOST_CHECK(container_contains(out_edges(u, g), e) == true); + + BOOST_CHECK((verify_isomorphism + (make_filtered_graph(g, ignore_edge(e)), cpy, iso_map))); + } + else { // edge not added + if (! (is_undirected(g) && u == v)) { + // e should be a parallel edge + BOOST_CHECK(source(e, g) == u); + BOOST_CHECK(target(e, g) == v); + } + // The graph should not be changed. + BOOST_CHECK((verify_isomorphism(g, cpy, iso_map))); + } + } // test_add_edge() + + + void test_remove_edge(vertex_t u, vertex_t v, Graph& g) + { + Graph cpy; + std::vector iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + deg_size_t occurances = count(adjacent_vertices(u, g), v); + + remove_edge(u, v, g); + + BOOST_CHECK(num_edges(g) + occurances == num_edges(cpy)); + BOOST_CHECK((verify_isomorphism + (g, make_filtered_graph(cpy, ignore_edges(u,v,cpy)), + iso_map))); + } + + void test_remove_edge(edge_t e, Graph& g) + { + Graph cpy; + std::vector iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + vertex_t u = source(e, g), v = target(e, g); + deg_size_t occurances = count(adjacent_vertices(u, g), v); + + remove_edge(e, g); + + BOOST_CHECK(num_edges(g) + 1 == num_edges(cpy)); + BOOST_CHECK(count(adjacent_vertices(u, g), v) + 1 == occurances); + BOOST_CHECK((verify_isomorphism + (g, make_filtered_graph(cpy, ignore_edge(e)), + iso_map))); + } + + void test_clear_vertex(vertex_t v, Graph& g) + { + Graph cpy; + std::vector iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + clear_vertex(v, g); + + BOOST_CHECK(out_degree(v, g) == 0); + BOOST_CHECK(num_vertices(g) == num_vertices(cpy)); + BOOST_CHECK((verify_isomorphism + (g, make_filtered_graph(cpy, keep_all(), ignore_vertex(v)), + iso_map))); + } + + //========================================================================= + // Property Map + + template + void test_readable_vertex_property_graph + (const std::vector& vertex_prop, PropertyTag, const Graph& g) + { + typedef typename property_map::const_type const_Map; + const_Map pmap = get(PropertyTag(), g); + typename std::vector::const_iterator i = vertex_prop.begin(); + + for (typename boost::graph_traits::vertex_iterator + bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits::vertex_descriptor v; + bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) { + //BGL_FORALL_VERTICES_T(v, g, Graph) { + typename property_traits::value_type + pval1 = get(pmap, v), pval2 = get(PropertyTag(), g, v); + BOOST_CHECK(pval1 == pval2); + BOOST_CHECK(pval1 == *i++); + } + } + + template + void test_vertex_property_graph + (const std::vector& vertex_prop, PropertyTag tag, Graph& g) + { + typedef typename property_map::type PMap; + PMap pmap = get(PropertyTag(), g); + typename std::vector::const_iterator i = vertex_prop.begin(); + for (typename boost::graph_traits::vertex_iterator + bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits::vertex_descriptor v; + bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) + // BGL_FORALL_VERTICES_T(v, g, Graph) + put(pmap, v, *i++); + + test_readable_vertex_property_graph(vertex_prop, tag, g); + + BGL_FORALL_VERTICES_T(v, g, Graph) + put(pmap, v, vertex_prop[0]); + + typename std::vector::const_iterator j = vertex_prop.begin(); + BGL_FORALL_VERTICES_T(v, g, Graph) + put(PropertyTag(), g, v, *j++); + + test_readable_vertex_property_graph(vertex_prop, tag, g); + } + + + }; + + +} // namespace boost + +#include + +#endif // BOOST_GRAPH_TEST_HPP diff --git a/thirdparty/boost/graph/graph_traits.hpp b/thirdparty/boost/graph/graph_traits.hpp new file mode 100644 index 0000000..8854fc0 --- /dev/null +++ b/thirdparty/boost/graph/graph_traits.hpp @@ -0,0 +1,168 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_TRAITS_HPP +#define BOOST_GRAPH_TRAITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + struct graph_traits { + typedef typename G::vertex_descriptor vertex_descriptor; + typedef typename G::edge_descriptor edge_descriptor; + typedef typename G::adjacency_iterator adjacency_iterator; + typedef typename G::out_edge_iterator out_edge_iterator; + typedef typename G::in_edge_iterator in_edge_iterator; + typedef typename G::vertex_iterator vertex_iterator; + typedef typename G::edge_iterator edge_iterator; + + typedef typename G::directed_category directed_category; + typedef typename G::edge_parallel_category edge_parallel_category; + typedef typename G::traversal_category traversal_category; + + typedef typename G::vertices_size_type vertices_size_type; + typedef typename G::edges_size_type edges_size_type; + typedef typename G::degree_size_type degree_size_type; + + static inline vertex_descriptor null_vertex(); + }; + + template + inline typename graph_traits::vertex_descriptor + graph_traits::null_vertex() + { + return G::null_vertex(); + } + + // directed_category tags + struct directed_tag { }; + struct undirected_tag { }; + struct bidirectional_tag : public directed_tag { }; + + namespace detail { + inline bool is_directed(directed_tag) { return true; } + inline bool is_directed(undirected_tag) { return false; } + } + + template + bool is_directed(const Graph&) { + typedef typename graph_traits::directed_category Cat; + return detail::is_directed(Cat()); + } + template + bool is_undirected(const Graph& g) { + return ! is_directed(g); + } + + // edge_parallel_category tags + struct allow_parallel_edge_tag {}; + struct disallow_parallel_edge_tag {}; + + namespace detail { + inline bool allows_parallel(allow_parallel_edge_tag) { return true; } + inline bool allows_parallel(disallow_parallel_edge_tag) { return false; } + } + + template + bool allows_parallel_edges(const Graph&) { + typedef typename graph_traits::edge_parallel_category Cat; + return detail::allows_parallel(Cat()); + } + + // traversal_category tags + struct incidence_graph_tag { }; + struct adjacency_graph_tag { }; + struct bidirectional_graph_tag : + public virtual incidence_graph_tag { }; + struct vertex_list_graph_tag { }; + struct edge_list_graph_tag { }; + struct adjacency_matrix_tag { }; + + //?? not the right place ?? Lee + typedef boost::forward_traversal_tag multi_pass_input_iterator_tag; + + template + struct edge_property_type { + typedef typename G::edge_property_type type; + }; + template + struct vertex_property_type { + typedef typename G::vertex_property_type type; + }; + template + struct graph_property_type { + typedef typename G::graph_property_type type; + }; + + struct no_vertex_bundle {}; + struct no_edge_bundle {}; + + template + struct vertex_bundle_type + { + typedef typename G::vertex_bundled type; + }; + + template + struct edge_bundle_type + { + typedef typename G::edge_bundled type; + }; + + namespace graph { namespace detail { + template + class bundled_result + { + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename mpl::if_c<(is_same::value), + vertex_bundle_type, + edge_bundle_type >::type bundler; + + public: + typedef typename bundler::type type; + }; + } } // end namespace graph::detail +} // namespace boost + +// Since pair is in namespace std, Koenig lookup will find source and +// target if they are also defined in namespace std. This is illegal, +// but the alternative is to put source and target in the global +// namespace which causes name conflicts with other libraries (like +// SUIF). +namespace std { + + /* Some helper functions for dealing with pairs as edges */ + template + T source(pair p, const G&) { return p.first; } + + template + T target(pair p, const G&) { return p.second; } + +} + +#if defined(__GNUC__) && defined(__SGI_STL_PORT) +// For some reason g++ with STLport does not see the above definition +// of source() and target() unless we bring them into the boost +// namespace. +namespace boost { + using std::source; + using std::target; +} +#endif + +#endif // BOOST_GRAPH_TRAITS_HPP diff --git a/thirdparty/boost/graph/graph_utility.hpp b/thirdparty/boost/graph/graph_utility.hpp new file mode 100644 index 0000000..99c735a --- /dev/null +++ b/thirdparty/boost/graph/graph_utility.hpp @@ -0,0 +1,425 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_UTILITY_HPP +#define BOOST_GRAPH_UTILITY_HPP + +#include +#include +#include +#include +#include +#include + +#if !defined BOOST_NO_SLIST +# ifdef BOOST_SLIST_HEADER +# include BOOST_SLIST_HEADER +# else +# include +# endif +#endif + +#include +#include +#include +#include +// iota moved to detail/algorithm.hpp +#include + +namespace boost { + + // Provide an undirected graph interface alternative to the + // the source() and target() edge functions. + template + inline + std::pair::vertex_descriptor, + typename graph_traits::vertex_descriptor> + incident(typename graph_traits::edge_descriptor e, + UndirectedGraph& g) + { + return std::make_pair(source(e,g), target(e,g)); + } + + // Provide an undirected graph interface alternative + // to the out_edges() function. + template + inline + std::pair::out_edge_iterator, + typename graph_traits::out_edge_iterator> + incident_edges(typename graph_traits::vertex_descriptor u, + Graph& g) + { + return out_edges(u, g); + } + + template + inline typename graph_traits::vertex_descriptor + opposite(typename graph_traits::edge_descriptor e, + typename graph_traits::vertex_descriptor v, + const Graph& g) + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + if (v == source(e, g)) + return target(e, g); + else if (v == target(e, g)) + return source(e, g); + else + return vertex_descriptor(); + } + + //=========================================================================== + // Some handy predicates + + template + struct incident_from_predicate { + incident_from_predicate(Vertex u, const Graph& g) + : m_u(u), m_g(g) { } + template + bool operator()(const Edge& e) const { + return source(e, m_g) == m_u; + } + Vertex m_u; + const Graph& m_g; + }; + template + inline incident_from_predicate + incident_from(Vertex u, const Graph& g) { + return incident_from_predicate(u, g); + } + + template + struct incident_to_predicate { + incident_to_predicate(Vertex u, const Graph& g) + : m_u(u), m_g(g) { } + template + bool operator()(const Edge& e) const { + return target(e, m_g) == m_u; + } + Vertex m_u; + const Graph& m_g; + }; + template + inline incident_to_predicate + incident_to(Vertex u, const Graph& g) { + return incident_to_predicate(u, g); + } + + template + struct incident_on_predicate { + incident_on_predicate(Vertex u, const Graph& g) + : m_u(u), m_g(g) { } + template + bool operator()(const Edge& e) const { + return source(e, m_g) == m_u || target(e, m_g) == m_u; + } + Vertex m_u; + const Graph& m_g; + }; + template + inline incident_on_predicate + incident_on(Vertex u, const Graph& g) { + return incident_on_predicate(u, g); + } + + template + struct connects_predicate { + connects_predicate(Vertex u, Vertex v, const Graph& g) + : m_u(u), m_v(v), m_g(g) { } + template + bool operator()(const Edge& e) const { + if (is_directed(m_g)) + return source(e, m_g) == m_u && target(e, m_g) == m_v; + else + return (source(e, m_g) == m_u && target(e, m_g) == m_v) + || (source(e, m_g) == m_v && target(e, m_g) == m_u); + } + Vertex m_u, m_v; + const Graph& m_g; + }; + template + inline connects_predicate + connects(Vertex u, Vertex v, const Graph& g) { + return connects_predicate(u, v, g); + } + + + // Need to convert all of these printing functions to take an ostream object + // -JGS + + template + void print_in_edges(const IncidenceGraph& G, Name name) + { + typename graph_traits::vertex_iterator ui,ui_end; + for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { + std::cout << get(name,*ui) << " <-- "; + typename graph_traits + ::in_edge_iterator ei, ei_end; + for(tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei) + std::cout << get(name,source(*ei,G)) << " "; + std::cout << std::endl; + } + } + + template + void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag) + { + typename graph_traits::vertex_iterator ui,ui_end; + for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { + std::cout << get(name,*ui) << " --> "; + typename graph_traits + ::out_edge_iterator ei, ei_end; + for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) + std::cout << get(name,target(*ei,G)) << " "; + std::cout << std::endl; + } + } + template + void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag) + { + typename graph_traits::vertex_iterator ui,ui_end; + for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { + std::cout << get(name,*ui) << " <--> "; + typename graph_traits + ::out_edge_iterator ei, ei_end; + for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) + std::cout << get(name,target(*ei,G)) << " "; + std::cout << std::endl; + } + } + template + void print_graph(const IncidenceGraph& G, Name name) + { + typedef typename graph_traits + ::directed_category Cat; + print_graph_dispatch(G, name, Cat()); + } + template + void print_graph(const IncidenceGraph& G) { + print_graph(G, get(vertex_index, G)); + } + + template + void print_edges(const EdgeListGraph& G, Name name) + { + typename graph_traits::edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) + std::cout << "(" << get(name, source(*ei, G)) + << "," << get(name, target(*ei, G)) << ") "; + std::cout << std::endl; + } + + template + void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename) + { + typename graph_traits::edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) + std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G)) + << "," << get(vname, target(*ei, G)) << ") "; + std::cout << std::endl; + } + + template + void print_vertices(const VertexListGraph& G, Name name) + { + typename graph_traits::vertex_iterator vi,vi_end; + for (tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi) + std::cout << get(name,*vi) << " "; + std::cout << std::endl; + } + + template + bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag) + { + typedef typename graph_traits::edge_descriptor + edge_descriptor; + typename graph_traits::adjacency_iterator vi, viend, + adj_found; + tie(vi, viend) = adjacent_vertices(a, g); + adj_found = std::find(vi, viend, b); + if (adj_found == viend) + return false; + + typename graph_traits::out_edge_iterator oi, oiend, + out_found; + tie(oi, oiend) = out_edges(a, g); + out_found = std::find_if(oi, oiend, incident_to(b, g)); + if (out_found == oiend) + return false; + + typename graph_traits::in_edge_iterator ii, iiend, + in_found; + tie(ii, iiend) = in_edges(b, g); + in_found = std::find_if(ii, iiend, incident_from(a, g)); + if (in_found == iiend) + return false; + + return true; + } + template + bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag) + { + typedef typename graph_traits::edge_descriptor + edge_descriptor; + typename graph_traits::adjacency_iterator vi, viend, found; + tie(vi, viend) = adjacent_vertices(a, g); +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT) + // Getting internal compiler error with std::find() + found = viend; + for (; vi != viend; ++vi) + if (*vi == b) { + found = vi; + break; + } +#else + found = std::find(vi, viend, b); +#endif + if ( found == viend ) + return false; + + typename graph_traits::out_edge_iterator oi, oiend, + out_found; + tie(oi, oiend) = out_edges(a, g); + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT) + // Getting internal compiler error with std::find() + out_found = oiend; + for (; oi != oiend; ++oi) + if (target(*oi, g) == b) { + out_found = oi; + break; + } +#else + out_found = std::find_if(oi, oiend, incident_to(b, g)); +#endif + if (out_found == oiend) + return false; + return true; + } + template + bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag) + { + return is_adj_dispatch(g, a, b, directed_tag()); + } + + template + bool is_adjacent(Graph& g, Vertex a, Vertex b) { + typedef typename graph_traits::directed_category Cat; + return is_adj_dispatch(g, a, b, Cat()); + } + + template + bool in_edge_set(Graph& g, Edge e) + { + typename Graph::edge_iterator ei, ei_end, found; + tie(ei, ei_end) = edges(g); + found = std::find(ei, ei_end, e); + return found != ei_end; + } + + template + bool in_vertex_set(Graph& g, Vertex v) + { + typename Graph::vertex_iterator vi, vi_end, found; + tie(vi, vi_end) = vertices(g); + found = std::find(vi, vi_end, v); + return found != vi_end; + } + + template + bool in_edge_set(Graph& g, Vertex u, Vertex v) + { + typename Graph::edge_iterator ei, ei_end; + for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) + if (source(*ei,g) == u && target(*ei,g) == v) + return true; + return false; + } + + // is x a descendant of y? + template + inline bool is_descendant + (typename property_traits::value_type x, + typename property_traits::value_type y, + ParentMap parent) + { + if (get(parent, x) == x) // x is the root of the tree + return false; + else if (get(parent, x) == y) + return true; + else + return is_descendant(get(parent, x), y, parent); + } + + // is y reachable from x? + template + inline bool is_reachable + (typename graph_traits::vertex_descriptor x, + typename graph_traits::vertex_descriptor y, + const IncidenceGraph& g, + VertexColorMap color) // should start out white for every vertex + { + typedef typename property_traits::value_type ColorValue; + dfs_visitor<> vis; + depth_first_visit(g, x, vis, color); + return get(color, y) != color_traits::white(); + } + + // Is the undirected graph connected? + // Is the directed graph strongly connected? + template + inline bool is_connected(const VertexListGraph& g, VertexColorMap color) + { + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename graph_traits::vertex_iterator + ui, ui_end, vi, vi_end, ci, ci_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (*ui != *vi) { + for (tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci) + put(color, *ci, Color::white()); + if (! is_reachable(*ui, *vi, color)) + return false; + } + return true; + } + + template + bool is_self_loop + (typename graph_traits::edge_descriptor e, + const Graph& g) + { + return source(e, g) == target(e, g); + } + + + template + std::pair + make_list(const T1& t1, const T2& t2) + { return std::make_pair(t1, t2); } + + template + std::pair > + make_list(const T1& t1, const T2& t2, const T3& t3) + { return std::make_pair(t1, std::make_pair(t2, t3)); } + + template + std::pair > > + make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4) + { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); } + + template + std::pair > > > + make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) + { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); } + +} /* namespace boost */ + +#endif /* BOOST_GRAPH_UTILITY_HPP*/ diff --git a/thirdparty/boost/graph/graphml.hpp b/thirdparty/boost/graph/graphml.hpp new file mode 100644 index 0000000..eac1c8c --- /dev/null +++ b/thirdparty/boost/graph/graphml.hpp @@ -0,0 +1,332 @@ +// Copyright (C) 2006 Tiago de Paula Peixoto +// Copyright (C) 2004 The Trustees of Indiana University. +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Authors: Douglas Gregor +// Andrew Lumsdaine +// Tiago de Paula Peixoto + +#ifndef BOOST_GRAPH_GRAPHML_HPP +#define BOOST_GRAPH_GRAPHML_HPP + +#include +#include +#include +#include +#include // for exceptions +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +///////////////////////////////////////////////////////////////////////////// +// Graph reader exceptions +///////////////////////////////////////////////////////////////////////////// +struct parse_error: public graph_exception +{ + parse_error(const std::string& error) {statement = "parse error: " + error;} + virtual ~parse_error() throw() {} + virtual const char* what() const throw() {return statement.c_str();} + std::string statement; +}; + + +class mutate_graph +{ +public: + virtual ~mutate_graph() {} + virtual bool is_directed() const = 0; + + virtual boost::any do_add_vertex() = 0; + virtual std::pair do_add_edge(boost::any source, boost::any target) = 0; + + virtual void + set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) = 0; + + virtual void + set_vertex_property(const std::string& name, boost::any vertex, const std::string& value, const std::string& value_type) = 0; + + virtual void + set_edge_property(const std::string& name, boost::any edge, const std::string& value, const std::string& value_type) = 0; +}; + +template +class mutate_graph_impl : public mutate_graph +{ + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + public: + mutate_graph_impl(MutableGraph& g, dynamic_properties& dp) + : m_g(g), m_dp(dp) { } + + bool is_directed() const + { + return is_convertible::directed_category, + directed_tag>::value; + } + + virtual any do_add_vertex() + { + return any(add_vertex(m_g)); + } + + virtual std::pair do_add_edge(any source, any target) + { + std::pair retval = add_edge(any_cast(source), + any_cast(target), m_g); + return std::make_pair(any(retval.first), retval.second); + } + + virtual void + set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) + { + bool type_found = false; + try + { + mpl::for_each(put_property + (name, m_dp, m_g, value, value_type, m_type_names, type_found)); + } + catch (bad_lexical_cast) + { + throw parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type); + } + if (!type_found) + throw parse_error("unrecognized type \"" + value_type + + "\" for key " + name); + + } + + virtual void + set_vertex_property(const std::string& name, any vertex, const std::string& value, const std::string& value_type) + { + bool type_found = false; + try + { + mpl::for_each(put_property + (name, m_dp, any_cast(vertex), + value, value_type, m_type_names, type_found)); + } + catch (bad_lexical_cast) + { + throw parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type); + } + if (!type_found) + throw parse_error("unrecognized type \"" + value_type + + "\" for key " + name); + + } + + virtual void + set_edge_property(const std::string& name, any edge, const std::string& value, const std::string& value_type) + { + bool type_found = false; + try + { + mpl::for_each(put_property + (name, m_dp, any_cast(edge), + value, value_type, m_type_names, type_found)); + } + catch (bad_lexical_cast) + { + throw parse_error("invalid value \"" + value + "\" for key " + + name + " of type " + value_type); + } + if (!type_found) + throw parse_error("unrecognized type \"" + value_type + + "\" for key " + name); + } + + template + class put_property + { + public: + put_property(const std::string& name, dynamic_properties& dp, const Key& key, + const std::string& value, const std::string& value_type, + char** type_names, bool& type_found) + : m_name(name), m_dp(dp), m_key(key), m_value(value), + m_value_type(value_type), m_type_names(type_names), + m_type_found(type_found) {} + template + void operator()(Value) + { + if (m_value_type == m_type_names[mpl::find::type::pos::value]) + { + put(m_name, m_dp, m_key, lexical_cast(m_value)); + m_type_found = true; + } + } + private: + const std::string& m_name; + dynamic_properties& m_dp; + const Key& m_key; + const std::string& m_value; + const std::string& m_value_type; + char** m_type_names; + bool& m_type_found; + }; + +protected: + MutableGraph& m_g; + dynamic_properties& m_dp; + typedef mpl::vector value_types; + static char* m_type_names[]; +}; + +template +char* mutate_graph_impl::m_type_names[] = {"boolean", "int", "long", "float", "double", "string"}; + +void +read_graphml(std::istream& in, mutate_graph& g); + +template +void +read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp) +{ + mutate_graph_impl mg(g,dp); + read_graphml(in, mg); +} + +template +class get_type_name +{ +public: + get_type_name(const std::type_info& type, char** type_names, std::string& type_name) + : m_type(type), m_type_names(type_names), m_type_name(type_name) {} + template + void operator()(Type) + { + if (typeid(Type) == m_type) + m_type_name = m_type_names[mpl::find::type::pos::value]; + } +private: + const std::type_info &m_type; + char** m_type_names; + std::string &m_type_name; +}; + + +template +void +write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, + const dynamic_properties& dp, bool ordered_vertices=false) +{ + typedef typename graph_traits::directed_category directed_category; + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + + BOOST_STATIC_CONSTANT(bool, + graph_is_directed = + (is_convertible::value)); + + out << "\n" + << "\n"; + + typedef mpl::vector value_types; + char* type_names[] = {"boolean", "int", "int", "int", "int", "long", "long", "long", "long", "float", "double", "double", "string"}; + std::map graph_key_ids; + std::map vertex_key_ids; + std::map edge_key_ids; + int key_count = 0; + + // Output keys + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + { + std::string key_id = "key" + lexical_cast(key_count++); + if (i->second->key() == typeid(Graph)) + vertex_key_ids[i->first] = key_id; + else if (i->second->key() == typeid(vertex_descriptor)) + vertex_key_ids[i->first] = key_id; + else if (i->second->key() == typeid(edge_descriptor)) + edge_key_ids[i->first] = key_id; + else + continue; + std::string type_name = "string"; + mpl::for_each(get_type_name(i->second->value(), type_names, type_name)); + out << " second->key() == typeid(Graph) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\"" + << " attr.name=\"" << i->first << "\"" + << " attr.type=\"" << type_name << "\"" + << " />\n"; + } + + out << " \n"; + + // Output graph data + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + { + if (i->second->key() == typeid(Graph)) + { + out << " first] << "\">" + << i->second->get_string(g) << "\n"; + } + } + + typedef typename graph_traits::vertex_iterator vertex_iterator; + vertex_iterator v, v_end; + for (tie(v, v_end) = vertices(g); v != v_end; ++v) + { + out << " \n"; + // Output data + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + { + if (i->second->key() == typeid(vertex_descriptor)) + { + out << " first] << "\">" + << i->second->get_string(*v) << "\n"; + } + } + out << " \n"; + } + + typedef typename graph_traits::edge_iterator edge_iterator; + edge_iterator e, e_end; + typename graph_traits::edges_size_type edge_count = 0; + for (tie(e, e_end) = edges(g); e != e_end; ++e) + { + out << " \n"; + + // Output data + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + { + if (i->second->key() == typeid(edge_descriptor)) + { + out << " first] << "\">" + << i->second->get_string(*e) << "\n"; + } + } + out << " \n"; + } + + out << " \n" + << "\n"; +} + + +template +void +write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp, + bool ordered_vertices=false) +{ + write_graphml(out, g, get(vertex_index, g), dp, ordered_vertices); +} + +} // boost namespace + +#endif // BOOST_GRAPH_GRAPHML_HPP diff --git a/thirdparty/boost/graph/graphviz.hpp b/thirdparty/boost/graph/graphviz.hpp new file mode 100644 index 0000000..5c260ef --- /dev/null +++ b/thirdparty/boost/graph/graphviz.hpp @@ -0,0 +1,783 @@ +//======================================================================= +// Copyright 2001 University of Notre Dame. +// Copyright 2003 Jeremy Siek +// Authors: Lie-Quan Lee and Jeremy Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPHVIZ_HPP +#define BOOST_GRAPHVIZ_HPP + +#include +#include +#include +#include +#include +#include // for FILE +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_DECLSPEC +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_GRAPH_DYN_LINK) +# ifdef BOOST_GRAPH_SOURCE +# define BOOST_GRAPH_DECL __declspec(dllexport) +# else +# define BOOST_GRAPH_DECL __declspec(dllimport) +# endif // BOOST_GRAPH_SOURCE +# endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC + +#ifndef BOOST_GRAPH_DECL +# define BOOST_GRAPH_DECL +#endif + +namespace boost { + + template + struct graphviz_io_traits { + static std::string name() { + return "digraph"; + } + static std::string delimiter() { + return "->"; + } }; + + template <> + struct graphviz_io_traits { + static std::string name() { + return "graph"; + } + static std::string delimiter() { + return "--"; + } + }; + + struct default_writer { + void operator()(std::ostream&) const { + } + template + void operator()(std::ostream&, const VorE&) const { + } + }; + + template + class label_writer { + public: + label_writer(Name _name) : name(_name) {} + template + void operator()(std::ostream& out, const VertexOrEdge& v) const { + out << "[label=\"" << get(name, v) << "\"]"; + } + private: + Name name; + }; + template + inline label_writer + make_label_writer(Name n) { + return label_writer(n); + } + + enum edge_attribute_t { edge_attribute = 1111 }; + enum vertex_attribute_t { vertex_attribute = 2222 }; + enum graph_graph_attribute_t { graph_graph_attribute = 3333 }; + enum graph_vertex_attribute_t { graph_vertex_attribute = 4444 }; + enum graph_edge_attribute_t { graph_edge_attribute = 5555 }; + + BOOST_INSTALL_PROPERTY(edge, attribute); + BOOST_INSTALL_PROPERTY(vertex, attribute); + BOOST_INSTALL_PROPERTY(graph, graph_attribute); + BOOST_INSTALL_PROPERTY(graph, vertex_attribute); + BOOST_INSTALL_PROPERTY(graph, edge_attribute); + + + template + inline void write_attributes(const Attribute& attr, std::ostream& out) { + typename Attribute::const_iterator i, iend; + i = attr.begin(); + iend = attr.end(); + + while ( i != iend ) { + out << i->first << "=\"" << i->second << "\""; + ++i; + if ( i != iend ) + out << ", "; + } + } + + template + inline void write_all_attributes(Attributes attributes, + const std::string& name, + std::ostream& out) + { + typename Attributes::const_iterator i = attributes.begin(), + end = attributes.end(); + if (i != end) { + out << name << " [\n"; + write_attributes(attributes, out); + out << "];\n"; + } + } + + inline void write_all_attributes(detail::error_property_not_found, + const std::string&, + std::ostream&) + { + // Do nothing - no attributes exist + } + + + + + template + struct graph_attributes_writer + { + graph_attributes_writer(GraphGraphAttributes gg, + GraphNodeAttributes gn, + GraphEdgeAttributes ge) + : g_attributes(gg), n_attributes(gn), e_attributes(ge) { } + + void operator()(std::ostream& out) const { + write_all_attributes(g_attributes, "graph", out); + write_all_attributes(n_attributes, "node", out); + write_all_attributes(e_attributes, "edge", out); + } + GraphGraphAttributes g_attributes; + GraphNodeAttributes n_attributes; + GraphEdgeAttributes e_attributes; + }; + + template + graph_attributes_writer + make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr, + const EAttrMap& e_attr) { + return graph_attributes_writer + (g_attr, n_attr, e_attr); + } + + + template + graph_attributes_writer + ::type, + typename graph_property::type, + typename graph_property::type> + make_graph_attributes_writer(const Graph& g) + { + typedef typename graph_property::type + GAttrMap; + typedef typename graph_property::type + NAttrMap; + typedef typename graph_property::type + EAttrMap; + GAttrMap gam = get_property(g, graph_graph_attribute); + NAttrMap nam = get_property(g, graph_vertex_attribute); + EAttrMap eam = get_property(g, graph_edge_attribute); + graph_attributes_writer writer(gam, nam, eam); + return writer; + } + + template + struct attributes_writer { + attributes_writer(AttributeMap attr) + : attributes(attr) { } + + template + void operator()(std::ostream& out, const VorE& e) const { + this->write_attribute(out, attributes[e]); + } + + private: + template + void write_attribute(std::ostream& out, + const AttributeSequence& seq) const + { + if (!seq.empty()) { + out << "["; + write_attributes(seq, out); + out << "]"; + } + } + + void write_attribute(std::ostream&, + detail::error_property_not_found) const + { + } + AttributeMap attributes; + }; + + template + attributes_writer + ::const_type> + make_edge_attributes_writer(const Graph& g) + { + typedef typename property_map::const_type + EdgeAttributeMap; + return attributes_writer(get(edge_attribute, g)); + } + + template + attributes_writer + ::const_type> + make_vertex_attributes_writer(const Graph& g) + { + typedef typename property_map::const_type + VertexAttributeMap; + return attributes_writer(get(vertex_attribute, g)); + } + + template + inline void write_graphviz(std::ostream& out, const Graph& g, + VertexPropertiesWriter vpw, + EdgePropertiesWriter epw, + GraphPropertiesWriter gpw, + VertexID vertex_id) + { + typedef typename graph_traits::directed_category cat_type; + typedef graphviz_io_traits Traits; + std::string name = "G"; + out << Traits::name() << " " << name << " {" << std::endl; + + gpw(out); //print graph properties + + typename graph_traits::vertex_iterator i, end; + + for(tie(i,end) = vertices(g); i != end; ++i) { + out << get(vertex_id, *i); + vpw(out, *i); //print vertex attributes + out << ";" << std::endl; + } + typename graph_traits::edge_iterator ei, edge_end; + for(tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) { + out << get(vertex_id, source(*ei, g)) << Traits::delimiter() << get(vertex_id, target(*ei, g)) << " "; + epw(out, *ei); //print edge attributes + out << ";" << std::endl; + } + out << "}" << std::endl; + } + + template + inline void write_graphviz(std::ostream& out, const Graph& g, + VertexPropertiesWriter vpw, + EdgePropertiesWriter epw, + GraphPropertiesWriter gpw) + { write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); } + +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + // ambiguous overload problem with VC++ + template + inline void + write_graphviz(std::ostream& out, const Graph& g) { + default_writer dw; + default_writer gw; + write_graphviz(out, g, dw, dw, gw); + } +#endif + + template + inline void + write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw) { + default_writer dw; + default_writer gw; + write_graphviz(out, g, vw, dw, gw); + } + + template + inline void + write_graphviz(std::ostream& out, const Graph& g, + VertexWriter vw, EdgeWriter ew) { + default_writer gw; + write_graphviz(out, g, vw, ew, gw); + } + + namespace detail { + + template + void write_graphviz_subgraph (std::ostream& out, + const subgraph& g, + RandomAccessIterator vertex_marker, + RandomAccessIterator edge_marker, + VertexID vertex_id) + { + typedef subgraph Graph; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::directed_category cat_type; + typedef graphviz_io_traits Traits; + + typedef typename graph_property::type NameType; + const NameType& g_name = get_property(g, graph_name); + + if ( g.is_root() ) + out << Traits::name() ; + else + out << "subgraph"; + + out << " " << g_name << " {" << std::endl; + + typename Graph::const_children_iterator i_child, j_child; + + //print graph/node/edge attributes +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + typedef typename graph_property::type + GAttrMap; + typedef typename graph_property::type + NAttrMap; + typedef typename graph_property::type + EAttrMap; + GAttrMap gam = get_property(g, graph_graph_attribute); + NAttrMap nam = get_property(g, graph_vertex_attribute); + EAttrMap eam = get_property(g, graph_edge_attribute); + graph_attributes_writer writer(gam, nam, eam); + writer(out); +#else + make_graph_attributes_writer(g)(out); +#endif + + //print subgraph + for ( tie(i_child,j_child) = g.children(); + i_child != j_child; ++i_child ) + write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker, + vertex_id); + + // Print out vertices and edges not in the subgraphs. + + typename graph_traits::vertex_iterator i, end; + typename graph_traits::edge_iterator ei, edge_end; + + for(tie(i,end) = vertices(g); i != end; ++i) { + Vertex v = g.local_to_global(*i); + int pos = get(vertex_id, v); + if ( vertex_marker[pos] ) { + vertex_marker[pos] = false; + out << pos; +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + typedef typename property_map::const_type + VertexAttributeMap; + attributes_writer vawriter(get(vertex_attribute, + g.root())); + vawriter(out, v); +#else + make_vertex_attributes_writer(g.root())(out, v); +#endif + out << ";" << std::endl; + } + } + + for (tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) { + Vertex u = g.local_to_global(source(*ei,g)), + v = g.local_to_global(target(*ei, g)); + int pos = get(get(edge_index, g.root()), g.local_to_global(*ei)); + if ( edge_marker[pos] ) { + edge_marker[pos] = false; + out << get(vertex_id, u) << " " << Traits::delimiter() + << " " << get(vertex_id, v); +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + typedef typename property_map::const_type + EdgeAttributeMap; + attributes_writer eawriter(get(edge_attribute, g)); + eawriter(out, *ei); +#else + make_edge_attributes_writer(g)(out, *ei); //print edge properties +#endif + out << ";" << std::endl; + } + } + out << "}" << std::endl; + } + } // namespace detail + + // requires graph_name graph property + template + void write_graphviz(std::ostream& out, const subgraph& g) { + std::vector edge_marker(num_edges(g), true); + std::vector vertex_marker(num_vertices(g), true); + + detail::write_graphviz_subgraph(out, g, + vertex_marker.begin(), + edge_marker.begin(), + get(vertex_index, g)); + } + + template + void write_graphviz(const std::string& filename, const subgraph& g) { + std::ofstream out(filename.c_str()); + std::vector edge_marker(num_edges(g), true); + std::vector vertex_marker(num_vertices(g), true); + + detail::write_graphviz_subgraph(out, g, + vertex_marker.begin(), + edge_marker.begin(), + get(vertex_index, g)); + } + + template + void write_graphviz(std::ostream& out, const subgraph& g, + VertexID vertex_id) + { + std::vector edge_marker(num_edges(g), true); + std::vector vertex_marker(num_vertices(g), true); + + detail::write_graphviz_subgraph(out, g, + vertex_marker.begin(), + edge_marker.begin(), + vertex_id); + } + + template + void write_graphviz(const std::string& filename, const subgraph& g, + VertexID vertex_id) + { + std::ofstream out(filename.c_str()); + std::vector edge_marker(num_edges(g), true); + std::vector vertex_marker(num_vertices(g), true); + + detail::write_graphviz_subgraph(out, g, + vertex_marker.begin(), + edge_marker.begin(), + vertex_id); + } + + typedef std::map GraphvizAttrList; + + typedef property + GraphvizVertexProperty; + + typedef property > + GraphvizEdgeProperty; + + typedef property > > > + GraphvizGraphProperty; + + typedef subgraph > + GraphvizDigraph; + + typedef subgraph > + GraphvizGraph; + + + // These four require linking the BGL-Graphviz library: libbgl-viz.a + // from the /src directory. + extern void read_graphviz(const std::string& file, GraphvizDigraph& g); + extern void read_graphviz(FILE* file, GraphvizDigraph& g); + + extern void read_graphviz(const std::string& file, GraphvizGraph& g); + extern void read_graphviz(FILE* file, GraphvizGraph& g); + + class dynamic_properties_writer + { + public: + dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) { } + + template + void operator()(std::ostream& out, Descriptor key) const + { + bool first = true; + for (dynamic_properties::const_iterator i = dp->begin(); + i != dp->end(); ++i) { + if (typeid(key) == i->second->key()) { + if (first) out << " ["; + else out << ", "; + first = false; + + out << i->first << "=\"" << i->second->get_string(key) << "\""; + } + } + + if (!first) out << "]"; + } + + private: + const dynamic_properties* dp; + }; + + class dynamic_vertex_properties_writer + { + public: + dynamic_vertex_properties_writer(const dynamic_properties& dp, + const std::string& node_id) + : dp(&dp), node_id(&node_id) { } + + template + void operator()(std::ostream& out, Descriptor key) const + { + bool first = true; + for (dynamic_properties::const_iterator i = dp->begin(); + i != dp->end(); ++i) { + if (typeid(key) == i->second->key() + && i->first != *node_id) { + if (first) out << " ["; + else out << ", "; + first = false; + + out << i->first << "=\"" << i->second->get_string(key) << "\""; + } + } + + if (!first) out << "]"; + } + + private: + const dynamic_properties* dp; + const std::string* node_id; + }; + + namespace graph { namespace detail { + + template + struct node_id_property_map + { + typedef std::string value_type; + typedef value_type reference; + typedef Vertex key_type; + typedef readable_property_map_tag category; + + node_id_property_map() {} + + node_id_property_map(const dynamic_properties& dp, + const std::string& node_id) + : dp(&dp), node_id(&node_id) { } + + const dynamic_properties* dp; + const std::string* node_id; + }; + + template + inline std::string + get(node_id_property_map pm, + typename node_id_property_map::key_type v) + { return get(*pm.node_id, *pm.dp, v); } + + } } // end namespace graph::detail + + template + inline void + write_graphviz(std::ostream& out, const Graph& g, + const dynamic_properties& dp, + const std::string& node_id = "node_id") + { + typedef typename graph_traits::vertex_descriptor Vertex; + write_graphviz(out, g, dp, node_id, + graph::detail::node_id_property_map(dp, node_id)); + } + + template + void + write_graphviz(std::ostream& out, const Graph& g, + const dynamic_properties& dp, const std::string& node_id, + VertexID id) + { + write_graphviz + (out, g, + /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id), + /*edge_writer=*/dynamic_properties_writer(dp), + /*graph_writer=*/default_writer(), + id); + } + +///////////////////////////////////////////////////////////////////////////// +// Graph reader exceptions +///////////////////////////////////////////////////////////////////////////// +struct graph_exception : public std::exception { + virtual ~graph_exception() throw() {} + virtual const char* what() const throw() = 0; +}; + +struct bad_parallel_edge : public graph_exception { + std::string from; + std::string to; + mutable std::string statement; + bad_parallel_edge(const std::string& i, const std::string& j) : + from(i), to(j) {} + + virtual ~bad_parallel_edge() throw() {} + const char* what() const throw() { + if(statement.empty()) + statement = + std::string("Failed to add parallel edge: (") + + from + "," + to + ")\n"; + + return statement.c_str(); + } +}; + +struct directed_graph_error : public graph_exception { + virtual ~directed_graph_error() throw() {} + virtual const char* what() const throw() { + return + "read_graphviz: " + "Tried to read a directed graph into an undirected graph."; + } +}; + +struct undirected_graph_error : public graph_exception { + virtual ~undirected_graph_error() throw() {} + virtual const char* what() const throw() { + return + "read_graphviz: " + "Tried to read an undirected graph into a directed graph."; + } +}; + +namespace detail { namespace graph { + +typedef std::string id_t; +typedef id_t node_t; + +// edges are not uniquely determined by adjacent nodes +class edge_t { + int idx_; + explicit edge_t(int i) : idx_(i) {} +public: + static edge_t new_edge() { + static int idx = 0; + return edge_t(idx++); + }; + + bool operator==(const edge_t& rhs) const { + return idx_ == rhs.idx_; + } + bool operator<(const edge_t& rhs) const { + return idx_ < rhs.idx_; + } +}; + +class mutate_graph +{ + public: + virtual ~mutate_graph() {} + virtual bool is_directed() const = 0; + virtual void do_add_vertex(const node_t& node) = 0; + + virtual void + do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) + = 0; + + virtual void + set_node_property(const id_t& key, const node_t& node, const id_t& value) = 0; + + virtual void + set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) = 0; + + virtual void // RG: need new second parameter to support BGL subgraphs + set_graph_property(const id_t& key, const id_t& value) = 0; +}; + +template +class mutate_graph_impl : public mutate_graph +{ + typedef typename graph_traits::vertex_descriptor bgl_vertex_t; + typedef typename graph_traits::edge_descriptor bgl_edge_t; + + public: + mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp, + std::string node_id_prop) + : graph_(graph), dp_(dp), node_id_prop_(node_id_prop) { } + + ~mutate_graph_impl() {} + + bool is_directed() const + { + return + boost::is_convertible< + typename boost::graph_traits::directed_category, + boost::directed_tag>::value; + } + + virtual void do_add_vertex(const node_t& node) + { + // Add the node to the graph. + bgl_vertex_t v = add_vertex(graph_); + + // Set up a mapping from name to BGL vertex. + bgl_nodes.insert(std::make_pair(node, v)); + + // node_id_prop_ allows the caller to see the real id names for nodes. + put(node_id_prop_, dp_, v, node); + } + + void + do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) + { + std::pair result = + add_edge(bgl_nodes[source], bgl_nodes[target], graph_); + + if(!result.second) { + // In the case of no parallel edges allowed + throw bad_parallel_edge(source, target); + } else { + bgl_edges.insert(std::make_pair(edge, result.first)); + } + } + + void + set_node_property(const id_t& key, const node_t& node, const id_t& value) + { + put(key, dp_, bgl_nodes[node], value); + } + + void + set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) + { + put(key, dp_, bgl_edges[edge], value); + } + + void + set_graph_property(const id_t& key, const id_t& value) + { + /* RG: pointer to graph prevents copying */ + put(key, dp_, &graph_, value); + } + + + protected: + MutableGraph& graph_; + dynamic_properties& dp_; + std::string node_id_prop_; + std::map bgl_nodes; + std::map bgl_edges; +}; + +BOOST_GRAPH_DECL +bool read_graphviz(std::istream& in, mutate_graph& graph); + +} } // end namespace detail::graph + +// Parse the passed stream as a GraphViz dot file. +template +bool read_graphviz(std::istream& in, MutableGraph& graph, + dynamic_properties& dp, + std::string const& node_id = "node_id") +{ + detail::graph::mutate_graph_impl m_graph(graph, dp, node_id); + return detail::graph::read_graphviz(in, m_graph); +} + +} // namespace boost + +#ifdef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS +# include +#endif // BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS + +#endif // BOOST_GRAPHVIZ_HPP diff --git a/thirdparty/boost/graph/gursoy_atun_layout.hpp b/thirdparty/boost/graph/gursoy_atun_layout.hpp new file mode 100644 index 0000000..c9048ce --- /dev/null +++ b/thirdparty/boost/graph/gursoy_atun_layout.hpp @@ -0,0 +1,631 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP +#define BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP + +// Gursoy-Atun graph layout, based on: +// "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach" +// in EuroPar 2000, p. 234 of LNCS 1900 +// http://springerlink.metapress.com/link.asp?id=pcu07ew5rhexp9yt + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace detail { + +struct over_distance_limit : public std::exception {}; + +template +struct update_position_visitor { + typedef typename Topology::point_type Point; + PositionMap position_map; + NodeDistanceMap node_distance; + const Topology& space; + Point input_vector; + double distance_limit; + double learning_constant; + double falloff_ratio; + + typedef boost::on_examine_vertex event_filter; + + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + + update_position_visitor(PositionMap position_map, + NodeDistanceMap node_distance, + const Topology& space, + const Point& input_vector, + double distance_limit, + double learning_constant, + double falloff_ratio): + position_map(position_map), node_distance(node_distance), + space(space), + input_vector(input_vector), distance_limit(distance_limit), + learning_constant(learning_constant), falloff_ratio(falloff_ratio) {} + + void operator()(vertex_descriptor v, const Graph&) const + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::pow; +#endif + + if (get(node_distance, v) > distance_limit) + throw over_distance_limit(); + Point old_position = get(position_map, v); + double distance = get(node_distance, v); + double fraction = + learning_constant * pow(falloff_ratio, distance * distance); + put(position_map, v, + space.move_position_toward(old_position, fraction, input_vector)); + } +}; + +template +struct gursoy_shortest +{ + template + static inline void + run(const Graph& g, typename graph_traits::vertex_descriptor s, + NodeDistanceMap node_distance, UpdatePosition& update_position, + EdgeWeightMap weight) + { + boost::dijkstra_shortest_paths(g, s, weight_map(weight). + visitor(boost::make_dijkstra_visitor(std::make_pair( + boost::record_distances(node_distance, boost::on_edge_relaxed()), + update_position)))); + } +}; + +template<> +struct gursoy_shortest +{ + template + static inline void + run(const Graph& g, typename graph_traits::vertex_descriptor s, + NodeDistanceMap node_distance, UpdatePosition& update_position, + dummy_property_map) + { + boost::breadth_first_search(g, s, + visitor(boost::make_bfs_visitor(std::make_pair( + boost::record_distances(node_distance, boost::on_tree_edge()), + update_position)))); + } +}; + +} // namespace detail + +template +void +gursoy_atun_step + (const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + Diameter diameter, + double learning_constant, + VertexIndexMap vertex_index_map, + EdgeWeightMap weight) +{ +#ifndef BOOST_NO_STDC_NAMESPACE + using std::pow; + using std::exp; +#endif + + typedef typename graph_traits::vertex_iterator + vertex_iterator; + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + typedef typename Topology::point_type point_type; + vertex_iterator i, iend; + std::vector distance_from_input_vector(num_vertices(graph)); + typedef boost::iterator_property_map::iterator, + VertexIndexMap, + double, double&> + DistanceFromInputMap; + DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(), + vertex_index_map); + std::vector node_distance_map_vector(num_vertices(graph)); + typedef boost::iterator_property_map::iterator, + VertexIndexMap, + double, double&> + NodeDistanceMap; + NodeDistanceMap node_distance(node_distance_map_vector.begin(), + vertex_index_map); + point_type input_vector = space.random_point(); + vertex_descriptor min_distance_loc + = graph_traits::null_vertex(); + double min_distance = 0.0; + bool min_distance_unset = true; + for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) { + double this_distance = space.distance(get(position, *i), input_vector); + put(distance_from_input, *i, this_distance); + if (min_distance_unset || this_distance < min_distance) { + min_distance = this_distance; + min_distance_loc = *i; + } + min_distance_unset = false; + } + assert (!min_distance_unset); // Graph must have at least one vertex + boost::detail::update_position_visitor< + PositionMap, NodeDistanceMap, Topology, + VertexListAndIncidenceGraph> + update_position(position, node_distance, space, + input_vector, diameter, learning_constant, + exp(-1. / (2 * diameter * diameter))); + std::fill(node_distance_map_vector.begin(), node_distance_map_vector.end(), 0); + try { + typedef detail::gursoy_shortest shortest; + shortest::run(graph, min_distance_loc, node_distance, update_position, + weight); + } catch (detail::over_distance_limit) { + /* Thrown to break out of BFS or Dijkstra early */ + } +} + +template +void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + int nsteps, + double diameter_initial, + double diameter_final, + double learning_constant_initial, + double learning_constant_final, + VertexIndexMap vertex_index_map, + EdgeWeightMap weight) +{ +#ifndef BOOST_NO_STDC_NAMESPACE + using std::pow; + using std::exp; +#endif + + typedef typename graph_traits::vertex_iterator + vertex_iterator; + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + typedef typename Topology::point_type point_type; + vertex_iterator i, iend; + double diameter_ratio = (double)diameter_final / diameter_initial; + double learning_constant_ratio = + learning_constant_final / learning_constant_initial; + std::vector distance_from_input_vector(num_vertices(graph)); + typedef boost::iterator_property_map::iterator, + VertexIndexMap, + double, double&> + DistanceFromInputMap; + DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(), + vertex_index_map); + std::vector node_distance_map_vector(num_vertices(graph)); + typedef boost::iterator_property_map::iterator, + VertexIndexMap, double, double&> + NodeDistanceMap; + NodeDistanceMap node_distance(node_distance_map_vector.begin(), + vertex_index_map); + for (int round = 0; round < nsteps; ++round) { + double part_done = (double)round / (nsteps - 1); + int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done)); + double learning_constant = + learning_constant_initial * pow(learning_constant_ratio, part_done); + gursoy_atun_step(graph, space, position, diameter, learning_constant, + vertex_index_map, weight); + } +} + +template +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + int nsteps, + double diameter_initial, + double diameter_final, + double learning_constant_initial, + double learning_constant_final, + VertexIndexMap vertex_index_map, + EdgeWeightMap weight) +{ + typedef typename graph_traits::vertex_iterator + vertex_iterator; + vertex_iterator i, iend; + for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) { + put(position, *i, space.random_point()); + } + gursoy_atun_refine(graph, space, + position, nsteps, + diameter_initial, diameter_final, + learning_constant_initial, learning_constant_final, + vertex_index_map, weight); +} + +template +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + int nsteps, + double diameter_initial, + double diameter_final, + double learning_constant_initial, + double learning_constant_final, + VertexIndexMap vertex_index_map) +{ + gursoy_atun_layout(graph, space, position, nsteps, + diameter_initial, diameter_final, + learning_constant_initial, learning_constant_final, + vertex_index_map, dummy_property_map()); +} + +template +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + int nsteps, + double diameter_initial, + double diameter_final = 1.0, + double learning_constant_initial = 0.8, + double learning_constant_final = 0.2) +{ + gursoy_atun_layout(graph, space, position, nsteps, diameter_initial, + diameter_final, learning_constant_initial, + learning_constant_final, get(vertex_index, graph)); +} + +template +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + int nsteps) +{ +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif + + gursoy_atun_layout(graph, space, position, nsteps, + sqrt((double)num_vertices(graph))); +} + +template +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position) +{ + gursoy_atun_layout(graph, space, position, num_vertices(graph)); +} + +template +void +gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, + PositionMap position, + const bgl_named_params& params) +{ +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif + + std::pair diam(sqrt(double(num_vertices(graph))), 1.0); + std::pair learn(0.8, 0.2); + gursoy_atun_layout(graph, space, position, + choose_param(get_param(params, iterations_t()), + num_vertices(graph)), + choose_param(get_param(params, diameter_range_t()), + diam).first, + choose_param(get_param(params, diameter_range_t()), + diam).second, + choose_param(get_param(params, learning_constant_range_t()), + learn).first, + choose_param(get_param(params, learning_constant_range_t()), + learn).second, + choose_const_pmap(get_param(params, vertex_index), graph, + vertex_index), + choose_param(get_param(params, edge_weight), + dummy_property_map())); +} + +/*********************************************************** + * Topologies * + ***********************************************************/ +template +class convex_topology +{ + struct point + { + point() { } + double& operator[](std::size_t i) {return values[i];} + const double& operator[](std::size_t i) const {return values[i];} + + private: + double values[Dims]; + }; + + public: + typedef point point_type; + + double distance(point a, point b) const + { + double dist = 0; + for (std::size_t i = 0; i < Dims; ++i) { + double diff = b[i] - a[i]; + dist += diff * diff; + } + // Exact properties of the distance are not important, as long as + // < on what this returns matches real distances + return dist; + } + + point move_position_toward(point a, double fraction, point b) const + { + point result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] + (b[i] - a[i]) * fraction; + return result; + } +}; + +template +class hypercube_topology : public convex_topology +{ + typedef uniform_01 rand_t; + + public: + typedef typename convex_topology::point_type point_type; + + explicit hypercube_topology(double scaling = 1.0) + : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)), + scaling(scaling) + { } + + hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : gen_ptr(), rand(new rand_t(gen)), scaling(scaling) { } + + point_type random_point() const + { + point_type p; + for (std::size_t i = 0; i < Dims; ++i) + p[i] = (*rand)() * scaling; + return p; + } + + private: + shared_ptr gen_ptr; + shared_ptr rand; + double scaling; +}; + +template +class square_topology : public hypercube_topology<2, RandomNumberGenerator> +{ + typedef hypercube_topology<2, RandomNumberGenerator> inherited; + + public: + explicit square_topology(double scaling = 1.0) : inherited(scaling) { } + + square_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : inherited(gen, scaling) { } +}; + +template +class cube_topology : public hypercube_topology<3, RandomNumberGenerator> +{ + typedef hypercube_topology<3, RandomNumberGenerator> inherited; + + public: + explicit cube_topology(double scaling = 1.0) : inherited(scaling) { } + + cube_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : inherited(gen, scaling) { } +}; + +template +class ball_topology : public convex_topology +{ + typedef uniform_01 rand_t; + + public: + typedef typename convex_topology::point_type point_type; + + explicit ball_topology(double radius = 1.0) + : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)), + radius(radius) + { } + + ball_topology(RandomNumberGenerator& gen, double radius = 1.0) + : gen_ptr(), rand(new rand_t(gen)), radius(radius) { } + + point_type random_point() const + { + point_type p; + double dist_sum; + do { + dist_sum = 0.0; + for (std::size_t i = 0; i < Dims; ++i) { + double x = (*rand)() * 2*radius - radius; + p[i] = x; + dist_sum += x * x; + } + } while (dist_sum > radius*radius); + return p; + } + + private: + shared_ptr gen_ptr; + shared_ptr rand; + double radius; +}; + +template +class circle_topology : public ball_topology<2, RandomNumberGenerator> +{ + typedef ball_topology<2, RandomNumberGenerator> inherited; + + public: + explicit circle_topology(double radius = 1.0) : inherited(radius) { } + + circle_topology(RandomNumberGenerator& gen, double radius = 1.0) + : inherited(gen, radius) { } +}; + +template +class sphere_topology : public ball_topology<3, RandomNumberGenerator> +{ + typedef ball_topology<3, RandomNumberGenerator> inherited; + + public: + explicit sphere_topology(double radius = 1.0) : inherited(radius) { } + + sphere_topology(RandomNumberGenerator& gen, double radius = 1.0) + : inherited(gen, radius) { } +}; + +template +class heart_topology +{ + // Heart is defined as the union of three shapes: + // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000) + // Circle centered at (-500, -500) radius 500*sqrt(2) + // Circle centered at (500, -500) radius 500*sqrt(2) + // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1)) + + struct point + { + point() { values[0] = 0.0; values[1] = 0.0; } + point(double x, double y) { values[0] = x; values[1] = y; } + + double& operator[](std::size_t i) { return values[i]; } + double operator[](std::size_t i) const { return values[i]; } + + private: + double values[2]; + }; + + bool in_heart(point p) const + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::abs; + using std::pow; +#endif + + if (p[1] < abs(p[0]) - 2000) return false; // Bottom + if (p[1] <= -1000) return true; // Diagonal of square + if (pow(p[0] - -500, 2) + pow(p[1] - -500, 2) <= 500000) + return true; // Left circle + if (pow(p[0] - 500, 2) + pow(p[1] - -500, 2) <= 500000) + return true; // Right circle + return false; + } + + bool segment_within_heart(point p1, point p2) const + { + // Assumes that p1 and p2 are within the heart + if ((p1[0] < 0) == (p2[0] < 0)) return true; // Same side of symmetry line + if (p1[0] == p2[0]) return true; // Vertical + double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]); + double intercept = p1[1] - p1[0] * slope; + if (intercept > 0) return false; // Crosses between circles + return true; + } + + typedef uniform_01 rand_t; + + public: + typedef point point_type; + + heart_topology() + : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)) { } + + heart_topology(RandomNumberGenerator& gen) + : gen_ptr(), rand(new rand_t(gen)) { } + + point random_point() const + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif + + point result; + double sqrt2 = sqrt(2.); + do { + result[0] = (*rand)() * (1000 + 1000 * sqrt2) - (500 + 500 * sqrt2); + result[1] = (*rand)() * (2000 + 500 * (sqrt2 - 1)) - 2000; + } while (!in_heart(result)); + return result; + } + + double distance(point a, point b) const + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif + if (segment_within_heart(a, b)) { + // Straight line + return sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1])); + } else { + // Straight line bending around (0, 0) + return sqrt(a[0] * a[0] + a[1] * a[1]) + sqrt(b[0] * b[0] + b[1] * b[1]); + } + } + + point move_position_toward(point a, double fraction, point b) const + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif + + if (segment_within_heart(a, b)) { + // Straight line + return point(a[0] + (b[0] - a[0]) * fraction, + a[1] + (b[1] - a[1]) * fraction); + } else { + double distance_to_point_a = sqrt(a[0] * a[0] + a[1] * a[1]); + double distance_to_point_b = sqrt(b[0] * b[0] + b[1] * b[1]); + double location_of_point = distance_to_point_a / + (distance_to_point_a + distance_to_point_b); + if (fraction < location_of_point) + return point(a[0] * (1 - fraction / location_of_point), + a[1] * (1 - fraction / location_of_point)); + else + return point( + b[0] * ((fraction - location_of_point) / (1 - location_of_point)), + b[1] * ((fraction - location_of_point) / (1 - location_of_point))); + } + } + + private: + shared_ptr gen_ptr; + shared_ptr rand; +}; + +} // namespace boost + +#endif // BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP diff --git a/thirdparty/boost/graph/howard_cycle_ratio.hpp b/thirdparty/boost/graph/howard_cycle_ratio.hpp new file mode 100644 index 0000000..dfef8d7 --- /dev/null +++ b/thirdparty/boost/graph/howard_cycle_ratio.hpp @@ -0,0 +1,611 @@ +/*! +* Copyright 2007 Technical University of Catalonia +* +* Use, modification and distribution is subject to the Boost Software +* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* Authors: Dmitry Bufistov +* Andrey Parfenov +*/ + +#ifndef BOOST_GRAPH_HOWARD_CYCLE_RATIO_HOWARD_HPP +#define BOOST_GRAPH_HOWARD_CYCLE_RATIO_HOWARD_HPP + +/*! +* \file Maximum cycle ratio algorithm (Jean Cochet-Terrasson, Guy +* Cochen and others) +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace detail { + /// To avoid round error. + static const double mcr_howard_ltolerance = 0.00001; + + /*! + * Calculate maximum cycle ratio of "good" directed multigraph + * g. Use Howard's iteration policy algorithm ("Numerical + * Computation of Spectral Elements in MAX-PLUS algebra" by Jean + * Cochet-Terrasson, Guy Cochen and others). + * + * \param g = (V, E) - a "good" directed multigraph (out_degree of + * each vertex is greater then 0). If graph is strongly connected + * then it is "good". + * + * \param vim - Vertex Index, read property Map: V -> [0, + * num_vertices(g)). + * + * \param ewm - edge weight read property map: E -> R + * + * \param ewm2 - edge weight2 read property map: E -> R+ + * + * \return maximum_{for all cycles C}CR(C), or + * -(std::numeric_limits)::max() if g is not "good". + */ + template + class Cmcr_Howard + { + public: + Cmcr_Howard(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, + TWeight2EdgeMap ew2m) + : m_g(g), m_vim(vim), m_ew1m(ewm), m_ew2m(ew2m), + m_g2pi_g_vm(std::vector().end(), m_vim), /// Stupid dummy initialization + m_minus_infinity(-(std::numeric_limits::max)()) + { + typedef typename boost::graph_traits::directed_category DirCat; + BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); + m_cr = m_minus_infinity; + } + + double operator()() + { + return maximum_cycle_ratio_Howard(); + } + + virtual ~Cmcr_Howard() { } + + protected: + typedef typename boost::graph_traits::vertex_descriptor + mcr_vertex_t; + typedef typename boost::graph_traits::edge_descriptor + mcr_edge_t; + + const TGraph& m_g; + typedef std::vector eigenmode_t; + eigenmode_t m_eigen_value; + eigenmode_t m_eigen_vector; + TVertexIndexMap m_vim; + TWeight1EdgeMap m_ew1m; + TWeight2EdgeMap m_ew2m; + + typedef typename boost::remove_const::value_type>::type mcr_edge_weight1_t; + typedef typename boost::remove_const::value_type>::type mcr_edge_weight2_t; + typedef typename boost::adjacency_list< + boost::listS, boost::vecS, boost::bidirectionalS, + boost::no_property, + boost::property > > + pi_graph_t; + typedef typename boost::property_map::type TPiGraphVertexIndexMap; + typedef typename boost::property_map::type TPiGraphEdgeWeight1Map; + typedef typename boost::property_map::type TPiGraphEdgeWeight2Map; + + typedef typename boost::property_traits::value_type pigraph_vertex_index_t; + + pi_graph_t m_pi_g; + typedef typename boost::graph_traits::vertex_descriptor pi_vertex_t; + typedef typename boost::graph_traits::edge_descriptor pi_edge_t; + typedef typename boost::iterator_property_map::iterator, TVertexIndexMap> g2pi_g_vm_t; + g2pi_g_vm_t m_g2pi_g_vm; ///Graph to Pi graph vertex map + std::vector m_g2pig; + int m_step_number; + const double m_minus_infinity; + typedef typename std::vector critical_cycle_t; + double m_cr; ///Cycle ratio that already has been found + + class bad_graph + { + public: + typedef typename boost::property_traits::value_type + v_index_t; + + bad_graph(v_index_t bvi) : bad_vertex_index(bvi) {} + v_index_t what() const throw() + { + return bad_vertex_index; + } + + private: + v_index_t bad_vertex_index; + }; + + double maximum_cycle_ratio_Howard() + { + try + { + construct_pi_graph(); + } + catch (const bad_graph& a) + { + return m_minus_infinity; + } + std::vector max_eigen_val(boost::num_vertices(m_g)); + m_eigen_value.resize(boost::num_vertices(m_g)); + m_eigen_vector.resize(boost::num_vertices(m_g)); + m_step_number = 0; + do + { + pi_eingen_value(get(vertex_index, m_pi_g), get(boost::edge_weight, m_pi_g), get(boost::edge_weight2, m_pi_g)); + ++m_step_number; + } + while (improve_policy_try1(max_eigen_val) || improve_policy_try2(max_eigen_val)); + return *(std::max_element(m_eigen_value.begin(), m_eigen_value.end())); + } + + /*! + * Construct an arbitrary policy m_pi_g. + */ + void construct_pi_graph() + { + m_g2pig.resize(boost::num_vertices(m_g)); + m_g2pi_g_vm = boost::make_iterator_property_map(m_g2pig.begin(), m_vim); + BGL_FORALL_VERTICES_T(vd, m_g, TGraph) + { + m_g2pi_g_vm[vd] = boost::add_vertex(m_pi_g); + store_pivertex(m_g2pi_g_vm[vd], vd); + } + BGL_FORALL_VERTICES_T(vd1, m_g, TGraph) + { + if (boost::out_edges(vd1, m_g).first == boost::out_edges(vd1, m_g).second) throw bad_graph(m_vim[vd1]); + mcr_edge_t ed = *boost::out_edges(vd1, m_g).first; + pi_edge_t pied = boost::add_edge(m_g2pi_g_vm[source(ed, m_g)], m_g2pi_g_vm[target(ed, m_g)], m_pi_g).first; + boost::put(boost::edge_weight, m_pi_g, pied, m_ew1m[ed]); + boost::put(boost::edge_weight2, m_pi_g, pied, m_ew2m[ed]); + } + } + + class bfs_eingmode_visitor : public boost::default_bfs_visitor + { + public: + bfs_eingmode_visitor(TPiGraphVertexIndexMap vi_m, TPiGraphEdgeWeight1Map w_m, TPiGraphEdgeWeight2Map& d_m, + eigenmode_t& e_val, eigenmode_t& e_vec, double ev) : m_index_map(vi_m), m_weight_map(w_m), m_delay_map(d_m), + m_eig_value(&e_val), m_eig_vec(&e_vec), m_eigen_value(ev) { } + + template < typename Edge, typename g_t> + void examine_edge(Edge e, const g_t & g) const + { + typedef typename boost::graph_traits::vertex_descriptor Vertex; + Vertex u = boost::target(e, g), v = boost::source(e, g); + pigraph_vertex_index_t ind = m_index_map[u]; + (*m_eig_value)[ind] = m_eigen_value; + (*m_eig_vec)[ind] = m_weight_map[e] - m_eigen_value * m_delay_map[e] + (*m_eig_vec)[m_index_map[v]]; + } + private: + TPiGraphVertexIndexMap m_index_map; + TPiGraphEdgeWeight1Map m_weight_map; + TPiGraphEdgeWeight2Map m_delay_map; + eigenmode_t* m_eig_value; + eigenmode_t* m_eig_vec; + double m_eigen_value; + }; + + /*! + * Find a vertex in the Pi Graph which belongs to cycle, just a DFV until back edge found + */ + pi_vertex_t find_good_source(const pi_vertex_t start_vertex) + { + pi_vertex_t good_vertex = start_vertex; + typename std::set s; + s.insert(start_vertex); + do + { + good_vertex = boost::target(*boost::out_edges(good_vertex, m_pi_g).first, m_pi_g); + } + while (s.insert(good_vertex).second); + return good_vertex; + } + virtual void store_pivertex(pi_vertex_t pivd, mcr_vertex_t vd) {} + virtual void store_critical_edge(pi_edge_t ed, critical_cycle_t& cc) {} + virtual void store_critical_cycle(critical_cycle_t& cc) {} + + /*! + * \param startV - vertex that belongs to a cycle in policy graph m_pi_g + */ + double calculate_eigen_value(pi_vertex_t startV) + { + std::pair accum_sums(0., 0.); + pi_vertex_t vd = startV; + critical_cycle_t cc; + do + { + pi_edge_t tmp_ed = *(boost::out_edges(vd, m_pi_g).first); + store_critical_edge(tmp_ed, cc); + accum_sums.first += boost::get(boost::edge_weight, m_pi_g, tmp_ed); + accum_sums.second += boost::get(boost::edge_weight2, m_pi_g, tmp_ed); + vd = boost::target(tmp_ed, m_pi_g); + } + while (vd != startV); + //assert((std::abs(accum_sums.first) <= 0.00000001) && "Division by zerro!"); + double cr = accum_sums.first / accum_sums.second; + if (cr > m_cr) + { + m_cr = cr; + store_critical_cycle(cc); + } + else + { + + } + return cr; + } + + /*! + * Value determination. Find a generalized eigenmode (n^{k+1}, x^{k+1}) of A^{Ï_{k+1}} of the pi graph (Algorithm IV.1). + */ + void pi_eingen_value( + TPiGraphVertexIndexMap index_map, + TPiGraphEdgeWeight1Map weight_map, + TPiGraphEdgeWeight2Map weigh2_map) + { + using namespace boost; + typedef std::vector color_map_t; + color_map_t vcm(num_vertices(m_pi_g), white_color);//Vertex color map + color_map_t::iterator uv_itr = vcm.begin(); //Undiscovered vertex + reverse_graph rev_g(m_pi_g); //For backward breadth visit + + while ((uv_itr = std::find_if(uv_itr, vcm.end(), + boost::bind(std::equal_to(), boost::white_color, _1))) != vcm.end()) + ///While there are undiscovered vertices + { + pi_vertex_t gv = find_good_source(pi_vertex_t(uv_itr - vcm.begin())); + pigraph_vertex_index_t gv_ind = index_map[gv]; + m_eigen_value[gv_ind] = calculate_eigen_value(gv) ; + bfs_eingmode_visitor bfs_vis(index_map, weight_map, weigh2_map, m_eigen_value, m_eigen_vector, m_eigen_value[gv_ind]); + typename boost::queue Q; + breadth_first_visit(rev_g, gv, Q, bfs_vis, make_iterator_property_map(vcm.begin(), index_map)); + } + } + + void improve_policy(mcr_vertex_t vd, mcr_edge_t new_edge) + { + remove_edge(*(out_edges(m_g2pi_g_vm[vd], m_pi_g).first), m_pi_g); + pi_edge_t ned = add_edge(m_g2pi_g_vm[vd], m_g2pi_g_vm[target(new_edge, m_g)], m_pi_g).first; + put(edge_weight, m_pi_g, ned, m_ew1m[new_edge]); + put(edge_weight2, m_pi_g, ned, m_ew2m[new_edge]); + } + /*! + * Policy Improvement. Improve the policy graph. The new policy graph has greater cycle ratio. + * \return false if nothing can be improved. + */ + bool improve_policy_try1(std::vector& max_eing_vals) + { + bool improved = false; + BGL_FORALL_VERTICES_T(vd, m_g, TGraph) + { + double max_ev = m_minus_infinity;/// Maximum eigen value for vertex + mcr_edge_t cr_ed;///Critical edge + + BGL_FORALL_OUTEDGES_T(vd, outed, m_g, TGraph) + { + if (m_eigen_value[m_vim[target(outed, m_g)]] > max_ev) + { + max_ev = m_eigen_value[m_vim[boost::target(outed, m_g)]]; + cr_ed = outed; + } + } + if (max_ev > m_eigen_value[get(m_vim,vd)]) + { + improve_policy(vd, cr_ed); + improved = true; + } + max_eing_vals[get(m_vim,vd)] = max_ev; + } + return improved; + } + + /*! + * \param max_eigen_values[u] = max_(for all adjacent vertices (u,v)) m_eigen_value[v] + */ + bool improve_policy_try2(const std::vector& max_eigen_values) + { + bool improved = false; + BGL_FORALL_VERTICES_T(vd, m_g, TGraph) + { + mcr_edge_t impr_edge; + double max_val = m_minus_infinity; + BGL_FORALL_OUTEDGES_T(vd, outed, m_g, TGraph) + { + ///If vertex vd is in the K(vd) set + if (max_eigen_values[get(m_vim, vd)] <= m_eigen_value[get(m_vim, target(outed, m_g))]) + { + double c_val = m_ew1m[outed] - m_ew2m[outed] * m_eigen_value[m_vim[boost::target(outed, m_g)]] + + m_eigen_vector[m_vim[boost::target(outed, m_g)]]; + if (c_val > max_val) + { + max_val = c_val; + impr_edge = outed; + } + } + } + if ((max_val - m_eigen_vector[get(m_vim, vd)]) > mcr_howard_ltolerance) + ///If m_eigen_vector[vd] == max_val + { + improve_policy(vd, impr_edge); + improved = true; + } + } + return improved; + } + };///Cmcr_Howard + + /*! + * \return maximum cycle ratio and one critical cycle. + */ + template + class Cmcr_Howard1 : public Cmcr_Howard + { + public: + typedef Cmcr_Howard inhr_t; + Cmcr_Howard1(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m) : inhr_t(g, vim, ewm, ew2m) + { + m_pi_g2g.resize(boost::num_vertices(g)); + m_pi_g2g_vm = boost::make_iterator_property_map(m_pi_g2g.begin(), boost::get(boost::vertex_index, this->m_pi_g)); + } + + void get_critical_cycle(typename inhr_t::critical_cycle_t& cc) { return cc.swap(m_critical_cycle); } + protected: + void store_pivertex(typename inhr_t::pi_vertex_t pivd, typename inhr_t::mcr_vertex_t vd) + { + m_pi_g2g_vm[pivd] = vd; + } + void store_critical_edge(typename inhr_t::pi_edge_t ed, typename inhr_t::critical_cycle_t& cc) + { + typename inhr_t::pi_vertex_t s = boost::source(ed, this->m_pi_g); + typename inhr_t::pi_vertex_t t = boost::target(ed, this->m_pi_g); + assert(boost::edge(m_pi_g2g_vm[s], m_pi_g2g_vm[t], this->m_g).second); + cc.push_back(boost::edge(m_pi_g2g_vm[s], m_pi_g2g_vm[t], this->m_g).first); ///Store corresponding edge of the m_g + } + void store_critical_cycle(typename inhr_t::critical_cycle_t& cc) + { + m_critical_cycle.swap(cc); + } + private: + typename inhr_t::critical_cycle_t m_critical_cycle; + typedef typename boost::iterator_property_map::iterator, typename inhr_t::TPiGraphVertexIndexMap> pi_g2g_vm_t; + pi_g2g_vm_t m_pi_g2g_vm; ///Maps policy graph vertices to input graph vertices + typename std::vector m_pi_g2g; + }; + + /*! + * Add sink vertex - this will make any graph good, the selfloop will have ratio equal to infinity + * Properties must be "self increasing" + */ + template + typename boost::graph_traits::vertex_descriptor + make_graph_good(TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m, + typename boost::property_traits::value_type infinity) + { + typedef typename boost::graph_traits::edge_descriptor Edge; + typename boost::graph_traits::vertex_descriptor sink = boost::add_vertex(g); + + BGL_FORALL_VERTICES_T(vd, g, TGraph) + { + Edge newed = boost::add_edge(vd, sink, g).first; + boost::put(ewm, newed, 0); + boost::put(ew2m, newed, 1); + } + Edge selfed = boost::edge(sink, sink, g).first; + boost::put(ewm, selfed, infinity); + return sink; + } + + /*! + * Construct from input graph g "safe" (suitable for maximum_cycle_ratio1() call) version - safeg + */ + template + void construct_safe_graph(const TG& g, TIndVertexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m, TSafeG& safeg, SafeG2GEdgeMap& sg2gm) + { + assert(num_vertices(g) == num_vertices(safeg)); + typedef typename graph_traits::edge_descriptor tmp_edge_t; + typedef typename graph_traits::edge_descriptor edge_t; + typename graph_traits::edge_iterator ei, ei_end; + + for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + tmp_edge_t tmped = add_edge(vim[source(*ei, g)], vim[target(*ei, g)], safeg).first; + sg2gm[tmped] = *ei; + put(edge_weight, safeg, tmped, get(ew1m, *ei)); + put(edge_weight2, safeg, tmped, get(ew2m, *ei)); + } + } + + template + double maximum_cycle_ratio_good_graph(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m, + typename std::vector::edge_descriptor>* pcc = 0) + { + if (pcc == 0) + { + return detail::Cmcr_Howard(g, vim, ewm, ew2m)(); + } + else + { + detail::Cmcr_Howard1 obj(g, vim, ewm, ew2m); + double maxcr = obj(); + obj.get_critical_cycle(*pcc); + return maxcr; + } + } + + template + double minimum_cycle_ratio_good_graph(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, + TWeight2EdgeMap ew2m, TEdgeIndexMap eim, + typename std::vector::edge_descriptor>* pcc = 0) + { + typedef typename boost::remove_const::value_type>::type weight_value_t; + BOOST_STATIC_ASSERT(!is_integral::value || is_signed::value); + typename std::vector ne_w(boost::num_edges(g)); + BGL_FORALL_EDGES_T(ed, g, TGraph) ne_w[boost::get(eim, ed)] = -ewm[ed]; + return -maximum_cycle_ratio_good_graph(g, vim, boost::make_iterator_property_map(ne_w.begin(), eim), ew2m, pcc); + } + + /*! + * \param g directed multigraph. + * \param pcc - pointer to the critical edges list. + * \param minus_infinity must be small enough to garanty that g has at least one cycle with greater ratio. + * \return minus_infinity if there're no cycles in the graph + */ + template + double maximum_cycle_ratio1(const TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type minus_infinity = -(std::numeric_limits::max)()) + { + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits::edge_descriptor Edge; + boost::function_requires< boost::ReadWritePropertyMapConcept >(); + boost::function_requires< boost::ReadWritePropertyMapConcept >(); + + TGraph& ncg = const_cast(g); + Vertex sink = detail::make_graph_good(ncg, ewm, ew2m, minus_infinity ); + + double res = maximum_cycle_ratio_good_graph(ncg, boost::get(boost::vertex_index, g), ewm, ew2m, pcc); + boost::clear_vertex(sink, ncg); boost::remove_vertex(sink, ncg); + return res; + } + + /*! + * Edge index MUST be in diapazon [0,..., num_edges(g)-1] + * \return plus_infinity if g has no cycles. + */ + template + double minimum_cycle_ratio1(const TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m, TEdgeIndexMap eim, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type plus_infinity = (std::numeric_limits::max)() + ) + { + typedef typename boost::property_traits::value_type ei_t; + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits::edge_descriptor Edge; + + boost::function_requires< boost::ReadWritePropertyMapConcept >(); + boost::function_requires< boost::ReadWritePropertyMapConcept >(); + boost::function_requires< boost::ReadWritePropertyMapConcept >(); + + TGraph& ncg = const_cast(g); + + ei_t nei = ei_t(boost::num_edges(g)); + Vertex sink = detail::make_graph_good(ncg, ewm, ew2m, plus_infinity ); + ///Maintain edge index invariant + BGL_FORALL_VERTICES_T(vd, ncg, TGraph) + { + typename boost::graph_traits::edge_descriptor ed = boost::edge(vd, sink, ncg).first; + boost::put(eim, ed, nei++); + } + double res = minimum_cycle_ratio_good_graph(ncg, boost::get(boost::vertex_index, ncg), ewm, ew2m, eim, pcc); + boost::clear_vertex(sink, ncg); boost::remove_vertex(sink, ncg); + return res; + } + struct edge_less_than + { + template bool operator()(const TEdgeDescriptor& x, const TEdgeDescriptor& y) const + { + return x.get_property() < y.get_property(); + } + }; + }///namespace detail + namespace + { + template struct safe_graph + { + typedef typename boost::adjacency_list > > type; + }; + } + + /*! + * Calculate the maximum cycle ratio (mcr) of the directed multigraph g. + * \param g directed multigraph + * \param pcc - If provided then a critical cycle will be written to corresponding vector. + * \param minus_infinity small enough value to garanty that g has at least one cycle with greater ratio. + * \return mcr or minus_infinity if g has no cycles. + */ + template + double maximum_cycle_ratio(const TGraph& g, TVertexIndexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type minus_infinity = + -(std::numeric_limits::max)()) + { + typedef typename remove_const::value_type>::type w1_t; + typedef typename remove_const::value_type>::type w2_t; + typedef typename safe_graph::type safe_graph_t; + typedef typename graph_traits::edge_descriptor tmp_edge_t; + typedef typename graph_traits::edge_descriptor edge_t; + typename std::map tmpg2g; + std::vector cc; + safe_graph_t sg(num_vertices(g)); + detail::construct_safe_graph(g, vim, ew1m, ew2m, sg, tmpg2g); + double mcr = maximum_cycle_ratio1(sg, get(edge_weight, sg), get(edge_weight2, sg), pcc ? &cc : 0, minus_infinity); + if (pcc && (mcr > minus_infinity)) + { + pcc->clear(); + for (typename std::vector::iterator it = cc.begin(); it != cc.end(); ++it) pcc->push_back(tmpg2g[*it]); + } + return mcr; + } + + template + double minimum_cycle_ratio(const TGraph& g, TVertexIndexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m, TIndEdgeMap eim, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type plus_infinity = + (std::numeric_limits::max)()) + { + typedef typename boost::remove_const::value_type>::type weight_value_t; + BOOST_STATIC_ASSERT(!is_integral::value || is_signed::value); + typename std::vector ne_w(boost::num_edges(g)); + BGL_FORALL_EDGES_T(ed, g, TGraph) ne_w[boost::get(eim, ed)] = -ew1m[ed]; + return -maximum_cycle_ratio(g, vim, boost::make_iterator_property_map(ne_w.begin(), eim), ew2m, pcc, -plus_infinity); + } + /*! + * Calculate maximum mean cycle of directed weighted multigraph. + * \param g directed multigraph + * \return maximum mean cycle of g or minus_infinity if g has no cycles. + */ + template + double maximum_mean_cycle(const TGraph& g, TVertexIndexMap vim, TWeightEdgeMap ewm, TIndEdgeMap eim, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type minus_infinity = + -(std::numeric_limits::max)()) + { + typedef typename boost::remove_const::value_type>::type weight_value_t; + typedef typename boost::graph_traits::edge_descriptor Edge; + typename std::vector ed_w2(boost::num_edges(g), 1); + return maximum_cycle_ratio(g, vim, ewm, boost::make_iterator_property_map(ed_w2.begin(), eim), pcc, minus_infinity); + } + + template + double minimum_mean_cycle(const TGraph& g, TVertexIndexMap vim, TWeightEdgeMap ewm, TIndEdgeMap eim, + typename std::vector::edge_descriptor>* pcc = 0, + typename boost::property_traits::value_type plus_infinity = + (std::numeric_limits::max)()) + { + typedef typename boost::remove_const::value_type>::type weight_value_t; + typedef typename boost::graph_traits::edge_descriptor Edge; + typename std::vector ed_w2(boost::num_edges(g), 1); + return minimum_cycle_ratio(g, vim, ewm, boost::make_iterator_property_map(ed_w2.begin(), eim), eim, pcc, plus_infinity); + } +} //namespace boost +#endif diff --git a/thirdparty/boost/graph/incremental_components.hpp b/thirdparty/boost/graph/incremental_components.hpp new file mode 100644 index 0000000..25e3f5c --- /dev/null +++ b/thirdparty/boost/graph/incremental_components.hpp @@ -0,0 +1,170 @@ +// +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_INCREMENTAL_COMPONENTS_HPP +#define BOOST_INCREMENTAL_COMPONENTS_HPP + +#include +#include + +namespace boost { + + // A connected component algorithm for the case when dynamically + // adding (but not removing) edges is common. The + // incremental_components() function is a preparing operation. Call + // same_component to check whether two vertices are in the same + // component, or use disjoint_set::find_set to determine the + // representative for a vertex. + + // This version of connected components does not require a full + // Graph. Instead, it just needs an edge list, where the vertices of + // each edge need to be of integer type. The edges are assumed to + // be undirected. The other difference is that the result is stored in + // a container, instead of just a decorator. The container should be + // empty before the algorithm is called. It will grow during the + // course of the algorithm. The container must be a model of + // BackInsertionSequence and RandomAccessContainer + // (std::vector is a good choice). After running the algorithm the + // index container will map each vertex to the representative + // vertex of the component to which it belongs. + // + // Adapted from an implementation by Alex Stepanov. The disjoint + // sets data structure is from Tarjan's "Data Structures and Network + // Algorithms", and the application to connected components is + // similar to the algorithm described in Ch. 22 of "Intro to + // Algorithms" by Cormen, et. all. + // + // RankContainer is a random accessable container (operator[] is + // defined) with a value type that can represent an integer part of + // a binary log of the value type of the corresponding + // ParentContainer (char is always enough) its size_type is no less + // than the size_type of the corresponding ParentContainer + + // An implementation of disjoint sets can be found in + // boost/pending/disjoint_sets.hpp + + template + void incremental_components(EdgeListGraph& g, DisjointSets& ds) + { + typename graph_traits::edge_iterator e, end; + for (tie(e,end) = edges(g); e != end; ++e) + ds.union_set(source(*e,g),target(*e,g)); + } + + template + void compress_components(ParentIterator first, ParentIterator last) + { + for (ParentIterator current = first; current != last; ++current) + detail::find_representative_with_full_compression(first, current-first); + } + + template + typename boost::detail::iterator_traits::difference_type + component_count(ParentIterator first, ParentIterator last) + { + std::ptrdiff_t count = 0; + for (ParentIterator current = first; current != last; ++current) + if (*current == current - first) ++count; + return count; + } + + // This algorithm can be applied to the result container of the + // connected_components algorithm to normalize + // the components. + template + void normalize_components(ParentIterator first, ParentIterator last) + { + for (ParentIterator current = first; current != last; ++current) + detail::normalize_node(first, current - first); + } + + template + void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds) + { + typename graph_traits + ::vertex_iterator v, vend; + for (tie(v, vend) = vertices(G); v != vend; ++v) + ds.make_set(*v); + } + + template + inline bool same_component(Vertex u, Vertex v, DisjointSet& ds) + { + return ds.find_set(u) == ds.find_set(v); + } + + // considering changing the so that it initializes with a pair of + // vertex iterators and a parent PA. + + template + class component_index + { + public://protected: (avoid friends for now) + typedef std::vector MyIndexContainer; + MyIndexContainer header; + MyIndexContainer index; + typedef typename MyIndexContainer::size_type SizeT; + typedef typename MyIndexContainer::const_iterator IndexIter; + public: + typedef detail::component_iterator + component_iterator; + class component { + friend class component_index; + protected: + IndexT number; + const component_index* comp_ind_ptr; + component(IndexT i, const component_index* p) + : number(i), comp_ind_ptr(p) {} + public: + typedef component_iterator iterator; + typedef component_iterator const_iterator; + typedef IndexT value_type; + iterator begin() const { + return iterator( comp_ind_ptr->index.begin(), + (comp_ind_ptr->header)[number] ); + } + iterator end() const { + return iterator( comp_ind_ptr->index.begin(), + comp_ind_ptr->index.size() ); + } + }; + typedef SizeT size_type; + typedef component value_type; + +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + template + component_index(Iterator first, Iterator last) + : index(std::distance(first, last)) + { + std::copy(first, last, index.begin()); + detail::construct_component_index(index, header); + } +#else + template + component_index(Iterator first, Iterator last) + : index(first, last) + { + detail::construct_component_index(index, header); + } +#endif + + component operator[](IndexT i) const { + return component(i, this); + } + SizeT size() const { + return header.size(); + } + + }; + +} // namespace boost + +#endif // BOOST_INCREMENTAL_COMPONENTS_HPP diff --git a/thirdparty/boost/graph/is_kuratowski_subgraph.hpp b/thirdparty/boost/graph/is_kuratowski_subgraph.hpp new file mode 100644 index 0000000..5cdf686 --- /dev/null +++ b/thirdparty/boost/graph/is_kuratowski_subgraph.hpp @@ -0,0 +1,332 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __IS_KURATOWSKI_SUBGRAPH_HPP__ +#define __IS_KURATOWSKI_SUBGRAPH_HPP__ + +#include +#include //for next/prior +#include //for tie +#include +#include +#include +#include + +#include +#include +#include + + + +namespace boost +{ + + namespace detail + { + + template + Graph make_K_5() + { + typename graph_traits::vertex_iterator vi, vi_end, inner_vi; + Graph K_5(5); + for(tie(vi,vi_end) = vertices(K_5); vi != vi_end; ++vi) + for(inner_vi = next(vi); inner_vi != vi_end; ++inner_vi) + add_edge(*vi, *inner_vi, K_5); + return K_5; + } + + + template + Graph make_K_3_3() + { + typename graph_traits::vertex_iterator + vi, vi_end, bipartition_start, inner_vi; + Graph K_3_3(6); + bipartition_start = next(next(next(vertices(K_3_3).first))); + for(tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start; ++vi) + for(inner_vi= bipartition_start; inner_vi != vi_end; ++inner_vi) + add_edge(*vi, *inner_vi, K_3_3); + return K_3_3; + } + + + template + void contract_edge(AdjacencyList& neighbors, Vertex u, Vertex v) + { + // Remove u from v's neighbor list + neighbors[v].erase(std::remove(neighbors[v].begin(), + neighbors[v].end(), u + ), + neighbors[v].end() + ); + + // Replace any references to u with references to v + typedef typename AdjacencyList::value_type::iterator + adjacency_iterator_t; + + adjacency_iterator_t u_neighbor_end = neighbors[u].end(); + for(adjacency_iterator_t u_neighbor_itr = neighbors[u].begin(); + u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr + ) + { + Vertex u_neighbor(*u_neighbor_itr); + std::replace(neighbors[u_neighbor].begin(), + neighbors[u_neighbor].end(), u, v + ); + } + + // Remove v from u's neighbor list + neighbors[u].erase(std::remove(neighbors[u].begin(), + neighbors[u].end(), v + ), + neighbors[u].end() + ); + + // Add everything in u's neighbor list to v's neighbor list + std::copy(neighbors[u].begin(), + neighbors[u].end(), + std::back_inserter(neighbors[v]) + ); + + // Clear u's neighbor list + neighbors[u].clear(); + + } + + } // namespace detail + + + + + template + bool is_kuratowski_subgraph(const Graph& g, + ForwardIterator begin, + ForwardIterator end, + VertexIndexMap vm + ) + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::edges_size_type e_size_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename std::vector v_list_t; + typedef typename v_list_t::iterator v_list_iterator_t; + typedef iterator_property_map + ::iterator, VertexIndexMap> + vertex_to_v_list_map_t; + + typedef adjacency_list small_graph_t; + + enum target_graph_t { k_3_3, k_5}; + + target_graph_t target_graph = k_3_3; //unless we decide otherwise later + + static small_graph_t K_5(detail::make_K_5()); + + static small_graph_t K_3_3(detail::make_K_3_3()); + + v_size_t n_vertices(num_vertices(g)); + v_size_t max_num_edges(3*n_vertices - 5); + + std::vector neighbors_vector(n_vertices); + vertex_to_v_list_map_t neighbors(neighbors_vector.begin(), vm); + + e_size_t count = 0; + for(ForwardIterator itr = begin; itr != end; ++itr) + { + + if (count++ > max_num_edges) + return false; + + edge_t e(*itr); + vertex_t u(source(e,g)); + vertex_t v(target(e,g)); + + neighbors[u].push_back(v); + neighbors[v].push_back(u); + + } + + + for(v_size_t max_size = 2; max_size < 5; ++max_size) + { + + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_t v(*vi); + + //a hack to make sure we don't contract the middle edge of a path + //of four degree-3 vertices + if (max_size == 4 && neighbors[v].size() == 3) + { + if (neighbors[neighbors[v][0]].size() + + neighbors[neighbors[v][1]].size() + + neighbors[neighbors[v][2]].size() + < 11 // so, it has two degree-3 neighbors + ) + continue; + } + + while (neighbors[v].size() > 0 && neighbors[v].size() < max_size) + { + // Find one of v's neighbors u such that that v and u + // have no neighbors in common. We'll look for such a + // neighbor with a naive cubic-time algorithm since the + // max size of any of the neighbor sets we'll consider + // merging is 3 + + bool neighbor_sets_intersect = false; + + vertex_t min_u = graph_traits::null_vertex(); + vertex_t u; + v_list_iterator_t v_neighbor_end = neighbors[v].end(); + for(v_list_iterator_t v_neighbor_itr = neighbors[v].begin(); + v_neighbor_itr != v_neighbor_end; + ++v_neighbor_itr + ) + { + neighbor_sets_intersect = false; + u = *v_neighbor_itr; + v_list_iterator_t u_neighbor_end = neighbors[u].end(); + for(v_list_iterator_t u_neighbor_itr = + neighbors[u].begin(); + u_neighbor_itr != u_neighbor_end && + !neighbor_sets_intersect; + ++u_neighbor_itr + ) + { + for(v_list_iterator_t inner_v_neighbor_itr = + neighbors[v].begin(); + inner_v_neighbor_itr != v_neighbor_end; + ++inner_v_neighbor_itr + ) + { + if (*u_neighbor_itr == *inner_v_neighbor_itr) + { + neighbor_sets_intersect = true; + break; + } + } + + } + if (!neighbor_sets_intersect && + (min_u == graph_traits::null_vertex() || + neighbors[u].size() < neighbors[min_u].size()) + ) + { + min_u = u; + } + + } + + if (min_u == graph_traits::null_vertex()) + // Exited the loop without finding an appropriate neighbor of + // v, so v must be a lost cause. Move on to other vertices. + break; + else + u = min_u; + + detail::contract_edge(neighbors, u, v); + + }//end iteration over v's neighbors + + }//end iteration through vertices v + + if (max_size == 3) + { + // check to see whether we should go on to find a K_5 + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + if (neighbors[*vi].size() == 4) + { + target_graph = k_5; + break; + } + + if (target_graph == k_3_3) + break; + } + + }//end iteration through max degree 2,3, and 4 + + + //Now, there should only be 5 or 6 vertices with any neighbors. Find them. + + v_list_t main_vertices; + vertex_iterator_t vi, vi_end; + + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + if (!neighbors[*vi].empty()) + main_vertices.push_back(*vi); + } + + // create a graph isomorphic to the contracted graph to test + // against K_5 and K_3_3 + small_graph_t contracted_graph(main_vertices.size()); + std::map::vertex_descriptor> + contracted_vertex_map; + + typename v_list_t::iterator itr, itr_end; + itr_end = main_vertices.end(); + typename graph_traits::vertex_iterator + si = vertices(contracted_graph).first; + + for(itr = main_vertices.begin(); itr != itr_end; ++itr, ++si) + { + contracted_vertex_map[*itr] = *si; + } + + typename v_list_t::iterator jtr, jtr_end; + for(itr = main_vertices.begin(); itr != itr_end; ++itr) + { + jtr_end = neighbors[*itr].end(); + for(jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr) + { + if (get(vm,*itr) < get(vm,*jtr)) + { + add_edge(contracted_vertex_map[*itr], + contracted_vertex_map[*jtr], + contracted_graph + ); + } + } + } + + if (target_graph == k_5) + { + return isomorphism(K_5,contracted_graph); + } + else //target_graph == k_3_3 + { + return isomorphism(K_3_3,contracted_graph); + } + + + } + + + + + + template + bool is_kuratowski_subgraph(const Graph& g, + ForwardIterator begin, + ForwardIterator end + ) + { + return is_kuratowski_subgraph(g, begin, end, get(vertex_index,g)); + } + + + + +} + +#endif //__IS_KURATOWSKI_SUBGRAPH_HPP__ diff --git a/thirdparty/boost/graph/is_straight_line_drawing.hpp b/thirdparty/boost/graph/is_straight_line_drawing.hpp new file mode 100644 index 0000000..e823477 --- /dev/null +++ b/thirdparty/boost/graph/is_straight_line_drawing.hpp @@ -0,0 +1,232 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __IS_STRAIGHT_LINE_DRAWING_HPP__ +#define __IS_STRAIGHT_LINE_DRAWING_HPP__ + +#include +#include //for next and prior +#include +#include +#include +#include +#include + +#include +#include +#include + + + +namespace boost +{ + + // Return true exactly when the line segments s1 = ((x1,y1), (x2,y2)) and + // s2 = ((a1,b1), (a2,b2)) intersect in a point other than the endpoints of + // the line segments. The one exception to this rule is when s1 = s2, in + // which case false is returned - this is to accomodate multiple edges + // between the same pair of vertices, which shouldn't invalidate the straight + // line embedding. A tolerance variable epsilon can also be used, which + // defines how far away from the endpoints of s1 and s2 we want to consider + // an intersection. + + bool intersects(double x1, double y1, + double x2, double y2, + double a1, double b1, + double a2, double b2, + double epsilon = 0.000001 + ) + { + + if (x1 - x2 == 0) + { + std::swap(x1,a1); + std::swap(y1,b1); + std::swap(x2,a2); + std::swap(y2,b2); + } + + if (x1 - x2 == 0) + { + BOOST_USING_STD_MAX(); + BOOST_USING_STD_MIN(); + + //two vertical line segments + double min_y = min BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2); + double max_y = max BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2); + double min_b = min BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2); + double max_b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2); + if ((max_y > max_b && max_b > min_y) || + (max_b > max_y && max_y > min_b) + ) + return true; + else + return false; + } + + double x_diff = x1 - x2; + double y_diff = y1 - y2; + double a_diff = a2 - a1; + double b_diff = b2 - b1; + + double beta_denominator = b_diff - (y_diff/((double)x_diff)) * a_diff; + + if (beta_denominator == 0) + { + //parallel lines + return false; + } + + double beta = (b2 - y2 - (y_diff/((double)x_diff)) * (a2 - x2)) / + beta_denominator; + double alpha = (a2 - x2 - beta*(a_diff))/x_diff; + + double upper_bound = 1 - epsilon; + double lower_bound = 0 + epsilon; + + return (beta < upper_bound && beta > lower_bound && + alpha < upper_bound && alpha > lower_bound); + + } + + + template + bool is_straight_line_drawing(const Graph& g, + GridPositionMap drawing, + VertexIndexMap vm + ) + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename graph_traits::edges_size_type e_size_t; + typedef typename graph_traits::vertices_size_type v_size_t; + + typedef std::size_t x_coord_t; + typedef std::size_t y_coord_t; + typedef boost::tuple edge_event_t; + typedef typename std::vector< edge_event_t > edge_event_queue_t; + + typedef tuple active_map_key_t; + typedef edge_t active_map_value_t; + typedef std::map< active_map_key_t, active_map_value_t > active_map_t; + typedef typename active_map_t::iterator active_map_iterator_t; + + + edge_event_queue_t edge_event_queue; + active_map_t active_edges; + + edge_iterator_t ei, ei_end; + for(tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_t e(*ei); + vertex_t s(source(e,g)); + vertex_t t(target(e,g)); + edge_event_queue.push_back + (make_tuple(e, + static_cast(drawing[s].x), + static_cast(drawing[s].y) + ) + ); + edge_event_queue.push_back + (make_tuple(e, + static_cast(drawing[t].x), + static_cast(drawing[t].y) + ) + ); + } + + // Order by edge_event_queue by first, then second coordinate + // (bucket_sort is a stable sort.) + bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), + property_map_tuple_adaptor() + ); + + bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), + property_map_tuple_adaptor() + ); + + typedef typename edge_event_queue_t::iterator event_queue_iterator_t; + event_queue_iterator_t itr_end = edge_event_queue.end(); + for(event_queue_iterator_t itr = edge_event_queue.begin(); + itr != itr_end; ++itr + ) + { + edge_t e(get<0>(*itr)); + vertex_t source_v(source(e,g)); + vertex_t target_v(target(e,g)); + if (drawing[source_v].x > drawing[target_v].x) + std::swap(source_v, target_v); + + active_map_key_t key(get(drawing, source_v).y, + get(drawing, target_v).y, + get(drawing, source_v).x, + get(drawing, target_v).x + ); + + active_map_iterator_t a_itr = active_edges.find(key); + if (a_itr == active_edges.end()) + { + active_edges[key] = e; + } + else + { + active_map_iterator_t before, after; + if (a_itr == active_edges.begin()) + before = active_edges.end(); + else + before = prior(a_itr); + after = next(a_itr); + + if (after != active_edges.end() || before != active_edges.end()) + { + + edge_t f = after != active_edges.end() ? + after->second : before->second; + + vertex_t e_source(source(e,g)); + vertex_t e_target(target(e,g)); + vertex_t f_source(source(f,g)); + vertex_t f_target(target(f,g)); + + if (intersects(drawing[e_source].x, + drawing[e_source].y, + drawing[e_target].x, + drawing[e_target].y, + drawing[f_source].x, + drawing[f_source].y, + drawing[f_target].x, + drawing[f_target].y + ) + ) + return false; + } + + active_edges.erase(a_itr); + + } + } + + return true; + + } + + + template + bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing) + { + return is_straight_line_drawing(g, drawing, get(vertex_index,g)); + } + +} + +#endif // __IS_STRAIGHT_LINE_DRAWING_HPP__ diff --git a/thirdparty/boost/graph/isomorphism.hpp b/thirdparty/boost/graph/isomorphism.hpp new file mode 100644 index 0000000..496a076 --- /dev/null +++ b/thirdparty/boost/graph/isomorphism.hpp @@ -0,0 +1,467 @@ +// Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_GRAPH_ISOMORPHISM_HPP +#define BOOST_GRAPH_ISOMORPHISM_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for make_indirect_pmap + +#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP +#define BOOST_ISO_INCLUDED_ITER_MACROS // local macro, see bottom of file +#include +#endif + +namespace boost { + + namespace detail { + + template + class isomorphism_algo + { + typedef typename graph_traits::vertex_descriptor vertex1_t; + typedef typename graph_traits::vertex_descriptor vertex2_t; + typedef typename graph_traits::edge_descriptor edge1_t; + typedef typename graph_traits::vertices_size_type size_type; + typedef typename Invariant1::result_type invar1_value; + typedef typename Invariant2::result_type invar2_value; + + const Graph1& G1; + const Graph2& G2; + IsoMapping f; + Invariant1 invariant1; + Invariant2 invariant2; + std::size_t max_invariant; + IndexMap1 index_map1; + IndexMap2 index_map2; + + std::vector dfs_vertices; + typedef typename std::vector::iterator vertex_iter; + std::vector dfs_num_vec; + typedef safe_iterator_property_map::iterator, + IndexMap1 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , int, int& +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + > DFSNumMap; + DFSNumMap dfs_num; + std::vector ordered_edges; + typedef typename std::vector::iterator edge_iter; + + std::vector in_S_vec; + typedef safe_iterator_property_map::iterator, + IndexMap2 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , char, char& +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + > InSMap; + InSMap in_S; + + int num_edges_on_k; + + friend struct compare_multiplicity; + struct compare_multiplicity + { + compare_multiplicity(Invariant1 invariant1, size_type* multiplicity) + : invariant1(invariant1), multiplicity(multiplicity) { } + bool operator()(const vertex1_t& x, const vertex1_t& y) const { + return multiplicity[invariant1(x)] < multiplicity[invariant1(y)]; + } + Invariant1 invariant1; + size_type* multiplicity; + }; + + struct record_dfs_order : default_dfs_visitor + { + record_dfs_order(std::vector& v, std::vector& e) + : vertices(v), edges(e) { } + + void discover_vertex(vertex1_t v, const Graph1&) const { + vertices.push_back(v); + } + void examine_edge(edge1_t e, const Graph1& G1) const { + edges.push_back(e); + } + std::vector& vertices; + std::vector& edges; + }; + + struct edge_cmp { + edge_cmp(const Graph1& G1, DFSNumMap dfs_num) + : G1(G1), dfs_num(dfs_num) { } + bool operator()(const edge1_t& e1, const edge1_t& e2) const { + using namespace std; + int u1 = dfs_num[source(e1,G1)], v1 = dfs_num[target(e1,G1)]; + int u2 = dfs_num[source(e2,G1)], v2 = dfs_num[target(e2,G1)]; + int m1 = (max)(u1, v1); + int m2 = (max)(u2, v2); + // lexicographical comparison + return std::make_pair(m1, std::make_pair(u1, v1)) + < std::make_pair(m2, std::make_pair(u2, v2)); + } + const Graph1& G1; + DFSNumMap dfs_num; + }; + + public: + isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, + IndexMap1 index_map1, IndexMap2 index_map2) + : G1(G1), G2(G2), f(f), invariant1(invariant1), invariant2(invariant2), + max_invariant(max_invariant), + index_map1(index_map1), index_map2(index_map2) + { + in_S_vec.resize(num_vertices(G1)); + in_S = make_safe_iterator_property_map + (in_S_vec.begin(), in_S_vec.size(), index_map2 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , in_S_vec.front() +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + ); + } + + bool test_isomorphism() + { + { + std::vector invar1_array; + BGL_FORALL_VERTICES_T(v, G1, Graph1) + invar1_array.push_back(invariant1(v)); + sort(invar1_array); + + std::vector invar2_array; + BGL_FORALL_VERTICES_T(v, G2, Graph2) + invar2_array.push_back(invariant2(v)); + sort(invar2_array); + if (! equal(invar1_array, invar2_array)) + return false; + } + + std::vector V_mult; + BGL_FORALL_VERTICES_T(v, G1, Graph1) + V_mult.push_back(v); + { + std::vector multiplicity(max_invariant, 0); + BGL_FORALL_VERTICES_T(v, G1, Graph1) + ++multiplicity[invariant1(v)]; + sort(V_mult, compare_multiplicity(invariant1, &multiplicity[0])); + } + + std::vector color_vec(num_vertices(G1)); + safe_iterator_property_map::iterator, + IndexMap1 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , default_color_type, default_color_type& +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + > + color_map(color_vec.begin(), color_vec.size(), index_map1); + record_dfs_order dfs_visitor(dfs_vertices, ordered_edges); + typedef color_traits Color; + for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u) { + if (color_map[*u] == Color::white()) { + dfs_visitor.start_vertex(*u, G1); + depth_first_visit(G1, *u, dfs_visitor, color_map); + } + } + // Create the dfs_num array and dfs_num_map + dfs_num_vec.resize(num_vertices(G1)); + dfs_num = make_safe_iterator_property_map(dfs_num_vec.begin(), + dfs_num_vec.size(), + index_map1 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , dfs_num_vec.front() +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + ); + size_type n = 0; + for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end(); ++v) + dfs_num[*v] = n++; + + sort(ordered_edges, edge_cmp(G1, dfs_num)); + + + int dfs_num_k = -1; + return this->match(ordered_edges.begin(), dfs_num_k); + } + + private: + bool match(edge_iter iter, int dfs_num_k) + { + if (iter != ordered_edges.end()) { + vertex1_t i = source(*iter, G1), j = target(*iter, G2); + if (dfs_num[i] > dfs_num_k) { + vertex1_t kp1 = dfs_vertices[dfs_num_k + 1]; + BGL_FORALL_VERTICES_T(u, G2, Graph2) { + if (invariant1(kp1) == invariant2(u) && in_S[u] == false) { + f[kp1] = u; + in_S[u] = true; + num_edges_on_k = 0; + + if (match(iter, dfs_num_k + 1)) +#if 0 + // dwa 2003/7/11 -- this *HAS* to be a bug! + ; +#endif + return true; + + in_S[u] = false; + } + } + + } + else if (dfs_num[j] > dfs_num_k) { + vertex1_t k = dfs_vertices[dfs_num_k]; + num_edges_on_k -= + count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S)); + + for (int jj = 0; jj < dfs_num_k; ++jj) { + vertex1_t j = dfs_vertices[jj]; + num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[k]); + } + + if (num_edges_on_k != 0) + return false; + BGL_FORALL_ADJ_T(f[i], v, G2, Graph2) + if (invariant2(v) == invariant1(j) && in_S[v] == false) { + f[j] = v; + in_S[v] = true; + num_edges_on_k = 1; + BOOST_USING_STD_MAX(); + int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j])); + if (match(next(iter), next_k)) + return true; + in_S[v] = false; + } + + + } + else { + if (container_contains(adjacent_vertices(f[i], G2), f[j])) { + ++num_edges_on_k; + if (match(next(iter), dfs_num_k)) + return true; + } + + } + } else + return true; + return false; + } + + }; + + + template + void compute_in_degree(const Graph& g, InDegreeMap in_degree_map) + { + BGL_FORALL_VERTICES_T(v, g, Graph) + put(in_degree_map, v, 0); + + BGL_FORALL_VERTICES_T(u, g, Graph) + BGL_FORALL_ADJ_T(u, v, g, Graph) + put(in_degree_map, v, get(in_degree_map, v) + 1); + } + + } // namespace detail + + + template + class degree_vertex_invariant + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::degree_size_type size_type; + public: + typedef vertex_t argument_type; + typedef size_type result_type; + + degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g) + : m_in_degree_map(in_degree_map), m_g(g) { } + + size_type operator()(vertex_t v) const { + return (num_vertices(m_g) + 1) * out_degree(v, m_g) + + get(m_in_degree_map, v); + } + // The largest possible vertex invariant number + size_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { + return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g); + } + private: + InDegreeMap m_in_degree_map; + const Graph& m_g; + }; + + + template + bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, + std::size_t max_invariant, + IndexMap1 index_map1, IndexMap2 index_map2) + + { + // Graph requirements + function_requires< VertexListGraphConcept >(); + function_requires< EdgeListGraphConcept >(); + function_requires< VertexListGraphConcept >(); + function_requires< BidirectionalGraphConcept >(); + + typedef typename graph_traits::vertex_descriptor vertex1_t; + typedef typename graph_traits::vertex_descriptor vertex2_t; + typedef typename graph_traits::vertices_size_type size_type; + + // Vertex invariant requirement + function_requires< AdaptableUnaryFunctionConcept >(); + function_requires< AdaptableUnaryFunctionConcept >(); + + // Property map requirements + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type IsoMappingValue; + BOOST_STATIC_ASSERT((is_same::value)); + + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type IndexMap1Value; + BOOST_STATIC_ASSERT((is_convertible::value)); + + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type IndexMap2Value; + BOOST_STATIC_ASSERT((is_convertible::value)); + + if (num_vertices(G1) != num_vertices(G2)) + return false; + if (num_vertices(G1) == 0 && num_vertices(G2) == 0) + return true; + + detail::isomorphism_algo + algo(G1, G2, f, invariant1, invariant2, max_invariant, + index_map1, index_map2); + return algo.test_isomorphism(); + } + + + namespace detail { + + template + bool isomorphism_impl(const Graph1& G1, const Graph2& G2, + IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2, + const bgl_named_params& params) + { + std::vector in_degree1_vec(num_vertices(G1)); + typedef safe_iterator_property_map::iterator, + IndexMap1 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , std::size_t, std::size_t& +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + > InDeg1; + InDeg1 in_degree1(in_degree1_vec.begin(), in_degree1_vec.size(), index_map1); + compute_in_degree(G1, in_degree1); + + std::vector in_degree2_vec(num_vertices(G2)); + typedef safe_iterator_property_map::iterator, + IndexMap2 +#ifdef BOOST_NO_STD_ITERATOR_TRAITS + , std::size_t, std::size_t& +#endif /* BOOST_NO_STD_ITERATOR_TRAITS */ + > InDeg2; + InDeg2 in_degree2(in_degree2_vec.begin(), in_degree2_vec.size(), index_map2); + compute_in_degree(G2, in_degree2); + + degree_vertex_invariant invariant1(in_degree1, G1); + degree_vertex_invariant invariant2(in_degree2, G2); + + return isomorphism(G1, G2, f, + choose_param(get_param(params, vertex_invariant1_t()), invariant1), + choose_param(get_param(params, vertex_invariant2_t()), invariant2), + choose_param(get_param(params, vertex_max_invariant_t()), (invariant2.max)()), + index_map1, index_map2 + ); + } + + } // namespace detail + + + // Named parameter interface + template + bool isomorphism(const Graph1& g1, + const Graph2& g2, + const bgl_named_params& params) + { + typedef typename graph_traits::vertex_descriptor vertex2_t; + typename std::vector::size_type n = num_vertices(g1); + std::vector f(n); + return detail::isomorphism_impl + (g1, g2, + choose_param(get_param(params, vertex_isomorphism_t()), + make_safe_iterator_property_map(f.begin(), f.size(), + choose_const_pmap(get_param(params, vertex_index1), + g1, vertex_index), vertex2_t())), + choose_const_pmap(get_param(params, vertex_index1), g1, vertex_index), + choose_const_pmap(get_param(params, vertex_index2), g2, vertex_index), + params + ); + } + + // All defaults interface + template + bool isomorphism(const Graph1& g1, const Graph2& g2) + { + return isomorphism(g1, g2, + bgl_named_params(0));// bogus named param + } + + + // Verify that the given mapping iso_map from the vertices of g1 to the + // vertices of g2 describes an isomorphism. + // Note: this could be made much faster by specializing based on the graph + // concepts modeled, but since we're verifying an O(n^(lg n)) algorithm, + // O(n^4) won't hurt us. + template + inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_map) + { +#if 0 + // problematic for filtered_graph! + if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2)) + return false; +#endif + + for (typename graph_traits::edge_iterator e1 = edges(g1).first; + e1 != edges(g1).second; ++e1) { + bool found_edge = false; + for (typename graph_traits::edge_iterator e2 = edges(g2).first; + e2 != edges(g2).second && !found_edge; ++e2) { + if (source(*e2, g2) == get(iso_map, source(*e1, g1)) && + target(*e2, g2) == get(iso_map, target(*e1, g1))) { + found_edge = true; + } + } + + if (!found_edge) + return false; + } + + return true; + } + +} // namespace boost + +#ifdef BOOST_ISO_INCLUDED_ITER_MACROS +#undef BOOST_ISO_INCLUDED_ITER_MACROS +#include +#endif + +#endif // BOOST_GRAPH_ISOMORPHISM_HPP diff --git a/thirdparty/boost/graph/iteration_macros.hpp b/thirdparty/boost/graph/iteration_macros.hpp new file mode 100644 index 0000000..84aa2ba --- /dev/null +++ b/thirdparty/boost/graph/iteration_macros.hpp @@ -0,0 +1,129 @@ +//======================================================================= +// Copyright 2001 Indiana University +// Author: Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP +#define BOOST_GRAPH_ITERATION_MACROS_HPP + +#define BGL_CAT(x,y) x ## y +#define BGL_FIRST(linenum) BGL_CAT(bgl_first_,linenum) +#define BGL_LAST(linenum) BGL_CAT(bgl_last_,linenum) + +/* + BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9 + expands to the following, but all on the same line + + for (typename boost::graph_traits::vertex_iterator + bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits::vertex_descriptor v; + bgl_first_9 != bgl_last ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) + + The purpose of having two for-loops is just to provide a place to + declare both the iterator and value variables. There is really only + one loop. The stopping condition gets executed two more times than it + usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9 + in the outer for-loop is in case the user puts a break statement + in the inner for-loop. + + The other macros work in a similar fashion. + + Use the _T versions when the graph type is a template parameter or + dependent on a template parameter. Otherwise use the non _T versions. + + */ + + +#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \ +for (typename boost::graph_traits::vertex_iterator \ + BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \ +for (boost::graph_traits::vertex_iterator \ + BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \ +for (typename boost::graph_traits::edge_iterator \ + BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \ +for (boost::graph_traits::edge_iterator \ + BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \ +for (typename boost::graph_traits::adjacency_iterator \ + BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (typename boost::graph_traits::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \ +for (boost::graph_traits::adjacency_iterator \ + BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (boost::graph_traits::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \ +for (typename boost::graph_traits::out_edge_iterator \ + BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (typename boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \ +for (boost::graph_traits::out_edge_iterator \ + BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \ +for (typename boost::graph_traits::in_edge_iterator \ + BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (typename boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \ +for (boost::graph_traits::in_edge_iterator \ + BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\ + BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ +for (boost::graph_traits::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ + ++BGL_FIRST(__LINE__)) + +#endif // BOOST_GRAPH_ITERATION_MACROS_HPP diff --git a/thirdparty/boost/graph/iteration_macros_undef.hpp b/thirdparty/boost/graph/iteration_macros_undef.hpp new file mode 100644 index 0000000..94aa145 --- /dev/null +++ b/thirdparty/boost/graph/iteration_macros_undef.hpp @@ -0,0 +1,22 @@ +//======================================================================= +// Copyright 2002 Indiana University. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifdef BOOST_GRAPH_ITERATION_MACROS_HPP + +#undef BOOST_GRAPH_ITERATION_MACROS_HPP +#undef BGL_CAT +#undef BGL_FIRST +#undef BGL_LAST +#undef BGL_FORALL_VERTICES +#undef BGL_FORALL_EDGES +#undef BGL_FORALL_ADJACENT +#undef BGL_FORALL_OUTEDGES +#undef BGL_FORALL_INEDGES + +#endif diff --git a/thirdparty/boost/graph/johnson_all_pairs_shortest.hpp b/thirdparty/boost/graph/johnson_all_pairs_shortest.hpp new file mode 100644 index 0000000..340b6d0 --- /dev/null +++ b/thirdparty/boost/graph/johnson_all_pairs_shortest.hpp @@ -0,0 +1,205 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the 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 implements the function + + template + bool + johnson_all_pairs_shortest_paths + (VertexAndEdgeListGraph& g, + DistanceMatrix& D, + const bgl_named_params& params) + */ + +#ifndef BOOST_GRAPH_JOHNSON_HPP +#define BOOST_GRAPH_JOHNSON_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + bool + johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, + DistanceMatrix& D, + VertexID id1, Weight w1, const BinaryPredicate& compare, + const BinaryFunction& combine, const Infinity& inf, + DistanceZero zero) + { + typedef graph_traits Traits1; + typedef typename property_traits::value_type DT; + function_requires< BasicMatrixConcept >(); + + typedef typename Traits1::directed_category DirCat; + bool is_undirected = is_same::value; + + typedef adjacency_list, + property< edge_weight_t, DT, + property< edge_weight2_t, DT > > > Graph2; + typedef graph_traits Traits2; + + Graph2 g2(num_vertices(g1) + 1); + typename property_map::type + w = get(edge_weight, g2); + typename property_map::type + w_hat = get(edge_weight2, g2); + typename property_map::type + d = get(vertex_distance, g2); + typedef typename property_map::type VertexID2; + VertexID2 id2 = get(vertex_index, g2); + + // Construct g2 where V[g2] = V[g1] U {s} + // and E[g2] = E[g1] U {(s,v)| v in V[g1]} + std::vector + verts1(num_vertices(g1) + 1); + typename Traits2::vertex_descriptor s = *vertices(g2).first; + { + typename Traits1::vertex_iterator v, v_end; + int i = 1; + for (tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i) { + typename Traits2::edge_descriptor e; bool z; + tie(e, z) = add_edge(s, get(id1, *v) + 1, g2); + put(w, e, zero); + verts1[i] = *v; + } + typename Traits1::edge_iterator e, e_end; + for (tie(e, e_end) = edges(g1); e != e_end; ++e) { + typename Traits2::edge_descriptor e2; bool z; + tie(e2, z) = add_edge(get(id1, source(*e, g1)) + 1, + get(id1, target(*e, g1)) + 1, g2); + put(w, e2, get(w1, *e)); + if (is_undirected) { + tie(e2, z) = add_edge(get(id1, target(*e, g1)) + 1, + get(id1, source(*e, g1)) + 1, g2); + put(w, e2, get(w1, *e)); + } + } + } + typename Traits2::vertex_iterator v, v_end, u, u_end; + typename Traits2::edge_iterator e, e_end; + std::vector

            h_vec(num_vertices(g2)); + typedef typename std::vector
            ::iterator iter_t; + iterator_property_map h(h_vec.begin(), id2); + + for (tie(v, v_end) = vertices(g2); v != v_end; ++v) + d[*v] = inf; + + put(d, s, zero); + // Using the non-named parameter versions of bellman_ford and + // dijkstra for portability reasons. + dummy_property_map pred; bellman_visitor<> bvis; + if (bellman_ford_shortest_paths + (g2, num_vertices(g2), w, pred, d, combine, compare, bvis)) { + for (tie(v, v_end) = vertices(g2); v != v_end; ++v) + put(h, *v, get(d, *v)); + // Reweight the edges to remove negatives + for (tie(e, e_end) = edges(g2); e != e_end; ++e) { + typename Traits2::vertex_descriptor a = source(*e, g2), + b = target(*e, g2); + put(w_hat, *e, get(w, *e) + get(h, a) - get(h, b)); + } + for (tie(u, u_end) = vertices(g2); u != u_end; ++u) { + dijkstra_visitor<> dvis; + dijkstra_shortest_paths + (g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero,dvis); + for (tie(v, v_end) = vertices(g2); v != v_end; ++v) { + if (*u != s && *v != s) { + typename Traits1::vertex_descriptor u1, v1; + u1 = verts1[id2[*u]]; v1 = verts1[id2[*v]]; + D[id2[*u]-1][id2[*v]-1] = get(d, *v) + get(h, *v) - get(h, *u); + } + } + } + return true; + } else + return false; + } + + template + bool + johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, + DistanceMatrix& D, + VertexID id1, Weight w1, DistanceZero zero) + { + typedef typename property_traits::value_type WT; + return johnson_all_pairs_shortest_paths(g1, D, id1, w1, + std::less(), + closed_plus(), + (std::numeric_limits::max)(), + zero); + } + + namespace detail { + + template + bool + johnson_dispatch(VertexAndEdgeListGraph& g, + DistanceMatrix& D, + const bgl_named_params& params, + Weight w, VertexID id) + { + typedef typename property_traits::value_type WT; + + return johnson_all_pairs_shortest_paths + (g, D, id, w, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus()), + choose_param(get_param(params, distance_inf_t()), + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()), + choose_param(get_param(params, distance_zero_t()), WT()) ); + } + + } // namespace detail + + template + bool + johnson_all_pairs_shortest_paths + (VertexAndEdgeListGraph& g, + DistanceMatrix& D, + const bgl_named_params& params) + { + return detail::johnson_dispatch + (g, D, params, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index) + ); + } + + template + bool + johnson_all_pairs_shortest_paths + (VertexAndEdgeListGraph& g, DistanceMatrix& D) + { + bgl_named_params params(1); + return detail::johnson_dispatch + (g, D, params, get(edge_weight, g), get(vertex_index, g)); + } + +} // namespace boost + +#endif // BOOST_GRAPH_JOHNSON_HPP + + diff --git a/thirdparty/boost/graph/kamada_kawai_spring_layout.hpp b/thirdparty/boost/graph/kamada_kawai_spring_layout.hpp new file mode 100644 index 0000000..3a12ccb --- /dev/null +++ b/thirdparty/boost/graph/kamada_kawai_spring_layout.hpp @@ -0,0 +1,542 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP +#define BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace detail { namespace graph { + /** + * Denotes an edge or display area side length used to scale a + * Kamada-Kawai drawing. + */ + template + struct edge_or_side + { + explicit edge_or_side(T value) : value(value) {} + + T value; + }; + + /** + * Compute the edge length from an edge length. This is trivial. + */ + template + T compute_edge_length(const Graph&, DistanceMap, IndexMap, + edge_or_side length) + { return length.value; } + + /** + * Compute the edge length based on the display area side + length. We do this by dividing the side length by the largest + shortest distance between any two vertices in the graph. + */ + template + T + compute_edge_length(const Graph& g, DistanceMap distance, IndexMap index, + edge_or_side length) + { + T result(0); + + typedef typename graph_traits::vertex_iterator vertex_iterator; + + for (vertex_iterator ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) { + vertex_iterator vi = ui; + for (++vi; vi != end; ++vi) { + T dij = distance[get(index, *ui)][get(index, *vi)]; + if (dij > result) result = dij; + } + } + return length.value / result; + } + + /** + * Implementation of the Kamada-Kawai spring layout algorithm. + */ + template + struct kamada_kawai_spring_layout_impl + { + typedef typename property_traits::value_type weight_type; + typedef std::pair deriv_type; + typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + + kamada_kawai_spring_layout_impl( + const Graph& g, + PositionMap position, + WeightMap weight, + EdgeOrSideLength edge_or_side_length, + Done done, + weight_type spring_constant, + VertexIndexMap index, + DistanceMatrix distance, + SpringStrengthMatrix spring_strength, + PartialDerivativeMap partial_derivatives) + : g(g), position(position), weight(weight), + edge_or_side_length(edge_or_side_length), done(done), + spring_constant(spring_constant), index(index), distance(distance), + spring_strength(spring_strength), + partial_derivatives(partial_derivatives) {} + + // Compute contribution of vertex i to the first partial + // derivatives (dE/dx_m, dE/dy_m) (for vertex m) + deriv_type + compute_partial_derivative(vertex_descriptor m, vertex_descriptor i) + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + + deriv_type result(0, 0); + if (i != m) { + weight_type x_diff = position[m].x - position[i].x; + weight_type y_diff = position[m].y - position[i].y; + weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff); + result.first = spring_strength[get(index, m)][get(index, i)] + * (x_diff - distance[get(index, m)][get(index, i)]*x_diff/dist); + result.second = spring_strength[get(index, m)][get(index, i)] + * (y_diff - distance[get(index, m)][get(index, i)]*y_diff/dist); + } + + return result; + } + + // Compute partial derivatives dE/dx_m and dE/dy_m + deriv_type + compute_partial_derivatives(vertex_descriptor m) + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + + deriv_type result(0, 0); + + // TBD: looks like an accumulate to me + std::pair verts = vertices(g); + for (/* no init */; verts.first != verts.second; ++verts.first) { + vertex_descriptor i = *verts.first; + deriv_type deriv = compute_partial_derivative(m, i); + result.first += deriv.first; + result.second += deriv.second; + } + + return result; + } + + // The actual Kamada-Kawai spring layout algorithm implementation + bool run() + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE + + // Compute d_{ij} and place it in the distance matrix + if (!johnson_all_pairs_shortest_paths(g, distance, index, weight, + weight_type(0))) + return false; + + // Compute L based on side length (if needed), or retrieve L + weight_type edge_length = + detail::graph::compute_edge_length(g, distance, index, + edge_or_side_length); + + // Compute l_{ij} and k_{ij} + const weight_type K = spring_constant; + vertex_iterator ui, end = vertices(g).second; + for (ui = vertices(g).first; ui != end; ++ui) { + vertex_iterator vi = ui; + for (++vi; vi != end; ++vi) { + weight_type dij = distance[get(index, *ui)][get(index, *vi)]; + if (dij == (std::numeric_limits::max)()) + return false; + distance[get(index, *ui)][get(index, *vi)] = edge_length * dij; + distance[get(index, *vi)][get(index, *ui)] = edge_length * dij; + spring_strength[get(index, *ui)][get(index, *vi)] = K/(dij*dij); + spring_strength[get(index, *vi)][get(index, *ui)] = K/(dij*dij); + } + } + + // Compute Delta_i and find max + vertex_descriptor p = *vertices(g).first; + weight_type delta_p(0); + + for (ui = vertices(g).first; ui != end; ++ui) { + deriv_type deriv = compute_partial_derivatives(*ui); + put(partial_derivatives, *ui, deriv); + + weight_type delta = + sqrt(deriv.first*deriv.first + deriv.second*deriv.second); + + if (delta > delta_p) { + p = *ui; + delta_p = delta; + } + } + + while (!done(delta_p, p, g, true)) { + // The contribution p makes to the partial derivatives of + // each vertex. Computing this (at O(n) cost) allows us to + // update the delta_i values in O(n) time instead of O(n^2) + // time. + std::vector p_partials(num_vertices(g)); + for (ui = vertices(g).first; ui != end; ++ui) { + vertex_descriptor i = *ui; + p_partials[get(index, i)] = compute_partial_derivative(i, p); + } + + do { + // Compute the 4 elements of the Jacobian + weight_type dE_dx_dx = 0, dE_dx_dy = 0, dE_dy_dx = 0, dE_dy_dy = 0; + for (ui = vertices(g).first; ui != end; ++ui) { + vertex_descriptor i = *ui; + if (i != p) { + weight_type x_diff = position[p].x - position[i].x; + weight_type y_diff = position[p].y - position[i].y; + weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff); + weight_type dist_cubed = dist * dist * dist; + weight_type k_mi = spring_strength[get(index,p)][get(index,i)]; + weight_type l_mi = distance[get(index, p)][get(index, i)]; + dE_dx_dx += k_mi * (1 - (l_mi * y_diff * y_diff)/dist_cubed); + dE_dx_dy += k_mi * l_mi * x_diff * y_diff / dist_cubed; + dE_dy_dx += k_mi * l_mi * x_diff * y_diff / dist_cubed; + dE_dy_dy += k_mi * (1 - (l_mi * x_diff * x_diff)/dist_cubed); + } + } + + // Solve for delta_x and delta_y + weight_type dE_dx = get(partial_derivatives, p).first; + weight_type dE_dy = get(partial_derivatives, p).second; + + weight_type delta_x = + (dE_dx_dy * dE_dy - dE_dy_dy * dE_dx) + / (dE_dx_dx * dE_dy_dy - dE_dx_dy * dE_dy_dx); + + weight_type delta_y = + (dE_dx_dx * dE_dy - dE_dy_dx * dE_dx) + / (dE_dy_dx * dE_dx_dy - dE_dx_dx * dE_dy_dy); + + + // Move p by (delta_x, delta_y) + position[p].x += delta_x; + position[p].y += delta_y; + + // Recompute partial derivatives and delta_p + deriv_type deriv = compute_partial_derivatives(p); + put(partial_derivatives, p, deriv); + + delta_p = + sqrt(deriv.first*deriv.first + deriv.second*deriv.second); + } while (!done(delta_p, p, g, false)); + + // Select new p by updating each partial derivative and delta + vertex_descriptor old_p = p; + for (ui = vertices(g).first; ui != end; ++ui) { + deriv_type old_deriv_p = p_partials[get(index, *ui)]; + deriv_type old_p_partial = + compute_partial_derivative(*ui, old_p); + deriv_type deriv = get(partial_derivatives, *ui); + + deriv.first += old_p_partial.first - old_deriv_p.first; + deriv.second += old_p_partial.second - old_deriv_p.second; + + put(partial_derivatives, *ui, deriv); + weight_type delta = + sqrt(deriv.first*deriv.first + deriv.second*deriv.second); + + if (delta > delta_p) { + p = *ui; + delta_p = delta; + } + } + } + + return true; + } + + const Graph& g; + PositionMap position; + WeightMap weight; + EdgeOrSideLength edge_or_side_length; + Done done; + weight_type spring_constant; + VertexIndexMap index; + DistanceMatrix distance; + SpringStrengthMatrix spring_strength; + PartialDerivativeMap partial_derivatives; + }; + } } // end namespace detail::graph + + /// States that the given quantity is an edge length. + template + inline detail::graph::edge_or_side + edge_length(T x) + { return detail::graph::edge_or_side(x); } + + /// States that the given quantity is a display area side length. + template + inline detail::graph::edge_or_side + side_length(T x) + { return detail::graph::edge_or_side(x); } + + /** + * \brief Determines when to terminate layout of a particular graph based + * on a given relative tolerance. + */ + template + struct layout_tolerance + { + layout_tolerance(const T& tolerance = T(0.001)) + : tolerance(tolerance), last_energy((std::numeric_limits::max)()), + last_local_energy((std::numeric_limits::max)()) { } + + template + bool + operator()(T delta_p, + typename boost::graph_traits::vertex_descriptor p, + const Graph& g, + bool global) + { + if (global) { + if (last_energy == (std::numeric_limits::max)()) { + last_energy = delta_p; + return false; + } + + T diff = last_energy - delta_p; + if (diff < T(0)) diff = -diff; + bool done = (delta_p == T(0) || diff / last_energy < tolerance); + last_energy = delta_p; + return done; + } else { + if (last_local_energy == (std::numeric_limits::max)()) { + last_local_energy = delta_p; + return delta_p == T(0); + } + + T diff = last_local_energy - delta_p; + bool done = (delta_p == T(0) || (diff / last_local_energy) < tolerance); + last_local_energy = delta_p; + return done; + } + } + + private: + T tolerance; + T last_energy; + T last_local_energy; + }; + + /** \brief Kamada-Kawai spring layout for undirected graphs. + * + * This algorithm performs graph layout (in two dimensions) for + * connected, undirected graphs. It operates by relating the layout + * of graphs to a dynamic spring system and minimizing the energy + * within that system. The strength of a spring between two vertices + * is inversely proportional to the square of the shortest distance + * (in graph terms) between those two vertices. Essentially, + * vertices that are closer in the graph-theoretic sense (i.e., by + * following edges) will have stronger springs and will therefore be + * placed closer together. + * + * Prior to invoking this algorithm, it is recommended that the + * vertices be placed along the vertices of a regular n-sided + * polygon. + * + * \param g (IN) must be a model of Vertex List Graph, Edge List + * Graph, and Incidence Graph and must be undirected. + * + * \param position (OUT) must be a model of Lvalue Property Map, + * where the value type is a class containing fields @c x and @c y + * that will be set to the @c x and @c y coordinates of each vertex. + * + * \param weight (IN) must be a model of Readable Property Map, + * which provides the weight of each edge in the graph @p g. + * + * \param edge_or_side_length (IN) provides either the unit length + * @c e of an edge in the layout or the length of a side @c s of the + * display area, and must be either @c boost::edge_length(e) or @c + * boost::side_length(s), respectively. + * + * \param done (IN) is a 4-argument function object that is passed + * the current value of delta_p (i.e., the energy of vertex @p p), + * the vertex @p p, the graph @p g, and a boolean flag indicating + * whether @p delta_p is the maximum energy in the system (when @c + * true) or the energy of the vertex being moved. Defaults to @c + * layout_tolerance instantiated over the value type of the weight + * map. + * + * \param spring_constant (IN) is the constant multiplied by each + * spring's strength. Larger values create systems with more energy + * that can take longer to stabilize; smaller values create systems + * with less energy that stabilize quickly but do not necessarily + * result in pleasing layouts. The default value is 1. + * + * \param index (IN) is a mapping from vertices to index values + * between 0 and @c num_vertices(g). The default is @c + * get(vertex_index,g). + * + * \param distance (UTIL/OUT) will be used to store the distance + * from every vertex to every other vertex, which is computed in the + * first stages of the algorithm. This value's type must be a model + * of BasicMatrix with value type equal to the value type of the + * weight map. The default is a a vector of vectors. + * + * \param spring_strength (UTIL/OUT) will be used to store the + * strength of the spring between every pair of vertices. This + * value's type must be a model of BasicMatrix with value type equal + * to the value type of the weight map. The default is a a vector of + * vectors. + * + * \param partial_derivatives (UTIL) will be used to store the + * partial derivates of each vertex with respect to the @c x and @c + * y coordinates. This must be a Read/Write Property Map whose value + * type is a pair with both types equivalent to the value type of + * the weight map. The default is an iterator property map. + * + * \returns @c true if layout was successful or @c false if a + * negative weight cycle was detected. + */ + template + bool + kamada_kawai_spring_layout( + const Graph& g, + PositionMap position, + WeightMap weight, + detail::graph::edge_or_side edge_or_side_length, + Done done, + typename property_traits::value_type spring_constant, + VertexIndexMap index, + DistanceMatrix distance, + SpringStrengthMatrix spring_strength, + PartialDerivativeMap partial_derivatives) + { + BOOST_STATIC_ASSERT((is_convertible< + typename graph_traits::directed_category*, + undirected_tag* + >::value)); + + detail::graph::kamada_kawai_spring_layout_impl< + Graph, PositionMap, WeightMap, + detail::graph::edge_or_side, Done, VertexIndexMap, + DistanceMatrix, SpringStrengthMatrix, PartialDerivativeMap> + alg(g, position, weight, edge_or_side_length, done, spring_constant, + index, distance, spring_strength, partial_derivatives); + return alg.run(); + } + + /** + * \overload + */ + template + bool + kamada_kawai_spring_layout( + const Graph& g, + PositionMap position, + WeightMap weight, + detail::graph::edge_or_side edge_or_side_length, + Done done, + typename property_traits::value_type spring_constant, + VertexIndexMap index) + { + typedef typename property_traits::value_type weight_type; + + typename graph_traits::vertices_size_type n = num_vertices(g); + typedef std::vector weight_vec; + + std::vector distance(n, weight_vec(n)); + std::vector spring_strength(n, weight_vec(n)); + std::vector > partial_derivatives(n); + + return + kamada_kawai_spring_layout( + g, position, weight, edge_or_side_length, done, spring_constant, index, + distance.begin(), + spring_strength.begin(), + make_iterator_property_map(partial_derivatives.begin(), index, + std::pair())); + } + + /** + * \overload + */ + template + bool + kamada_kawai_spring_layout( + const Graph& g, + PositionMap position, + WeightMap weight, + detail::graph::edge_or_side edge_or_side_length, + Done done, + typename property_traits::value_type spring_constant) + { + return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, + done, spring_constant, + get(vertex_index, g)); + } + + /** + * \overload + */ + template + bool + kamada_kawai_spring_layout( + const Graph& g, + PositionMap position, + WeightMap weight, + detail::graph::edge_or_side edge_or_side_length, + Done done) + { + typedef typename property_traits::value_type weight_type; + return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, + done, weight_type(1)); + } + + /** + * \overload + */ + template + bool + kamada_kawai_spring_layout( + const Graph& g, + PositionMap position, + WeightMap weight, + detail::graph::edge_or_side edge_or_side_length) + { + typedef typename property_traits::value_type weight_type; + return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, + layout_tolerance(), + weight_type(1.0), + get(vertex_index, g)); + } +} // end namespace boost + +#endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP diff --git a/thirdparty/boost/graph/king_ordering.hpp b/thirdparty/boost/graph/king_ordering.hpp new file mode 100644 index 0000000..e4c1a2d --- /dev/null +++ b/thirdparty/boost/graph/king_ordering.hpp @@ -0,0 +1,320 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2004, 2005 Trustees of Indiana University +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, +// Doug Gregor, D. Kevin McGrath +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//=======================================================================// +#ifndef BOOST_GRAPH_KING_HPP +#define BOOST_GRAPH_KING_HPP + +#include +#include + +/* + King Algorithm for matrix reordering +*/ + +namespace boost { + namespace detail { + template + class bfs_king_visitor:public default_bfs_visitor + { + public: + bfs_king_visitor(OutputIterator *iter, Buffer *b, Compare compare, + PseudoDegreeMap deg, std::vector loc, VecMap color, + VertexIndexMap vertices): + permutation(iter), Qptr(b), degree(deg), comp(compare), + Qlocation(loc), colors(color), vertex_map(vertices) { } + + template + void finish_vertex(Vertex, Graph& g) { + typename graph_traits::out_edge_iterator ei, ei_end; + Vertex v, w; + + typedef typename std::deque::iterator iterator; + typedef typename std::deque::reverse_iterator reverse_iterator; + + reverse_iterator rend = Qptr->rend()-index_begin; + reverse_iterator rbegin = Qptr->rbegin(); + + + //heap the vertices already there + std::make_heap(rbegin, rend, boost::bind(comp, _2, _1)); + + unsigned i = 0; + + for(i = index_begin; i != Qptr->size(); ++i){ + colors[get(vertex_map, (*Qptr)[i])] = 1; + Qlocation[get(vertex_map, (*Qptr)[i])] = i; + } + + i = 0; + + for( ; rbegin != rend; rend--){ + percolate_down(i); + w = (*Qptr)[index_begin+i]; + for (tie(ei, ei_end) = out_edges(w, g); ei != ei_end; ++ei) { + v = target(*ei, g); + put(degree, v, get(degree, v) - 1); + + if (colors[get(vertex_map, v)] == 1) { + percolate_up(get(vertex_map, v), i); + } + } + + colors[get(vertex_map, w)] = 0; + i++; + } + } + + template + void examine_vertex(Vertex u, const Graph&) { + + *(*permutation)++ = u; + index_begin = Qptr->size(); + + } + protected: + + + //this function replaces pop_heap, and tracks state information + template + void percolate_down(int offset){ + typedef typename std::deque::reverse_iterator reverse_iterator; + + int heap_last = index_begin + offset; + int heap_first = Qptr->size() - 1; + + //pop_heap functionality: + //swap first, last + std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]); + + //swap in the location queue + std::swap(Qlocation[heap_first], Qlocation[heap_last]); + + //set drifter, children + int drifter = heap_first; + int drifter_heap = Qptr->size() - drifter; + + int right_child_heap = drifter_heap * 2 + 1; + int right_child = Qptr->size() - right_child_heap; + + int left_child_heap = drifter_heap * 2; + int left_child = Qptr->size() - left_child_heap; + + //check that we are staying in the heap + bool valid = (right_child < heap_last) ? false : true; + + //pick smallest child of drifter, and keep in mind there might only be left child + int smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ? + right_child : left_child; + + while(valid && smallest_child < heap_last && comp((*Qptr)[drifter], (*Qptr)[smallest_child])){ + + //if smallest child smaller than drifter, swap them + std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]); + std::swap(Qlocation[drifter], Qlocation[smallest_child]); + + //update the values, run again, as necessary + drifter = smallest_child; + drifter_heap = Qptr->size() - drifter; + + right_child_heap = drifter_heap * 2 + 1; + right_child = Qptr->size() - right_child_heap; + + left_child_heap = drifter_heap * 2; + left_child = Qptr->size() - left_child_heap; + + valid = (right_child < heap_last) ? false : true; + + smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ? + right_child : left_child; + } + + } + + + + // this is like percolate down, but we always compare against the + // parent, as there is only a single choice + template + void percolate_up(int vertex, int offset){ + + int child_location = Qlocation[vertex]; + int heap_child_location = Qptr->size() - child_location; + int heap_parent_location = (int)(heap_child_location/2); + unsigned parent_location = Qptr->size() - heap_parent_location; + + bool valid = (heap_parent_location != 0 && child_location > index_begin + offset && + parent_location < Qptr->size()); + + while(valid && comp((*Qptr)[child_location], (*Qptr)[parent_location])){ + + //swap in the heap + std::swap((*Qptr)[child_location], (*Qptr)[parent_location]); + + //swap in the location queue + std::swap(Qlocation[child_location], Qlocation[parent_location]); + + child_location = parent_location; + heap_child_location = heap_parent_location; + heap_parent_location = (int)(heap_child_location/2); + parent_location = Qptr->size() - heap_parent_location; + valid = (heap_parent_location != 0 && child_location > index_begin + offset); + } + } + + OutputIterator *permutation; + int index_begin; + Buffer *Qptr; + PseudoDegreeMap degree; + Compare comp; + std::vector Qlocation; + VecMap colors; + VertexIndexMap vertex_map; + }; + + + } // namespace detail + + + template + OutputIterator + king_ordering(const Graph& g, + std::deque< typename graph_traits::vertex_descriptor > + vertex_queue, + OutputIterator permutation, + ColorMap color, DegreeMap degree, + VertexIndexMap index_map) + { + typedef typename property_traits::value_type ds_type; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef iterator_property_map::iterator, VertexIndexMap, ds_type, ds_type&> PseudoDegreeMap; + typedef indirect_cmp > Compare; + typedef typename boost::sparse::sparse_ordering_queue queue; + typedef typename detail::bfs_king_visitor, VertexIndexMap > Visitor; + typedef typename graph_traits::vertices_size_type + vertices_size_type; + std::vector pseudo_degree_vec(num_vertices(g)); + PseudoDegreeMap pseudo_degree(pseudo_degree_vec.begin(), index_map); + + typename graph_traits::vertex_iterator ui, ui_end; + queue Q; + // Copy degree to pseudo_degree + // initialize the color map + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){ + put(pseudo_degree, *ui, get(degree, *ui)); + put(color, *ui, Color::white()); + } + + Compare comp(pseudo_degree); + std::vector colors(num_vertices(g)); + + for(vertices_size_type i = 0; i < num_vertices(g); i++) + colors[i] = 0; + + std::vector loc(num_vertices(g)); + + //create the visitor + Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map); + + while( !vertex_queue.empty() ) { + Vertex s = vertex_queue.front(); + vertex_queue.pop_front(); + + //call BFS with visitor + breadth_first_visit(g, s, Q, vis, color); + } + + return permutation; + } + + + // This is the case where only a single starting vertex is supplied. + template + OutputIterator + king_ordering(const Graph& g, + typename graph_traits::vertex_descriptor s, + OutputIterator permutation, + ColorMap color, DegreeMap degree, VertexIndexMap index_map) + { + + std::deque< typename graph_traits::vertex_descriptor > vertex_queue; + vertex_queue.push_front( s ); + return king_ordering(g, vertex_queue, permutation, color, degree, + index_map); + } + + + template < class Graph, class OutputIterator, + class ColorMap, class DegreeMap, class VertexIndexMap> + OutputIterator + king_ordering(const Graph& G, OutputIterator permutation, + ColorMap color, DegreeMap degree, VertexIndexMap index_map) + { + if (vertices(G).first == vertices(G).second) + return permutation; + + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits::vertex_iterator VerIter; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + std::deque vertex_queue; + + // Mark everything white + BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white()); + + // Find one vertex from each connected component + BGL_FORALL_VERTICES_T(v, G, Graph) { + if (get(color, v) == Color::white()) { + depth_first_visit(G, v, dfs_visitor<>(), color); + vertex_queue.push_back(v); + } + } + + // Find starting nodes for all vertices + // TBD: How to do this with a directed graph? + for (typename std::deque::iterator i = vertex_queue.begin(); + i != vertex_queue.end(); ++i) + *i = find_starting_node(G, *i, color, degree); + + return king_ordering(G, vertex_queue, permutation, color, degree, + index_map); + } + + template + OutputIterator + king_ordering(const Graph& G, OutputIterator permutation, + VertexIndexMap index_map) + { + if (vertices(G).first == vertices(G).second) + return permutation; + + typedef out_degree_property_map DegreeMap; + std::vector colors(num_vertices(G)); + return king_ordering(G, permutation, + make_iterator_property_map(&colors[0], index_map, + colors[0]), + make_out_degree_map(G), index_map); + } + + template + inline OutputIterator + king_ordering(const Graph& G, OutputIterator permutation) + { return king_ordering(G, permutation, get(vertex_index, G)); } + +} // namespace boost + + +#endif // BOOST_GRAPH_KING_HPP diff --git a/thirdparty/boost/graph/kolmogorov_max_flow.hpp b/thirdparty/boost/graph/kolmogorov_max_flow.hpp new file mode 100644 index 0000000..a10f155 --- /dev/null +++ b/thirdparty/boost/graph/kolmogorov_max_flow.hpp @@ -0,0 +1,807 @@ +// Copyright (c) 2006, Stephan Diederich +// +// This code may be used under either of the following two licences: +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. +// +// Or: +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_KOLMOGOROV_MAX_FLOW_HPP +#define BOOST_KOLMOGOROV_MAX_FLOW_HPP + +#include +#include +#include +#include +#include +#include +#include // for std::min and std::max + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace detail { + + template + class kolmogorov{ + typedef typename property_traits::value_type tEdgeVal; + typedef graph_traits tGraphTraits; + typedef typename tGraphTraits::vertex_iterator vertex_iterator; + typedef typename tGraphTraits::vertex_descriptor vertex_descriptor; + typedef typename tGraphTraits::edge_descriptor edge_descriptor; + typedef typename tGraphTraits::edge_iterator edge_iterator; + typedef typename tGraphTraits::out_edge_iterator out_edge_iterator; + typedef boost::queue tQueue; //queue of vertices, used in adoption-stage + typedef typename property_traits::value_type tColorValue; + typedef color_traits tColorTraits; + typedef typename property_traits::value_type tDistanceVal; + + public: + kolmogorov(Graph& g, + EdgeCapacityMap cap, + ResidualCapacityEdgeMap res, + ReverseEdgeMap rev, + PredecessorMap pre, + ColorMap color, + DistanceMap dist, + IndexMap idx, + vertex_descriptor src, + vertex_descriptor sink): + m_g(g), + m_index_map(idx), + m_cap_map(cap), + m_res_cap_map(res), + m_rev_edge_map(rev), + m_pre_map(pre), + m_tree_map(color), + m_dist_map(dist), + m_source(src), + m_sink(sink), + m_active_nodes(), + m_in_active_list_vec(num_vertices(g), false), + m_in_active_list_map(make_iterator_property_map(m_in_active_list_vec.begin(), m_index_map)), + m_has_parent_vec(num_vertices(g), false), + m_has_parent_map(make_iterator_property_map(m_has_parent_vec.begin(), m_index_map)), + m_time_vec(num_vertices(g), 0), + m_time_map(make_iterator_property_map(m_time_vec.begin(), m_index_map)), + m_flow(0), + m_time(1), + m_last_grow_vertex(graph_traits::null_vertex()){ + // initialize the color-map with gray-values + vertex_iterator vi, v_end; + for(tie(vi, v_end) = vertices(m_g); vi != v_end; ++vi){ + set_tree(*vi, tColorTraits::gray()); + } + // Initialize flow to zero which means initializing + // the residual capacity equal to the capacity + edge_iterator ei, e_end; + for(tie(ei, e_end) = edges(m_g); ei != e_end; ++ei) { + m_res_cap_map[*ei] = m_cap_map[*ei]; + assert(m_rev_edge_map[m_rev_edge_map[*ei]] == *ei); //check if the reverse edge map is build up properly + } + //init the search trees with the two terminals + set_tree(m_source, tColorTraits::black()); + set_tree(m_sink, tColorTraits::white()); + m_time_map[m_source] = 1; + m_time_map[m_sink] = 1; + } + + ~kolmogorov(){} + + tEdgeVal max_flow(){ + //augment direct paths from SOURCE->SINK and SOURCE->VERTEX->SINK + augment_direct_paths(); + //start the main-loop + while(true){ + bool path_found; + edge_descriptor connecting_edge; + tie(connecting_edge, path_found) = grow(); //find a path from source to sink + if(!path_found){ + //we're finished, no more paths were found + break; + } + ++m_time; + augment(connecting_edge); //augment that path + adopt(); //rebuild search tree structure + } + return m_flow; + } + + //the complete class is protected, as we want access to members in derived test-class (see $(BOOST_ROOT)/libs/graph/test/kolmogorov_max_flow_test.cpp) + protected: + void augment_direct_paths(){ + //in a first step, we augment all direct paths from source->NODE->sink + //and additionally paths from source->sink + //this improves especially graphcuts for segmentation, as most of the nodes have source/sink connects + //but shouldn't have an impact on other maxflow problems (this is done in grow() anyway) + out_edge_iterator ei, e_end; + for(tie(ei, e_end) = out_edges(m_source, m_g); ei != e_end; ++ei){ + edge_descriptor from_source = *ei; + vertex_descriptor current_node = target(from_source, m_g); + if(current_node == m_sink){ + tEdgeVal cap = m_res_cap_map[from_source]; + m_res_cap_map[from_source] = 0; + m_flow += cap; + continue; + } + edge_descriptor to_sink; + bool is_there; + tie(to_sink, is_there) = edge(current_node, m_sink, m_g); + if(is_there){ + tEdgeVal cap_from_source = m_res_cap_map[from_source]; + tEdgeVal cap_to_sink = m_res_cap_map[to_sink]; + if(cap_from_source > cap_to_sink){ + set_tree(current_node, tColorTraits::black()); + add_active_node(current_node); + set_edge_to_parent(current_node, from_source); + m_dist_map[current_node] = 1; + m_time_map[current_node] = 1; + //add stuff to flow and update residuals + //we dont need to update reverse_edges, as incoming/outgoing edges to/from source/sink don't count for max-flow + m_res_cap_map[from_source] -= cap_to_sink; + m_res_cap_map[to_sink] = 0; + m_flow += cap_to_sink; + } else if(cap_to_sink > 0){ + set_tree(current_node, tColorTraits::white()); + add_active_node(current_node); + set_edge_to_parent(current_node, to_sink); + m_dist_map[current_node] = 1; + m_time_map[current_node] = 1; + //add stuff to flow and update residuals + //we dont need to update reverse_edges, as incoming/outgoing edges to/from source/sink don't count for max-flow + m_res_cap_map[to_sink] -= cap_from_source; + m_res_cap_map[from_source] = 0; + m_flow += cap_from_source; + } + } else if(m_res_cap_map[from_source]){ + //there is no sink connect, so we can't augment this path + //but to avoid adding m_source to the active nodes, we just activate this node and set the approciate things + set_tree(current_node, tColorTraits::black()); + set_edge_to_parent(current_node, from_source); + m_dist_map[current_node] = 1; + m_time_map[current_node] = 1; + add_active_node(current_node); + } + } + for(tie(ei, e_end) = out_edges(m_sink, m_g); ei != e_end; ++ei){ + edge_descriptor to_sink = m_rev_edge_map[*ei]; + vertex_descriptor current_node = source(to_sink, m_g); + if(m_res_cap_map[to_sink]){ + set_tree(current_node, tColorTraits::white()); + set_edge_to_parent(current_node, to_sink); + m_dist_map[current_node] = 1; + m_time_map[current_node] = 1; + add_active_node(current_node); + } + } + } + + /** + * returns a pair of an edge and a boolean. if the bool is true, the edge is a connection of a found path from s->t , read "the link" and + * source(returnVal, m_g) is the end of the path found in the source-tree + * target(returnVal, m_g) is the beginning of the path found in the sink-tree + */ + std::pair grow(){ + assert(m_orphans.empty()); + vertex_descriptor current_node; + while((current_node = get_next_active_node()) != graph_traits::null_vertex()){ //if there is one + assert(get_tree(current_node) != tColorTraits::gray() && (has_parent(current_node) || current_node==m_source || current_node==m_sink)); + if(get_tree(current_node) == tColorTraits::black()){ + //source tree growing + out_edge_iterator ei, e_end; + if(current_node != m_last_grow_vertex){ + m_last_grow_vertex = current_node; + tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g); + } + for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it){ + edge_descriptor out_edge = *m_last_grow_edge_it; + if(m_res_cap_map[out_edge] > 0){ //check if we have capacity left on this edge + vertex_descriptor other_node = target(out_edge, m_g); + if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node + set_tree(other_node, tColorTraits::black()); //aquire other node to our search tree + set_edge_to_parent(other_node, out_edge); //set us as parent + m_dist_map[other_node] = m_dist_map[current_node] + 1; //and update the distance-heuristic + m_time_map[other_node] = m_time_map[current_node]; + add_active_node(other_node); + } else if(get_tree(other_node) == tColorTraits::black()){ + if(is_closer_to_terminal(current_node, other_node)){ //we do this to get shorter paths. check if we are nearer to the source as its parent is + set_edge_to_parent(other_node, out_edge); + m_dist_map[other_node] = m_dist_map[current_node] + 1; + m_time_map[other_node] = m_time_map[current_node]; + } + } else{ + assert(get_tree(other_node)==tColorTraits::white()); + //kewl, found a path from one to the other search tree, return the connecting edge in src->sink dir + return std::make_pair(out_edge, true); + } + } + } //for all out-edges + } //source-tree-growing + else{ + assert(get_tree(current_node) == tColorTraits::white()); + out_edge_iterator ei, e_end; + if(current_node != m_last_grow_vertex){ + m_last_grow_vertex = current_node; + tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g); + } + for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it){ + edge_descriptor in_edge = m_rev_edge_map[*m_last_grow_edge_it]; + if(m_res_cap_map[in_edge] > 0){ //check if there is capacity left + vertex_descriptor other_node = source(in_edge, m_g); + if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node + set_tree(other_node, tColorTraits::white()); //aquire that node to our search tree + set_edge_to_parent(other_node, in_edge); //set us as parent + add_active_node(other_node); //activate that node + m_dist_map[other_node] = m_dist_map[current_node] + 1; //set its distance + m_time_map[other_node] = m_time_map[current_node]; //and time + } else if(get_tree(other_node) == tColorTraits::white()){ + if(is_closer_to_terminal(current_node, other_node)){ + //we are closer to the sink than its parent is, so we "adopt" him + set_edge_to_parent(other_node, in_edge); + m_dist_map[other_node] = m_dist_map[current_node] + 1; + m_time_map[other_node] = m_time_map[current_node]; + } + } else{ + assert(get_tree(other_node)==tColorTraits::black()); + //kewl, found a path from one to the other search tree, return the connecting edge in src->sink dir + return std::make_pair(in_edge, true); + } + } + } //for all out-edges + } //sink-tree growing + //all edges of that node are processed, and no more paths were found. so remove if from the front of the active queue + finish_node(current_node); + } //while active_nodes not empty + return std::make_pair(edge_descriptor(), false); //no active nodes anymore and no path found, we're done + } + + /** + * augments path from s->t and updates residual graph + * source(e, m_g) is the end of the path found in the source-tree + * target(e, m_g) is the beginning of the path found in the sink-tree + * this phase generates orphans on satured edges, if the attached verts are from different search-trees + * orphans are ordered in distance to sink/source. first the farest from the source are front_inserted into the orphans list, + * and after that the sink-tree-orphans are front_inserted. when going to adoption stage the orphans are popped_front, and so we process the nearest + * verts to the terminals first + */ + void augment(edge_descriptor e){ + assert(get_tree(target(e, m_g)) == tColorTraits::white()); + assert(get_tree(source(e, m_g)) == tColorTraits::black()); + assert(m_orphans.empty()); + + const tEdgeVal bottleneck = find_bottleneck(e); + //now we push the found flow through the path + //for each edge we saturate we have to look for the verts that belong to that edge, one of them becomes an orphans + //now process the connecting edge + m_res_cap_map[e] -= bottleneck; + assert(m_res_cap_map[e] >= 0); + m_res_cap_map[m_rev_edge_map[e]] += bottleneck; + + //now we follow the path back to the source + vertex_descriptor current_node = source(e, m_g); + while(current_node != m_source){ + edge_descriptor pred = get_edge_to_parent(current_node); + m_res_cap_map[pred] -= bottleneck; + assert(m_res_cap_map[pred] >= 0); + m_res_cap_map[m_rev_edge_map[pred]] += bottleneck; + if(m_res_cap_map[pred] == 0){ + set_no_parent(current_node); + m_orphans.push_front(current_node); + } + current_node = source(pred, m_g); + } + //then go forward in the sink-tree + current_node = target(e, m_g); + while(current_node != m_sink){ + edge_descriptor pred = get_edge_to_parent(current_node); + m_res_cap_map[pred] -= bottleneck; + assert(m_res_cap_map[pred] >= 0); + m_res_cap_map[m_rev_edge_map[pred]] += bottleneck; + if(m_res_cap_map[pred] == 0){ + set_no_parent(current_node); + m_orphans.push_front(current_node); + } + current_node = target(pred, m_g); + } + //and add it to the max-flow + m_flow += bottleneck; + } + + /** + * returns the bottleneck of a s->t path (end_of_path is last vertex in source-tree, begin_of_path is first vertex in sink-tree) + */ + inline tEdgeVal find_bottleneck(edge_descriptor e){ + BOOST_USING_STD_MIN(); + tEdgeVal minimum_cap = m_res_cap_map[e]; + vertex_descriptor current_node = source(e, m_g); + //first go back in the source tree + while(current_node != m_source){ + edge_descriptor pred = get_edge_to_parent(current_node); + minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, m_res_cap_map[pred]); + current_node = source(pred, m_g); + } + //then go forward in the sink-tree + current_node = target(e, m_g); + while(current_node != m_sink){ + edge_descriptor pred = get_edge_to_parent(current_node); + minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, m_res_cap_map[pred]); + current_node = target(pred, m_g); + } + return minimum_cap; + } + + /** + * rebuild search trees + * empty the queue of orphans, and find new parents for them or just drop them from the search trees + */ + void adopt(){ + while(!m_orphans.empty() || !m_child_orphans.empty()){ + vertex_descriptor current_node; + if(m_child_orphans.empty()){ + //get the next orphan from the main-queue and remove it + current_node = m_orphans.front(); + m_orphans.pop_front(); + } else{ + current_node = m_child_orphans.front(); + m_child_orphans.pop(); + } + if(get_tree(current_node) == tColorTraits::black()){ + //we're in the source-tree + tDistanceVal min_distance = (std::numeric_limits::max)(); + edge_descriptor new_parent_edge; + out_edge_iterator ei, e_end; + for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ + const edge_descriptor in_edge = m_rev_edge_map[*ei]; + assert(target(in_edge, m_g) == current_node); //we should be the target of this edge + if(m_res_cap_map[in_edge] > 0){ + vertex_descriptor other_node = source(in_edge, m_g); + if(get_tree(other_node) == tColorTraits::black() && has_source_connect(other_node)){ + if(m_dist_map[other_node] < min_distance){ + min_distance = m_dist_map[other_node]; + new_parent_edge = in_edge; + } + } + } + } + if(min_distance != (std::numeric_limits::max)()){ + set_edge_to_parent(current_node, new_parent_edge); + m_dist_map[current_node] = min_distance + 1; + m_time_map[current_node] = m_time; + } else{ + m_time_map[current_node] = 0; + for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ + edge_descriptor in_edge = m_rev_edge_map[*ei]; + vertex_descriptor other_node = source(in_edge, m_g); + if(get_tree(other_node) == tColorTraits::black() && has_parent(other_node)){ + if(m_res_cap_map[in_edge] > 0){ + add_active_node(other_node); + } + if(source(get_edge_to_parent(other_node), m_g) == current_node){ + //we are the parent of that node + //it has to find a new parent, too + set_no_parent(other_node); + m_child_orphans.push(other_node); + } + } + } + set_tree(current_node, tColorTraits::gray()); + } //no parent found + } //source-tree-adoption + else{ + //now we should be in the sink-tree, check that... + assert(get_tree(current_node) == tColorTraits::white()); + out_edge_iterator ei, e_end; + edge_descriptor new_parent_edge; + tDistanceVal min_distance = (std::numeric_limits::max)(); + for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ + const edge_descriptor out_edge = *ei; + if(m_res_cap_map[out_edge] > 0){ + const vertex_descriptor other_node = target(out_edge, m_g); + if(get_tree(other_node) == tColorTraits::white() && has_sink_connect(other_node)) + if(m_dist_map[other_node] < min_distance){ + min_distance = m_dist_map[other_node]; + new_parent_edge = out_edge; + } + } + } + if(min_distance != (std::numeric_limits::max)()){ + set_edge_to_parent(current_node, new_parent_edge); + m_dist_map[current_node] = min_distance + 1; + m_time_map[current_node] = m_time; + } else{ + m_time_map[current_node] = 0; + for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ + const edge_descriptor out_edge = *ei; + const vertex_descriptor other_node = target(out_edge, m_g); + if(get_tree(other_node) == tColorTraits::white() && has_parent(other_node)){ + if(m_res_cap_map[out_edge] > 0){ + add_active_node(other_node); + } + if(target(get_edge_to_parent(other_node), m_g) == current_node){ + //we were it's parent, so it has to find a new one, too + set_no_parent(other_node); + m_child_orphans.push(other_node); + } + } + } + set_tree(current_node, tColorTraits::gray()); + } //no parent found + } //sink-tree adoption + } //while !orphans.empty() + } //adopt + + /** + * return next active vertex if there is one, otherwise a null_vertex + */ + inline vertex_descriptor get_next_active_node(){ + while(true){ + if(m_active_nodes.empty()) + return graph_traits::null_vertex(); + vertex_descriptor v = m_active_nodes.front(); + + if(!has_parent(v) && v != m_source && v != m_sink){ //if it has no parent, this node can't be active(if its not source or sink) + m_active_nodes.pop(); + m_in_active_list_map[v] = false; + } else{ + assert(get_tree(v) == tColorTraits::black() || get_tree(v) == tColorTraits::white()); + return v; + } + } + } + + /** + * adds v as an active vertex, but only if its not in the list already + */ + inline void add_active_node(vertex_descriptor v){ + assert(get_tree(v) != tColorTraits::gray()); + if(m_in_active_list_map[v]){ + return; + } else{ + m_in_active_list_map[v] = true; + m_active_nodes.push(v); + } + } + + /** + * finish_node removes a node from the front of the active queue (its called in grow phase, if no more paths can be found using this node) + */ + inline void finish_node(vertex_descriptor v){ + assert(m_active_nodes.front() == v); + m_active_nodes.pop(); + m_in_active_list_map[v] = false; + m_last_grow_vertex = graph_traits::null_vertex(); + } + + /** + * removes a vertex from the queue of active nodes (actually this does nothing, + * but checks if this node has no parent edge, as this is the criteria for beeing no more active) + */ + inline void remove_active_node(vertex_descriptor v){ + assert(!has_parent(v)); + } + + /** + * returns the search tree of v; tColorValue::black() for source tree, white() for sink tree, gray() for no tree + */ + inline tColorValue get_tree(vertex_descriptor v) const { + return m_tree_map[v]; + } + + /** + * sets search tree of v; tColorValue::black() for source tree, white() for sink tree, gray() for no tree + */ + inline void set_tree(vertex_descriptor v, tColorValue t){ + m_tree_map[v] = t; + } + + /** + * returns edge to parent vertex of v; + */ + inline edge_descriptor get_edge_to_parent(vertex_descriptor v) const{ + return m_pre_map[v]; + } + + /** + * returns true if the edge stored in m_pre_map[v] is a valid entry + */ + inline bool has_parent(vertex_descriptor v) const{ + return m_has_parent_map[v]; + } + + /** + * sets edge to parent vertex of v; + */ + inline void set_edge_to_parent(vertex_descriptor v, edge_descriptor f_edge_to_parent){ + assert(m_res_cap_map[f_edge_to_parent] > 0); + m_pre_map[v] = f_edge_to_parent; + m_has_parent_map[v] = true; + } + + /** + * removes the edge to parent of v (this is done by invalidating the entry an additional map) + */ + inline void set_no_parent(vertex_descriptor v){ + m_has_parent_map[v] = false; + } + + /** + * checks if vertex v has a connect to the sink-vertex (@var m_sink) + * @param v the vertex which is checked + * @return true if a path to the sink was found, false if not + */ + inline bool has_sink_connect(vertex_descriptor v){ + tDistanceVal current_distance = 0; + vertex_descriptor current_vertex = v; + while(true){ + if(m_time_map[current_vertex] == m_time){ + //we found a node which was already checked this round. use it for distance calculations + current_distance += m_dist_map[current_vertex]; + break; + } + if(current_vertex == m_sink){ + m_time_map[m_sink] = m_time; + break; + } + if(has_parent(current_vertex)){ + //it has a parent, so get it + current_vertex = target(get_edge_to_parent(current_vertex), m_g); + ++current_distance; + } else{ + //no path found + return false; + } + } + current_vertex=v; + while(m_time_map[current_vertex] != m_time){ + m_dist_map[current_vertex] = current_distance--; + m_time_map[current_vertex] = m_time; + current_vertex = target(get_edge_to_parent(current_vertex), m_g); + } + return true; + } + + /** + * checks if vertex v has a connect to the source-vertex (@var m_source) + * @param v the vertex which is checked + * @return true if a path to the source was found, false if not + */ + inline bool has_source_connect(vertex_descriptor v){ + tDistanceVal current_distance = 0; + vertex_descriptor current_vertex = v; + while(true){ + if(m_time_map[current_vertex] == m_time){ + //we found a node which was already checked this round. use it for distance calculations + current_distance += m_dist_map[current_vertex]; + break; + } + if(current_vertex == m_source){ + m_time_map[m_source] = m_time; + break; + } + if(has_parent(current_vertex)){ + //it has a parent, so get it + current_vertex = source(get_edge_to_parent(current_vertex), m_g); + ++current_distance; + } else{ + //no path found + return false; + } + } + current_vertex=v; + while(m_time_map[current_vertex] != m_time){ + m_dist_map[current_vertex] = current_distance-- ; + m_time_map[current_vertex] = m_time; + current_vertex = source(get_edge_to_parent(current_vertex), m_g); + } + return true; + } + + /** + * returns true, if p is closer to a terminal than q + */ + inline bool is_closer_to_terminal(vertex_descriptor p, vertex_descriptor q){ + //checks the timestamps first, to build no cycles, and after that the real distance + return (m_time_map[q] <= m_time_map[p] && m_dist_map[q] > m_dist_map[p]+1); + } + + //////// + // member vars + //////// + Graph& m_g; + IndexMap m_index_map; + EdgeCapacityMap m_cap_map; + ResidualCapacityEdgeMap m_res_cap_map; + ReverseEdgeMap m_rev_edge_map; + PredecessorMap m_pre_map; //stores paths found in the growth stage + ColorMap m_tree_map; //maps each vertex into one of the two search tree or none (gray()) + DistanceMap m_dist_map; //stores distance to source/sink nodes + vertex_descriptor m_source; + vertex_descriptor m_sink; + + tQueue m_active_nodes; + std::vector m_in_active_list_vec; + iterator_property_map::iterator, IndexMap> m_in_active_list_map; + + std::list m_orphans; + tQueue m_child_orphans; // we use a second queuqe for child orphans, as they are FIFO processed + + std::vector m_has_parent_vec; + iterator_property_map::iterator, IndexMap> m_has_parent_map; + + std::vector m_time_vec; //timestamp of each node, used for sink/source-path calculations + iterator_property_map::iterator, IndexMap> m_time_map; + tEdgeVal m_flow; + long m_time; + vertex_descriptor m_last_grow_vertex; + out_edge_iterator m_last_grow_edge_it; + out_edge_iterator m_last_grow_edge_end; + }; + } //namespace detail + + /** + * non-named-parameter version, given everything + * this is the catch all version + */ + template + typename property_traits::value_type + kolmogorov_max_flow + (Graph& g, + CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, + ReverseEdgeMap rev_map, + PredecessorMap pre_map, + ColorMap color, + DistanceMap dist, + IndexMap idx, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink + ) + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + //as this method is the last one before we instantiate the solver, we do the concept checks here + function_requires >(); //to have vertices(), num_vertices(), + function_requires >(); //to have edges() + function_requires >(); //to have source(), target() and out_edges() + function_requires >(); //read flow-values from edges + function_requires >(); //write flow-values to residuals + function_requires >(); //read out reverse edges + function_requires >(); //store predecessor there + function_requires >(); //write corresponding tree + function_requires >(); //write distance to source/sink + function_requires >(); //get index 0...|V|-1 + assert(num_vertices(g) >= 2 && src != sink); + detail::kolmogorov + algo(g, cap, res_cap, rev_map, pre_map, color, dist, idx, src, sink); + return algo.max_flow(); + } + + /** + * non-named-parameter version, given: capacity, residucal_capacity, reverse_edges, and an index map. + */ + template + typename property_traits::value_type + kolmogorov_max_flow + (Graph& g, + CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, + ReverseEdgeMap rev, + IndexMap idx, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink) + { + typename graph_traits::vertices_size_type n_verts = num_vertices(g); + std::vector::edge_descriptor> predecessor_vec(n_verts); + std::vector color_vec(n_verts); + std::vector::vertices_size_type> distance_vec(n_verts); + return kolmogorov_max_flow + (g, cap, res_cap, rev, + make_iterator_property_map(predecessor_vec.begin(), idx), + make_iterator_property_map(color_vec.begin(), idx), + make_iterator_property_map(distance_vec.begin(), idx), + idx, src, sink); + } + + /** + * non-named-parameter version, some given: capacity, residual_capacity, reverse_edges, color_map and an index map. + * Use this if you are interested in the minimum cut, as the color map provides that info + */ + template + typename property_traits::value_type + kolmogorov_max_flow + (Graph& g, + CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, + ReverseEdgeMap rev, + ColorMap color, + IndexMap idx, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink) + { + typename graph_traits::vertices_size_type n_verts = num_vertices(g); + std::vector::edge_descriptor> predecessor_vec(n_verts); + std::vector::vertices_size_type> distance_vec(n_verts); + + return kolmogorov_max_flow + (g, cap, res_cap, rev, + make_iterator_property_map(predecessor_vec.begin(), idx), + color, + make_iterator_property_map(distance_vec.begin(), idx), + idx, src, sink); + } + + /** + * named-parameter version, some given + */ + template + typename property_traits::const_type>::value_type + kolmogorov_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + const bgl_named_params& params) + { + return kolmogorov_max_flow(g, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_pmap(get_param(params, vertex_predecessor), g, vertex_predecessor), + choose_pmap(get_param(params, vertex_color), g, vertex_color), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + src, sink); + } + + /** + * named-parameter version, none given + */ + template + typename property_traits::const_type>::value_type + kolmogorov_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink) + { + bgl_named_params params(0); // bogus empty param + return kolmogorov_max_flow(g, src, sink, params); + } +} // namespace boost + +#endif // BOOST_KOLMOGOROV_MAX_FLOW_HPP + diff --git a/thirdparty/boost/graph/kruskal_min_spanning_tree.hpp b/thirdparty/boost/graph/kruskal_min_spanning_tree.hpp new file mode 100644 index 0000000..150aa9d --- /dev/null +++ b/thirdparty/boost/graph/kruskal_min_spanning_tree.hpp @@ -0,0 +1,155 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_MST_KRUSKAL_HPP +#define BOOST_GRAPH_MST_KRUSKAL_HPP + +/* + *Minimum Spanning Tree + * Kruskal Algorithm + * + *Requirement: + * undirected graph + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + + +namespace boost { + + // Kruskal's algorithm for Minimum Spanning Tree + // + // This is a greedy algorithm to calculate the Minimum Spanning Tree + // for an undirected graph with weighted edges. The output will be a + // set of edges. + // + + namespace detail { + + template + void + kruskal_mst_impl(const Graph& G, + OutputIterator spanning_tree_edges, + Rank rank, Parent parent, Weight weight) + { + if (num_vertices(G) == 0) return; // Nothing to do in this case + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + function_requires >(); + typedef typename property_traits::value_type W_value; + typedef typename property_traits::value_type R_value; + typedef typename property_traits::value_type P_value; + function_requires >(); + function_requires >(); + function_requires >(); + + disjoint_sets dset(rank, parent); + + typename graph_traits::vertex_iterator ui, uiend; + for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) + dset.make_set(*ui); + + typedef indirect_cmp > weight_greater; + weight_greater wl(weight); + std::priority_queue, weight_greater> Q(wl); + /*push all edge into Q*/ + typename graph_traits::edge_iterator ei, eiend; + for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei) + Q.push(*ei); + + while (! Q.empty()) { + Edge e = Q.top(); + Q.pop(); + Vertex u = dset.find_set(source(e, G)); + Vertex v = dset.find_set(target(e, G)); + if ( u != v ) { + *spanning_tree_edges++ = e; + dset.link(u, v); + } + } + } + + } // namespace detail + + // Named Parameters Variants + + template + inline void + kruskal_minimum_spanning_tree(const Graph& g, + OutputIterator spanning_tree_edges) + { + typedef typename graph_traits::vertices_size_type size_type; + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename property_map::type index_map_t; + if (num_vertices(g) == 0) return; // Nothing to do in this case + typename graph_traits::vertices_size_type + n = num_vertices(g); + std::vector rank_map(n); + std::vector pred_map(n); + + detail::kruskal_mst_impl + (g, spanning_tree_edges, + make_iterator_property_map(rank_map.begin(), get(vertex_index, g), rank_map[0]), + make_iterator_property_map(pred_map.begin(), get(vertex_index, g), pred_map[0]), + get(edge_weight, g)); + } + + template + inline void + kruskal_minimum_spanning_tree(const Graph& g, + OutputIterator spanning_tree_edges, + const bgl_named_params& params) + { + typedef typename graph_traits::vertices_size_type size_type; + typedef typename graph_traits::vertex_descriptor vertex_t; + if (num_vertices(g) == 0) return; // Nothing to do in this case + typename graph_traits::vertices_size_type n; + n = is_default_param(get_param(params, vertex_rank)) + ? num_vertices(g) : 1; + std::vector rank_map(n); + n = is_default_param(get_param(params, vertex_predecessor)) + ? num_vertices(g) : 1; + std::vector pred_map(n); + + detail::kruskal_mst_impl + (g, spanning_tree_edges, + choose_param + (get_param(params, vertex_rank), + make_iterator_property_map + (rank_map.begin(), + choose_pmap(get_param(params, vertex_index), g, vertex_index), rank_map[0])), + choose_param + (get_param(params, vertex_predecessor), + make_iterator_property_map + (pred_map.begin(), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + pred_map[0])), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); + } + +} // namespace boost + + +#endif // BOOST_GRAPH_MST_KRUSKAL_HPP + diff --git a/thirdparty/boost/graph/leda_graph.hpp b/thirdparty/boost/graph/leda_graph.hpp new file mode 100644 index 0000000..8df0bd5 --- /dev/null +++ b/thirdparty/boost/graph/leda_graph.hpp @@ -0,0 +1,952 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2004 The Trustees of Indiana University. +// Copyright 2007 University of Karlsruhe +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor, +// Jens Mueller +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_LEDA_HPP +#define BOOST_GRAPH_LEDA_HPP + +#include +#include +#include +#include + +#include +#include +#include + +// The functions and classes in this file allows the user to +// treat a LEDA GRAPH object as a boost graph "as is". No +// wrapper is needed for the GRAPH object. + +// Warning: this implementation relies on partial specialization +// for the graph_traits class (so it won't compile with Visual C++) + +// Warning: this implementation is in alpha and has not been tested + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { + + struct leda_graph_traversal_category : + public virtual bidirectional_graph_tag, + public virtual adjacency_graph_tag, + public virtual vertex_list_graph_tag { }; + + template + struct graph_traits< leda::GRAPH > { + typedef leda::node vertex_descriptor; + typedef leda::edge edge_descriptor; + + class adjacency_iterator + : public iterator_facade + { + public: + adjacency_iterator(leda::node node = 0, + const leda::GRAPH* g = 0) + : base(node), g(g) {} + private: + leda::node dereference() const { return leda::target(base); } + + bool equal(const adjacency_iterator& other) const + { return base == other.base; } + + void increment() { base = g->adj_succ(base); } + void decrement() { base = g->adj_pred(base); } + + leda::edge base; + const leda::GRAPH* g; + + friend class iterator_core_access; + }; + + class out_edge_iterator + : public iterator_facade + { + public: + out_edge_iterator(leda::node node = 0, + const leda::GRAPH* g = 0) + : base(node), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const out_edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->adj_succ(base); } + void decrement() { base = g->adj_pred(base); } + + leda::edge base; + const leda::GRAPH* g; + + friend class iterator_core_access; + }; + + class in_edge_iterator + : public iterator_facade + { + public: + in_edge_iterator(leda::node node = 0, + const leda::GRAPH* g = 0) + : base(node), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const in_edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->in_succ(base); } + void decrement() { base = g->in_pred(base); } + + leda::edge base; + const leda::GRAPH* g; + + friend class iterator_core_access; + }; + + class vertex_iterator + : public iterator_facade + { + public: + vertex_iterator(leda::node node = 0, + const leda::GRAPH* g = 0) + : base(node), g(g) {} + + private: + const leda::node& dereference() const { return base; } + + bool equal(const vertex_iterator& other) const + { return base == other.base; } + + void increment() { base = g->succ_node(base); } + void decrement() { base = g->pred_node(base); } + + leda::node base; + const leda::GRAPH* g; + + friend class iterator_core_access; + }; + + class edge_iterator + : public iterator_facade + { + public: + edge_iterator(leda::edge edge = 0, + const leda::GRAPH* g = 0) + : base(edge), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->succ_edge(base); } + void decrement() { base = g->pred_edge(base); } + + leda::node base; + const leda::GRAPH* g; + + friend class iterator_core_access; + }; + + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; // not sure here + typedef leda_graph_traversal_category traversal_category; + typedef int vertices_size_type; + typedef int edges_size_type; + typedef int degree_size_type; + }; + + + + template<> + struct graph_traits { + typedef leda::node vertex_descriptor; + typedef leda::edge edge_descriptor; + + class adjacency_iterator + : public iterator_facade + { + public: + adjacency_iterator(leda::edge edge = 0, + const leda::graph* g = 0) + : base(edge), g(g) {} + + private: + leda::node dereference() const { return leda::target(base); } + + bool equal(const adjacency_iterator& other) const + { return base == other.base; } + + void increment() { base = g->adj_succ(base); } + void decrement() { base = g->adj_pred(base); } + + leda::edge base; + const leda::graph* g; + + friend class iterator_core_access; + }; + + class out_edge_iterator + : public iterator_facade + { + public: + out_edge_iterator(leda::edge edge = 0, + const leda::graph* g = 0) + : base(edge), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const out_edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->adj_succ(base); } + void decrement() { base = g->adj_pred(base); } + + leda::edge base; + const leda::graph* g; + + friend class iterator_core_access; + }; + + class in_edge_iterator + : public iterator_facade + { + public: + in_edge_iterator(leda::edge edge = 0, + const leda::graph* g = 0) + : base(edge), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const in_edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->in_succ(base); } + void decrement() { base = g->in_pred(base); } + + leda::edge base; + const leda::graph* g; + + friend class iterator_core_access; + }; + + class vertex_iterator + : public iterator_facade + { + public: + vertex_iterator(leda::node node = 0, + const leda::graph* g = 0) + : base(node), g(g) {} + + private: + const leda::node& dereference() const { return base; } + + bool equal(const vertex_iterator& other) const + { return base == other.base; } + + void increment() { base = g->succ_node(base); } + void decrement() { base = g->pred_node(base); } + + leda::node base; + const leda::graph* g; + + friend class iterator_core_access; + }; + + class edge_iterator + : public iterator_facade + { + public: + edge_iterator(leda::edge edge = 0, + const leda::graph* g = 0) + : base(edge), g(g) {} + + private: + const leda::edge& dereference() const { return base; } + + bool equal(const edge_iterator& other) const + { return base == other.base; } + + void increment() { base = g->succ_edge(base); } + void decrement() { base = g->pred_edge(base); } + + leda::edge base; + const leda::graph* g; + + friend class iterator_core_access; + }; + + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; // not sure here + typedef leda_graph_traversal_category traversal_category; + typedef int vertices_size_type; + typedef int edges_size_type; + typedef int degree_size_type; + }; + +} // namespace boost +#endif + +namespace boost { + + //=========================================================================== + // functions for GRAPH + + template + typename graph_traits< leda::GRAPH >::vertex_descriptor + source(typename graph_traits< leda::GRAPH >::edge_descriptor e, + const leda::GRAPH& g) + { + return source(e); + } + + template + typename graph_traits< leda::GRAPH >::vertex_descriptor + target(typename graph_traits< leda::GRAPH >::edge_descriptor e, + const leda::GRAPH& g) + { + return target(e); + } + + template + inline std::pair< + typename graph_traits< leda::GRAPH >::vertex_iterator, + typename graph_traits< leda::GRAPH >::vertex_iterator > + vertices(const leda::GRAPH& g) + { + typedef typename graph_traits< leda::GRAPH >::vertex_iterator + Iter; + return std::make_pair( Iter(g.first_node(),&g), Iter(0,&g) ); + } + + template + inline std::pair< + typename graph_traits< leda::GRAPH >::edge_iterator, + typename graph_traits< leda::GRAPH >::edge_iterator > + edges(const leda::GRAPH& g) + { + typedef typename graph_traits< leda::GRAPH >::edge_iterator + Iter; + return std::make_pair( Iter(g.first_edge(),&g), Iter(0,&g) ); + } + + template + inline std::pair< + typename graph_traits< leda::GRAPH >::out_edge_iterator, + typename graph_traits< leda::GRAPH >::out_edge_iterator > + out_edges( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + typedef typename graph_traits< leda::GRAPH > + ::out_edge_iterator Iter; + return std::make_pair( Iter(g.first_adj_edge(u,0),&g), Iter(0,&g) ); + } + + template + inline std::pair< + typename graph_traits< leda::GRAPH >::in_edge_iterator, + typename graph_traits< leda::GRAPH >::in_edge_iterator > + in_edges( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + typedef typename graph_traits< leda::GRAPH > + ::in_edge_iterator Iter; + return std::make_pair( Iter(g.first_adj_edge(u,1),&g), Iter(0,&g) ); + } + + template + inline std::pair< + typename graph_traits< leda::GRAPH >::adjacency_iterator, + typename graph_traits< leda::GRAPH >::adjacency_iterator > + adjacent_vertices( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + typedef typename graph_traits< leda::GRAPH > + ::adjacency_iterator Iter; + return std::make_pair( Iter(g.first_adj_edge(u,0),&g), Iter(0,&g) ); + } + + template + typename graph_traits< leda::GRAPH >::vertices_size_type + num_vertices(const leda::GRAPH& g) + { + return g.number_of_nodes(); + } + + template + typename graph_traits< leda::GRAPH >::edges_size_type + num_edges(const leda::GRAPH& g) + { + return g.number_of_edges(); + } + + template + typename graph_traits< leda::GRAPH >::degree_size_type + out_degree( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + return g.outdeg(u); + } + + template + typename graph_traits< leda::GRAPH >::degree_size_type + in_degree( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + return g.indeg(u); + } + + template + typename graph_traits< leda::GRAPH >::degree_size_type + degree( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + const leda::GRAPH& g) + { + return g.outdeg(u) + g.indeg(u); + } + + template + typename graph_traits< leda::GRAPH >::vertex_descriptor + add_vertex(leda::GRAPH& g) + { + return g.new_node(); + } + + template + typename graph_traits< leda::GRAPH >::vertex_descriptor + add_vertex(const vtype& vp, leda::GRAPH& g) + { + return g.new_node(vp); + } + + template + void clear_vertex( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + leda::GRAPH& g) + { + typename graph_traits< leda::GRAPH >::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end)=out_edges(u,g); ei!=ei_end; ei++) + remove_edge(*ei); + + typename graph_traits< leda::GRAPH >::in_edge_iterator iei, iei_end; + for (tie(iei, iei_end)=in_edges(u,g); iei!=iei_end; iei++) + remove_edge(*iei); + } + + template + void remove_vertex( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + leda::GRAPH& g) + { + g.del_node(u); + } + + template + std::pair< + typename graph_traits< leda::GRAPH >::edge_descriptor, + bool> + add_edge( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + typename graph_traits< leda::GRAPH >::vertex_descriptor v, + leda::GRAPH& g) + { + return std::make_pair(g.new_edge(u, v), true); + } + + template + std::pair< + typename graph_traits< leda::GRAPH >::edge_descriptor, + bool> + add_edge( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + typename graph_traits< leda::GRAPH >::vertex_descriptor v, + const etype& et, + leda::GRAPH& g) + { + return std::make_pair(g.new_edge(u, v, et), true); + } + + template + void + remove_edge( + typename graph_traits< leda::GRAPH >::vertex_descriptor u, + typename graph_traits< leda::GRAPH >::vertex_descriptor v, + leda::GRAPH& g) + { + typename graph_traits< leda::GRAPH >::out_edge_iterator + i,iend; + for (boost::tie(i,iend) = out_edges(u,g); i != iend; ++i) + if (target(*i,g) == v) + g.del_edge(*i); + } + + template + void + remove_edge( + typename graph_traits< leda::GRAPH >::edge_descriptor e, + leda::GRAPH& g) + { + g.del_edge(e); + } + + //=========================================================================== + // functions for graph (non-templated version) + + graph_traits::vertex_descriptor + source(graph_traits::edge_descriptor e, + const leda::graph& g) + { + return source(e); + } + + graph_traits::vertex_descriptor + target(graph_traits::edge_descriptor e, + const leda::graph& g) + { + return target(e); + } + + inline std::pair< + graph_traits::vertex_iterator, + graph_traits::vertex_iterator > + vertices(const leda::graph& g) + { + typedef graph_traits::vertex_iterator + Iter; + return std::make_pair( Iter(g.first_node(),&g), Iter(0,&g) ); + } + + inline std::pair< + graph_traits::edge_iterator, + graph_traits::edge_iterator > + edges(const leda::graph& g) + { + typedef graph_traits::edge_iterator + Iter; + return std::make_pair( Iter(g.first_edge(),&g), Iter(0,&g) ); + } + + inline std::pair< + graph_traits::out_edge_iterator, + graph_traits::out_edge_iterator > + out_edges( + graph_traits::vertex_descriptor u, const leda::graph& g) + { + typedef graph_traits::out_edge_iterator Iter; + return std::make_pair( Iter(g.first_adj_edge(u),&g), Iter(0,&g) ); + } + + inline std::pair< + graph_traits::in_edge_iterator, + graph_traits::in_edge_iterator > + in_edges( + graph_traits::vertex_descriptor u, + const leda::graph& g) + { + typedef graph_traits + ::in_edge_iterator Iter; + return std::make_pair( Iter(g.first_in_edge(u),&g), Iter(0,&g) ); + } + + inline std::pair< + graph_traits::adjacency_iterator, + graph_traits::adjacency_iterator > + adjacent_vertices( + graph_traits::vertex_descriptor u, + const leda::graph& g) + { + typedef graph_traits + ::adjacency_iterator Iter; + return std::make_pair( Iter(g.first_adj_edge(u),&g), Iter(0,&g) ); + } + + graph_traits::vertices_size_type + num_vertices(const leda::graph& g) + { + return g.number_of_nodes(); + } + + graph_traits::edges_size_type + num_edges(const leda::graph& g) + { + return g.number_of_edges(); + } + + graph_traits::degree_size_type + out_degree( + graph_traits::vertex_descriptor u, + const leda::graph& g) + { + return g.outdeg(u); + } + + graph_traits::degree_size_type + in_degree( + graph_traits::vertex_descriptor u, + const leda::graph& g) + { + return g.indeg(u); + } + + graph_traits::degree_size_type + degree( + graph_traits::vertex_descriptor u, + const leda::graph& g) + { + return g.outdeg(u) + g.indeg(u); + } + + graph_traits::vertex_descriptor + add_vertex(leda::graph& g) + { + return g.new_node(); + } + + void + remove_edge( + graph_traits::vertex_descriptor u, + graph_traits::vertex_descriptor v, + leda::graph& g) + { + graph_traits::out_edge_iterator + i,iend; + for (boost::tie(i,iend) = out_edges(u,g); i != iend; ++i) + if (target(*i,g) == v) + g.del_edge(*i); + } + + void + remove_edge( + graph_traits::edge_descriptor e, + leda::graph& g) + { + g.del_edge(e); + } + + void clear_vertex( + graph_traits::vertex_descriptor u, + leda::graph& g) + { + graph_traits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end)=out_edges(u,g); ei!=ei_end; ei++) + remove_edge(*ei, g); + + graph_traits::in_edge_iterator iei, iei_end; + for (tie(iei, iei_end)=in_edges(u,g); iei!=iei_end; iei++) + remove_edge(*iei, g); + } + + void remove_vertex( + graph_traits::vertex_descriptor u, + leda::graph& g) + { + g.del_node(u); + } + + std::pair< + graph_traits::edge_descriptor, + bool> + add_edge( + graph_traits::vertex_descriptor u, + graph_traits::vertex_descriptor v, + leda::graph& g) + { + return std::make_pair(g.new_edge(u, v), true); + } + + + //=========================================================================== + // property maps for GRAPH + + class leda_graph_id_map + : public put_get_helper + { + public: + typedef readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef leda::node key_type; + leda_graph_id_map() { } + template + long operator[](T x) const { return x->id(); } + }; + template + inline leda_graph_id_map + get(vertex_index_t, const leda::GRAPH& g) { + return leda_graph_id_map(); + } + template + inline leda_graph_id_map + get(edge_index_t, const leda::GRAPH& g) { + return leda_graph_id_map(); + } + + template + struct leda_property_map { }; + + template <> + struct leda_property_map { + template + struct bind_ { + typedef leda_graph_id_map type; + typedef leda_graph_id_map const_type; + }; + }; + template <> + struct leda_property_map { + template + struct bind_ { + typedef leda_graph_id_map type; + typedef leda_graph_id_map const_type; + }; + }; + + + template + class leda_graph_data_map + : public put_get_helper > + { + public: + typedef Data value_type; + typedef DataRef reference; + typedef void key_type; + typedef lvalue_property_map_tag category; + leda_graph_data_map(GraphPtr g) : m_g(g) { } + template + DataRef operator[](NodeOrEdge x) const { return (*m_g)[x]; } + protected: + GraphPtr m_g; + }; + + template <> + struct leda_property_map { + template + struct bind_ { + typedef leda_graph_data_map*> type; + typedef leda_graph_data_map*> const_type; + }; + }; + template + inline typename property_map< leda::GRAPH, vertex_all_t>::type + get(vertex_all_t, leda::GRAPH& g) { + typedef typename property_map< leda::GRAPH, vertex_all_t>::type + pmap_type; + return pmap_type(&g); + } + template + inline typename property_map< leda::GRAPH, vertex_all_t>::const_type + get(vertex_all_t, const leda::GRAPH& g) { + typedef typename property_map< leda::GRAPH, + vertex_all_t>::const_type pmap_type; + return pmap_type(&g); + } + + template <> + struct leda_property_map { + template + struct bind_ { + typedef leda_graph_data_map*> type; + typedef leda_graph_data_map*> const_type; + }; + }; + template + inline typename property_map< leda::GRAPH, edge_all_t>::type + get(edge_all_t, leda::GRAPH& g) { + typedef typename property_map< leda::GRAPH, edge_all_t>::type + pmap_type; + return pmap_type(&g); + } + template + inline typename property_map< leda::GRAPH, edge_all_t>::const_type + get(edge_all_t, const leda::GRAPH& g) { + typedef typename property_map< leda::GRAPH, + edge_all_t>::const_type pmap_type; + return pmap_type(&g); + } + + // property map interface to the LEDA node_array class + + template + class leda_node_property_map + : public put_get_helper > + { + public: + typedef E value_type; + typedef ERef reference; + typedef leda::node key_type; + typedef lvalue_property_map_tag category; + leda_node_property_map(NodeMapPtr a) : m_array(a) { } + ERef operator[](leda::node n) const { return (*m_array)[n]; } + protected: + NodeMapPtr m_array; + }; + template + leda_node_property_map*> + make_leda_node_property_map(const leda::node_array& a) + { + typedef leda_node_property_map*> + pmap_type; + return pmap_type(&a); + } + template + leda_node_property_map*> + make_leda_node_property_map(leda::node_array& a) + { + typedef leda_node_property_map*> pmap_type; + return pmap_type(&a); + } + + template + leda_node_property_map*> + make_leda_node_property_map(const leda::node_map& a) + { + typedef leda_node_property_map*> + pmap_type; + return pmap_type(&a); + } + template + leda_node_property_map*> + make_leda_node_property_map(leda::node_map& a) + { + typedef leda_node_property_map*> pmap_type; + return pmap_type(&a); + } + + // g++ 'enumeral_type' in template unification not implemented workaround + template + struct property_map, Tag> { + typedef typename + leda_property_map::template bind_ map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; + }; + + template + inline + typename boost::property_traits< + typename boost::property_map,PropertyTag>::const_type +::value_type + get(PropertyTag p, const leda::GRAPH& g, const Key& key) { + return get(get(p, g), key); + } + + template + inline void + put(PropertyTag p, leda::GRAPH& g, + const Key& key, const Value& value) + { + typedef typename property_map, PropertyTag>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); + } + + // property map interface to the LEDA edge_array class + + template + class leda_edge_property_map + : public put_get_helper > + { + public: + typedef E value_type; + typedef ERef reference; + typedef leda::edge key_type; + typedef lvalue_property_map_tag category; + leda_edge_property_map(EdgeMapPtr a) : m_array(a) { } + ERef operator[](leda::edge n) const { return (*m_array)[n]; } + protected: + EdgeMapPtr m_array; + }; + template + leda_edge_property_map*> + make_leda_node_property_map(const leda::node_array& a) + { + typedef leda_edge_property_map*> + pmap_type; + return pmap_type(&a); + } + template + leda_edge_property_map*> + make_leda_edge_property_map(leda::edge_array& a) + { + typedef leda_edge_property_map*> pmap_type; + return pmap_type(&a); + } + + template + leda_edge_property_map*> + make_leda_edge_property_map(const leda::edge_map& a) + { + typedef leda_edge_property_map*> + pmap_type; + return pmap_type(&a); + } + template + leda_edge_property_map*> + make_leda_edge_property_map(leda::edge_map& a) + { + typedef leda_edge_property_map*> pmap_type; + return pmap_type(&a); + } + +} // namespace boost + +#endif // BOOST_GRAPH_LEDA_HPP diff --git a/thirdparty/boost/graph/make_biconnected_planar.hpp b/thirdparty/boost/graph/make_biconnected_planar.hpp new file mode 100644 index 0000000..09f9a6c --- /dev/null +++ b/thirdparty/boost/graph/make_biconnected_planar.hpp @@ -0,0 +1,121 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __MAKE_BICONNECTED_PLANAR_HPP__ +#define __MAKE_BICONNECTED_PLANAR_HPP__ + +#include +#include //for tie +#include +#include +#include +#include +#include + +#include + + +namespace boost +{ + + + + template + void make_biconnected_planar(Graph& g, + PlanarEmbedding embedding, + EdgeIndexMap em, + AddEdgeVisitor& vis + ) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::edges_size_type edge_size_t; + typedef typename + property_traits::value_type embedding_value_t; + typedef typename embedding_value_t::const_iterator embedding_iterator_t; + typedef iterator_property_map + ::iterator, EdgeIndexMap> component_map_t; + + edge_size_t n_edges(num_edges(g)); + std::vector articulation_points; + std::vector component_vector(n_edges); + component_map_t component_map(component_vector.begin(), em); + + biconnected_components(g, component_map, + std::back_inserter(articulation_points)); + + typename std::vector::iterator ap, ap_end; + ap_end = articulation_points.end(); + for(ap = articulation_points.begin(); ap != ap_end; ++ap) + { + vertex_t v(*ap); + embedding_iterator_t pi = embedding[v].begin(); + embedding_iterator_t pi_end = embedding[v].end(); + edge_size_t previous_component(n_edges + 1); + vertex_t previous_vertex = graph_traits::null_vertex(); + + for(; pi != pi_end; ++pi) + { + edge_t e(*pi); + vertex_t e_source(source(e,g)); + vertex_t e_target(target(e,g)); + + //Skip self-loops and parallel edges + if (e_source == e_target || previous_vertex == e_target) + continue; + + vertex_t current_vertex = e_source == v ? e_target : e_source; + edge_size_t current_component = component_map[e]; + if (previous_vertex != graph_traits::null_vertex() && + current_component != previous_component) + { + vis.visit_vertex_pair(current_vertex, previous_vertex, g); + } + previous_vertex = current_vertex; + previous_component = current_component; + } + } + + } + + + + + template + inline void make_biconnected_planar(Graph& g, + PlanarEmbedding embedding, + EdgeIndexMap em + ) + { + default_add_edge_visitor vis; + make_biconnected_planar(g, embedding, em, vis); + } + + + + + template + inline void make_biconnected_planar(Graph& g, PlanarEmbedding embedding) + { + make_biconnected_planar(g, embedding, get(edge_index,g)); + } + + +} // namespace boost + + + +#endif //__MAKE_BICONNECTED_PLANAR_HPP__ diff --git a/thirdparty/boost/graph/make_connected.hpp b/thirdparty/boost/graph/make_connected.hpp new file mode 100644 index 0000000..0e6536e --- /dev/null +++ b/thirdparty/boost/graph/make_connected.hpp @@ -0,0 +1,99 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __MAKE_CONNECTED_HPP__ +#define __MAKE_CONNECTED_HPP__ + +#include +#include //for next +#include //for tie +#include +#include +#include + +#include +#include + + +namespace boost +{ + + + template + void make_connected(Graph& g, VertexIndexMap vm, AddEdgeVisitor& vis) + { + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef iterator_property_map< typename std::vector::iterator, + VertexIndexMap + > vertex_to_v_size_map_t; + + std::vector component_vector(num_vertices(g)); + vertex_to_v_size_map_t component(component_vector.begin(), vm); + std::vector vertices_by_component(num_vertices(g)); + + v_size_t num_components = connected_components(g, component); + + if (num_components < 2) + return; + + vertex_iterator_t vi, vi_end; + tie(vi,vi_end) = vertices(g); + std::copy(vi, vi_end, vertices_by_component.begin()); + + bucket_sort(vertices_by_component.begin(), + vertices_by_component.end(), + component, + num_components + ); + + typedef typename std::vector::iterator vec_of_vertices_itr_t; + + vec_of_vertices_itr_t ci_end = vertices_by_component.end(); + vec_of_vertices_itr_t ci_prev = vertices_by_component.begin(); + if (ci_prev == ci_end) + return; + + for(vec_of_vertices_itr_t ci = next(ci_prev); + ci != ci_end; ci_prev = ci, ++ci + ) + { + if (component[*ci_prev] != component[*ci]) + vis.visit_vertex_pair(*ci_prev, *ci, g); + } + + } + + + + + template + inline void make_connected(Graph& g, VertexIndexMap vm) + { + default_add_edge_visitor vis; + make_connected(g, vm, vis); + } + + + + + template + inline void make_connected(Graph& g) + { + make_connected(g, get(vertex_index,g)); + } + + + + +} // namespace boost + +#endif //__MAKE_CONNECTED_HPP__ diff --git a/thirdparty/boost/graph/make_maximal_planar.hpp b/thirdparty/boost/graph/make_maximal_planar.hpp new file mode 100644 index 0000000..687b707 --- /dev/null +++ b/thirdparty/boost/graph/make_maximal_planar.hpp @@ -0,0 +1,275 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __MAKE_MAXIMAL_PLANAR_HPP__ +#define __MAKE_MAXIMAL_PLANAR_HPP__ + +#include +#include //for tie +#include +#include +#include +#include +#include + +#include +#include + + +namespace boost +{ + + + template + struct triangulation_visitor : public planar_face_traversal_visitor + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename graph_traits::degree_size_type degree_size_t; + typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::adjacency_iterator + adjacency_iterator_t; + typedef typename std::vector vertex_vector_t; + typedef typename std::vector v_size_vector_t; + typedef typename std::vector degree_size_vector_t; + typedef iterator_property_map + < typename v_size_vector_t::iterator, VertexIndexMap > + vertex_to_v_size_map_t; + typedef iterator_property_map + < typename degree_size_vector_t::iterator, VertexIndexMap > + vertex_to_degree_size_map_t; + typedef typename vertex_vector_t::iterator face_iterator; + + + triangulation_visitor(Graph& arg_g, + VertexIndexMap arg_vm, + AddEdgeVisitor arg_add_edge_visitor + ) : + g(arg_g), + vm(arg_vm), + add_edge_visitor(arg_add_edge_visitor), + timestamp(0), + marked_vector(num_vertices(g), timestamp), + degree_vector(num_vertices(g), 0), + marked(marked_vector.begin(), vm), + degree(degree_vector.begin(), vm) + { + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(degree, *vi, out_degree(*vi, g)); + } + + template + void next_vertex(Vertex v) + { + // Self-loops will appear as consecutive vertices in the list of + // vertices on a face. We want to skip these. + if (!vertices_on_face.empty() && + (vertices_on_face.back() == v || vertices_on_face.front() == v) + ) + return; + + vertices_on_face.push_back(v); + } + + void end_face() + { + ++timestamp; + + if (vertices_on_face.size() <= 3) + { + // At most three vertices on this face - don't need to triangulate + vertices_on_face.clear(); + return; + } + + // Find vertex on face of minimum degree + degree_size_t min_degree = num_vertices(g); + typename vertex_vector_t::iterator min_degree_vertex_itr; + face_iterator fi_end = vertices_on_face.end(); + for(face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi) + { + degree_size_t deg = get(degree,*fi); + if (deg < min_degree) + { + min_degree_vertex_itr = fi; + min_degree = deg; + } + } + + // To simplify some of the manipulations, we'll re-arrange + // vertices_on_face so that it still contains the same + // (counter-clockwise) order of the vertices on this face, but now the + // min_degree_vertex is the first element in vertices_on_face. + vertex_vector_t temp_vector; + std::copy(min_degree_vertex_itr, vertices_on_face.end(), + std::back_inserter(temp_vector)); + std::copy(vertices_on_face.begin(), min_degree_vertex_itr, + std::back_inserter(temp_vector)); + vertices_on_face.swap(temp_vector); + + // Mark all of the min degree vertex's neighbors + adjacency_iterator_t ai, ai_end; + for(tie(ai,ai_end) = adjacent_vertices(vertices_on_face.front(),g); + ai != ai_end; ++ai + ) + { + put(marked, *ai, timestamp); + } + + typename vertex_vector_t::iterator marked_neighbor + = vertices_on_face.end(); + + // The iterator manipulations on the next two lines are safe because + // vertices_on_face.size() > 3 (from the first test in this function) + fi_end = prior(vertices_on_face.end()); + for(face_iterator fi = next(next(vertices_on_face.begin())); + fi != fi_end; ++fi + ) + { + if (get(marked, *fi) == timestamp) + { + marked_neighbor = fi; + break; + } + } + + if (marked_neighbor == vertices_on_face.end()) + { + add_edge_range( + vertices_on_face[0], + next(next(vertices_on_face.begin())), + prior(vertices_on_face.end()) + ); + } + else + { + add_edge_range( + vertices_on_face[1], + next(marked_neighbor), + vertices_on_face.end() + ); + + add_edge_range( + *next(marked_neighbor), + next(next(vertices_on_face.begin())), + marked_neighbor + ); + } + + //reset for the next face + vertices_on_face.clear(); + + } + + private: + + + void add_edge_range(vertex_t anchor, + face_iterator fi, + face_iterator fi_end + ) + { + for (; fi != fi_end; ++fi) + { + vertex_t v(*fi); + add_edge_visitor.visit_vertex_pair(anchor, v, g); + put(degree, anchor, get(degree, anchor) + 1); + put(degree, v, get(degree, v) + 1); + } + } + + + Graph& g; + VertexIndexMap vm; + AddEdgeVisitor add_edge_visitor; + v_size_t timestamp; + vertex_vector_t vertices_on_face; + v_size_vector_t marked_vector; + degree_size_vector_t degree_vector; + vertex_to_v_size_map_t marked; + vertex_to_degree_size_map_t degree; + + }; + + + + + template + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm, + EdgeIndexMap em, + AddEdgeVisitor& vis) + { + triangulation_visitor + visitor(g, vm, vis); + planar_face_traversal(g, embedding, visitor, em); + } + + + + + template + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm, + EdgeIndexMap em + ) + { + default_add_edge_visitor vis; + make_maximal_planar(g, embedding, vm, em, vis); + } + + + + + template + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm + ) + { + make_maximal_planar(g, embedding, vm, get(edge_index,g)); + } + + + + + template + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding + ) + { + make_maximal_planar(g, embedding, get(vertex_index,g)); + } + + + + +} // namespace boost + + + +#endif //__MAKE_MAXIMAL_PLANAR_HPP__ diff --git a/thirdparty/boost/graph/matrix_as_graph.hpp b/thirdparty/boost/graph/matrix_as_graph.hpp new file mode 100644 index 0000000..064f36e --- /dev/null +++ b/thirdparty/boost/graph/matrix_as_graph.hpp @@ -0,0 +1,127 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_MATRIX2GRAPH_HPP +#define BOOST_GRAPH_MATRIX2GRAPH_HPP + +#include +#include +#include +#include +#include + +namespace boost { + + template + class matrix_adj_iterator; + + template + class matrix_incidence_iterator; + +} + +#define BOOST_GRAPH_ADAPT_MATRIX_TO_GRAPH(Matrix) \ +namespace boost { \ + template <> \ + struct graph_traits< Matrix > { \ + typedef Matrix::OneD::const_iterator Iter; \ + typedef Matrix::size_type V; \ + typedef V vertex_descriptor; \ + typedef Iter E; \ + typedef E edge_descriptor; \ + typedef boost::matrix_incidence_iterator out_edge_iterator; \ + typedef boost::matrix_adj_iterator adjacency_iterator; \ + typedef Matrix::size_type size_type; \ + typedef boost::int_iterator vertex_iterator; \ + \ + friend std::pair \ + vertices(const Matrix& g) { \ + typedef vertex_iterator VIter; \ + return std::make_pair(VIter(0), VIter(g.nrows())); \ + } \ + \ + friend std::pair \ + out_edges(V v, const Matrix& g) { \ + typedef out_edge_iterator IncIter; \ + return std::make_pair(IncIter(g[v].begin()), \ + IncIter(g[v].end())); \ + } \ + friend std::pair \ + adjacent_vertices(V v, const Matrix& g) { \ + typedef adjacency_iterator AdjIter; \ + return std::make_pair(AdjIter(g[v].begin()), \ + AdjIter(g[v].end())); \ + } \ + friend vertex_descriptor \ + source(E e, const Matrix& g) { \ + return e.row(); \ + } \ + friend vertex_descriptor \ + target(E e, const Matrix& g) { \ + return e.column(); \ + } \ + friend size_type \ + num_vertices(const Matrix& g) { \ + return g.nrows(); \ + } \ + friend size_type \ + num_edges(const Matrix& g) { \ + return g.nnz(); \ + } \ + friend size_type \ + out_degree(V i, const Matrix& g) { \ + return g[i].nnz(); \ + } \ + }; \ +} + +namespace boost { + + template + class matrix_adj_iterator + : public std::iterator + { + typedef matrix_adj_iterator self; + public: + matrix_adj_iterator() { } + matrix_adj_iterator(Iter i) : _iter(i) { } + matrix_adj_iterator(const self& x) : _iter(x._iter) { } + self& operator=(const self& x) { _iter = x._iter; return *this; } + Vertex operator*() { return _iter.column(); } + self& operator++() { ++_iter; return *this; } + self operator++(int) { self t = *this; ++_iter; return t; } + bool operator==(const self& x) const { return _iter == x._iter; } + bool operator!=(const self& x) const { return _iter != x._iter; } + protected: + Iter _iter; + }; + + template + class matrix_incidence_iterator + : public std::iterator + { + typedef matrix_incidence_iterator self; + public: + matrix_incidence_iterator() { } + matrix_incidence_iterator(Iter i) : _iter(i) { } + matrix_incidence_iterator(const self& x) : _iter(x._iter) { } + self& operator=(const self& x) { _iter = x._iter; return *this; } + Iter operator*() { return _iter; } + self& operator++() { ++_iter; return *this; } + self operator++(int) { self t = *this; ++_iter; return t; } + bool operator==(const self& x) const { return _iter == x._iter; } + bool operator!=(const self& x) const { return _iter != x._iter; } + protected: + Iter _iter; + }; + +} /* namespace boost */ + +#endif /* BOOST_GRAPH_MATRIX2GRAPH_HPP*/ diff --git a/thirdparty/boost/graph/max_cardinality_matching.hpp b/thirdparty/boost/graph/max_cardinality_matching.hpp new file mode 100644 index 0000000..2405d59 --- /dev/null +++ b/thirdparty/boost/graph/max_cardinality_matching.hpp @@ -0,0 +1,883 @@ +//======================================================================= +// Copyright (c) 2005 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +//======================================================================= + +#ifndef BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP +#define BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP + +#include +#include +#include +#include // for std::sort and std::stable_sort +#include // for std::pair +#include +#include // for boost::tie +#include +#include +#include +#include +#include +#include + + +namespace boost +{ + namespace graph { namespace detail { + enum { V_EVEN, V_ODD, V_UNREACHED }; + } } // end namespace graph::detail + + template + typename graph_traits::vertices_size_type + matching_size(const Graph& g, MateMap mate, VertexIndexMap vm) + { + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::vertex_descriptor + vertex_descriptor_t; + typedef typename graph_traits::vertices_size_type v_size_t; + + v_size_t size_of_matching = 0; + vertex_iterator_t vi, vi_end; + + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_descriptor_t v = *vi; + if (get(mate,v) != graph_traits::null_vertex() + && get(vm,v) < get(vm,get(mate,v))) + ++size_of_matching; + } + return size_of_matching; + } + + + + + template + inline typename graph_traits::vertices_size_type + matching_size(const Graph& g, MateMap mate) + { + return matching_size(g, mate, get(vertex_index,g)); + } + + + + + template + bool is_a_matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { + typedef typename graph_traits::vertex_descriptor + vertex_descriptor_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + + vertex_iterator_t vi, vi_end; + for( tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_descriptor_t v = *vi; + if (get(mate,v) != graph_traits::null_vertex() + && v != get(mate,get(mate,v))) + return false; + } + return true; + } + + + + + template + inline bool is_a_matching(const Graph& g, MateMap mate) + { + return is_a_matching(g, mate, get(vertex_index,g)); + } + + + + + //*************************************************************************** + //*************************************************************************** + // Maximum Cardinality Matching Functors + //*************************************************************************** + //*************************************************************************** + + template + struct no_augmenting_path_finder + { + no_augmenting_path_finder(const Graph& g, MateMap mate, VertexIndexMap vm) + { } + + inline bool augment_matching() { return false; } + + template + void get_current_matching(PropertyMap p) {} + }; + + + + + template + class edmonds_augmenting_path_finder + { + // This implementation of Edmonds' matching algorithm closely + // follows Tarjan's description of the algorithm in "Data + // Structures and Network Algorithms." + + public: + + //generates the type of an iterator property map from vertices to type X + template + struct map_vertex_to_ + { + typedef boost::iterator_property_map::iterator, + VertexIndexMap> type; + }; + + typedef typename graph_traits::vertex_descriptor + vertex_descriptor_t; + typedef typename std::pair< vertex_descriptor_t, vertex_descriptor_t > + vertex_pair_t; + typedef typename graph_traits::edge_descriptor edge_descriptor_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename graph_traits::edges_size_type e_size_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::out_edge_iterator + out_edge_iterator_t; + typedef typename std::deque vertex_list_t; + typedef typename std::vector edge_list_t; + typedef typename map_vertex_to_::type + vertex_to_vertex_map_t; + typedef typename map_vertex_to_::type vertex_to_int_map_t; + typedef typename map_vertex_to_::type + vertex_to_vertex_pair_map_t; + typedef typename map_vertex_to_::type vertex_to_vsize_map_t; + typedef typename map_vertex_to_::type vertex_to_esize_map_t; + + + + + edmonds_augmenting_path_finder(const Graph& arg_g, MateMap arg_mate, + VertexIndexMap arg_vm) : + g(arg_g), + vm(arg_vm), + n_vertices(num_vertices(arg_g)), + + mate_vector(n_vertices), + ancestor_of_v_vector(n_vertices), + ancestor_of_w_vector(n_vertices), + vertex_state_vector(n_vertices), + origin_vector(n_vertices), + pred_vector(n_vertices), + bridge_vector(n_vertices), + ds_parent_vector(n_vertices), + ds_rank_vector(n_vertices), + + mate(mate_vector.begin(), vm), + ancestor_of_v(ancestor_of_v_vector.begin(), vm), + ancestor_of_w(ancestor_of_w_vector.begin(), vm), + vertex_state(vertex_state_vector.begin(), vm), + origin(origin_vector.begin(), vm), + pred(pred_vector.begin(), vm), + bridge(bridge_vector.begin(), vm), + ds_parent_map(ds_parent_vector.begin(), vm), + ds_rank_map(ds_rank_vector.begin(), vm), + + ds(ds_rank_map, ds_parent_map) + { + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + mate[*vi] = get(arg_mate, *vi); + } + + + + + bool augment_matching() + { + //As an optimization, some of these values can be saved from one + //iteration to the next instead of being re-initialized each + //iteration, allowing for "lazy blossom expansion." This is not + //currently implemented. + + e_size_t timestamp = 0; + even_edges.clear(); + + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_descriptor_t u = *vi; + + origin[u] = u; + pred[u] = u; + ancestor_of_v[u] = 0; + ancestor_of_w[u] = 0; + ds.make_set(u); + + if (mate[u] == graph_traits::null_vertex()) + { + vertex_state[u] = graph::detail::V_EVEN; + out_edge_iterator_t ei, ei_end; + for(tie(ei,ei_end) = out_edges(u,g); ei != ei_end; ++ei) + even_edges.push_back( *ei ); + } + else + vertex_state[u] = graph::detail::V_UNREACHED; + } + + //end initializations + + vertex_descriptor_t v,w,w_free_ancestor,v_free_ancestor; + w_free_ancestor = graph_traits::null_vertex(); + v_free_ancestor = graph_traits::null_vertex(); + bool found_alternating_path = false; + + while(!even_edges.empty() && !found_alternating_path) + { + // since we push even edges onto the back of the list as + // they're discovered, taking them off the back will search + // for augmenting paths depth-first. + edge_descriptor_t current_edge = even_edges.back(); + even_edges.pop_back(); + + v = source(current_edge,g); + w = target(current_edge,g); + + vertex_descriptor_t v_prime = origin[ds.find_set(v)]; + vertex_descriptor_t w_prime = origin[ds.find_set(w)]; + + // because of the way we put all of the edges on the queue, + // v_prime should be labeled V_EVEN; the following is a + // little paranoid but it could happen... + if (vertex_state[v_prime] != graph::detail::V_EVEN) + { + std::swap(v_prime,w_prime); + std::swap(v,w); + } + + if (vertex_state[w_prime] == graph::detail::V_UNREACHED) + { + vertex_state[w_prime] = graph::detail::V_ODD; + vertex_state[mate[w_prime]] = graph::detail::V_EVEN; + out_edge_iterator_t ei, ei_end; + for( tie(ei,ei_end) = out_edges(mate[w_prime], g); ei != ei_end; ++ei) + even_edges.push_back(*ei); + pred[w_prime] = v; + } + + //w_prime == v_prime can happen below if we get an edge that has been + //shrunk into a blossom + else if (vertex_state[w_prime] == graph::detail::V_EVEN && w_prime != v_prime) + { + vertex_descriptor_t w_up = w_prime; + vertex_descriptor_t v_up = v_prime; + vertex_descriptor_t nearest_common_ancestor + = graph_traits::null_vertex(); + w_free_ancestor = graph_traits::null_vertex(); + v_free_ancestor = graph_traits::null_vertex(); + + // We now need to distinguish between the case that + // w_prime and v_prime share an ancestor under the + // "parent" relation, in which case we've found a + // blossom and should shrink it, or the case that + // w_prime and v_prime both have distinct ancestors that + // are free, in which case we've found an alternating + // path between those two ancestors. + + ++timestamp; + + while (nearest_common_ancestor == graph_traits::null_vertex() && + (v_free_ancestor == graph_traits::null_vertex() || + w_free_ancestor == graph_traits::null_vertex() + ) + ) + { + ancestor_of_w[w_up] = timestamp; + ancestor_of_v[v_up] = timestamp; + + if (w_free_ancestor == graph_traits::null_vertex()) + w_up = parent(w_up); + if (v_free_ancestor == graph_traits::null_vertex()) + v_up = parent(v_up); + + if (mate[v_up] == graph_traits::null_vertex()) + v_free_ancestor = v_up; + if (mate[w_up] == graph_traits::null_vertex()) + w_free_ancestor = w_up; + + if (ancestor_of_w[v_up] == timestamp) + nearest_common_ancestor = v_up; + else if (ancestor_of_v[w_up] == timestamp) + nearest_common_ancestor = w_up; + else if (v_free_ancestor == w_free_ancestor && + v_free_ancestor != graph_traits::null_vertex()) + nearest_common_ancestor = v_up; + } + + if (nearest_common_ancestor == graph_traits::null_vertex()) + found_alternating_path = true; //to break out of the loop + else + { + //shrink the blossom + link_and_set_bridges(w_prime, nearest_common_ancestor, std::make_pair(w,v)); + link_and_set_bridges(v_prime, nearest_common_ancestor, std::make_pair(v,w)); + } + } + } + + if (!found_alternating_path) + return false; + + // retrieve the augmenting path and put it in aug_path + reversed_retrieve_augmenting_path(v, v_free_ancestor); + retrieve_augmenting_path(w, w_free_ancestor); + + // augment the matching along aug_path + vertex_descriptor_t a,b; + while (!aug_path.empty()) + { + a = aug_path.front(); + aug_path.pop_front(); + b = aug_path.front(); + aug_path.pop_front(); + mate[a] = b; + mate[b] = a; + } + + return true; + + } + + + + + template + void get_current_matching(PropertyMap pm) + { + vertex_iterator_t vi,vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(pm, *vi, mate[*vi]); + } + + + + + template + void get_vertex_state_map(PropertyMap pm) + { + vertex_iterator_t vi,vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(pm, *vi, vertex_state[origin[ds.find_set(*vi)]]); + } + + + + + private: + + vertex_descriptor_t parent(vertex_descriptor_t x) + { + if (vertex_state[x] == graph::detail::V_EVEN + && mate[x] != graph_traits::null_vertex()) + return mate[x]; + else if (vertex_state[x] == graph::detail::V_ODD) + return origin[ds.find_set(pred[x])]; + else + return x; + } + + + + + void link_and_set_bridges(vertex_descriptor_t x, + vertex_descriptor_t stop_vertex, + vertex_pair_t the_bridge) + { + for(vertex_descriptor_t v = x; v != stop_vertex; v = parent(v)) + { + ds.union_set(v, stop_vertex); + origin[ds.find_set(stop_vertex)] = stop_vertex; + + if (vertex_state[v] == graph::detail::V_ODD) + { + bridge[v] = the_bridge; + out_edge_iterator_t oei, oei_end; + for(tie(oei, oei_end) = out_edges(v,g); oei != oei_end; ++oei) + even_edges.push_back(*oei); + } + } + } + + + // Since none of the STL containers support both constant-time + // concatenation and reversal, the process of expanding an + // augmenting path once we know one exists is a little more + // complicated than it has to be. If we know the path is from v to + // w, then the augmenting path is recursively defined as: + // + // path(v,w) = [v], if v = w + // = concat([v, mate[v]], path(pred[mate[v]], w), + // if v != w and vertex_state[v] == graph::detail::V_EVEN + // = concat([v], reverse(path(x,mate[v])), path(y,w)), + // if v != w, vertex_state[v] == graph::detail::V_ODD, and bridge[v] = (x,y) + // + // These next two mutually recursive functions implement this definition. + + void retrieve_augmenting_path(vertex_descriptor_t v, vertex_descriptor_t w) + { + if (v == w) + aug_path.push_back(v); + else if (vertex_state[v] == graph::detail::V_EVEN) + { + aug_path.push_back(v); + aug_path.push_back(mate[v]); + retrieve_augmenting_path(pred[mate[v]], w); + } + else //vertex_state[v] == graph::detail::V_ODD + { + aug_path.push_back(v); + reversed_retrieve_augmenting_path(bridge[v].first, mate[v]); + retrieve_augmenting_path(bridge[v].second, w); + } + } + + + void reversed_retrieve_augmenting_path(vertex_descriptor_t v, + vertex_descriptor_t w) + { + + if (v == w) + aug_path.push_back(v); + else if (vertex_state[v] == graph::detail::V_EVEN) + { + reversed_retrieve_augmenting_path(pred[mate[v]], w); + aug_path.push_back(mate[v]); + aug_path.push_back(v); + } + else //vertex_state[v] == graph::detail::V_ODD + { + reversed_retrieve_augmenting_path(bridge[v].second, w); + retrieve_augmenting_path(bridge[v].first, mate[v]); + aug_path.push_back(v); + } + } + + + + + //private data members + + const Graph& g; + VertexIndexMap vm; + v_size_t n_vertices; + + //storage for the property maps below + std::vector mate_vector; + std::vector ancestor_of_v_vector; + std::vector ancestor_of_w_vector; + std::vector vertex_state_vector; + std::vector origin_vector; + std::vector pred_vector; + std::vector bridge_vector; + std::vector ds_parent_vector; + std::vector ds_rank_vector; + + //iterator property maps + vertex_to_vertex_map_t mate; + vertex_to_esize_map_t ancestor_of_v; + vertex_to_esize_map_t ancestor_of_w; + vertex_to_int_map_t vertex_state; + vertex_to_vertex_map_t origin; + vertex_to_vertex_map_t pred; + vertex_to_vertex_pair_map_t bridge; + vertex_to_vertex_map_t ds_parent_map; + vertex_to_vsize_map_t ds_rank_map; + + vertex_list_t aug_path; + edge_list_t even_edges; + disjoint_sets< vertex_to_vsize_map_t, vertex_to_vertex_map_t > ds; + + }; + + + + + //*************************************************************************** + //*************************************************************************** + // Initial Matching Functors + //*************************************************************************** + //*************************************************************************** + + template + struct greedy_matching + { + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; + + static void find_matching(const Graph& g, MateMap mate) + { + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(mate, *vi, graph_traits::null_vertex()); + + edge_iterator_t ei, ei_end; + for( tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_descriptor_t e = *ei; + vertex_descriptor_t u = source(e,g); + vertex_descriptor_t v = target(e,g); + + if (get(mate,u) == get(mate,v)) + //only way equality can hold is if + // mate[u] == mate[v] == null_vertex + { + put(mate,u,v); + put(mate,v,u); + } + } + } + }; + + + + + template + struct extra_greedy_matching + { + // The "extra greedy matching" is formed by repeating the + // following procedure as many times as possible: Choose the + // unmatched vertex v of minimum non-zero degree. Choose the + // neighbor w of v which is unmatched and has minimum degree over + // all of v's neighbors. Add (u,v) to the matching. Ties for + // either choice are broken arbitrarily. This procedure takes time + // O(m log n), where m is the number of edges in the graph and n + // is the number of vertices. + + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor_t; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; + typedef std::pair vertex_pair_t; + + struct select_first + { + inline static vertex_descriptor_t select_vertex(const vertex_pair_t p) + {return p.first;} + }; + + struct select_second + { + inline static vertex_descriptor_t select_vertex(const vertex_pair_t p) + {return p.second;} + }; + + template + class less_than_by_degree + { + public: + less_than_by_degree(const Graph& g): m_g(g) {} + bool operator() (const vertex_pair_t x, const vertex_pair_t y) + { + return + out_degree(PairSelector::select_vertex(x), m_g) + < out_degree(PairSelector::select_vertex(y), m_g); + } + private: + const Graph& m_g; + }; + + + static void find_matching(const Graph& g, MateMap mate) + { + typedef std::vector > + directed_edges_vector_t; + + directed_edges_vector_t edge_list; + vertex_iterator_t vi, vi_end; + for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + put(mate, *vi, graph_traits::null_vertex()); + + edge_iterator_t ei, ei_end; + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_descriptor_t e = *ei; + vertex_descriptor_t u = source(e,g); + vertex_descriptor_t v = target(e,g); + edge_list.push_back(std::make_pair(u,v)); + edge_list.push_back(std::make_pair(v,u)); + } + + //sort the edges by the degree of the target, then (using a + //stable sort) by degree of the source + std::sort(edge_list.begin(), edge_list.end(), + less_than_by_degree(g)); + std::stable_sort(edge_list.begin(), edge_list.end(), + less_than_by_degree(g)); + + //construct the extra greedy matching + for(typename directed_edges_vector_t::const_iterator itr = edge_list.begin(); itr != edge_list.end(); ++itr) + { + if (get(mate,itr->first) == get(mate,itr->second)) + //only way equality can hold is if mate[itr->first] == mate[itr->second] == null_vertex + { + put(mate, itr->first, itr->second); + put(mate, itr->second, itr->first); + } + } + } + }; + + + + + template + struct empty_matching + { + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; + + static void find_matching(const Graph& g, MateMap mate) + { + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(mate, *vi, graph_traits::null_vertex()); + } + }; + + + + + //*************************************************************************** + //*************************************************************************** + // Matching Verifiers + //*************************************************************************** + //*************************************************************************** + + namespace detail + { + + template + class odd_components_counter : public dfs_visitor<> + // This depth-first search visitor will count the number of connected + // components with an odd number of vertices. It's used by + // maximum_matching_verifier. + { + public: + odd_components_counter(SizeType& c_count): + m_count(c_count) + { + m_count = 0; + } + + template + void start_vertex(Vertex v, Graph&) + { + m_parity = false; + } + + template + void discover_vertex(Vertex u, Graph&) + { + m_parity = !m_parity; + m_parity ? ++m_count : --m_count; + } + + protected: + SizeType& m_count; + + private: + bool m_parity; + + }; + + }//namespace detail + + + + + template + struct no_matching_verifier + { + inline static bool + verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { return true;} + }; + + + + + template + struct maximum_cardinality_matching_verifier + { + + template + struct map_vertex_to_ + { + typedef boost::iterator_property_map::iterator, + VertexIndexMap> type; + }; + + typedef typename graph_traits::vertex_descriptor + vertex_descriptor_t; + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename map_vertex_to_::type vertex_to_int_map_t; + typedef typename map_vertex_to_::type + vertex_to_vertex_map_t; + + + template + struct non_odd_vertex { + //this predicate is used to create a filtered graph that + //excludes vertices labeled "graph::detail::V_ODD" + non_odd_vertex() : vertex_state(0) { } + + non_odd_vertex(VertexStateMap* arg_vertex_state) + : vertex_state(arg_vertex_state) { } + + template + bool operator()(const Vertex& v) const + { + BOOST_ASSERT(vertex_state); + return get(*vertex_state, v) != graph::detail::V_ODD; + } + + VertexStateMap* vertex_state; + }; + + + static bool verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { + //For any graph G, let o(G) be the number of connected + //components in G of odd size. For a subset S of G's vertex set + //V(G), let (G - S) represent the subgraph of G induced by + //removing all vertices in S from G. Let M(G) be the size of the + //maximum cardinality matching in G. Then the Tutte-Berge + //formula guarantees that + // + // 2 * M(G) = min ( |V(G)| + |U| + o(G - U) ) + // + //where the minimum is taken over all subsets U of + //V(G). Edmonds' algorithm finds a set U that achieves the + //minimum in the above formula, namely the vertices labeled + //"ODD." This function runs one iteration of Edmonds' algorithm + //to find U, then verifies that the size of the matching given + //by mate satisfies the Tutte-Berge formula. + + //first, make sure it's a valid matching + if (!is_a_matching(g,mate,vm)) + return false; + + //We'll try to augment the matching once. This serves two + //purposes: first, if we find some augmenting path, the matching + //is obviously non-maximum. Second, running edmonds' algorithm + //on a graph with no augmenting path will create the + //Edmonds-Gallai decomposition that we need as a certificate of + //maximality - we can get it by looking at the vertex_state map + //that results. + edmonds_augmenting_path_finder + augmentor(g,mate,vm); + if (augmentor.augment_matching()) + return false; + + std::vector vertex_state_vector(num_vertices(g)); + vertex_to_int_map_t vertex_state(vertex_state_vector.begin(), vm); + augmentor.get_vertex_state_map(vertex_state); + + //count the number of graph::detail::V_ODD vertices + v_size_t num_odd_vertices = 0; + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + if (vertex_state[*vi] == graph::detail::V_ODD) + ++num_odd_vertices; + + //count the number of connected components with odd cardinality + //in the graph without graph::detail::V_ODD vertices + non_odd_vertex filter(&vertex_state); + filtered_graph > fg(g, keep_all(), filter); + + v_size_t num_odd_components; + detail::odd_components_counter occ(num_odd_components); + depth_first_search(fg, visitor(occ).vertex_index_map(vm)); + + if (2 * matching_size(g,mate,vm) == num_vertices(g) + num_odd_vertices - num_odd_components) + return true; + else + return false; + } + }; + + + + + template class AugmentingPathFinder, + template class InitialMatchingFinder, + template class MatchingVerifier> + bool matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { + + InitialMatchingFinder::find_matching(g,mate); + + AugmentingPathFinder augmentor(g,mate,vm); + bool not_maximum_yet = true; + while(not_maximum_yet) + { + not_maximum_yet = augmentor.augment_matching(); + } + augmentor.get_current_matching(mate); + + return MatchingVerifier::verify_matching(g,mate,vm); + + } + + + + + template + inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { + return matching + < Graph, MateMap, VertexIndexMap, + edmonds_augmenting_path_finder, extra_greedy_matching, maximum_cardinality_matching_verifier> + (g, mate, vm); + } + + + + + template + inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate) + { + return checked_edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g)); + } + + + + + template + inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm) + { + matching < Graph, MateMap, VertexIndexMap, + edmonds_augmenting_path_finder, extra_greedy_matching, no_matching_verifier> + (g, mate, vm); + } + + + + + template + inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate) + { + edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g)); + } + +}//namespace boost + +#endif //BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP diff --git a/thirdparty/boost/graph/minimum_degree_ordering.hpp b/thirdparty/boost/graph/minimum_degree_ordering.hpp new file mode 100644 index 0000000..b6d791a --- /dev/null +++ b/thirdparty/boost/graph/minimum_degree_ordering.hpp @@ -0,0 +1,655 @@ +//-*-c++-*- +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Lie-Quan Lee, Jeremy Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef MINIMUM_DEGREE_ORDERING_HPP +#define MINIMUM_DEGREE_ORDERING_HPP + +#include +#include +#include +#include +#include // for integer_traits +#include +#include + +namespace boost { + + namespace detail { + + // + // Given a set of n integers (where the integer values range from + // zero to n-1), we want to keep track of a collection of stacks + // of integers. It so happens that an integer will appear in at + // most one stack at a time, so the stacks form disjoint sets. + // Because of these restrictions, we can use one big array to + // store all the stacks, intertwined with one another. + // No allocation/deallocation happens in the push()/pop() methods + // so this is faster than using std::stack's. + // + template + class Stacks { + typedef SignedInteger value_type; + typedef typename std::vector::size_type size_type; + public: + Stacks(size_type n) : data(n) {} + + //: stack + class stack { + typedef typename std::vector::iterator Iterator; + public: + stack(Iterator _data, const value_type& head) + : data(_data), current(head) {} + + // did not use default argument here to avoid internal compiler error + // in g++. + stack(Iterator _data) + : data(_data), current(-(std::numeric_limits::max)()) {} + + void pop() { + assert(! empty()); + current = data[current]; + } + void push(value_type v) { + data[v] = current; + current = v; + } + bool empty() { + return current == -(std::numeric_limits::max)(); + } + value_type& top() { return current; } + private: + Iterator data; + value_type current; + }; + + // To return a stack object + stack make_stack() + { return stack(data.begin()); } + protected: + std::vector data; + }; + + + // marker class, a generalization of coloring. + // + // This class is to provide a generalization of coloring which has + // complexity of amortized constant time to set all vertices' color + // back to be untagged. It implemented by increasing a tag. + // + // The colors are: + // not tagged + // tagged + // multiple_tagged + // done + // + template + class Marker { + typedef SignedInteger value_type; + typedef typename std::vector::size_type size_type; + + static value_type done() + { return (std::numeric_limits::max)()/2; } + public: + Marker(size_type _num, VertexIndexMap index_map) + : tag(1 - (std::numeric_limits::max)()), + data(_num, - (std::numeric_limits::max)()), + id(index_map) {} + + void mark_done(Vertex node) { data[get(id, node)] = done(); } + + bool is_done(Vertex node) { return data[get(id, node)] == done(); } + + void mark_tagged(Vertex node) { data[get(id, node)] = tag; } + + void mark_multiple_tagged(Vertex node) { data[get(id, node)] = multiple_tag; } + + bool is_tagged(Vertex node) const { return data[get(id, node)] >= tag; } + + bool is_not_tagged(Vertex node) const { return data[get(id, node)] < tag; } + + bool is_multiple_tagged(Vertex node) const + { return data[get(id, node)] >= multiple_tag; } + + void increment_tag() { + const size_type num = data.size(); + ++tag; + if ( tag >= done() ) { + tag = 1 - (std::numeric_limits::max)(); + for (size_type i = 0; i < num; ++i) + if ( data[i] < done() ) + data[i] = - (std::numeric_limits::max)(); + } + } + + void set_multiple_tag(value_type mdeg0) + { + const size_type num = data.size(); + multiple_tag = tag + mdeg0; + + if ( multiple_tag >= done() ) { + tag = 1-(std::numeric_limits::max)(); + + for (size_type i=0; i::max)(); + + multiple_tag = tag + mdeg0; + } + } + + void set_tag_as_multiple_tag() { tag = multiple_tag; } + + protected: + value_type tag; + value_type multiple_tag; + std::vector data; + VertexIndexMap id; + }; + + template< class Iterator, class SignedInteger, + class Vertex, class VertexIndexMap, int offset = 1 > + class Numbering { + typedef SignedInteger number_type; + number_type num; //start from 1 instead of zero + Iterator data; + number_type max_num; + VertexIndexMap id; + public: + Numbering(Iterator _data, number_type _max_num, VertexIndexMap id) + : num(1), data(_data), max_num(_max_num), id(id) {} + void operator()(Vertex node) { data[get(id, node)] = -num; } + bool all_done(number_type i = 0) const { return num + i > max_num; } + void increment(number_type i = 1) { num += i; } + bool is_numbered(Vertex node) const { + return data[get(id, node)] < 0; + } + void indistinguishable(Vertex i, Vertex j) { + data[get(id, i)] = - (get(id, j) + offset); + } + }; + + template + class degreelists_marker { + public: + typedef SignedInteger value_type; + typedef typename std::vector::size_type size_type; + degreelists_marker(size_type n, VertexIndexMap id) + : marks(n, 0), id(id) {} + void mark_need_update(Vertex i) { marks[get(id, i)] = 1; } + bool need_update(Vertex i) { return marks[get(id, i)] == 1; } + bool outmatched_or_done (Vertex i) { return marks[get(id, i)] == -1; } + void mark(Vertex i) { marks[get(id, i)] = -1; } + void unmark(Vertex i) { marks[get(id, i)] = 0; } + private: + std::vector marks; + VertexIndexMap id; + }; + + // Helper function object for edge removal + template + class predicateRemoveEdge1 { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + public: + predicateRemoveEdge1(Graph& _g, MarkerP& _marker, + NumberD _numbering, Stack& n_e, VertexIndexMap id) + : g(&_g), marker(&_marker), numbering(_numbering), + neighbor_elements(&n_e), id(id) {} + + bool operator()(edge_t e) { + vertex_t dist = target(e, *g); + if ( marker->is_tagged(dist) ) + return true; + marker->mark_tagged(dist); + if (numbering.is_numbered(dist)) { + neighbor_elements->push(get(id, dist)); + return true; + } + return false; + } + private: + Graph* g; + MarkerP* marker; + NumberD numbering; + Stack* neighbor_elements; + VertexIndexMap id; + }; + + // Helper function object for edge removal + template + class predicate_remove_tagged_edges + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + public: + predicate_remove_tagged_edges(Graph& _g, MarkerP& _marker) + : g(&_g), marker(&_marker) {} + + bool operator()(edge_t e) { + vertex_t dist = target(e, *g); + if ( marker->is_tagged(dist) ) + return true; + return false; + } + private: + Graph* g; + MarkerP* marker; + }; + + template + class mmd_impl + { + // Typedefs + typedef graph_traits Traits; + typedef typename Traits::vertices_size_type size_type; + typedef typename detail::integer_traits::difference_type + diff_t; + typedef typename Traits::vertex_descriptor vertex_t; + typedef typename Traits::adjacency_iterator adj_iter; + typedef iterator_property_map IndexVertexMap; + typedef detail::Stacks Workspace; + typedef bucket_sorter + DegreeLists; + typedef Numbering + NumberingD; + typedef degreelists_marker + DegreeListsMarker; + typedef Marker MarkerP; + + // Data Members + + // input parameters + Graph& G; + int delta; + DegreeMap degree; + InversePermutationMap inverse_perm; + PermutationMap perm; + SuperNodeMap supernode_size; + VertexIndexMap vertex_index_map; + + // internal data-structures + std::vector index_vertex_vec; + size_type n; + IndexVertexMap index_vertex_map; + DegreeLists degreelists; + NumberingD numbering; + DegreeListsMarker degree_lists_marker; + MarkerP marker; + Workspace work_space; + public: + mmd_impl(Graph& g, size_type n_, int delta, DegreeMap degree, + InversePermutationMap inverse_perm, + PermutationMap perm, + SuperNodeMap supernode_size, + VertexIndexMap id) + : G(g), delta(delta), degree(degree), + inverse_perm(inverse_perm), + perm(perm), + supernode_size(supernode_size), + vertex_index_map(id), + index_vertex_vec(n_), + n(n_), + degreelists(n_ + 1, n_, degree, id), + numbering(inverse_perm, n_, vertex_index_map), + degree_lists_marker(n_, vertex_index_map), + marker(n_, vertex_index_map), + work_space(n_) + { + typename graph_traits::vertex_iterator v, vend; + size_type vid = 0; + for (tie(v, vend) = vertices(G); v != vend; ++v, ++vid) + index_vertex_vec[vid] = *v; + index_vertex_map = IndexVertexMap(&index_vertex_vec[0]); + + // Initialize degreelists. Degreelists organizes the nodes + // according to their degree. + for (tie(v, vend) = vertices(G); v != vend; ++v) { + put(degree, *v, out_degree(*v, G)); + degreelists.push(*v); + } + } + + void do_mmd() + { + // Eliminate the isolated nodes -- these are simply the nodes + // with no neighbors, which are accessible as a list (really, a + // stack) at location 0. Since these don't affect any other + // nodes, we can eliminate them without doing degree updates. + typename DegreeLists::stack list_isolated = degreelists[0]; + while (!list_isolated.empty()) { + vertex_t node = list_isolated.top(); + marker.mark_done(node); + numbering(node); + numbering.increment(); + list_isolated.pop(); + } + size_type min_degree = 1; + typename DegreeLists::stack list_min_degree = degreelists[min_degree]; + + while (list_min_degree.empty()) { + ++min_degree; + list_min_degree = degreelists[min_degree]; + } + + // check if the whole eliminating process is done + while (!numbering.all_done()) { + + size_type min_degree_limit = min_degree + delta; // WARNING + typename Workspace::stack llist = work_space.make_stack(); + + // multiple elimination + while (delta >= 0) { + + // Find the next non-empty degree + for (list_min_degree = degreelists[min_degree]; + list_min_degree.empty() && min_degree <= min_degree_limit; + ++min_degree, list_min_degree = degreelists[min_degree]) + ; + if (min_degree > min_degree_limit) + break; + + const vertex_t node = list_min_degree.top(); + const size_type node_id = get(vertex_index_map, node); + list_min_degree.pop(); + numbering(node); + + // check if node is the last one + if (numbering.all_done(supernode_size[node])) { + numbering.increment(supernode_size[node]); + break; + } + marker.increment_tag(); + marker.mark_tagged(node); + + this->eliminate(node); + + numbering.increment(supernode_size[node]); + llist.push(node_id); + } // multiple elimination + + if (numbering.all_done()) + break; + + this->update( llist, min_degree); + } + + } // do_mmd() + + void eliminate(vertex_t node) + { + typename Workspace::stack element_neighbor = work_space.make_stack(); + + // Create two function objects for edge removal + typedef typename Workspace::stack WorkStack; + predicateRemoveEdge1 + p(G, marker, numbering, element_neighbor, vertex_index_map); + + predicate_remove_tagged_edges p2(G, marker); + + // Reconstruct the adjacent node list, push element neighbor in a List. + remove_out_edge_if(node, p, G); + //during removal element neighbors are collected. + + while (!element_neighbor.empty()) { + // element absorb + size_type e_id = element_neighbor.top(); + vertex_t element = get(index_vertex_map, e_id); + adj_iter i, i_end; + for (tie(i, i_end) = adjacent_vertices(element, G); i != i_end; ++i){ + vertex_t i_node = *i; + if (!marker.is_tagged(i_node) && !numbering.is_numbered(i_node)) { + marker.mark_tagged(i_node); + add_edge(node, i_node, G); + } + } + element_neighbor.pop(); + } + adj_iter v, ve; + for (tie(v, ve) = adjacent_vertices(node, G); v != ve; ++v) { + vertex_t v_node = *v; + if (!degree_lists_marker.need_update(v_node) + && !degree_lists_marker.outmatched_or_done(v_node)) { + degreelists.remove(v_node); + } + //update out edges of v_node + remove_out_edge_if(v_node, p2, G); + + if ( out_degree(v_node, G) == 0 ) { // indistinguishable nodes + supernode_size[node] += supernode_size[v_node]; + supernode_size[v_node] = 0; + numbering.indistinguishable(v_node, node); + marker.mark_done(v_node); + degree_lists_marker.mark(v_node); + } else { // not indistinguishable nodes + add_edge(v_node, node, G); + degree_lists_marker.mark_need_update(v_node); + } + } + } // eliminate() + + + template + void update(Stack llist, size_type& min_degree) + { + size_type min_degree0 = min_degree + delta + 1; + + while (! llist.empty()) { + size_type deg, deg0 = 0; + + marker.set_multiple_tag(min_degree0); + typename Workspace::stack q2list = work_space.make_stack(); + typename Workspace::stack qxlist = work_space.make_stack(); + + vertex_t current = get(index_vertex_map, llist.top()); + adj_iter i, ie; + for (tie(i,ie) = adjacent_vertices(current, G); i != ie; ++i) { + vertex_t i_node = *i; + const size_type i_id = get(vertex_index_map, i_node); + if (supernode_size[i_node] != 0) { + deg0 += supernode_size[i_node]; + marker.mark_multiple_tagged(i_node); + if (degree_lists_marker.need_update(i_node)) { + if (out_degree(i_node, G) == 2) + q2list.push(i_id); + else + qxlist.push(i_id); + } + } + } + + while (!q2list.empty()) { + const size_type u_id = q2list.top(); + vertex_t u_node = get(index_vertex_map, u_id); + // if u_id is outmatched by others, no need to update degree + if (degree_lists_marker.outmatched_or_done(u_node)) { + q2list.pop(); + continue; + } + marker.increment_tag(); + deg = deg0; + + adj_iter nu = adjacent_vertices(u_node, G).first; + vertex_t neighbor = *nu; + if (neighbor == u_node) { + ++nu; + neighbor = *nu; + } + if (numbering.is_numbered(neighbor)) { + adj_iter i, ie; + for (tie(i,ie) = adjacent_vertices(neighbor, G); + i != ie; ++i) { + const vertex_t i_node = *i; + if (i_node == u_node || supernode_size[i_node] == 0) + continue; + if (marker.is_tagged(i_node)) { + if (degree_lists_marker.need_update(i_node)) { + if ( out_degree(i_node, G) == 2 ) { // is indistinguishable + supernode_size[u_node] += supernode_size[i_node]; + supernode_size[i_node] = 0; + numbering.indistinguishable(i_node, u_node); + marker.mark_done(i_node); + degree_lists_marker.mark(i_node); + } else // is outmatched + degree_lists_marker.mark(i_node); + } + } else { + marker.mark_tagged(i_node); + deg += supernode_size[i_node]; + } + } + } else + deg += supernode_size[neighbor]; + + deg -= supernode_size[u_node]; + degree[u_node] = deg; //update degree + degreelists[deg].push(u_node); + //u_id has been pushed back into degreelists + degree_lists_marker.unmark(u_node); + if (min_degree > deg) + min_degree = deg; + q2list.pop(); + } // while (!q2list.empty()) + + while (!qxlist.empty()) { + const size_type u_id = qxlist.top(); + const vertex_t u_node = get(index_vertex_map, u_id); + + // if u_id is outmatched by others, no need to update degree + if (degree_lists_marker.outmatched_or_done(u_node)) { + qxlist.pop(); + continue; + } + marker.increment_tag(); + deg = deg0; + adj_iter i, ie; + for (tie(i, ie) = adjacent_vertices(u_node, G); i != ie; ++i) { + vertex_t i_node = *i; + if (marker.is_tagged(i_node)) + continue; + marker.mark_tagged(i_node); + + if (numbering.is_numbered(i_node)) { + adj_iter j, je; + for (tie(j, je) = adjacent_vertices(i_node, G); j != je; ++j) { + const vertex_t j_node = *j; + if (marker.is_not_tagged(j_node)) { + marker.mark_tagged(j_node); + deg += supernode_size[j_node]; + } + } + } else + deg += supernode_size[i_node]; + } // for adjacent vertices of u_node + deg -= supernode_size[u_node]; + degree[u_node] = deg; + degreelists[deg].push(u_node); + // u_id has been pushed back into degreelists + degree_lists_marker.unmark(u_node); + if (min_degree > deg) + min_degree = deg; + qxlist.pop(); + } // while (!qxlist.empty()) { + + marker.set_tag_as_multiple_tag(); + llist.pop(); + } // while (! llist.empty()) + + } // update() + + + void build_permutation(InversePermutationMap next, + PermutationMap prev) + { + // collect the permutation info + size_type i; + for (i = 0; i < n; ++i) { + diff_t size = supernode_size[get(index_vertex_map, i)]; + if ( size <= 0 ) { + prev[i] = next[i]; + supernode_size[get(index_vertex_map, i)] + = next[i] + 1; // record the supernode info + } else + prev[i] = - next[i]; + } + for (i = 1; i < n + 1; ++i) { + if ( prev[i-1] > 0 ) + continue; + diff_t parent = i; + while ( prev[parent - 1] < 0 ) { + parent = - prev[parent - 1]; + } + + diff_t root = parent; + diff_t num = prev[root - 1] + 1; + next[i-1] = - num; + prev[root-1] = num; + + parent = i; + diff_t next_node = - prev[parent - 1]; + while (next_node > 0) { + prev[parent-1] = - root; + parent = next_node; + next_node = - prev[parent - 1]; + } + } + for (i = 0; i < n; i++) { + diff_t num = - next[i] - 1; + next[i] = num; + prev[num] = i; + } + } // build_permutation() + }; + + } //namespace detail + + + // MMD algorithm + // + //The implementation presently includes the enhancements for mass + //elimination, incomplete degree update, multiple elimination, and + //external degree. + // + //Important Note: This implementation requires the BGL graph to be + //directed. Therefore, nonzero entry (i, j) in a symmetrical matrix + //A coresponds to two directed edges (i->j and j->i). + // + //see Alan George and Joseph W. H. Liu, The Evolution of the Minimum + //Degree Ordering Algorithm, SIAM Review, 31, 1989, Page 1-19 + template + void minimum_degree_ordering + (Graph& G, + DegreeMap degree, + InversePermutationMap inverse_perm, + PermutationMap perm, + SuperNodeMap supernode_size, + int delta, + VertexIndexMap vertex_index_map) + { + detail::mmd_impl + impl(G, num_vertices(G), delta, degree, inverse_perm, + perm, supernode_size, vertex_index_map); + impl.do_mmd(); + impl.build_permutation(inverse_perm, perm); + } + +} // namespace boost + +#endif // MINIMUM_DEGREE_ORDERING_HPP diff --git a/thirdparty/boost/graph/named_function_params.hpp b/thirdparty/boost/graph/named_function_params.hpp new file mode 100644 index 0000000..6660b40 --- /dev/null +++ b/thirdparty/boost/graph/named_function_params.hpp @@ -0,0 +1,795 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP +#define BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP + +#include + +namespace boost { + + struct distance_compare_t { }; + struct distance_combine_t { }; + struct distance_inf_t { }; + struct distance_zero_t { }; + struct buffer_param_t { }; + struct edge_copy_t { }; + struct vertex_copy_t { }; + struct vertex_isomorphism_t { }; + struct vertex_invariant_t { }; + struct vertex_invariant1_t { }; + struct vertex_invariant2_t { }; + struct edge_compare_t { }; + struct vertex_max_invariant_t { }; + struct orig_to_copy_t { }; + struct root_vertex_t { }; + struct attractive_force_t { }; + struct repulsive_force_t { }; + struct force_pairs_t { }; + struct cooling_t { }; + struct vertex_displacement_t { }; + struct iterations_t { }; + struct diameter_range_t { }; + struct learning_constant_range_t { }; + + namespace detail { + template + struct wrap_ref { + wrap_ref(T& r) : ref(r) {} + T& ref; + }; + } + + template + struct bgl_named_params : public Base + { + typedef bgl_named_params self; + typedef Base next_type; + typedef Tag tag_type; + typedef T value_type; + bgl_named_params(T v) : m_value(v) { } + bgl_named_params(T v, const Base& b) : Base(b), m_value(v) { } + T m_value; + + template + bgl_named_params + weight_map(const WeightMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + weight_map2(const WeightMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + distance_map(const DistanceMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + predecessor_map(const PredecessorMap& pmap) const { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + rank_map(const RankMap& pmap) const { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + root_map(const RootMap& pmap) const { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + root_vertex(const Vertex& r) const { + typedef bgl_named_params Params; + return Params(r, *this); + } + + template + bgl_named_params + edge_centrality_map(const EdgeCentralityMap& r) const { + typedef bgl_named_params Params; + return Params(r, *this); + } + + template + bgl_named_params + centrality_map(const CentralityMap& r) const { + typedef bgl_named_params Params; + return Params(r, *this); + } + + template + bgl_named_params + color_map(const ColorMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + vertex_color_map(const ColorMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + edge_color_map(const ColorMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + capacity_map(CapacityMap pmap) { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + residual_capacity_map(Residual_CapacityMap pmap) { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + reverse_edge_map(ReverseMap pmap) { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + discover_time_map(const DiscoverTimeMap& pmap) const { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + lowpoint_map(const LowPointMap& pmap) const { + typedef bgl_named_params + Params; + return Params(pmap, *this); + } + + template + bgl_named_params + vertex_index_map(const IndexMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + vertex_index1_map(const IndexMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + vertex_index2_map(const IndexMap& pmap) const { + typedef bgl_named_params Params; + return Params(pmap, *this); + } + + template + bgl_named_params + visitor(const Visitor& vis) const { + typedef bgl_named_params Params; + return Params(vis, *this); + } + + template + bgl_named_params + distance_compare(Compare cmp) const { + typedef bgl_named_params Params; + return Params(cmp, *this); + } + + template + bgl_named_params + distance_combine(Combine cmb) const { + typedef bgl_named_params Params; + return Params(cmb, *this); + } + + template + bgl_named_params + distance_inf(Init init) const { + typedef bgl_named_params Params; + return Params(init, *this); + } + + template + bgl_named_params + distance_zero(Init init) const { + typedef bgl_named_params Params; + return Params(init, *this); + } + + template + bgl_named_params, buffer_param_t, self> + buffer(Buffer& b) const { + typedef bgl_named_params, buffer_param_t, self> + Params; + return Params(detail::wrap_ref(b), *this); + } + + template + bgl_named_params + edge_copy(const Copier& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + vertex_copy(const Copier& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + orig_to_copy(const Orig2CopyMap& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + isomorphism_map(const IsoMap& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + vertex_invariant(const VertexInvar& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + vertex_invariant1(const VertexInvar& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + vertex_invariant2(const VertexInvar& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + vertex_max_invariant(const VertexMaxInvar& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + displacement_map(const VertexDisplacement& c) const { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + attractive_force(const AttractiveForce& c) { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + repulsive_force(const RepulsiveForce& c) { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + force_pairs(const ForcePairs& c) { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + cooling(const Cooling& c) { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params + iterations(const TP& c) { + typedef bgl_named_params Params; + return Params(c, *this); + } + + template + bgl_named_params, diameter_range_t, self> + diameter_range(const std::pair& c) { + typedef bgl_named_params, diameter_range_t, self> Params; + return Params(c, *this); + } + + template + bgl_named_params, learning_constant_range_t, self> + learning_constant_range(const std::pair& c) { + typedef bgl_named_params, learning_constant_range_t, self> + Params; + return Params(c, *this); + } + }; + + template + bgl_named_params + weight_map(WeightMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + weight_map2(WeightMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + distance_map(DistanceMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + predecessor_map(PredecessorMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + rank_map(RankMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + root_map(RootMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + root_vertex(const Vertex& r) { + typedef bgl_named_params Params; + return Params(r); + } + + template + bgl_named_params + edge_centrality_map(const EdgeCentralityMap& r) { + typedef bgl_named_params Params; + return Params(r); + } + + template + bgl_named_params + centrality_map(const CentralityMap& r) { + typedef bgl_named_params Params; + return Params(r); + } + + template + bgl_named_params + color_map(ColorMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + capacity_map(CapacityMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + residual_capacity_map(Residual_CapacityMap pmap) { + typedef bgl_named_params + Params; + return Params(pmap); + } + + template + bgl_named_params + reverse_edge_map(ReverseMap pmap) { + typedef bgl_named_params + Params; + return Params(pmap); + } + + template + bgl_named_params + discover_time_map(DiscoverTimeMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + lowpoint_map(LowPointMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + vertex_index_map(IndexMap pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + vertex_index1_map(const IndexMap& pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + vertex_index2_map(const IndexMap& pmap) { + typedef bgl_named_params Params; + return Params(pmap); + } + + template + bgl_named_params + visitor(const Visitor& vis) { + typedef bgl_named_params Params; + return Params(vis); + } + + template + bgl_named_params + distance_compare(Compare cmp) { + typedef bgl_named_params Params; + return Params(cmp); + } + + template + bgl_named_params + distance_combine(Combine cmb) { + typedef bgl_named_params Params; + return Params(cmb); + } + + template + bgl_named_params + distance_inf(Init init) { + typedef bgl_named_params Params; + return Params(init); + } + + template + bgl_named_params + distance_zero(Init init) { + typedef bgl_named_params Params; + return Params(init); + } + + template + bgl_named_params, buffer_param_t> + buffer(Buffer& b) { + typedef bgl_named_params, buffer_param_t> Params; + return Params(detail::wrap_ref(b)); + } + + template + bgl_named_params + edge_copy(const Copier& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + vertex_copy(const Copier& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + orig_to_copy(const Orig2CopyMap& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + isomorphism_map(const IsoMap& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + vertex_invariant(const VertexInvar& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + vertex_invariant1(const VertexInvar& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + vertex_invariant2(const VertexInvar& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + vertex_max_invariant(const VertexMaxInvar& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + displacement_map(const VertexDisplacement& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + attractive_force(const AttractiveForce& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + repulsive_force(const RepulsiveForce& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + force_pairs(const ForcePairs& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + cooling(const Cooling& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params + iterations(const T& c) { + typedef bgl_named_params Params; + return Params(c); + } + + template + bgl_named_params, diameter_range_t> + diameter_range(const std::pair& c) { + typedef bgl_named_params, diameter_range_t> Params; + return Params(c); + } + + template + bgl_named_params, learning_constant_range_t> + learning_constant_range(const std::pair& c) { + typedef bgl_named_params, learning_constant_range_t> + Params; + return Params(c); + } + + //=========================================================================== + // Functions for extracting parameters from bgl_named_params + + template + inline + typename property_value< bgl_named_params, Tag2>::type + get_param(const bgl_named_params& p, Tag2 tag2) + { + enum { match = detail::same_property::value }; + typedef typename + property_value< bgl_named_params, Tag2>::type T2; + T2* t2 = 0; + typedef detail::property_value_dispatch Dispatcher; + return Dispatcher::const_get_value(p, t2, tag2); + } + + + namespace detail { + // MSVC++ workaround + template + struct choose_param_helper { + template struct result { typedef Param type; }; + template + static const Param& apply(const Param& p, const Default&) { return p; } + }; + template <> + struct choose_param_helper { + template struct result { typedef Default type; }; + template + static const Default& apply(const error_property_not_found&, const Default& d) + { return d; } + }; + } // namespace detail + + template + const typename detail::choose_param_helper

            ::template result::type& + choose_param(const P& param, const Default& d) { + return detail::choose_param_helper

            ::apply(param, d); + } + + template + inline bool is_default_param(const T&) { return false; } + + inline bool is_default_param(const detail::error_property_not_found&) + { return true; } + + namespace detail { + + struct choose_parameter { + template + struct bind_ { + typedef const P& const_result_type; + typedef const P& result_type; + typedef P type; + }; + + template + static typename bind_::const_result_type + const_apply(const P& p, const Graph&, Tag&) + { return p; } + + template + static typename bind_::result_type + apply(const P& p, Graph&, Tag&) + { return p; } + }; + + struct choose_default_param { + template + struct bind_ { + typedef typename property_map::type + result_type; + typedef typename property_map::const_type + const_result_type; + typedef typename property_map::const_type + type; + }; + + template + static typename bind_::const_result_type + const_apply(const P&, const Graph& g, Tag tag) { + return get(tag, g); + } + template + static typename bind_::result_type + apply(const P&, Graph& g, Tag tag) { + return get(tag, g); + } + }; + + template + struct choose_property_map { + typedef choose_parameter type; + }; + template <> + struct choose_property_map { + typedef choose_default_param type; + }; + + template + struct choose_pmap_helper { + typedef typename choose_property_map::type Selector; + typedef typename Selector:: template bind_ Bind; + typedef Bind type; + typedef typename Bind::result_type result_type; + typedef typename Bind::const_result_type const_result_type; + typedef typename Bind::type result; + }; + + // used in the max-flow algorithms + template + struct edge_capacity_value + { + typedef bgl_named_params Params; + typedef typename property_value< Params, edge_capacity_t>::type Param; + typedef typename detail::choose_pmap_helper::result CapacityEdgeMap; + typedef typename property_traits::value_type type; + }; + + } // namespace detail + + + // Use this function instead of choose_param() when you want + // to avoid requiring get(tag, g) when it is not used. + template + typename + detail::choose_pmap_helper::const_result_type + choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag) + { + typedef typename + detail::choose_pmap_helper::Selector Choice; + return Choice::const_apply(p, g, tag); + } + + template + typename detail::choose_pmap_helper::result_type + choose_pmap(const Param& p, Graph& g, PropertyTag tag) + { + typedef typename + detail::choose_pmap_helper::Selector Choice; + return Choice::apply(p, g, tag); + } + +} // namespace boost + +#endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP diff --git a/thirdparty/boost/graph/neighbor_bfs.hpp b/thirdparty/boost/graph/neighbor_bfs.hpp new file mode 100644 index 0000000..53ef7a1 --- /dev/null +++ b/thirdparty/boost/graph/neighbor_bfs.hpp @@ -0,0 +1,323 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP +#define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP + +/* + Neighbor Breadth First Search + Like BFS, but traverses in-edges as well as out-edges. + (for directed graphs only. use normal BFS for undirected graphs) +*/ +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + struct NeighborBFSVisitorConcept { + void constraints() { + function_requires< CopyConstructibleConcept >(); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_out_edge(e, g); + vis.examine_in_edge(e, g); + vis.tree_out_edge(e, g); + vis.tree_in_edge(e, g); + vis.non_tree_out_edge(e, g); + vis.non_tree_in_edge(e, g); + vis.gray_target(e, g); + vis.black_target(e, g); + vis.gray_source(e, g); + vis.black_source(e, g); + vis.finish_vertex(u, g); + } + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + template + class neighbor_bfs_visitor { + public: + neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) { } + + template + void initialize_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, on_initialize_vertex()); + } + template + void discover_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, on_discover_vertex()); + } + template + void examine_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, on_examine_vertex()); + } + template + void examine_out_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_examine_edge()); + } + template + void tree_out_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_tree_edge()); + } + template + void non_tree_out_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_non_tree_edge()); + } + template + void gray_target(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_gray_target()); + } + template + void black_target(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_black_target()); + } + template + void examine_in_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_examine_edge()); + } + template + void tree_in_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_tree_edge()); + } + template + void non_tree_in_edge(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_non_tree_edge()); + } + template + void gray_source(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_gray_target()); + } + template + void black_source(Edge e, Graph& g) { + invoke_visitors(m_vis, e, g, on_black_target()); + } + template + void finish_vertex(Vertex u, Graph& g) { + invoke_visitors(m_vis, u, g, on_finish_vertex()); + } + protected: + Visitors m_vis; + }; + + template + neighbor_bfs_visitor + make_neighbor_bfs_visitor(Visitors vis) { + return neighbor_bfs_visitor(vis); + } + + namespace detail { + + template + void neighbor_bfs_impl + (const BidirectionalGraph& g, + typename graph_traits::vertex_descriptor s, + Buffer& Q, BFSVisitor vis, ColorMap color) + + { + function_requires< BidirectionalGraphConcept >(); + typedef graph_traits GTraits; + typedef typename GTraits::vertex_descriptor Vertex; + typedef typename GTraits::edge_descriptor Edge; + function_requires< + NeighborBFSVisitorConcept >(); + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + put(color, s, Color::gray()); + vis.discover_vertex(s, g); + Q.push(s); + while (! Q.empty()) { + Vertex u = Q.top(); + Q.pop(); // pop before push to avoid problem if Q is priority_queue. + vis.examine_vertex(u, g); + + typename GTraits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + Edge e = *ei; + vis.examine_out_edge(e, g); + Vertex v = target(e, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { + vis.tree_out_edge(e, g); + put(color, v, Color::gray()); + vis.discover_vertex(v, g); + Q.push(v); + } else { + vis.non_tree_out_edge(e, g); + if (v_color == Color::gray()) + vis.gray_target(e, g); + else + vis.black_target(e, g); + } + } // for out-edges + + typename GTraits::in_edge_iterator in_ei, in_ei_end; + for (tie(in_ei, in_ei_end) = in_edges(u, g); + in_ei != in_ei_end; ++in_ei) { + Edge e = *in_ei; + vis.examine_in_edge(e, g); + Vertex v = source(e, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { + vis.tree_in_edge(e, g); + put(color, v, Color::gray()); + vis.discover_vertex(v, g); + Q.push(v); + } else { + vis.non_tree_in_edge(e, g); + if (v_color == Color::gray()) + vis.gray_source(e, g); + else + vis.black_source(e, g); + } + } // for in-edges + + put(color, u, Color::black()); + vis.finish_vertex(u, g); + } // while + } + + + template + void neighbor_bfs_helper + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + ColorMap color, + BFSVisitor vis, + const bgl_named_params& params) + { + typedef graph_traits Traits; + // Buffer default + typedef typename Traits::vertex_descriptor Vertex; + typedef boost::queue queue_t; + queue_t Q; + detail::wrap_ref Qref(Q); + // Initialization + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename boost::graph_traits::vertex_iterator i, i_end; + for (tie(i, i_end) = vertices(g); i != i_end; ++i) { + put(color, *i, Color::white()); + vis.initialize_vertex(*i, g); + } + neighbor_bfs_impl + (g, s, + choose_param(get_param(params, buffer_param_t()), Qref).ref, + vis, color); + } + + //------------------------------------------------------------------------- + // Choose between default color and color parameters. Using + // function dispatching so that we don't require vertex index if + // the color default is not being used. + + template + struct neighbor_bfs_dispatch { + template + static void apply + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params, + ColorMap color) + { + neighbor_bfs_helper + (g, s, color, + choose_param(get_param(params, graph_visitor), + make_neighbor_bfs_visitor(null_visitor())), + params); + } + }; + + template <> + struct neighbor_bfs_dispatch { + template + static void apply + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params, + detail::error_property_not_found) + { + std::vector color_vec(num_vertices(g)); + null_visitor null_vis; + + neighbor_bfs_helper + (g, s, + make_iterator_property_map + (color_vec.begin(), + choose_const_pmap(get_param(params, vertex_index), + g, vertex_index), color_vec[0]), + choose_param(get_param(params, graph_visitor), + make_neighbor_bfs_visitor(null_vis)), + params); + } + }; + + } // namespace detail + + + // Named Parameter Variant + template + void neighbor_breadth_first_search + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // The graph is passed by *const* reference so that graph adaptors + // (temporaries) can be passed into this function. However, the + // graph is not really const since we may write to property maps + // of the graph. + VertexListGraph& ng = const_cast(g); + typedef typename property_value< bgl_named_params, + vertex_color_t>::type C; + detail::neighbor_bfs_dispatch::apply(ng, s, params, + get_param(params, vertex_color)); + } + + + // This version does not initialize colors, user has to. + + template + void neighbor_breadth_first_visit + (IncidenceGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + typedef graph_traits Traits; + // Buffer default + typedef boost::queue queue_t; + queue_t Q; + detail::wrap_ref Qref(Q); + + detail::neighbor_bfs_impl + (g, s, + choose_param(get_param(params, buffer_param_t()), Qref).ref, + choose_param(get_param(params, graph_visitor), + make_neighbor_bfs_visitor(null_visitor())), + choose_pmap(get_param(params, vertex_color), g, vertex_color) + ); + } + +} // namespace boost + +#endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP + diff --git a/thirdparty/boost/graph/page_rank.hpp b/thirdparty/boost/graph/page_rank.hpp new file mode 100644 index 0000000..f126444 --- /dev/null +++ b/thirdparty/boost/graph/page_rank.hpp @@ -0,0 +1,153 @@ +// Copyright 2004-5 The Trustees of Indiana University. +// Copyright 2002 Brad King and Douglas Gregor + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine + +#ifndef BOOST_GRAPH_PAGE_RANK_HPP +#define BOOST_GRAPH_PAGE_RANK_HPP + +#include +#include +#include +#include +#include + +namespace boost { namespace graph { + +struct n_iterations +{ + explicit n_iterations(std::size_t n) : n(n) { } + + template + bool + operator()(const RankMap&, const Graph&) + { + return n-- == 0; + } + + private: + std::size_t n; +}; + +namespace detail { + template + void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank, + typename property_traits::value_type damping, + incidence_graph_tag) + { + typedef typename property_traits::value_type rank_type; + + // Set new rank maps + BGL_FORALL_VERTICES_T(v, g, Graph) put(to_rank, v, rank_type(1 - damping)); + + BGL_FORALL_VERTICES_T(u, g, Graph) { + rank_type u_rank_out = damping * get(from_rank, u) / out_degree(u, g); + BGL_FORALL_ADJ_T(u, v, g, Graph) + put(to_rank, v, get(to_rank, v) + u_rank_out); + } + } + + template + void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank, + typename property_traits::value_type damping, + bidirectional_graph_tag) + { + typedef typename property_traits::value_type damping_type; + BGL_FORALL_VERTICES_T(v, g, Graph) { + typename property_traits::value_type rank(0); + BGL_FORALL_INEDGES_T(v, e, g, Graph) + rank += get(from_rank, source(e, g)) / out_degree(source(e, g), g); + put(to_rank, v, (damping_type(1) - damping) + damping * rank); + } + } +} // end namespace detail + +template +void +page_rank(const Graph& g, RankMap rank_map, Done done, + typename property_traits::value_type damping, + typename graph_traits::vertices_size_type n, + RankMap2 rank_map2) +{ + typedef typename property_traits::value_type rank_type; + + rank_type initial_rank = rank_type(rank_type(1) / n); + BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, initial_rank); + + bool to_map_2 = true; + while ((to_map_2 && !done(rank_map, g)) || + (!to_map_2 && !done(rank_map2, g))) { + typedef typename graph_traits::traversal_category category; + + if (to_map_2) { + detail::page_rank_step(g, rank_map, rank_map2, damping, category()); + } else { + detail::page_rank_step(g, rank_map2, rank_map, damping, category()); + } + to_map_2 = !to_map_2; + } + + if (!to_map_2) { + BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, get(rank_map2, v)); + } +} + +template +void +page_rank(const Graph& g, RankMap rank_map, Done done, + typename property_traits::value_type damping, + typename graph_traits::vertices_size_type n) +{ + typedef typename property_traits::value_type rank_type; + + std::vector ranks2(num_vertices(g)); + page_rank(g, rank_map, done, damping, n, + make_iterator_property_map(ranks2.begin(), get(vertex_index, g))); +} + +template +inline void +page_rank(const Graph& g, RankMap rank_map, Done done, + typename property_traits::value_type damping = 0.85) +{ + page_rank(g, rank_map, done, damping, num_vertices(g)); +} + +template +inline void +page_rank(const Graph& g, RankMap rank_map) +{ + page_rank(g, rank_map, n_iterations(20)); +} + +// TBD: this could be _much_ more efficient, using a queue to store +// the vertices that should be reprocessed and keeping track of which +// vertices are in the queue with a property map. Baah, this only +// applies when we have a bidirectional graph. +template +void +remove_dangling_links(MutableGraph& g) +{ + typename graph_traits::vertices_size_type old_n; + do { + old_n = num_vertices(g); + + typename graph_traits::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; /* in loop */) { + typename graph_traits::vertex_descriptor v = *vi++; + if (out_degree(v, g) == 0) { + clear_vertex(v, g); + remove_vertex(v, g); + } + } + } while (num_vertices(g) < old_n); +} + +} } // end namespace boost::graph + +#endif // BOOST_GRAPH_PAGE_RANK_HPP diff --git a/thirdparty/boost/graph/planar_canonical_ordering.hpp b/thirdparty/boost/graph/planar_canonical_ordering.hpp new file mode 100644 index 0000000..b10b95a --- /dev/null +++ b/thirdparty/boost/graph/planar_canonical_ordering.hpp @@ -0,0 +1,211 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= + +#ifndef __PLANAR_CANONICAL_ORDERING_HPP__ +#define __PLANAR_CANONICAL_ORDERING_HPP__ + +#include +#include +#include +#include //for next and prior +#include +#include + + +namespace boost +{ + + + template + void planar_canonical_ordering(const Graph& g, + PlanarEmbedding embedding, + OutputIterator ordering, + VertexIndexMap vm) + { + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::adjacency_iterator + adjacency_iterator_t; + typedef typename std::pair vertex_pair_t; + typedef typename property_traits::value_type + embedding_value_t; + typedef typename embedding_value_t::const_iterator embedding_iterator_t; + typedef iterator_property_map + ::iterator, VertexIndexMap> + vertex_to_vertex_map_t; + typedef iterator_property_map + ::iterator, VertexIndexMap> + vertex_to_size_t_map_t; + + enum {PROCESSED, + UNPROCESSED, + ONE_NEIGHBOR_PROCESSED, + READY_TO_BE_PROCESSED}; + + std::vector processed_neighbor_vector(num_vertices(g)); + vertex_to_vertex_map_t processed_neighbor + (processed_neighbor_vector.begin(), vm); + + std::vector status_vector(num_vertices(g), UNPROCESSED); + vertex_to_size_t_map_t status(status_vector.begin(), vm); + + std::list ready_to_be_processed; + + vertex_t first_vertex = *vertices(g).first; + vertex_t second_vertex; + adjacency_iterator_t ai, ai_end; + for(tie(ai,ai_end) = adjacent_vertices(first_vertex,g); ai != ai_end; ++ai) + { + if (*ai == first_vertex) + continue; + second_vertex = *ai; + break; + } + + ready_to_be_processed.push_back(first_vertex); + status[first_vertex] = READY_TO_BE_PROCESSED; + ready_to_be_processed.push_back(second_vertex); + status[second_vertex] = READY_TO_BE_PROCESSED; + + while(!ready_to_be_processed.empty()) + { + vertex_t u = ready_to_be_processed.front(); + ready_to_be_processed.pop_front(); + + if (status[u] != READY_TO_BE_PROCESSED && u != second_vertex) + continue; + + embedding_iterator_t ei, ei_start, ei_end; + embedding_iterator_t next_edge_itr, prior_edge_itr; + + ei_start = embedding[u].begin(); + ei_end = embedding[u].end(); + prior_edge_itr = prior(ei_end); + while(source(*prior_edge_itr, g) == target(*prior_edge_itr,g)) + prior_edge_itr = prior(prior_edge_itr); + + for(ei = ei_start; ei != ei_end; ++ei) + { + + edge_t e(*ei); // e = (u,v) + next_edge_itr = next(ei) == ei_end ? ei_start : next(ei); + vertex_t v = source(e,g) == u ? target(e,g) : source(e,g); + + vertex_t prior_vertex = source(*prior_edge_itr, g) == u ? + target(*prior_edge_itr, g) : source(*prior_edge_itr, g); + vertex_t next_vertex = source(*next_edge_itr, g) == u ? + target(*next_edge_itr, g) : source(*next_edge_itr, g); + + // Need prior_vertex, u, v, and next_vertex to all be + // distinct. This is possible, since the input graph is + // triangulated. It'll be true all the time in a simple + // graph, but loops and parallel edges cause some complications. + if (prior_vertex == v || prior_vertex == u) + { + prior_edge_itr = ei; + continue; + } + + //Skip any self-loops + if (u == v) + continue; + + // Move next_edge_itr (and next_vertex) forwards + // past any loops or parallel edges + while (next_vertex == v || next_vertex == u) + { + next_edge_itr = next(next_edge_itr) == ei_end ? + ei_start : next(next_edge_itr); + next_vertex = source(*next_edge_itr, g) == u ? + target(*next_edge_itr, g) : source(*next_edge_itr, g); + } + + + if (status[v] == UNPROCESSED) + { + status[v] = ONE_NEIGHBOR_PROCESSED; + processed_neighbor[v] = u; + } + else if (status[v] == ONE_NEIGHBOR_PROCESSED) + { + vertex_t x = processed_neighbor[v]; + //are edges (v,u) and (v,x) adjacent in the planar + //embedding? if so, set status[v] = 1. otherwise, set + //status[v] = 2. + + if ((next_vertex == x && + !(first_vertex == u && second_vertex == x) + ) + || + (prior_vertex == x && + !(first_vertex == x && second_vertex == u) + ) + ) + { + status[v] = READY_TO_BE_PROCESSED; + } + else + { + status[v] = READY_TO_BE_PROCESSED + 1; + } + } + else if (status[v] > ONE_NEIGHBOR_PROCESSED) + { + //check the two edges before and after (v,u) in the planar + //embedding, and update status[v] accordingly + + bool processed_before = false; + if (status[prior_vertex] == PROCESSED) + processed_before = true; + + bool processed_after = false; + if (status[next_vertex] == PROCESSED) + processed_after = true; + + if (!processed_before && !processed_after) + ++status[v]; + + else if (processed_before && processed_after) + --status[v]; + + } + + if (status[v] == READY_TO_BE_PROCESSED) + ready_to_be_processed.push_back(v); + + prior_edge_itr = ei; + + } + + status[u] = PROCESSED; + *ordering = u; + ++ordering; + + } + + } + + + template + void planar_canonical_ordering(const Graph& g, + PlanarEmbedding embedding, + OutputIterator ordering + ) + { + planar_canonical_ordering(g, embedding, ordering, get(vertex_index,g)); + } + + +} //namespace boost + +#endif //__PLANAR_CANONICAL_ORDERING_HPP__ diff --git a/thirdparty/boost/graph/planar_detail/add_edge_visitors.hpp b/thirdparty/boost/graph/planar_detail/add_edge_visitors.hpp new file mode 100644 index 0000000..7b5bf65 --- /dev/null +++ b/thirdparty/boost/graph/planar_detail/add_edge_visitors.hpp @@ -0,0 +1,59 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __ADD_EDGE_VISITORS_HPP__ +#define __ADD_EDGE_VISITORS_HPP__ + +#include + +namespace boost +{ + + struct default_add_edge_visitor + { + + template + void visit_vertex_pair(Vertex u, Vertex v, Graph& g) + { + add_edge(u,v,g); + } + + }; + + template + struct edge_index_update_visitor + { + + typedef typename + property_traits::value_type edge_index_value_t; + + edge_index_update_visitor(EdgeIndexMap em, + edge_index_value_t next_index_available + ) : + m_em(em), + m_next_index(next_index_available) + {} + + template + void visit_vertex_pair(Vertex u, Vertex v, Graph& g) + { + typedef typename graph_traits::edge_descriptor edge_t; + std::pair return_value = add_edge(u,v,g); + if (return_value.second) + put( m_em, return_value.first, m_next_index++); + } + + private: + + EdgeIndexMap m_em; + edge_index_value_t m_next_index; + + }; + +} // namespace boost + +#endif //__ADD_EDGE_VISITORS_HPP__ diff --git a/thirdparty/boost/graph/planar_detail/boyer_myrvold_impl.hpp b/thirdparty/boost/graph/planar_detail/boyer_myrvold_impl.hpp new file mode 100644 index 0000000..44750fc --- /dev/null +++ b/thirdparty/boost/graph/planar_detail/boyer_myrvold_impl.hpp @@ -0,0 +1,2010 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= +#ifndef __BOYER_MYRVOLD_IMPL_HPP__ +#define __BOYER_MYRVOLD_IMPL_HPP__ + +#include +#include +#include //for boost::next +#include //for std::min macros +#include +#include +#include +#include +#include +#include +#include +#include + + + +namespace boost +{ + + template + struct planar_dfs_visitor : public dfs_visitor<> + { + planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p, + DFSNumberMap dfs_n, LeastAncestorMap lam, + DFSParentEdgeMap dfs_edge) + : low(lpm), + parent(dfs_p), + df_number(dfs_n), + least_ancestor(lam), + df_edge(dfs_edge), + count(0) + {} + + + template + void start_vertex(const Vertex& u, Graph&) + { + put(parent, u, u); + put(least_ancestor, u, count); + } + + + template + void discover_vertex(const Vertex& u, Graph&) + { + put(low, u, count); + put(df_number, u, count); + ++count; + } + + template + void tree_edge(const Edge& e, Graph& g) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + vertex_t s(source(e,g)); + vertex_t t(target(e,g)); + + put(parent, t, s); + put(df_edge, t, e); + put(least_ancestor, t, get(df_number, s)); + } + + template + void back_edge(const Edge& e, Graph& g) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::vertices_size_type v_size_t; + + vertex_t s(source(e,g)); + vertex_t t(target(e,g)); + BOOST_USING_STD_MIN(); + + if ( t != get(parent, s) ) { + v_size_t s_low_df_number = get(low, s); + v_size_t t_df_number = get(df_number, t); + v_size_t s_least_ancestor_df_number = get(least_ancestor, s); + + put(low, s, + min BOOST_PREVENT_MACRO_SUBSTITUTION(s_low_df_number, + t_df_number) + ); + + put(least_ancestor, s, + min BOOST_PREVENT_MACRO_SUBSTITUTION(s_least_ancestor_df_number, + t_df_number + ) + ); + + } + } + + template + void finish_vertex(const Vertex& u, Graph& g) + { + typedef typename graph_traits::vertices_size_type v_size_t; + + Vertex u_parent = get(parent, u); + v_size_t u_parent_lowpoint = get(low, u_parent); + v_size_t u_lowpoint = get(low, u); + BOOST_USING_STD_MIN(); + + if (u_parent != u) + { + put(low, u_parent, + min BOOST_PREVENT_MACRO_SUBSTITUTION(u_lowpoint, + u_parent_lowpoint + ) + ); + } + } + + LowPointMap low; + DFSParentMap parent; + DFSNumberMap df_number; + LeastAncestorMap least_ancestor; + DFSParentEdgeMap df_edge; + SizeType count; + + }; + + + + + + + template + class boyer_myrvold_impl + { + + typedef typename graph_traits::vertices_size_type v_size_t; + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename graph_traits::out_edge_iterator + out_edge_iterator_t; + typedef graph::detail::face_handle + face_handle_t; + typedef std::vector vertex_vector_t; + typedef std::vector edge_vector_t; + typedef std::list vertex_list_t; + typedef std::list< face_handle_t > face_handle_list_t; + typedef boost::shared_ptr< face_handle_list_t > face_handle_list_ptr_t; + typedef boost::shared_ptr< vertex_list_t > vertex_list_ptr_t; + typedef boost::tuple merge_stack_frame_t; + typedef std::vector merge_stack_t; + + template + struct map_vertex_to_ + { + typedef iterator_property_map + ::iterator, VertexIndexMap> type; + }; + + typedef typename map_vertex_to_::type vertex_to_v_size_map_t; + typedef typename map_vertex_to_::type vertex_to_vertex_map_t; + typedef typename map_vertex_to_::type vertex_to_edge_map_t; + typedef typename map_vertex_to_::type + vertex_to_vertex_list_ptr_map_t; + typedef typename map_vertex_to_< edge_vector_t >::type + vertex_to_edge_vector_map_t; + typedef typename map_vertex_to_::type vertex_to_bool_map_t; + typedef typename map_vertex_to_::type + vertex_to_face_handle_map_t; + typedef typename map_vertex_to_::type + vertex_to_face_handle_list_ptr_map_t; + typedef typename map_vertex_to_::type + vertex_to_separated_node_map_t; + + template + struct face_vertex_iterator + { + typedef face_iterator + type; + }; + + template + struct face_edge_iterator + { + typedef face_iterator + type; + }; + + + + public: + + + + boyer_myrvold_impl(const Graph& arg_g, VertexIndexMap arg_vm): + g(arg_g), + vm(arg_vm), + + low_point_vector(num_vertices(g)), + dfs_parent_vector(num_vertices(g)), + dfs_number_vector(num_vertices(g)), + least_ancestor_vector(num_vertices(g)), + pertinent_roots_vector(num_vertices(g)), + backedge_flag_vector(num_vertices(g), num_vertices(g) + 1), + visited_vector(num_vertices(g), num_vertices(g) + 1), + face_handles_vector(num_vertices(g)), + dfs_child_handles_vector(num_vertices(g)), + separated_dfs_child_list_vector(num_vertices(g)), + separated_node_in_parent_list_vector(num_vertices(g)), + canonical_dfs_child_vector(num_vertices(g)), + flipped_vector(num_vertices(g), false), + backedges_vector(num_vertices(g)), + dfs_parent_edge_vector(num_vertices(g)), + + vertices_by_dfs_num(num_vertices(g)), + + low_point(low_point_vector.begin(), vm), + dfs_parent(dfs_parent_vector.begin(), vm), + dfs_number(dfs_number_vector.begin(), vm), + least_ancestor(least_ancestor_vector.begin(), vm), + pertinent_roots(pertinent_roots_vector.begin(), vm), + backedge_flag(backedge_flag_vector.begin(), vm), + visited(visited_vector.begin(), vm), + face_handles(face_handles_vector.begin(), vm), + dfs_child_handles(dfs_child_handles_vector.begin(), vm), + separated_dfs_child_list(separated_dfs_child_list_vector.begin(), vm), + separated_node_in_parent_list + (separated_node_in_parent_list_vector.begin(), vm), + canonical_dfs_child(canonical_dfs_child_vector.begin(), vm), + flipped(flipped_vector.begin(), vm), + backedges(backedges_vector.begin(), vm), + dfs_parent_edge(dfs_parent_edge_vector.begin(), vm) + + { + + planar_dfs_visitor + vis + (low_point, dfs_parent, dfs_number, least_ancestor, dfs_parent_edge); + + // Perform a depth-first search to find each vertex's low point, least + // ancestor, and dfs tree information + depth_first_search(g, visitor(vis).vertex_index_map(vm)); + + // Sort vertices by their lowpoint - need this later in the constructor + vertex_vector_t vertices_by_lowpoint(num_vertices(g)); + std::copy( vertices(g).first, vertices(g).second, + vertices_by_lowpoint.begin() + ); + bucket_sort(vertices_by_lowpoint.begin(), + vertices_by_lowpoint.end(), + low_point, + num_vertices(g) + ); + + // Sort vertices by their dfs number - need this to iterate by reverse + // DFS number in the main loop. + std::copy( vertices(g).first, vertices(g).second, + vertices_by_dfs_num.begin() + ); + bucket_sort(vertices_by_dfs_num.begin(), + vertices_by_dfs_num.end(), + dfs_number, + num_vertices(g) + ); + + // Initialize face handles. A face handle is an abstraction that serves + // two uses in our implementation - it allows us to efficiently move + // along the outer face of embedded bicomps in a partially embedded + // graph, and it provides storage for the planar embedding. Face + // handles are implemented by a sequence of edges and are associated + // with a particular vertex - the sequence of edges represents the + // current embedding of edges around that vertex, and the first and + // last edges in the sequence represent the pair of edges on the outer + // face that are adjacent to the associated vertex. This lets us embed + // edges in the graph by just pushing them on the front or back of the + // sequence of edges held by the face handles. + // + // Our algorithm starts with a DFS tree of edges (where every vertex is + // an articulation point and every edge is a singleton bicomp) and + // repeatedly merges bicomps by embedding additional edges. Note that + // any bicomp at any point in the algorithm can be associated with a + // unique edge connecting the vertex of that bicomp with the lowest DFS + // number (which we refer to as the "root" of the bicomp) with its DFS + // child in the bicomp: the existence of two such edges would contradict + // the properties of a DFS tree. We refer to the DFS child of the root + // of a bicomp as the "canonical DFS child" of the bicomp. Note that a + // vertex can be the root of more than one bicomp. + // + // We move around the external faces of a bicomp using a few property + // maps, which we'll initialize presently: + // + // - face_handles: maps a vertex to a face handle that can be used to + // move "up" a bicomp. For a vertex that isn't an articulation point, + // this holds the face handles that can be used to move around that + // vertex's unique bicomp. For a vertex that is an articulation point, + // this holds the face handles associated with the unique bicomp that + // the vertex is NOT the root of. These handles can therefore be used + // to move from any point on the outer face of the tree of bicomps + // around the current outer face towards the root of the DFS tree. + // + // - dfs_child_handles: these are used to hold face handles for + // vertices that are articulation points - dfs_child_handles[v] holds + // the face handles corresponding to vertex u in the bicomp with root + // u and canonical DFS child v. + // + // - canonical_dfs_child: this property map allows one to determine the + // canonical DFS child of a bicomp while traversing the outer face. + // This property map is only valid when applied to one of the two + // vertices adjacent to the root of the bicomp on the outer face. To + // be more precise, if v is the canonical DFS child of a bicomp, + // canonical_dfs_child[dfs_child_handles[v].first_vertex()] == v and + // canonical_dfs_child[dfs_child_handles[v].second_vertex()] == v. + // + // - pertinent_roots: given a vertex v, pertinent_roots[v] contains a + // list of face handles pointing to the top of bicomps that need to + // be visited by the current walkdown traversal (since they lead to + // backedges that need to be embedded). These lists are populated by + // the walkup and consumed by the walkdown. + + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_t v(*vi); + vertex_t parent = dfs_parent[v]; + + if (parent != v) + { + edge_t parent_edge = dfs_parent_edge[v]; + add_to_embedded_edges(parent_edge, StoreOldHandlesPolicy()); + face_handles[v] = face_handle_t(v, parent_edge, g); + dfs_child_handles[v] = face_handle_t(parent, parent_edge, g); + } + else + { + face_handles[v] = face_handle_t(v); + dfs_child_handles[v] = face_handle_t(parent); + } + + canonical_dfs_child[v] = v; + pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t); + separated_dfs_child_list[v] = vertex_list_ptr_t(new vertex_list_t); + + } + + // We need to create a list of not-yet-merged depth-first children for + // each vertex that will be updated as bicomps get merged. We sort each + // list by ascending lowpoint, which allows the externally_active + // function to run in constant time, and we keep a pointer to each + // vertex's representation in its parent's list, which allows merging + //in constant time. + + for(typename vertex_vector_t::iterator itr = + vertices_by_lowpoint.begin(); + itr != vertices_by_lowpoint.end(); ++itr) + { + vertex_t v(*itr); + vertex_t parent(dfs_parent[v]); + if (v != parent) + { + separated_node_in_parent_list[v] = + separated_dfs_child_list[parent]->insert + (separated_dfs_child_list[parent]->end(), v); + } + } + + // The merge stack holds path information during a walkdown iteration + merge_stack.reserve(num_vertices(g)); + + } + + + + + + + bool is_planar() + { + + // This is the main algorithm: starting with a DFS tree of embedded + // edges (which, since it's a tree, is planar), iterate through all + // vertices by reverse DFS number, attempting to embed all backedges + // connecting the current vertex to vertices with higher DFS numbers. + // + // The walkup is a procedure that examines all such backedges and sets + // up the required data structures so that they can be searched by the + // walkdown in linear time. The walkdown does the actual work of + // embedding edges and flipping bicomps, and can identify when it has + // come across a kuratowski subgraph. + // + // store_old_face_handles caches face handles from the previous + // iteration - this is used only for the kuratowski subgraph isolation, + // and is therefore dispatched based on the StoreOldHandlesPolicy. + // + // clean_up_embedding does some clean-up and fills in values that have + // to be computed lazily during the actual execution of the algorithm + // (for instance, whether or not a bicomp is flipped in the final + // embedding). It's dispatched on the the StoreEmbeddingPolicy, since + // it's not needed if an embedding isn't desired. + + typename vertex_vector_t::reverse_iterator vi, vi_end; + + vi_end = vertices_by_dfs_num.rend(); + for(vi = vertices_by_dfs_num.rbegin(); vi != vi_end; ++vi) + { + + store_old_face_handles(StoreOldHandlesPolicy()); + + vertex_t v(*vi); + + walkup(v); + + if (!walkdown(v)) + return false; + + } + + clean_up_embedding(StoreEmbeddingPolicy()); + + return true; + + } + + + + + + + private: + + + + + + void walkup(vertex_t v) + { + + // The point of the walkup is to follow all backedges from v to + // vertices with higher DFS numbers, and update pertinent_roots + // for the bicomp roots on the path from backedge endpoints up + // to v. This will set the stage for the walkdown to efficiently + // traverse the graph of bicomps down from v. + + typedef typename face_vertex_iterator::type walkup_iterator_t; + + out_edge_iterator_t oi, oi_end; + for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) + { + edge_t e(*oi); + vertex_t e_source(source(e,g)); + vertex_t e_target(target(e,g)); + + if (e_source == e_target) + { + self_loops.push_back(e); + continue; + } + + vertex_t w(e_source == v ? e_target : e_source); + + //continue if not a back edge or already embedded + if (dfs_number[w] < dfs_number[v] || e == dfs_parent_edge[w]) + continue; + + backedges[w].push_back(e); + + v_size_t timestamp = dfs_number[v]; + backedge_flag[w] = timestamp; + + walkup_iterator_t walkup_itr(w, face_handles); + walkup_iterator_t walkup_end; + vertex_t lead_vertex = w; + + while (true) + { + + // Move to the root of the current bicomp or the first visited + // vertex on the bicomp by going up each side in parallel + + while(walkup_itr != walkup_end && + visited[*walkup_itr] != timestamp + ) + { + lead_vertex = *walkup_itr; + visited[lead_vertex] = timestamp; + ++walkup_itr; + } + + // If we've found the root of a bicomp through a path we haven't + // seen before, update pertinent_roots with a handle to the + // current bicomp. Otherwise, we've just seen a path we've been + // up before, so break out of the main while loop. + + if (walkup_itr == walkup_end) + { + vertex_t dfs_child = canonical_dfs_child[lead_vertex]; + vertex_t parent = dfs_parent[dfs_child]; + + visited[dfs_child_handles[dfs_child].first_vertex()] + = timestamp; + visited[dfs_child_handles[dfs_child].second_vertex()] + = timestamp; + + if (low_point[dfs_child] < dfs_number[v] || + least_ancestor[dfs_child] < dfs_number[v] + ) + { + pertinent_roots[parent]->push_back + (dfs_child_handles[dfs_child]); + } + else + { + pertinent_roots[parent]->push_front + (dfs_child_handles[dfs_child]); + } + + if (parent != v && visited[parent] != timestamp) + { + walkup_itr = walkup_iterator_t(parent, face_handles); + lead_vertex = parent; + } + else + break; + } + else + break; + } + + } + + } + + + + + + + + bool walkdown(vertex_t v) + { + // This procedure is where all of the action is - pertinent_roots + // has already been set up by the walkup, so we just need to move + // down bicomps from v until we find vertices that have been + // labeled as backedge endpoints. Once we find such a vertex, we + // embed the corresponding edge and glue together the bicomps on + // the path connecting the two vertices in the edge. This may + // involve flipping bicomps along the way. + + vertex_t w; //the other endpoint of the edge we're embedding + + while (!pertinent_roots[v]->empty()) + { + + face_handle_t root_face_handle = pertinent_roots[v]->front(); + face_handle_t curr_face_handle = root_face_handle; + pertinent_roots[v]->pop_front(); + + merge_stack.clear(); + + while(true) + { + + typename face_vertex_iterator<>::type + first_face_itr, second_face_itr, face_end; + vertex_t first_side_vertex + = graph_traits::null_vertex(); + vertex_t second_side_vertex; + vertex_t first_tail, second_tail; + + first_tail = second_tail = curr_face_handle.get_anchor(); + first_face_itr = typename face_vertex_iterator<>::type + (curr_face_handle, face_handles, first_side()); + second_face_itr = typename face_vertex_iterator<>::type + (curr_face_handle, face_handles, second_side()); + + for(; first_face_itr != face_end; ++first_face_itr) + { + vertex_t face_vertex(*first_face_itr); + if (pertinent(face_vertex, v) || + externally_active(face_vertex, v) + ) + { + first_side_vertex = face_vertex; + second_side_vertex = face_vertex; + break; + } + first_tail = face_vertex; + } + + if (first_side_vertex == graph_traits::null_vertex() || + first_side_vertex == curr_face_handle.get_anchor() + ) + break; + + for(;second_face_itr != face_end; ++second_face_itr) + { + vertex_t face_vertex(*second_face_itr); + if (pertinent(face_vertex, v) || + externally_active(face_vertex, v) + ) + { + second_side_vertex = face_vertex; + break; + } + second_tail = face_vertex; + } + + vertex_t chosen; + bool chose_first_upper_path; + if (internally_active(first_side_vertex, v)) + { + chosen = first_side_vertex; + chose_first_upper_path = true; + } + else if (internally_active(second_side_vertex, v)) + { + chosen = second_side_vertex; + chose_first_upper_path = false; + } + else if (pertinent(first_side_vertex, v)) + { + chosen = first_side_vertex; + chose_first_upper_path = true; + } + else if (pertinent(second_side_vertex, v)) + { + chosen = second_side_vertex; + chose_first_upper_path = false; + } + else + { + + // If there's a pertinent vertex on the lower face + // between the first_face_itr and the second_face_itr, + // this graph isn't planar. + for(; + *first_face_itr != second_side_vertex; + ++first_face_itr + ) + { + vertex_t p(*first_face_itr); + if (pertinent(p,v)) + { + //Found a Kuratowski subgraph + kuratowski_v = v; + kuratowski_x = first_side_vertex; + kuratowski_y = second_side_vertex; + return false; + } + } + + // Otherwise, the fact that we didn't find a pertinent + // vertex on this face is fine - we should set the + // short-circuit edges and break out of this loop to + // start looking at a different pertinent root. + + if (first_side_vertex == second_side_vertex) + { + if (first_tail != v) + { + vertex_t first + = face_handles[first_tail].first_vertex(); + vertex_t second + = face_handles[first_tail].second_vertex(); + tie(first_side_vertex, first_tail) + = make_tuple(first_tail, + first == first_side_vertex ? + second : first + ); + } + else if (second_tail != v) + { + vertex_t first + = face_handles[second_tail].first_vertex(); + vertex_t second + = face_handles[second_tail].second_vertex(); + tie(second_side_vertex, second_tail) + = make_tuple(second_tail, + first == second_side_vertex ? + second : first); + } + else + break; + } + + canonical_dfs_child[first_side_vertex] + = canonical_dfs_child[root_face_handle.first_vertex()]; + canonical_dfs_child[second_side_vertex] + = canonical_dfs_child[root_face_handle.second_vertex()]; + root_face_handle.set_first_vertex(first_side_vertex); + root_face_handle.set_second_vertex(second_side_vertex); + + if (face_handles[first_side_vertex].first_vertex() == + first_tail + ) + face_handles[first_side_vertex].set_first_vertex(v); + else + face_handles[first_side_vertex].set_second_vertex(v); + + if (face_handles[second_side_vertex].first_vertex() == + second_tail + ) + face_handles[second_side_vertex].set_first_vertex(v); + else + face_handles[second_side_vertex].set_second_vertex(v); + + break; + + } + + + // When we unwind the stack, we need to know which direction + // we came down from on the top face handle + + bool chose_first_lower_path = + (chose_first_upper_path && + face_handles[chosen].first_vertex() == first_tail) + || + (!chose_first_upper_path && + face_handles[chosen].first_vertex() == second_tail); + + //If there's a backedge at the chosen vertex, embed it now + if (backedge_flag[chosen] == dfs_number[v]) + { + w = chosen; + + backedge_flag[chosen] = num_vertices(g) + 1; + add_to_merge_points(chosen, StoreOldHandlesPolicy()); + + typename edge_vector_t::iterator ei, ei_end; + ei_end = backedges[chosen].end(); + for(ei = backedges[chosen].begin(); ei != ei_end; ++ei) + { + edge_t e(*ei); + add_to_embedded_edges(e, StoreOldHandlesPolicy()); + + if (chose_first_lower_path) + face_handles[chosen].push_first(e, g); + else + face_handles[chosen].push_second(e, g); + } + + } + else + { + merge_stack.push_back(make_tuple + (chosen, chose_first_upper_path, chose_first_lower_path) + ); + curr_face_handle = *pertinent_roots[chosen]->begin(); + continue; + } + + //Unwind the merge stack to the root, merging all bicomps + + bool bottom_path_follows_first; + bool top_path_follows_first; + bool next_bottom_follows_first = chose_first_upper_path; + face_handle_t top_handle, bottom_handle; + + vertex_t merge_point = chosen; + + while(!merge_stack.empty()) + { + + bottom_path_follows_first = next_bottom_follows_first; + tie(merge_point, + next_bottom_follows_first, + top_path_follows_first + ) = merge_stack.back(); + merge_stack.pop_back(); + + face_handle_t top_handle(face_handles[merge_point]); + face_handle_t bottom_handle + (*pertinent_roots[merge_point]->begin()); + + vertex_t bottom_dfs_child = canonical_dfs_child + [pertinent_roots[merge_point]->begin()->first_vertex()]; + + remove_vertex_from_separated_dfs_child_list( + canonical_dfs_child + [pertinent_roots[merge_point]->begin()->first_vertex()] + ); + + pertinent_roots[merge_point]->pop_front(); + + add_to_merge_points(top_handle.get_anchor(), + StoreOldHandlesPolicy() + ); + + if (top_path_follows_first && bottom_path_follows_first) + { + bottom_handle.flip(); + top_handle.glue_first_to_second(bottom_handle); + } + else if (!top_path_follows_first && + bottom_path_follows_first + ) + { + flipped[bottom_dfs_child] = true; + top_handle.glue_second_to_first(bottom_handle); + } + else if (top_path_follows_first && + !bottom_path_follows_first + ) + { + flipped[bottom_dfs_child] = true; + top_handle.glue_first_to_second(bottom_handle); + } + else //!top_path_follows_first && !bottom_path_follows_first + { + bottom_handle.flip(); + top_handle.glue_second_to_first(bottom_handle); + } + + } + + //Finally, embed all edges (v,w) at their upper end points + canonical_dfs_child[w] + = canonical_dfs_child[root_face_handle.first_vertex()]; + + add_to_merge_points(root_face_handle.get_anchor(), + StoreOldHandlesPolicy() + ); + + typename edge_vector_t::iterator ei, ei_end; + ei_end = backedges[chosen].end(); + for(ei = backedges[chosen].begin(); ei != ei_end; ++ei) + { + if (next_bottom_follows_first) + root_face_handle.push_first(*ei, g); + else + root_face_handle.push_second(*ei, g); + } + + backedges[chosen].clear(); + curr_face_handle = root_face_handle; + + }//while(true) + + }//while(!pertinent_roots[v]->empty()) + + return true; + + } + + + + + + + void store_old_face_handles(graph::detail::no_old_handles) {} + + void store_old_face_handles(graph::detail::store_old_handles) + { + for(typename std::vector::iterator mp_itr + = current_merge_points.begin(); + mp_itr != current_merge_points.end(); ++mp_itr) + { + face_handles[*mp_itr].store_old_face_handles(); + } + current_merge_points.clear(); + } + + + void add_to_merge_points(vertex_t v, graph::detail::no_old_handles) {} + + void add_to_merge_points(vertex_t v, graph::detail::store_old_handles) + { + current_merge_points.push_back(v); + } + + + void add_to_embedded_edges(edge_t e, graph::detail::no_old_handles) {} + + void add_to_embedded_edges(edge_t e, graph::detail::store_old_handles) + { + embedded_edges.push_back(e); + } + + + + + void clean_up_embedding(graph::detail::no_embedding) {} + + void clean_up_embedding(graph::detail::store_embedding) + { + + // If the graph isn't biconnected, we'll still have entries + // in the separated_dfs_child_list for some vertices. Since + // these represent articulation points, we can obtain a + // planar embedding no matter what order we embed them in. + + vertex_iterator_t xi, xi_end; + for(tie(xi,xi_end) = vertices(g); xi != xi_end; ++xi) + { + if (!separated_dfs_child_list[*xi]->empty()) + { + typename vertex_list_t::iterator yi, yi_end; + yi_end = separated_dfs_child_list[*xi]->end(); + for(yi = separated_dfs_child_list[*xi]->begin(); + yi != yi_end; ++yi + ) + { + dfs_child_handles[*yi].flip(); + face_handles[*xi].glue_first_to_second + (dfs_child_handles[*yi]); + } + } + } + + // Up until this point, we've flipped bicomps lazily by setting + // flipped[v] to true if the bicomp rooted at v was flipped (the + // lazy aspect of this flip is that all descendents of that vertex + // need to have their orientations reversed as well). Now, we + // traverse the DFS tree by DFS number and perform the actual + // flipping as needed + + typedef typename vertex_vector_t::iterator vertex_vector_itr_t; + vertex_vector_itr_t vi_end = vertices_by_dfs_num.end(); + for(vertex_vector_itr_t vi = vertices_by_dfs_num.begin(); + vi != vi_end; ++vi + ) + { + vertex_t v(*vi); + bool v_flipped = flipped[v]; + bool p_flipped = flipped[dfs_parent[v]]; + if (v_flipped && !p_flipped) + { + face_handles[v].flip(); + } + else if (p_flipped && !v_flipped) + { + face_handles[v].flip(); + flipped[v] = true; + } + else + { + flipped[v] = false; + } + } + + // If there are any self-loops in the graph, they were flagged + // during the walkup, and we should add them to the embedding now. + // Adding a self loop anywhere in the embedding could never + // invalidate the embedding, but they would complicate the traversal + // if they were added during the walkup/walkdown. + + typename edge_vector_t::iterator ei, ei_end; + ei_end = self_loops.end(); + for(ei = self_loops.begin(); ei != ei_end; ++ei) + { + edge_t e(*ei); + face_handles[source(e,g)].push_second(e,g); + } + + } + + + + + + bool pertinent(vertex_t w, vertex_t v) + { + // w is pertinent with respect to v if there is a backedge (v,w) or if + // w is the root of a bicomp that contains a pertinent vertex. + + return backedge_flag[w] == dfs_number[v] || !pertinent_roots[w]->empty(); + } + + + + bool externally_active(vertex_t w, vertex_t v) + { + // Let a be any proper depth-first search ancestor of v. w is externally + // active with respect to v if there exists a backedge (a,w) or a + // backedge (a,w_0) for some w_0 in a descendent bicomp of w. + + v_size_t dfs_number_of_v = dfs_number[v]; + return (least_ancestor[w] < dfs_number_of_v) || + (!separated_dfs_child_list[w]->empty() && + low_point[separated_dfs_child_list[w]->front()] < dfs_number_of_v); + } + + + + bool internally_active(vertex_t w, vertex_t v) + { + return pertinent(w,v) && !externally_active(w,v); + } + + + + + void remove_vertex_from_separated_dfs_child_list(vertex_t v) + { + typename vertex_list_t::iterator to_delete + = separated_node_in_parent_list[v]; + garbage.splice(garbage.end(), + *separated_dfs_child_list[dfs_parent[v]], + to_delete, + next(to_delete) + ); + } + + + + + + // End of the implementation of the basic Boyer-Myrvold Algorithm. The rest + // of the code below implements the isolation of a Kuratowski subgraph in + // the case that the input graph is not planar. This is by far the most + // complicated part of the implementation. + + + + + public: + + + + + template + vertex_t kuratowski_walkup(vertex_t v, + EdgeToBoolPropertyMap forbidden_edge, + EdgeToBoolPropertyMap goal_edge, + EdgeToBoolPropertyMap is_embedded, + EdgeContainer& path_edges + ) + { + vertex_t current_endpoint; + bool seen_goal_edge = false; + out_edge_iterator_t oi, oi_end; + + for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) + forbidden_edge[*oi] = true; + + for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) + { + path_edges.clear(); + + edge_t e(*oi); + current_endpoint = target(*oi,g) == v ? + source(*oi,g) : target(*oi,g); + + if (dfs_number[current_endpoint] < dfs_number[v] || + is_embedded[e] || + v == current_endpoint //self-loop + ) + { + //Not a backedge + continue; + } + + path_edges.push_back(e); + if (goal_edge[e]) + { + return current_endpoint; + } + + typedef typename face_edge_iterator<>::type walkup_itr_t; + + walkup_itr_t + walkup_itr(current_endpoint, face_handles, first_side()); + walkup_itr_t walkup_end; + + seen_goal_edge = false; + + while (true) + { + + if (walkup_itr != walkup_end && forbidden_edge[*walkup_itr]) + break; + + while(walkup_itr != walkup_end && + !goal_edge[*walkup_itr] && + !forbidden_edge[*walkup_itr] + ) + { + edge_t f(*walkup_itr); + forbidden_edge[f] = true; + path_edges.push_back(f); + current_endpoint = + source(f, g) == current_endpoint ? + target(f, g) : + source(f,g); + ++walkup_itr; + } + + if (walkup_itr != walkup_end && goal_edge[*walkup_itr]) + { + path_edges.push_back(*walkup_itr); + seen_goal_edge = true; + break; + } + + walkup_itr + = walkup_itr_t(current_endpoint, face_handles, first_side()); + + } + + if (seen_goal_edge) + break; + + } + + if (seen_goal_edge) + return current_endpoint; + else + return graph_traits::null_vertex(); + + } + + + + + + + + + template + void extract_kuratowski_subgraph(OutputIterator o_itr, EdgeIndexMap em) + { + + // If the main algorithm has failed to embed one of the back-edges from + // a vertex v, we can use the current state of the algorithm to isolate + // a Kuratowksi subgraph. The isolation process breaks down into five + // cases, A - E. The general configuration of all five cases is shown in + // figure 1. There is a vertex v from which the planar + // v embedding process could not proceed. This means that + // | there exists some bicomp containing three vertices + // ----- x,y, and z as shown such that x and y are externally + // | | active with respect to v (which means that there are + // x y two vertices x_0 and y_0 such that (1) both x_0 and + // | | y_0 are proper depth-first search ancestors of v and + // --z-- (2) there are two disjoint paths, one connecting x + // and x_0 and one connecting y and y_0, both consisting + // fig. 1 entirely of unembedded edges). Furthermore, there + // exists a vertex z_0 such that z is a depth-first + // search ancestor of z_0 and (v,z_0) is an unembedded back-edge from v. + // x,y and z all exist on the same bicomp, which consists entirely of + // embedded edges. The five subcases break down as follows, and are + // handled by the algorithm logically in the order A-E: First, if v is + // not on the same bicomp as x,y, and z, a K_3_3 can be isolated - this + // is case A. So, we'll assume that v is on the same bicomp as x,y, and + // z. If z_0 is on a different bicomp than x,y, and z, a K_3_3 can also + // be isolated - this is a case B - so we'll assume from now on that v + // is on the same bicomp as x, y, and z=z_0. In this case, one can use + // properties of the Boyer-Myrvold algorithm to show the existence of an + // "x-y path" connecting some vertex on the "left side" of the x,y,z + // bicomp with some vertex on the "right side" of the bicomp (where the + // left and right are split by a line drawn through v and z.If either of + // the endpoints of the x-y path is above x or y on the bicomp, a K_3_3 + // can be isolated - this is a case C. Otherwise, both endpoints are at + // or below x and y on the bicomp. If there is a vertex alpha on the x-y + // path such that alpha is not x or y and there's a path from alpha to v + // that's disjoint from any of the edges on the bicomp and the x-y path, + // a K_3_3 can be isolated - this is a case D. Otherwise, properties of + // the Boyer-Myrvold algorithm can be used to show that another vertex + // w exists on the lower half of the bicomp such that w is externally + // active with respect to v. w can then be used to isolate a K_5 - this + // is the configuration of case E. + + vertex_iterator_t vi, vi_end; + edge_iterator_t ei, ei_end; + out_edge_iterator_t oei, oei_end; + typename std::vector::iterator xi, xi_end; + + // Clear the short-circuit edges - these are needed for the planar + // testing/embedding algorithm to run in linear time, but they'll + // complicate the kuratowski subgraph isolation + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + face_handles[*vi].reset_vertex_cache(); + dfs_child_handles[*vi].reset_vertex_cache(); + } + + vertex_t v = kuratowski_v; + vertex_t x = kuratowski_x; + vertex_t y = kuratowski_y; + + typedef iterator_property_map + ::iterator, EdgeIndexMap> + edge_to_bool_map_t; + + std::vector is_in_subgraph_vector(num_edges(g), false); + edge_to_bool_map_t is_in_subgraph(is_in_subgraph_vector.begin(), em); + + std::vector is_embedded_vector(num_edges(g), false); + edge_to_bool_map_t is_embedded(is_embedded_vector.begin(), em); + + typename std::vector::iterator embedded_itr, embedded_end; + embedded_end = embedded_edges.end(); + for(embedded_itr = embedded_edges.begin(); + embedded_itr != embedded_end; ++embedded_itr + ) + is_embedded[*embedded_itr] = true; + + // upper_face_vertex is true for x,y, and all vertices above x and y in + // the bicomp + std::vector upper_face_vertex_vector(num_vertices(g), false); + vertex_to_bool_map_t upper_face_vertex + (upper_face_vertex_vector.begin(), vm); + + std::vector lower_face_vertex_vector(num_vertices(g), false); + vertex_to_bool_map_t lower_face_vertex + (lower_face_vertex_vector.begin(), vm); + + // These next few variable declarations are all things that we need + // to find. + vertex_t z; + vertex_t bicomp_root; + vertex_t w = graph_traits::null_vertex(); + face_handle_t w_handle; + face_handle_t v_dfchild_handle; + vertex_t first_x_y_path_endpoint = graph_traits::null_vertex(); + vertex_t second_x_y_path_endpoint = graph_traits::null_vertex(); + vertex_t w_ancestor = v; + + enum case_t{NO_CASE_CHOSEN, CASE_A, CASE_B, CASE_C, CASE_D, CASE_E}; + case_t chosen_case = NO_CASE_CHOSEN; + + std::vector x_external_path; + std::vector y_external_path; + std::vector case_d_edges; + + std::vector z_v_path; + std::vector w_path; + + //first, use a walkup to find a path from V that starts with a + //backedge from V, then goes up until it hits either X or Y + //(but doesn't find X or Y as the root of a bicomp) + + typename face_vertex_iterator<>::type + x_upper_itr(x, face_handles, first_side()); + typename face_vertex_iterator<>::type + x_lower_itr(x, face_handles, second_side()); + typename face_vertex_iterator<>::type face_itr, face_end; + + // Don't know which path from x is the upper or lower path - + // we'll find out here + for(face_itr = x_upper_itr; face_itr != face_end; ++face_itr) + { + if (*face_itr == y) + { + std::swap(x_upper_itr, x_lower_itr); + break; + } + } + + upper_face_vertex[x] = true; + + vertex_t current_vertex = x; + vertex_t previous_vertex; + for(face_itr = x_upper_itr; face_itr != face_end; ++face_itr) + { + previous_vertex = current_vertex; + current_vertex = *face_itr; + upper_face_vertex[current_vertex] = true; + } + + v_dfchild_handle + = dfs_child_handles[canonical_dfs_child[previous_vertex]]; + + for(face_itr = x_lower_itr; *face_itr != y; ++face_itr) + { + vertex_t current_vertex(*face_itr); + lower_face_vertex[current_vertex] = true; + + typename face_handle_list_t::iterator roots_itr, roots_end; + + if (w == graph_traits::null_vertex()) //haven't found a w yet + { + roots_end = pertinent_roots[current_vertex]->end(); + for(roots_itr = pertinent_roots[current_vertex]->begin(); + roots_itr != roots_end; ++roots_itr + ) + { + if (low_point[canonical_dfs_child[roots_itr->first_vertex()]] + < dfs_number[v] + ) + { + w = current_vertex; + w_handle = *roots_itr; + break; + } + } + } + + } + + for(; face_itr != face_end; ++face_itr) + { + vertex_t current_vertex(*face_itr); + upper_face_vertex[current_vertex] = true; + bicomp_root = current_vertex; + } + + typedef typename face_edge_iterator<>::type walkup_itr_t; + + std::vector outer_face_edge_vector(num_edges(g), false); + edge_to_bool_map_t outer_face_edge(outer_face_edge_vector.begin(), em); + + walkup_itr_t walkup_end; + for(walkup_itr_t walkup_itr(x, face_handles, first_side()); + walkup_itr != walkup_end; ++walkup_itr + ) + { + outer_face_edge[*walkup_itr] = true; + is_in_subgraph[*walkup_itr] = true; + } + + for(walkup_itr_t walkup_itr(x, face_handles, second_side()); + walkup_itr != walkup_end; ++walkup_itr + ) + { + outer_face_edge[*walkup_itr] = true; + is_in_subgraph[*walkup_itr] = true; + } + + std::vector forbidden_edge_vector(num_edges(g), false); + edge_to_bool_map_t forbidden_edge(forbidden_edge_vector.begin(), em); + + std::vector goal_edge_vector(num_edges(g), false); + edge_to_bool_map_t goal_edge(goal_edge_vector.begin(), em); + + + //Find external path to x and to y + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_t e(*ei); + goal_edge[e] + = !outer_face_edge[e] && (source(e,g) == x || target(e,g) == x); + forbidden_edge[*ei] = outer_face_edge[*ei]; + } + + vertex_t x_ancestor = v; + vertex_t x_endpoint = graph_traits::null_vertex(); + + while(x_endpoint == graph_traits::null_vertex()) + { + x_ancestor = dfs_parent[x_ancestor]; + x_endpoint = kuratowski_walkup(x_ancestor, + forbidden_edge, + goal_edge, + is_embedded, + x_external_path + ); + + } + + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_t e(*ei); + goal_edge[e] + = !outer_face_edge[e] && (source(e,g) == y || target(e,g) == y); + forbidden_edge[*ei] = outer_face_edge[*ei]; + } + + vertex_t y_ancestor = v; + vertex_t y_endpoint = graph_traits::null_vertex(); + + while(y_endpoint == graph_traits::null_vertex()) + { + y_ancestor = dfs_parent[y_ancestor]; + y_endpoint = kuratowski_walkup(y_ancestor, + forbidden_edge, + goal_edge, + is_embedded, + y_external_path + ); + + } + + + vertex_t parent, child; + + //If v isn't on the same bicomp as x and y, it's a case A + if (bicomp_root != v) + { + chosen_case = CASE_A; + + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + if (lower_face_vertex[*vi]) + for(tie(oei,oei_end) = out_edges(*vi,g); oei != oei_end; ++oei) + if(!outer_face_edge[*oei]) + goal_edge[*oei] = true; + + for(tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) + forbidden_edge[*ei] = outer_face_edge[*ei]; + + z = kuratowski_walkup + (v, forbidden_edge, goal_edge, is_embedded, z_v_path); + + } + else if (w != graph_traits::null_vertex()) + { + chosen_case = CASE_B; + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_t e(*ei); + goal_edge[e] = false; + forbidden_edge[e] = outer_face_edge[e]; + } + + goal_edge[w_handle.first_edge()] = true; + goal_edge[w_handle.second_edge()] = true; + + z = kuratowski_walkup(v, + forbidden_edge, + goal_edge, + is_embedded, + z_v_path + ); + + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + forbidden_edge[*ei] = outer_face_edge[*ei]; + } + + typename std::vector::iterator pi, pi_end; + pi_end = z_v_path.end(); + for(pi = z_v_path.begin(); pi != pi_end; ++pi) + { + goal_edge[*pi] = true; + } + + w_ancestor = v; + vertex_t w_endpoint = graph_traits::null_vertex(); + + while(w_endpoint == graph_traits::null_vertex()) + { + w_ancestor = dfs_parent[w_ancestor]; + w_endpoint = kuratowski_walkup(w_ancestor, + forbidden_edge, + goal_edge, + is_embedded, + w_path + ); + + } + + // We really want both the w walkup and the z walkup to finish on + // exactly the same edge, but for convenience (since we don't have + // control over which side of a bicomp a walkup moves up) we've + // defined the walkup to either end at w_handle.first_edge() or + // w_handle.second_edge(). If both walkups ended at different edges, + // we'll do a little surgery on the w walkup path to make it follow + // the other side of the final bicomp. + + if ((w_path.back() == w_handle.first_edge() && + z_v_path.back() == w_handle.second_edge()) + || + (w_path.back() == w_handle.second_edge() && + z_v_path.back() == w_handle.first_edge()) + ) + { + walkup_itr_t wi, wi_end; + edge_t final_edge = w_path.back(); + vertex_t anchor + = source(final_edge, g) == w_handle.get_anchor() ? + target(final_edge, g) : source(final_edge, g); + if (face_handles[anchor].first_edge() == final_edge) + wi = walkup_itr_t(anchor, face_handles, second_side()); + else + wi = walkup_itr_t(anchor, face_handles, first_side()); + + w_path.pop_back(); + + for(; wi != wi_end; ++wi) + { + edge_t e(*wi); + if (w_path.back() == e) + w_path.pop_back(); + else + w_path.push_back(e); + } + } + + + } + else + { + + //We need to find a valid z, since the x-y path re-defines the lower + //face, and the z we found earlier may now be on the upper face. + + chosen_case = CASE_E; + + + // The z we've used so far is just an externally active vertex on the + // lower face path, but may not be the z we need for a case C, D, or + // E subgraph. the z we need now is any externally active vertex on + // the lower face path with both old_face_handles edges on the outer + // face. Since we know an x-y path exists, such a z must also exist. + + //TODO: find this z in the first place. + + //find the new z + + for(face_itr = x_lower_itr; *face_itr != y; ++face_itr) + { + vertex_t possible_z(*face_itr); + if (pertinent(possible_z,v) && + outer_face_edge[face_handles[possible_z].old_first_edge()] && + outer_face_edge[face_handles[possible_z].old_second_edge()] + ) + { + z = possible_z; + break; + } + } + + //find x-y path, and a w if one exists. + + if (externally_active(z,v)) + w = z; + + + typedef typename face_edge_iterator + ::type old_face_iterator_t; + + old_face_iterator_t + first_old_face_itr(z, face_handles, first_side()); + old_face_iterator_t + second_old_face_itr(z, face_handles, second_side()); + old_face_iterator_t old_face_itr, old_face_end; + + std::vector old_face_iterators; + old_face_iterators.push_back(first_old_face_itr); + old_face_iterators.push_back(second_old_face_itr); + + std::vector x_y_path_vertex_vector(num_vertices(g), false); + vertex_to_bool_map_t x_y_path_vertex + (x_y_path_vertex_vector.begin(), vm); + + typename std::vector::iterator + of_itr, of_itr_end; + of_itr_end = old_face_iterators.end(); + for(of_itr = old_face_iterators.begin(); + of_itr != of_itr_end; ++of_itr + ) + { + + old_face_itr = *of_itr; + + vertex_t previous_vertex; + bool seen_x_or_y = false; + vertex_t current_vertex = z; + for(; old_face_itr != old_face_end; ++old_face_itr) + { + edge_t e(*old_face_itr); + previous_vertex = current_vertex; + current_vertex = source(e,g) == current_vertex ? + target(e,g) : source(e,g); + + if (current_vertex == x || current_vertex == y) + seen_x_or_y = true; + + if (w == graph_traits::null_vertex() && + externally_active(current_vertex,v) && + outer_face_edge[e] && + outer_face_edge[*next(old_face_itr)] && + !seen_x_or_y + ) + { + w = current_vertex; + } + + if (!outer_face_edge[e]) + { + if (!upper_face_vertex[current_vertex] && + !lower_face_vertex[current_vertex] + ) + { + x_y_path_vertex[current_vertex] = true; + } + + is_in_subgraph[e] = true; + if (upper_face_vertex[source(e,g)] || + lower_face_vertex[source(e,g)] + ) + { + if (first_x_y_path_endpoint == + graph_traits::null_vertex() + ) + first_x_y_path_endpoint = source(e,g); + else + second_x_y_path_endpoint = source(e,g); + } + if (upper_face_vertex[target(e,g)] || + lower_face_vertex[target(e,g)] + ) + { + if (first_x_y_path_endpoint == + graph_traits::null_vertex() + ) + first_x_y_path_endpoint = target(e,g); + else + second_x_y_path_endpoint = target(e,g); + } + + + } + else if (previous_vertex == x || previous_vertex == y) + { + chosen_case = CASE_C; + } + + } + + } + + // Look for a case D - one of v's embedded edges will connect to the + // x-y path along an inner face path. + + //First, get a list of all of v's embedded child edges + + out_edge_iterator_t v_edge_itr, v_edge_end; + for(tie(v_edge_itr,v_edge_end) = out_edges(v,g); + v_edge_itr != v_edge_end; ++v_edge_itr + ) + { + edge_t embedded_edge(*v_edge_itr); + + if (!is_embedded[embedded_edge] || + embedded_edge == dfs_parent_edge[v] + ) + continue; + + case_d_edges.push_back(embedded_edge); + + vertex_t current_vertex + = source(embedded_edge,g) == v ? + target(embedded_edge,g) : source(embedded_edge,g); + + typename face_edge_iterator<>::type + internal_face_itr, internal_face_end; + if (face_handles[current_vertex].first_vertex() == v) + { + internal_face_itr = typename face_edge_iterator<>::type + (current_vertex, face_handles, second_side()); + } + else + { + internal_face_itr = typename face_edge_iterator<>::type + (current_vertex, face_handles, first_side()); + } + + while(internal_face_itr != internal_face_end && + !outer_face_edge[*internal_face_itr] && + !x_y_path_vertex[current_vertex] + ) + { + edge_t e(*internal_face_itr); + case_d_edges.push_back(e); + current_vertex = + source(e,g) == current_vertex ? target(e,g) : source(e,g); + ++internal_face_itr; + } + + if (x_y_path_vertex[current_vertex]) + { + chosen_case = CASE_D; + break; + } + else + { + case_d_edges.clear(); + } + + } + + + } + + + + + if (chosen_case != CASE_B && chosen_case != CASE_A) + { + + //Finding z and w. + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + edge_t e(*ei); + goal_edge[e] = !outer_face_edge[e] && + (source(e,g) == z || target(e,g) == z); + forbidden_edge[e] = outer_face_edge[e]; + } + + kuratowski_walkup(v, + forbidden_edge, + goal_edge, + is_embedded, + z_v_path + ); + + if (chosen_case == CASE_E) + { + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + forbidden_edge[*ei] = outer_face_edge[*ei]; + goal_edge[*ei] = !outer_face_edge[*ei] && + (source(*ei,g) == w || target(*ei,g) == w); + } + + for(tie(oei, oei_end) = out_edges(w,g); oei != oei_end; ++oei) + { + if (!outer_face_edge[*oei]) + goal_edge[*oei] = true; + } + + typename std::vector::iterator pi, pi_end; + pi_end = z_v_path.end(); + for(pi = z_v_path.begin(); pi != pi_end; ++pi) + { + goal_edge[*pi] = true; + } + + w_ancestor = v; + vertex_t w_endpoint = graph_traits::null_vertex(); + + while(w_endpoint == graph_traits::null_vertex()) + { + w_ancestor = dfs_parent[w_ancestor]; + w_endpoint = kuratowski_walkup(w_ancestor, + forbidden_edge, + goal_edge, + is_embedded, + w_path + ); + + } + + } + + + } + + + //We're done isolating the Kuratowski subgraph at this point - + //but there's still some cleaning up to do. + + //Update is_in_subgraph with the paths we just found + + xi_end = x_external_path.end(); + for(xi = x_external_path.begin(); xi != xi_end; ++xi) + is_in_subgraph[*xi] = true; + + xi_end = y_external_path.end(); + for(xi = y_external_path.begin(); xi != xi_end; ++xi) + is_in_subgraph[*xi] = true; + + xi_end = z_v_path.end(); + for(xi = z_v_path.begin(); xi != xi_end; ++xi) + is_in_subgraph[*xi] = true; + + xi_end = case_d_edges.end(); + for(xi = case_d_edges.begin(); xi != xi_end; ++xi) + is_in_subgraph[*xi] = true; + + xi_end = w_path.end(); + for(xi = w_path.begin(); xi != xi_end; ++xi) + is_in_subgraph[*xi] = true; + + child = bicomp_root; + parent = dfs_parent[child]; + while(child != parent) + { + is_in_subgraph[dfs_parent_edge[child]] = true; + tie(parent, child) = std::make_pair( dfs_parent[parent], parent ); + } + + + + + // At this point, we've already isolated the Kuratowski subgraph and + // collected all of the edges that compose it in the is_in_subgraph + // property map. But we want the verification of such a subgraph to be + // a deterministic process, and we can simplify the function + // is_kuratowski_subgraph by cleaning up some edges here. + + if (chosen_case == CASE_B) + { + is_in_subgraph[dfs_parent_edge[v]] = false; + } + else if (chosen_case == CASE_C) + { + // In a case C subgraph, at least one of the x-y path endpoints + // (call it alpha) is above either x or y on the outer face. The + // other endpoint may be attached at x or y OR above OR below. In + // any of these three cases, we can form a K_3_3 by removing the + // edge attached to v on the outer face that is NOT on the path to + // alpha. + + typename face_vertex_iterator::type + face_itr, face_end; + if (face_handles[v_dfchild_handle.first_vertex()].first_edge() == + v_dfchild_handle.first_edge() + ) + { + face_itr = typename face_vertex_iterator + ::type + (v_dfchild_handle.first_vertex(), face_handles, second_side()); + } + else + { + face_itr = typename face_vertex_iterator + ::type + (v_dfchild_handle.first_vertex(), face_handles, first_side()); + } + + for(; true; ++face_itr) + { + vertex_t current_vertex(*face_itr); + if (current_vertex == x || current_vertex == y) + { + is_in_subgraph[v_dfchild_handle.first_edge()] = false; + break; + } + else if (current_vertex == first_x_y_path_endpoint || + current_vertex == second_x_y_path_endpoint) + { + is_in_subgraph[v_dfchild_handle.second_edge()] = false; + break; + } + } + + } + else if (chosen_case == CASE_D) + { + // Need to remove both of the edges adjacent to v on the outer face. + // remove the connecting edges from v to bicomp, then + // is_kuratowski_subgraph will shrink vertices of degree 1 + // automatically... + + is_in_subgraph[v_dfchild_handle.first_edge()] = false; + is_in_subgraph[v_dfchild_handle.second_edge()] = false; + + } + else if (chosen_case == CASE_E) + { + // Similarly to case C, if the endpoints of the x-y path are both + // below x and y, we should remove an edge to allow the subgraph to + // contract to a K_3_3. + + + if ((first_x_y_path_endpoint != x && first_x_y_path_endpoint != y) || + (second_x_y_path_endpoint != x && second_x_y_path_endpoint != y) + ) + { + is_in_subgraph[dfs_parent_edge[v]] = false; + + vertex_t deletion_endpoint, other_endpoint; + if (lower_face_vertex[first_x_y_path_endpoint]) + { + deletion_endpoint = second_x_y_path_endpoint; + other_endpoint = first_x_y_path_endpoint; + } + else + { + deletion_endpoint = first_x_y_path_endpoint; + other_endpoint = second_x_y_path_endpoint; + } + + typename face_edge_iterator<>::type face_itr, face_end; + + bool found_other_endpoint = false; + for(face_itr = typename face_edge_iterator<>::type + (deletion_endpoint, face_handles, first_side()); + face_itr != face_end; ++face_itr + ) + { + edge_t e(*face_itr); + if (source(e,g) == other_endpoint || + target(e,g) == other_endpoint + ) + { + found_other_endpoint = true; + break; + } + } + + if (found_other_endpoint) + { + is_in_subgraph[face_handles[deletion_endpoint].first_edge()] + = false; + } + else + { + is_in_subgraph[face_handles[deletion_endpoint].second_edge()] + = false; + } + } + + } + + + for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + if (is_in_subgraph[*ei]) + *o_itr = *ei; + + } + + + + template + void make_edge_permutation(EdgePermutation perm) + { + vertex_iterator_t vi, vi_end; + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_t v(*vi); + perm[v].clear(); + face_handles[v].get_list(std::back_inserter(perm[v])); + } + } + + + private: + + const Graph& g; + VertexIndexMap vm; + + vertex_t kuratowski_v; + vertex_t kuratowski_x; + vertex_t kuratowski_y; + + vertex_list_t garbage; // we delete items from linked lists by + // splicing them into garbage + + //only need these two for kuratowski subgraph isolation + std::vector current_merge_points; + std::vector embedded_edges; + + //property map storage + std::vector low_point_vector; + std::vector dfs_parent_vector; + std::vector dfs_number_vector; + std::vector least_ancestor_vector; + std::vector pertinent_roots_vector; + std::vector backedge_flag_vector; + std::vector visited_vector; + std::vector< face_handle_t > face_handles_vector; + std::vector< face_handle_t > dfs_child_handles_vector; + std::vector< vertex_list_ptr_t > separated_dfs_child_list_vector; + std::vector< typename vertex_list_t::iterator > + separated_node_in_parent_list_vector; + std::vector canonical_dfs_child_vector; + std::vector flipped_vector; + std::vector backedges_vector; + edge_vector_t self_loops; + std::vector dfs_parent_edge_vector; + vertex_vector_t vertices_by_dfs_num; + + //property maps + vertex_to_v_size_map_t low_point; + vertex_to_vertex_map_t dfs_parent; + vertex_to_v_size_map_t dfs_number; + vertex_to_v_size_map_t least_ancestor; + vertex_to_face_handle_list_ptr_map_t pertinent_roots; + vertex_to_v_size_map_t backedge_flag; + vertex_to_v_size_map_t visited; + vertex_to_face_handle_map_t face_handles; + vertex_to_face_handle_map_t dfs_child_handles; + vertex_to_vertex_list_ptr_map_t separated_dfs_child_list; + vertex_to_separated_node_map_t separated_node_in_parent_list; + vertex_to_vertex_map_t canonical_dfs_child; + vertex_to_bool_map_t flipped; + vertex_to_edge_vector_map_t backedges; + vertex_to_edge_map_t dfs_parent_edge; //only need for kuratowski + + merge_stack_t merge_stack; + + }; + + +} //namespace boost + +#endif //__BOYER_MYRVOLD_IMPL_HPP__ diff --git a/thirdparty/boost/graph/planar_detail/bucket_sort.hpp b/thirdparty/boost/graph/planar_detail/bucket_sort.hpp new file mode 100644 index 0000000..f656ccb --- /dev/null +++ b/thirdparty/boost/graph/planar_detail/bucket_sort.hpp @@ -0,0 +1,144 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __BUCKET_SORT_HPP__ +#define __BUCKET_SORT_HPP__ + +#include +#include +#include + + + +namespace boost +{ + + + template + struct rank_comparison + { + rank_comparison(ItemToRankMap arg_itrm) : itrm(arg_itrm) {} + + template + bool operator() (Item x, Item y) const + { + return get(itrm, x) < get(itrm, y); + } + + private: + ItemToRankMap itrm; + + }; + + + template + struct property_map_tuple_adaptor : + public put_get_helper< typename PropertyMapWrapper::value_type, + property_map_tuple_adaptor + + > + { + typedef typename PropertyMapWrapper::reference reference; + typedef typename PropertyMapWrapper::value_type value_type; + typedef TupleType key_type; + typedef readable_property_map_tag category; + + property_map_tuple_adaptor() {} + + property_map_tuple_adaptor(PropertyMapWrapper wrapper_map) : + m_wrapper_map(wrapper_map) + {} + + inline value_type operator[](const key_type& x) const + { + return get(m_wrapper_map, get(x)); + } + + static const int n = N; + PropertyMapWrapper m_wrapper_map; + + }; + + + + + // This function sorts a sequence of n items by their ranks in linear time, + // given that all ranks are in the range [0, range). This sort is stable. + template + void bucket_sort(ForwardIterator begin, + ForwardIterator end, + ItemToRankMap rank, + SizeType range = 0) + { +#ifdef BOOST_GRAPH_PREFER_STD_LIB + std::stable_sort(begin, end, rank_comparison(rank)); +#else + typedef std::vector + < typename boost::property_traits::key_type > + vector_of_values_t; + typedef std::vector< vector_of_values_t > vector_of_vectors_t; + + if (!range) + { + rank_comparison cmp(rank); + ForwardIterator max_by_rank = std::max_element(begin, end, cmp); + if (max_by_rank == end) + return; + range = get(rank, *max_by_rank) + 1; + } + + vector_of_vectors_t temp_values(range); + + for(ForwardIterator itr = begin; itr != end; ++itr) + { + temp_values[get(rank, *itr)].push_back(*itr); + } + + ForwardIterator orig_seq_itr = begin; + typename vector_of_vectors_t::iterator itr_end = temp_values.end(); + for(typename vector_of_vectors_t::iterator itr = temp_values.begin(); + itr != itr_end; ++itr + ) + { + typename vector_of_values_t::iterator jtr_end = itr->end(); + for(typename vector_of_values_t::iterator jtr = itr->begin(); + jtr != jtr_end; ++jtr + ) + { + *orig_seq_itr = *jtr; + ++orig_seq_itr; + } + } +#endif + } + + + template + void bucket_sort(ForwardIterator begin, + ForwardIterator end, + ItemToRankMap rank) + { + bucket_sort(begin, end, rank, 0); + } + + template + void bucket_sort(ForwardIterator begin, + ForwardIterator end + ) + { + bucket_sort(begin, end, identity_property_map()); + } + + +} //namespace boost + + +#endif //__BUCKET_SORT_HPP__ diff --git a/thirdparty/boost/graph/planar_detail/face_handles.hpp b/thirdparty/boost/graph/planar_detail/face_handles.hpp new file mode 100644 index 0000000..81c8cce --- /dev/null +++ b/thirdparty/boost/graph/planar_detail/face_handles.hpp @@ -0,0 +1,497 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= + +#ifndef __FACE_HANDLES_HPP__ +#define __FACE_HANDLES_HPP__ + + +#include +#include +#include + + +// A "face handle" is an optimization meant to serve two purposes in +// the implementation of the Boyer-Myrvold planarity test: (1) it holds +// the partial planar embedding of a particular vertex as it's being +// constructed, and (2) it allows for efficient traversal around the +// outer face of the partial embedding at that particular vertex. A face +// handle is lightweight, just a shared pointer to the actual implementation, +// since it is passed around/copied liberally in the algorithm. It consists +// of an "anchor" (the actual vertex it's associated with) as well as a +// sequence of edges. The functions first_vertex/second_vertex and +// first_edge/second_edge allow fast access to the beginning and end of the +// stored sequence, which allows one to traverse the outer face of the partial +// planar embedding as it's being created. +// +// There are some policies below that define the contents of the face handles: +// in the case no embedding is needed (for example, if one just wants to use +// the Boyer-Myrvold algorithm as a true/false test for planarity, the +// no_embedding class can be passed as the StoreEmbedding policy. Otherwise, +// either std_list (which uses as std::list) or recursive_lazy_list can be +// passed as this policy. recursive_lazy_list has the best theoretical +// performance (O(n) for a sequence of interleaved concatenations and reversals +// of the underlying list), but I've noticed little difference between std_list +// and recursive_lazy_list in my tests, even though using std_list changes +// the worst-case complexity of the planarity test to O(n^2) +// +// Another policy is StoreOldHandlesPolicy, which specifies whether or not +// to keep a record of the previous first/second vertex/edge - this is needed +// if a Kuratowski subgraph needs to be isolated. + + +namespace boost { namespace graph { namespace detail { + + + //face handle policies + + //EmbeddingStorage policy + struct store_embedding {}; + struct recursive_lazy_list : public store_embedding {}; + struct std_list : public store_embedding {}; + struct no_embedding {}; + + //StoreOldHandlesPolicy + struct store_old_handles {}; + struct no_old_handles {}; + + + + + template + struct lazy_list_node + { + typedef shared_ptr< lazy_list_node > ptr_t; + + lazy_list_node(const DataType& data) : + m_reversed(false), + m_data(data), + m_has_data(true) + {} + + lazy_list_node(ptr_t left_child, ptr_t right_child) : + m_reversed(false), + m_has_data(false), + m_left_child(left_child), + m_right_child(right_child) + {} + + bool m_reversed; + DataType m_data; + bool m_has_data; + shared_ptr m_left_child; + shared_ptr m_right_child; + }; + + + + template + struct old_handles_storage; + + template + struct old_handles_storage + { + Vertex first_vertex; + Vertex second_vertex; + Edge first_edge; + Edge second_edge; + }; + + template + struct old_handles_storage + {}; + + + + + + + template + struct edge_list_storage; + + + + + + template + struct edge_list_storage + { + typedef void type; + + void push_back(Edge) {} + void push_front(Edge) {} + void reverse() {} + void concat_front(edge_list_storage) {} + void concat_back(edge_list_storage) {} + template + void get_list(OutputIterator) {} + }; + + + + + + template + struct edge_list_storage + { + typedef lazy_list_node node_type; + typedef shared_ptr< node_type > type; + type value; + + void push_back(Edge e) + { + type new_node(new node_type(e)); + value = type(new node_type(value, new_node)); + } + + void push_front(Edge e) + { + type new_node(new node_type(e)); + value = type(new node_type(new_node, value)); + } + + void reverse() + { + value->m_reversed = !value->m_reversed; + } + + void concat_front(edge_list_storage other) + { + value = type(new node_type(other.value, value)); + } + + void concat_back(edge_list_storage other) + { + value = type(new node_type(value, other.value)); + } + + template + void get_list(OutputIterator out) + { + get_list_helper(out, value); + } + + private: + + template + void get_list_helper(OutputIterator o_itr, + type root, + bool flipped = false + ) + { + if (!root) + return; + + if (root->m_has_data) + *o_itr = root->m_data; + + if ((flipped && !root->m_reversed) || + (!flipped && root->m_reversed) + ) + { + get_list_helper(o_itr, root->m_right_child, true); + get_list_helper(o_itr, root->m_left_child, true); + } + else + { + get_list_helper(o_itr, root->m_left_child, false); + get_list_helper(o_itr, root->m_right_child, false); + } + + } + + }; + + + + + + template + struct edge_list_storage + { + typedef std::list type; + type value; + + void push_back(Edge e) + { + value.push_back(e); + } + + void push_front(Edge e) + { + value.push_front(e); + } + + void reverse() + { + value.reverse(); + } + + void concat_front(edge_list_storage other) + { + value.splice(value.begin(), other.value); + } + + void concat_back(edge_list_storage other) + { + value.splice(value.end(), other.value); + } + + template + void get_list(OutputIterator out) + { + std::copy(value.begin(), value.end(), out); + } + + }; + + + + + + + + template + struct face_handle_impl + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename edge_list_storage::type + edge_list_storage_t; + + + face_handle_impl() : + cached_first_vertex(graph_traits::null_vertex()), + cached_second_vertex(graph_traits::null_vertex()), + true_first_vertex(graph_traits::null_vertex()), + true_second_vertex(graph_traits::null_vertex()), + anchor(graph_traits::null_vertex()) + { + initialize_old_vertices_dispatch(StoreOldHandlesPolicy()); + } + + void initialize_old_vertices_dispatch(store_old_handles) + { + old_handles.first_vertex = graph_traits::null_vertex(); + old_handles.second_vertex = graph_traits::null_vertex(); + } + + void initialize_old_vertices_dispatch(no_old_handles) {} + + vertex_t cached_first_vertex; + vertex_t cached_second_vertex; + vertex_t true_first_vertex; + vertex_t true_second_vertex; + vertex_t anchor; + edge_t cached_first_edge; + edge_t cached_second_edge; + + edge_list_storage edge_list; + old_handles_storage old_handles; + + }; + + + + + + + + + + + + template + class face_handle + { + public: + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef face_handle_impl + impl_t; + typedef face_handle + self_t; + + face_handle(vertex_t anchor = graph_traits::null_vertex()) : + pimpl(new impl_t()) + { + pimpl->anchor = anchor; + } + + face_handle(vertex_t anchor, edge_t initial_edge, const Graph& g) : + pimpl(new impl_t()) + { + vertex_t s(source(initial_edge,g)); + vertex_t t(target(initial_edge,g)); + vertex_t other_vertex = s == anchor ? t : s; + pimpl->anchor = anchor; + pimpl->cached_first_edge = initial_edge; + pimpl->cached_second_edge = initial_edge; + pimpl->cached_first_vertex = other_vertex; + pimpl->cached_second_vertex = other_vertex; + pimpl->true_first_vertex = other_vertex; + pimpl->true_second_vertex = other_vertex; + + pimpl->edge_list.push_back(initial_edge); + store_old_face_handles_dispatch(StoreOldHandlesPolicy()); + } + + //default copy construction, assignment okay. + + void push_first(edge_t e, const Graph& g) + { + pimpl->edge_list.push_front(e); + pimpl->cached_first_vertex = pimpl->true_first_vertex = + source(e, g) == pimpl->anchor ? target(e,g) : source(e,g); + pimpl->cached_first_edge = e; + } + + void push_second(edge_t e, const Graph& g) + { + pimpl->edge_list.push_back(e); + pimpl->cached_second_vertex = pimpl->true_second_vertex = + source(e, g) == pimpl->anchor ? target(e,g) : source(e,g); + pimpl->cached_second_edge = e; + } + + inline void store_old_face_handles() + { + store_old_face_handles_dispatch(StoreOldHandlesPolicy()); + } + + inline vertex_t first_vertex() const + { + return pimpl->cached_first_vertex; + } + + inline vertex_t second_vertex() const + { + return pimpl->cached_second_vertex; + } + + inline vertex_t true_first_vertex() const + { + return pimpl->true_first_vertex; + } + + inline vertex_t true_second_vertex() const + { + return pimpl->true_second_vertex; + } + + inline vertex_t old_first_vertex() const + { + return pimpl->old_handles.first_vertex; + } + + inline vertex_t old_second_vertex() const + { + return pimpl->old_handles.second_vertex; + } + + inline edge_t old_first_edge() const + { + return pimpl->old_handles.first_edge; + } + + inline edge_t old_second_edge() const + { + return pimpl->old_handles.second_edge; + } + + inline edge_t first_edge() const + { + return pimpl->cached_first_edge; + } + + inline edge_t second_edge() const + { + return pimpl->cached_second_edge; + } + + inline vertex_t get_anchor() const + { + return pimpl->anchor; + } + + void glue_first_to_second + (face_handle& bottom) + { + pimpl->edge_list.concat_front(bottom.pimpl->edge_list); + pimpl->true_first_vertex = bottom.pimpl->true_first_vertex; + pimpl->cached_first_vertex = bottom.pimpl->cached_first_vertex; + pimpl->cached_first_edge = bottom.pimpl->cached_first_edge; + } + + void glue_second_to_first + (face_handle& bottom) + { + pimpl->edge_list.concat_back(bottom.pimpl->edge_list); + pimpl->true_second_vertex = bottom.pimpl->true_second_vertex; + pimpl->cached_second_vertex = bottom.pimpl->cached_second_vertex; + pimpl->cached_second_edge = bottom.pimpl->cached_second_edge; + } + + void flip() + { + pimpl->edge_list.reverse(); + std::swap(pimpl->true_first_vertex, pimpl->true_second_vertex); + std::swap(pimpl->cached_first_vertex, pimpl->cached_second_vertex); + std::swap(pimpl->cached_first_edge, pimpl->cached_second_edge); + } + + template + void get_list(OutputIterator o_itr) + { + pimpl->edge_list.get_list(o_itr); + } + + void reset_vertex_cache() + { + pimpl->cached_first_vertex = pimpl->true_first_vertex; + pimpl->cached_second_vertex = pimpl->true_second_vertex; + } + + inline void set_first_vertex(vertex_t v) + { + pimpl->cached_first_vertex = v; + } + + inline void set_second_vertex(vertex_t v) + { + pimpl->cached_second_vertex = v; + } + + private: + + void store_old_face_handles_dispatch(store_old_handles) + { + pimpl->old_handles.first_vertex = pimpl->true_first_vertex; + pimpl->old_handles.second_vertex = pimpl->true_second_vertex; + pimpl->old_handles.first_edge = pimpl->cached_first_edge; + pimpl->old_handles.second_edge = pimpl->cached_second_edge; + } + + void store_old_face_handles_dispatch(no_old_handles) {} + + + + boost::shared_ptr pimpl; + + }; + + +} /* namespace detail */ } /* namespace graph */ } /* namespace boost */ + + +#endif //__FACE_HANDLES_HPP__ diff --git a/thirdparty/boost/graph/planar_detail/face_iterators.hpp b/thirdparty/boost/graph/planar_detail/face_iterators.hpp new file mode 100644 index 0000000..b4007d9 --- /dev/null +++ b/thirdparty/boost/graph/planar_detail/face_iterators.hpp @@ -0,0 +1,375 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= + +#ifndef __FACE_ITERATORS_HPP__ +#define __FACE_ITERATORS_HPP__ + +#include +#include +#include + +namespace boost +{ + + //tags for defining traversal properties + + //VisitorType + struct lead_visitor {}; + struct follow_visitor {}; + + //TraversalType + struct single_side {}; + struct both_sides {}; + + //TraversalSubType + struct first_side {}; //for single_side + struct second_side {}; //for single_side + struct alternating {}; //for both_sides + + //Time + struct current_iteration {}; + struct previous_iteration {}; + + // Why TraversalType AND TraversalSubType? TraversalSubType is a function + // template parameter passed in to the constructor of the face iterator, + // whereas TraversalType is a class template parameter. This lets us decide + // at runtime whether to move along the first or second side of a bicomp (by + // assigning a face_iterator that has been constructed with TraversalSubType + // = first_side or second_side to a face_iterator variable) without any of + // the virtual function overhead that comes with implementing this + // functionality as a more structured form of type erasure. It also allows + // a single face_iterator to be the end iterator of two iterators traversing + // both sides of a bicomp. + + //ValueType is either graph_traits::vertex_descriptor + //or graph_traits::edge_descriptor + + + //forward declaration (defining defaults) + template + class face_iterator; + + + + template + struct edge_storage + {}; + + template + struct edge_storage + { + typename graph_traits::edge_descriptor value; + }; + + + + + //specialization for TraversalType = traverse_vertices + template + + class face_iterator + : public boost::iterator_facade < face_iterator, + ValueType, + boost::forward_traversal_tag, + ValueType + > + { + public: + + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef face_iterator + self; + typedef typename FaceHandlesMap::value_type face_handle_t; + + face_iterator() : + m_lead(graph_traits::null_vertex()), + m_follow(graph_traits::null_vertex()) + {} + + template + face_iterator(face_handle_t anchor_handle, + FaceHandlesMap face_handles, + TraversalSubType traversal_type): + m_follow(anchor_handle.get_anchor()), + m_face_handles(face_handles) + { + set_lead_dispatch(anchor_handle, traversal_type); + } + + template + face_iterator(vertex_t anchor, + FaceHandlesMap face_handles, + TraversalSubType traversal_type): + m_follow(anchor), + m_face_handles(face_handles) + { + set_lead_dispatch(m_face_handles[anchor], traversal_type); + } + + private: + + friend class boost::iterator_core_access; + + + + + inline vertex_t get_first_vertex(face_handle_t anchor_handle, + current_iteration + ) + { + return anchor_handle.first_vertex(); + } + + inline vertex_t get_second_vertex(face_handle_t anchor_handle, + current_iteration + ) + { + return anchor_handle.second_vertex(); + } + + inline vertex_t get_first_vertex(face_handle_t anchor_handle, + previous_iteration + ) + { + return anchor_handle.old_first_vertex(); + } + + inline vertex_t get_second_vertex(face_handle_t anchor_handle, + previous_iteration + ) + { + return anchor_handle.old_second_vertex(); + } + + + + + + inline void set_lead_dispatch(face_handle_t anchor_handle, first_side) + { + m_lead = get_first_vertex(anchor_handle, Time()); + set_edge_to_first_dispatch(anchor_handle, ValueType(), Time()); + } + + inline void set_lead_dispatch(face_handle_t anchor_handle, second_side) + { + m_lead = get_second_vertex(anchor_handle, Time()); + set_edge_to_second_dispatch(anchor_handle, ValueType(), Time()); + } + + + + + + inline void set_edge_to_first_dispatch(face_handle_t anchor_handle, + edge_t, + current_iteration + ) + { + m_edge.value = anchor_handle.first_edge(); + } + + inline void set_edge_to_second_dispatch(face_handle_t anchor_handle, + edge_t, + current_iteration + ) + { + m_edge.value = anchor_handle.second_edge(); + } + + inline void set_edge_to_first_dispatch(face_handle_t anchor_handle, + edge_t, + previous_iteration + ) + { + m_edge.value = anchor_handle.old_first_edge(); + } + + inline void set_edge_to_second_dispatch(face_handle_t anchor_handle, + edge_t, + previous_iteration + ) + { + m_edge.value = anchor_handle.old_second_edge(); + } + + template + inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T) + {} + + template + inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T) + {} + + void increment() + { + face_handle_t curr_face_handle(m_face_handles[m_lead]); + vertex_t first = get_first_vertex(curr_face_handle, Time()); + vertex_t second = get_second_vertex(curr_face_handle, Time()); + if (first == m_follow) + { + m_follow = m_lead; + set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time()); + m_lead = second; + } + else if (second == m_follow) + { + m_follow = m_lead; + set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time()); + m_lead = first; + } + else + m_lead = m_follow = graph_traits::null_vertex(); + } + + bool equal(self const& other) const + { + return m_lead == other.m_lead && m_follow == other.m_follow; + } + + ValueType dereference() const + { + return dereference_dispatch(VisitorType(), ValueType()); + } + + inline ValueType dereference_dispatch(lead_visitor, vertex_t) const + { return m_lead; } + + inline ValueType dereference_dispatch(follow_visitor, vertex_t) const + { return m_follow; } + + inline ValueType dereference_dispatch(lead_visitor, edge_t) const + { return m_edge.value; } + + inline ValueType dereference_dispatch(follow_visitor, edge_t) const + { return m_edge.value; } + + vertex_t m_lead; + vertex_t m_follow; + edge_storage::value > m_edge; + FaceHandlesMap m_face_handles; + }; + + + + + + + + + + template + class face_iterator + + : public boost::iterator_facade< face_iterator, + ValueType, + boost::forward_traversal_tag, + ValueType > + { + public: + + typedef face_iterator + self; + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename FaceHandlesMap::value_type face_handle_t; + + face_iterator() {} + + face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles): + first_itr(anchor_handle, face_handles, first_side()), + second_itr(anchor_handle, face_handles, second_side()), + first_is_active(true), + first_increment(true) + {} + + face_iterator(vertex_t anchor, FaceHandlesMap face_handles): + first_itr(face_handles[anchor], face_handles, first_side()), + second_itr(face_handles[anchor], face_handles, second_side()), + first_is_active(true), + first_increment(true) + {} + + private: + + friend class boost::iterator_core_access; + + typedef face_iterator + + inner_itr_t; + + void increment() + { + if (first_increment) + { + ++first_itr; + ++second_itr; + first_increment = false; + } + else if (first_is_active) + ++first_itr; + else + ++second_itr; + first_is_active = !first_is_active; + } + + bool equal(self const& other) const + { + //Want this iterator to be equal to the "end" iterator when at least + //one of the iterators has reached the root of the current bicomp. + //This isn't ideal, but it works. + + return (first_itr == other.first_itr || second_itr == other.second_itr); + } + + ValueType dereference() const + { + return first_is_active ? *first_itr : *second_itr; + } + + inner_itr_t first_itr; + inner_itr_t second_itr; + inner_itr_t face_end; + bool first_is_active; + bool first_increment; + + }; + + +} /* namespace boost */ + + +#endif //__FACE_ITERATORS_HPP__ diff --git a/thirdparty/boost/graph/planar_face_traversal.hpp b/thirdparty/boost/graph/planar_face_traversal.hpp new file mode 100644 index 0000000..eaa7c37 --- /dev/null +++ b/thirdparty/boost/graph/planar_face_traversal.hpp @@ -0,0 +1,210 @@ +//======================================================================= +// Copyright (c) Aaron Windsor 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) +//======================================================================= + +#ifndef __PLANAR_FACE_TRAVERSAL_HPP__ +#define __PLANAR_FACE_TRAVERSAL_HPP__ + +#include +#include //for next and prior +#include + + +namespace boost +{ + + + + + struct planar_face_traversal_visitor + { + void begin_traversal() + {} + + void begin_face() + {} + + template + void next_edge(Edge e) + {} + + template + void next_vertex(Vertex v) + {} + + void end_face() + {} + + void end_traversal() + {} + + }; + + + + + + template + void planar_face_traversal(const Graph& g, + PlanarEmbedding embedding, + Visitor& visitor, EdgeIndexMap em + ) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits::edge_descriptor edge_t; + typedef typename graph_traits::vertex_iterator vertex_iterator_t; + typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename + property_traits::value_type embedding_value_t; + typedef typename embedding_value_t::const_iterator embedding_iterator_t; + + typedef typename + std::vector< std::set > distinguished_edge_storage_t; + typedef typename + std::vector< std::map > + distinguished_edge_to_edge_storage_t; + + typedef typename + boost::iterator_property_map + + distinguished_edge_map_t; + + typedef typename + boost::iterator_property_map + + distinguished_edge_to_edge_map_t; + + distinguished_edge_storage_t visited_vector(num_edges(g)); + distinguished_edge_to_edge_storage_t next_edge_vector(num_edges(g)); + + distinguished_edge_map_t visited(visited_vector.begin(), em); + distinguished_edge_to_edge_map_t next_edge(next_edge_vector.begin(), em); + + vertex_iterator_t vi, vi_end; + typename std::vector::iterator ei, ei_end; + edge_iterator_t fi, fi_end; + embedding_iterator_t pi, pi_begin, pi_end; + + visitor.begin_traversal(); + + // Initialize the next_edge property map. This map is initialized from the + // PlanarEmbedding so that get(next_edge, e)[v] is the edge that comes + // after e in the clockwise embedding around vertex v. + + for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_t v(*vi); + pi_begin = embedding[v].begin(); + pi_end = embedding[v].end(); + for(pi = pi_begin; pi != pi_end; ++pi) + { + edge_t e(*pi); + std::map m = get(next_edge, e); + m[v] = next(pi) == pi_end ? *pi_begin : *next(pi); + put(next_edge, e, m); + } + } + + // Take a copy of the edges in the graph here, since we want to accomodate + // face traversals that add edges to the graph (for triangulation, in + // particular) and don't want to use invalidated edge iterators. + // Also, while iterating over all edges in the graph, we single out + // any self-loops, which need some special treatment in the face traversal. + + std::vector self_loops; + std::vector edges_cache; + std::vector vertices_in_edge; + + for(tie(fi,fi_end) = edges(g); fi != fi_end; ++fi) + { + edge_t e(*fi); + edges_cache.push_back(e); + if (source(e,g) == target(e,g)) + self_loops.push_back(e); + } + + + // Iterate over all edges in the graph + ei_end = edges_cache.end(); + for(ei = edges_cache.begin(); ei != ei_end; ++ei) + { + + edge_t e(*ei); + vertices_in_edge.clear(); + vertices_in_edge.push_back(source(e,g)); + vertices_in_edge.push_back(target(e,g)); + + typename std::vector::iterator vi, vi_end; + vi_end = vertices_in_edge.end(); + + //Iterate over both vertices in the current edge + for(vi = vertices_in_edge.begin(); vi != vi_end; ++vi) + { + + vertex_t v(*vi); + std::set e_visited = get(visited, e); + typename std::set::iterator e_visited_found + = e_visited.find(v); + + if (e_visited_found == e_visited.end()) + visitor.begin_face(); + + while (e_visited.find(v) == e_visited.end()) + { + visitor.next_vertex(v); + visitor.next_edge(e); + e_visited.insert(v); + put(visited, e, e_visited); + v = source(e,g) == v ? target(e,g) : source(e,g); + e = get(next_edge, e)[v]; + e_visited = get(visited, e); + } + + if (e_visited_found == e_visited.end()) + visitor.end_face(); + + } + + } + + // Iterate over all self-loops, visiting them once separately + // (they've already been visited once, this visitation is for + // the "inside" of the self-loop) + + ei_end = self_loops.end(); + for(ei = self_loops.begin(); ei != ei_end; ++ei) + { + visitor.begin_face(); + visitor.next_edge(*ei); + visitor.next_vertex(source(*ei,g)); + visitor.end_face(); + } + + visitor.end_traversal(); + + } + + + + template + inline void planar_face_traversal(const Graph& g, + PlanarEmbedding embedding, + Visitor& visitor + ) + { + planar_face_traversal(g, embedding, visitor, get(edge_index, g)); + } + + + + +} //namespace boost + +#endif //__PLANAR_FACE_TRAVERSAL_HPP__ diff --git a/thirdparty/boost/graph/plod_generator.hpp b/thirdparty/boost/graph/plod_generator.hpp new file mode 100644 index 0000000..9277b3d --- /dev/null +++ b/thirdparty/boost/graph/plod_generator.hpp @@ -0,0 +1,161 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_PLOD_GENERATOR_HPP +#define BOOST_GRAPH_PLOD_GENERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + template + class plod_iterator + { + typedef std::vector > out_degrees_t; + typedef typename graph_traits::directed_category directed_category; + + public: + typedef std::input_iterator_tag iterator_category; + typedef std::pair value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef void difference_type; + + plod_iterator() + : gen(0), out_degrees(), degrees_left(0), allow_self_loops(false) { } + + plod_iterator(RandomGenerator& gen, std::size_t n, + double alpha, double beta, bool allow_self_loops = false) + : gen(&gen), n(n), out_degrees(new out_degrees_t), + degrees_left(0), allow_self_loops(allow_self_loops) + { + using std::pow; + + uniform_int x(0, n-1); + for (std::size_t i = 0; i != n; ++i) { + std::size_t xv = x(gen); + std::size_t degree = (xv == 0? 0 : std::size_t(beta * pow(xv, -alpha))); + if (degree != 0) { + out_degrees->push_back(std::make_pair(i, degree)); + } + degrees_left += degree; + } + + next(directed_category()); + } + + reference operator*() const { return current; } + pointer operator->() const { return ¤t; } + + plod_iterator& operator++() + { + next(directed_category()); + return *this; + } + + plod_iterator operator++(int) + { + plod_iterator temp(*this); + ++(*this); + return temp; + } + + bool operator==(const plod_iterator& other) const + { + return degrees_left == other.degrees_left; + } + + bool operator!=(const plod_iterator& other) const + { return !(*this == other); } + + private: + void next(directed_tag) + { + uniform_int x(0, out_degrees->size()-1); + std::size_t source; + do { + source = x(*gen); + } while ((*out_degrees)[source].second == 0); + current.first = (*out_degrees)[source].first; + do { + current.second = x(*gen); + } while (current.first == current.second && !allow_self_loops); + --degrees_left; + if (--(*out_degrees)[source].second == 0) { + (*out_degrees)[source] = out_degrees->back(); + out_degrees->pop_back(); + } + } + + void next(undirected_tag) + { + std::size_t source, target; + while (true) { + /* We may get to the point where we can't actually find any + new edges, so we just add some random edge and set the + degrees left = 0 to signal termination. */ + if (out_degrees->size() < 2) { + uniform_int x(0, n); + current.first = x(*gen); + do { + current.second = x(*gen); + } while (current.first == current.second && !allow_self_loops); + degrees_left = 0; + out_degrees->clear(); + return; + } + + uniform_int x(0, out_degrees->size()-1); + + // Select source vertex + source = x(*gen); + if ((*out_degrees)[source].second == 0) { + (*out_degrees)[source] = out_degrees->back(); + out_degrees->pop_back(); + continue; + } + + // Select target vertex + target = x(*gen); + if ((*out_degrees)[target].second == 0) { + (*out_degrees)[target] = out_degrees->back(); + out_degrees->pop_back(); + continue; + } else if (source != target + || (allow_self_loops && (*out_degrees)[source].second > 2)) { + break; + } + } + + // Update degree counts + --(*out_degrees)[source].second; + --degrees_left; + --(*out_degrees)[target].second; + --degrees_left; + current.first = (*out_degrees)[source].first; + current.second = (*out_degrees)[target].first; + } + + RandomGenerator* gen; + std::size_t n; + shared_ptr out_degrees; + std::size_t degrees_left; + bool allow_self_loops; + value_type current; + }; + +} // end namespace boost + +#endif // BOOST_GRAPH_PLOD_GENERATOR_HPP diff --git a/thirdparty/boost/graph/prim_minimum_spanning_tree.hpp b/thirdparty/boost/graph/prim_minimum_spanning_tree.hpp new file mode 100644 index 0000000..58e0b6a --- /dev/null +++ b/thirdparty/boost/graph/prim_minimum_spanning_tree.hpp @@ -0,0 +1,91 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_MST_PRIM_HPP +#define BOOST_GRAPH_MST_PRIM_HPP + +#include +#include +#include + +namespace boost { + + namespace detail { + // this should be somewhere else in boost... + template struct _project2nd { + V operator()(U, V v) const { return v; } + }; + } + + namespace detail { + + // This is Prim's algorithm to calculate the Minimum Spanning Tree + // for an undirected graph with weighted edges. + + template + inline void + prim_mst_impl(const Graph& G, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params, + Weight) + { + typedef typename property_traits::value_type W; + std::less compare; + detail::_project2nd combine; + dijkstra_shortest_paths(G, s, params.distance_compare(compare). + distance_combine(combine)); + } + } // namespace detail + + template + inline void + prim_minimum_spanning_tree + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + DijkstraVisitor vis) + { + typedef typename property_traits::value_type W; + std::less compare; + detail::_project2nd combine; + dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map, + compare, combine, (std::numeric_limits::max)(), 0, + vis); + } + + template + inline void prim_minimum_spanning_tree + (const VertexListGraph& g, + PredecessorMap p_map, + const bgl_named_params& params) + { + detail::prim_mst_impl + (g, + choose_param(get_param(params, root_vertex_t()), *vertices(g).first), + params.predecessor_map(p_map), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); + } + + template + inline void prim_minimum_spanning_tree + (const VertexListGraph& g, PredecessorMap p_map) + { + detail::prim_mst_impl + (g, *vertices(g).first, predecessor_map(p_map). + weight_map(get(edge_weight, g)), + get(edge_weight, g)); + } + +} // namespace boost + +#endif // BOOST_GRAPH_MST_PRIM_HPP diff --git a/thirdparty/boost/graph/profile.hpp b/thirdparty/boost/graph/profile.hpp new file mode 100644 index 0000000..b9c21fa --- /dev/null +++ b/thirdparty/boost/graph/profile.hpp @@ -0,0 +1,43 @@ +// +//======================================================================= +// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch) +// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_GRAPH_PROFILE_HPP +#define BOOST_GRAPH_PROFILE_HPP + +#include +#include +#include + +namespace boost { + + template + typename graph_traits::vertices_size_type + profile(const Graph& g, VertexIndexMap index) + { + typename graph_traits::vertices_size_type b = 0; + typename graph_traits::vertex_iterator i, end; + for (tie(i, end) = vertices(g); i != end; ++i){ + b += ith_bandwidth(*i, g, index) + 1; + } + + return b; + } + + template + typename graph_traits::vertices_size_type + profile(const Graph& g) + { + return profile(g, get(vertex_index, g)); + } + + +} // namespace boost + +#endif // BOOST_GRAPH_PROFILE_HPP diff --git a/thirdparty/boost/graph/properties.hpp b/thirdparty/boost/graph/properties.hpp new file mode 100644 index 0000000..98ca1ec --- /dev/null +++ b/thirdparty/boost/graph/properties.hpp @@ -0,0 +1,389 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_PROPERTIES_HPP +#define BOOST_GRAPH_PROPERTIES_HPP + +#include +#include +#include +#include +#include +#include + + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# define Graph Graph_ +# define RandomAccessContainer RandomAccessContainer_ +#endif + +namespace boost { + + enum default_color_type { white_color, gray_color, green_color, red_color, black_color }; + + template + struct color_traits { + static default_color_type white() { return white_color; } + static default_color_type gray() { return gray_color; } + static default_color_type green() { return green_color; } + static default_color_type red() { return red_color; } + static default_color_type black() { return black_color; } + }; + + // These functions are now obsolete, replaced by color_traits. + inline default_color_type white(default_color_type) { return white_color; } + inline default_color_type gray(default_color_type) { return gray_color; } + inline default_color_type green(default_color_type) { return green_color; } + inline default_color_type red(default_color_type) { return red_color; } + inline default_color_type black(default_color_type) { return black_color; } + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template <> + struct property_traits { + typedef default_color_type value_type; + typedef std::ptrdiff_t key_type; + typedef default_color_type& reference; + typedef lvalue_property_map_tag category; + }; + // get/put already defined for T* +#endif + + struct graph_property_tag { }; + struct vertex_property_tag { }; + struct edge_property_tag { }; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // See examples/edge_property.cpp for how to use this. +#define BOOST_INSTALL_PROPERTY(KIND, NAME) \ + template <> struct property_kind { \ + typedef KIND##_property_tag type; \ + } +#else +#define BOOST_INSTALL_PROPERTY(KIND, NAME) \ + template <> struct property_kind { \ + typedef KIND##_property_tag type; \ + } +#endif + +#define BOOST_DEF_PROPERTY(KIND, NAME) \ + enum KIND##_##NAME##_t { KIND##_##NAME }; \ + BOOST_INSTALL_PROPERTY(KIND, NAME) + + BOOST_DEF_PROPERTY(vertex, all); + BOOST_DEF_PROPERTY(edge, all); + BOOST_DEF_PROPERTY(graph, all); + BOOST_DEF_PROPERTY(vertex, index); + BOOST_DEF_PROPERTY(vertex, index1); + BOOST_DEF_PROPERTY(vertex, index2); + BOOST_DEF_PROPERTY(vertex, root); + BOOST_DEF_PROPERTY(edge, index); + BOOST_DEF_PROPERTY(edge, name); + BOOST_DEF_PROPERTY(edge, weight); + BOOST_DEF_PROPERTY(edge, weight2); + BOOST_DEF_PROPERTY(edge, color); + BOOST_DEF_PROPERTY(vertex, name); + BOOST_DEF_PROPERTY(graph, name); + BOOST_DEF_PROPERTY(vertex, distance); + BOOST_DEF_PROPERTY(vertex, color); + BOOST_DEF_PROPERTY(vertex, degree); + BOOST_DEF_PROPERTY(vertex, in_degree); + BOOST_DEF_PROPERTY(vertex, out_degree); + BOOST_DEF_PROPERTY(vertex, current_degree); + BOOST_DEF_PROPERTY(vertex, priority); + BOOST_DEF_PROPERTY(vertex, discover_time); + BOOST_DEF_PROPERTY(vertex, finish_time); + BOOST_DEF_PROPERTY(vertex, predecessor); + BOOST_DEF_PROPERTY(vertex, rank); + BOOST_DEF_PROPERTY(vertex, centrality); + BOOST_DEF_PROPERTY(vertex, lowpoint); + BOOST_DEF_PROPERTY(edge, reverse); + BOOST_DEF_PROPERTY(edge, capacity); + BOOST_DEF_PROPERTY(edge, residual_capacity); + BOOST_DEF_PROPERTY(edge, centrality); + BOOST_DEF_PROPERTY(graph, visitor); + + // These tags are used for property bundles + BOOST_DEF_PROPERTY(vertex, bundle); + BOOST_DEF_PROPERTY(edge, bundle); + +#undef BOOST_DEF_PROPERTY + + namespace detail { + + struct dummy_edge_property_selector { + template + struct bind_ { + typedef identity_property_map type; + typedef identity_property_map const_type; + }; + }; + struct dummy_vertex_property_selector { + template + struct bind_ { + typedef identity_property_map type; + typedef identity_property_map const_type; + }; + }; + + } // namespace detail + + // Graph classes can either partially specialize property_map + // or they can specialize these two selector classes. + template + struct edge_property_selector { + typedef detail::dummy_edge_property_selector type; + }; + + template + struct vertex_property_selector { + typedef detail::dummy_vertex_property_selector type; + }; + + namespace detail { + + template + struct edge_property_map { + typedef typename Graph::edge_property_type Property; + typedef typename Graph::graph_tag graph_tag; + typedef typename edge_property_selector::type Selector; + typedef typename Selector::template bind_ + Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + template + class vertex_property_map { + typedef typename Graph::vertex_property_type Property; + typedef typename Graph::graph_tag graph_tag; + typedef typename vertex_property_selector::type Selector; + typedef typename Selector::template bind_ + Bind; + public: + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + + // This selects the kind of property map, whether is maps from + // edges or from vertices. + // + // It is overly complicated because it's a workaround for + // partial specialization. + struct choose_vertex_property_map { + template + struct bind_ { + typedef vertex_property_map type; + }; + }; + struct choose_edge_property_map { + template + struct bind_ { + typedef edge_property_map type; + }; + }; + template + struct property_map_kind_selector { + // VC++ gets confused if this isn't defined, even though + // this never gets used. + typedef choose_vertex_property_map type; + }; + template <> struct property_map_kind_selector { + typedef choose_vertex_property_map type; + }; + template <> struct property_map_kind_selector { + typedef choose_edge_property_map type; + }; + } // namespace detail + + template + struct property_map { + private: + typedef typename property_kind::type Kind; + typedef typename detail::property_map_kind_selector::type Selector; + typedef typename Selector::template bind_ Bind; + typedef typename Bind::type Map; + public: + typedef typename Map::type type; + typedef typename Map::const_type const_type; + }; + + // shortcut for accessing the value type of the property map + template + class property_map_value { + typedef typename property_map::const_type PMap; + public: + typedef typename property_traits::value_type type; + }; + + template + class graph_property { + public: + typedef typename property_value::type type; + }; + + template + class vertex_property { + public: + typedef typename Graph::vertex_property_type type; + }; + template + class edge_property { + public: + typedef typename Graph::edge_property_type type; + }; + + template + class degree_property_map + : public put_get_helper::degree_size_type, + degree_property_map > + { + public: + typedef typename graph_traits::vertex_descriptor key_type; + typedef typename graph_traits::degree_size_type value_type; + typedef value_type reference; + typedef readable_property_map_tag category; + degree_property_map(const Graph& g) : m_g(g) { } + value_type operator[](const key_type& v) const { + return degree(v, m_g); + } + private: + const Graph& m_g; + }; + template + inline degree_property_map + make_degree_map(const Graph& g) { + return degree_property_map(g); + } + + //======================================================================== + // Iterator Property Map Generating Functions contributed by + // Kevin Vanhorn. (see also the property map generating functions + // in boost/property_map.hpp) + +#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) + // A helper function for creating a vertex property map out of a + // random access iterator and the internal vertex index map from a + // graph. + template + inline + iterator_property_map< + RandomAccessIterator, + typename property_map::type, + typename std::iterator_traits::value_type, + typename std::iterator_traits::reference + > + make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g) + { + return make_iterator_property_map(iter, get(vertex_index, g)); + } + + // Use this next function when vertex_descriptor is known to be an + // integer type, with values ranging from 0 to num_vertices(g). + // + template + inline + iterator_property_map< + RandomAccessIterator, + identity_property_map, + typename std::iterator_traits::value_type, + typename std::iterator_traits::reference + > + make_iterator_vertex_map(RandomAccessIterator iter) + { + return make_iterator_property_map(iter, identity_property_map()); + } +#endif + + template + inline + iterator_property_map< + typename RandomAccessContainer::iterator, + typename property_map::type, + typename RandomAccessContainer::value_type, + typename RandomAccessContainer::reference + > + make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g) + { + assert(c.size() >= num_vertices(g)); + return make_iterator_vertex_map(c.begin(), g); + } + + template inline + iterator_property_map< + typename RandomAccessContainer::iterator, + identity_property_map, + typename RandomAccessContainer::value_type, + typename RandomAccessContainer::reference + > + make_container_vertex_map(RandomAccessContainer& c) + { + return make_iterator_vertex_map(c.begin()); + } + +#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES +#endif + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct bundle_property_map + : put_get_helper > + { + typedef Descriptor key_type; + typedef T value_type; + typedef T& reference; + typedef lvalue_property_map_tag category; + + bundle_property_map() { } + bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {} + + reference operator[](key_type k) const { return (*g)[k].*pm; } + private: + Graph* g; + T Bundle::* pm; + }; + + namespace detail { + template + struct is_vertex_bundle : is_convertible {}; + } + + template + struct property_map + { + private: + typedef graph_traits traits; + typedef typename Graph::vertex_bundled vertex_bundled; + typedef typename Graph::edge_bundled edge_bundled; + typedef typename mpl::if_c<(detail::is_vertex_bundle::value), + typename traits::vertex_descriptor, + typename traits::edge_descriptor>::type + descriptor; + typedef typename mpl::if_c<(detail::is_vertex_bundle::value), + vertex_bundled, + edge_bundled>::type + actual_bundle; + + public: + typedef bundle_property_map type; + typedef bundle_property_map + const_type; + }; +#endif + +} // namespace boost + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# undef Graph +# undef RandomAccessIterator +#endif + + +#endif /* BOOST_GRAPH_PROPERTIES_HPPA */ diff --git a/thirdparty/boost/graph/property_iter_range.hpp b/thirdparty/boost/graph/property_iter_range.hpp new file mode 100644 index 0000000..1c4570c --- /dev/null +++ b/thirdparty/boost/graph/property_iter_range.hpp @@ -0,0 +1,118 @@ + +// (C) Copyright François Faure, iMAGIS-GRAVIR / UJF, 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) +// +// Revision History: +// 03 May 2001 Jeremy Siek +// Generalized the property map iterator and moved that +// part to boost/property_map.hpp. Also modified to +// differentiate between const/mutable graphs and +// added a workaround to avoid partial specialization. + +// 02 May 2001 François Faure +// Initial version. + +#ifndef BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP +#define BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP + +#include +#include +#include +#include + +namespace boost { + +//====================================================================== +// graph property iterator range + + template + class graph_property_iter_range { + typedef typename property_map::type map_type; + typedef typename property_map::const_type + const_map_type; + typedef typename property_kind::type Kind; + typedef typename mpl::if_c::value, + typename graph_traits::vertex_iterator, + typename graph_traits::edge_iterator>::type iter; + public: + typedef typename property_map_iterator_generator::type + iterator; + typedef typename property_map_iterator_generator + ::type const_iterator; + typedef std::pair type; + typedef std::pair const_type; + }; + + namespace detail { + + template + typename graph_property_iter_range::type + get_property_iter_range_kind(Graph& graph, const Tag& tag, + const vertex_property_tag& ) + { + typedef typename graph_property_iter_range::iterator iter; + return std::make_pair(iter(vertices(graph).first, get(tag, graph)), + iter(vertices(graph).second, get(tag, graph))); + } + + template + typename graph_property_iter_range::const_type + get_property_iter_range_kind(const Graph& graph, const Tag& tag, + const vertex_property_tag& ) + { + typedef typename graph_property_iter_range + ::const_iterator iter; + return std::make_pair(iter(vertices(graph).first, get(tag, graph)), + iter(vertices(graph).second, get(tag, graph))); + } + + + template + typename graph_property_iter_range::type + get_property_iter_range_kind(Graph& graph, const Tag& tag, + const edge_property_tag& ) + { + typedef typename graph_property_iter_range::iterator iter; + return std::make_pair(iter(edges(graph).first, get(tag, graph)), + iter(edges(graph).second, get(tag, graph))); + } + + template + typename graph_property_iter_range::const_type + get_property_iter_range_kind(const Graph& graph, const Tag& tag, + const edge_property_tag& ) + { + typedef typename graph_property_iter_range + ::const_iterator iter; + return std::make_pair(iter(edges(graph).first, get(tag, graph)), + iter(edges(graph).second, get(tag, graph))); + } + + } // namespace detail + + //====================================================================== + // get an iterator range of properties + + template + typename graph_property_iter_range::type + get_property_iter_range(Graph& graph, const Tag& tag) + { + typedef typename property_kind::type Kind; + return detail::get_property_iter_range_kind(graph, tag, Kind()); + } + + template + typename graph_property_iter_range::const_type + get_property_iter_range(const Graph& graph, const Tag& tag) + { + typedef typename property_kind::type Kind; + return detail::get_property_iter_range_kind(graph, tag, Kind()); + } + +} // namespace boost + + +#endif // BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP diff --git a/thirdparty/boost/graph/push_relabel_max_flow.hpp b/thirdparty/boost/graph/push_relabel_max_flow.hpp new file mode 100644 index 0000000..64cbbd8 --- /dev/null +++ b/thirdparty/boost/graph/push_relabel_max_flow.hpp @@ -0,0 +1,727 @@ +//======================================================================= +// Copyright 2000 University of Notre Dame. +// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_PUSH_RELABEL_MAX_FLOW_HPP +#define BOOST_PUSH_RELABEL_MAX_FLOW_HPP + +#include +#include +#include +#include +#include +#include // for std::min and std::max + +#include +#include +#include +#include + +namespace boost { + + namespace detail { + + // This implementation is based on Goldberg's + // "On Implementing Push-Relabel Method for the Maximum Flow Problem" + // by B.V. Cherkassky and A.V. Goldberg, IPCO '95, pp. 157--171 + // and on the h_prf.c and hi_pr.c code written by the above authors. + + // This implements the highest-label version of the push-relabel method + // with the global relabeling and gap relabeling heuristics. + + // The terms "rank", "distance", "height" are synonyms in + // Goldberg's implementation, paper and in the CLR. A "layer" is a + // group of vertices with the same distance. The vertices in each + // layer are categorized as active or inactive. An active vertex + // has positive excess flow and its distance is less than n (it is + // not blocked). + + template + struct preflow_layer { + std::list active_vertices; + std::list inactive_vertices; + }; + + template integer + class FlowValue> + class push_relabel + { + public: + typedef graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::vertex_iterator vertex_iterator; + typedef typename Traits::out_edge_iterator out_edge_iterator; + typedef typename Traits::vertices_size_type vertices_size_type; + typedef typename Traits::edges_size_type edges_size_type; + + typedef preflow_layer Layer; + typedef std::vector< Layer > LayerArray; + typedef typename LayerArray::iterator layer_iterator; + typedef typename LayerArray::size_type distance_size_type; + + typedef color_traits ColorTraits; + + //======================================================================= + // Some helper predicates + + inline bool is_admissible(vertex_descriptor u, vertex_descriptor v) { + return distance[u] == distance[v] + 1; + } + inline bool is_residual_edge(edge_descriptor a) { + return 0 < residual_capacity[a]; + } + inline bool is_saturated(edge_descriptor a) { + return residual_capacity[a] == 0; + } + + //======================================================================= + // Layer List Management Functions + + typedef typename std::list::iterator list_iterator; + + void add_to_active_list(vertex_descriptor u, Layer& layer) { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + layer.active_vertices.push_front(u); + max_active = max BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], max_active); + min_active = min BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], min_active); + layer_list_ptr[u] = layer.active_vertices.begin(); + } + void remove_from_active_list(vertex_descriptor u) { + layers[distance[u]].active_vertices.erase(layer_list_ptr[u]); + } + + void add_to_inactive_list(vertex_descriptor u, Layer& layer) { + layer.inactive_vertices.push_front(u); + layer_list_ptr[u] = layer.inactive_vertices.begin(); + } + void remove_from_inactive_list(vertex_descriptor u) { + layers[distance[u]].inactive_vertices.erase(layer_list_ptr[u]); + } + + //======================================================================= + // initialization + push_relabel(Graph& g_, + EdgeCapacityMap cap, + ResidualCapacityEdgeMap res, + ReverseEdgeMap rev, + vertex_descriptor src_, + vertex_descriptor sink_, + VertexIndexMap idx) + : g(g_), n(num_vertices(g_)), capacity(cap), src(src_), sink(sink_), + index(idx), + excess_flow(num_vertices(g_)), + current(num_vertices(g_), out_edges(*vertices(g_).first, g_).second), + distance(num_vertices(g_)), + color(num_vertices(g_)), + reverse_edge(rev), + residual_capacity(res), + layers(num_vertices(g_)), + layer_list_ptr(num_vertices(g_), + layers.front().inactive_vertices.end()), + push_count(0), update_count(0), relabel_count(0), + gap_count(0), gap_node_count(0), + work_since_last_update(0) + { + vertex_iterator u_iter, u_end; + // Don't count the reverse edges + edges_size_type m = num_edges(g) / 2; + nm = alpha() * n + m; + + // Initialize flow to zero which means initializing + // the residual capacity to equal the capacity. + out_edge_iterator ei, e_end; + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) { + residual_capacity[*ei] = capacity[*ei]; + } + + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + vertex_descriptor u = *u_iter; + excess_flow[u] = 0; + current[u] = out_edges(u, g).first; + } + + bool overflow_detected = false; + FlowValue test_excess = 0; + + out_edge_iterator a_iter, a_end; + for (tie(a_iter, a_end) = out_edges(src, g); a_iter != a_end; ++a_iter) + if (target(*a_iter, g) != src) + test_excess += residual_capacity[*a_iter]; + if (test_excess > (std::numeric_limits::max)()) + overflow_detected = true; + + if (overflow_detected) + excess_flow[src] = (std::numeric_limits::max)(); + else { + excess_flow[src] = 0; + for (tie(a_iter, a_end) = out_edges(src, g); + a_iter != a_end; ++a_iter) { + edge_descriptor a = *a_iter; + if (target(a, g) != src) { + ++push_count; + FlowValue delta = residual_capacity[a]; + residual_capacity[a] -= delta; + residual_capacity[reverse_edge[a]] += delta; + excess_flow[target(a, g)] += delta; + } + } + } + max_distance = num_vertices(g) - 1; + max_active = 0; + min_active = n; + + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + vertex_descriptor u = *u_iter; + if (u == sink) { + distance[u] = 0; + continue; + } else if (u == src && !overflow_detected) + distance[u] = n; + else + distance[u] = 1; + + if (excess_flow[u] > 0) + add_to_active_list(u, layers[1]); + else if (distance[u] < n) + add_to_inactive_list(u, layers[1]); + } + + } // push_relabel constructor + + //======================================================================= + // This is a breadth-first search over the residual graph + // (well, actually the reverse of the residual graph). + // Would be cool to have a graph view adaptor for hiding certain + // edges, like the saturated (non-residual) edges in this case. + // Goldberg's implementation abused "distance" for the coloring. + void global_distance_update() + { + BOOST_USING_STD_MAX(); + ++update_count; + vertex_iterator u_iter, u_end; + for (tie(u_iter,u_end) = vertices(g); u_iter != u_end; ++u_iter) { + color[*u_iter] = ColorTraits::white(); + distance[*u_iter] = n; + } + color[sink] = ColorTraits::gray(); + distance[sink] = 0; + + for (distance_size_type l = 0; l <= max_distance; ++l) { + layers[l].active_vertices.clear(); + layers[l].inactive_vertices.clear(); + } + + max_distance = max_active = 0; + min_active = n; + + Q.push(sink); + while (! Q.empty()) { + vertex_descriptor u = Q.top(); + Q.pop(); + distance_size_type d_v = distance[u] + 1; + + out_edge_iterator ai, a_end; + for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) { + edge_descriptor a = *ai; + vertex_descriptor v = target(a, g); + if (color[v] == ColorTraits::white() + && is_residual_edge(reverse_edge[a])) { + distance[v] = d_v; + color[v] = ColorTraits::gray(); + current[v] = out_edges(v, g).first; + max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(d_v, max_distance); + + if (excess_flow[v] > 0) + add_to_active_list(v, layers[d_v]); + else + add_to_inactive_list(v, layers[d_v]); + + Q.push(v); + } + } + } + } // global_distance_update() + + //======================================================================= + // This function is called "push" in Goldberg's h_prf implementation, + // but it is called "discharge" in the paper and in hi_pr.c. + void discharge(vertex_descriptor u) + { + assert(excess_flow[u] > 0); + while (1) { + out_edge_iterator ai, ai_end; + for (ai = current[u], ai_end = out_edges(u, g).second; + ai != ai_end; ++ai) { + edge_descriptor a = *ai; + if (is_residual_edge(a)) { + vertex_descriptor v = target(a, g); + if (is_admissible(u, v)) { + ++push_count; + if (v != sink && excess_flow[v] == 0) { + remove_from_inactive_list(v); + add_to_active_list(v, layers[distance[v]]); + } + push_flow(a); + if (excess_flow[u] == 0) + break; + } + } + } // for out_edges of i starting from current + + Layer& layer = layers[distance[u]]; + distance_size_type du = distance[u]; + + if (ai == ai_end) { // i must be relabeled + relabel_distance(u); + if (layer.active_vertices.empty() + && layer.inactive_vertices.empty()) + gap(du); + if (distance[u] == n) + break; + } else { // i is no longer active + current[u] = ai; + add_to_inactive_list(u, layer); + break; + } + } // while (1) + } // discharge() + + //======================================================================= + // This corresponds to the "push" update operation of the paper, + // not the "push" function in Goldberg's h_prf.c implementation. + // The idea is to push the excess flow from from vertex u to v. + void push_flow(edge_descriptor u_v) + { + vertex_descriptor + u = source(u_v, g), + v = target(u_v, g); + + BOOST_USING_STD_MIN(); + FlowValue flow_delta + = min BOOST_PREVENT_MACRO_SUBSTITUTION(excess_flow[u], residual_capacity[u_v]); + + residual_capacity[u_v] -= flow_delta; + residual_capacity[reverse_edge[u_v]] += flow_delta; + + excess_flow[u] -= flow_delta; + excess_flow[v] += flow_delta; + } // push_flow() + + //======================================================================= + // The main purpose of this routine is to set distance[v] + // to the smallest value allowed by the valid labeling constraints, + // which are: + // distance[t] = 0 + // distance[u] <= distance[v] + 1 for every residual edge (u,v) + // + distance_size_type relabel_distance(vertex_descriptor u) + { + BOOST_USING_STD_MAX(); + ++relabel_count; + work_since_last_update += beta(); + + distance_size_type min_distance = num_vertices(g); + distance[u] = min_distance; + + // Examine the residual out-edges of vertex i, choosing the + // edge whose target vertex has the minimal distance. + out_edge_iterator ai, a_end, min_edge_iter; + for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) { + ++work_since_last_update; + edge_descriptor a = *ai; + vertex_descriptor v = target(a, g); + if (is_residual_edge(a) && distance[v] < min_distance) { + min_distance = distance[v]; + min_edge_iter = ai; + } + } + ++min_distance; + if (min_distance < n) { + distance[u] = min_distance; // this is the main action + current[u] = min_edge_iter; + max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(min_distance, max_distance); + } + return min_distance; + } // relabel_distance() + + //======================================================================= + // cleanup beyond the gap + void gap(distance_size_type empty_distance) + { + ++gap_count; + + distance_size_type r; // distance of layer before the current layer + r = empty_distance - 1; + + // Set the distance for the vertices beyond the gap to "infinity". + for (layer_iterator l = layers.begin() + empty_distance + 1; + l < layers.begin() + max_distance; ++l) { + list_iterator i; + for (i = l->inactive_vertices.begin(); + i != l->inactive_vertices.end(); ++i) { + distance[*i] = n; + ++gap_node_count; + } + l->inactive_vertices.clear(); + } + max_distance = r; + max_active = r; + } + + //======================================================================= + // This is the core part of the algorithm, "phase one". + FlowValue maximum_preflow() + { + work_since_last_update = 0; + + while (max_active >= min_active) { // "main" loop + + Layer& layer = layers[max_active]; + list_iterator u_iter = layer.active_vertices.begin(); + + if (u_iter == layer.active_vertices.end()) + --max_active; + else { + vertex_descriptor u = *u_iter; + remove_from_active_list(u); + + discharge(u); + + if (work_since_last_update * global_update_frequency() > nm) { + global_distance_update(); + work_since_last_update = 0; + } + } + } // while (max_active >= min_active) + + return excess_flow[sink]; + } // maximum_preflow() + + //======================================================================= + // remove excess flow, the "second phase" + // This does a DFS on the reverse flow graph of nodes with excess flow. + // If a cycle is found, cancel it. + // Return the nodes with excess flow in topological order. + // + // Unlike the prefl_to_flow() implementation, we use + // "color" instead of "distance" for the DFS labels + // "parent" instead of nl_prev for the DFS tree + // "topo_next" instead of nl_next for the topological ordering + void convert_preflow_to_flow() + { + vertex_iterator u_iter, u_end; + out_edge_iterator ai, a_end; + + vertex_descriptor r, restart, u; + + std::vector parent(n); + std::vector topo_next(n); + + vertex_descriptor tos(parent[0]), + bos(parent[0]); // bogus initialization, just to avoid warning + bool bos_null = true; + + // handle self-loops + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai) + if (target(*ai, g) == *u_iter) + residual_capacity[*ai] = capacity[*ai]; + + // initialize + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + u = *u_iter; + color[u] = ColorTraits::white(); + parent[u] = u; + current[u] = out_edges(u, g).first; + } + // eliminate flow cycles and topologically order the vertices + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + u = *u_iter; + if (color[u] == ColorTraits::white() + && excess_flow[u] > 0 + && u != src && u != sink ) { + r = u; + color[r] = ColorTraits::gray(); + while (1) { + for (; current[u] != out_edges(u, g).second; ++current[u]) { + edge_descriptor a = *current[u]; + if (capacity[a] == 0 && is_residual_edge(a)) { + vertex_descriptor v = target(a, g); + if (color[v] == ColorTraits::white()) { + color[v] = ColorTraits::gray(); + parent[v] = u; + u = v; + break; + } else if (color[v] == ColorTraits::gray()) { + // find minimum flow on the cycle + FlowValue delta = residual_capacity[a]; + while (1) { + BOOST_USING_STD_MIN(); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[*current[v]]); + if (v == u) + break; + else + v = target(*current[v], g); + } + // remove delta flow units + v = u; + while (1) { + a = *current[v]; + residual_capacity[a] -= delta; + residual_capacity[reverse_edge[a]] += delta; + v = target(a, g); + if (v == u) + break; + } + + // back-out of DFS to the first saturated edge + restart = u; + for (v = target(*current[u], g); v != u; v = target(a, g)){ + a = *current[v]; + if (color[v] == ColorTraits::white() + || is_saturated(a)) { + color[target(*current[v], g)] = ColorTraits::white(); + if (color[v] != ColorTraits::white()) + restart = v; + } + } + if (restart != u) { + u = restart; + ++current[u]; + break; + } + } // else if (color[v] == ColorTraits::gray()) + } // if (capacity[a] == 0 ... + } // for out_edges(u, g) (though "u" changes during loop) + + if (current[u] == out_edges(u, g).second) { + // scan of i is complete + color[u] = ColorTraits::black(); + if (u != src) { + if (bos_null) { + bos = u; + bos_null = false; + tos = u; + } else { + topo_next[u] = tos; + tos = u; + } + } + if (u != r) { + u = parent[u]; + ++current[u]; + } else + break; + } + } // while (1) + } // if (color[u] == white && excess_flow[u] > 0 & ...) + } // for all vertices in g + + // return excess flows + // note that the sink is not on the stack + if (! bos_null) { + for (u = tos; u != bos; u = topo_next[u]) { + ai = out_edges(u, g).first; + while (excess_flow[u] > 0 && ai != out_edges(u, g).second) { + if (capacity[*ai] == 0 && is_residual_edge(*ai)) + push_flow(*ai); + ++ai; + } + } + // do the bottom + u = bos; + ai = out_edges(u, g).first; + while (excess_flow[u] > 0) { + if (capacity[*ai] == 0 && is_residual_edge(*ai)) + push_flow(*ai); + ++ai; + } + } + + } // convert_preflow_to_flow() + + //======================================================================= + inline bool is_flow() + { + vertex_iterator u_iter, u_end; + out_edge_iterator ai, a_end; + + // check edge flow values + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai) { + edge_descriptor a = *ai; + if (capacity[a] > 0) + if ((residual_capacity[a] + residual_capacity[reverse_edge[a]] + != capacity[a] + capacity[reverse_edge[a]]) + || (residual_capacity[a] < 0) + || (residual_capacity[reverse_edge[a]] < 0)) + return false; + } + } + + // check conservation + FlowValue sum; + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) { + vertex_descriptor u = *u_iter; + if (u != src && u != sink) { + if (excess_flow[u] != 0) + return false; + sum = 0; + for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) + if (capacity[*ai] > 0) + sum -= capacity[*ai] - residual_capacity[*ai]; + else + sum += residual_capacity[*ai]; + + if (excess_flow[u] != sum) + return false; + } + } + + return true; + } // is_flow() + + bool is_optimal() { + // check if mincut is saturated... + global_distance_update(); + return distance[src] >= n; + } + + void print_statistics(std::ostream& os) const { + os << "pushes: " << push_count << std::endl + << "relabels: " << relabel_count << std::endl + << "updates: " << update_count << std::endl + << "gaps: " << gap_count << std::endl + << "gap nodes: " << gap_node_count << std::endl + << std::endl; + } + + void print_flow_values(std::ostream& os) const { + os << "flow values" << std::endl; + vertex_iterator u_iter, u_end; + out_edge_iterator ei, e_end; + for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + if (capacity[*ei] > 0) + os << *u_iter << " " << target(*ei, g) << " " + << (capacity[*ei] - residual_capacity[*ei]) << std::endl; + os << std::endl; + } + + //======================================================================= + + Graph& g; + vertices_size_type n; + vertices_size_type nm; + EdgeCapacityMap capacity; + vertex_descriptor src; + vertex_descriptor sink; + VertexIndexMap index; + + // will need to use random_access_property_map with these + std::vector< FlowValue > excess_flow; + std::vector< out_edge_iterator > current; + std::vector< distance_size_type > distance; + std::vector< default_color_type > color; + + // Edge Property Maps that must be interior to the graph + ReverseEdgeMap reverse_edge; + ResidualCapacityEdgeMap residual_capacity; + + LayerArray layers; + std::vector< list_iterator > layer_list_ptr; + distance_size_type max_distance; // maximal distance + distance_size_type max_active; // maximal distance with active node + distance_size_type min_active; // minimal distance with active node + boost::queue Q; + + // Statistics counters + long push_count; + long update_count; + long relabel_count; + long gap_count; + long gap_node_count; + + inline double global_update_frequency() { return 0.5; } + inline vertices_size_type alpha() { return 6; } + inline long beta() { return 12; } + + long work_since_last_update; + }; + + } // namespace detail + + template + typename property_traits::value_type + push_relabel_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + CapacityEdgeMap cap, ResidualCapacityEdgeMap res, + ReverseEdgeMap rev, VertexIndexMap index_map) + { + typedef typename property_traits::value_type FlowValue; + + detail::push_relabel + algo(g, cap, res, rev, src, sink, index_map); + + FlowValue flow = algo.maximum_preflow(); + + algo.convert_preflow_to_flow(); + + assert(algo.is_flow()); + assert(algo.is_optimal()); + + return flow; + } // push_relabel_max_flow() + + template + typename detail::edge_capacity_value::type + push_relabel_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + const bgl_named_params& params) + { + return push_relabel_max_flow + (g, src, sink, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), + g, edge_residual_capacity), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index) + ); + } + + template + typename property_traits< + typename property_map::const_type + >::value_type + push_relabel_max_flow + (Graph& g, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink) + { + bgl_named_params params(0); // bogus empty param + return push_relabel_max_flow(g, src, sink, params); + } + +} // namespace boost + +#endif // BOOST_PUSH_RELABEL_MAX_FLOW_HPP + diff --git a/thirdparty/boost/graph/random.hpp b/thirdparty/boost/graph/random.hpp new file mode 100644 index 0000000..38c8ad7 --- /dev/null +++ b/thirdparty/boost/graph/random.hpp @@ -0,0 +1,205 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright (C) Vladimir Prus 2003 +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_RANDOM_HPP +#define BOOST_GRAPH_RANDOM_HPP + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +namespace boost { + + // grab a random vertex from the graph's vertex set + template + typename graph_traits::vertex_descriptor + random_vertex(Graph& g, RandomNumGen& gen) + { + if (num_vertices(g) > 1) { + #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581)) + std::size_t n = std::random( num_vertices(g) ); + #else + uniform_int<> distrib(0, num_vertices(g)-1); + variate_generator > rand_gen(gen, distrib); + std::size_t n = rand_gen(); + #endif + typename graph_traits::vertex_iterator + i = vertices(g).first; + while (n-- > 0) ++i; // std::advance not VC++ portable + return *i; + } else + return *vertices(g).first; + } + + template + typename graph_traits::edge_descriptor + random_edge(Graph& g, RandomNumGen& gen) { + if (num_edges(g) > 1) { + #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581)) + typename graph_traits::edges_size_type + n = std::random( num_edges(g) ); + #else + uniform_int<> distrib(0, num_edges(g)-1); + variate_generator > rand_gen(gen, distrib); + typename graph_traits::edges_size_type + n = rand_gen(); + #endif + typename graph_traits::edge_iterator + i = edges(g).first; + while (n-- > 0) ++i; // std::advance not VC++ portable + return *i; + } else + return *edges(g).first; + } + + namespace detail { + class dummy_property_copier { + public: + template + void operator()(const V1&, const V2&) const {} + }; + } + + template + void generate_random_graph1 + (MutableGraph& g, + typename graph_traits::vertices_size_type V, + typename graph_traits::vertices_size_type E, + RandNumGen& gen, + bool allow_parallel = true, + bool self_edges = false) + { + typedef graph_traits Traits; + typedef typename Traits::vertices_size_type v_size_t; + typedef typename Traits::edges_size_type e_size_t; + typedef typename Traits::vertex_descriptor vertex_descriptor; + + // When parallel edges are not allowed, we create a new graph which + // does not allow parallel edges, construct it and copy back. + // This is not efficient if 'g' already disallow parallel edges, + // but that's task for later. + if (!allow_parallel) { + + typedef typename boost::graph_traits::directed_category dir; + typedef typename mpl::if_, + directedS, undirectedS>::type select; + adjacency_list g2; + generate_random_graph1(g2, V, E, gen, true, self_edges); + + copy_graph(g2, g, vertex_copy(detail::dummy_property_copier()). + edge_copy(detail::dummy_property_copier())); + + } else { + + for (v_size_t i = 0; i < V; ++i) + add_vertex(g); + + for (e_size_t j = 0; j < E; ++j) { + vertex_descriptor a = random_vertex(g, gen), b; + do { + b = random_vertex(g, gen); + } while (self_edges == false && a == b); + add_edge(a, b, g); + } + } + } + + template + void generate_random_graph + (MutableGraph& g, + typename graph_traits::vertices_size_type V, + typename graph_traits::vertices_size_type E, + RandNumGen& gen, + bool allow_parallel = true, + bool self_edges = false) + { + generate_random_graph1(g, V, E, gen, allow_parallel, self_edges); + } + + template + void generate_random_graph + (MutableGraph& g, + typename graph_traits::vertices_size_type V, + typename graph_traits::vertices_size_type E, + RandNumGen& gen, + VertexOutputIterator vertex_out, + EdgeOutputIterator edge_out, + bool self_edges = false) + { + typedef graph_traits Traits; + typedef typename Traits::vertices_size_type v_size_t; + typedef typename Traits::edges_size_type e_size_t; + typedef typename Traits::vertex_descriptor vertex_t; + typedef typename Traits::edge_descriptor edge_t; + + for (v_size_t i = 0; i < V; ++i) + *vertex_out++ = add_vertex(g); + + for (e_size_t j = 0; j < E; ++j) { + vertex_t a = random_vertex(g, gen), b; + do { + b = random_vertex(g, gen); + } while (self_edges == false && a == b); + edge_t e; bool inserted; + tie(e, inserted) = add_edge(a, b, g); + if (inserted) + *edge_out++ = std::make_pair(source(e, g), target(e, g)); + } + } + + namespace detail { + + template + void randomize_property(G& g, RandomGenerator& rg, + Property, vertex_property_tag) + { + typename property_map::type pm = get(Property(), g); + typename graph_traits::vertex_iterator vi, ve; + for (tie(vi, ve) = vertices(g); vi != ve; ++vi) { + pm[*vi] = rg(); + } + } + + template + void randomize_property(G& g, RandomGenerator& rg, + Property, edge_property_tag) + { + typename property_map::type pm = get(Property(), g); + typename graph_traits::edge_iterator ei, ee; + for (tie(ei, ee) = edges(g); ei != ee; ++ei) { + pm[*ei] = rg(); + } + } + } + + template + void randomize_property(G& g, RandomGenerator& rg) + { + detail::randomize_property + (g, rg, Property(), typename property_kind::type()); + } + + + + +} + + +#endif diff --git a/thirdparty/boost/graph/random_layout.hpp b/thirdparty/boost/graph/random_layout.hpp new file mode 100644 index 0000000..1bf75f2 --- /dev/null +++ b/thirdparty/boost/graph/random_layout.hpp @@ -0,0 +1,49 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_RANDOM_LAYOUT_HPP +#define BOOST_GRAPH_RANDOM_LAYOUT_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + +template +void +random_graph_layout(const Graph& g, PositionMap position_map, + Dimension minX, Dimension maxX, + Dimension minY, Dimension maxY, + RandomNumberGenerator& gen) +{ + typedef typename mpl::if_, + uniform_int, + uniform_real >::type distrib_t; + typedef typename mpl::if_, + RandomNumberGenerator&, + uniform_01 > + ::type gen_t; + + gen_t my_gen(gen); + distrib_t x(minX, maxX); + distrib_t y(minY, maxY); + typename graph_traits::vertex_iterator vi, vi_end; + for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { + position_map[*vi].x = x(my_gen); + position_map[*vi].y = y(my_gen); + } +} + +} // end namespace boost + +#endif // BOOST_GRAPH_RANDOM_LAYOUT_HPP diff --git a/thirdparty/boost/graph/read_dimacs.hpp b/thirdparty/boost/graph/read_dimacs.hpp new file mode 100644 index 0000000..e4f1d2e --- /dev/null +++ b/thirdparty/boost/graph/read_dimacs.hpp @@ -0,0 +1,277 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +/* + Reads maximal flow problem in extended DIMACS format. + This works, but could use some polishing. +*/ + +/* ----------------------------------------------------------------- */ + +#include +#include +#include + +namespace boost { + +template +int read_dimacs_max_flow(Graph& g, + CapacityMap capacity, + ReverseEdgeMap reverse_edge, + typename graph_traits::vertex_descriptor& src, + typename graph_traits::vertex_descriptor& sink, + std::istream& in=std::cin) +{ + // const int MAXLINE = 100; /* max line length in the input file */ + const int ARC_FIELDS = 3; /* no of fields in arc line */ + const int NODE_FIELDS = 2; /* no of fields in node line */ + const int P_FIELDS = 3; /* no of fields in problem line */ + const char* PROBLEM_TYPE = "max"; /* name of problem type*/ + + typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + std::vector verts; + + long m, n, /* number of edges and nodes */ + i, head, tail, cap; + + long no_lines=0, /* no of current input line */ + no_plines=0, /* no of problem-lines */ + no_nslines=0, /* no of node-source-lines */ + no_nklines=0, /* no of node-source-lines */ + no_alines=0; /* no of arc-lines */ + + std::string in_line; /* for reading input line */ + char pr_type[3]; /* for reading type of the problem */ + char nd; /* source (s) or sink (t) */ + + int k, /* temporary */ + err_no; /* no of detected error */ + + /* -------------- error numbers & error messages ---------------- */ + const int EN1 = 0; + const int EN2 = 1; + const int EN3 = 2; + const int EN4 = 3; + // const int EN6 = 4; + // const int EN10 = 5; + // const int EN7 = 6; + const int EN8 = 7; + const int EN9 = 8; + const int EN11 = 9; + const int EN12 = 10; + // const int EN13 = 11; + const int EN14 = 12; + const int EN16 = 13; + const int EN15 = 14; + const int EN17 = 15; + const int EN18 = 16; + const int EN21 = 17; + const int EN19 = 18; + const int EN20 = 19; + const int EN22 = 20; + + static char *err_message[] = + { + /* 0*/ "more than one problem line.", + /* 1*/ "wrong number of parameters in the problem line.", + /* 2*/ "it is not a Max Flow problem line.", + /* 3*/ "bad value of a parameter in the problem line.", + /* 4*/ "can't obtain enough memory to solve this problem.", + /* 5*/ "more than one line with the problem name.", + /* 6*/ "can't read problem name.", + /* 7*/ "problem description must be before node description.", + /* 8*/ "this parser doesn't support multiply sources and sinks.", + /* 9*/ "wrong number of parameters in the node line.", + /*10*/ "wrong value of parameters in the node line.", + /*11*/ " ", + /*12*/ "source and sink descriptions must be before arc descriptions.", + /*13*/ "too many arcs in the input.", + /*14*/ "wrong number of parameters in the arc line.", + /*15*/ "wrong value of parameters in the arc line.", + /*16*/ "unknown line type in the input.", + /*17*/ "reading error.", + /*18*/ "not enough arcs in the input.", + /*19*/ "source or sink doesn't have incident arcs.", + /*20*/ "can't read anything from the input file." + }; + /* --------------------------------------------------------------- */ + + /* The main loop: + - reads the line of the input, + - analyses its type, + - checks correctness of parameters, + - puts data to the arrays, + - does service functions + */ + + while (std::getline(in, in_line)) { + ++no_lines; + + switch (in_line[0]) { + case 'c': /* skip lines with comments */ + case '\n': /* skip empty lines */ + case '\0': /* skip empty lines at the end of file */ + break; + + case 'p': /* problem description */ + if ( no_plines > 0 ) + /* more than one problem line */ + { err_no = EN1 ; goto error; } + + no_plines = 1; + + if ( + /* reading problem line: type of problem, no of nodes, no of arcs */ + sscanf ( in_line.c_str(), "%*c %3s %ld %ld", pr_type, &n, &m ) + != P_FIELDS + ) + /*wrong number of parameters in the problem line*/ + { err_no = EN2; goto error; } + + if ( strcmp ( pr_type, PROBLEM_TYPE ) ) + /*wrong problem type*/ + { err_no = EN3; goto error; } + + if ( n <= 0 || m <= 0 ) + /*wrong value of no of arcs or nodes*/ + { err_no = EN4; goto error; } + + { + for (long vi = 0; vi < n; ++vi) + verts.push_back(add_vertex(g)); + } + break; + + case 'n': /* source(s) description */ + if ( no_plines == 0 ) + /* there was not problem line above */ + { err_no = EN8; goto error; } + + /* reading source or sink */ + k = sscanf ( in_line.c_str(),"%*c %ld %c", &i, &nd ); + --i; // index from 0 + if ( k < NODE_FIELDS ) + /* node line is incorrect */ + { err_no = EN11; goto error; } + + if ( i < 0 || i > n ) + /* wrong value of node */ + { err_no = EN12; goto error; } + + switch (nd) { + case 's': /* source line */ + + if ( no_nslines != 0) + /* more than one source line */ + { err_no = EN9; goto error; } + + no_nslines = 1; + src = verts[i]; + break; + + case 't': /* sink line */ + + if ( no_nklines != 0) + /* more than one sink line */ + { err_no = EN9; goto error; } + + no_nklines = 1; + sink = verts[i]; + break; + + default: + /* wrong type of node-line */ + err_no = EN12; goto error; + } + break; + + case 'a': /* arc description */ + if ( no_nslines == 0 || no_nklines == 0 ) + /* there was not source and sink description above */ + { err_no = EN14; goto error; } + + if ( no_alines >= m ) + /*too many arcs on input*/ + { err_no = EN16; goto error; } + + if ( + /* reading an arc description */ + sscanf ( in_line.c_str(),"%*c %ld %ld %ld", + &tail, &head, &cap ) + != ARC_FIELDS + ) + /* arc description is not correct */ + { err_no = EN15; goto error; } + + --tail; // index from 0, not 1 + --head; + if ( tail < 0 || tail > n || + head < 0 || head > n + ) + /* wrong value of nodes */ + { err_no = EN17; goto error; } + + { + edge_descriptor e1, e2; + bool in1, in2; + tie(e1, in1) = add_edge(verts[tail], verts[head], g); + tie(e2, in2) = add_edge(verts[head], verts[tail], g); + if (!in1 || !in2) { + std::cerr << "unable to add edge (" << head << "," << tail << ")" + << std::endl; + return -1; + } + capacity[e1] = cap; + capacity[e2] = 0; + reverse_edge[e1] = e2; + reverse_edge[e2] = e1; + } + ++no_alines; + break; + + default: + /* unknown type of line */ + err_no = EN18; goto error; + + } /* end of switch */ + } /* end of input loop */ + + /* ----- all is red or error while reading ----- */ + + if ( feof (stdin) == 0 ) /* reading error */ + { err_no=EN21; goto error; } + + if ( no_lines == 0 ) /* empty input */ + { err_no = EN22; goto error; } + + if ( no_alines < m ) /* not enough arcs */ + { err_no = EN19; goto error; } + + if ( out_degree(src, g) == 0 || out_degree(sink, g) == 0 ) + /* no arc goes out of the source */ + { err_no = EN20; goto error; } + + /* Thanks God! all is done */ + return (0); + + /* ---------------------------------- */ + error: /* error found reading input */ + + printf ( "\nline %ld of input - %s\n", + no_lines, err_message[err_no] ); + + exit (1); + return (0); /* to avoid warning */ +} +/* -------------------- end of parser -------------------*/ + +} // namespace boost diff --git a/thirdparty/boost/graph/relax.hpp b/thirdparty/boost/graph/relax.hpp new file mode 100644 index 0000000..65afefe --- /dev/null +++ b/thirdparty/boost/graph/relax.hpp @@ -0,0 +1,77 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_RELAX_HPP +#define BOOST_GRAPH_RELAX_HPP + +#include +#include // for numeric limits +#include +#include + +namespace boost { + + // The following version of the plus functor prevents + // problems due to overflow at positive infinity. + + template + struct closed_plus + { + T operator()(const T& a, const T& b) const { + using namespace std; + T zero(0); + T result = a + b; + if (result < zero && a >= zero && b >= zero) + return (numeric_limits::max)(); + return result; + } + }; + + template + bool relax(typename graph_traits::edge_descriptor e, + const Graph& g, const WeightMap& w, + PredecessorMap& p, DistanceMap& d, + const BinaryFunction& combine, const BinaryPredicate& compare) + { + typedef typename graph_traits::directed_category DirCat; + bool is_undirected = is_same::value; + typedef typename graph_traits::vertex_descriptor Vertex; + Vertex u = source(e, g), v = target(e, g); + typedef typename property_traits::value_type D; + typedef typename property_traits::value_type W; + D d_u = get(d, u), d_v = get(d, v); + W w_e = get(w, e); + + if ( compare(combine(d_u, w_e), d_v) ) { + put(d, v, combine(d_u, w_e)); + put(p, v, u); + return true; + } else if (is_undirected && compare(combine(d_v, w_e), d_u)) { + put(d, u, combine(d_v, w_e)); + put(p, u, v); + return true; + } else + return false; + } + + template + bool relax(typename graph_traits::edge_descriptor e, + const Graph& g, WeightMap w, PredecessorMap p, DistanceMap d) + { + typedef typename property_traits::value_type D; + typedef closed_plus Combine; + typedef std::less Compare; + return relax(e, g, w, p, d, Combine(), Compare()); + } + +} // namespace boost + +#endif /* BOOST_GRAPH_RELAX_HPP */ diff --git a/thirdparty/boost/graph/reverse_graph.hpp b/thirdparty/boost/graph/reverse_graph.hpp new file mode 100644 index 0000000..fa3a5c6 --- /dev/null +++ b/thirdparty/boost/graph/reverse_graph.hpp @@ -0,0 +1,324 @@ +// (C) Copyright David Abrahams 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef REVERSE_GRAPH_DWA092300_H_ +# define REVERSE_GRAPH_DWA092300_H_ + +#include +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# define BidirectionalGraph BidirectionalGraph_ +#endif + +namespace boost { + +struct reverse_graph_tag { }; + + namespace detail { + + template struct choose_rev_edge_iter { }; + template <> struct choose_rev_edge_iter { + template struct bind_ { + typedef typename graph_traits::edge_iterator type; + }; + }; + template <> struct choose_rev_edge_iter { + template struct bind_ { + typedef void type; + }; + }; + + } // namespace detail + +template +class reverse_graph { + typedef reverse_graph Self; + typedef graph_traits Traits; + public: + typedef BidirectionalGraph base_type; + + // Constructor + reverse_graph(GraphRef g) : m_g(g) {} + + // Graph requirements + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::traversal_category traversal_category; + + // IncidenceGraph requirements + typedef typename Traits::in_edge_iterator out_edge_iterator; + typedef typename Traits::degree_size_type degree_size_type; + + // BidirectionalGraph requirements + typedef typename Traits::out_edge_iterator in_edge_iterator; + + // AdjacencyGraph requirements + typedef typename adjacency_iterator_generator::type adjacency_iterator; + + // VertexListGraph requirements + typedef typename Traits::vertex_iterator vertex_iterator; + + // EdgeListGraph requirements + enum { is_edge_list = is_convertible::value }; + typedef detail::choose_rev_edge_iter ChooseEdgeIter; + typedef typename ChooseEdgeIter:: + template bind_::type edge_iterator; + typedef typename Traits::vertices_size_type vertices_size_type; + typedef typename Traits::edges_size_type edges_size_type; + + // More typedefs used by detail::edge_property_map, vertex_property_map + typedef typename BidirectionalGraph::edge_property_type + edge_property_type; + typedef typename BidirectionalGraph::vertex_property_type + vertex_property_type; + typedef reverse_graph_tag graph_tag; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + // Bundled properties support + template + typename graph::detail::bundled_result::type& + operator[](Descriptor x) + { return m_g[x]; } + + template + typename graph::detail::bundled_result::type const& + operator[](Descriptor x) const + { return m_g[x]; } +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + + static vertex_descriptor null_vertex() + { return Traits::null_vertex(); } + + // would be private, but template friends aren't portable enough. + // private: + GraphRef m_g; +}; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct vertex_bundle_type > + : vertex_bundle_type { }; + + template + struct edge_bundle_type > + : edge_bundle_type { }; +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + +template +inline reverse_graph +make_reverse_graph(const BidirectionalGraph& g) +{ + return reverse_graph(g); +} + +template +inline reverse_graph +make_reverse_graph(BidirectionalGraph& g) +{ + return reverse_graph(g); +} + +template +std::pair::vertex_iterator, + typename reverse_graph::vertex_iterator> +vertices(const reverse_graph& g) +{ + return vertices(g.m_g); +} + +template +std::pair::edge_iterator, + typename reverse_graph::edge_iterator> +edges(const reverse_graph& g) +{ + return edges(g.m_g); +} + +template +inline std::pair +out_edges(const typename BidirectionalGraph::vertex_descriptor u, + const reverse_graph& g) +{ + return in_edges(u, g.m_g); +} + +template +inline typename BidirectionalGraph::vertices_size_type +num_vertices(const reverse_graph& g) +{ + return num_vertices(g.m_g); +} + +template +inline typename reverse_graph::edges_size_type +num_edges(const reverse_graph& g) +{ + return num_edges(g.m_g); +} + +template +inline typename BidirectionalGraph::degree_size_type +out_degree(const typename BidirectionalGraph::vertex_descriptor u, + const reverse_graph& g) +{ + return in_degree(u, g.m_g); +} + +template +inline std::pair +edge(const typename BidirectionalGraph::vertex_descriptor u, + const typename BidirectionalGraph::vertex_descriptor v, + const reverse_graph& g) +{ + return edge(v, u, g.m_g); +} + +template +inline std::pair +in_edges(const typename BidirectionalGraph::vertex_descriptor u, + const reverse_graph& g) +{ + return out_edges(u, g.m_g); +} + +template +inline std::pair::adjacency_iterator, + typename reverse_graph::adjacency_iterator> +adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u, + const reverse_graph& g) +{ + typedef reverse_graph Graph; + typename Graph::out_edge_iterator first, last; + tie(first, last) = out_edges(u, g); + typedef typename Graph::adjacency_iterator adjacency_iterator; + return std::make_pair(adjacency_iterator(first, const_cast(&g)), + adjacency_iterator(last, const_cast(&g))); +} + +template +inline typename BidirectionalGraph::degree_size_type +in_degree(const typename BidirectionalGraph::vertex_descriptor u, + const reverse_graph& g) +{ + return out_degree(u, g.m_g); +} + +template +inline typename graph_traits::vertex_descriptor +source(const Edge& e, const reverse_graph& g) +{ + return target(e, g.m_g); +} + +template +inline typename graph_traits::vertex_descriptor +target(const Edge& e, const reverse_graph& g) +{ + return source(e, g.m_g); +} + + +namespace detail { + + struct reverse_graph_vertex_property_selector { + template + struct bind_ { + typedef typename ReverseGraph::base_type Graph; + typedef property_map PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; + }; + + struct reverse_graph_edge_property_selector { + template + struct bind_ { + typedef typename ReverseGraph::base_type Graph; + typedef property_map PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; + }; + +} // namespace detail + +template <> +struct vertex_property_selector { + typedef detail::reverse_graph_vertex_property_selector type; +}; + +template <> +struct edge_property_selector { + typedef detail::reverse_graph_edge_property_selector type; +}; + +template +typename property_map::type +get(Property p, reverse_graph& g) +{ + return get(p, g.m_g); +} + +template +typename property_map::const_type +get(Property p, const reverse_graph& g) +{ + const BidirGraph& gref = g.m_g; // in case GRef is non-const + return get(p, gref); +} + +template +typename property_traits< + typename property_map::const_type +>::value_type +get(Property p, const reverse_graph& g, const Key& k) +{ + return get(p, g.m_g, k); +} + +template +void +put(Property p, const reverse_graph& g, const Key& k, + const Value& val) +{ + put(p, g.m_g, k, val); +} + +template +inline void +set_property(const reverse_graph& g, Tag tag, + const Value& value) +{ + set_property(g.m_g, tag, value); +} + +template +inline +typename graph_property::type +get_property(const reverse_graph& g, Tag tag) +{ + return get_property(g.m_g, tag); +} + +} // namespace boost + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# undef BidirectionalGraph +#endif + +#endif diff --git a/thirdparty/boost/graph/sequential_vertex_coloring.hpp b/thirdparty/boost/graph/sequential_vertex_coloring.hpp new file mode 100644 index 0000000..a06712e --- /dev/null +++ b/thirdparty/boost/graph/sequential_vertex_coloring.hpp @@ -0,0 +1,124 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2004 The Trustees of Indiana University +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP +#define BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP + +#include +#include +#include +#include +#include + +#ifdef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# include +#endif + +/* This algorithm is to find coloring of a graph + + Algorithm: + Let G = (V,E) be a graph with vertices (somehow) ordered v_1, v_2, ..., + v_n. For k = 1, 2, ..., n the sequential algorithm assigns v_k to the + smallest possible color. + + Reference: + + Thomas F. Coleman and Jorge J. More, Estimation of sparse Jacobian + matrices and graph coloring problems. J. Numer. Anal. V20, P187-209, 1983 + + v_k is stored as o[k] here. + + The color of the vertex v will be stored in color[v]. + i.e., vertex v belongs to coloring color[v] */ + +namespace boost { + template + typename property_traits::value_type + sequential_vertex_coloring(const VertexListGraph& G, OrderPA order, + ColorMap color) + { + typedef graph_traits GraphTraits; + typedef typename GraphTraits::vertex_descriptor Vertex; + typedef typename property_traits::value_type size_type; + + size_type max_color = 0; + const size_type V = num_vertices(G); + + // We need to keep track of which colors are used by + // adjacent vertices. We do this by marking the colors + // that are used. The mark array contains the mark + // for each color. The length of mark is the + // number of vertices since the maximum possible number of colors + // is the number of vertices. + std::vector mark(V, + std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()); + + //Initialize colors + typename GraphTraits::vertex_iterator v, vend; + for (tie(v, vend) = vertices(G); v != vend; ++v) + put(color, *v, V-1); + + //Determine the color for every vertex one by one + for ( size_type i = 0; i < V; i++) { + Vertex current = get(order,i); + typename GraphTraits::adjacency_iterator v, vend; + + //Mark the colors of vertices adjacent to current. + //i can be the value for marking since i increases successively + for (tie(v,vend) = adjacent_vertices(current, G); v != vend; ++v) + mark[get(color,*v)] = i; + + //Next step is to assign the smallest un-marked color + //to the current vertex. + size_type j = 0; + + //Scan through all useable colors, find the smallest possible + //color that is not used by neighbors. Note that if mark[j] + //is equal to i, color j is used by one of the current vertex's + //neighbors. + while ( j < max_color && mark[j] == i ) + ++j; + + if ( j == max_color ) //All colors are used up. Add one more color + ++max_color; + + //At this point, j is the smallest possible color + put(color, current, j); //Save the color of vertex current + } + + return max_color; + } + + template + typename property_traits::value_type + sequential_vertex_coloring(const VertexListGraph& G, ColorMap color) + { + typedef typename graph_traits::vertex_descriptor + vertex_descriptor; + typedef typename graph_traits::vertex_iterator + vertex_iterator; + + std::pair v = vertices(G); +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + std::vector order(v.first, v.second); +#else + std::vector order; + order.reserve(std::distance(v.first, v.second)); + while (v.first != v.second) order.push_back(*v.first++); +#endif + return sequential_vertex_coloring + (G, + make_iterator_property_map + (order.begin(), identity_property_map(), + graph_traits::null_vertex()), + color); + } +} + +#endif diff --git a/thirdparty/boost/graph/simple_point.hpp b/thirdparty/boost/graph/simple_point.hpp new file mode 100644 index 0000000..63df034 --- /dev/null +++ b/thirdparty/boost/graph/simple_point.hpp @@ -0,0 +1,23 @@ +//======================================================================= +// Copyright 2005 Trustees of Indiana University +// Authors: Andrew Lumsdaine, Douglas Gregor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_SIMPLE_POINT_HPP +#define BOOST_GRAPH_SIMPLE_POINT_HPP + +namespace boost { + +template +struct simple_point +{ + T x; + T y; +}; + +} // end namespace boost + +#endif // BOOST_GRAPH_SIMPLE_POINT_HPP diff --git a/thirdparty/boost/graph/sloan_ordering.hpp b/thirdparty/boost/graph/sloan_ordering.hpp new file mode 100644 index 0000000..c240215 --- /dev/null +++ b/thirdparty/boost/graph/sloan_ordering.hpp @@ -0,0 +1,448 @@ +// +//======================================================================= +// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch) +// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_GRAPH_SLOAN_HPP +#define BOOST_GRAPH_SLOAN_HPP + +#define WEIGHT1 1 //default weight for the distance in the Sloan algorithm +#define WEIGHT2 2 //default weight for the degree in the Sloan algorithm +#define MAXINT 2147483647 //Maximum value for a 32bit integer + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//////////////////////////////////////////////////////////// +// +//Sloan-Algorithm for graph reordering +//(optimzes profile and wavefront, not primiraly bandwidth +// +//////////////////////////////////////////////////////////// + +namespace boost { + + ///////////////////////////////////////////////////////////////////////// + // Function that returns the maximum depth of + // a rooted level strucutre (RLS) + // + ///////////////////////////////////////////////////////////////////////// + template + unsigned RLS_depth(Distance& d) + { + unsigned h_s = 0; + typename Distance::iterator iter; + + for (iter = d.begin(); iter != d.end(); ++iter) + { + if(*iter > h_s) + { + h_s = *iter; + } + } + + return h_s; + } + + + + ///////////////////////////////////////////////////////////////////////// + // Function that returns the width of the largest level of + // a rooted level strucutre (RLS) + // + ///////////////////////////////////////////////////////////////////////// + template + unsigned RLS_max_width(Distance& d, my_int depth) + { + + //Searching for the maximum width of a level + std::vector dummy_width(depth+1, 0); + std::vector::iterator my_it; + typename Distance::iterator iter; + unsigned w_max = 0; + + for (iter = d.begin(); iter != d.end(); ++iter) + { + dummy_width[*iter]++; + } + + for(my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it) + { + if(*my_it > w_max) w_max = *my_it; + } + + return w_max; + + } + + + ///////////////////////////////////////////////////////////////////////// + // Function for finding a good starting node for Sloan algorithm + // + // This is to find a good starting node. "good" is in the sense + // of the ordering generated. + ///////////////////////////////////////////////////////////////////////// + template + typename graph_traits::vertex_descriptor + sloan_start_end_vertices(Graph& G, + typename graph_traits::vertex_descriptor &s, + ColorMap color, + DegreeMap degree) + { + typedef typename property_traits::value_type Degree; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename std::vector< typename graph_traits::vertices_size_type>::iterator vec_iter; + typedef typename graph_traits::vertices_size_type size_type; + + typedef typename property_map::const_type VertexID; + + s = *(vertices(G).first); + Vertex e = s; + Vertex i; + unsigned my_degree = get(degree, s ); + unsigned dummy, h_i, h_s, w_i, w_e; + bool new_start = true; + unsigned maximum_degree = 0; + + //Creating a std-vector for storing the distance from the start vertex in dist + std::vector::vertices_size_type> dist(num_vertices(G), 0); + + //Wrap a property_map_iterator around the std::iterator + boost::iterator_property_map dist_pmap(dist.begin(), get(vertex_index, G)); + + //Creating a property_map for the indices of a vertex + typename property_map::type index_map = get(vertex_index, G); + + //Creating a priority queue + typedef indirect_cmp > Compare; + Compare comp(degree); + std::priority_queue, Compare> degree_queue(comp); + + //step 1 + //Scan for the vertex with the smallest degree and the maximum degree + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + { + dummy = get(degree, *ui); + + if(dummy < my_degree) + { + my_degree = dummy; + s = *ui; + } + + if(dummy > maximum_degree) + { + maximum_degree = dummy; + } + } + //end 1 + + do{ + new_start = false; //Setting the loop repetition status to false + + //step 2 + //initialize the the disance std-vector with 0 + for(typename std::vector::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; + + //generating the RLS (rooted level structure) + breadth_first_search + (G, s, visitor + ( + make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) + ) + ); + + //end 2 + + //step 3 + //calculating the depth of the RLS + h_s = RLS_depth(dist); + + //step 4 + //pushing one node of each degree in an ascending manner into degree_queue + std::vector shrink_trace(maximum_degree, false); + for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + { + dummy = get(degree, *ui); + + if( (dist[index_map[*ui]] == h_s ) && ( !shrink_trace[ dummy ] ) ) + { + degree_queue.push(*ui); + shrink_trace[ dummy ] = true; + } + } + + //end 3 & 4 + + + //step 5 + //Initializing w + w_e = MAXINT; + //end 5 + + + //step 6 + //Testing for termination + while( !degree_queue.empty() ) + { + i = degree_queue.top(); //getting the node with the lowest degree from the degree queue + degree_queue.pop(); //ereasing the node with the lowest degree from the degree queue + + //generating a RLS + for(typename std::vector::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; + + breadth_first_search + (G, i, boost::visitor + ( + make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) + ) + ); + + //Calculating depth and width of the rooted level + h_i = RLS_depth(dist); + w_i = RLS_max_width(dist, h_i); + + //Testing for termination + if( (h_i > h_s) && (w_i < w_e) ) + { + h_s = h_i; + s = i; + while(!degree_queue.empty()) degree_queue.pop(); + new_start = true; + } + else if(w_i < w_e) + { + w_e = w_i; + e = i; + } + } + //end 6 + + }while(new_start); + + return e; + } + + ////////////////////////////////////////////////////////////////////////// + // Sloan algorithm with a given starting Vertex. + // + // This algorithm requires user to provide a starting vertex to + // compute Sloan ordering. + ////////////////////////////////////////////////////////////////////////// + template + OutputIterator + sloan_ordering(Graph& g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor e, + OutputIterator permutation, + ColorMap color, + DegreeMap degree, + PriorityMap priority, + Weight W1, + Weight W2) + { + //typedef typename property_traits::value_type Degree; + typedef typename property_traits::value_type Degree; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename std::vector::vertices_size_type>::iterator vec_iter; + typedef typename graph_traits::vertices_size_type size_type; + + typedef typename property_map::const_type VertexID; + + + //Creating a std-vector for storing the distance from the end vertex in it + typename std::vector::vertices_size_type> dist(num_vertices(g), 0); + + //Wrap a property_map_iterator around the std::iterator + boost::iterator_property_map dist_pmap(dist.begin(), get(vertex_index, g)); + + breadth_first_search + (g, e, visitor + ( + make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) + ) + ); + + //Creating a property_map for the indices of a vertex + typename property_map::type index_map = get(vertex_index, g); + + //Sets the color and priority to their initial status + unsigned cdeg; + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(color, *ui, Color::white()); + cdeg=get(degree, *ui)+1; + put(priority, *ui, W1*dist[index_map[*ui]]-W2*cdeg ); + } + + //Priority list + typedef indirect_cmp > Compare; + Compare comp(priority); + std::list priority_list; + + //Some more declarations + typename graph_traits::out_edge_iterator ei, ei_end, ei2, ei2_end; + Vertex u, v, w; + + put(color, s, Color::green()); //Sets the color of the starting vertex to gray + priority_list.push_front(s); //Puts s into the priority_list + + while ( !priority_list.empty() ) + { + priority_list.sort(comp); //Orders the elements in the priority list in an ascending manner + + u = priority_list.front(); //Accesses the last element in the priority list + priority_list.pop_front(); //Removes the last element in the priority list + + if(get(color, u) == Color::green() ) + { + //for-loop over all out-edges of vertex u + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + v = target(*ei, g); + + put( priority, v, get(priority, v) + W2 ); //updates the priority + + if (get(color, v) == Color::white() ) //test if the vertex is inactive + { + put(color, v, Color::green() ); //giving the vertex a preactive status + priority_list.push_front(v); //writing the vertex in the priority_queue + } + } + } + + //Here starts step 8 + *permutation++ = u; //Puts u to the first position in the permutation-vector + put(color, u, Color::black() ); //Gives u an inactive status + + //for loop over all the adjacent vertices of u + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + + v = target(*ei, g); + + if (get(color, v) == Color::green() ) { //tests if the vertex is inactive + + put(color, v, Color::red() ); //giving the vertex an active status + put(priority, v, get(priority, v)+W2); //updates the priority + + //for loop over alll adjacent vertices of v + for (tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end; ++ei2) { + w = target(*ei2, g); + + if(get(color, w) != Color::black() ) { //tests if vertex is postactive + + put(priority, w, get(priority, w)+W2); //updates the priority + + if(get(color, w) == Color::white() ){ + + put(color, w, Color::green() ); // gives the vertex a preactive status + priority_list.push_front(w); // puts the vertex into the priority queue + + } //end if + + } //end if + + } //end for + + } //end if + + } //end for + + } //end while + + + return permutation; + } + + ///////////////////////////////////////////////////////////////////////////////////////// + // Same algorithm as before, but without the weights given (taking default weights + template + OutputIterator + sloan_ordering(Graph& g, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor e, + OutputIterator permutation, + ColorMap color, + DegreeMap degree, + PriorityMap priority) + { + return sloan_ordering(g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2); + } + + + ////////////////////////////////////////////////////////////////////////// + // Sloan algorithm without a given starting Vertex. + // + // This algorithm finds a good starting vertex itself to + // compute Sloan-ordering. + ////////////////////////////////////////////////////////////////////////// + + + + template < class Graph, class OutputIterator, + class Color, class Degree, + class Priority, class Weight> + inline OutputIterator + sloan_ordering(Graph& G, + OutputIterator permutation, + Color color, + Degree degree, + Priority priority, + Weight W1, + Weight W2 ) + { + typedef typename boost::graph_traits::vertex_descriptor Vertex; + + Vertex s, e; + e = sloan_start_end_vertices(G, s, color, degree); + + return sloan_ordering(G, s, e, permutation, color, degree, priority, W1, W2); + } + + ///////////////////////////////////////////////////////////////////////////////////////// + // Same as before, but without given weights (default weights are taken instead) + template < class Graph, class OutputIterator, + class Color, class Degree, + class Priority > + inline OutputIterator + sloan_ordering(Graph& G, + OutputIterator permutation, + Color color, + Degree degree, + Priority priority) + { + return sloan_ordering(G, permutation, color, degree, priority, WEIGHT1, WEIGHT2); + } + + +} // namespace boost + + +#endif // BOOST_GRAPH_SLOAN_HPP diff --git a/thirdparty/boost/graph/small_world_generator.hpp b/thirdparty/boost/graph/small_world_generator.hpp new file mode 100644 index 0000000..8ae3e4d --- /dev/null +++ b/thirdparty/boost/graph/small_world_generator.hpp @@ -0,0 +1,114 @@ +// Copyright 2004 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Douglas Gregor +// Andrew Lumsdaine +#ifndef BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP +#define BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP + +#include +#include +#include +#include + +namespace boost { + + // Assumes undirected + template + class small_world_iterator + { + typedef typename graph_traits::vertices_size_type + vertices_size_type; + + public: + typedef std::input_iterator_tag iterator_category; + typedef std::pair value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef void difference_type; + + small_world_iterator() : gen(0) {} + small_world_iterator(RandomGenerator& gen, vertices_size_type n, + vertices_size_type k, double prob = 0.0, + bool allow_self_loops = false) + : gen(&gen), n(n), k(k), prob(prob), source(0), + target(allow_self_loops? 0 : 1), + allow_self_loops(allow_self_loops), + current(0, allow_self_loops? 0 : 1) + { } + + reference operator*() const { return current; } + pointer operator->() const { return ¤t; } + + small_world_iterator& operator++() + { + target = (target + 1) % n; + if (target == (source + k/2 + 1) % n) { + ++source; + if (allow_self_loops) target = source; + else target = (source + 1) % n; + } + current.first = source; + + uniform_01 rand01(*gen); + uniform_int rand_vertex_gen(0, n-1); + double x = rand01(); + *gen = rand01.base(); // GRRRR + if (x < prob) { + vertices_size_type lower = (source + n - k/2) % n; + vertices_size_type upper = (source + k/2) % n; + do { + current.second = rand_vertex_gen(*gen); + } while (current.second >= lower && current.second <= upper + || (upper < lower + && (current.second >= lower || current.second <= upper))); + } else { + current.second = target; + } + return *this; + } + + small_world_iterator operator++(int) + { + small_world_iterator temp(*this); + ++(*this); + return temp; + } + + bool operator==(const small_world_iterator& other) const + { + if (!gen && other.gen) return other == *this; + else if (gen && !other.gen) return source == n; + else if (!gen && !other.gen) return true; + return source == other.source && target == other.target; + } + + bool operator!=(const small_world_iterator& other) const + { return !(*this == other); } + + private: + void next() + { + uniform_int rand_vertex(0, n-1); + current.first = rand_vertex(*gen); + do { + current.second = rand_vertex(*gen); + } while (current.first == current.second && !allow_self_loops); + } + + RandomGenerator* gen; + vertices_size_type n; + vertices_size_type k; + double prob; + vertices_size_type source; + vertices_size_type target; + bool allow_self_loops; + value_type current; + }; + +} // end namespace boost + +#endif // BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP diff --git a/thirdparty/boost/graph/smallest_last_ordering.hpp b/thirdparty/boost/graph/smallest_last_ordering.hpp new file mode 100644 index 0000000..2753fa1 --- /dev/null +++ b/thirdparty/boost/graph/smallest_last_ordering.hpp @@ -0,0 +1,122 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +// Revision History: +// 17 March 2006: Fixed a bug: when updating the degree a vertex +// could be moved to a wrong bucket. (Roman Dementiev) +// + + + +#ifndef BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP +#define BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP +/* + The smallest-last ordering is defined for the loopless graph G with + vertices a(j), j = 1,2,...,n where a(j) is the j-th column of A and + with edge (a(i),a(j)) if and only if columns i and j have a + non-zero in the same row position. The smallest-last ordering is + determined recursively by letting list(k), k = n,...,1 be a column + with least degree in the subgraph spanned by the un-ordered + columns. + */ +#include +#include +#include +#include +#include + +namespace boost { + + template + void + smallest_last_vertex_ordering(const VertexListGraph& G, Order order, + Degree degree, Marker marker) { + typedef typename boost::graph_traits GraphTraits; + typedef typename GraphTraits::vertex_descriptor Vertex; + //typedef typename GraphTraits::size_type size_type; + typedef std::size_t size_type; + + const size_type num = num_vertices(G); + + typedef typename boost::detail::vertex_property_map::type ID; + typedef bucket_sorter BucketSorter; + + BucketSorter degree_bucket_sorter(num, num, degree, + get(vertex_index,G)); + + smallest_last_vertex_ordering(G, order, degree, marker, degree_bucket_sorter); + } + + template + void + smallest_last_vertex_ordering(const VertexListGraph& G, Order order, + Degree degree, Marker marker, + BucketSorter& degree_buckets) { + typedef typename boost::graph_traits GraphTraits; + typedef typename GraphTraits::vertex_descriptor Vertex; + //typedef typename GraphTraits::size_type size_type; + typedef std::size_t size_type; + + const size_type num = num_vertices(G); + + typename GraphTraits::vertex_iterator v, vend; + for (boost::tie(v, vend) = vertices(G); v != vend; ++v) { + put(marker, *v, num); + put(degree, *v, out_degree(*v, G)); + degree_buckets.push(*v); + } + + size_type minimum_degree = 0; + size_type current_order = num - 1; + + while ( 1 ) { + typedef typename BucketSorter::stack MDStack; + MDStack minimum_degree_stack = degree_buckets[minimum_degree]; + while (minimum_degree_stack.empty()) + minimum_degree_stack = degree_buckets[++minimum_degree]; + + Vertex node = minimum_degree_stack.top(); + put(order, current_order, node); + + if ( current_order == 0 ) //find all vertices + break; + + minimum_degree_stack.pop(); + put(marker, node, 0); //node has been ordered. + + typename GraphTraits::adjacency_iterator v, vend; + for (boost::tie(v,vend) = adjacent_vertices(node, G); v != vend; ++v) + + if ( get(marker,*v) > current_order ) { //*v is unordered vertex + put(marker, *v, current_order); //mark the columns adjacent to node + + //delete *v from the bucket sorter + degree_buckets.remove(*v); + + //It is possible minimum degree goes down + //Here we keep tracking it. + put(degree, *v, get(degree, *v) - 1); + BOOST_USING_STD_MIN(); + minimum_degree = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_degree, get(degree, *v)); + + //reinsert *v in the bucket sorter with the new degree + degree_buckets.push(*v); + } + + current_order--; + } + + //at this point, order[i] = v_i; + } + +} + +#endif + diff --git a/thirdparty/boost/graph/stanford_graph.hpp b/thirdparty/boost/graph/stanford_graph.hpp new file mode 100644 index 0000000..e18384d --- /dev/null +++ b/thirdparty/boost/graph/stanford_graph.hpp @@ -0,0 +1,565 @@ +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef BOOST_GRAPH_SGB_GRAPH_HPP +#define BOOST_GRAPH_SGB_GRAPH_HPP + +#include +#include +#include +#include +#include +#include + +// Thanks to Andreas Scherer for numerous suggestions and fixes! + +// This file adapts a Stanford GraphBase (SGB) Graph pointer into a +// VertexListGraph. Note that a graph adaptor class is not needed, +// SGB's Graph* is used as is. The VertexListGraph concept is fulfilled by +// defining the appropriate non-member functions for Graph*. +// +// The PROTOTYPES change file extensions to SGB must be applied so +// that the SGB functions have real prototypes which are necessary for +// the C++ compiler. To apply the PROTOTYPES extensions, before you do +// "make tests install" for SGB do "ln -s PROTOTYPES/* ." to the SGB +// root directory (or just copy all the files from the PROTOTYPES +// directory to the SGB root directory). +// +extern "C" { + // We include all global definitions for the general stuff + // of The Stanford GraphBase and its various graph generator + // functions by reading all SGB headerfiles as in section 2 of + // the "test_sample" program. +#include /* SGB data structures */ +#include /* SGB input/output routines */ +#include /* random number generator */ +#include /* routines for shortest paths */ +#include /* the basic graph operations */ +#undef empty /* avoid name clash with C++ standard library */ + inline Graph* empty( long n ) /* and provide workaround */ + { return board(n,0L,0L,0L,2L,0L,0L); } +#include /* graphs based on literature */ +#include /* graphs based on economic data */ +#include /* graphs based on football scores */ +#include /* graphs based on logic circuits */ +#undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */ + // val ==> Vertex::x.I +#include /* graphs based on Mona Lisa */ +#include /* graphs based on mileage data */ +#include /* planar graphs */ +#include /* Ramanujan graphs */ +#include /* random graphs */ +#include /* graphs based on Roget's Thesaurus */ +#include /* we save results in ASCII format */ +#include /* five-letter-word graphs */ +#undef weight /* avoid name clash with BGL parameter */ + // weight ==> Vertex::u.I +} + +namespace boost { + class sgb_edge; +} + +class sgb_out_edge_iterator; +class sgb_adj_iterator; +class sgb_vertex_iterator; + +namespace boost { + typedef Graph* sgb_graph_ptr; + typedef const Graph* sgb_const_graph_ptr; + + struct sgb_traversal_tag : + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag { }; + + template <> struct graph_traits { + typedef Vertex* vertex_descriptor; + typedef boost::sgb_edge edge_descriptor; + typedef sgb_out_edge_iterator out_edge_iterator; + typedef void in_edge_iterator; + typedef sgb_adj_iterator adjacency_iterator; + typedef sgb_vertex_iterator vertex_iterator; + typedef void edge_iterator; + typedef long vertices_size_type; + typedef long edge_size_type; + typedef long degree_size_type; + typedef directed_tag directed_category; + typedef sgb_traversal_tag traversal_category; + typedef allow_parallel_edge_tag edge_parallel_category; + }; + template <> struct graph_traits { + typedef Vertex* vertex_descriptor; + typedef boost::sgb_edge edge_descriptor; + typedef sgb_out_edge_iterator out_edge_iterator; + typedef void in_edge_iterator; + typedef sgb_adj_iterator adjacency_iterator; + typedef sgb_vertex_iterator vertex_iterator; + typedef void edge_iterator; + typedef long vertices_size_type; + typedef long edge_size_type; + typedef long degree_size_type; + typedef directed_tag directed_category; + typedef sgb_traversal_tag traversal_category; + typedef allow_parallel_edge_tag edge_parallel_category; + }; +} + +namespace boost { + + struct edge_length_t { + typedef edge_property_tag kind; + }; + + // We could just use Arc* as the edge descriptor type, but + // we want to add the source(e,g) function which requires + // that we carry along a pointer to the source vertex. + class sgb_edge { + typedef sgb_edge self; + public: + sgb_edge() : _arc(0), _src(0) { } + sgb_edge(Arc* a, Vertex* s) : _arc(a), _src(s) { } + friend Vertex* source(self e, sgb_const_graph_ptr) { return e._src; } + friend Vertex* target(self e, sgb_const_graph_ptr) { return e._arc->tip; } + friend bool operator==(const self& a, const self& b) { + return a._arc == b._arc; } + friend bool operator!=(const self& a, const self& b) { + return a._arc != b._arc; } +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template friend class sgb_edge_length_map; + template friend class sgb_edge_util_map; + friend long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key); + friend long get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key); + friend void put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value); + protected: +#endif + Arc* _arc; + Vertex* _src; + }; +} // namespace boost + + class sgb_out_edge_iterator + : public boost::forward_iterator_helper< + sgb_out_edge_iterator, boost::sgb_edge, + std::ptrdiff_t, boost::sgb_edge*, boost::sgb_edge> + { + typedef sgb_out_edge_iterator self; + public: + sgb_out_edge_iterator() : _src(0), _arc(0) {} + sgb_out_edge_iterator(Vertex* s, Arc* d) : _src(s), _arc(d) {} + boost::sgb_edge operator*() { return boost::sgb_edge(_arc, _src); } + self& operator++() { _arc = _arc->next; return *this; } + friend bool operator==(const self& x, const self& y) { + return x._arc == y._arc; } + protected: + Vertex* _src; + Arc* _arc; + }; + + class sgb_adj_iterator + : public boost::forward_iterator_helper< + sgb_adj_iterator, Vertex*, std::ptrdiff_t, Vertex**,Vertex*> + { + typedef sgb_adj_iterator self; + public: + sgb_adj_iterator() : _arc(0) {} + sgb_adj_iterator(Arc* d) : _arc(d) {} + Vertex* operator*() { return _arc->tip; } + self& operator++() { _arc = _arc->next; return *this; } + friend bool operator==(const self& x, const self& y) { + return x._arc == y._arc; } + protected: + Arc* _arc; + }; + + // The reason we have this instead of just using Vertex* is that we + // want to use Vertex* as the vertex_descriptor instead of just + // Vertex, which avoids problems with boost passing vertex descriptors + // by value and how that interacts with the sgb_vertex_id_map. + class sgb_vertex_iterator + : public boost::forward_iterator_helper< + sgb_vertex_iterator, Vertex*, std::ptrdiff_t, Vertex**, Vertex*> + { + typedef sgb_vertex_iterator self; + public: + sgb_vertex_iterator() : _v(0) { } + sgb_vertex_iterator(Vertex* v) : _v(v) { } + Vertex* operator*() { return _v; } + self& operator++() { ++_v; return *this; } + friend bool operator==(const self& x, const self& y) { + return x._v == y._v; } + protected: + Vertex* _v; + }; + +namespace boost { + + inline std::pair + vertices(sgb_const_graph_ptr g) + { + return std::make_pair(sgb_vertex_iterator(g->vertices), + sgb_vertex_iterator(g->vertices + g->n)); + } + + inline std::pair + out_edges(Vertex* u, sgb_const_graph_ptr) + { + return std::make_pair( sgb_out_edge_iterator(u, u->arcs), + sgb_out_edge_iterator(u, 0) ); + } + + inline boost::graph_traits::degree_size_type + out_degree(Vertex* u, sgb_const_graph_ptr g) + { + boost::graph_traits::out_edge_iterator i, i_end; + boost::tie(i, i_end) = out_edges(u, g); + return std::distance(i, i_end); + } + + // in_edges? + + inline std::pair + adjacent_vertices(Vertex* u, sgb_const_graph_ptr) + { + return std::make_pair( sgb_adj_iterator(u->arcs), + sgb_adj_iterator(0) ); + } + + inline long num_vertices(sgb_const_graph_ptr g) { return g->n; } + inline long num_edges(sgb_const_graph_ptr g) { return g->m; } + + inline Vertex* vertex(long v, sgb_const_graph_ptr g) + { return g->vertices + v; } + + // Various Property Maps + + // Vertex ID + class sgb_vertex_id_map + : public boost::put_get_helper + { + public: + typedef boost::readable_property_map_tag category; + typedef long value_type; + typedef long reference; + typedef Vertex* key_type; + sgb_vertex_id_map() : _g(0) { } + sgb_vertex_id_map(sgb_graph_ptr g) : _g(g) { } + long operator[](Vertex* v) const { return v - _g->vertices; } + protected: + sgb_graph_ptr _g; + }; + inline sgb_vertex_id_map get(vertex_index_t, sgb_graph_ptr g) { + return sgb_vertex_id_map(g); + } + + // Vertex Name + class sgb_vertex_name_map + : public boost::put_get_helper + { + public: + typedef boost::readable_property_map_tag category; + typedef char* value_type; + typedef char* reference; + typedef Vertex* key_type; + char* operator[](Vertex* v) const { return v->name; } + }; + inline sgb_vertex_name_map get(vertex_name_t, sgb_graph_ptr) { + return sgb_vertex_name_map(); + } + + // Vertex Property Tags +#define SGB_PROPERTY_TAG(KIND,TAG) \ + template struct TAG##_property { \ + typedef KIND##_property_tag kind; \ + typedef T type; \ + }; + SGB_PROPERTY_TAG(vertex, u) + SGB_PROPERTY_TAG(vertex, v) + SGB_PROPERTY_TAG(vertex, w) + SGB_PROPERTY_TAG(vertex, x) + SGB_PROPERTY_TAG(vertex, y) + SGB_PROPERTY_TAG(vertex, z) + + // Edge Property Tags + SGB_PROPERTY_TAG(edge, a) + SGB_PROPERTY_TAG(edge, b) + + // Various Utility Maps + + // helpers + inline Vertex*& get_util(util& u, Vertex*) { return u.V; } + inline Arc*& get_util(util& u, Arc*) { return u.A; } + inline sgb_graph_ptr& get_util(util& u, sgb_graph_ptr) { return u.G; } + inline char*& get_util(util& u, char*) { return u.S; } + inline long& get_util(util& u, long) { return u.I; } + +#define SGB_GET_UTIL_FIELD(KIND,X) \ + template \ + inline T& get_util_field(KIND* k, X##_property) { \ + return get_util(k->X, T()); } + + SGB_GET_UTIL_FIELD(Vertex, u) + SGB_GET_UTIL_FIELD(Vertex, v) + SGB_GET_UTIL_FIELD(Vertex, w) + SGB_GET_UTIL_FIELD(Vertex, x) + SGB_GET_UTIL_FIELD(Vertex, y) + SGB_GET_UTIL_FIELD(Vertex, z) + + SGB_GET_UTIL_FIELD(Arc, a) + SGB_GET_UTIL_FIELD(Arc, b) + + // Vertex Utility Map + template + class sgb_vertex_util_map + : public boost::put_get_helper > + { + public: + typedef boost::lvalue_property_map_tag category; + typedef typename Tag::type value_type; + typedef Vertex* key_type; + typedef Ref reference; + reference operator[](Vertex* v) const { + return get_util_field(v, Tag()); + } + }; + + // Edge Utility Map + template + class sgb_edge_util_map + : public boost::put_get_helper > + { + public: + typedef boost::lvalue_property_map_tag category; + typedef typename Tag::type value_type; + typedef Vertex* key_type; + typedef Ref reference; + reference operator[](const sgb_edge& e) const { + return get_util_field(e._arc, Tag()); + } + }; + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + inline sgb_vertex_util_map + get_property_map(Tag, const sgb_graph_ptr& g, vertex_property_tag) { + return sgb_vertex_util_map(); + } + template + inline sgb_vertex_util_map + get_property_map(Tag, sgb_graph_ptr& g, vertex_property_tag) { + return sgb_vertex_util_map(); + } + + template + inline sgb_edge_util_map + get_property_map(Tag, const sgb_graph_ptr& g, edge_property_tag) { + return sgb_edge_util_map(); + } + template + inline sgb_edge_util_map + get_property_map(Tag, sgb_graph_ptr& g, edge_property_tag) { + return sgb_edge_util_map(); + } + +#endif // ! BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // Edge Length Access + template + class sgb_edge_length_map + : public boost::put_get_helper > + { + public: + typedef boost::lvalue_property_map_tag category; + typedef long value_type; + typedef sgb_edge key_type; + typedef Ref reference; + reference operator[](const sgb_edge& e) const { + return e._arc->len; + } + }; + + inline sgb_edge_length_map + get(edge_length_t, const sgb_graph_ptr&) { + return sgb_edge_length_map(); + } + inline sgb_edge_length_map + get(edge_length_t, const sgb_const_graph_ptr&) { + return sgb_edge_length_map(); + } + inline sgb_edge_length_map + get(edge_length_t, sgb_graph_ptr&) { + return sgb_edge_length_map(); + } + inline long + get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key) { + return key._arc->len; + } + inline long + get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key) { + return key._arc->len; + } + inline void + put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value) + { + key._arc->len = value; + } + + // Property Map Traits Classes + template <> + struct property_map { + typedef sgb_edge_length_map type; + typedef sgb_edge_length_map const_type; + }; + template <> + struct property_map { + typedef sgb_vertex_id_map type; + typedef sgb_vertex_id_map const_type; + }; + template <> + struct property_map { + typedef sgb_vertex_name_map type; + typedef sgb_vertex_name_map const_type; + }; + + template <> + struct property_map { + typedef sgb_edge_length_map const_type; + }; + template <> + struct property_map { + typedef sgb_vertex_id_map const_type; + }; + template <> + struct property_map { + typedef sgb_vertex_name_map const_type; + }; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + namespace detail { + template + struct sgb_choose_property_map { }; + template + struct sgb_choose_property_map { + typedef typename PropertyTag::type value_type; + typedef sgb_vertex_util_map type; + typedef sgb_vertex_util_map const_type; + }; + template + struct sgb_choose_property_map { + typedef typename PropertyTag::type value_type; + typedef sgb_edge_util_map type; + typedef sgb_edge_util_map const_type; + }; + } // namespace detail + template + struct property_map { + typedef typename property_kind::type Kind; + typedef detail::sgb_choose_property_map Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + template + struct property_map { + typedef typename property_kind::type Kind; + typedef detail::sgb_choose_property_map Choice; + typedef typename Choice::const_type const_type; + }; + +#define SGB_UTIL_ACCESSOR(KIND,X) \ + template \ + inline sgb_##KIND##_util_map< X##_property, T&> \ + get(X##_property, sgb_graph_ptr&) { \ + return sgb_##KIND##_util_map< X##_property, T&>(); \ + } \ + template \ + inline sgb_##KIND##_util_map< X##_property, const T&> \ + get(X##_property, const sgb_graph_ptr&) { \ + return sgb_##KIND##_util_map< X##_property, const T&>(); \ + } \ + template \ + inline sgb_##KIND##_util_map< X##_property, const T&> \ + get(X##_property, const sgb_const_graph_ptr&) { \ + return sgb_##KIND##_util_map< X##_property, const T&>(); \ + } \ + template \ + inline typename \ + sgb_##KIND##_util_map< X##_property, const T&>::value_type \ + get(X##_property, const sgb_graph_ptr&, const Key& key) { \ + return sgb_##KIND##_util_map< X##_property, const T&>()[key]; \ + } \ + template \ + inline typename \ + sgb_##KIND##_util_map< X##_property, const T&>::value_type \ + get(X##_property, const sgb_const_graph_ptr&, const Key& key) { \ + return sgb_##KIND##_util_map< X##_property, const T&>()[key]; \ + } \ + template \ + inline void \ + put(X##_property, sgb_graph_ptr&, const Key& key, const Value& value) { \ + sgb_##KIND##_util_map< X##_property, T&>()[key] = value; \ + } + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#define SGB_UTIL_ACCESSOR_TYPE(KIND,TAG,TYPE) \ + inline sgb_##KIND##_util_map< TAG, TYPE& > \ + get(TAG, sgb_graph_ptr&) { \ + return sgb_##KIND##_util_map< TAG, TYPE& >(); \ + } \ + inline sgb_##KIND##_util_map< TAG, const TYPE& > \ + get(TAG, const sgb_graph_ptr&) { \ + return sgb_##KIND##_util_map< TAG, const TYPE& >(); \ + } \ + inline sgb_##KIND##_util_map< TAG, const TYPE& > \ + get(TAG, const sgb_const_graph_ptr&) { \ + return sgb_##KIND##_util_map< TAG, const TYPE& >(); \ + } \ + template \ + inline typename sgb_##KIND##_util_map< TAG, const TYPE& >::value_type \ + get(TAG, const sgb_graph_ptr&, const Key& key) { \ + return sgb_##KIND##_util_map< TAG, const TYPE& >()[key]; \ + } \ + template \ + inline typename sgb_##KIND##_util_map< TAG, const TYPE& >::value_type \ + get(TAG, const sgb_const_graph_ptr&, const Key& key) { \ + return sgb_##KIND##_util_map< TAG, const TYPE& >()[key]; \ + } \ + template \ + inline void \ + put(TAG, sgb_graph_ptr&, const Key& key, const Value& value) { \ + sgb_##KIND##_util_map< TAG, TYPE& >()[key] = value; \ + } \ + template <> struct property_map > { \ + typedef sgb_##KIND##_util_map< TAG, TYPE&> type; \ + typedef sgb_##KIND##_util_map< TAG, const TYPE&> const_type; \ + } + +#define SGB_UTIL_ACCESSOR(KIND,TAG) \ + SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Vertex*); \ + SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Arc*); \ + SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, sgb_graph_ptr); \ + SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, long); \ + SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, char*); + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + SGB_UTIL_ACCESSOR(vertex, u) + SGB_UTIL_ACCESSOR(vertex, v) + SGB_UTIL_ACCESSOR(vertex, w) + SGB_UTIL_ACCESSOR(vertex, x) + SGB_UTIL_ACCESSOR(vertex, y) + SGB_UTIL_ACCESSOR(vertex, z) + + SGB_UTIL_ACCESSOR(edge, a) + SGB_UTIL_ACCESSOR(edge, b) + +} // namespace boost + +#endif // BOOST_GRAPH_SGB_GRAPH_HPP diff --git a/thirdparty/boost/graph/strong_components.hpp b/thirdparty/boost/graph/strong_components.hpp new file mode 100644 index 0000000..7fdfcdb --- /dev/null +++ b/thirdparty/boost/graph/strong_components.hpp @@ -0,0 +1,334 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_GRAPH_STRONG_COMPONENTS_HPP +#define BOOST_GRAPH_STRONG_COMPONENTS_HPP + +#include +#include +#include +#include +#include + +namespace boost { + + //========================================================================== + // This is Tarjan's algorithm for strongly connected components + // from his paper "Depth first search and linear graph algorithms". + // It calculates the components in a single application of DFS. + // We implement the algorithm as a dfs-visitor. + + namespace detail { + + template + class tarjan_scc_visitor : public dfs_visitor<> + { + typedef typename property_traits::value_type comp_type; + typedef typename property_traits::value_type time_type; + public: + tarjan_scc_visitor(ComponentMap comp_map, RootMap r, DiscoverTime d, + comp_type& c_, Stack& s_) + : c(c_), comp(comp_map), root(r), discover_time(d), + dfs_time(time_type()), s(s_) { } + + template + void discover_vertex(typename graph_traits::vertex_descriptor v, + const Graph&) { + put(root, v, v); + put(comp, v, (std::numeric_limits::max)()); + put(discover_time, v, dfs_time++); + s.push(v); + } + template + void finish_vertex(typename graph_traits::vertex_descriptor v, + const Graph& g) { + typename graph_traits::vertex_descriptor w; + typename graph_traits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { + w = target(*ei, g); + if (get(comp, w) == (std::numeric_limits::max)()) + put(root, v, this->min_discover_time(get(root,v), get(root,w))); + } + if (get(root, v) == v) { + do { + w = s.top(); s.pop(); + put(comp, w, c); + } while (w != v); + ++c; + } + } + private: + template + Vertex min_discover_time(Vertex u, Vertex v) { + return get(discover_time, u) < get(discover_time,v) ? u : v; + } + + comp_type& c; + ComponentMap comp; + RootMap root; + DiscoverTime discover_time; + time_type dfs_time; + Stack& s; + }; + + template + typename property_traits::value_type + strong_components_impl + (const Graph& g, // Input + ComponentMap comp, // Output + // Internal record keeping + RootMap root, + DiscoverTime discover_time, + const bgl_named_params& params) + { + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadWritePropertyMapConcept >(); + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type RootV; + function_requires< ConvertibleConcept >(); + function_requires< ReadWritePropertyMapConcept >(); + + typename property_traits::value_type total = 0; + + std::stack s; + detail::tarjan_scc_visitor > + vis(comp, root, discover_time, total, s); + depth_first_search(g, params.visitor(vis)); + return total; + } + + //------------------------------------------------------------------------- + // The dispatch functions handle the defaults for the rank and discover + // time property maps. + // dispatch with class specialization to avoid VC++ bug + + template + struct strong_comp_dispatch2 { + template + inline static typename property_traits::value_type + apply(const Graph& g, + ComponentMap comp, + RootMap r_map, + const bgl_named_params& params, + DiscoverTimeMap time_map) + { + return strong_components_impl(g, comp, r_map, time_map, params); + } + }; + + + template <> + struct strong_comp_dispatch2 { + template + inline static typename property_traits::value_type + apply(const Graph& g, + ComponentMap comp, + RootMap r_map, + const bgl_named_params& params, + detail::error_property_not_found) + { + typedef typename graph_traits::vertices_size_type size_type; + size_type n = num_vertices(g) > 0 ? num_vertices(g) : 1; + std::vector time_vec(n); + return strong_components_impl + (g, comp, r_map, + make_iterator_property_map(time_vec.begin(), choose_const_pmap + (get_param(params, vertex_index), + g, vertex_index), time_vec[0]), + params); + } + }; + + template + inline typename property_traits::value_type + scc_helper2(const Graph& g, + ComponentMap comp, + RootMap r_map, + const bgl_named_params& params, + DiscoverTimeMap time_map) + { + return strong_comp_dispatch2::apply(g, comp, r_map, params, time_map); + } + + template + struct strong_comp_dispatch1 { + + template + inline static typename property_traits::value_type + apply(const Graph& g, + ComponentMap comp, + const bgl_named_params& params, + RootMap r_map) + { + return scc_helper2(g, comp, r_map, params, get_param(params, vertex_discover_time)); + } + }; + template <> + struct strong_comp_dispatch1 { + + template + inline static typename property_traits::value_type + apply(const Graph& g, + ComponentMap comp, + const bgl_named_params& params, + detail::error_property_not_found) + { + typedef typename graph_traits::vertex_descriptor Vertex; + typename std::vector::size_type + n = num_vertices(g) > 0 ? num_vertices(g) : 1; + std::vector root_vec(n); + return scc_helper2 + (g, comp, + make_iterator_property_map(root_vec.begin(), choose_const_pmap + (get_param(params, vertex_index), + g, vertex_index), root_vec[0]), + params, + get_param(params, vertex_discover_time)); + } + }; + + template + inline typename property_traits::value_type + scc_helper1(const Graph& g, + ComponentMap comp, + const bgl_named_params& params, + RootMap r_map) + { + return detail::strong_comp_dispatch1::apply(g, comp, params, + r_map); + } + + } // namespace detail + + template + inline typename property_traits::value_type + strong_components(const Graph& g, ComponentMap comp, + const bgl_named_params& params) + { + typedef typename graph_traits::directed_category DirCat; + BOOST_STATIC_ASSERT((is_convertible::value == true)); + return detail::scc_helper1(g, comp, params, + get_param(params, vertex_root_t())); + } + + template + inline typename property_traits::value_type + strong_components(const Graph& g, ComponentMap comp) + { + typedef typename graph_traits::directed_category DirCat; + BOOST_STATIC_ASSERT((is_convertible::value == true)); + bgl_named_params params(0); + return strong_components(g, comp, params); + } + + template + void build_component_lists + (const Graph& g, + typename graph_traits::vertices_size_type num_scc, + ComponentMap component_number, + ComponentLists& components) + { + components.resize(num_scc); + typename graph_traits::vertex_iterator vi, vi_end; + for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + components[component_number[*vi]].push_back(*vi); + } + + +} // namespace boost + +#include +#include +#include +#include +#include // for components_recorder + +namespace boost { + + //========================================================================== + // This is the version of strongly connected components from + // "Intro. to Algorithms" by Cormen, Leiserson, Rivest, which was + // adapted from "Data Structure and Algorithms" by Aho, Hopcroft, + // and Ullman, who credit the algorithm to S.R. Kosaraju and M. Sharir. + // The algorithm is based on computing DFS forests the graph + // and its transpose. + + // This algorithm is slower than Tarjan's by a constant factor, uses + // more memory, and puts more requirements on the graph type. + + template + typename property_traits::value_type + kosaraju_strong_components(Graph& G, ComponentsMap c, + FinishTime finish_time, ColorMap color) + { + function_requires< MutableGraphConcept >(); + // ... + + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename property_traits::value_type time = 0; + depth_first_search + (G, make_dfs_visitor(stamp_times(finish_time, time, on_finish_vertex())), + color); + + Graph G_T(num_vertices(G)); + transpose_graph(G, G_T); + + typedef typename property_traits::value_type count_type; + + count_type c_count(0); + detail::components_recorder + vis(c, c_count); + + // initialize G_T + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(G_T); ui != ui_end; ++ui) + put(color, *ui, Color::white()); + + typedef typename property_traits::value_type D; + typedef indirect_cmp< FinishTime, std::less > Compare; + + Compare fl(finish_time); + std::priority_queue, Compare > Q(fl); + + typename graph_traits::vertex_iterator i, j, iend, jend; + tie(i, iend) = vertices(G_T); + tie(j, jend) = vertices(G); + for ( ; i != iend; ++i, ++j) { + put(finish_time, *i, get(finish_time, *j)); + Q.push(*i); + } + + while ( !Q.empty() ) { + Vertex u = Q.top(); + Q.pop(); + if (get(color, u) == Color::white()) { + depth_first_visit(G_T, u, vis, color); + ++c_count; + } + } + return c_count; + } + +} // namespace boost + +#endif // BOOST_GRAPH_STRONG_COMPONENTS_HPP diff --git a/thirdparty/boost/graph/subgraph.hpp b/thirdparty/boost/graph/subgraph.hpp new file mode 100644 index 0000000..e926f51 --- /dev/null +++ b/thirdparty/boost/graph/subgraph.hpp @@ -0,0 +1,872 @@ +//======================================================================= +// Copyright 2001 University of Notre Dame. +// Authors: Jeremy G. Siek and Lie-Quan Lee +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef BOOST_SUBGRAPH_HPP +#define BOOST_SUBGRAPH_HPP + +// UNDER CONSTRUCTION + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { + + struct subgraph_tag { }; + + // Invariants of an induced subgraph: + // - If vertex u is in subgraph g, then u must be in g.parent(). + // - If edge e is in subgraph g, then e must be in g.parent(). + // - If edge e=(u,v) is in the root graph, then edge e + // is also in any subgraph that contains both vertex u and v. + + // The Graph template parameter must have a vertex_index + // and edge_index internal property. It is assumed that + // the vertex indices are assigned automatically by the + // graph during a call to add_vertex(). It is not + // assumed that the edge vertices are assigned automatically, + // they are explicitly assigned here. + + template + class subgraph { + typedef graph_traits Traits; + typedef std::list*> ChildrenList; + public: + // Graph requirements + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::traversal_category traversal_category; + + static vertex_descriptor null_vertex() + { + return Traits::null_vertex(); + } + + + // IncidenceGraph requirements + typedef typename Traits::out_edge_iterator out_edge_iterator; + typedef typename Traits::degree_size_type degree_size_type; + + // AdjacencyGraph requirements + typedef typename Traits::adjacency_iterator adjacency_iterator; + + // VertexListGraph requirements + typedef typename Traits::vertex_iterator vertex_iterator; + typedef typename Traits::vertices_size_type vertices_size_type; + + // EdgeListGraph requirements + typedef typename Traits::edge_iterator edge_iterator; + typedef typename Traits::edges_size_type edges_size_type; + + typedef typename Traits::in_edge_iterator in_edge_iterator; + + typedef typename Graph::edge_property_type edge_property_type; + typedef typename Graph::vertex_property_type vertex_property_type; + typedef subgraph_tag graph_tag; + typedef Graph graph_type; + typedef typename Graph::graph_property_type graph_property_type; + + // Constructors + + // Create the main graph, the root of the subgraph tree + subgraph() + : m_parent(0), m_edge_counter(0) + { } + subgraph(const graph_property_type& p) + : m_graph(p), m_parent(0), m_edge_counter(0) + { } + subgraph(vertices_size_type n, + const graph_property_type& p = graph_property_type()) + : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n) + { + typename Graph::vertex_iterator v, v_end; + vertices_size_type i = 0; + for (tie(v, v_end) = vertices(m_graph); v != v_end; ++v) + m_global_vertex[i++] = *v; + } + + // copy constructor + subgraph(const subgraph& x) + : m_graph(x.m_graph), m_parent(x.m_parent), + m_edge_counter(x.m_edge_counter), + m_global_vertex(x.m_global_vertex), + m_global_edge(x.m_global_edge) + { + // Do a deep copy + for (typename ChildrenList::const_iterator i = x.m_children.begin(); + i != x.m_children.end(); ++i) + m_children.push_back(new subgraph( **i )); + } + + + ~subgraph() { + for (typename ChildrenList::iterator i = m_children.begin(); + i != m_children.end(); ++i) + delete *i; + } + + + // Create a subgraph + subgraph& create_subgraph() { + m_children.push_back(new subgraph()); + m_children.back()->m_parent = this; + return *m_children.back(); + } + + // Create a subgraph with the specified vertex set. + template + subgraph& create_subgraph(VertexIterator first, + VertexIterator last) + { + m_children.push_back(new subgraph()); + m_children.back()->m_parent = this; + for (; first != last; ++first) + add_vertex(*first, *m_children.back()); + return *m_children.back(); + } + + // local <-> global descriptor conversion functions + vertex_descriptor local_to_global(vertex_descriptor u_local) const + { + return m_global_vertex[u_local]; + } + vertex_descriptor global_to_local(vertex_descriptor u_global) const + { + vertex_descriptor u_local; bool in_subgraph; + tie(u_local, in_subgraph) = this->find_vertex(u_global); + assert(in_subgraph == true); + return u_local; + } + edge_descriptor local_to_global(edge_descriptor e_local) const + { + return m_global_edge[get(get(edge_index, m_graph), e_local)]; + } + edge_descriptor global_to_local(edge_descriptor e_global) const + { + return + (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second; + } + + // Is vertex u (of the root graph) contained in this subgraph? + // If so, return the matching local vertex. + std::pair + find_vertex(vertex_descriptor u_global) const + { + typename std::map::const_iterator + i = m_local_vertex.find(u_global); + bool valid = i != m_local_vertex.end(); + return std::make_pair((valid ? (*i).second : null_vertex()), valid); + } + + // Return the parent graph. + subgraph& parent() { return *m_parent; } + const subgraph& parent() const { return *m_parent; } + + bool is_root() const { return m_parent == 0; } + + // Return the root graph of the subgraph tree. + subgraph& root() { + if (this->is_root()) + return *this; + else + return m_parent->root(); + } + const subgraph& root() const { + if (this->is_root()) + return *this; + else + return m_parent->root(); + } + + // Return the children subgraphs of this graph/subgraph. + // Use a list of pointers because the VC++ std::list doesn't like + // storing incomplete type. + typedef indirect_iterator< + typename ChildrenList::const_iterator + , subgraph + , std::bidirectional_iterator_tag + > + children_iterator; + + typedef indirect_iterator< + typename ChildrenList::const_iterator + , subgraph const + , std::bidirectional_iterator_tag + > + const_children_iterator; + + std::pair + children() const + { + return std::make_pair(const_children_iterator(m_children.begin()), + const_children_iterator(m_children.end())); + } + + std::pair + children() + { + return std::make_pair(children_iterator(m_children.begin()), + children_iterator(m_children.end())); + } + + std::size_t num_children() const { return m_children.size(); } + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + // Bundled properties support + template + typename graph::detail::bundled_result::type& + operator[](Descriptor x) + { + if (m_parent == 0) return m_graph[x]; + else return root().m_graph[local_to_global(x)]; + } + + template + typename graph::detail::bundled_result::type const& + operator[](Descriptor x) const + { + if (m_parent == 0) return m_graph[x]; + else return root().m_graph[local_to_global(x)]; + } +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + + // private: + typedef typename property_map::type EdgeIndexMap; + typedef typename property_traits::value_type edge_index_type; + BOOST_STATIC_ASSERT((!is_same::value)); + + Graph m_graph; + subgraph* m_parent; + edge_index_type m_edge_counter; // for generating unique edge indices + ChildrenList m_children; + std::vector m_global_vertex; // local -> global + std::map m_local_vertex; // global -> local + std::vector m_global_edge; // local -> global + std::map m_local_edge; // global -> local + + edge_descriptor + local_add_edge(vertex_descriptor u_local, vertex_descriptor v_local, + edge_descriptor e_global) + { + edge_descriptor e_local; + bool inserted; + tie(e_local, inserted) = add_edge(u_local, v_local, m_graph); + put(edge_index, m_graph, e_local, m_edge_counter++); + m_global_edge.push_back(e_global); + m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local; + return e_local; + } + + }; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct vertex_bundle_type > : vertex_bundle_type { }; + + template + struct edge_bundle_type > : edge_bundle_type { }; +#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + + //=========================================================================== + // Functions special to the Subgraph Class + + template + typename subgraph::vertex_descriptor + add_vertex(typename subgraph::vertex_descriptor u_global, + subgraph& g) + { + assert(!g.is_root()); + typename subgraph::vertex_descriptor u_local, v_global, uu_global; + typename subgraph::edge_descriptor e_global; + + u_local = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + g.m_local_vertex[u_global] = u_local; + + subgraph& r = g.root(); + + // remember edge global and local maps + { + typename subgraph::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(u_global, r); + ei != ei_end; ++ei) { + e_global = *ei; + v_global = target(e_global, r); + if (g.find_vertex(v_global).second == true) + g.local_add_edge(u_local, g.global_to_local(v_global), e_global); + } + } + if (is_directed(g)) { // not necessary for undirected graph + typename subgraph::vertex_iterator vi, vi_end; + typename subgraph::out_edge_iterator ei, ei_end; + for (tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) { + v_global = *vi; + if (g.find_vertex(v_global).second) + for (tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) { + e_global = *ei; + uu_global = target(e_global, r); + if (uu_global == u_global && g.find_vertex(v_global).second) + g.local_add_edge(g.global_to_local(v_global), u_local, e_global); + } + } + } + + return u_local; + } + + //=========================================================================== + // Functions required by the IncidenceGraph concept + + template + std::pair::out_edge_iterator, + typename graph_traits::out_edge_iterator> + out_edges(typename graph_traits::vertex_descriptor u_local, + const subgraph& g) + { return out_edges(u_local, g.m_graph); } + + template + typename graph_traits::degree_size_type + out_degree(typename graph_traits::vertex_descriptor u_local, + const subgraph& g) + { return out_degree(u_local, g.m_graph); } + + template + typename graph_traits::vertex_descriptor + source(typename graph_traits::edge_descriptor e_local, + const subgraph& g) + { return source(e_local, g.m_graph); } + + template + typename graph_traits::vertex_descriptor + target(typename graph_traits::edge_descriptor e_local, + const subgraph& g) + { return target(e_local, g.m_graph); } + + //=========================================================================== + // Functions required by the BidirectionalGraph concept + + template + std::pair::in_edge_iterator, + typename graph_traits::in_edge_iterator> + in_edges(typename graph_traits::vertex_descriptor u_local, + const subgraph& g) + { return in_edges(u_local, g.m_graph); } + + template + typename graph_traits::degree_size_type + in_degree(typename graph_traits::vertex_descriptor u_local, + const subgraph& g) + { return in_degree(u_local, g.m_graph); } + + template + typename graph_traits::degree_size_type + degree(typename graph_traits::vertex_descriptor u_local, + const subgraph& g) + { return degree(u_local, g.m_graph); } + + //=========================================================================== + // Functions required by the AdjacencyGraph concept + + template + std::pair::adjacency_iterator, + typename subgraph::adjacency_iterator> + adjacent_vertices(typename subgraph::vertex_descriptor u_local, + const subgraph& g) + { return adjacent_vertices(u_local, g.m_graph); } + + //=========================================================================== + // Functions required by the VertexListGraph concept + + template + std::pair::vertex_iterator, + typename subgraph::vertex_iterator> + vertices(const subgraph& g) + { return vertices(g.m_graph); } + + template + typename subgraph::vertices_size_type + num_vertices(const subgraph& g) + { return num_vertices(g.m_graph); } + + //=========================================================================== + // Functions required by the EdgeListGraph concept + + template + std::pair::edge_iterator, + typename subgraph::edge_iterator> + edges(const subgraph& g) + { return edges(g.m_graph); } + + template + typename subgraph::edges_size_type + num_edges(const subgraph& g) + { return num_edges(g.m_graph); } + + //=========================================================================== + // Functions required by the AdjacencyMatrix concept + + template + std::pair::edge_descriptor, bool> + edge(typename subgraph::vertex_descriptor u_local, + typename subgraph::vertex_descriptor v_local, + const subgraph& g) + { + return edge(u_local, v_local, g.m_graph); + } + + //=========================================================================== + // Functions required by the MutableGraph concept + + namespace detail { + + template + void add_edge_recur_down + (Vertex u_global, Vertex v_global, Edge e_global, subgraph& g); + + template + void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global, + Children& c, subgraph* orig) + { + for (typename Children::iterator i = c.begin(); i != c.end(); ++i) + if ((*i)->find_vertex(u_global).second + && (*i)->find_vertex(v_global).second) + add_edge_recur_down(u_global, v_global, e_global, **i, orig); + } + + template + void add_edge_recur_down + (Vertex u_global, Vertex v_global, Edge e_global, subgraph& g, + subgraph* orig) + { + if (&g != orig ) { + // add local edge only if u_global and v_global are in subgraph g + Vertex u_local, v_local; + bool u_in_subgraph, v_in_subgraph; + tie(u_local, u_in_subgraph) = g.find_vertex(u_global); + tie(v_local, v_in_subgraph) = g.find_vertex(v_global); + if (u_in_subgraph && v_in_subgraph) + g.local_add_edge(u_local, v_local, e_global); + } + children_add_edge(u_global, v_global, e_global, g.m_children, orig); + } + + template + std::pair::edge_descriptor, bool> + add_edge_recur_up(Vertex u_global, Vertex v_global, + const typename Graph::edge_property_type& ep, + subgraph& g, subgraph* orig) + { + if (g.is_root()) { + typename subgraph::edge_descriptor e_global; + bool inserted; + tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph); + put(edge_index, g.m_graph, e_global, g.m_edge_counter++); + g.m_global_edge.push_back(e_global); + children_add_edge(u_global, v_global, e_global, g.m_children, orig); + return std::make_pair(e_global, inserted); + } else + return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig); + } + + } // namespace detail + + // Add an edge to the subgraph g, specified by the local vertex + // descriptors u and v. In addition, the edge will be added to any + // other subgraphs which contain vertex descriptors u and v. + + template + std::pair::edge_descriptor, bool> + add_edge(typename subgraph::vertex_descriptor u_local, + typename subgraph::vertex_descriptor v_local, + const typename G::edge_property_type& ep, + subgraph& g) + { + if (g.is_root()) // u_local and v_local are really global + return detail::add_edge_recur_up(u_local, v_local, ep, g, &g); + else { + typename subgraph::edge_descriptor e_local, e_global; + bool inserted; + tie(e_global, inserted) = detail::add_edge_recur_up + (g.local_to_global(u_local), g.local_to_global(v_local), ep, g, &g); + e_local = g.local_add_edge(u_local, v_local, e_global); + return std::make_pair(e_local, inserted); + } + } + + template + std::pair::edge_descriptor, bool> + add_edge(typename subgraph::vertex_descriptor u, + typename subgraph::vertex_descriptor v, + subgraph& g) + { + typename G::edge_property_type ep; + return add_edge(u, v, ep, g); + } + + namespace detail { + + //------------------------------------------------------------------------- + // implementation of remove_edge(u,v,g) + + template + void remove_edge_recur_down(Vertex u_global, Vertex v_global, + subgraph& g); + + template + void children_remove_edge(Vertex u_global, Vertex v_global, + Children& c) + { + for (typename Children::iterator i = c.begin(); i != c.end(); ++i) + if ((*i)->find_vertex(u_global).second + && (*i)->find_vertex(v_global).second) + remove_edge_recur_down(u_global, v_global, **i); + } + + template + void remove_edge_recur_down(Vertex u_global, Vertex v_global, + subgraph& g) + { + Vertex u_local, v_local; + u_local = g.m_local_vertex[u_global]; + v_local = g.m_local_vertex[v_global]; + remove_edge(u_local, v_local, g.m_graph); + children_remove_edge(u_global, v_global, g.m_children); + } + + template + void remove_edge_recur_up(Vertex u_global, Vertex v_global, + subgraph& g) + { + if (g.is_root()) { + remove_edge(u_global, v_global, g.m_graph); + children_remove_edge(u_global, v_global, g.m_children); + } else + remove_edge_recur_up(u_global, v_global, *g.m_parent); + } + + //------------------------------------------------------------------------- + // implementation of remove_edge(e,g) + + template + void remove_edge_recur_down(Edge e_global, subgraph& g); + + template + void children_remove_edge(Edge e_global, Children& c) + { + for (typename Children::iterator i = c.begin(); i != c.end(); ++i) + if ((*i)->find_vertex(source(e_global, **i)).second + && (*i)->find_vertex(target(e_global, **i)).second) + remove_edge_recur_down(source(e_global, **i), + target(e_global, **i), **i); + } + + template + void remove_edge_recur_down(Edge e_global, subgraph& g) + { + remove_edge(g.global_to_local(e_global), g.m_graph); + children_remove_edge(e_global, g.m_children); + } + + template + void remove_edge_recur_up(Edge e_global, subgraph& g) + { + if (g.is_root()) { + remove_edge(e_global, g.m_graph); + children_remove_edge(e_global, g.m_children); + } else + remove_edge_recur_up(e_global, *g.m_parent); + } + + } // namespace detail + + template + void + remove_edge(typename subgraph::vertex_descriptor u_local, + typename subgraph::vertex_descriptor v_local, + subgraph& g) + { + if (g.is_root()) + detail::remove_edge_recur_up(u_local, v_local, g); + else + detail::remove_edge_recur_up(g.local_to_global(u_local), + g.local_to_global(v_local), g); + } + + template + void + remove_edge(typename subgraph::edge_descriptor e_local, + subgraph& g) + { + if (g.is_root()) + detail::remove_edge_recur_up(e_local, g); + else + detail::remove_edge_recur_up(g.local_to_global(e_local), g); + } + + template + void + remove_edge_if(Predicate p, subgraph& g) + { + // This is wrong... + remove_edge_if(p, g.m_graph); + } + + template + void + clear_vertex(typename subgraph::vertex_descriptor v_local, + subgraph& g) + { + // this is wrong... + clear_vertex(v_local, g.m_graph); + } + + namespace detail { + + template + typename subgraph::vertex_descriptor + add_vertex_recur_up(subgraph& g) + { + typename subgraph::vertex_descriptor u_local, u_global; + if (g.is_root()) { + u_global = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + } else { + u_global = add_vertex_recur_up(*g.m_parent); + u_local = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + g.m_local_vertex[u_global] = u_local; + } + return u_global; + } + + } // namespace detail + + template + typename subgraph::vertex_descriptor + add_vertex(subgraph& g) + { + typename subgraph::vertex_descriptor u_local, u_global; + if (g.is_root()) { + u_global = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + u_local = u_global; + } else { + u_global = detail::add_vertex_recur_up(g.parent()); + u_local = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + g.m_local_vertex[u_global] = u_local; + } + return u_local; + } + + template + void remove_vertex(typename subgraph::vertex_descriptor u, + subgraph& g) + { + // UNDER CONSTRUCTION + assert(false); + } + + + //=========================================================================== + // Functions required by the PropertyGraph concept + + template + class subgraph_global_property_map + : public put_get_helper< + typename property_traits::reference, + subgraph_global_property_map > + { + typedef property_traits Traits; + public: + typedef typename Traits::category category; + typedef typename Traits::value_type value_type; + typedef typename Traits::key_type key_type; + typedef typename Traits::reference reference; + + subgraph_global_property_map() { } + + subgraph_global_property_map(GraphPtr g) + : m_g(g) { } + + inline reference operator[](key_type e_local) const { + PropertyMap pmap = get(Tag(), m_g->root().m_graph); + if (m_g->m_parent == 0) + return pmap[e_local]; + else + return pmap[m_g->local_to_global(e_local)]; + } + GraphPtr m_g; + }; + + template + class subgraph_local_property_map + : public put_get_helper< + typename property_traits::reference, + subgraph_local_property_map > + { + typedef property_traits Traits; + public: + typedef typename Traits::category category; + typedef typename Traits::value_type value_type; + typedef typename Traits::key_type key_type; + typedef typename Traits::reference reference; + + subgraph_local_property_map() { } + + subgraph_local_property_map(GraphPtr g) + : m_g(g) { } + + inline reference operator[](key_type e_local) const { + PropertyMap pmap = get(Tag(), *m_g); + return pmap[e_local]; + } + GraphPtr m_g; + }; + + namespace detail { + + struct subgraph_any_pmap { + template + class bind_ { + typedef typename SubGraph::graph_type Graph; + typedef SubGraph* SubGraphPtr; + typedef const SubGraph* const_SubGraphPtr; + typedef typename property_map::type PMap; + typedef typename property_map::const_type const_PMap; + public: + typedef subgraph_global_property_map type; + typedef subgraph_global_property_map + const_type; + }; + }; + struct subgraph_id_pmap { + template + struct bind_ { + typedef typename SubGraph::graph_type Graph; + typedef SubGraph* SubGraphPtr; + typedef const SubGraph* const_SubGraphPtr; + typedef typename property_map::type PMap; + typedef typename property_map::const_type const_PMap; + public: + typedef subgraph_local_property_map type; + typedef subgraph_local_property_map + const_type; + }; + }; + template + struct subgraph_choose_pmap_helper { + typedef subgraph_any_pmap type; + }; + template <> + struct subgraph_choose_pmap_helper { + typedef subgraph_id_pmap type; + }; + template + struct subgraph_choose_pmap { + typedef typename subgraph_choose_pmap_helper::type Helper; + typedef typename Helper::template bind_ Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + struct subgraph_property_generator { + template + struct bind_ { + typedef subgraph_choose_pmap Choice; + typedef typename Choice::type type; + typedef typename Choice::const_type const_type; + }; + }; + + } // namespace detail + + template <> + struct vertex_property_selector { + typedef detail::subgraph_property_generator type; + }; + + template <> + struct edge_property_selector { + typedef detail::subgraph_property_generator type; + }; + + template + typename property_map< subgraph, Property>::type + get(Property, subgraph& g) + { + typedef typename property_map< subgraph, Property>::type PMap; + return PMap(&g); + } + + template + typename property_map< subgraph, Property>::const_type + get(Property, const subgraph& g) + { + typedef typename property_map< subgraph, Property>::const_type PMap; + return PMap(&g); + } + + template + typename property_traits< + typename property_map< subgraph, Property>::const_type + >::value_type + get(Property, const subgraph& g, const Key& k) + { + typedef typename property_map< subgraph, Property>::const_type PMap; + PMap pmap(&g); + return pmap[k]; + } + + template + void + put(Property, subgraph& g, const Key& k, const Value& val) + { + typedef typename property_map< subgraph, Property>::type PMap; + PMap pmap(&g); + pmap[k] = val; + } + + template + inline + typename graph_property::type& + get_property(subgraph& g, Tag tag) { + return get_property(g.m_graph, tag); + } + + template + inline + const typename graph_property::type& + get_property(const subgraph& g, Tag tag) { + return get_property(g.m_graph, tag); + } + + //=========================================================================== + // Miscellaneous Functions + + template + typename subgraph::vertex_descriptor + vertex(typename subgraph::vertices_size_type n, const subgraph& g) + { + return vertex(n, g.m_graph); + } + +} // namespace boost + +#endif // BOOST_SUBGRAPH_HPP diff --git a/thirdparty/boost/graph/topological_sort.hpp b/thirdparty/boost/graph/topological_sort.hpp new file mode 100644 index 0000000..3faede2 --- /dev/null +++ b/thirdparty/boost/graph/topological_sort.hpp @@ -0,0 +1,76 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_TOPOLOGICAL_SORT_HPP +#define BOOST_GRAPH_TOPOLOGICAL_SORT_HPP + +#include +#include +#include +#include +#include + +namespace boost { + + + // Topological sort visitor + // + // This visitor merely writes the linear ordering into an + // OutputIterator. The OutputIterator could be something like an + // ostream_iterator, or it could be a back/front_insert_iterator. + // Note that if it is a back_insert_iterator, the recorded order is + // the reverse topological order. On the other hand, if it is a + // front_insert_iterator, the recorded order is the topological + // order. + // + template + struct topo_sort_visitor : public dfs_visitor<> + { + topo_sort_visitor(OutputIterator _iter) + : m_iter(_iter) { } + + template + void back_edge(const Edge& u, Graph&) { throw not_a_dag(); } + + template + void finish_vertex(const Vertex& u, Graph&) { *m_iter++ = u; } + + OutputIterator m_iter; + }; + + + // Topological Sort + // + // The topological sort algorithm creates a linear ordering + // of the vertices such that if edge (u,v) appears in the graph, + // then u comes before v in the ordering. The graph must + // be a directed acyclic graph (DAG). The implementation + // consists mainly of a call to depth-first search. + // + + template + void topological_sort(VertexListGraph& g, OutputIterator result, + const bgl_named_params& params) + { + typedef topo_sort_visitor TopoVisitor; + depth_first_search(g, params.visitor(TopoVisitor(result))); + } + + template + void topological_sort(VertexListGraph& g, OutputIterator result) + { + topological_sort(g, result, + bgl_named_params(0)); // bogus + } + +} // namespace boost + +#endif /*BOOST_GRAPH_TOPOLOGICAL_SORT_H*/ diff --git a/thirdparty/boost/graph/transitive_closure.hpp b/thirdparty/boost/graph/transitive_closure.hpp new file mode 100644 index 0000000..f48cdae --- /dev/null +++ b/thirdparty/boost/graph/transitive_closure.hpp @@ -0,0 +1,370 @@ +// Copyright (C) 2001 Vladimir Prus +// Copyright (C) 2001 Jeremy Siek +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// NOTE: this final is generated by libs/graph/doc/transitive_closure.w + +#ifndef BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP +#define BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP + +#include +#include // for std::min and std::max +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + + namespace detail + { + inline void + union_successor_sets(const std::vector < std::size_t > &s1, + const std::vector < std::size_t > &s2, + std::vector < std::size_t > &s3) + { + BOOST_USING_STD_MIN(); + for (std::size_t k = 0; k < s1.size(); ++k) + s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]); + } + } // namespace detail + + namespace detail + { + template < typename Container, typename ST = std::size_t, + typename VT = typename Container::value_type > + struct subscript_t:public std::unary_function < ST, VT > + { + typedef VT& result_type; + + subscript_t(Container & c):container(&c) + { + } + VT & operator() (const ST & i) const + { + return (*container)[i]; + } + protected: + Container * container; + }; + template < typename Container > + subscript_t < Container > subscript(Container & c) { + return subscript_t < Container > (c); + } + } // namespace detail + + template < typename Graph, typename GraphTC, + typename G_to_TC_VertexMap, + typename VertexIndexMap > + void transitive_closure(const Graph & g, GraphTC & tc, + G_to_TC_VertexMap g_to_tc_map, + VertexIndexMap index_map) + { + if (num_vertices(g) == 0) + return; + typedef typename graph_traits < Graph >::vertex_descriptor vertex; + typedef typename graph_traits < Graph >::edge_descriptor edge; + typedef typename graph_traits < Graph >::vertex_iterator vertex_iterator; + typedef typename property_traits < VertexIndexMap >::value_type size_type; + typedef typename graph_traits < + Graph >::adjacency_iterator adjacency_iterator; + + function_requires < VertexListGraphConcept < Graph > >(); + function_requires < AdjacencyGraphConcept < Graph > >(); + function_requires < VertexMutableGraphConcept < GraphTC > >(); + function_requires < EdgeMutableGraphConcept < GraphTC > >(); + function_requires < ReadablePropertyMapConcept < VertexIndexMap, + vertex > >(); + + typedef size_type cg_vertex; + std::vector < cg_vertex > component_number_vec(num_vertices(g)); + iterator_property_map < cg_vertex *, VertexIndexMap, cg_vertex, cg_vertex& > + component_number(&component_number_vec[0], index_map); + + int num_scc = strong_components(g, component_number, + vertex_index_map(index_map)); + + std::vector < std::vector < vertex > >components; + build_component_lists(g, num_scc, component_number, components); + + typedef std::vector > CG_t; + CG_t CG(num_scc); + for (cg_vertex s = 0; s < components.size(); ++s) { + std::vector < cg_vertex > adj; + for (size_type i = 0; i < components[s].size(); ++i) { + vertex u = components[s][i]; + adjacency_iterator v, v_end; + for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { + cg_vertex t = component_number[*v]; + if (s != t) // Avoid loops in the condensation graph + adj.push_back(t); + } + } + std::sort(adj.begin(), adj.end()); + typename std::vector::iterator di = + std::unique(adj.begin(), adj.end()); + if (di != adj.end()) + adj.erase(di, adj.end()); + CG[s] = adj; + } + + std::vector topo_order; + std::vector topo_number(num_vertices(CG)); + topological_sort(CG, std::back_inserter(topo_order), + vertex_index_map(identity_property_map())); + std::reverse(topo_order.begin(), topo_order.end()); + size_type n = 0; + for (typename std::vector::iterator iter = topo_order.begin(); + iter != topo_order.end(); ++iter) + topo_number[*iter] = n++; + + for (size_type i = 0; i < num_vertices(CG); ++i) + std::sort(CG[i].begin(), CG[i].end(), + boost::bind(std::less(), + boost::bind(detail::subscript(topo_number), _1), + boost::bind(detail::subscript(topo_number), _2))); + + std::vector > chains; + { + std::vector in_a_chain(num_vertices(CG)); + for (typename std::vector::iterator i = topo_order.begin(); + i != topo_order.end(); ++i) { + cg_vertex v = *i; + if (!in_a_chain[v]) { + chains.resize(chains.size() + 1); + std::vector& chain = chains.back(); + for (;;) { + chain.push_back(v); + in_a_chain[v] = true; + typename graph_traits::adjacency_iterator adj_first, adj_last; + tie(adj_first, adj_last) = adjacent_vertices(v, CG); + typename graph_traits::adjacency_iterator next + = std::find_if(adj_first, adj_last, + std::not1(detail::subscript(in_a_chain))); + if (next != adj_last) + v = *next; + else + break; // end of chain, dead-end + + } + } + } + } + std::vector chain_number(num_vertices(CG)); + std::vector pos_in_chain(num_vertices(CG)); + for (size_type i = 0; i < chains.size(); ++i) + for (size_type j = 0; j < chains[i].size(); ++j) { + cg_vertex v = chains[i][j]; + chain_number[v] = i; + pos_in_chain[v] = j; + } + + cg_vertex inf = (std::numeric_limits< cg_vertex >::max)(); + std::vector > successors(num_vertices(CG), + std::vector + (chains.size(), inf)); + for (typename std::vector::reverse_iterator + i = topo_order.rbegin(); i != topo_order.rend(); ++i) { + cg_vertex u = *i; + typename graph_traits::adjacency_iterator adj, adj_last; + for (tie(adj, adj_last) = adjacent_vertices(u, CG); + adj != adj_last; ++adj) { + cg_vertex v = *adj; + if (topo_number[v] < successors[u][chain_number[v]]) { + // Succ(u) = Succ(u) U Succ(v) + detail::union_successor_sets(successors[u], successors[v], + successors[u]); + // Succ(u) = Succ(u) U {v} + successors[u][chain_number[v]] = topo_number[v]; + } + } + } + + for (size_type i = 0; i < CG.size(); ++i) + CG[i].clear(); + for (size_type i = 0; i < CG.size(); ++i) + for (size_type j = 0; j < chains.size(); ++j) { + size_type topo_num = successors[i][j]; + if (topo_num < inf) { + cg_vertex v = topo_order[topo_num]; + for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k) + CG[i].push_back(chains[j][k]); + } + } + + + // Add vertices to the transitive closure graph + typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex; + { + vertex_iterator i, i_end; + for (tie(i, i_end) = vertices(g); i != i_end; ++i) + g_to_tc_map[*i] = add_vertex(tc); + } + // Add edges between all the vertices in two adjacent SCCs + typename graph_traits::vertex_iterator si, si_end; + for (tie(si, si_end) = vertices(CG); si != si_end; ++si) { + cg_vertex s = *si; + typename graph_traits::adjacency_iterator i, i_end; + for (tie(i, i_end) = adjacent_vertices(s, CG); i != i_end; ++i) { + cg_vertex t = *i; + for (size_type k = 0; k < components[s].size(); ++k) + for (size_type l = 0; l < components[t].size(); ++l) + add_edge(g_to_tc_map[components[s][k]], + g_to_tc_map[components[t][l]], tc); + } + } + // Add edges connecting all vertices in a SCC + for (size_type i = 0; i < components.size(); ++i) + if (components[i].size() > 1) + for (size_type k = 0; k < components[i].size(); ++k) + for (size_type l = 0; l < components[i].size(); ++l) { + vertex u = components[i][k], v = components[i][l]; + add_edge(g_to_tc_map[u], g_to_tc_map[v], tc); + } + + // Find loopbacks in the original graph. + // Need to add it to transitive closure. + { + vertex_iterator i, i_end; + for (tie(i, i_end) = vertices(g); i != i_end; ++i) + { + adjacency_iterator ab, ae; + for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab) + { + if (*ab == *i) + if (components[component_number[*i]].size() == 1) + add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc); + } + } + } + } + + template + void transitive_closure(const Graph & g, GraphTC & tc) + { + if (num_vertices(g) == 0) + return; + typedef typename property_map::const_type + VertexIndexMap; + VertexIndexMap index_map = get(vertex_index, g); + + typedef typename graph_traits::vertex_descriptor tc_vertex; + std::vector to_tc_vec(num_vertices(g)); + iterator_property_map < tc_vertex *, VertexIndexMap, tc_vertex, tc_vertex&> + g_to_tc_map(&to_tc_vec[0], index_map); + + transitive_closure(g, tc, g_to_tc_map, index_map); + } + + namespace detail + { + template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap, + typename VertexIndexMap> + void transitive_closure_dispatch + (const Graph & g, GraphTC & tc, + G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map) + { + typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex; + typename std::vector < tc_vertex >::size_type + n = is_default_param(g_to_tc_map) ? num_vertices(g) : 1; + std::vector < tc_vertex > to_tc_vec(n); + + transitive_closure + (g, tc, + choose_param(g_to_tc_map, make_iterator_property_map + (to_tc_vec.begin(), index_map, to_tc_vec[0])), + index_map); + } + } // namespace detail + + template < typename Graph, typename GraphTC, + typename P, typename T, typename R > + void transitive_closure(const Graph & g, GraphTC & tc, + const bgl_named_params < P, T, R > ¶ms) + { + if (num_vertices(g) == 0) + return; + detail::transitive_closure_dispatch + (g, tc, get_param(params, orig_to_copy_t()), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index) ); + } + + + template < typename G > void warshall_transitive_closure(G & g) + { + typedef typename graph_traits < G >::vertex_descriptor vertex; + typedef typename graph_traits < G >::vertex_iterator vertex_iterator; + + function_requires < AdjacencyMatrixConcept < G > >(); + function_requires < EdgeMutableGraphConcept < G > >(); + + // Matrix form: + // for k + // for i + // if A[i,k] + // for j + // A[i,j] = A[i,j] | A[k,j] + vertex_iterator ki, ke, ii, ie, ji, je; + for (tie(ki, ke) = vertices(g); ki != ke; ++ki) + for (tie(ii, ie) = vertices(g); ii != ie; ++ii) + if (edge(*ii, *ki, g).second) + for (tie(ji, je) = vertices(g); ji != je; ++ji) + if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) { + add_edge(*ii, *ji, g); + } + } + + + template < typename G > void warren_transitive_closure(G & g) + { + using namespace boost; + typedef typename graph_traits < G >::vertex_descriptor vertex; + typedef typename graph_traits < G >::vertex_iterator vertex_iterator; + + function_requires < AdjacencyMatrixConcept < G > >(); + function_requires < EdgeMutableGraphConcept < G > >(); + + // Make sure second loop will work + if (num_vertices(g) == 0) + return; + + // for i = 2 to n + // for k = 1 to i - 1 + // if A[i,k] + // for j = 1 to n + // A[i,j] = A[i,j] | A[k,j] + + vertex_iterator ic, ie, jc, je, kc, ke; + for (tie(ic, ie) = vertices(g), ++ic; ic != ie; ++ic) + for (tie(kc, ke) = vertices(g); *kc != *ic; ++kc) + if (edge(*ic, *kc, g).second) + for (tie(jc, je) = vertices(g); jc != je; ++jc) + if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) { + add_edge(*ic, *jc, g); + } + // for i = 1 to n - 1 + // for k = i + 1 to n + // if A[i,k] + // for j = 1 to n + // A[i,j] = A[i,j] | A[k,j] + + for (tie(ic, ie) = vertices(g), --ie; ic != ie; ++ic) + for (kc = ic, ke = ie, ++kc; kc != ke; ++kc) + if (edge(*ic, *kc, g).second) + for (tie(jc, je) = vertices(g); jc != je; ++jc) + if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) { + add_edge(*ic, *jc, g); + } + } + + +} // namespace boost + +#endif // BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP diff --git a/thirdparty/boost/graph/transpose_graph.hpp b/thirdparty/boost/graph/transpose_graph.hpp new file mode 100644 index 0000000..5c0f352 --- /dev/null +++ b/thirdparty/boost/graph/transpose_graph.hpp @@ -0,0 +1,40 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_TRANSPOSE_HPP +#define BOOST_GRAPH_TRANSPOSE_HPP + +#include +#include +#include +#include + + +namespace boost { + + template + void transpose_graph(const VertexListGraph& G, MutableGraph& G_T) + { + reverse_graph R(G); + copy_graph(R, G_T); + } + + template + void transpose_graph(const VertexListGraph& G, MutableGraph& G_T, + const bgl_named_params& params) + { + reverse_graph Rev(G); + copy_graph(Rev, G_T, params); + } + +} // namespace boost + +#endif // BOOST_GRAPH_TRANSPOSE_HPP diff --git a/thirdparty/boost/graph/tree_traits.hpp b/thirdparty/boost/graph/tree_traits.hpp new file mode 100644 index 0000000..d7d840a --- /dev/null +++ b/thirdparty/boost/graph/tree_traits.hpp @@ -0,0 +1,43 @@ +// (C) Copyright Jeremy Siek 1999. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_TREE_STRUCTURE_HPP +#define BOOST_TREE_STRUCTURE_HPP + +namespace boost { + + template + struct tree_traits { + typedef typename T::node_descriptor node_descriptor; + typedef typename T::children_iterator children_iterator; + }; + + + template + void traverse_tree(typename tree_traits::node_descriptor v, + Tree& t, TreeVisitor visitor) + { + visitor.preorder(v, t); + typename tree_traits::children_iterator i, end; + tie(i, end) = children(v, t); + if (i != end) { + traverse_tree(*i++, t, visitor); + visitor.inorder(v, t); + while (i != end) + traverse_tree(*i++, t, visitor); + } else + visitor.inorder(v, t); + visitor.postorder(v, t); + } + + struct null_tree_visitor { + template void preorder(Node, Tree&) { } + template void inorder(Node, Tree&) { } + template void postorder(Node, Tree&) { } + }; + +} /* namespace boost */ + +#endif /* BOOST_TREE_STRUCTURE_HPP */ diff --git a/thirdparty/boost/graph/two_bit_color_map.hpp b/thirdparty/boost/graph/two_bit_color_map.hpp new file mode 100644 index 0000000..9551bb8 --- /dev/null +++ b/thirdparty/boost/graph/two_bit_color_map.hpp @@ -0,0 +1,90 @@ +// Copyright (C) 2005-2006 The Trustees of Indiana University. + +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jeremiah Willcock +// Douglas Gregor +// Andrew Lumsdaine + +// Two bit per color property map + +#ifndef BOOST_TWO_BIT_COLOR_MAP_HPP +#define BOOST_TWO_BIT_COLOR_MAP_HPP + +#include +#include + +namespace boost { + +enum two_bit_color_type { + two_bit_white = 0, + two_bit_gray = 1, + two_bit_green = 2, + two_bit_black = 3 +}; + +template <> +struct color_traits +{ + static two_bit_color_type white() { return two_bit_white; } + static two_bit_color_type gray() { return two_bit_gray; } + static two_bit_color_type green() { return two_bit_green; } + static two_bit_color_type black() { return two_bit_black; } +}; + + +template +struct two_bit_color_map +{ + std::size_t n; + IndexMap index; + shared_array data; + + typedef typename property_traits::key_type key_type; + typedef two_bit_color_type value_type; + typedef void reference; + typedef read_write_property_map_tag category; + + explicit two_bit_color_map(std::size_t n, const IndexMap& index = IndexMap()) + : n(n), index(index), data(new unsigned char[(n + 3) / 4]) + { + } +}; + +template +inline two_bit_color_type +get(const two_bit_color_map& pm, + typename two_bit_color_map::key_type key) +{ + typename property_traits::value_type i = get(pm.index, key); + assert (i < pm.n); + return two_bit_color_type((pm.data.get()[i / 4] >> ((i % 4) * 2)) & 3); +} + +template +inline void +put(const two_bit_color_map& pm, + typename two_bit_color_map::key_type key, + two_bit_color_type value) +{ + typename property_traits::value_type i = get(pm.index, key); + assert (i < pm.n); + assert (value >= 0 && value < 4); + std::size_t byte_num = i / 4; + std::size_t bit_position = ((i % 4) * 2); + pm.data.get()[byte_num] = (pm.data.get()[byte_num] & ~(3 << bit_position)) + | (value << bit_position); +} + +template +inline two_bit_color_map +make_two_bit_color_map(std::size_t n, const IndexMap& index_map) +{ + return two_bit_color_map(n, index_map); +} + +} // end namespace boost + +#endif // BOOST_TWO_BIT_COLOR_MAP_HPP diff --git a/thirdparty/boost/graph/undirected_dfs.hpp b/thirdparty/boost/graph/undirected_dfs.hpp new file mode 100644 index 0000000..b372fbc --- /dev/null +++ b/thirdparty/boost/graph/undirected_dfs.hpp @@ -0,0 +1,250 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +#ifndef BOOST_GRAPH_UNDIRECTED_DFS_HPP +#define BOOST_GRAPH_UNDIRECTED_DFS_HPP + +#include +#include + +namespace boost { + + namespace detail { + +// Define BOOST_RECURSIVE_DFS to use older, recursive version. +// It is retained for a while in order to perform performance +// comparison. +#ifndef BOOST_RECURSIVE_DFS + + template + void undir_dfv_impl + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, + VertexColorMap vertex_color, + EdgeColorMap edge_color) + { + function_requires >(); + function_requires >(); + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; + function_requires >(); + function_requires >(); + typedef typename property_traits::value_type ColorValue; + typedef typename property_traits::value_type EColorValue; + function_requires< ColorValueConcept >(); + function_requires< ColorValueConcept >(); + typedef color_traits Color; + typedef color_traits EColor; + typedef typename graph_traits::out_edge_iterator Iter; + typedef std::pair > VertexInfo; + + std::vector stack; + + put(vertex_color, u, Color::gray()); + vis.discover_vertex(u, g); + stack.push_back(std::make_pair(u, out_edges(u, g))); + while (!stack.empty()) { + VertexInfo& back = stack.back(); + u = back.first; + Iter ei, ei_end; + tie(ei, ei_end) = back.second; + stack.pop_back(); + while (ei != ei_end) { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(vertex_color, v); + EColorValue uv_color = get(edge_color, *ei); + put(edge_color, *ei, EColor::black()); + if (v_color == Color::white()) { + vis.tree_edge(*ei, g); + stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end))); + u = v; + put(vertex_color, u, Color::gray()); + vis.discover_vertex(u, g); + tie(ei, ei_end) = out_edges(u, g); + } else if (v_color == Color::gray()) { + if (uv_color == EColor::white()) vis.back_edge(*ei, g); + ++ei; + } else { // if (v_color == Color::black()) + ++ei; + } + } + put(vertex_color, u, Color::black()); + vis.finish_vertex(u, g); + } + } + +#else // BOOST_RECURSIVE_DFS + + template + void undir_dfv_impl + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, // pass-by-reference here, important! + VertexColorMap vertex_color, + EdgeColorMap edge_color) + { + function_requires >(); + function_requires >(); + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::edge_descriptor Edge; + function_requires >(); + function_requires >(); + typedef typename property_traits::value_type ColorValue; + typedef typename property_traits::value_type EColorValue; + function_requires< ColorValueConcept >(); + function_requires< ColorValueConcept >(); + typedef color_traits Color; + typedef color_traits EColor; + typename graph_traits::out_edge_iterator ei, ei_end; + + put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g); + for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { + Vertex v = target(*ei, g); vis.examine_edge(*ei, g); + ColorValue v_color = get(vertex_color, v); + EColorValue uv_color = get(edge_color, *ei); + put(edge_color, *ei, EColor::black()); + if (v_color == Color::white()) { vis.tree_edge(*ei, g); + undir_dfv_impl(g, v, vis, vertex_color, edge_color); + } else if (v_color == Color::gray() && uv_color == EColor::white()) + vis.back_edge(*ei, g); + } + put(vertex_color, u, Color::black()); vis.finish_vertex(u, g); + } + +#endif // ! BOOST_RECURSIVE_DFS + + } // namespace detail + + template + void + undirected_dfs(const Graph& g, DFSVisitor vis, + VertexColorMap vertex_color, EdgeColorMap edge_color, + Vertex start_vertex) + { + function_requires >(); + function_requires >(); + + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g); + } + typename graph_traits::edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(edge_color, *ei, Color::white()); + + if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g); + detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color); + } + + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + ColorValue u_color = get(vertex_color, *ui); + if (u_color == Color::white()) { vis.start_vertex(*ui, g); + detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color); + } + } + } + + template + void + undirected_dfs(const Graph& g, DFSVisitor vis, + VertexColorMap vertex_color, EdgeColorMap edge_color) + { + undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first); + } + + namespace detail { + template + struct udfs_dispatch { + + template + static void + apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params&, + EdgeColorMap edge_color, + VertexColorMap vertex_color) + { + undirected_dfs(g, vis, vertex_color, edge_color, start_vertex); + } + }; + + template <> + struct udfs_dispatch { + template + static void + apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params& params, + EdgeColorMap edge_color, + detail::error_property_not_found) + { + std::vector color_vec(num_vertices(g)); + default_color_type c = white_color; // avoid warning about un-init + undirected_dfs + (g, vis, make_iterator_property_map + (color_vec.begin(), + choose_const_pmap(get_param(params, vertex_index), + g, vertex_index), c), + edge_color, + start_vertex); + } + }; + + } // namespace detail + + + // Named Parameter Variant + template + void + undirected_dfs(const Graph& g, + const bgl_named_params& params) + { + typedef typename property_value< bgl_named_params, + vertex_color_t>::type C; + detail::udfs_dispatch::apply + (g, + choose_param(get_param(params, graph_visitor), + make_dfs_visitor(null_visitor())), + choose_param(get_param(params, root_vertex_t()), + *vertices(g).first), + params, + get_param(params, edge_color), + get_param(params, vertex_color) + ); + } + + + template + void undirected_depth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color) + { + detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color); + } + + +} // namespace boost + + +#endif diff --git a/thirdparty/boost/graph/vector_as_graph.hpp b/thirdparty/boost/graph/vector_as_graph.hpp new file mode 100644 index 0000000..ff03e9b --- /dev/null +++ b/thirdparty/boost/graph/vector_as_graph.hpp @@ -0,0 +1,332 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Copyright 2006 The Trustees of Indiana University. +// Copyright (C) 2001 Vladimir Prus +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +// The mutating functions (add_edge, etc.) were added by Vladimir Prus. + +#ifndef BOOST_VECTOR_AS_GRAPH_HPP +#define BOOST_VECTOR_AS_GRAPH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + This module implements the VertexListGraph concept using a + std::vector as the "back-bone" of the graph (the vector *is* the + graph object). The edge-lists type of the graph is templated, so the + user can choose any STL container, so long as the value_type of the + container is convertible to the size_type of the vector. For now any + graph properties must be stored seperately. + + This module requires the C++ compiler to support partial + specialization for the graph_traits class, so this is not portable + to VC++. + +*/ + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#error The vector-as-graph module requires a compiler that supports partial specialization +#endif + + +namespace boost { + namespace detail { + template struct val_out_edge_ret; + template struct val_out_edge_iter; + template struct val_edge; + } +} + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { + + struct vector_as_graph_traversal_tag + : public vertex_list_graph_tag, + public adjacency_graph_tag, + public incidence_graph_tag { }; + + template + struct graph_traits< std::vector > + { + typedef typename EdgeList::value_type V; + typedef V vertex_descriptor; + typedef typename detail::val_edge::type edge_descriptor; + typedef typename EdgeList::const_iterator adjacency_iterator; + typedef typename detail::val_out_edge_iter::type + out_edge_iterator; + typedef void in_edge_iterator; + typedef void edge_iterator; + typedef typename integer_range::iterator vertex_iterator; + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; + typedef vector_as_graph_traversal_tag traversal_category; + typedef typename std::vector::size_type vertices_size_type; + typedef void edges_size_type; + typedef typename EdgeList::size_type degree_size_type; + }; + template + struct edge_property_type< std::vector > + { + typedef void type; + }; + template + struct vertex_property_type< std::vector > + { + typedef void type; + }; + template + struct graph_property_type< std::vector > + { + typedef void type; + }; +} +#endif + +namespace boost { + + namespace detail { + + // "val" is short for Vector Adjacency List + + template + struct val_edge + { + typedef typename EdgeList::value_type V; + typedef std::pair type; + }; + + // need rewrite this using boost::iterator_adaptor + template + class val_out_edge_iterator + : public boost::iterator, + std::ptrdiff_t, std::pair*, const std::pair > + { + typedef val_out_edge_iterator self; + typedef std::pair Edge; + public: + val_out_edge_iterator() { } + val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) { } + Edge operator*() const { return Edge(_source, *_iter); } + self& operator++() { ++_iter; return *this; } + self operator++(int) { self t = *this; ++_iter; return t; } + bool operator==(const self& x) const { return _iter == x._iter; } + bool operator!=(const self& x) const { return _iter != x._iter; } + protected: + V _source; + Iter _iter; + }; + + template + struct val_out_edge_iter + { + typedef typename EdgeList::value_type V; + typedef typename EdgeList::const_iterator Iter; + typedef val_out_edge_iterator type; + }; + + template + struct val_out_edge_ret + { + typedef typename val_out_edge_iter::type IncIter; + typedef std::pair type; + }; + + } // namesapce detail + + template + typename detail::val_out_edge_ret::type + out_edges(typename EdgeList::value_type v, + const std::vector& g) + { + typedef typename detail::val_out_edge_iter::type Iter; + typedef typename detail::val_out_edge_ret::type return_type; + return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end())); + } + + template + typename EdgeList::size_type + out_degree(typename EdgeList::value_type v, + const std::vector& g) + { + return g[v].size(); + } + + template + std::pair + adjacent_vertices(typename EdgeList::value_type v, + const std::vector& g) + { + return std::make_pair(g[v].begin(), g[v].end()); + } + + // source() and target() already provided for pairs in graph_traits.hpp + + template + std::pair + ::iterator, + typename boost::integer_range + ::iterator > + vertices(const std::vector& v) + { + typedef typename boost::integer_range + ::iterator Iter; + return std::make_pair(Iter(0), Iter(v.size())); + } + + template + typename std::vector::size_type + num_vertices(const std::vector& v) + { + return v.size(); + } + + template + typename std::pair::type, bool> + add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v, + std::vector& g) + { + typedef typename detail::val_edge::type edge_type; + g[u].insert(g[u].end(), v); + return std::make_pair(edge_type(u, v), true); + } + + template + typename std::pair::type, bool> + edge(typename EdgeList::value_type u, typename EdgeList::value_type v, + std::vector& g) + { + typedef typename detail::val_edge::type edge_type; + typename EdgeList::iterator i = g[u].begin(), end = g[u].end(); + for (; i != end; ++i) + if (*i == v) + return std::make_pair(edge_type(u, v), true); + return std::make_pair(edge_type(), false); + } + + template + void + remove_edge(typename EdgeList::value_type u, typename EdgeList::value_type v, + std::vector& g) + { + typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v); + if (i != g[u].end()) + g[u].erase(i, g[u].end()); + } + + template + void + remove_edge(typename detail::val_edge::type e, + std::vector& g) + { + typename EdgeList::value_type u, v; + u = e.first; + v = e.second; + // FIXME: edge type does not fully specify the edge to be deleted + typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v); + if (i != g[u].end()) + g[u].erase(i, g[u].end()); + } + + template + void + remove_edge_if(Predicate p, + std::vector& g) + { + for (std::size_t u = 0; u < g.size(); ++u) { + // Oops! gcc gets internal compiler error on compose_....... + + typedef typename EdgeList::iterator iterator; + iterator b = g[u].begin(), e = g[u].end(); + + if (!g[u].empty()) { + + for(; b != e;) { + if (p(std::make_pair(u, *b))) { + --e; + if (b == e) + break; + else + iter_swap(b, e); + } else { + ++b; + } + } + } + + if (e != g[u].end()) + g[u].erase(e, g[u].end()); + } + } + + template + typename EdgeList::value_type + add_vertex(std::vector& g) + { + g.resize(g.size()+1); + return g.size()-1; + } + + template + void + clear_vertex(typename EdgeList::value_type u, + std::vector& g) + { + g[u].clear(); + for (std::size_t i = 0; i < g.size(); ++i) + remove_edge(i, u, g); + } + + template + void + remove_vertex(typename EdgeList::value_type u, + std::vector& g) + { + typedef typename EdgeList::iterator iterator; + clear_vertex(u, g); + g.erase(g.begin() + u); + for (std::size_t i = 0; i < g.size(); ++i) + for ( iterator it = g[i].begin(); it != g[i].end(); ++it ) + // after clear_vertex *it is never equal to u + if ( *it > u ) + --*it; + } + + template + struct property_map, vertex_index_t> + { + typedef identity_property_map type; + typedef type const_type; + }; + + template + identity_property_map + get(vertex_index_t, const std::vector&) + { + return identity_property_map(); + } + + template + identity_property_map + get(vertex_index_t, std::vector&) + { + return identity_property_map(); + } +} // namespace boost + +#endif // BOOST_VECTOR_AS_GRAPH_HPP diff --git a/thirdparty/boost/graph/visitors.hpp b/thirdparty/boost/graph/visitors.hpp new file mode 100644 index 0000000..e0c44b2 --- /dev/null +++ b/thirdparty/boost/graph/visitors.hpp @@ -0,0 +1,279 @@ +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// +// Revision History: +// 01 April 2001: Modified to use new header. (JMaddock) +// +#ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP +#define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP + +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# define Graph Graph_ +#endif + +namespace boost { + + // This is a bit more convenient than std::numeric_limits because + // you don't have to explicitly provide type T. + template + inline T numeric_limits_max(T) { return (std::numeric_limits::max)(); } + + //======================================================================== + // Event Tags + + namespace detail { + // For partial specialization workaround + enum event_visitor_enum + { on_no_event_num, + on_initialize_vertex_num, on_start_vertex_num, + on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num, + on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num, + on_gray_target_num, on_black_target_num, + on_forward_or_cross_edge_num, on_back_edge_num, + on_edge_relaxed_num, on_edge_not_relaxed_num, + on_edge_minimized_num, on_edge_not_minimized_num + }; + + template + struct functor_to_visitor : Visitor + { + typedef Event event_filter; + functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {} + }; + + } // namespace detail + + struct on_no_event { enum { num = detail::on_no_event_num }; }; + + struct on_initialize_vertex { + enum { num = detail::on_initialize_vertex_num }; }; + struct on_start_vertex { enum { num = detail::on_start_vertex_num }; }; + struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; }; + struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; }; + struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; }; + + struct on_examine_edge { enum { num = detail::on_examine_edge_num }; }; + struct on_tree_edge { enum { num = detail::on_tree_edge_num }; }; + struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; }; + struct on_gray_target { enum { num = detail::on_gray_target_num }; }; + struct on_black_target { enum { num = detail::on_black_target_num }; }; + struct on_forward_or_cross_edge { + enum { num = detail::on_forward_or_cross_edge_num }; }; + struct on_back_edge { enum { num = detail::on_back_edge_num }; }; + + struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; }; + struct on_edge_not_relaxed { + enum { num = detail::on_edge_not_relaxed_num }; }; + struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; }; + struct on_edge_not_minimized { + enum { num = detail::on_edge_not_minimized_num }; }; + + struct true_tag { enum { num = true }; }; + struct false_tag { enum { num = false }; }; + + //======================================================================== + // base_visitor and null_visitor + + // needed for MSVC workaround + template + struct base_visitor { + typedef on_no_event event_filter; + template + void operator()(T, Graph&) { } + }; + + struct null_visitor : public base_visitor { + typedef on_no_event event_filter; + template + void operator()(T, Graph&) { } + }; + + //======================================================================== + // The invoke_visitors() function + + namespace detail { + template + inline void + invoke_dispatch(Visitor& v, T x, Graph& g, true_tag) { + v(x, g); + } + template + inline void + invoke_dispatch(Visitor&, T, Graph&, false_tag) { } + } // namespace detail + + template + inline void + invoke_visitors(std::pair& vlist, T x, Graph& g, Tag tag) { + typedef typename Visitor::event_filter Category; + typedef typename graph_detail::is_same::is_same_tag + IsSameTag; + detail::invoke_dispatch(vlist.first, x, g, IsSameTag()); + invoke_visitors(vlist.second, x, g, tag); + } +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + template + inline void + invoke_visitors(base_visitor& vis, T x, Graph& g, Tag) { + typedef typename Visitor::event_filter Category; + typedef typename graph_detail::is_same::is_same_tag + IsSameTag; + Visitor& v = static_cast(vis); + detail::invoke_dispatch(v, x, g, IsSameTag()); + } +#else + template + inline void + invoke_visitors(Visitor& v, T x, Graph& g, Tag) { + typedef typename Visitor::event_filter Category; + typedef typename graph_detail::is_same::is_same_tag + IsSameTag; + detail::invoke_dispatch(v, x, g, IsSameTag()); + } +#endif + + //======================================================================== + // predecessor_recorder + + template + struct predecessor_recorder + : public base_visitor > + { + typedef Tag event_filter; + predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { } + template + void operator()(Edge e, const Graph& g) { + put(m_predecessor, target(e, g), source(e, g)); + } + PredecessorMap m_predecessor; + }; + template + predecessor_recorder + record_predecessors(PredecessorMap pa, Tag) { + return predecessor_recorder (pa); + } + + //======================================================================== + // edge_predecessor_recorder + + template + struct edge_predecessor_recorder + : public base_visitor > + { + typedef Tag event_filter; + edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { } + template + void operator()(Edge e, const Graph& g) { + put(m_predecessor, target(e, g), e); + } + PredEdgeMap m_predecessor; + }; + template + edge_predecessor_recorder + record_edge_predecessors(PredEdgeMap pa, Tag) { + return edge_predecessor_recorder (pa); + } + + //======================================================================== + // distance_recorder + + template + struct distance_recorder + : public base_visitor > + { + typedef Tag event_filter; + distance_recorder(DistanceMap pa) : m_distance(pa) { } + template + void operator()(Edge e, const Graph& g) { + typename graph_traits::vertex_descriptor + u = source(e, g), v = target(e, g); + put(m_distance, v, get(m_distance, u) + 1); + } + DistanceMap m_distance; + }; + template + distance_recorder + record_distances(DistanceMap pa, Tag) { + return distance_recorder (pa); + } + + //======================================================================== + // time_stamper + + + template + struct time_stamper + : public base_visitor > + { + typedef Tag event_filter; + time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { } + template + void operator()(Vertex u, const Graph&) { + put(m_time_pa, u, ++m_time); + } + TimeMap m_time_pa; + TimeT& m_time; + }; + template + time_stamper + stamp_times(TimeMap pa, TimeT& time_counter, Tag) { + return time_stamper(pa, time_counter); + } + + //======================================================================== + // property_writer + + template + struct property_writer + : public base_visitor > + { + typedef Tag event_filter; + + property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { } + + template + void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); } + PA m_pa; + OutputIterator m_out; + }; + template + property_writer + write_property(PA pa, OutputIterator out, Tag) { + return property_writer(pa, out); + } + +#define BOOST_GRAPH_EVENT_STUB(Event,Kind) \ + typedef ::boost::Event Event##_type; \ + template \ + Kind##_visitor, Visitors> > \ + do_##Event(Visitor visitor) \ + { \ + typedef std::pair, \ + Visitors> visitor_list; \ + typedef Kind##_visitor result_type; \ + return result_type(visitor_list(visitor, m_vis)); \ + } + +} /* namespace boost */ + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// Stay out of the way of the concept checking class +# undef Graph +#endif + +#endif diff --git a/thirdparty/boost/graph/wavefront.hpp b/thirdparty/boost/graph/wavefront.hpp new file mode 100644 index 0000000..392396d --- /dev/null +++ b/thirdparty/boost/graph/wavefront.hpp @@ -0,0 +1,135 @@ +// +//======================================================================= +// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch) +// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +// + +#ifndef BOOST_GRAPH_WAVEFRONT_HPP +#define BOOST_GRAPH_WAVEFRONT_HPP + +#include +#include +#include +#include +#include +#include +#include // for std::min and std::max + +namespace boost { + + template + typename graph_traits::vertices_size_type + ith_wavefront(typename graph_traits::vertex_descriptor i, + const Graph& g, + VertexIndexMap index) + { + typename graph_traits::vertex_descriptor v, w; + typename graph_traits::vertices_size_type b = 1; + typename graph_traits::out_edge_iterator edge_it2, edge_it2_end; + typename graph_traits::vertices_size_type index_i = index[i]; + std::vector rows_active(num_vertices(g), false); + + rows_active[index_i] = true; + + typename graph_traits::vertex_iterator ui, ui_end; + for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + v = *ui; + if(index[v] <= index_i) + { + for (tie(edge_it2, edge_it2_end) = out_edges(v, g); edge_it2 != edge_it2_end; ++edge_it2) + { + w = target(*edge_it2, g); + if( (index[w] >= index_i) && (!rows_active[index[w]]) ) + { + b++; + rows_active[index[w]] = true; + } + } + } + } + + return b; + } + + + template + typename graph_traits::vertices_size_type + ith_wavefront(typename graph_traits::vertex_descriptor i, + const Graph& g) + { + return ith_wavefront(i, g, get(vertex_index, g)); + } + + + template + typename graph_traits::vertices_size_type + max_wavefront(const Graph& g, VertexIndexMap index) + { + BOOST_USING_STD_MAX(); + typename graph_traits::vertices_size_type b = 0; + typename graph_traits::vertex_iterator i, end; + for (tie(i, end) = vertices(g); i != end; ++i) + b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b, ith_wavefront(*i, g, index)); + return b; + } + + template + typename graph_traits::vertices_size_type + max_wavefront(const Graph& g) + { + return max_wavefront(g, get(vertex_index, g)); + } + + + template + double + aver_wavefront(const Graph& g, VertexIndexMap index) + { + double b = 0; + typename graph_traits::vertex_iterator i, end; + for (tie(i, end) = vertices(g); i != end; ++i) + b += ith_wavefront(*i, g, index); + + b /= num_vertices(g); + return b; + } + + template + double + aver_wavefront(const Graph& g) + { + return aver_wavefront(g, get(vertex_index, g)); + } + + + template + double + rms_wavefront(const Graph& g, VertexIndexMap index) + { + double b = 0; + typename graph_traits::vertex_iterator i, end; + for (tie(i, end) = vertices(g); i != end; ++i) + b += std::pow(double ( ith_wavefront(*i, g, index) ), 2.0); + + b /= num_vertices(g); + + return std::sqrt(b); + } + + template + double + rms_wavefront(const Graph& g) + { + return rms_wavefront(g, get(vertex_index, g)); + } + + +} // namespace boost + +#endif // BOOST_GRAPH_WAVEFRONT_HPP diff --git a/thirdparty/boost/graph/write_dimacs.hpp b/thirdparty/boost/graph/write_dimacs.hpp new file mode 100644 index 0000000..fb28259 --- /dev/null +++ b/thirdparty/boost/graph/write_dimacs.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2006, Stephan Diederich +// +// This code may be used under either of the following two licences: +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE. +// +// Or: +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/* + Writes maximal flow problem in extended DIMACS format to an OutputIterator + Vertex indices are read from an IndexMap and shiftet by 1. + so their new range is [1..num_vertices(g)] +*/ + +/* ----------------------------------------------------------------- */ + +#include +#include +#include + +namespace boost { + +template +void write_dimacs_max_flow(const Graph& g, + CapacityMap capacity, + IndexMap idx, + typename graph_traits::vertex_descriptor src, + typename graph_traits::vertex_descriptor sink, + std::ostream& out) +{ + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits::edges_size_type edges_size_type; + typedef typename graph_traits::edge_iterator edge_iterator; + + out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" << std::endl; + out << "p max " << num_vertices(g) << " " << num_edges(g) << std::endl; //print problem description "max" and number of verts and edges + out << "n " << get(idx, src) + 1 << " s" << std::endl;; //say which one is source + out << "n " << get(idx, sink) + 1 << " t" << std::endl; //say which one is sink + + //output the edges + edge_iterator ei, e_end; + for(tie(ei,e_end) = edges(g); ei!=e_end; ++ei){ + out << "a " << idx[ source(*ei, g) ] + 1 << " " << idx[ target(*ei, g) ] + 1 << " " << get(capacity,*ei) << std::endl; + } +} + +} // namespace boost diff --git a/thirdparty/boost/implicit_cast.hpp b/thirdparty/boost/implicit_cast.hpp new file mode 100644 index 0000000..b0ff30a --- /dev/null +++ b/thirdparty/boost/implicit_cast.hpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 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) +#ifndef IMPLICIT_CAST_DWA200356_HPP +# define IMPLICIT_CAST_DWA200356_HPP + +# include + +namespace boost { + +// implementation originally suggested by C. Green in +// http://lists.boost.org/MailArchives/boost/msg00886.php + +// The use of identity creates a non-deduced form, so that the +// explicit template argument must be supplied +template +inline T implicit_cast (typename mpl::identity::type x) { + return x; +} + +// incomplete return type now is here +//template +//void implicit_cast (...); + +} // namespace boost + + +#endif // IMPLICIT_CAST_DWA200356_HPP diff --git a/thirdparty/boost/indirect_reference.hpp b/thirdparty/boost/indirect_reference.hpp new file mode 100644 index 0000000..7675e78 --- /dev/null +++ b/thirdparty/boost/indirect_reference.hpp @@ -0,0 +1,43 @@ +#ifndef INDIRECT_REFERENCE_DWA200415_HPP +# define INDIRECT_REFERENCE_DWA200415_HPP + +// +// Copyright David Abrahams 2004. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// typename indirect_reference

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

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

            + , iterator_reference

            + , detail::smart_ptr_reference

            + > +{ +}; + +} // namespace boost + +#endif // INDIRECT_REFERENCE_DWA200415_HPP diff --git a/thirdparty/boost/integer.hpp b/thirdparty/boost/integer.hpp new file mode 100644 index 0000000..09d6512 --- /dev/null +++ b/thirdparty/boost/integer.hpp @@ -0,0 +1,127 @@ +// boost integer.hpp header file -------------------------------------------// + +// Copyright Beman Dawes and Daryle Walker 1999. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 22 Sep 01 Added value-based integer templates. (Daryle Walker) +// 01 Apr 01 Modified to use new header. (John Maddock) +// 30 Jul 00 Add typename syntax fix (Jens Maurer) +// 28 Aug 99 Initial version + +#ifndef BOOST_INTEGER_HPP +#define BOOST_INTEGER_HPP + +#include // self include + +#include // for boost::integer_traits +#include // for std::numeric_limits + +namespace boost +{ + + // Helper templates ------------------------------------------------------// + + // fast integers from least integers + // int_fast_t<> works correctly for unsigned too, in spite of the name. + template< typename LeastInt > + struct int_fast_t { typedef LeastInt fast; }; // imps may specialize + + // convert category to type + template< int Category > struct int_least_helper {}; // default is empty + + // specializatons: 1=long, 2=int, 3=short, 4=signed char, + // 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char + // no specializations for 0 and 5: requests for a type > long are in error + template<> struct int_least_helper<1> { typedef long least; }; + template<> struct int_least_helper<2> { typedef int least; }; + template<> struct int_least_helper<3> { typedef short least; }; + template<> struct int_least_helper<4> { typedef signed char least; }; + template<> struct int_least_helper<6> { typedef unsigned long least; }; + template<> struct int_least_helper<7> { typedef unsigned int least; }; + template<> struct int_least_helper<8> { typedef unsigned short least; }; + template<> struct int_least_helper<9> { typedef unsigned char least; }; + + // integer templates specifying number of bits ---------------------------// + + // signed + template< int Bits > // bits (including sign) required + struct int_t + { + typedef typename int_least_helper + < + (Bits-1 <= std::numeric_limits::digits) + + (Bits-1 <= std::numeric_limits::digits) + + (Bits-1 <= std::numeric_limits::digits) + + (Bits-1 <= std::numeric_limits::digits) + >::least least; + typedef typename int_fast_t::fast fast; + }; + + // unsigned + template< int Bits > // bits required + struct uint_t + { + typedef typename int_least_helper + < + 5 + + (Bits <= std::numeric_limits::digits) + + (Bits <= std::numeric_limits::digits) + + (Bits <= std::numeric_limits::digits) + + (Bits <= std::numeric_limits::digits) + >::least least; + typedef typename int_fast_t::fast fast; + // int_fast_t<> works correctly for unsigned too, in spite of the name. + }; + + // integer templates specifying extreme value ----------------------------// + + // signed + template< long MaxValue > // maximum value to require support + struct int_max_value_t + { + typedef typename int_least_helper + < + (MaxValue <= integer_traits::const_max) + + (MaxValue <= integer_traits::const_max) + + (MaxValue <= integer_traits::const_max) + + (MaxValue <= integer_traits::const_max) + >::least least; + typedef typename int_fast_t::fast fast; + }; + + template< long MinValue > // minimum value to require support + struct int_min_value_t + { + typedef typename int_least_helper + < + (MinValue >= integer_traits::const_min) + + (MinValue >= integer_traits::const_min) + + (MinValue >= integer_traits::const_min) + + (MinValue >= integer_traits::const_min) + >::least least; + typedef typename int_fast_t::fast fast; + }; + + // unsigned + template< unsigned long Value > // maximum value to require support + struct uint_value_t + { + typedef typename int_least_helper + < + 5 + + (Value <= integer_traits::const_max) + + (Value <= integer_traits::const_max) + + (Value <= integer_traits::const_max) + + (Value <= integer_traits::const_max) + >::least least; + typedef typename int_fast_t::fast fast; + }; + + +} // namespace boost + +#endif // BOOST_INTEGER_HPP diff --git a/thirdparty/boost/integer/integer_mask.hpp b/thirdparty/boost/integer/integer_mask.hpp new file mode 100644 index 0000000..49060bc --- /dev/null +++ b/thirdparty/boost/integer/integer_mask.hpp @@ -0,0 +1,93 @@ +// 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 +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://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 + + +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.) + +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( 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 + + +#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 ); \ + } + +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 + +#undef BOOST_LOW_BITS_MASK_SPECIALIZE + + +} // namespace boost + + +#endif // BOOST_INTEGER_INTEGER_MASK_HPP diff --git a/thirdparty/boost/integer/static_log2.hpp b/thirdparty/boost/integer/static_log2.hpp new file mode 100644 index 0000000..95ffcd4 --- /dev/null +++ b/thirdparty/boost/integer/static_log2.hpp @@ -0,0 +1,132 @@ +// -------------- Boost static_log2.hpp header file ----------------------- // +// +// Copyright (C) 2001 Daryle Walker. +// Copyright (C) 2003 Vesa Karvonen. +// Copyright (C) 2003 Gennaro Prota. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// --------------------------------------------------- +// See http://www.boost.org/libs/integer for documentation. +// ------------------------------------------------------------------------- // + + +#ifndef BOOST_INTEGER_STATIC_LOG2_HPP +#define BOOST_INTEGER_STATIC_LOG2_HPP + +#include "boost/config.hpp" // for BOOST_STATIC_CONSTANT + +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 unsigned long argument_type; + typedef int result_type; + + + template + struct choose_initial_n { + + enum { 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 { + + enum { 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 + // ---------------------------------------- + + typedef detail::static_log2_impl::argument_type static_log2_argument_type; + typedef detail::static_log2_impl::result_type static_log2_result_type; + + + 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/thirdparty/boost/integer/static_min_max.hpp b/thirdparty/boost/integer/static_min_max.hpp new file mode 100644 index 0000000..e00a4af --- /dev/null +++ b/thirdparty/boost/integer/static_min_max.hpp @@ -0,0 +1,55 @@ +// Boost integer/static_min_max.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 +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_INTEGER_STATIC_MIN_MAX_HPP +#define BOOST_INTEGER_STATIC_MIN_MAX_HPP + +#include // self include + +#include // for BOOST_STATIC_CONSTANT + + +namespace boost +{ + + +// Compile-time extrema class declarations ---------------------------------// +// Get the minimum or maximum of two values, signed or unsigned. + +template < long Value1, long Value2 > +struct static_signed_min +{ + BOOST_STATIC_CONSTANT( long, value = (Value1 > Value2) ? Value2 : Value1 ); +}; + +template < long Value1, long Value2 > +struct static_signed_max +{ + BOOST_STATIC_CONSTANT( long, value = (Value1 < Value2) ? Value2 : Value1 ); +}; + +template < unsigned long Value1, unsigned long Value2 > +struct static_unsigned_min +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (Value1 > Value2) ? Value2 : Value1 ); +}; + +template < unsigned long Value1, unsigned long Value2 > +struct static_unsigned_max +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (Value1 < Value2) ? Value2 : Value1 ); +}; + + +} // namespace boost + + +#endif // BOOST_INTEGER_STATIC_MIN_MAX_HPP diff --git a/thirdparty/boost/integer_fwd.hpp b/thirdparty/boost/integer_fwd.hpp new file mode 100644 index 0000000..07d963d --- /dev/null +++ b/thirdparty/boost/integer_fwd.hpp @@ -0,0 +1,152 @@ +// Boost integer_fwd.hpp header file ---------------------------------------// + +// (C) Copyright Dave Abrahams and Daryle Walker 2001. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +#ifndef BOOST_INTEGER_FWD_HPP +#define BOOST_INTEGER_FWD_HPP + +#include // for UCHAR_MAX, etc. +#include // for std::size_t + +#include // for BOOST_NO_INTRINSIC_WCHAR_T +#include // for std::numeric_limits + + +namespace boost +{ + + +// From ------------------------------------------------// + +// Only has typedefs or using statements, with #conditionals + + +// From -----------------------------------------// + +template < class T > + class integer_traits; + +template < > + class integer_traits< bool >; + +template < > + class integer_traits< char >; + +template < > + class integer_traits< signed char >; + +template < > + class integer_traits< unsigned char >; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template < > + class integer_traits< wchar_t >; +#endif + +template < > + class integer_traits< short >; + +template < > + class integer_traits< unsigned short >; + +template < > + class integer_traits< int >; + +template < > + class integer_traits< unsigned int >; + +template < > + class integer_traits< long >; + +template < > + class integer_traits< unsigned long >; + +#ifdef ULLONG_MAX +template < > + class integer_traits< ::boost::long_long_type>; + +template < > + class integer_traits< ::boost::ulong_long_type >; +#endif + + +// From ------------------------------------------------// + +template < typename LeastInt > + struct int_fast_t; + +template< int Bits > + struct int_t; + +template< int Bits > + struct uint_t; + +template< long MaxValue > + struct int_max_value_t; + +template< long MinValue > + struct int_min_value_t; + +template< unsigned long Value > + struct uint_value_t; + + +// From -----------------------------------// + +template < std::size_t Bit > + struct high_bit_mask_t; + +template < std::size_t Bits > + struct low_bits_mask_t; + +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; + +#if USHRT_MAX > UCHAR_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif + +#if UINT_MAX > USHRT_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif + +#if ULONG_MAX > UINT_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif + + +// From ------------------------------------// + +template < unsigned long Value > + struct static_log2; + +template < > + struct static_log2< 0ul >; + + +// From ---------------------------------// + +template < long Value1, long Value2 > + struct static_signed_min; + +template < long Value1, long Value2 > + struct static_signed_max; + +template < unsigned long Value1, unsigned long Value2 > + struct static_unsigned_min; + +template < unsigned long Value1, unsigned long Value2 > + struct static_unsigned_max; + + +} // namespace boost + + +#endif // BOOST_INTEGER_FWD_HPP diff --git a/thirdparty/boost/integer_traits.hpp b/thirdparty/boost/integer_traits.hpp new file mode 100644 index 0000000..24b6774 --- /dev/null +++ b/thirdparty/boost/integer_traits.hpp @@ -0,0 +1,236 @@ +/* boost integer_traits.hpp header file + * + * Copyright Jens Maurer 2000 + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * $Id: integer_traits.hpp 32576 2006-02-05 10:19:42Z johnmaddock $ + * + * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers + */ + +// See http://www.boost.org/libs/integer for documentation. + + +#ifndef BOOST_INTEGER_TRAITS_HPP +#define BOOST_INTEGER_TRAITS_HPP + +#include +#include + +// These are an implementation detail and not part of the interface +#include +// we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it, +// and some may have but not ... +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__)) +#include +#endif + + +namespace boost { +template +class integer_traits : public std::numeric_limits +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = false); +}; + +namespace detail { +template +class integer_traits_base +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = true); + BOOST_STATIC_CONSTANT(T, const_min = min_val); + BOOST_STATIC_CONSTANT(T, const_max = max_val); +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool integer_traits_base::is_integral; + +template +const T integer_traits_base::const_min; + +template +const T integer_traits_base::const_max; +#endif + +} // namespace detail + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template<> +class integer_traits + : public std::numeric_limits, + // Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native + // library: they are wrong! +#if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__) + public detail::integer_traits_base +#elif defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__)) + // No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned: + public detail::integer_traits_base +#elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\ + || (defined __APPLE__)\ + || (defined(__OpenBSD__) && defined(__GNUC__))\ + || (defined(__NetBSD__) && defined(__GNUC__))\ + || (defined(__FreeBSD__) && defined(__GNUC__))\ + || (defined(__DragonFly__) && defined(__GNUC__))\ + || (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT)) + // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int. + // - SGI MIPSpro with native library + // - gcc 3.x on HP-UX + // - Mac OS X with native library + // - gcc on FreeBSD, OpenBSD and NetBSD + public detail::integer_traits_base +#elif defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 2) && !defined(__SGI_STL_PORT) + // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as unsigned int. + // - gcc 2.95.x on HP-UX + // (also, std::numeric_limits appears to return the wrong values). + public detail::integer_traits_base +#else +#error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler. +#endif +{ }; +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) +#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +{ }; + +#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> +{ }; + +#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> +{ }; + +#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> +{ }; + +#elif defined(BOOST_HAS_LONG_LONG) +// +// we have long long but no constants, this happens for example with gcc in -ansi mode, +// we'll just have to work out the values for ourselves (assumes 2's compliment representation): +// +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) - 1)), ~(1LL << (sizeof(::boost::long_long_type) - 1))> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> +{ }; + +#endif +#endif + +} // namespace boost + +#endif /* BOOST_INTEGER_TRAITS_HPP */ + + + diff --git a/thirdparty/boost/interprocess/allocators/adaptive_pool.hpp b/thirdparty/boost/interprocess/allocators/adaptive_pool.hpp new file mode 100644 index 0000000..c65e74e --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/adaptive_pool.hpp @@ -0,0 +1,451 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_ADAPTIVE_POOL_HPP +#define BOOST_INTERPROCESS_ADAPTIVE_POOL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes adaptive_pool pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail{ + +template < unsigned int Version + , class T + , class SegmentManager + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class adaptive_pool_base + : public node_pool_allocation_impl + < adaptive_pool_base + < Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> + , Version + , T + , SegmentManager + > +{ + public: + typedef typename SegmentManager::void_pointer void_pointer; + typedef SegmentManager segment_manager; + typedef adaptive_pool_base + self_t; + typedef detail::shared_adaptive_node_pool + < SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t; + typedef typename detail:: + pointer_to_other::type node_pool_ptr; + + BOOST_STATIC_ASSERT((Version <=2)); + + public: + //------- + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef detail::version_type version; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + //!Obtains adaptive_pool_base from + //!adaptive_pool_base + template + struct rebind + { + typedef adaptive_pool_base other; + }; + + /// @cond + private: + //!Not assignable from related adaptive_pool_base + template + adaptive_pool_base& operator= + (const adaptive_pool_base&); + + //!Not assignable from other adaptive_pool_base + adaptive_pool_base& operator=(const adaptive_pool_base&); + /// @endcond + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + adaptive_pool_base(segment_manager *segment_mngr) + : mp_node_pool(detail::get_or_create_node_pool(segment_mngr)) { } + + //!Copy constructor from other adaptive_pool_base. Increments the reference + //!count of the associated node pool. Never throws + adaptive_pool_base(const adaptive_pool_base &other) + : mp_node_pool(other.get_node_pool()) + { + mp_node_pool->inc_ref_count(); + } + + //!Copy constructor from related adaptive_pool_base. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + adaptive_pool_base + (const adaptive_pool_base &other) + : mp_node_pool(detail::get_or_create_node_pool(other.get_segment_manager())) { } + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~adaptive_pool_base() + { detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); } + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const + { return detail::get_pointer(mp_node_pool); } + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const + { return mp_node_pool->get_segment_manager(); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2) + { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); } + + /// @cond + private: + node_pool_ptr mp_node_pool; + /// @endcond +}; + +//!Equality test for same type +//!of adaptive_pool_base +template inline +bool operator==(const adaptive_pool_base &alloc1, + const adaptive_pool_base &alloc2) + { return alloc1.get_node_pool() == alloc2.get_node_pool(); } + +//!Inequality test for same type +//!of adaptive_pool_base +template inline +bool operator!=(const adaptive_pool_base &alloc1, + const adaptive_pool_base &alloc2) + { return alloc1.get_node_pool() != alloc2.get_node_pool(); } + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + , std::size_t MaxFreeChunks = 2 + , unsigned char OverheadPercent = 5 + > +class adaptive_pool_v1 + : public adaptive_pool_base + < 1 + , T + , SegmentManager + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > +{ + public: + typedef detail::adaptive_pool_base + < 1, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t; + + template + struct rebind + { + typedef adaptive_pool_v1 other; + }; + + adaptive_pool_v1(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + adaptive_pool_v1 + (const adaptive_pool_v1 &other) + : base_t(other) + {} +}; + +} //namespace detail{ + +/// @endcond + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//! +//!This node allocator shares a segregated storage between all instances +//!of adaptive_pool with equal sizeof(T) placed in the same segment +//!group. NodesPerChunk is the number of nodes allocated at once when the allocator +//!needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks +//!that the adaptive node pool will hold. The rest of the totally free chunks will be +//!deallocated with the segment manager. +//! +//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator: +//!(memory usable for nodes / total memory allocated from the segment manager) +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class adaptive_pool + /// @cond + : public detail::adaptive_pool_base + < 2 + , T + , SegmentManager + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef detail::adaptive_pool_base + < 2, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t; + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef adaptive_pool other; + }; + + adaptive_pool(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + adaptive_pool + (const adaptive_pool &other) + : base_t(other) + {} + + #else //BOOST_INTERPROCESS_DOXYGEN_INVOKED + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains adaptive_pool from + //!adaptive_pool + template + struct rebind + { + typedef adaptive_pool other; + }; + + private: + //!Not assignable from + //!related adaptive_pool + template + adaptive_pool& operator= + (const adaptive_pool&); + + //!Not assignable from + //!other adaptive_pool + adaptive_pool& operator=(const adaptive_pool&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + adaptive_pool(segment_manager *segment_mngr); + + //!Copy constructor from other adaptive_pool. Increments the reference + //!count of the associated node pool. Never throws + adaptive_pool(const adaptive_pool &other); + + //!Copy constructor from related adaptive_pool. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + adaptive_pool + (const adaptive_pool &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~adaptive_pool(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of adaptive_pool +template inline +bool operator==(const adaptive_pool &alloc1, + const adaptive_pool &alloc2); + +//!Inequality test for same type +//!of adaptive_pool +template inline +bool operator!=(const adaptive_pool &alloc1, + const adaptive_pool &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_ADAPTIVE_POOL_HPP + diff --git a/thirdparty/boost/interprocess/allocators/allocation_type.hpp b/thirdparty/boost/interprocess/allocators/allocation_type.hpp new file mode 100644 index 0000000..ab2b215 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/allocation_type.hpp @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_TYPE_COMMAND_HPP +#define BOOST_INTERPROCESS_TYPE_COMMAND_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace interprocess { + +/// @cond +enum allocation_type_v +{ + // constants for allocation commands + allocate_new_v = 0x01, + expand_fwd_v = 0x02, + expand_bwd_v = 0x04, +// expand_both = expand_fwd | expand_bwd, +// expand_or_new = allocate_new | expand_both, + shrink_in_place_v = 0x08, + nothrow_allocation_v = 0x10, + zero_memory_v = 0x20, + try_shrink_in_place_v = 0x40 +}; + +typedef int allocation_type; +/// @endcond +static const allocation_type allocate_new = (allocation_type)allocate_new_v; +static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; +static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; +static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v; +static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v; +static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v; +static const allocation_type zero_memory = (allocation_type)zero_memory_v; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_TYPE_COMMAND_HPP + diff --git a/thirdparty/boost/interprocess/allocators/allocator.hpp b/thirdparty/boost/interprocess/allocators/allocator.hpp new file mode 100644 index 0000000..9b21051 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/allocator.hpp @@ -0,0 +1,301 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +//!\file +//!Describes an allocator that allocates portions of fixed size +//!memory buffer (shared memory, mapped file...) + +namespace boost { +namespace interprocess { + + +//!An STL compatible allocator that uses a segment manager as +//!memory source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +template +class allocator +{ + /// @cond + private: + + //Self type + typedef allocator self_t; + + //Segment manager + typedef SegmentManager segment_manager; + + //Pointer to void + typedef typename segment_manager::void_pointer aux_pointer_t; + + //Typedef to const void pointer + typedef typename + detail::pointer_to_other + ::type cvoid_ptr; + + //Pointer to the allocator + typedef typename detail::pointer_to_other + ::type alloc_ptr_t; + + //Not assignable from related allocator + template + allocator& operator=(const allocator&); + + //Not assignable from other allocator + allocator& operator=(const allocator&); + + //Pointer to the allocator + alloc_ptr_t mp_mngr; + /// @endcond + + public: + typedef T value_type; + typedef typename detail::pointer_to_other + ::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef detail::version_type version; + + /// @cond + + //Experimental. Don't use. + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef detail::multiallocation_chain_adaptor + multiallocation_chain; +// typedef typename SegmentManager:: +// multiallocation_chain multiallocation_chain; + + /// @endcond + + //!Obtains an allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef allocator other; + }; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const + { return detail::get_pointer(mp_mngr); } + + //!Constructor from the segment manager. + //!Never throws + allocator(segment_manager *segment_mngr) + : mp_mngr(segment_mngr) { } + + //!Constructor from other allocator. + //!Never throws + allocator(const allocator &other) + : mp_mngr(other.get_segment_manager()){ } + + //!Constructor from related allocator. + //!Never throws + template + allocator(const allocator &other) + : mp_mngr(other.get_segment_manager()){} + + //!Allocates memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_ptr hint = 0) + { + (void)hint; + if(count > this->max_size()) + throw bad_alloc(); + return pointer((value_type*)mp_mngr->allocate(count*sizeof(T))); + } + + //!Deallocates memory previously allocated. + //!Never throws + void deallocate(const pointer &ptr, size_type) + { mp_mngr->deallocate(detail::get_pointer(ptr)); } + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const + { return mp_mngr->get_size()/sizeof(T); } + + //!Swap segment manager. Does not throw. If each allocator is placed in + //!different memory segments, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2) + { detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); } + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const + { + return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0) + { + return mp_mngr->allocation_command + (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse)); + } + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements) + { + return multiallocation_iterator + (mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements)); + } + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements) + { + return multiallocation_iterator + (mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T))); + } + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it) + { return mp_mngr->deallocate_many(it.base()); } + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one() + { return this->allocate(1); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements) + { return this->allocate_many(1, num_elements); } + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p) + { return this->deallocate(p, 1); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it) + { return this->deallocate_many(it); } + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const + { return pointer(boost::addressof(value)); } + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const + { return const_pointer(boost::addressof(value)); } + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr) + { new(detail::get_pointer(ptr)) value_type; } + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr) + { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } +}; + +//!Equality test for same type +//!of allocator +template inline +bool operator==(const allocator &alloc1, + const allocator &alloc2) + { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); } + +//!Inequality test for same type +//!of allocator +template inline +bool operator!=(const allocator &alloc1, + const allocator &alloc2) + { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } + +} //namespace interprocess { + +/// @cond + +template +struct has_trivial_destructor; + +template +struct has_trivial_destructor + > +{ + enum { value = true }; +}; +/// @endcond + +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_ALLOCATOR_HPP + diff --git a/thirdparty/boost/interprocess/allocators/cached_adaptive_pool.hpp b/thirdparty/boost/interprocess/allocators/cached_adaptive_pool.hpp new file mode 100644 index 0000000..1ec7560 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/cached_adaptive_pool.hpp @@ -0,0 +1,353 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP +#define BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes cached_adaptive_pool pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail { + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + , std::size_t MaxFreeChunks = 2 + , unsigned char OverheadPercent = 5 + > +class cached_adaptive_pool_v1 + : public detail::cached_allocator_impl + < T + , detail::shared_adaptive_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + , 1> +{ + public: + typedef detail::cached_allocator_impl + < T + , detail::shared_adaptive_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + , 1> base_t; + + template + struct rebind + { + typedef cached_adaptive_pool_v1 + other; + }; + + cached_adaptive_pool_v1(SegmentManager *segment_mngr, + std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) + : base_t(segment_mngr, max_cached_nodes) + {} + + template + cached_adaptive_pool_v1 + (const cached_adaptive_pool_v1 + &other) + : base_t(other) + {} +}; + +} //namespace detail{ + +/// @endcond + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//! +//!This node allocator shares a segregated storage between all instances of +//!cached_adaptive_pool with equal sizeof(T) placed in the same +//!memory segment. But also caches some nodes privately to +//!avoid some synchronization overhead. +//! +//!NodesPerChunk is the minimum number of nodes of nodes allocated at once when +//!the allocator needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks +//!that the adaptive node pool will hold. The rest of the totally free chunks will be +//!deallocated with the segment manager. +//! +//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator: +//!(memory usable for nodes / total memory allocated from the segment manager) +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class cached_adaptive_pool + /// @cond + : public detail::cached_allocator_impl + < T + , detail::shared_adaptive_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + , 2> + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + public: + typedef detail::cached_allocator_impl + < T + , detail::shared_adaptive_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + , 2> base_t; + + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef cached_adaptive_pool + other; + }; + + cached_adaptive_pool(SegmentManager *segment_mngr, + std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) + : base_t(segment_mngr, max_cached_nodes) + {} + + template + cached_adaptive_pool + (const cached_adaptive_pool &other) + : base_t(other) + {} + + #else + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains cached_adaptive_pool from + //!cached_adaptive_pool + template + struct rebind + { + typedef cached_adaptive_pool other; + }; + + private: + //!Not assignable from + //!related cached_adaptive_pool + template + cached_adaptive_pool& operator= + (const cached_adaptive_pool&); + + //!Not assignable from + //!other cached_adaptive_pool + cached_adaptive_pool& operator=(const cached_adaptive_pool&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + cached_adaptive_pool(segment_manager *segment_mngr); + + //!Copy constructor from other cached_adaptive_pool. Increments the reference + //!count of the associated node pool. Never throws + cached_adaptive_pool(const cached_adaptive_pool &other); + + //!Copy constructor from related cached_adaptive_pool. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + cached_adaptive_pool + (const cached_adaptive_pool &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~cached_adaptive_pool(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + //!Sets the new max cached nodes value. This can provoke deallocations + //!if "newmax" is less than current cached nodes. Never throws + void set_max_cached_nodes(std::size_t newmax); + + //!Returns the max cached nodes parameter. + //!Never throws + std::size_t get_max_cached_nodes() const; + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of cached_adaptive_pool +template inline +bool operator==(const cached_adaptive_pool &alloc1, + const cached_adaptive_pool &alloc2); + +//!Inequality test for same type +//!of cached_adaptive_pool +template inline +bool operator!=(const cached_adaptive_pool &alloc1, + const cached_adaptive_pool &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + + +#include + +#endif //#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP + diff --git a/thirdparty/boost/interprocess/allocators/cached_node_allocator.hpp b/thirdparty/boost/interprocess/allocators/cached_node_allocator.hpp new file mode 100644 index 0000000..4d50cca --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/cached_node_allocator.hpp @@ -0,0 +1,323 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_CACHED_NODE_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_CACHED_NODE_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes cached_cached_node_allocator pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + + +/// @cond + +namespace detail { + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + > +class cached_node_allocator_v1 + : public detail::cached_allocator_impl + < T + , detail::shared_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + > + , 1> +{ + public: + typedef detail::cached_allocator_impl + < T + , detail::shared_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + > + , 1> base_t; + + template + struct rebind + { + typedef cached_node_allocator_v1 + other; + }; + + cached_node_allocator_v1(SegmentManager *segment_mngr, + std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) + : base_t(segment_mngr, max_cached_nodes) + {} + + template + cached_node_allocator_v1 + (const cached_node_allocator_v1 + &other) + : base_t(other) + {} +}; + +} //namespace detail{ + +/// @endcond + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + > +class cached_node_allocator + /// @cond + : public detail::cached_allocator_impl + < T + , detail::shared_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + > + , 2> + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + public: + typedef detail::cached_allocator_impl + < T + , detail::shared_node_pool + < SegmentManager + , sizeof(T) + , NodesPerChunk + > + , 2> base_t; + + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef cached_node_allocator other; + }; + + cached_node_allocator(SegmentManager *segment_mngr, + std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) + : base_t(segment_mngr, max_cached_nodes) + {} + + template + cached_node_allocator + (const cached_node_allocator &other) + : base_t(other) + {} + + #else + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains cached_node_allocator from + //!cached_node_allocator + template + struct rebind + { + typedef cached_node_allocator other; + }; + + private: + //!Not assignable from + //!related cached_node_allocator + template + cached_node_allocator& operator= + (const cached_node_allocator&); + + //!Not assignable from + //!other cached_node_allocator + cached_node_allocator& operator=(const cached_node_allocator&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + cached_node_allocator(segment_manager *segment_mngr); + + //!Copy constructor from other cached_node_allocator. Increments the reference + //!count of the associated node pool. Never throws + cached_node_allocator(const cached_node_allocator &other); + + //!Copy constructor from related cached_node_allocator. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + cached_node_allocator + (const cached_node_allocator &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~cached_node_allocator(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + //!Sets the new max cached nodes value. This can provoke deallocations + //!if "newmax" is less than current cached nodes. Never throws + void set_max_cached_nodes(std::size_t newmax); + + //!Returns the max cached nodes parameter. + //!Never throws + std::size_t get_max_cached_nodes() const; + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of cached_node_allocator +template inline +bool operator==(const cached_node_allocator &alloc1, + const cached_node_allocator &alloc2); + +//!Inequality test for same type +//!of cached_node_allocator +template inline +bool operator!=(const cached_node_allocator &alloc1, + const cached_node_allocator &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_CACHED_NODE_ALLOCATOR_HPP + diff --git a/thirdparty/boost/interprocess/allocators/detail/adaptive_node_pool.hpp b/thirdparty/boost/interprocess/allocators/detail/adaptive_node_pool.hpp new file mode 100644 index 0000000..4057c3e --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/detail/adaptive_node_pool.hpp @@ -0,0 +1,617 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_ADAPTIVE_NODE_POOL_HPP +#define BOOST_INTERPROCESS_DETAIL_ADAPTIVE_NODE_POOL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes the real adaptive pool shared by many Interprocess pool allocators + +namespace boost { +namespace interprocess { +namespace detail { + +template +class private_adaptive_node_pool_impl +{ + //Non-copyable + private_adaptive_node_pool_impl(); + private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &); + private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &); + + typedef typename SegmentManagerBase::void_pointer void_pointer; + + public: + typedef typename node_slist::node_t node_t; + typedef typename node_slist::node_slist_t free_nodes_t; + typedef typename SegmentManagerBase::multiallocation_iterator multiallocation_iterator; + typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain; + + private: + typedef typename bi::make_set_base_hook + < bi::void_pointer + , bi::optimize_size + , bi::constant_time_size + , bi::link_mode >::type multiset_hook_t; + + struct hdr_offset_holder + { + hdr_offset_holder(std::size_t offset = 0) + : hdr_offset(offset) + {} + std::size_t hdr_offset; + }; + + struct chunk_info_t + : + public hdr_offset_holder, + public multiset_hook_t + { + //An intrusive list of free node from this chunk + free_nodes_t free_nodes; + friend bool operator <(const chunk_info_t &l, const chunk_info_t &r) + { +// { return l.free_nodes.size() < r.free_nodes.size(); } + //Let's order blocks first by free nodes and then by address + //so that highest address fully free chunks are deallocated. + //This improves returning memory to the OS (trimming). + const bool is_less = l.free_nodes.size() < r.free_nodes.size(); + const bool is_equal = l.free_nodes.size() == r.free_nodes.size(); + return is_less || (is_equal && (&l < &r)); + } + }; + typedef typename bi::make_multiset + >::type chunk_multiset_t; + typedef typename chunk_multiset_t::iterator chunk_iterator; + + static const std::size_t MaxAlign = alignment_of::value; + static const std::size_t HdrSize = ((sizeof(chunk_info_t)-1)/MaxAlign+1)*MaxAlign; + static const std::size_t HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign; + static std::size_t calculate_alignment + (std::size_t overhead_percent, std::size_t real_node_size) + { + //to-do: handle real_node_size != node_size + const std::size_t divisor = overhead_percent*real_node_size; + const std::size_t dividend = HdrOffsetSize*100; + std::size_t elements_per_subchunk = (dividend - 1)/divisor + 1; + std::size_t candidate_power_of_2 = + upper_power_of_2(elements_per_subchunk*real_node_size + HdrOffsetSize); + bool overhead_satisfied = false; + while(!overhead_satisfied){ + elements_per_subchunk = (candidate_power_of_2 - HdrOffsetSize)/real_node_size; + std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*real_node_size; + if(overhead_size*100/candidate_power_of_2 < overhead_percent){ + overhead_satisfied = true; + } + else{ + candidate_power_of_2 <<= 1; + } + } + return candidate_power_of_2; + } + + static void calculate_num_subchunks + (std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_chunk + ,std::size_t &num_subchunks, std::size_t &real_num_node) + { + std::size_t elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size; + std::size_t possible_num_subchunk = (elements_per_chunk - 1)/elements_per_subchunk + 1; + std::size_t hdr_subchunk_elements = (alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/real_node_size; + while(((possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements) < elements_per_chunk){ + ++possible_num_subchunk; + } + num_subchunks = possible_num_subchunk; + real_num_node = (possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements; + } + + public: + //!Segment manager typedef + typedef SegmentManagerBase segment_manager_base_type; + + //!Constructor from a segment manager. Never throws + private_adaptive_node_pool_impl + ( segment_manager_base_type *segment_mngr_base, std::size_t node_size + , std::size_t nodes_per_chunk, std::size_t max_free_chunks + , unsigned char overhead_percent + ) + : m_max_free_chunks(max_free_chunks) + , m_real_node_size(lcm(node_size, std::size_t(alignment_of::value))) + //Round the size to a power of two value. + //This is the total memory size (including payload) that we want to + //allocate from the general-purpose allocator + , m_real_chunk_alignment(calculate_alignment(overhead_percent, m_real_node_size)) + //This is the real number of nodes per chunk + , m_num_subchunks(0) + , m_real_num_node(0) + //General purpose allocator + , mp_segment_mngr_base(segment_mngr_base) + , m_chunk_multiset() + , m_totally_free_chunks(0) + { + calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node); + } + + //!Destructor. Deallocates all allocated chunks. Never throws + ~private_adaptive_node_pool_impl() + { priv_clear(); } + + std::size_t get_real_num_node() const + { return m_real_num_node; } + + //!Returns the segment manager. Never throws + segment_manager_base_type* get_segment_manager_base()const + { return detail::get_pointer(mp_segment_mngr_base); } + + //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc + void *allocate_node() + { + priv_invariants(); + //If there are no free nodes we allocate a new block + if (m_chunk_multiset.empty()){ + priv_alloc_chunk(1); + } + //We take the first free node the multiset can't be empty + return priv_take_first_node(); + } + + //!Deallocates an array pointed by ptr. Never throws + void deallocate_node(void *pElem) + { + this->priv_reinsert_nodes_in_chunk + (multiallocation_iterator::create_simple_range(pElem)); + //Update free chunk count + if(m_totally_free_chunks > m_max_free_chunks){ + this->priv_deallocate_free_chunks(m_max_free_chunks); + } + priv_invariants(); + } + + //!Allocates a singly linked list of n nodes ending in null pointer. + //!can throw boost::interprocess::bad_alloc + void allocate_nodes(multiallocation_chain &nodes, const std::size_t n) + { + try{ + priv_invariants(); + for(std::size_t i = 0; i != n; ++i){ + //If there are no free nodes we allocate all needed chunks + if (m_chunk_multiset.empty()){ + priv_alloc_chunk(((n - i) - 1)/m_real_num_node + 1); + } + nodes.push_front(priv_take_first_node()); + } + } + catch(...){ + this->deallocate_nodes(nodes, nodes.size()); + this->priv_deallocate_free_chunks(m_max_free_chunks); + throw; + } + priv_invariants(); + } + + //!Allocates n nodes, pointed by the multiallocation_iterator. + //!Can throw boost::interprocess::bad_alloc + multiallocation_iterator allocate_nodes(const std::size_t n) + { + multiallocation_chain chain; + this->allocate_nodes(chain, n); + return chain.get_it(); + } + + //!Deallocates a linked list of nodes. Never throws + void deallocate_nodes(multiallocation_chain &nodes) + { + this->deallocate_nodes(nodes.get_it()); + nodes.reset(); + } + + //!Deallocates the first n nodes of a linked list of nodes. Never throws + void deallocate_nodes(multiallocation_chain &nodes, std::size_t n) + { + assert(nodes.size() >= n); + for(std::size_t i = 0; i < n; ++i){ + this->deallocate_node(nodes.pop_front()); + } + } + + //!Deallocates the nodes pointed by the multiallocation iterator. Never throws + void deallocate_nodes(multiallocation_iterator it) + { + this->priv_reinsert_nodes_in_chunk(it); + if(m_totally_free_chunks > m_max_free_chunks){ + this->priv_deallocate_free_chunks(m_max_free_chunks); + } + } + + void deallocate_free_chunks() + { this->priv_deallocate_free_chunks(0); } + + std::size_t num_free_nodes() + { + typedef typename chunk_multiset_t::const_iterator citerator; + std::size_t count = 0; + citerator it (m_chunk_multiset.begin()), itend(m_chunk_multiset.end()); + for(; it != itend; ++it){ + count += it->free_nodes.size(); + } + return count; + } + + void swap(private_adaptive_node_pool_impl &other) + { + assert(m_max_free_chunks == other.m_max_free_chunks); + assert(m_real_node_size == other.m_real_node_size); + assert(m_real_chunk_alignment == other.m_real_chunk_alignment); + assert(m_real_num_node == other.m_real_num_node); + std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base); + std::swap(m_totally_free_chunks, other.m_totally_free_chunks); + m_chunk_multiset.swap(other.m_chunk_multiset); + } + + private: + void priv_deallocate_free_chunks(std::size_t max_free_chunks) + { + priv_invariants(); + //Now check if we've reached the free nodes limit + //and check if we have free chunks. If so, deallocate as much + //as we can to stay below the limit + for( chunk_iterator itend = m_chunk_multiset.end() + ; m_totally_free_chunks > max_free_chunks + ; --m_totally_free_chunks + ){ + assert(!m_chunk_multiset.empty()); + chunk_iterator it = itend; + --it; + std::size_t num_nodes = it->free_nodes.size(); + assert(num_nodes == m_real_num_node); + (void)num_nodes; + m_chunk_multiset.erase_and_dispose + (it, chunk_destroyer(this)); + } + } + + void priv_reinsert_nodes_in_chunk(multiallocation_iterator it) + { + multiallocation_iterator itend; + chunk_iterator chunk_it(m_chunk_multiset.end()); + while(it != itend){ + void *pElem = &*it; + ++it; + priv_invariants(); + chunk_info_t *chunk_info = this->priv_chunk_from_node(pElem); + assert(chunk_info->free_nodes.size() < m_real_num_node); + //We put the node at the beginning of the free node list + node_t * to_deallocate = static_cast(pElem); + chunk_info->free_nodes.push_front(*to_deallocate); + + chunk_iterator this_chunk(chunk_multiset_t::s_iterator_to(*chunk_info)); + chunk_iterator next_chunk(this_chunk); + ++next_chunk; + + //Cache the free nodes from the chunk + std::size_t this_chunk_free_nodes = this_chunk->free_nodes.size(); + + if(this_chunk_free_nodes == 1){ + m_chunk_multiset.insert(m_chunk_multiset.begin(), *chunk_info); + } + else{ + chunk_iterator next_chunk(this_chunk); + ++next_chunk; + if(next_chunk != chunk_it){ + std::size_t next_free_nodes = next_chunk->free_nodes.size(); + if(this_chunk_free_nodes > next_free_nodes){ + //Now move the chunk to the new position + m_chunk_multiset.erase(this_chunk); + m_chunk_multiset.insert(*chunk_info); + } + } + } + //Update free chunk count + if(this_chunk_free_nodes == m_real_num_node){ + ++m_totally_free_chunks; + } + priv_invariants(); + } + } + + node_t *priv_take_first_node() + { + assert(m_chunk_multiset.begin() != m_chunk_multiset.end()); + //We take the first free node the multiset can't be empty + free_nodes_t &free_nodes = m_chunk_multiset.begin()->free_nodes; + node_t *first_node = &free_nodes.front(); + const std::size_t free_nodes_count = free_nodes.size(); + assert(0 != free_nodes_count); + free_nodes.pop_front(); + if(free_nodes_count == 1){ + m_chunk_multiset.erase(m_chunk_multiset.begin()); + } + else if(free_nodes_count == m_real_num_node){ + --m_totally_free_chunks; + } + priv_invariants(); + return first_node; + } + + class chunk_destroyer; + friend class chunk_destroyer; + + class chunk_destroyer + { + public: + chunk_destroyer(const private_adaptive_node_pool_impl *impl) + : mp_impl(impl) + {} + + void operator()(typename chunk_multiset_t::pointer to_deallocate) + { + std::size_t free_nodes = to_deallocate->free_nodes.size(); + (void)free_nodes; + assert(free_nodes == mp_impl->m_real_num_node); + assert(0 == to_deallocate->hdr_offset); + hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subchunk_from_chunk((chunk_info_t*)detail::get_pointer(to_deallocate)); + mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder); + } + const private_adaptive_node_pool_impl *mp_impl; + }; + + //This macro will activate invariant checking. Slow, but helpful for debugging the code. + #define BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS + void priv_invariants() + #ifdef BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS + #undef BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS + { + //We iterate through the chunk list to free the memory + chunk_iterator it(m_chunk_multiset.begin()), + itend(m_chunk_multiset.end()), to_deallocate; + if(it != itend){ + for(++it; it != itend; ++it){ + chunk_iterator prev(it); + --prev; + std::size_t sp = prev->free_nodes.size(), + si = it->free_nodes.size(); + assert(sp <= si); + (void)sp; (void)si; + } + } + + { + //Check that the total free nodes are correct + it = m_chunk_multiset.begin(); + itend = m_chunk_multiset.end(); + std::size_t total_free_nodes = 0; + for(; it != itend; ++it){ + total_free_nodes += it->free_nodes.size(); + } + assert(total_free_nodes >= m_totally_free_chunks*m_real_num_node); + } + + { + //Check that the total totally free chunks are correct + it = m_chunk_multiset.begin(); + itend = m_chunk_multiset.end(); + std::size_t total_free_chunks = 0; + for(; it != itend; ++it){ + total_free_chunks += (it->free_nodes.size() == m_real_num_node); + } + assert(total_free_chunks == m_totally_free_chunks); + } + { + //Check that header offsets are correct + it = m_chunk_multiset.begin(); + for(; it != itend; ++it){ + hdr_offset_holder *hdr_off_holder = priv_first_subchunk_from_chunk(&*it); + for(std::size_t i = 0, max = m_num_subchunks; i < max; ++i){ + assert(hdr_off_holder->hdr_offset == std::size_t((char*)&*it- (char*)hdr_off_holder)); + assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1))); + assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1))); + hdr_off_holder = (hdr_offset_holder *)((char*)hdr_off_holder + m_real_chunk_alignment); + } + } + } + } + #else + {} //empty + #endif + + //!Deallocates all used memory. Never throws + void priv_clear() + { + #ifndef NDEBUG + chunk_iterator it = m_chunk_multiset.begin(); + chunk_iterator itend = m_chunk_multiset.end(); + std::size_t num_free_nodes = 0; + for(; it != itend; ++it){ + //Check for memory leak + assert(it->free_nodes.size() == m_real_num_node); + ++num_free_nodes; + } + assert(num_free_nodes == m_totally_free_chunks); + #endif + priv_invariants(); + m_chunk_multiset.clear_and_dispose + (chunk_destroyer(this)); + m_totally_free_chunks = 0; + } + + chunk_info_t *priv_chunk_from_node(void *node) const + { + hdr_offset_holder *hdr_off_holder = + (hdr_offset_holder*)((std::size_t)node & std::size_t(~(m_real_chunk_alignment - 1))); + assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1))); + assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1))); + chunk_info_t *chunk = (chunk_info_t *)(((char*)hdr_off_holder) + hdr_off_holder->hdr_offset); + assert(chunk->hdr_offset == 0); + return chunk; + } + + hdr_offset_holder *priv_first_subchunk_from_chunk(chunk_info_t *chunk) const + { + hdr_offset_holder *hdr_off_holder = (hdr_offset_holder*) + (((char*)chunk) - (m_num_subchunks-1)*m_real_chunk_alignment); + assert(hdr_off_holder->hdr_offset == std::size_t((char*)chunk - (char*)hdr_off_holder)); + assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1))); + assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1))); + return hdr_off_holder; + } + + //!Allocates a several chunks of nodes. Can throw boost::interprocess::bad_alloc + void priv_alloc_chunk(std::size_t n) + { + std::size_t real_chunk_size = m_real_chunk_alignment*m_num_subchunks - SegmentManagerBase::PayloadPerAllocation; + std::size_t elements_per_subchunk = (m_real_chunk_alignment - HdrOffsetSize)/m_real_node_size; + std::size_t hdr_subchunk_elements = (m_real_chunk_alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/m_real_node_size; + + for(std::size_t i = 0; i != n; ++i){ + //We allocate a new NodeBlock and put it the last + //element of the tree + char *mem_address = detail::char_ptr_cast + (mp_segment_mngr_base->allocate_aligned(real_chunk_size, m_real_chunk_alignment)); + if(!mem_address) throw std::bad_alloc(); + ++m_totally_free_chunks; + + //First initialize header information on the last subchunk + char *hdr_addr = mem_address + m_real_chunk_alignment*(m_num_subchunks-1); + chunk_info_t *c_info = new(hdr_addr)chunk_info_t; + //Some structural checks + assert(static_cast(&static_cast(c_info)->hdr_offset) == + static_cast(c_info)); + typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin(); + for( std::size_t subchunk = 0, maxsubchunk = m_num_subchunks - 1 + ; subchunk < maxsubchunk + ; ++subchunk, mem_address += m_real_chunk_alignment){ + //Initialize header offset mark + new(mem_address) hdr_offset_holder(std::size_t(hdr_addr - mem_address)); + char *pNode = mem_address + HdrOffsetSize; + for(std::size_t i = 0; i < elements_per_subchunk; ++i){ + prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t); + pNode += m_real_node_size; + } + } + { + char *pNode = hdr_addr + HdrSize; + //We initialize all Nodes in Node Block to insert + //them in the free Node list + for(std::size_t i = 0; i < hdr_subchunk_elements; ++i){ + prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t); + pNode += m_real_node_size; + } + } + //Insert the chunk after the free node list is full + m_chunk_multiset.insert(m_chunk_multiset.end(), *c_info); + } + } + + private: + typedef typename pointer_to_other + ::type segment_mngr_base_ptr_t; + + const std::size_t m_max_free_chunks; + const std::size_t m_real_node_size; + //Round the size to a power of two value. + //This is the total memory size (including payload) that we want to + //allocate from the general-purpose allocator + const std::size_t m_real_chunk_alignment; + std::size_t m_num_subchunks; + //This is the real number of nodes per chunk + //const + std::size_t m_real_num_node; + segment_mngr_base_ptr_t mp_segment_mngr_base;//Segment manager + chunk_multiset_t m_chunk_multiset; //Intrusive chunk list + std::size_t m_totally_free_chunks; //Free chunks +}; + +template< class SegmentManager + , std::size_t NodeSize + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class private_adaptive_node_pool + : public private_adaptive_node_pool_impl + +{ + typedef private_adaptive_node_pool_impl + base_t; + //Non-copyable + private_adaptive_node_pool(); + private_adaptive_node_pool(const private_adaptive_node_pool &); + private_adaptive_node_pool &operator=(const private_adaptive_node_pool &); + + public: + typedef SegmentManager segment_manager; + + static const std::size_t nodes_per_chunk = NodesPerChunk; + + //!Constructor from a segment manager. Never throws + private_adaptive_node_pool(segment_manager *segment_mngr) + : base_t(segment_mngr, NodeSize, NodesPerChunk, MaxFreeChunks, OverheadPercent) + {} + + //!Returns the segment manager. Never throws + segment_manager* get_segment_manager() const + { return static_cast(base_t::get_segment_manager_base()); } +}; + +//!Pooled shared memory allocator using adaptive pool. Includes +//!a reference count but the class does not delete itself, this is +//!responsibility of user classes. Node size (NodeSize) and the number of +//!nodes allocated per chunk (NodesPerChunk) are known at compile time +template< class SegmentManager + , std::size_t NodeSize + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class shared_adaptive_node_pool + : public detail::shared_pool_impl + < private_adaptive_node_pool + + > +{ + typedef detail::shared_pool_impl + < private_adaptive_node_pool + + > base_t; + public: + shared_adaptive_node_pool(SegmentManager *segment_mgnr) + : base_t(segment_mgnr) + {} +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ADAPTIVE_NODE_POOL_HPP + diff --git a/thirdparty/boost/interprocess/allocators/detail/allocator_common.hpp b/thirdparty/boost/interprocess/allocators/detail/allocator_common.hpp new file mode 100644 index 0000000..aa64a6f --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/detail/allocator_common.hpp @@ -0,0 +1,760 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP +#define BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP + +#include +#include +#include +#include +#include //pointer_to_other, get_pointer +#include //std::pair +#include //boost::addressof +#include //BOOST_ASSERT +#include //bad_alloc +#include //scoped_lock +#include //allocation_type +#include //std::swap + + +namespace boost { +namespace interprocess { +namespace detail { + +//!Object function that creates the node allocator if it is not created and +//!increments reference count if it is already created +template +struct get_or_create_node_pool_func +{ + + //!This connects or constructs the unique instance of node_pool_t + //!Can throw boost::interprocess::bad_alloc + void operator()() + { + //Find or create the node_pool_t + mp_node_pool = mp_segment_manager->template find_or_construct + (unique_instance)(mp_segment_manager); + //If valid, increment link count + if(mp_node_pool != 0) + mp_node_pool->inc_ref_count(); + } + + //!Constructor. Initializes function + //!object parameters + get_or_create_node_pool_func(typename NodePool::segment_manager *mngr) + : mp_segment_manager(mngr){} + + NodePool *mp_node_pool; + typename NodePool::segment_manager *mp_segment_manager; +}; + +template +inline NodePool *get_or_create_node_pool(typename NodePool::segment_manager *mgnr) +{ + detail::get_or_create_node_pool_func func(mgnr); + mgnr->atomic_func(func); + return func.mp_node_pool; +} + +//!Object function that decrements the reference count. If the count +//!reaches to zero destroys the node allocator from memory. +//!Never throws +template +struct destroy_if_last_link_func +{ + //!Decrements reference count and destroys the object if there is no + //!more attached allocators. Never throws + void operator()() + { + //If not the last link return + if(mp_node_pool->dec_ref_count() != 0) return; + + //Last link, let's destroy the segment_manager + mp_node_pool->get_segment_manager()->template destroy(unique_instance); + } + + //!Constructor. Initializes function + //!object parameters + destroy_if_last_link_func(NodePool *pool) + : mp_node_pool(pool) + {} + + NodePool *mp_node_pool; +}; + +//!Destruction function, initializes and executes destruction function +//!object. Never throws +template +inline void destroy_node_pool_if_last_link(NodePool *pool) +{ + //Get segment manager + typename NodePool::segment_manager *mngr = pool->get_segment_manager(); + //Execute destruction functor atomically + destroy_if_last_link_funcfunc(pool); + mngr->atomic_func(func); +} + +template +class cache_impl +{ + typedef typename NodePool::segment_manager:: + void_pointer void_pointer; + typedef typename pointer_to_other + ::type node_pool_ptr; + typedef typename NodePool::multiallocation_chain multiallocation_chain; + node_pool_ptr mp_node_pool; + multiallocation_chain m_cached_nodes; + std::size_t m_max_cached_nodes; + + public: + typedef typename NodePool::multiallocation_iterator multiallocation_iterator; + typedef typename NodePool::segment_manager segment_manager; + + cache_impl(segment_manager *segment_mngr, std::size_t max_cached_nodes) + : mp_node_pool(get_or_create_node_pool(segment_mngr)) + , m_max_cached_nodes(max_cached_nodes) + {} + + cache_impl(const cache_impl &other) + : mp_node_pool(other.get_node_pool()) + , m_max_cached_nodes(other.get_max_cached_nodes()) + { + mp_node_pool->inc_ref_count(); + } + + ~cache_impl() + { + this->deallocate_all_cached_nodes(); + detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); + } + + NodePool *get_node_pool() const + { return detail::get_pointer(mp_node_pool); } + + segment_manager *get_segment_manager() const + { return mp_node_pool->get_segment_manager(); } + + std::size_t get_max_cached_nodes() const + { return m_max_cached_nodes; } + + void *cached_allocation() + { + //If don't have any cached node, we have to get a new list of free nodes from the pool + if(m_cached_nodes.empty()){ + mp_node_pool->allocate_nodes(m_cached_nodes, m_max_cached_nodes/2); + } + return m_cached_nodes.pop_front(); + } + + multiallocation_iterator cached_allocation(std::size_t n) + { + multiallocation_chain chain; + std::size_t count = n; + BOOST_TRY{ + //If don't have any cached node, we have to get a new list of free nodes from the pool + while(!m_cached_nodes.empty() && count--){ + void *ret = m_cached_nodes.pop_front(); + chain.push_back(ret); + } + + if(chain.size() != n){ + mp_node_pool->allocate_nodes(chain, n - chain.size()); + } + assert(chain.size() == n); + chain.splice_back(m_cached_nodes); + return multiallocation_iterator(chain.get_it()); + } + BOOST_CATCH(...){ + this->cached_deallocation(multiallocation_iterator(chain.get_it())); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + void cached_deallocation(void *ptr) + { + //Check if cache is full + if(m_cached_nodes.size() >= m_max_cached_nodes){ + //This only occurs if this allocator deallocate memory allocated + //with other equal allocator. Since the cache is full, and more + //deallocations are probably coming, we'll make some room in cache + //in a single, efficient multi node deallocation. + this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2); + } + m_cached_nodes.push_front(ptr); + } + + void cached_deallocation(multiallocation_iterator it) + { + multiallocation_iterator itend; + + while(it != itend){ + void *addr = &*it; + ++it; + m_cached_nodes.push_front(addr); + } + + //Check if cache is full + if(m_cached_nodes.size() >= m_max_cached_nodes){ + //This only occurs if this allocator deallocate memory allocated + //with other equal allocator. Since the cache is full, and more + //deallocations are probably coming, we'll make some room in cache + //in a single, efficient multi node deallocation. + this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2); + } + } + + //!Sets the new max cached nodes value. This can provoke deallocations + //!if "newmax" is less than current cached nodes. Never throws + void set_max_cached_nodes(std::size_t newmax) + { + m_max_cached_nodes = newmax; + this->priv_deallocate_remaining_nodes(); + } + + //!Frees all cached nodes. + //!Never throws + void deallocate_all_cached_nodes() + { + if(m_cached_nodes.empty()) return; + mp_node_pool->deallocate_nodes(m_cached_nodes); + } + + private: + //!Frees all cached nodes at once. + //!Never throws + void priv_deallocate_remaining_nodes() + { + if(m_cached_nodes.size() > m_max_cached_nodes){ + priv_deallocate_n_nodes(m_cached_nodes.size()-m_max_cached_nodes); + } + } + + //!Frees n cached nodes at once. Never throws + void priv_deallocate_n_nodes(std::size_t n) + { + //Deallocate all new linked list at once + mp_node_pool->deallocate_nodes(m_cached_nodes, n); + } +}; + +template +class array_allocation_impl +{ + const Derived *derived() const + { return static_cast(this); } + Derived *derived() + { return static_cast(this); } + + typedef typename SegmentManager::void_pointer void_pointer; + + public: + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + public: + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const + { + return (size_type)this->derived()->get_segment_manager()->size(detail::get_pointer(p))/sizeof(T); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0) + { + return this->derived()->get_segment_manager()->allocation_command + (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse)); + } + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements) + { + return multiallocation_iterator + (this->derived()->get_segment_manager()->allocate_many(sizeof(T)*elem_size, num_elements)); + } + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements) + { + return multiallocation_iterator + (this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T))); + } + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it) + { return this->derived()->get_segment_manager()->deallocate_many(it.base()); } + + //!Returns the number of elements that could be + //!allocated. Never throws + size_type max_size() const + { return this->derived()->get_segment_manager()->get_size()/sizeof(T); } + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const + { return pointer(boost::addressof(value)); } + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const + { return const_pointer(boost::addressof(value)); } + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr) + { new(detail::get_pointer(ptr)) value_type; } + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr) + { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } +}; + + +template +class node_pool_allocation_impl + : public array_allocation_impl + < Derived + , T + , SegmentManager> +{ + const Derived *derived() const + { return static_cast(this); } + Derived *derived() + { return static_cast(this); } + + typedef typename SegmentManager::void_pointer void_pointer; + typedef typename detail:: + pointer_to_other::type cvoid_pointer; + + public: + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + public: + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0) + { + (void)hint; + if(count > this->max_size()) + throw bad_alloc(); + else if(Version == 1 && count == 1) + return pointer(static_cast(this->derived()->get_node_pool()->allocate_node())); + else + return pointer(static_cast + (this->derived()->get_node_pool()->get_segment_manager()->allocate(sizeof(T)*count))); + } + + //!Deallocate allocated memory. Never throws + void deallocate(const pointer &ptr, size_type count) + { + (void)count; + if(Version == 1 && count == 1) + this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(ptr)); + else + this->derived()->get_node_pool()->get_segment_manager()->deallocate(detail::get_pointer(ptr)); + } + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one() + { return pointer(static_cast(this->derived()->get_node_pool()->allocate_node())); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements) + { return multiallocation_iterator(this->derived()->get_node_pool()->allocate_nodes(num_elements)); } + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p) + { this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(p)); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it) + { this->derived()->get_node_pool()->deallocate_nodes(it.base()); } + + //!Deallocates all free chunks of the pool + void deallocate_free_chunks() + { this->derived()->get_node_pool()->deallocate_free_chunks(); } +}; + +template +class cached_allocator_impl + : public array_allocation_impl + , T, typename NodePool::segment_manager> +{ + cached_allocator_impl & operator=(const cached_allocator_impl& other); + typedef array_allocation_impl + < cached_allocator_impl + + , T + , typename NodePool::segment_manager> base_t; + + public: + typedef NodePool node_pool_t; + typedef typename NodePool::segment_manager segment_manager; + typedef typename segment_manager::void_pointer void_pointer; + typedef typename detail:: + pointer_to_other::type cvoid_pointer; + typedef typename base_t::pointer pointer; + typedef typename base_t::size_type size_type; + typedef typename base_t::multiallocation_iterator multiallocation_iterator; + typedef typename base_t::multiallocation_chain multiallocation_chain; + typedef typename base_t::value_type value_type; + + public: + enum { DEFAULT_MAX_CACHED_NODES = 64 }; + + cached_allocator_impl(segment_manager *segment_mngr, std::size_t max_cached_nodes) + : m_cache(segment_mngr, max_cached_nodes) + {} + + cached_allocator_impl(const cached_allocator_impl &other) + : m_cache(other.m_cache) + {} + + //!Copy constructor from related cached_adaptive_pool_base. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + cached_allocator_impl + (const cached_allocator_impl + &other) + : m_cache(other.get_segment_manager(), other.get_max_cached_nodes()) + {} + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const + { return m_cache.get_node_pool(); } + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const + { return m_cache.get_segment_manager(); } + + //!Sets the new max cached nodes value. This can provoke deallocations + //!if "newmax" is less than current cached nodes. Never throws + void set_max_cached_nodes(std::size_t newmax) + { m_cache.set_max_cached_nodes(newmax); } + + //!Returns the max cached nodes parameter. + //!Never throws + std::size_t get_max_cached_nodes() const + { return m_cache.get_max_cached_nodes(); } + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0) + { + (void)hint; + void * ret; + if(count > this->max_size()) + throw bad_alloc(); + else if(Version == 1 && count == 1){ + ret = m_cache.cached_allocation(); + } + else{ + ret = this->get_segment_manager()->allocate(sizeof(T)*count); + } + return pointer(static_cast(ret)); + } + + //!Deallocate allocated memory. Never throws + void deallocate(const pointer &ptr, size_type count) + { + (void)count; + if(Version == 1 && count == 1){ + m_cache.cached_deallocation(detail::get_pointer(ptr)); + } + else{ + this->get_segment_manager()->deallocate(detail::get_pointer(ptr)); + } + } + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one() + { return pointer(static_cast(this->m_cache.cached_allocation())); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements) + { return multiallocation_iterator(this->m_cache.cached_allocation(num_elements)); } + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p) + { this->m_cache.cached_deallocation(detail::get_pointer(p)); } + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it) + { m_cache.cached_deallocation(it.base()); } + + //!Deallocates all free chunks of the pool + void deallocate_free_chunks() + { m_cache.get_node_pool()->deallocate_free_chunks(); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different shared memory segments, the result is undefined. + friend void swap(cached_allocator_impl &alloc1, cached_allocator_impl &alloc2) + { + detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); + alloc1.m_cached_nodes.swap(alloc2.m_cached_nodes); + detail::do_swap(alloc1.m_max_cached_nodes, alloc2.m_max_cached_nodes); + } + + void deallocate_cache() + { m_cache.deallocate_all_cached_nodes(); } + + /// @cond + private: + cache_impl m_cache; +}; + +//!Equality test for same type of +//!cached_allocator_impl +template inline +bool operator==(const cached_allocator_impl &alloc1, + const cached_allocator_impl &alloc2) + { return alloc1.get_node_pool() == alloc2.get_node_pool(); } + +//!Inequality test for same type of +//!cached_allocator_impl +template inline +bool operator!=(const cached_allocator_impl &alloc1, + const cached_allocator_impl &alloc2) + { return alloc1.get_node_pool() != alloc2.get_node_pool(); } + + +//!Pooled shared memory allocator using adaptive pool. Includes +//!a reference count but the class does not delete itself, this is +//!responsibility of user classes. Node size (NodeSize) and the number of +//!nodes allocated per chunk (NodesPerChunk) are known at compile time +template +class shared_pool_impl + : public private_node_allocator_t +{ + public: + //!Segment manager typedef + typedef typename private_node_allocator_t::segment_manager segment_manager; + typedef typename private_node_allocator_t:: + multiallocation_iterator multiallocation_iterator; + typedef typename private_node_allocator_t:: + multiallocation_chain multiallocation_chain; + + private: + typedef typename segment_manager::mutex_family::mutex_type mutex_type; + + public: + //!Constructor from a segment manager. Never throws + shared_pool_impl(segment_manager *segment_mngr) + : private_node_allocator_t(segment_mngr) + {} + + //!Destructor. Deallocates all allocated chunks. Never throws + ~shared_pool_impl() + {} + + //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc + void *allocate_node() + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return private_node_allocator_t::allocate_node(); + } + + //!Deallocates an array pointed by ptr. Never throws + void deallocate_node(void *ptr) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::deallocate_node(ptr); + } + + //!Allocates a singly linked list of n nodes ending in null pointer. + //!can throw boost::interprocess::bad_alloc + void allocate_nodes(multiallocation_chain &nodes, std::size_t n) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return private_node_allocator_t::allocate_nodes(nodes, n); + } + + //!Allocates n nodes, pointed by the multiallocation_iterator. + //!Can throw boost::interprocess::bad_alloc + multiallocation_iterator allocate_nodes(const std::size_t n) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return private_node_allocator_t::allocate_nodes(n); + } + + //!Deallocates a linked list of nodes ending in null pointer. Never throws + void deallocate_nodes(multiallocation_chain &nodes, std::size_t num) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::deallocate_nodes(nodes, num); + } + + //!Deallocates a linked list of nodes ending in null pointer. Never throws + void deallocate_nodes(multiallocation_chain &nodes) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::deallocate_nodes(nodes); + } + + //!Deallocates the nodes pointed by the multiallocation iterator. Never throws + void deallocate_nodes(multiallocation_iterator it) + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::deallocate_nodes(it); + } + + //!Deallocates all the free chunks of memory. Never throws + void deallocate_free_chunks() + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::deallocate_free_chunks(); + } + + //!Deallocates all used memory from the common pool. + //!Precondition: all nodes allocated from this pool should + //!already be deallocated. Otherwise, undefined behavior. Never throws + void purge_chunks() + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + private_node_allocator_t::purge_chunks(); + } + + //!Increments internal reference count and returns new count. Never throws + std::size_t inc_ref_count() + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return ++m_header.m_usecount; + } + + //!Decrements internal reference count and returns new count. Never throws + std::size_t dec_ref_count() + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + assert(m_header.m_usecount > 0); + return --m_header.m_usecount; + } + + private: + //!This struct includes needed data and derives from + //!interprocess_mutex to allow EBO when using null_mutex + struct header_t : mutex_type + { + std::size_t m_usecount; //Number of attached allocators + + header_t() + : m_usecount(0) {} + } m_header; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP diff --git a/thirdparty/boost/interprocess/allocators/detail/node_pool.hpp b/thirdparty/boost/interprocess/allocators/detail/node_pool.hpp new file mode 100644 index 0000000..2be550a --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/detail/node_pool.hpp @@ -0,0 +1,420 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP +#define BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes the real adaptive pool shared by many Interprocess adaptive pool allocators + +namespace boost { +namespace interprocess { +namespace detail { + +template +class private_node_pool_impl +{ + //Non-copyable + private_node_pool_impl(); + private_node_pool_impl(const private_node_pool_impl &); + private_node_pool_impl &operator=(const private_node_pool_impl &); + + //A node object will hold node_t when it's not allocated + public: + typedef typename SegmentManagerBase::void_pointer void_pointer; + typedef typename node_slist::slist_hook_t slist_hook_t; + typedef typename node_slist::node_t node_t; + typedef typename node_slist::node_slist_t free_nodes_t; + typedef typename SegmentManagerBase::multiallocation_iterator multiallocation_iterator; + typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain; + + private: + typedef typename bi::make_slist + < node_t, bi::base_hook + , bi::linear + , bi::constant_time_size >::type chunkslist_t; + public: + + //!Segment manager typedef + typedef SegmentManagerBase segment_manager_base_type; + + //!Constructor from a segment manager. Never throws + private_node_pool_impl(segment_manager_base_type *segment_mngr_base, std::size_t node_size, std::size_t nodes_per_chunk) + : m_nodes_per_chunk(nodes_per_chunk) + , m_real_node_size(detail::lcm(node_size, std::size_t(alignment_of::value))) + //General purpose allocator + , mp_segment_mngr_base(segment_mngr_base) + , m_chunklist() + , m_freelist() + //Debug node count + , m_allocated(0) + {} + + //!Destructor. Deallocates all allocated chunks. Never throws + ~private_node_pool_impl() + { this->purge_chunks(); } + + std::size_t get_real_num_node() const + { return m_nodes_per_chunk; } + + //!Returns the segment manager. Never throws + segment_manager_base_type* get_segment_manager_base()const + { return detail::get_pointer(mp_segment_mngr_base); } + + //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc + void *allocate_node() + { + //If there are no free nodes we allocate a new block + if (m_freelist.empty()) + priv_alloc_chunk(); + //We take the first free node + node_t *n = (node_t*)&m_freelist.front(); + m_freelist.pop_front(); + ++m_allocated; + return n; + } + + //!Deallocates an array pointed by ptr. Never throws + void deallocate_node(void *ptr) + { + //We put the node at the beginning of the free node list + node_t * to_deallocate = static_cast(ptr); + m_freelist.push_front(*to_deallocate); + assert(m_allocated>0); + --m_allocated; + } + + //!Allocates a singly linked list of n nodes ending in null pointer and pushes them in the chain. + //!can throw boost::interprocess::bad_alloc + void allocate_nodes(multiallocation_chain &nodes, const std::size_t n) + { + std::size_t i = 0; + try{ + for(; i < n; ++i){ + nodes.push_front(this->allocate_node()); + } + } + catch(...){ + this->deallocate_nodes(nodes, i); + throw; + } + } + + //!Allocates a singly linked list of n nodes ending in null pointer + //!can throw boost::interprocess::bad_alloc + multiallocation_iterator allocate_nodes(const std::size_t n) + { + multiallocation_chain nodes; + std::size_t i = 0; + try{ + for(; i < n; ++i){ + nodes.push_front(this->allocate_node()); + } + } + catch(...){ + this->deallocate_nodes(nodes, i); + throw; + } + return nodes.get_it(); + } + + //!Deallocates a linked list of nodes. Never throws + void deallocate_nodes(multiallocation_chain &nodes) + { + this->deallocate_nodes(nodes.get_it()); + nodes.reset(); + } + + //!Deallocates the first n nodes of a linked list of nodes. Never throws + void deallocate_nodes(multiallocation_chain &nodes, std::size_t num) + { + assert(nodes.size() >= num); + for(std::size_t i = 0; i < num; ++i){ + deallocate_node(nodes.pop_front()); + } + } + + //!Deallocates the nodes pointed by the multiallocation iterator. Never throws + void deallocate_nodes(multiallocation_iterator it) + { + multiallocation_iterator itend; + while(it != itend){ + void *addr = &*it; + ++it; + deallocate_node(addr); + } + } + + //!Deallocates all the free chunks of memory. Never throws + void deallocate_free_chunks() + { + typedef typename free_nodes_t::iterator nodelist_iterator; + typename chunkslist_t::iterator bit(m_chunklist.before_begin()), + it(m_chunklist.begin()), + itend(m_chunklist.end()); + free_nodes_t backup_list; + nodelist_iterator backup_list_last = backup_list.before_begin(); + + //Execute the algorithm and get an iterator to the last value + std::size_t blocksize = detail::get_rounded_size + (m_real_node_size*m_nodes_per_chunk, alignment_of::value); + + while(it != itend){ + //Collect all the nodes from the chunk pointed by it + //and push them in the list + free_nodes_t free_nodes; + nodelist_iterator last_it = free_nodes.before_begin(); + const void *addr = get_chunk_from_hook(&*it, blocksize); + + m_freelist.remove_and_dispose_if + (is_between(addr, blocksize), push_in_list(free_nodes, last_it)); + + //If the number of nodes is equal to m_nodes_per_chunk + //this means that the block can be deallocated + if(free_nodes.size() == m_nodes_per_chunk){ + //Unlink the nodes + free_nodes.clear(); + it = m_chunklist.erase_after(bit); + mp_segment_mngr_base->deallocate((void*)addr); + } + //Otherwise, insert them in the backup list, since the + //next "remove_if" does not need to check them again. + else{ + //Assign the iterator to the last value if necessary + if(backup_list.empty() && !m_freelist.empty()){ + backup_list_last = last_it; + } + //Transfer nodes. This is constant time. + backup_list.splice_after + ( backup_list.before_begin() + , free_nodes + , free_nodes.before_begin() + , last_it + , free_nodes.size()); + bit = it; + ++it; + } + } + //We should have removed all the nodes from the free list + assert(m_freelist.empty()); + + //Now pass all the node to the free list again + m_freelist.splice_after + ( m_freelist.before_begin() + , backup_list + , backup_list.before_begin() + , backup_list_last + , backup_list.size()); + } + + std::size_t num_free_nodes() + { return m_freelist.size(); } + + //!Deallocates all used memory. Precondition: all nodes allocated from this pool should + //!already be deallocated. Otherwise, undefined behaviour. Never throws + void purge_chunks() + { + //check for memory leaks + assert(m_allocated==0); + std::size_t blocksize = detail::get_rounded_size + (m_real_node_size*m_nodes_per_chunk, alignment_of::value); + typename chunkslist_t::iterator + it(m_chunklist.begin()), itend(m_chunklist.end()), aux; + + //We iterate though the NodeBlock list to free the memory + while(!m_chunklist.empty()){ + void *addr = get_chunk_from_hook(&m_chunklist.front(), blocksize); + m_chunklist.pop_front(); + mp_segment_mngr_base->deallocate(addr); + } + //Just clear free node list + m_freelist.clear(); + } + + void swap(private_node_pool_impl &other) + { + std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base); + m_chunklist.swap(other.m_chunklist); + m_freelist.swap(other.m_freelist); + std::swap(m_allocated, other.m_allocated); + } + + private: + + struct push_in_list + { + push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it) + : slist_(l), last_it_(it) + {} + + void operator()(typename free_nodes_t::pointer p) const + { + slist_.push_front(*p); + if(slist_.size() == 1){ //Cache last element + ++last_it_ = slist_.begin(); + } + } + + private: + free_nodes_t &slist_; + typename free_nodes_t::iterator &last_it_; + }; + + struct is_between + : std::unary_function + { + is_between(const void *addr, std::size_t size) + : beg_((const char *)addr), end_(beg_+size) + {} + + bool operator()(typename free_nodes_t::const_reference v) const + { + return (beg_ <= (const char *)&v && + end_ > (const char *)&v); + } + private: + const char * beg_; + const char * end_; + }; + + //!Allocates a chunk of nodes. Can throw boost::interprocess::bad_alloc + void priv_alloc_chunk() + { + //We allocate a new NodeBlock and put it as first + //element in the free Node list + std::size_t blocksize = + detail::get_rounded_size(m_real_node_size*m_nodes_per_chunk, alignment_of::value); + char *pNode = detail::char_ptr_cast + (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t))); + if(!pNode) throw bad_alloc(); + char *pBlock = pNode; + m_chunklist.push_front(get_chunk_hook(pBlock, blocksize)); + + //We initialize all Nodes in Node Block to insert + //them in the free Node list + for(std::size_t i = 0; i < m_nodes_per_chunk; ++i, pNode += m_real_node_size){ + m_freelist.push_front(*new (pNode) node_t); + } + } + + private: + //!Returns a reference to the chunk hook placed in the end of the chunk + static inline node_t & get_chunk_hook (void *chunk, std::size_t blocksize) + { + return *static_cast( + static_cast((detail::char_ptr_cast(chunk) + blocksize))); + } + + //!Returns the starting address of the chunk reference to the chunk hook placed in the end of the chunk + inline void *get_chunk_from_hook (node_t *hook, std::size_t blocksize) + { + return static_cast((detail::char_ptr_cast(hook) - blocksize)); + } + + private: + typedef typename pointer_to_other + ::type segment_mngr_base_ptr_t; + + const std::size_t m_nodes_per_chunk; + const std::size_t m_real_node_size; + segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager + chunkslist_t m_chunklist; //Intrusive container of chunks + free_nodes_t m_freelist; //Intrusive container of free nods + std::size_t m_allocated; //Used nodes for debugging +}; + + +//!Pooled shared memory allocator using single segregated storage. Includes +//!a reference count but the class does not delete itself, this is +//!responsibility of user classes. Node size (NodeSize) and the number of +//!nodes allocated per chunk (NodesPerChunk) are known at compile time +template< class SegmentManager, std::size_t NodeSize, std::size_t NodesPerChunk > +class private_node_pool + //Inherit from the implementation to avoid template bloat + : public private_node_pool_impl +{ + typedef private_node_pool_impl base_t; + //Non-copyable + private_node_pool(); + private_node_pool(const private_node_pool &); + private_node_pool &operator=(const private_node_pool &); + + public: + typedef SegmentManager segment_manager; + + static const std::size_t nodes_per_chunk = NodesPerChunk; + + //!Constructor from a segment manager. Never throws + private_node_pool(segment_manager *segment_mngr) + : base_t(segment_mngr, NodeSize, NodesPerChunk) + {} + + //!Returns the segment manager. Never throws + segment_manager* get_segment_manager() const + { return static_cast(base_t::get_segment_manager_base()); } +}; + + +//!Pooled shared memory allocator using single segregated storage. Includes +//!a reference count but the class does not delete itself, this is +//!responsibility of user classes. Node size (NodeSize) and the number of +//!nodes allocated per chunk (NodesPerChunk) are known at compile time +//!Pooled shared memory allocator using adaptive pool. Includes +//!a reference count but the class does not delete itself, this is +//!responsibility of user classes. Node size (NodeSize) and the number of +//!nodes allocated per chunk (NodesPerChunk) are known at compile time +template< class SegmentManager + , std::size_t NodeSize + , std::size_t NodesPerChunk + > +class shared_node_pool + : public detail::shared_pool_impl + < private_node_pool + + > +{ + typedef detail::shared_pool_impl + < private_node_pool + + > base_t; + public: + shared_node_pool(SegmentManager *segment_mgnr) + : base_t(segment_mgnr) + {} +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_NODE_POOL_HPP diff --git a/thirdparty/boost/interprocess/allocators/detail/node_tools.hpp b/thirdparty/boost/interprocess/allocators/detail/node_tools.hpp new file mode 100644 index 0000000..e787aef --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/detail/node_tools.hpp @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_NODE_TOOLS_HPP +#define BOOST_INTERPROCESS_DETAIL_NODE_TOOLS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include + +namespace boost { +namespace interprocess { +namespace detail { + + +template +struct node_slist +{ + //This hook will be used to chain the individual nodes + typedef typename bi::make_slist_base_hook + , bi::link_mode >::type slist_hook_t; + + //A node object will hold node_t when it's not allocated + struct node_t + : public slist_hook_t + {}; + + typedef typename bi::make_slist + , bi::base_hook >::type node_slist_t; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_NODE_TOOLS_HPP diff --git a/thirdparty/boost/interprocess/allocators/node_allocator.hpp b/thirdparty/boost/interprocess/allocators/node_allocator.hpp new file mode 100644 index 0000000..ac5f2a5 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/node_allocator.hpp @@ -0,0 +1,434 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes node_allocator pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail{ + +template < unsigned int Version + , class T + , class SegmentManager + , std::size_t NodesPerChunk + > +class node_allocator_base + : public node_pool_allocation_impl + < node_allocator_base + < Version, T, SegmentManager, NodesPerChunk> + , Version + , T + , SegmentManager + > +{ + public: + typedef typename SegmentManager::void_pointer void_pointer; + typedef SegmentManager segment_manager; + typedef node_allocator_base + self_t; + typedef detail::shared_node_pool + < SegmentManager, sizeof(T), NodesPerChunk> node_pool_t; + typedef typename detail:: + pointer_to_other::type node_pool_ptr; + + BOOST_STATIC_ASSERT((Version <=2)); + + public: + //------- + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef detail::version_type version; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + //!Obtains node_allocator_base from + //!node_allocator_base + template + struct rebind + { + typedef node_allocator_base other; + }; + + /// @cond + private: + //!Not assignable from related node_allocator_base + template + node_allocator_base& operator= + (const node_allocator_base&); + + //!Not assignable from other node_allocator_base + node_allocator_base& operator=(const node_allocator_base&); + /// @endcond + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + node_allocator_base(segment_manager *segment_mngr) + : mp_node_pool(detail::get_or_create_node_pool(segment_mngr)) { } + + //!Copy constructor from other node_allocator_base. Increments the reference + //!count of the associated node pool. Never throws + node_allocator_base(const node_allocator_base &other) + : mp_node_pool(other.get_node_pool()) + { + mp_node_pool->inc_ref_count(); + } + + //!Copy constructor from related node_allocator_base. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + node_allocator_base + (const node_allocator_base &other) + : mp_node_pool(detail::get_or_create_node_pool(other.get_segment_manager())) { } + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~node_allocator_base() + { detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); } + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const + { return detail::get_pointer(mp_node_pool); } + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const + { return mp_node_pool->get_segment_manager(); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2) + { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); } + + /// @cond + private: + node_pool_ptr mp_node_pool; + /// @endcond +}; + +//!Equality test for same type +//!of node_allocator_base +template inline +bool operator==(const node_allocator_base &alloc1, + const node_allocator_base &alloc2) + { return alloc1.get_node_pool() == alloc2.get_node_pool(); } + +//!Inequality test for same type +//!of node_allocator_base +template inline +bool operator!=(const node_allocator_base &alloc1, + const node_allocator_base &alloc2) + { return alloc1.get_node_pool() != alloc2.get_node_pool(); } + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + > +class node_allocator_v1 + : public node_allocator_base + < 1 + , T + , SegmentManager + , NodesPerChunk + > +{ + public: + typedef detail::node_allocator_base + < 1, T, SegmentManager, NodesPerChunk> base_t; + + template + struct rebind + { + typedef node_allocator_v1 other; + }; + + node_allocator_v1(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + node_allocator_v1 + (const node_allocator_v1 &other) + : base_t(other) + {} +}; + +} //namespace detail{ + +/// @endcond + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//!This node allocator shares a segregated storage between all instances +//!of node_allocator with equal sizeof(T) placed in the same segment +//!group. NodesPerChunk is the number of nodes allocated at once when the allocator +//!needs runs out of nodes +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + > +class node_allocator + /// @cond + : public detail::node_allocator_base + < 2 + , T + , SegmentManager + , NodesPerChunk + > + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef detail::node_allocator_base + < 2, T, SegmentManager, NodesPerChunk> base_t; + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef node_allocator other; + }; + + node_allocator(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + node_allocator + (const node_allocator &other) + : base_t(other) + {} + + #else //BOOST_INTERPROCESS_DOXYGEN_INVOKED + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains node_allocator from + //!node_allocator + template + struct rebind + { + typedef node_allocator other; + }; + + private: + //!Not assignable from + //!related node_allocator + template + node_allocator& operator= + (const node_allocator&); + + //!Not assignable from + //!other node_allocator + node_allocator& operator=(const node_allocator&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + node_allocator(segment_manager *segment_mngr); + + //!Copy constructor from other node_allocator. Increments the reference + //!count of the associated node pool. Never throws + node_allocator(const node_allocator &other); + + //!Copy constructor from related node_allocator. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + node_allocator + (const node_allocator &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~node_allocator(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of node_allocator +template inline +bool operator==(const node_allocator &alloc1, + const node_allocator &alloc2); + +//!Inequality test for same type +//!of node_allocator +template inline +bool operator!=(const node_allocator &alloc1, + const node_allocator &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP diff --git a/thirdparty/boost/interprocess/allocators/private_adaptive_pool.hpp b/thirdparty/boost/interprocess/allocators/private_adaptive_pool.hpp new file mode 100644 index 0000000..575e8a1 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/private_adaptive_pool.hpp @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_PRIVATE_ADAPTIVE_POOL_HPP +#define BOOST_INTERPROCESS_PRIVATE_ADAPTIVE_POOL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes private_adaptive_pool_base pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail { + +template < unsigned int Version + , class T + , class SegmentManager + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class private_adaptive_pool_base + : public node_pool_allocation_impl + < private_adaptive_pool_base < Version, T, SegmentManager, NodesPerChunk + , MaxFreeChunks, OverheadPercent> + , Version + , T + , SegmentManager + > +{ + /// @cond + private: + typedef typename SegmentManager::void_pointer void_pointer; + typedef SegmentManager segment_manager; + typedef private_adaptive_pool_base + < Version, T, SegmentManager, NodesPerChunk + , MaxFreeChunks, OverheadPercent> self_t; + typedef detail::private_adaptive_node_pool + node_pool_t; + + BOOST_STATIC_ASSERT((Version <=2)); + + /// @endcond + + public: + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef detail::version_type + version; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + //!Obtains node_allocator from other node_allocator + template + struct rebind + { + typedef private_adaptive_pool_base + other; + }; + + /// @cond + private: + //!Not assignable from related private_adaptive_pool_base + template + private_adaptive_pool_base& operator= + (const private_adaptive_pool_base&); + + //!Not assignable from other private_adaptive_pool_base + private_adaptive_pool_base& operator=(const private_adaptive_pool_base&); + /// @endcond + + public: + //!Constructor from a segment manager + private_adaptive_pool_base(segment_manager *segment_mngr) + : m_node_pool(segment_mngr) + {} + + //!Copy constructor from other private_adaptive_pool_base. Never throws + private_adaptive_pool_base(const private_adaptive_pool_base &other) + : m_node_pool(other.get_segment_manager()) + {} + + //!Copy constructor from related private_adaptive_pool_base. Never throws. + template + private_adaptive_pool_base + (const private_adaptive_pool_base + &other) + : m_node_pool(other.get_segment_manager()) + {} + + //!Destructor, frees all used memory. Never throws + ~private_adaptive_pool_base() + {} + + //!Returns the segment manager. Never throws + segment_manager* get_segment_manager()const + { return m_node_pool.get_segment_manager(); } + + //!Returns the internal node pool. Never throws + node_pool_t* get_node_pool() const + { return const_cast(&m_node_pool); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different shared memory segments, the result is undefined. + friend void swap(self_t &alloc1,self_t &alloc2) + { alloc1.m_node_pool.swap(alloc2.m_node_pool); } + + /// @cond + private: + node_pool_t m_node_pool; + /// @endcond +}; + +//!Equality test for same type of private_adaptive_pool_base +template inline +bool operator==(const private_adaptive_pool_base &alloc1, + const private_adaptive_pool_base &alloc2) +{ return &alloc1 == &alloc2; } + +//!Inequality test for same type of private_adaptive_pool_base +template inline +bool operator!=(const private_adaptive_pool_base &alloc1, + const private_adaptive_pool_base &alloc2) +{ return &alloc1 != &alloc2; } + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + , std::size_t MaxFreeChunks = 2 + , unsigned char OverheadPercent = 5 + > +class private_adaptive_pool_v1 + : public private_adaptive_pool_base + < 1 + , T + , SegmentManager + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > +{ + public: + typedef detail::private_adaptive_pool_base + < 1, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t; + + template + struct rebind + { + typedef private_adaptive_pool_v1 other; + }; + + private_adaptive_pool_v1(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + private_adaptive_pool_v1 + (const private_adaptive_pool_v1 &other) + : base_t(other) + {} +}; + +} //namespace detail { + +/// @endcond + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//!This allocator has its own node pool. +//! +//!NodesPerChunk is the minimum number of nodes of nodes allocated at once when +//!the allocator needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks +//!that the adaptive node pool will hold. The rest of the totally free chunks will be +//!deallocated with the segment manager. +//! +//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator: +//!(memory usable for nodes / total memory allocated from the segment manager) +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + , std::size_t MaxFreeChunks + , unsigned char OverheadPercent + > +class private_adaptive_pool + /// @cond + : public detail::private_adaptive_pool_base + < 2 + , T + , SegmentManager + , NodesPerChunk + , MaxFreeChunks + , OverheadPercent + > + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef detail::private_adaptive_pool_base + < 2, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t; + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef private_adaptive_pool + other; + }; + + private_adaptive_pool(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + private_adaptive_pool + (const private_adaptive_pool &other) + : base_t(other) + {} + + #else + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains private_adaptive_pool from + //!private_adaptive_pool + template + struct rebind + { + typedef private_adaptive_pool + other; + }; + + private: + //!Not assignable from + //!related private_adaptive_pool + template + private_adaptive_pool& operator= + (const private_adaptive_pool&); + + //!Not assignable from + //!other private_adaptive_pool + private_adaptive_pool& operator=(const private_adaptive_pool&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + private_adaptive_pool(segment_manager *segment_mngr); + + //!Copy constructor from other private_adaptive_pool. Increments the reference + //!count of the associated node pool. Never throws + private_adaptive_pool(const private_adaptive_pool &other); + + //!Copy constructor from related private_adaptive_pool. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + private_adaptive_pool + (const private_adaptive_pool &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~private_adaptive_pool(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of private_adaptive_pool +template inline +bool operator==(const private_adaptive_pool &alloc1, + const private_adaptive_pool &alloc2); + +//!Inequality test for same type +//!of private_adaptive_pool +template inline +bool operator!=(const private_adaptive_pool &alloc1, + const private_adaptive_pool &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_ADAPTIVE_POOL_HPP + diff --git a/thirdparty/boost/interprocess/allocators/private_node_allocator.hpp b/thirdparty/boost/interprocess/allocators/private_node_allocator.hpp new file mode 100644 index 0000000..fb3ef06 --- /dev/null +++ b/thirdparty/boost/interprocess/allocators/private_node_allocator.hpp @@ -0,0 +1,632 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +/* +#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes private_node_allocator pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//!This allocator has its own node pool. NodesPerChunk is the number of nodes allocated +//!at once when the allocator needs runs out of nodes +template +class private_node_allocator +{ + /// @cond + private: + typedef typename SegmentManager::void_pointer void_pointer; + typedef typename detail:: + pointer_to_other::type cvoid_pointer; + typedef SegmentManager segment_manager; + typedef typename detail::pointer_to_other + ::type segment_mngr_ptr_t; + typedef private_node_allocator + self_t; + typedef detail::private_node_pool + priv_node_pool_t; + /// @endcond + + public: + //------- + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains node_allocator from other node_allocator + template + struct rebind + { + typedef private_node_allocator other; + }; + + /// @cond + private: + //!Not assignable from related private_node_allocator + template + private_node_allocator& operator= + (const private_node_allocator&); + + //!Not assignable from other private_node_allocator + private_node_allocator& operator=(const private_node_allocator&); + /// @endcond + + public: + + //!Constructor from a segment manager + private_node_allocator(segment_manager *segment_mngr) + : m_node_pool(segment_mngr){} + + //!Copy constructor from other private_node_allocator. Never throws + private_node_allocator(const private_node_allocator &other) + : m_node_pool(other.get_segment_manager()){} + + //!Copy constructor from related private_node_allocator. Never throws. + template + private_node_allocator + (const private_node_allocator &other) + : m_node_pool(other.get_segment_manager()) + {} + + //!Destructor, frees all used memory. Never throws + ~private_node_allocator() + {} + + //!Returns the segment manager. Never throws + segment_manager* get_segment_manager()const + { return m_node_pool.get_segment_manager(); } + + //!Returns the number of elements that could be allocated. Never throws + size_type max_size() const + { return this->get_segment_manager()->get_size()/sizeof(value_type); } + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0) + { + (void)hint; + if(count > this->max_size()) + throw bad_alloc(); + else if(count == 1) + return pointer(static_cast(m_node_pool.allocate_node())); + else + return pointer(static_cast + (m_node_pool.get_segment_manager()->allocate(sizeof(T)*count))); + } + + //!Deallocate allocated memory. Never throws + void deallocate(const pointer &ptr, size_type count) + { + if(count == 1) + m_node_pool.deallocate_node(detail::get_pointer(ptr)); + else + m_node_pool.get_segment_manager()->deallocate(detail::get_pointer(ptr)); + } + + //!Deallocates all free chunks of the pool + void deallocate_free_chunks() + { m_node_pool.deallocate_free_chunks(); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different shared memory segments, the result is undefined. + friend void swap(self_t &alloc1,self_t &alloc2) + { alloc1.m_node_pool.swap(alloc2.m_node_pool); } + + //These functions are obsolete. These are here to conserve + //backwards compatibility with containers using them... + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const + { return pointer(boost::addressof(value)); } + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const + { return const_pointer(boost::addressof(value)); } + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr) + { new(detail::get_pointer(ptr)) value_type; } + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr) + { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } + + /// @cond + private: + priv_node_pool_t m_node_pool; + /// @endcond +}; + +//!Equality test for same type of private_node_allocator +template inline +bool operator==(const private_node_allocator &alloc1, + const private_node_allocator &alloc2) +{ return &alloc1 == &alloc2; } + +//!Inequality test for same type of private_node_allocator +template inline +bool operator!=(const private_node_allocator &alloc1, + const private_node_allocator &alloc2) +{ + return &alloc1 != &alloc2; +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP + +*/ + +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP +#define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes private_node_allocator_base pooled shared memory STL compatible allocator + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail { + +template < unsigned int Version + , class T + , class SegmentManager + , std::size_t NodesPerChunk + > +class private_node_allocator_base + : public node_pool_allocation_impl + < private_node_allocator_base < Version, T, SegmentManager, NodesPerChunk> + , Version + , T + , SegmentManager + > +{ + /// @cond + private: + typedef typename SegmentManager::void_pointer void_pointer; + typedef SegmentManager segment_manager; + typedef private_node_allocator_base + < Version, T, SegmentManager, NodesPerChunk> self_t; + typedef detail::private_node_pool + node_pool_t; + + BOOST_STATIC_ASSERT((Version <=2)); + + /// @endcond + + public: + typedef typename detail:: + pointer_to_other::type pointer; + typedef typename detail:: + pointer_to_other::type const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef detail::version_type + version; + typedef transform_iterator + < typename SegmentManager:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + typedef typename SegmentManager:: + multiallocation_chain multiallocation_chain; + + //!Obtains node_allocator from other node_allocator + template + struct rebind + { + typedef private_node_allocator_base + other; + }; + + /// @cond + private: + //!Not assignable from related private_node_allocator_base + template + private_node_allocator_base& operator= + (const private_node_allocator_base&); + + //!Not assignable from other private_node_allocator_base + private_node_allocator_base& operator=(const private_node_allocator_base&); + /// @endcond + + public: + //!Constructor from a segment manager + private_node_allocator_base(segment_manager *segment_mngr) + : m_node_pool(segment_mngr) + {} + + //!Copy constructor from other private_node_allocator_base. Never throws + private_node_allocator_base(const private_node_allocator_base &other) + : m_node_pool(other.get_segment_manager()) + {} + + //!Copy constructor from related private_node_allocator_base. Never throws. + template + private_node_allocator_base + (const private_node_allocator_base + &other) + : m_node_pool(other.get_segment_manager()) + {} + + //!Destructor, frees all used memory. Never throws + ~private_node_allocator_base() + {} + + //!Returns the segment manager. Never throws + segment_manager* get_segment_manager()const + { return m_node_pool.get_segment_manager(); } + + //!Returns the internal node pool. Never throws + node_pool_t* get_node_pool() const + { return const_cast(&m_node_pool); } + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different shared memory segments, the result is undefined. + friend void swap(self_t &alloc1,self_t &alloc2) + { alloc1.m_node_pool.swap(alloc2.m_node_pool); } + + /// @cond + private: + node_pool_t m_node_pool; + /// @endcond +}; + +//!Equality test for same type of private_node_allocator_base +template inline +bool operator==(const private_node_allocator_base &alloc1, + const private_node_allocator_base &alloc2) +{ return &alloc1 == &alloc2; } + +//!Inequality test for same type of private_node_allocator_base +template inline +bool operator!=(const private_node_allocator_base &alloc1, + const private_node_allocator_base &alloc2) +{ return &alloc1 != &alloc2; } + +template < class T + , class SegmentManager + , std::size_t NodesPerChunk = 64 + > +class private_node_allocator_v1 + : public private_node_allocator_base + < 1 + , T + , SegmentManager + , NodesPerChunk + > +{ + public: + typedef detail::private_node_allocator_base + < 1, T, SegmentManager, NodesPerChunk> base_t; + + template + struct rebind + { + typedef private_node_allocator_v1 other; + }; + + private_node_allocator_v1(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + private_node_allocator_v1 + (const private_node_allocator_v1 &other) + : base_t(other) + {} +}; + +} //namespace detail { + +/// @endcond + +//!An STL node allocator that uses a segment manager as memory +//!source. The internal pointer type will of the same type (raw, smart) as +//!"typename SegmentManager::void_pointer" type. This allows +//!placing the allocator in shared memory, memory mapped-files, etc... +//!This allocator has its own node pool. NodesPerChunk is the number of nodes allocated +//!at once when the allocator needs runs out of nodes +template < class T + , class SegmentManager + , std::size_t NodesPerChunk + > +class private_node_allocator + /// @cond + : public detail::private_node_allocator_base + < 2 + , T + , SegmentManager + , NodesPerChunk + > + /// @endcond +{ + + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef detail::private_node_allocator_base + < 2, T, SegmentManager, NodesPerChunk> base_t; + public: + typedef detail::version_type version; + + template + struct rebind + { + typedef private_node_allocator + other; + }; + + private_node_allocator(SegmentManager *segment_mngr) + : base_t(segment_mngr) + {} + + template + private_node_allocator + (const private_node_allocator &other) + : base_t(other) + {} + + #else + public: + typedef implementation_defined::segment_manager segment_manager; + typedef segment_manager::void_pointer void_pointer; + typedef implementation_defined::pointer pointer; + typedef implementation_defined::const_pointer const_pointer; + typedef T value_type; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + //!Obtains private_node_allocator from + //!private_node_allocator + template + struct rebind + { + typedef private_node_allocator + other; + }; + + private: + //!Not assignable from + //!related private_node_allocator + template + private_node_allocator& operator= + (const private_node_allocator&); + + //!Not assignable from + //!other private_node_allocator + private_node_allocator& operator=(const private_node_allocator&); + + public: + //!Constructor from a segment manager. If not present, constructs a node + //!pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + private_node_allocator(segment_manager *segment_mngr); + + //!Copy constructor from other private_node_allocator. Increments the reference + //!count of the associated node pool. Never throws + private_node_allocator(const private_node_allocator &other); + + //!Copy constructor from related private_node_allocator. If not present, constructs + //!a node pool. Increments the reference count of the associated node pool. + //!Can throw boost::interprocess::bad_alloc + template + private_node_allocator + (const private_node_allocator &other); + + //!Destructor, removes node_pool_t from memory + //!if its reference count reaches to zero. Never throws + ~private_node_allocator(); + + //!Returns a pointer to the node pool. + //!Never throws + node_pool_t* get_node_pool() const; + + //!Returns the segment manager. + //!Never throws + segment_manager* get_segment_manager()const; + + //!Returns the number of elements that could be allocated. + //!Never throws + size_type max_size() const; + + //!Allocate memory for an array of count elements. + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate(size_type count, cvoid_pointer hint = 0); + + //!Deallocate allocated memory. + //!Never throws + void deallocate(const pointer &ptr, size_type count); + + //!Deallocates all free chunks + //!of the pool + void deallocate_free_chunks(); + + //!Swaps allocators. Does not throw. If each allocator is placed in a + //!different memory segment, the result is undefined. + friend void swap(self_t &alloc1, self_t &alloc2); + + //!Returns address of mutable object. + //!Never throws + pointer address(reference value) const; + + //!Returns address of non mutable object. + //!Never throws + const_pointer address(const_reference value) const; + + //!Default construct an object. + //!Throws if T's default constructor throws + void construct(const pointer &ptr); + + //!Destroys object. Throws if object's + //!destructor throws + void destroy(const pointer &ptr); + + //!Returns maximum the number of objects the previously allocated memory + //!pointed by p can hold. This size only works for memory allocated with + //!allocate, allocation_command and allocate_many. + size_type size(const pointer &p) const; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements); + + //!Allocates n_elements elements, each one of size elem_sizes[i]in a + //!contiguous chunk + //!of memory. The elements must be deallocated + multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements); + + //!Allocates many elements of size elem_size in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. The elements must be deallocated + //!with deallocate(...) + void deallocate_many(multiallocation_iterator it); + + //!Allocates just one object. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + //!Throws boost::interprocess::bad_alloc if there is no enough memory + pointer allocate_one(); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + multiallocation_iterator allocate_individual(std::size_t num_elements); + + //!Deallocates memory previously allocated with allocate_one(). + //!You should never use deallocate_one to deallocate memory allocated + //!with other functions different from allocate_one(). Never throws + void deallocate_one(const pointer &p); + + //!Allocates many elements of size == 1 in a contiguous chunk + //!of memory. The minimum number to be allocated is min_elements, + //!the preferred and maximum number is + //!preferred_elements. The number of actually allocated elements is + //!will be assigned to received_size. Memory allocated with this function + //!must be deallocated only with deallocate_one(). + void deallocate_individual(multiallocation_iterator it); + #endif +}; + +#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED + +//!Equality test for same type +//!of private_node_allocator +template inline +bool operator==(const private_node_allocator &alloc1, + const private_node_allocator &alloc2); + +//!Inequality test for same type +//!of private_node_allocator +template inline +bool operator!=(const private_node_allocator &alloc1, + const private_node_allocator &alloc2); + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP + diff --git a/thirdparty/boost/interprocess/containers/deque.hpp b/thirdparty/boost/interprocess/containers/deque.hpp new file mode 100644 index 0000000..e76e79f --- /dev/null +++ b/thirdparty/boost/interprocess/containers/deque.hpp @@ -0,0 +1,1561 @@ +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_deque.h and stl_uninitialized.h files. +// Modified by Ion Gaztanaga 2005. +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DEQUE_HPP +#define BOOST_INTERPROCESS_DEQUE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { + +/// @cond +template +class deque; + +// Note: this function is simply a kludge to work around several compilers' +// bugs in handling constant expressions. +inline std::size_t deque_buf_size(std::size_t size) + { return size < 512 ? std::size_t(512 / size) : std::size_t(1); } + +// Deque base class. It has two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. +template +class deque_base +{ + public: + typedef typename Alloc::value_type val_alloc_val; + typedef typename Alloc::pointer val_alloc_ptr; + typedef typename Alloc::const_pointer val_alloc_cptr; + typedef typename Alloc::reference val_alloc_ref; + typedef typename Alloc::const_reference val_alloc_cref; + typedef typename Alloc::value_type val_alloc_diff; + typedef typename Alloc::template rebind + ::other ptr_alloc_t; + typedef typename ptr_alloc_t::value_type ptr_alloc_val; + typedef typename ptr_alloc_t::pointer ptr_alloc_ptr; + typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr; + typedef typename ptr_alloc_t::reference ptr_alloc_ref; + typedef typename ptr_alloc_t::const_reference ptr_alloc_cref; + typedef typename Alloc::template + rebind::other allocator_type; + typedef allocator_type stored_allocator_type; + + protected: + enum { trivial_dctr_after_move = boost::has_trivial_destructor::value }; + + typedef typename Alloc::template + rebind::other map_allocator_type; + + val_alloc_ptr priv_allocate_node() + { return this->alloc().allocate(deque_buf_size(sizeof(T))); } + + void priv_deallocate_node(val_alloc_ptr p) + { this->alloc().deallocate(p, deque_buf_size(sizeof(T))); } + + ptr_alloc_ptr priv_allocate_map(std::size_t n) + { return this->ptr_alloc().allocate(n); } + + void priv_deallocate_map(ptr_alloc_ptr p, std::size_t n) + { this->ptr_alloc().deallocate(p, n); } + + public: + // Class invariants: + // For any nonsingular iterator i: + // i.node is the address of an element in the map array. The + // contents of i.node is a pointer to the beginning of a node. + // i.first == //(i.node) + // i.last == i.first + node_size + // i.cur is a pointer in the range [i.first, i.last). NOTE: + // the implication of this is that i.cur is always a dereferenceable + // pointer, even if i is a past-the-end iterator. + // Start and Finish are always nonsingular iterators. NOTE: this means + // that an empty deque must have one node, and that a deque + // with N elements, where N is the buffer size, must have two nodes. + // For every node other than start.node and finish.node, every element + // in the node is an initialized object. If start.node == finish.node, + // then [start.cur, finish.cur) are initialized objects, and + // the elements outside that range are uninitialized storage. Otherwise, + // [start.cur, start.last) and [finish.first, finish.cur) are initialized + // objects, and [start.first, start.cur) and [finish.cur, finish.last) + // are uninitialized storage. + // [map, map + map_size) is a valid, non-empty range. + // [start.node, finish.node] is a valid range contained within + // [map, map + map_size). + // A pointer in the range [map, map + map_size) points to an allocated node + // if and only if the pointer is in the range [start.node, finish.node]. + class const_iterator + : public std::iterator + { + public: + static std::size_t s_buffer_size() { return deque_buf_size(sizeof(T)); } + + typedef std::random_access_iterator_tag iterator_category; + typedef val_alloc_val value_type; + typedef val_alloc_cptr pointer; + typedef val_alloc_cref reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef ptr_alloc_ptr index_pointer; + typedef const_iterator self_t; + + friend class deque; + friend class deque_base; + + protected: + val_alloc_ptr m_cur; + val_alloc_ptr m_first; + val_alloc_ptr m_last; + index_pointer m_node; + + public: + const_iterator(val_alloc_ptr x, index_pointer y) + : m_cur(x), m_first(*y), + m_last(*y + s_buffer_size()), m_node(y) {} + + const_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {} + + const_iterator(const const_iterator& x) + : m_cur(x.m_cur), m_first(x.m_first), + m_last(x.m_last), m_node(x.m_node) {} + + reference operator*() const + { return *this->m_cur; } + + pointer operator->() const + { return this->m_cur; } + + difference_type operator-(const self_t& x) const + { + return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) + + (this->m_cur - this->m_first) + (x.m_last - x.m_cur); + } + + self_t& operator++() + { + ++this->m_cur; + if (this->m_cur == this->m_last) { + this->priv_set_node(this->m_node + 1); + this->m_cur = this->m_first; + } + return *this; + } + + self_t operator++(int) + { + self_t tmp = *this; + ++*this; + return tmp; + } + + self_t& operator--() + { + if (this->m_cur == this->m_first) { + this->priv_set_node(this->m_node - 1); + this->m_cur = this->m_last; + } + --this->m_cur; + return *this; + } + + self_t operator--(int) + { + self_t tmp = *this; + --*this; + return tmp; + } + + self_t& operator+=(difference_type n) + { + difference_type offset = n + (this->m_cur - this->m_first); + if (offset >= 0 && offset < difference_type(this->s_buffer_size())) + this->m_cur += n; + else { + difference_type node_offset = + offset > 0 ? offset / difference_type(this->s_buffer_size()) + : -difference_type((-offset - 1) / this->s_buffer_size()) - 1; + this->priv_set_node(this->m_node + node_offset); + this->m_cur = this->m_first + + (offset - node_offset * difference_type(this->s_buffer_size())); + } + return *this; + } + + self_t operator+(difference_type n) const + { self_t tmp = *this; return tmp += n; } + + self_t& operator-=(difference_type n) + { return *this += -n; } + + self_t operator-(difference_type n) const + { self_t tmp = *this; return tmp -= n; } + + reference operator[](difference_type n) const + { return *(*this + n); } + + bool operator==(const self_t& x) const + { return this->m_cur == x.m_cur; } + + bool operator!=(const self_t& x) const + { return !(*this == x); } + + bool operator<(const self_t& x) const + { + return (this->m_node == x.m_node) ? + (this->m_cur < x.m_cur) : (this->m_node < x.m_node); + } + + bool operator>(const self_t& x) const + { return x < *this; } + + bool operator<=(const self_t& x) const + { return !(x < *this); } + + bool operator>=(const self_t& x) const + { return !(*this < x); } + + void priv_set_node(index_pointer new_node) + { + this->m_node = new_node; + this->m_first = *new_node; + this->m_last = this->m_first + difference_type(this->s_buffer_size()); + } + + friend const_iterator operator+(std::ptrdiff_t n, const const_iterator& x) + { return x + n; } + }; + + //Deque iterator + class iterator : public const_iterator + { + public: + typedef std::random_access_iterator_tag iterator_category; + typedef val_alloc_val value_type; + typedef ptr_alloc_ptr pointer; + typedef val_alloc_ref reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef ptr_alloc_ptr index_pointer; + typedef const_iterator self_t; + + friend class deque; + friend class deque_base; + + private: + explicit iterator(const const_iterator& x) : const_iterator(x){} + + public: + //Constructors + iterator(val_alloc_ptr x, index_pointer y) : const_iterator(x, y){} + iterator() : const_iterator(){} + //iterator(const const_iterator &cit) : const_iterator(cit){} + iterator(const iterator& x) : const_iterator(x){} + + //Pointer like operators + reference operator*() const { return *this->m_cur; } + pointer operator->() const { return this->m_cur; } + + reference operator[](difference_type n) const { return *(*this + n); } + + //Increment / Decrement + iterator& operator++() + { this->const_iterator::operator++(); return *this; } + + iterator operator++(int) + { iterator tmp = *this; ++*this; return tmp; } + + iterator& operator--() + { this->const_iterator::operator--(); return *this; } + + iterator operator--(int) + { iterator tmp = *this; --*this; return tmp; } + + // Arithmetic + iterator& operator+=(difference_type off) + { this->const_iterator::operator+=(off); return *this; } + + iterator operator+(difference_type off) const + { return iterator(this->const_iterator::operator+(off)); } + + friend iterator operator+(difference_type off, const iterator& right) + { return iterator(off+static_cast(right)); } + + iterator& operator-=(difference_type off) + { this->const_iterator::operator-=(off); return *this; } + + iterator operator-(difference_type off) const + { return iterator(this->const_iterator::operator-(off)); } + + difference_type operator-(const const_iterator& right) const + { return static_cast(*this) - right; } + }; + + deque_base(const allocator_type& a, std::size_t num_elements) + : members_(a) + { this->priv_initialize_map(num_elements); } + + deque_base(const allocator_type& a) + : members_(a) + {} + + ~deque_base() + { + if (this->members_.m_map) { + this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1); + this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); + } + } + + protected: + void priv_initialize_map(std::size_t num_elements) + { + std::size_t num_nodes = num_elements / deque_buf_size(sizeof(T)) + 1; + + this->members_.m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2); + this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size); + + ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2; + ptr_alloc_ptr nfinish = nstart + num_nodes; + + BOOST_TRY { + this->priv_create_nodes(nstart, nfinish); + } + BOOST_CATCH(...){ + this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); + this->members_.m_map = 0; + this->members_.m_map_size = 0; + BOOST_RETHROW + } + BOOST_CATCH_END + + this->members_.m_start.priv_set_node(nstart); + this->members_.m_finish.priv_set_node(nfinish - 1); + this->members_.m_start.m_cur = this->members_.m_start.m_first; + this->members_.m_finish.m_cur = this->members_.m_finish.m_first + + num_elements % deque_buf_size(sizeof(T)); + } + + void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) + { + ptr_alloc_ptr cur; + BOOST_TRY { + for (cur = nstart; cur < nfinish; ++cur) + *cur = this->priv_allocate_node(); + } + BOOST_CATCH(...){ + this->priv_destroy_nodes(nstart, cur); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) + { + for (ptr_alloc_ptr n = nstart; n < nfinish; ++n) + this->priv_deallocate_node(*n); + } + + enum { InitialMapSize = 8 }; + + protected: + struct members_holder + : public ptr_alloc_t + , public allocator_type + { + members_holder(const allocator_type &a) + : map_allocator_type(a), allocator_type(a) + , m_map(0), m_map_size(0) + , m_start(), m_finish() + {} + + ptr_alloc_ptr m_map; + std::size_t m_map_size; + iterator m_start; + iterator m_finish; + } members_; + + ptr_alloc_t &ptr_alloc() + { return members_; } + + const ptr_alloc_t &ptr_alloc() const + { return members_; } + + allocator_type &alloc() + { return members_; } + + const allocator_type &alloc() const + { return members_; } +}; +/// @endcond + +//! Deque class +//! +template +class deque : protected deque_base +{ + /// @cond + typedef deque_base Base; + + public: // Basic types + typedef typename Alloc::value_type val_alloc_val; + typedef typename Alloc::pointer val_alloc_ptr; + typedef typename Alloc::const_pointer val_alloc_cptr; + typedef typename Alloc::reference val_alloc_ref; + typedef typename Alloc::const_reference val_alloc_cref; + typedef typename Alloc::template + rebind::other ptr_alloc_t; + typedef typename ptr_alloc_t::value_type ptr_alloc_val; + typedef typename ptr_alloc_t::pointer ptr_alloc_ptr; + typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr; + typedef typename ptr_alloc_t::reference ptr_alloc_ref; + typedef typename ptr_alloc_t::const_reference ptr_alloc_cref; + /// @endcond + + typedef T value_type; + typedef val_alloc_ptr pointer; + typedef val_alloc_cptr const_pointer; + typedef val_alloc_ref reference; + typedef val_alloc_cref const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef typename Base::allocator_type allocator_type; + + public: // Iterators + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + /// @cond + protected: // Internal typedefs + typedef ptr_alloc_ptr index_pointer; + static std::size_t s_buffer_size() + { return deque_buf_size(sizeof(T)); } + /// @endcond + + allocator_type get_allocator() const { return Base::alloc(); } + + public: // Basic accessors + iterator begin() + { return this->members_.m_start; } + + iterator end() + { return this->members_.m_finish; } + + const_iterator begin() const + { return this->members_.m_start; } + + const_iterator end() const + { return this->members_.m_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(this->members_.m_finish); } + + reverse_iterator rend() + { return reverse_iterator(this->members_.m_start); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(this->members_.m_finish); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(this->members_.m_start); } + + reference operator[](size_type n) + { return this->members_.m_start[difference_type(n)]; } + + const_reference operator[](size_type n) const + { return this->members_.m_start[difference_type(n)]; } + + void priv_range_check(size_type n) const + { if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); } + + reference at(size_type n) + { this->priv_range_check(n); return (*this)[n]; } + + const_reference at(size_type n) const + { this->priv_range_check(n); return (*this)[n]; } + + reference front() { return *this->members_.m_start; } + + reference back() + { + iterator tmp = this->members_.m_finish; + --tmp; + return *tmp; + } + + const_reference front() const + { return *this->members_.m_start; } + + const_reference back() const + { const_iterator tmp = this->members_.m_finish; --tmp; return *tmp; } + + size_type size() const + { return this->members_.m_finish - this->members_.m_start; } + + size_type max_size() const + { return this->alloc().max_size(); } + + bool empty() const + { return this->members_.m_finish == this->members_.m_start; } + + explicit deque(const allocator_type& a = allocator_type()) + : Base(a, 0) {} + + deque(const deque& x) + : Base(x.alloc(), x.size()) + { std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start); } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + deque(const detail::moved_object &mx) + : Base(mx.get()) + { this->swap(mx.get()); } + #else + deque(deque &&x) + : Base(x)) + { this->swap(x); } + #endif + + deque(size_type n, const value_type& value, + const allocator_type& a = allocator_type()) : Base(a, n) + { this->priv_fill_initialize(value); } + + explicit deque(size_type n) : Base(allocator_type(), n) + { this->resize(n); } + + // Check whether it's an integral type. If so, it's not an iterator. + template + deque(InpIt first, InpIt last, + const allocator_type& a = allocator_type()) : Base(a) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_initialize_dispatch(first, last, Result()); + } + + ~deque() + { priv_destroy_range(this->members_.m_start, this->members_.m_finish); } + + deque& operator= (const deque& x) + { + const size_type len = size(); + if (&x != this) { + if (len >= x.size()) + this->erase(std::copy(x.begin(), x.end(), this->members_.m_start), this->members_.m_finish); + else { + const_iterator mid = x.begin() + difference_type(len); + std::copy(x.begin(), mid, this->members_.m_start); + this->insert(this->members_.m_finish, mid, x.end()); + } + } + return *this; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + deque& operator= (const detail::moved_object &mx) + { this->clear(); this->swap(mx.get()); return *this; } + #else + deque& operator= (deque &&mx) + { this->clear(); this->swap(mx); return *this; } + #endif + + void swap(deque& x) + { + std::swap(this->members_.m_start, x.members_.m_start); + std::swap(this->members_.m_finish, x.members_.m_finish); + std::swap(this->members_.m_map, x.members_.m_map); + std::swap(this->members_.m_map_size, x.members_.m_map_size); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object &mx) + { this->swap(mx.get()); } + #else + void swap(deque &&mx) + { this->swap(mx); } + #endif + + void assign(size_type n, const T& val) + { this->priv_fill_assign(n, val); } + + template + void assign(InpIt first, InpIt last) { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_assign_dispatch(first, last, Result()); + } + + void push_back(const value_type& t) + { + if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t); + ++this->members_.m_finish.m_cur; + } + else + this->priv_push_back_aux(t); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_back(const detail::moved_object &mt) + { + if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt); + ++this->members_.m_finish.m_cur; + } + else + this->priv_push_back_aux(mt); + } + #else + void push_back(value_type &&mt) + { + if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt)); + ++this->members_.m_finish.m_cur; + } + else + this->priv_push_back_aux(move(mt)); + } + #endif + + void push_front(const value_type& t) + { + if (this->members_.m_start.m_cur != this->members_.m_start.m_first) { + new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(t); + --this->members_.m_start.m_cur; + } + else + this->priv_push_front_aux(t); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_front(const detail::moved_object &mt) + { + if (this->members_.m_start.m_cur != this->members_.m_start.m_first) { + new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(mt); + --this->members_.m_start.m_cur; + } + else + this->priv_push_front_aux(mt); + } + #else + void push_front(value_type &&mt) + { + if (this->members_.m_start.m_cur != this->members_.m_start.m_first) { + new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(move(mt)); + --this->members_.m_start.m_cur; + } + else + this->priv_push_front_aux(move(mt)); + } + #endif + + void pop_back() + { + if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) { + --this->members_.m_finish.m_cur; + detail::get_pointer(this->members_.m_finish.m_cur)->~value_type(); + } + else + this->priv_pop_back_aux(); + } + + void pop_front() + { + if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) { + detail::get_pointer(this->members_.m_start.m_cur)->~value_type(); + ++this->members_.m_start.m_cur; + } + else + this->priv_pop_front_aux(); + } + + iterator insert(iterator position, const value_type& x) + { + if (position.m_cur == this->members_.m_start.m_cur) { + this->push_front(x); + return this->members_.m_start; + } + else if (position.m_cur == this->members_.m_finish.m_cur) { + this->push_back(x); + iterator tmp = this->members_.m_finish; + --tmp; + return tmp; + } + else { + return this->priv_insert_aux(position, x); + } + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object &mx) + { + if (position.m_cur == this->members_.m_start.m_cur) { + this->push_front(mx); + return this->members_.m_start; + } + else if (position.m_cur == this->members_.m_finish.m_cur) { + this->push_back(mx); + iterator tmp = this->members_.m_finish; + --tmp; + return tmp; + } + else { + return this->priv_insert_aux(position, mx); + } + } + #else + iterator insert(iterator position, value_type &&mx) + { + if (position.m_cur == this->members_.m_start.m_cur) { + this->push_front(move(mx)); + return this->members_.m_start; + } + else if (position.m_cur == this->members_.m_finish.m_cur) { + this->push_back(move(mx)); + iterator tmp = this->members_.m_finish; + --tmp; + return tmp; + } + else { + return this->priv_insert_aux(position, move(mx)); + } + } + #endif + + void insert(iterator pos, size_type n, const value_type& x) + { this->priv_fill_insert(pos, n, x); } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator pos, InpIt first, InpIt last) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_insert_dispatch(pos, first, last, Result()); + } + + void resize(size_type new_size, const value_type& x) + { + const size_type len = size(); + if (new_size < len) + this->erase(this->members_.m_start + new_size, this->members_.m_finish); + else + this->insert(this->members_.m_finish, new_size - len, x); + } + + void resize(size_type new_size) + { + const size_type len = size(); + if (new_size < len) + this->erase(this->members_.m_start + new_size, this->members_.m_finish); + else{ + size_type n = new_size - this->size(); + this->priv_reserve_elements_at_back(new_size); + + while(n--){ + //T default_constructed = move(T()); + T default_constructed; +/* if(boost::is_scalar::value){ + //Value initialization + new(&default_constructed)T(); + }*/ + this->push_back(move(default_constructed)); + } + } + } + + iterator erase(iterator pos) + { + iterator next = pos; + ++next; + difference_type index = pos - this->members_.m_start; + if (size_type(index) < (this->size() >> 1)) { + std::copy_backward( detail::make_move_iterator(this->members_.m_start) + , detail::make_move_iterator(pos) + , next); + pop_front(); + } + else { + std::copy( detail::make_move_iterator(next) + , detail::make_move_iterator(this->members_.m_finish) + , pos); + pop_back(); + } + return this->members_.m_start + index; + } + + iterator erase(iterator first, iterator last) + { + if (first == this->members_.m_start && last == this->members_.m_finish) { + this->clear(); + return this->members_.m_finish; + } + else { + difference_type n = last - first; + difference_type elems_before = first - this->members_.m_start; + if (elems_before < static_cast(this->size() - n) - elems_before) { + std::copy_backward( detail::make_move_iterator(this->members_.m_start) + , detail::make_move_iterator(first) + , last); + iterator new_start = this->members_.m_start + n; + if(!Base::trivial_dctr_after_move) + this->priv_destroy_range(this->members_.m_start, new_start); + this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node); + this->members_.m_start = new_start; + } + else { + std::copy( detail::make_move_iterator(last) + , detail::make_move_iterator(this->members_.m_finish) + , first); + iterator new_finish = this->members_.m_finish - n; + if(!Base::trivial_dctr_after_move) + this->priv_destroy_range(new_finish, this->members_.m_finish); + this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1); + this->members_.m_finish = new_finish; + } + return this->members_.m_start + elems_before; + } + } + + void clear() + { + for (index_pointer node = this->members_.m_start.m_node + 1; + node < this->members_.m_finish.m_node; + ++node) { + this->priv_destroy_range(*node, *node + this->s_buffer_size()); + this->priv_deallocate_node(*node); + } + + if (this->members_.m_start.m_node != this->members_.m_finish.m_node) { + this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last); + this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur); + this->priv_deallocate_node(this->members_.m_finish.m_first); + } + else + this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur); + + this->members_.m_finish = this->members_.m_start; + } + + /// @cond + private: + + template + void insert(iterator pos, InpIt first, InpIt last, std::input_iterator_tag) + { std::copy(first, last, std::inserter(*this, pos)); } + + template + void insert(iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag) + { + + size_type n = 0; + n = std::distance(first, last); + + if (pos.m_cur == this->members_.m_start.m_cur) { + iterator new_start = this->priv_reserve_elements_at_front(n); + BOOST_TRY{ + std::uninitialized_copy(first, last, new_start); + this->members_.m_start = new_start; + } + BOOST_CATCH(...){ + this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node); + BOOST_RETHROW + } + BOOST_CATCH_END + } + else if (pos.m_cur == this->members_.m_finish.m_cur) { + iterator new_finish = this->priv_reserve_elements_at_back(n); + BOOST_TRY{ + std::uninitialized_copy(first, last, this->members_.m_finish); + this->members_.m_finish = new_finish; + } + BOOST_CATCH(...){ + this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + else + this->priv_insert_aux(pos, first, last, n); + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + void priv_fill_assign(size_type n, const T& val) { + if (n > size()) { + std::fill(begin(), end(), val); + this->insert(end(), n - size(), val); + } + else { + this->erase(begin() + n, end()); + std::fill(begin(), end(), val); + } + } + + template + void priv_initialize_dispatch(Integer n, Integer x, detail::true_) + { + this->priv_initialize_map(n); + this->priv_fill_initialize(x); + } + + template + void priv_initialize_dispatch(InpIt first, InpIt last, detail::false_) + { + typedef typename std::iterator_traits::iterator_category ItCat; + this->priv_range_initialize(first, last, ItCat()); + } + + void priv_destroy_range(iterator p, iterator p2) + { + for(;p != p2; ++p) + detail::get_pointer(&*p)->~value_type(); + } + + void priv_destroy_range(pointer p, pointer p2) + { + for(;p != p2; ++p) + detail::get_pointer(&*p)->~value_type(); + } + + template + void priv_assign_dispatch(Integer n, Integer val, detail::true_) + { this->priv_fill_assign((size_type) n, (T) val); } + + template + void priv_assign_dispatch(InpIt first, InpIt last, detail::false_) + { + typedef typename std::iterator_traits::iterator_category ItCat; + this->priv_assign_aux(first, last, ItCat()); + } + + template + void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag) + { + iterator cur = begin(); + for ( ; first != last && cur != end(); ++cur, ++first) + *cur = *first; + if (first == last) + this->erase(cur, end()); + else + this->insert(end(), first, last); + } + + template + void priv_assign_aux(FwdIt first, FwdIt last, + std::forward_iterator_tag) { + size_type len = 0; + std::distance(first, last, len); + if (len > size()) { + FwdIt mid = first; + std::advance(mid, size()); + std::copy(first, mid, begin()); + this->insert(end(), mid, last); + } + else + this->erase(std::copy(first, last, begin()), end()); + } + + template + void priv_insert_dispatch(iterator pos, Integer n, Integer x, + detail::true_) + { + this->priv_fill_insert(pos, (size_type) n, (value_type) x); + } + + template + void priv_insert_dispatch(iterator pos, + InpIt first, InpIt last, + detail::false_) + { + typedef typename std::iterator_traits::iterator_category ItCat; + this->insert(pos, first, last, ItCat()); + } + + iterator priv_insert_aux(iterator pos, const value_type& x) + { + size_type n = pos - begin(); + this->priv_insert_aux(pos, size_type(1), x); + return iterator(this->begin() + n); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator priv_insert_aux(iterator pos, const detail::moved_object &mx) + { + typedef repeat_iterator r_iterator; + typedef detail::move_iterator move_it; + //Just call more general insert(pos, size, value) and return iterator + size_type n = pos - begin(); + this->insert(pos + ,move_it(r_iterator(mx.get(), 1)) + ,move_it(r_iterator())); + return iterator(this->begin() + n); + } + #else + iterator priv_insert_aux(iterator pos, value_type &&mx) + { + typedef repeat_iterator r_iterator; + typedef detail::move_iterator move_it; + //Just call more general insert(pos, size, value) and return iterator + size_type n = pos - begin(); + this->insert(pos + ,move_it(r_iterator(mx, 1)) + ,move_it(r_iterator())); + return iterator(this->begin() + n); + } + #endif + + void priv_insert_aux(iterator pos, size_type n, const value_type& x) + { + typedef constant_iterator c_it; + this->insert(pos, c_it(x, n), c_it()); + } + + template + void priv_insert_aux(iterator pos, FwdIt first, FwdIt last, size_type n) + { + const difference_type elemsbefore = pos - this->members_.m_start; + size_type length = size(); + if (elemsbefore < static_cast(length / 2)) { + iterator new_start = this->priv_reserve_elements_at_front(n); + iterator old_start = this->members_.m_start; + pos = this->members_.m_start + elemsbefore; + BOOST_TRY { + if (elemsbefore >= difference_type(n)) { + iterator start_n = this->members_.m_start + difference_type(n); + std::uninitialized_copy(detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(start_n), new_start); + this->members_.m_start = new_start; + std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start); + std::copy(first, last, pos - difference_type(n)); + } + else { + FwdIt mid = first; + std::advance(mid, difference_type(n) - elemsbefore); + this->priv_uninitialized_copy_copy + (detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(pos), first, mid, new_start); + this->members_.m_start = new_start; + std::copy(mid, last, old_start); + } + } + BOOST_CATCH(...){ + this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node); + BOOST_RETHROW + } + BOOST_CATCH_END + } + else { + iterator new_finish = this->priv_reserve_elements_at_back(n); + iterator old_finish = this->members_.m_finish; + const difference_type elemsafter = + difference_type(length) - elemsbefore; + pos = this->members_.m_finish - elemsafter; + BOOST_TRY { + if (elemsafter > difference_type(n)) { + iterator finish_n = this->members_.m_finish - difference_type(n); + std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish); + this->members_.m_finish = new_finish; + std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish); + std::copy(first, last, pos); + } + else { + FwdIt mid = first; + std::advance(mid, elemsafter); + this->priv_uninitialized_copy_copy(mid, last, detail::make_move_iterator(pos), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish); + this->members_.m_finish = new_finish; + std::copy(first, mid, pos); + } + } + BOOST_CATCH(...){ + this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + } + + void priv_fill_insert(iterator pos, size_type n, const value_type& x) + { + typedef constant_iterator c_it; + this->insert(pos, c_it(x, n), c_it()); + } + + // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized, + // but none of the deque's elements have yet been constructed. + void priv_fill_initialize(const value_type& value) + { + index_pointer cur; + BOOST_TRY { + for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){ + std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value); + } + std::uninitialized_fill(this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value); + } + BOOST_CATCH(...){ + this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template + void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag) + { + this->priv_initialize_map(0); + BOOST_TRY { + for ( ; first != last; ++first) + this->push_back(*first); + } + BOOST_CATCH(...){ + this->clear(); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template + void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag) + { + size_type n = 0; + n = std::distance(first, last); + this->priv_initialize_map(n); + + index_pointer cur_node; + BOOST_TRY { + for (cur_node = this->members_.m_start.m_node; + cur_node < this->members_.m_finish.m_node; + ++cur_node) { + FwdIt mid = first; + std::advance(mid, this->s_buffer_size()); + std::uninitialized_copy(first, mid, *cur_node); + first = mid; + } + std::uninitialized_copy(first, last, this->members_.m_finish.m_first); + } + BOOST_CATCH(...){ + this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1. + void priv_push_back_aux(const value_type& t = value_type()) + { + this->priv_reserve_map_at_back(); + *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node(); + BOOST_TRY { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t); + this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1); + this->members_.m_finish.m_cur = this->members_.m_finish.m_first; + } + BOOST_CATCH(...){ + this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void priv_push_back_aux(const detail::moved_object &mt) + { + this->priv_reserve_map_at_back(); + *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node(); + BOOST_TRY { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt); + this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1); + this->members_.m_finish.m_cur = this->members_.m_finish.m_first; + } + BOOST_CATCH(...){ + this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #else + void priv_push_back_aux(value_type &&mt) + { + this->priv_reserve_map_at_back(); + *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node(); + BOOST_TRY { + new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt)); + this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1); + this->members_.m_finish.m_cur = this->members_.m_finish.m_first; + } + BOOST_CATCH(...){ + this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #endif + + // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_first. + void priv_push_front_aux(const value_type& t) + { + this->priv_reserve_map_at_front(); + *(this->members_.m_start.m_node - 1) = this->priv_allocate_node(); + BOOST_TRY { + this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1); + this->members_.m_start.m_cur = this->members_.m_start.m_last - 1; + new(detail::get_pointer(this->members_.m_start.m_cur))value_type(t); + } + BOOST_CATCH(...){ + ++this->members_.m_start; + this->priv_deallocate_node(*(this->members_.m_start.m_node - 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void priv_push_front_aux(const detail::moved_object &mt) + { + this->priv_reserve_map_at_front(); + *(this->members_.m_start.m_node - 1) = this->priv_allocate_node(); + BOOST_TRY { + this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1); + this->members_.m_start.m_cur = this->members_.m_start.m_last - 1; + new(detail::get_pointer(this->members_.m_start.m_cur))value_type(mt); + } + BOOST_CATCH(...){ + ++this->members_.m_start; + this->priv_deallocate_node(*(this->members_.m_start.m_node - 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #else + void priv_push_front_aux(value_type &&mt) + { + this->priv_reserve_map_at_front(); + *(this->members_.m_start.m_node - 1) = this->priv_allocate_node(); + BOOST_TRY { + this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1); + this->members_.m_start.m_cur = this->members_.m_start.m_last - 1; + new(detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt)); + } + BOOST_CATCH(...){ + ++this->members_.m_start; + this->priv_deallocate_node(*(this->members_.m_start.m_node - 1)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #endif + + // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first. + void priv_pop_back_aux() + { + this->priv_deallocate_node(this->members_.m_finish.m_first); + this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1); + this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1; + detail::get_pointer(this->members_.m_finish.m_cur)->~value_type(); + } + + // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that + // if the deque has at least one element (a precondition for this member + // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque + // must have at least two nodes. + void priv_pop_front_aux() + { + detail::get_pointer(this->members_.m_start.m_cur)->~value_type(); + this->priv_deallocate_node(this->members_.m_start.m_first); + this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1); + this->members_.m_start.m_cur = this->members_.m_start.m_first; + } + + iterator priv_reserve_elements_at_front(size_type n) + { + size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first; + if (n > vacancies) + this->priv_new_elements_at_front(n - vacancies); + return this->members_.m_start - difference_type(n); + } + + iterator priv_reserve_elements_at_back(size_type n) + { + size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1; + if (n > vacancies) + this->priv_new_elements_at_back(n - vacancies); + return this->members_.m_finish + difference_type(n); + } + + void priv_new_elements_at_front(size_type new_elems) + { + size_type new_nodes = (new_elems + this->s_buffer_size() - 1) / + this->s_buffer_size(); + this->priv_reserve_map_at_front(new_nodes); + size_type i = 1; + BOOST_TRY { + for (; i <= new_nodes; ++i) + *(this->members_.m_start.m_node - i) = this->priv_allocate_node(); + } + BOOST_CATCH(...) { + for (size_type j = 1; j < i; ++j) + this->priv_deallocate_node(*(this->members_.m_start.m_node - j)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + void priv_new_elements_at_back(size_type new_elems) + { + size_type new_nodes = (new_elems + this->s_buffer_size() - 1) + / this->s_buffer_size(); + this->priv_reserve_map_at_back(new_nodes); + size_type i; + BOOST_TRY { + for (i = 1; i <= new_nodes; ++i) + *(this->members_.m_finish.m_node + i) = this->priv_allocate_node(); + } + BOOST_CATCH(...) { + for (size_type j = 1; j < i; ++j) + this->priv_deallocate_node(*(this->members_.m_finish.m_node + j)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + // Makes sure the this->members_.m_map has space for new nodes. Does not actually + // add the nodes. Can invalidate this->members_.m_map pointers. (And consequently, + // deque iterators.) + void priv_reserve_map_at_back (size_type nodes_to_add = 1) + { + if (nodes_to_add + 1 > this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map)) + this->priv_reallocate_map(nodes_to_add, false); + } + + void priv_reserve_map_at_front (size_type nodes_to_add = 1) + { + if (nodes_to_add > size_type(this->members_.m_start.m_node - this->members_.m_map)) + this->priv_reallocate_map(nodes_to_add, true); + } + + void priv_reallocate_map(size_type nodes_to_add, bool add_at_front) + { + size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1; + size_type new_num_nodes = old_num_nodes + nodes_to_add; + + index_pointer new_nstart; + if (this->members_.m_map_size > 2 * new_num_nodes) { + new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2 + + (add_at_front ? nodes_to_add : 0); + if (new_nstart < this->members_.m_start.m_node) + std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); + else + std::copy_backward(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, + new_nstart + old_num_nodes); + } + else { + size_type new_map_size = + this->members_.m_map_size + max_value(this->members_.m_map_size, nodes_to_add) + 2; + + index_pointer new_map = this->priv_allocate_map(new_map_size); + new_nstart = new_map + (new_map_size - new_num_nodes) / 2 + + (add_at_front ? nodes_to_add : 0); + std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); + this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); + + this->members_.m_map = new_map; + this->members_.m_map_size = new_map_size; + } + + this->members_.m_start.priv_set_node(new_nstart); + this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1); + } + + // this->priv_uninitialized_copy_fill + // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and + // fills [first2 + (last1 - first1), last2) with x. + void priv_uninitialized_copy_fill(iterator first1, iterator last1, + iterator first2, iterator last2, + const T& x) + { + iterator mid2 = std::uninitialized_copy(first1, last1, first2); + BOOST_TRY { + std::uninitialized_fill(mid2, last2, x); + } + BOOST_CATCH(...){ + for(;first2 != mid2; ++first2){ + detail::get_pointer(&*first2)->~value_type(); + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + + // this->priv_uninitialized_fill_copy + // Fills [result, mid) with x, and copies [first, last) into + // [mid, mid + (last - first)). + iterator priv_uninitialized_fill_copy(iterator result, iterator mid, + const T& x, + iterator first, iterator last) + { + std::uninitialized_fill(result, mid, x); + BOOST_TRY { + return std::uninitialized_copy(first, last, mid); + } + BOOST_CATCH(...){ + for(;result != mid; ++result){ + detail::get_pointer(&*result)->~value_type(); + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + + // this->priv_uninitialized_copy_copy + // Copies [first1, last1) into [result, result + (last1 - first1)), and + // copies [first2, last2) into + // [result, result + (last1 - first1) + (last2 - first2)). + template + FwdIt priv_uninitialized_copy_copy(InpIt1 first1, InpIt1 last1, + InpIt2 first2, InpIt2 last2, + FwdIt result) + { + FwdIt mid = std::uninitialized_copy(first1, last1, result); + BOOST_TRY { + return std::uninitialized_copy(first2, last2, mid); + } + BOOST_CATCH(...){ + for(;result != mid; ++result){ + detail::get_pointer(&*result)->~value_type(); + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + /// @endcond +}; + +// Nonmember functions. +template +inline bool operator==(const deque& x, + const deque& y) +{ + return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +} + +template +inline bool operator<(const deque& x, + const deque& y) +{ + return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +inline bool operator!=(const deque& x, + const deque& y) + { return !(x == y); } + +template +inline bool operator>(const deque& x, + const deque& y) + { return y < x; } + +template +inline bool operator<=(const deque& x, + const deque& y) + { return !(y < x); } + +template +inline bool operator>=(const deque& x, + const deque& y) + { return !(x < y); } + +template +inline void swap(deque& x, deque& y) + { x.swap(y); } + +/// @cond + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = has_trivial_destructor::value }; +}; +/// @endcond + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif // #ifndef BOOST_INTERPROCESS_DEQUE_HPP + diff --git a/thirdparty/boost/interprocess/containers/detail/flat_tree.hpp b/thirdparty/boost/interprocess/containers/detail/flat_tree.hpp new file mode 100644 index 0000000..1bbe71f --- /dev/null +++ b/thirdparty/boost/interprocess/containers/detail/flat_tree.hpp @@ -0,0 +1,743 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (c) 2001 by Andrei Alexandrescu +// This code accompanies the book: +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Patterns Applied". Copyright (c) 2001. Addison-Wesley. +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this +// permission notice appear in supporting documentation. +// The author or Addison-Welsey Longman make no representations about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. +/////////////////////////////////////////////////////////////////////////////// +// +// Parts of this file come from AssocVector.h file from Loki library +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_FLAT_TREE_HPP +#define BOOST_INTERPROCESS_FLAT_TREE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace interprocess { + +namespace detail { + +template +class flat_tree +{ + typedef boost::interprocess::vector vector_t; + typedef Alloc allocator_t; + + public: + class value_compare + : private Compare + { + typedef Value first_argument_type; + typedef Value second_argument_type; + typedef bool return_type; + public: + value_compare(const Compare &pred) + : Compare(pred) + {} + + bool operator()(const Value& lhs, const Value& rhs) const + { + KeyOfValue key_extract; + return Compare::operator()(key_extract(lhs), key_extract(rhs)); + } + + const Compare &get_comp() const + { return *this; } + + Compare &get_comp() + { return *this; } + }; + + private: + struct Data + //Inherit from value_compare to do EBO + : public value_compare + { + public: + Data(const Compare &comp, + const vector_t &vect) + : value_compare(comp), m_vect(vect){} + + Data(const value_compare &comp, + const vector_t &vect) + : value_compare(comp), m_vect(vect){} + + Data(const Compare &comp, + const allocator_t &alloc) + : value_compare(comp), m_vect(alloc){} + public: + vector_t m_vect; + }; + + Data m_data; + + public: + + typedef typename vector_t::value_type value_type; + typedef typename vector_t::pointer pointer; + typedef typename vector_t::const_pointer const_pointer; + typedef typename vector_t::reference reference; + typedef typename vector_t::const_reference const_reference; + typedef Key key_type; + typedef Compare key_compare; + typedef typename vector_t::allocator_type allocator_type; + typedef allocator_type stored_allocator_type; + typedef typename allocator_type::size_type size_type; + typedef typename allocator_type::difference_type difference_type; + typedef typename vector_t::iterator iterator; + typedef typename vector_t::const_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + + // allocation/deallocation + flat_tree(const Compare& comp = Compare(), + const allocator_type& a = allocator_type()) + : m_data(comp, a) + { } + + flat_tree(const flat_tree& x) + : m_data(x.m_data, x.m_data.m_vect) + { } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_tree(const detail::moved_object &x) + : m_data(move(x.get().m_data)) + { } + #else + flat_tree(flat_tree &&x) + : m_data(move(x.m_data)) + { } + #endif + + ~flat_tree() + { } + + flat_tree& operator=(const flat_tree& x) + { m_data = x.m_data; return *this; } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_tree& operator=(const detail::moved_object& mx) + { m_data = move(mx.get().m_data); return *this; } + #else + flat_tree& operator=(flat_tree &&mx) + { m_data = move(mx.m_data); return *this; } + #endif + + public: + // accessors: + Compare key_comp() const + { return this->m_data.get_comp(); } + + allocator_type get_allocator() const + { return this->m_data.m_vect.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return this->m_data.m_vect.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return this->m_data.m_vect.get_stored_allocator(); } + + iterator begin() + { return this->m_data.m_vect.begin(); } + + const_iterator begin() const + { return this->m_data.m_vect.begin(); } + + iterator end() + { return this->m_data.m_vect.end(); } + + const_iterator end() const + { return this->m_data.m_vect.end(); } + + reverse_iterator rbegin() + { return reverse_iterator(this->end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(this->end()); } + + reverse_iterator rend() + { return reverse_iterator(this->begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(this->begin()); } + + bool empty() const + { return this->m_data.m_vect.empty(); } + + size_type size() const + { return this->m_data.m_vect.size(); } + + size_type max_size() const + { return this->m_data.m_vect.max_size(); } + + void swap(flat_tree& other) + { + value_compare& mycomp = this->m_data; + value_compare& othercomp = other.m_data; + detail::do_swap(mycomp, othercomp); + vector_t & myvect = this->m_data.m_vect; + vector_t & othervect = other.m_data.m_vect; + myvect.swap(othervect); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object& other) + { this->swap(other.get()); } + #else + void swap(flat_tree &&other) + { this->swap(other); } + #endif + + public: + // insert/erase + std::pair insert_unique(const value_type& val) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(val, data); + if(ret.second){ + ret.first = priv_insert_commit(data, val); + } + return ret; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert_unique(const detail::moved_object& mval) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(mval.get(), data); + if(ret.second){ + ret.first = priv_insert_commit(data, mval); + } + return ret; + } + #else + std::pair insert_unique(value_type && mval) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(mval, data); + if(ret.second){ + ret.first = priv_insert_commit(data, move(mval)); + } + return ret; + } + #endif + + + iterator insert_equal(const value_type& val) + { + iterator i = this->upper_bound(KeyOfValue()(val)); + i = this->m_data.m_vect.insert(i, val); + return i; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert_equal(const detail::moved_object& mval) + { + iterator i = this->upper_bound(KeyOfValue()(mval.get())); + i = this->m_data.m_vect.insert(i, mval); + return i; + } + #else + iterator insert_equal(value_type && mval) + { + iterator i = this->upper_bound(KeyOfValue()(mval)); + i = this->m_data.m_vect.insert(i, move(mval)); + return i; + } + #endif + + iterator insert_unique(const_iterator pos, const value_type& val) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(pos, val, data); + if(ret.second){ + ret.first = priv_insert_commit(data, val); + } + return ret.first; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert_unique(const_iterator pos, const detail::moved_object& mval) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(pos, mval.get(), data); + if(ret.second){ + ret.first = priv_insert_commit(data, mval); + } + return ret.first; + } + #else + iterator insert_unique(const_iterator pos, value_type&&mval) + { + insert_commit_data data; + std::pair ret = priv_insert_unique_prepare(pos, mval, data); + if(ret.second){ + ret.first = priv_insert_commit(data, move(mval)); + } + return ret.first; + } + #endif + + iterator insert_equal(const_iterator pos, const value_type& val) + { + insert_commit_data data; + priv_insert_equal_prepare(pos, val, data); + return priv_insert_commit(data, val); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert_equal(const_iterator pos, const detail::moved_object& mval) + { + insert_commit_data data; + priv_insert_equal_prepare(pos, mval.get(), data); + return priv_insert_commit(data, mval); + } + #else + iterator insert_equal(const_iterator pos, value_type && mval) + { + insert_commit_data data; + priv_insert_equal_prepare(pos, mval, data); + return priv_insert_commit(data, move(mval)); + } + #endif + + template + void insert_unique(InIt first, InIt last) + { + for ( ; first != last; ++first) + this->insert_unique(*first); + } + + template + void insert_equal(InIt first, InIt last) + { + typedef typename + std::iterator_traits::iterator_category ItCat; + priv_insert_equal(first, last, ItCat()); + } + + iterator erase(const_iterator position) + { return this->m_data.m_vect.erase(position); } + + size_type erase(const key_type& k) + { + std::pair itp = this->equal_range(k); + size_type ret = static_cast(itp.second-itp.first); + if (ret){ + this->m_data.m_vect.erase(itp.first, itp.second); + } + return ret; + } + + iterator erase(const_iterator first, const_iterator last) + { return this->m_data.m_vect.erase(first, last); } + + void clear() + { this->m_data.m_vect.clear(); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { this->m_data.m_vect.shrink_to_fit(); } + + // set operations: + iterator find(const key_type& k) + { + const Compare &key_comp = this->m_data.get_comp(); + iterator i = this->lower_bound(k); + + if (i != this->end() && key_comp(k, KeyOfValue()(*i))){ + i = this->end(); + } + return i; + } + + const_iterator find(const key_type& k) const + { + const Compare &key_comp = this->m_data.get_comp(); + const_iterator i = this->lower_bound(k); + + if (i != this->end() && key_comp(k, KeyOfValue()(*i))){ + i = this->end(); + } + return i; + } + + size_type count(const key_type& k) const + { + std::pair p = this->equal_range(k); + size_type n = p.second - p.first; + return n; + } + + iterator lower_bound(const key_type& k) + { return this->priv_lower_bound(this->begin(), this->end(), k); } + + const_iterator lower_bound(const key_type& k) const + { return this->priv_lower_bound(this->begin(), this->end(), k); } + + iterator upper_bound(const key_type& k) + { return this->priv_upper_bound(this->begin(), this->end(), k); } + + const_iterator upper_bound(const key_type& k) const + { return this->priv_upper_bound(this->begin(), this->end(), k); } + + std::pair equal_range(const key_type& k) + { return this->priv_equal_range(this->begin(), this->end(), k); } + + std::pair equal_range(const key_type& k) const + { return this->priv_equal_range(this->begin(), this->end(), k); } + + size_type capacity() const + { return this->m_data.m_vect.capacity(); } + + void reserve(size_type count) + { this->m_data.m_vect.reserve(count); } + + private: + struct insert_commit_data + { + iterator position; + }; + + // insert/erase + void priv_insert_equal_prepare + (const_iterator p, const value_type& val, insert_commit_data &data) + { + iterator &pos = (iterator &)(const_iterator &)p; + // N1780 + // To insert val at pos: + // if pos == end || val <= *pos + // if pos == begin || val >= *(pos-1) + // insert val before pos + // else + // insert val before upper_bound(val) + // else if pos+1 == end || val <= *(pos+1) + // insert val after pos + // else + // insert val before lower_bound(val) + const value_compare &value_comp = this->m_data; + + if(pos == this->end() || !value_comp(*pos, val)){ + if (pos == this->begin() || !value_comp(val, pos[-1])){ + data.position = pos; + } + else{ + data.position = + this->priv_upper_bound(this->begin(), pos, KeyOfValue()(val)); + } + } + //Works, but increases code complexity + //else if (++pos == this->end() || !value_comp(*pos, val)){ + // return this->m_data.m_vect.insert(pos, val); + //} + else{ + data.position = + this->priv_lower_bound(pos, this->end(), KeyOfValue()(val)); + } + } + + std::pair priv_insert_unique_prepare + (iterator beg, iterator end, const value_type& val, insert_commit_data &commit_data) + { + const value_compare &value_comp = this->m_data; + commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val)); + return std::pair + ( commit_data.position + , commit_data.position == end || value_comp(val, *commit_data.position)); + } + + std::pair priv_insert_unique_prepare + (const value_type& val, insert_commit_data &commit_data) + { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); } + + std::pair priv_insert_unique_prepare + (const_iterator p, const value_type& val, insert_commit_data &commit_data) + { + iterator &pos = (iterator &)(const_iterator &)p; + //N1780. Props to Howard Hinnant! + //To insert val at pos: + //if pos == end || val <= *pos + // if pos == begin || val >= *(pos-1) + // insert val before pos + // else + // insert val before upper_bound(val) + //else if pos+1 == end || val <= *(pos+1) + // insert val after pos + //else + // insert val before lower_bound(val) + const value_compare &value_comp = this->m_data; + + if(pos == this->end() || value_comp(val, *pos)){ + if(pos != this->begin() && !value_comp(val, pos[-1])){ + if(value_comp(pos[-1], val)){ + commit_data.position = iterator(pos); + return std::pair(pos, true); + } + else{ + return std::pair(pos, false); + } + } + return this->priv_insert_unique_prepare(this->begin(), pos, val, commit_data); + } + + // Works, but increases code complexity + //Next check + //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){ + // if(value_comp(val, pos[1])){ + // commit_data.position = pos+1; + // return std::pair(pos+1, true); + // } + // else{ + // return std::pair(pos+1, false); + // } + //} + else{ + //[... pos ... val ... ] + //The hint is before the insertion position, so insert it + //in the remaining range + return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data); + } + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + iterator priv_insert_commit + (insert_commit_data &commit_data, const Convertible &convertible) + { return this->m_data.m_vect.insert(commit_data.position, convertible); } + #else + template + iterator priv_insert_commit + (insert_commit_data &commit_data, Convertible &&convertible) + { return this->m_data.m_vect.insert(commit_data.position, forward(convertible)); } + #endif + + template + RanIt priv_lower_bound(RanIt first, RanIt last, + const key_type & key) const + { + const Compare &key_comp = this->m_data.get_comp(); + KeyOfValue key_extract; + difference_type len = last - first, half; + RanIt middle; + + while (len > 0) { + half = len >> 1; + middle = first; + middle += half; + + if (key_comp(key_extract(*middle), key)) { + ++middle; + first = middle; + len = len - half - 1; + } + else + len = half; + } + return first; + } + + template + RanIt priv_upper_bound(RanIt first, RanIt last, + const key_type & key) const + { + const Compare &key_comp = this->m_data.get_comp(); + KeyOfValue key_extract; + difference_type len = last - first, half; + RanIt middle; + + while (len > 0) { + half = len >> 1; + middle = first; + middle += half; + + if (key_comp(key, key_extract(*middle))) { + len = half; + } + else{ + first = ++middle; + len = len - half - 1; + } + } + return first; + } + + template + std::pair + priv_equal_range(RanIt first, RanIt last, const key_type& key) const + { + const Compare &key_comp = this->m_data.get_comp(); + KeyOfValue key_extract; + difference_type len = last - first, half; + RanIt middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + middle += half; + + if (key_comp(key_extract(*middle), key)){ + first = middle; + ++first; + len = len - half - 1; + } + else if (key_comp(key, key_extract(*middle))){ + len = half; + } + else { + left = this->priv_lower_bound(first, middle, key); + first += len; + right = this->priv_upper_bound(++middle, first, key); + return std::pair(left, right); + } + } + return std::pair(first, first); + } + + template + void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag) + { + size_type len = static_cast(std::distance(first, last)); + this->reserve(this->size()+len); + this->priv_insert_equal(first, last, std::input_iterator_tag()); + } + + template + void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag) + { + for ( ; first != last; ++first) + this->insert_equal(*first); + } + +/* + template + void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag) + { + size_type len = static_cast(std::distance(first, last)); + this->reserve(this->size()+len); + priv_insert_unique(first, last, std::input_iterator_tag()); + } + + template + void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag) + { + for ( ; first != last; ++first) + this->insert_unique(*first); + } +*/ +}; + +template +inline bool +operator==(const flat_tree& x, + const flat_tree& y) +{ + return x.size() == y.size() && + std::equal(x.begin(), x.end(), y.begin()); +} + +template +inline bool +operator<(const flat_tree& x, + const flat_tree& y) +{ + return std::lexicographical_compare(x.begin(), x.end(), + y.begin(), y.end()); +} + +template +inline bool +operator!=(const flat_tree& x, + const flat_tree& y) + { return !(x == y); } + +template +inline bool +operator>(const flat_tree& x, + const flat_tree& y) + { return y < x; } + +template +inline bool +operator<=(const flat_tree& x, + const flat_tree& y) + { return !(y < x); } + +template +inline bool +operator>=(const flat_tree& x, + const flat_tree& y) + { return !(x < y); } + + +template +inline void +swap(flat_tree& x, + flat_tree& y) + { x.swap(y); } + +} //namespace detail { + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif // BOOST_INTERPROCESS_FLAT_TREE_HPP diff --git a/thirdparty/boost/interprocess/containers/detail/node_alloc_holder.hpp b/thirdparty/boost/interprocess/containers/detail/node_alloc_holder.hpp new file mode 100644 index 0000000..e9a5395 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/detail/node_alloc_holder.hpp @@ -0,0 +1,401 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_ +#define BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_ + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace boost { +namespace interprocess { +namespace detail { + +template +struct node_compare + : private ValueCompare +{ + typedef typename ValueCompare::key_type key_type; + typedef typename ValueCompare::value_type value_type; + typedef typename ValueCompare::key_of_value key_of_value; + + node_compare(const ValueCompare &pred) + : ValueCompare(pred) + {} + + ValueCompare &value_comp() + { return static_cast(*this); } + + ValueCompare &value_comp() const + { return static_cast(*this); } + + bool operator()(const Node &a, const Node &b) const + { return ValueCompare::operator()(a.m_data, b.m_data); } +}; + +template +struct node_alloc_holder +{ + typedef node_alloc_holder self_t; + typedef typename A::value_type value_type; + typedef typename ICont::value_type Node; + typedef typename A::template rebind::other NodeAlloc; + typedef A ValAlloc; + typedef typename NodeAlloc::pointer NodePtr; + typedef detail::scoped_deallocator Deallocator; + typedef typename NodeAlloc::size_type size_type; + typedef typename NodeAlloc::difference_type difference_type; + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + typedef detail::integral_constant::value> alloc_version; + typedef typename ICont::iterator icont_iterator; + typedef typename ICont::const_iterator icont_citerator; + typedef allocator_destroyer Destroyer; + + node_alloc_holder(const ValAlloc &a) + : members_(a) + {} + + node_alloc_holder(const node_alloc_holder &other) + : members_(other.node_alloc()) + {} + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + node_alloc_holder(const detail::moved_object &other) + : members_(move(other.get().node_alloc())) + { this->swap(other.get()); } + #else + node_alloc_holder(node_alloc_holder &&other) + : members_(move(other.node_alloc())) + { this->swap(other); } + #endif + + template + node_alloc_holder(const ValAlloc &a, const Pred &c) + : members_(a, typename ICont::value_compare(c)) + {} + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + node_alloc_holder(const detail::moved_object &a, const Pred &c) + : members_(a.get(), typename ICont::value_compare(c)) + {} + #else + template + node_alloc_holder(ValAlloc &&a, const Pred &c) + : members_(a, typename ICont::value_compare(c)) + {} + #endif + + template + node_alloc_holder(const node_alloc_holder &other, const Pred &c) + : members_(other.node_alloc(), typename ICont::value_compare(c)) + {} + + ~node_alloc_holder() + {} + + size_type max_size() const + { return this->node_alloc().max_size(); } + + NodePtr allocate_one() + { return this->allocate_one(alloc_version()); } + + NodePtr allocate_one(allocator_v1) + { return this->node_alloc().allocate(1); } + + NodePtr allocate_one(allocator_v2) + { return this->node_alloc().allocate_one(); } + + void deallocate_one(NodePtr p) + { return this->deallocate_one(p, alloc_version()); } + + void deallocate_one(NodePtr p, allocator_v1) + { this->node_alloc().deallocate(p, 1); } + + void deallocate_one(NodePtr p, allocator_v2) + { this->node_alloc().deallocate_one(p); } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + static void construct(const NodePtr &ptr, const Convertible &value) + { new(detail::get_pointer(ptr)) Node(value); } + #else + template + static void construct(const NodePtr &ptr, Convertible &&value) + { new(detail::get_pointer(ptr)) Node(forward(value)); } + #endif + + static void construct(const NodePtr &ptr) + { new(detail::get_pointer(ptr)) Node(); } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + static void construct(const NodePtr &ptr, + const detail::moved_object > &value) + { + typedef typename Node::hook_type hook_type; + typedef typename Node::value_type::first_type first_type; + typedef typename Node::value_type::second_type second_type; + Node *nodeptr = detail::get_pointer(ptr); + + //Hook constructor does not throw + new(static_cast(nodeptr))hook_type(); + //Now construct pair members_holder + value_type *valueptr = &nodeptr->m_data; + new((void*)&valueptr->first) first_type(move(value.get().first)); + BOOST_TRY{ + new((void*)&valueptr->second) second_type(move(value.get().second)); + } + BOOST_CATCH(...){ + valueptr->first.~first_type(); + static_cast(nodeptr)->~hook_type(); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #else + template + static void construct(const NodePtr &ptr, + std::pair &&value) + { + typedef typename Node::hook_type hook_type; + typedef typename Node::value_type::first_type first_type; + typedef typename Node::value_type::second_type second_type; + Node *nodeptr = detail::get_pointer(ptr); + + //Hook constructor does not throw + new(static_cast(nodeptr))hook_type(); + //Now construct pair members_holder + value_type *valueptr = &nodeptr->m_data; + new((void*)&valueptr->first) first_type(move(value.first)); + BOOST_TRY{ + new((void*)&valueptr->second) second_type(move(value.second)); + } + BOOST_CATCH(...){ + valueptr->first.~first_type(); + static_cast(nodeptr)->~hook_type(); + BOOST_RETHROW + } + BOOST_CATCH_END + } + #endif + + static void destroy(const NodePtr &ptr) + { detail::get_pointer(ptr)->~Node(); } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + NodePtr create_node(const Convertible& x) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + self_t::construct(p, x); + node_deallocator.release(); + return (p); + } + #else + template + NodePtr create_node(Convertible &&x) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + self_t::construct(p, forward(x)); + node_deallocator.release(); + return (p); + } + #endif + + template + NodePtr create_node_from_it(It it) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + ::boost::interprocess::construct_in_place(detail::get_pointer(p), it); + node_deallocator.release(); + return (p); + } + + NodePtr create_node() + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + self_t::construct(p); + node_deallocator.release(); + return (p); + } + + void destroy_node(NodePtr node) + { + self_t::destroy(node); + this->deallocate_one(node); + } + + void swap(node_alloc_holder &x) + { + NodeAlloc& this_alloc = this->node_alloc(); + NodeAlloc& other_alloc = x.node_alloc(); + + if (this_alloc != other_alloc){ + detail::do_swap(this_alloc, other_alloc); + } + + this->icont().swap(x.icont()); + } + + template + FwdIterator allocate_many_and_construct + (FwdIterator beg, difference_type n, Inserter inserter) + { + typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator; + + //Try to allocate memory in a single chunk + multiallocation_iterator itbeg = + this->node_alloc().allocate_individual(n), itend, itold; + int constructed = 0; + Node *p = 0; + BOOST_TRY{ + for(difference_type i = 0; i < n; ++i, ++beg, --constructed){ + p = &*itbeg; + ++itbeg; + //This can throw + boost::interprocess::construct_in_place(p, beg); + ++constructed; + //This can throw in some containers (predicate might throw) + inserter(*p); + } + } + BOOST_CATCH(...){ + if(constructed){ + this->destroy(p); + } + this->node_alloc().deallocate_many(itbeg); + BOOST_RETHROW + } + BOOST_CATCH_END + return beg; + } + + void clear(allocator_v1) + { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } + + void clear(allocator_v2) + { + allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc()); + this->icont().clear_and_dispose(chain_holder.get_chain_builder()); + } + + icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1) + { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); } + + icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2) + { + allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc()); + return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder()); + } + + template + size_type erase_key(const Key& k, const Comparator &comp, allocator_v1) + { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); } + + template + size_type erase_key(const Key& k, const Comparator &comp, allocator_v2) + { + allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc()); + return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder()); + } + + protected: + struct cloner + { + cloner(node_alloc_holder &holder) + : m_holder(holder) + {} + + NodePtr operator()(const Node &other) const + { return m_holder.create_node(other.m_data); } + + node_alloc_holder &m_holder; + }; + + struct destroyer + { + destroyer(node_alloc_holder &holder) + : m_holder(holder) + {} + + void operator()(NodePtr n) const + { m_holder.destroy_node(n); } + + node_alloc_holder &m_holder; + }; + + struct members_holder + : public NodeAlloc + { + private: + members_holder(const members_holder&); + + public: + template + members_holder(const ConvertibleToAlloc &c2alloc) + : NodeAlloc(c2alloc) + {} + + template + members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c) + : NodeAlloc(c2alloc), m_icont(c) + {} + //The intrusive container + ICont m_icont; + } members_; + + ICont &non_const_icont() const + { return const_cast(this->members_.m_icont); } + + ICont &icont() + { return this->members_.m_icont; } + + const ICont &icont() const + { return this->members_.m_icont; } + + NodeAlloc &node_alloc() + { return static_cast(this->members_); } + + const NodeAlloc &node_alloc() const + { return static_cast(this->members_); } +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif // BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_ diff --git a/thirdparty/boost/interprocess/containers/detail/tree.hpp b/thirdparty/boost/interprocess/containers/detail/tree.hpp new file mode 100644 index 0000000..68cab1f --- /dev/null +++ b/thirdparty/boost/interprocess/containers/detail/tree.hpp @@ -0,0 +1,950 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_tree file. Modified by Ion Gaztanaga 2005. +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +#ifndef BOOST_INTERPROCESS_TREE_HPP +#define BOOST_INTERPROCESS_TREE_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +template +struct value_compare_impl + : public KeyCompare +{ + typedef Value value_type; + typedef KeyCompare key_compare; + typedef KeyOfValue key_of_value; + typedef Key key_type; + + value_compare_impl(key_compare kcomp) + : key_compare(kcomp) + {} + + const key_compare &key_comp() const + { return static_cast(*this); } + + key_compare &key_comp() + { return static_cast(*this); } + + template + bool operator()(const A &a, const B &b) const + { return key_compare::operator()(KeyOfValue()(a), KeyOfValue()(b)); } +}; + +template +struct rbtree_node + : public bi::make_set_base_hook + < bi::void_pointer + , bi::link_mode + , bi::optimize_size + >::type +{ + typedef typename bi::make_set_base_hook + < bi::void_pointer + , bi::link_mode + , bi::optimize_size + >::type hook_type; + + typedef T value_type; + + typedef rbtree_node node_type; + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + rbtree_node(const Convertible &conv) + : m_data(conv){} + #else + template + rbtree_node(Convertible &&conv) + : m_data(forward(conv)){} + #endif + + rbtree_node &operator=(const rbtree_node &other) + { do_assign(other.m_data); return *this; } + + T m_data; + private: + + template + void do_assign(const std::pair &p) + { + const_cast(m_data.first) = p.first; + m_data.second = p.second; + } + + template + void do_assign(const V &v) + { m_data = v; } + + public: + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + + template + static void construct(node_type *ptr, const Convertible &value) + { new(ptr) node_type(value); } + + template + static void construct(node_type *ptr, + const detail::moved_object > &value) + { + //std::pair is not movable so we define our own type and overwrite it + typedef detail::pair hack_pair_t; + + typedef rbtree_node hack_node_t; + + new((void*)ptr) hack_node_t(value); + } + + #else + + template + static void construct(node_type *ptr, Convertible &&value) + { new(ptr) node_type(forward(value)); } + + template + static void construct(node_type *ptr, + std::pair &&value) + { + //std::pair is not movable so we define our own type and overwrite it + typedef detail::pair hack_pair_t; + + typedef rbtree_node hack_node_t; + + new((void*)ptr) hack_node_t(value); + } + + #endif +}; + +}//namespace detail { + +template +struct has_own_construct_from_it + < boost::interprocess::detail::rbtree_node > +{ + static const bool value = true; +}; + +namespace detail { + +template +struct intrusive_rbtree_type +{ + typedef typename A::value_type value_type; + typedef typename detail::pointer_to_other + ::type void_pointer; + typedef typename detail::rbtree_node + node_type; + typedef node_compare node_compare_type; + typedef typename bi::make_rbtree + + ,bi::base_hook + ,bi::constant_time_size + ,bi::size_type + >::type container_type; + typedef container_type type ; +}; + +} //namespace detail { + +namespace detail { + +template +class rbtree + : protected detail::node_alloc_holder + + >::type + > +{ + typedef typename detail::intrusive_rbtree_type + + >::type Icont; + typedef detail::node_alloc_holder AllocHolder; + typedef typename AllocHolder::NodePtr NodePtr; + typedef rbtree < Key, Value, KeyOfValue + , KeyCompare, A> ThisType; + typedef typename AllocHolder::NodeAlloc NodeAlloc; + typedef typename AllocHolder::ValAlloc ValAlloc; + typedef typename AllocHolder::Node Node; + typedef typename Icont::iterator iiterator; + typedef typename Icont::const_iterator iconst_iterator; + typedef detail::allocator_destroyer Destroyer; + typedef typename AllocHolder::allocator_v1 allocator_v1; + typedef typename AllocHolder::allocator_v2 allocator_v2; + typedef typename AllocHolder::alloc_version alloc_version; + + class RecyclingCloner; + friend class RecyclingCloner; + + class RecyclingCloner + { + public: + RecyclingCloner(AllocHolder &holder, Icont &irbtree) + : m_holder(holder), m_icont(irbtree) + {} + + NodePtr operator()(const Node &other) const + { +// if(!m_icont.empty()){ + if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){ + //First recycle a node (this can't throw) + //NodePtr p = m_icont.unlink_leftmost_without_rebalance(); + try{ + //This can throw + *p = other; + return p; + } + catch(...){ + //If there is an exception destroy the whole source + m_holder.destroy_node(p); + while((p = m_icont.unlink_leftmost_without_rebalance())){ + m_holder.destroy_node(p); + } + throw; + } + } + else{ + return m_holder.create_node(other); + } + } + + AllocHolder &m_holder; + Icont &m_icont; + }; + + public: + typedef Key key_type; + typedef Value value_type; + typedef A allocator_type; + typedef KeyCompare key_compare; + typedef value_compare_impl< Key, Value + , KeyCompare, KeyOfValue> value_compare; + typedef typename A::pointer pointer; + typedef typename A::const_pointer const_pointer; + typedef typename A::reference reference; + typedef typename A::const_reference const_reference; + typedef typename A::size_type size_type; + typedef typename A::difference_type difference_type; + typedef difference_type rbtree_difference_type; + typedef pointer rbtree_pointer; + typedef const_pointer rbtree_const_pointer; + typedef reference rbtree_reference; + typedef const_reference rbtree_const_reference; + typedef NodeAlloc stored_allocator_type; + + private: + + template + struct key_node_compare + : private KeyValueCompare + { + key_node_compare(KeyValueCompare comp) + : KeyValueCompare(comp) + {} + + template + bool operator()(const Node &n, const KeyType &k) const + { return KeyValueCompare::operator()(n.m_data, k); } + + template + bool operator()(const KeyType &k, const Node &n) const + { return KeyValueCompare::operator()(k, n.m_data); } + }; + + typedef key_node_compare KeyNodeCompare; + + public: + //rbtree const_iterator + class const_iterator + : public std::iterator + < std::bidirectional_iterator_tag + , value_type , rbtree_difference_type + , rbtree_const_pointer , rbtree_const_reference> + { + protected: + typedef typename Icont::iterator iiterator; + iiterator m_it; + explicit const_iterator(iiterator it) : m_it(it){} + void prot_incr() { ++m_it; } + void prot_decr() { --m_it; } + + private: + iiterator get() + { return this->m_it; } + + public: + friend class rbtree ; + typedef rbtree_difference_type difference_type; + + //Constructors + const_iterator() + : m_it() + {} + + //Pointer like operators + const_reference operator*() const + { return m_it->m_data; } + + const_pointer operator->() const + { return const_pointer(&m_it->m_data); } + + //Increment / Decrement + const_iterator& operator++() + { prot_incr(); return *this; } + + const_iterator operator++(int) + { iiterator tmp = m_it; ++*this; return const_iterator(tmp); } + + const_iterator& operator--() + { prot_decr(); return *this; } + + const_iterator operator--(int) + { iiterator tmp = m_it; --*this; return const_iterator(tmp); } + + //Comparison operators + bool operator== (const const_iterator& r) const + { return m_it == r.m_it; } + + bool operator!= (const const_iterator& r) const + { return m_it != r.m_it; } + }; + + //rbtree iterator + class iterator : public const_iterator + { + private: + explicit iterator(iiterator it) + : const_iterator(it) + {} + + iiterator get() + { return this->m_it; } + + public: + friend class rbtree ; + typedef rbtree_pointer pointer; + typedef rbtree_reference reference; + + //Constructors + iterator(){} + + //Pointer like operators + reference operator*() const { return this->m_it->m_data; } + pointer operator->() const { return pointer(&this->m_it->m_data); } + + //Increment / Decrement + iterator& operator++() + { this->prot_incr(); return *this; } + + iterator operator++(int) + { iiterator tmp = this->m_it; ++*this; return iterator(tmp); } + + iterator& operator--() + { this->prot_decr(); return *this; } + + iterator operator--(int) + { iterator tmp = *this; --*this; return tmp; } + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + rbtree(const key_compare& comp = key_compare(), + const allocator_type& a = allocator_type()) + : AllocHolder(a, comp) + {} + + template + rbtree(InputIterator first, InputIterator last, const key_compare& comp, + const allocator_type& a, bool unique_insertion) + : AllocHolder(a, comp) + { + typedef typename std::iterator_traits::iterator_category ItCat; + priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat()); + } + + rbtree(const rbtree& x) + : AllocHolder(x, x.key_comp()) + { + this->icont().clone_from + (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + rbtree(const detail::moved_object& x) + : AllocHolder(x.get(), x.get().key_comp()) + { this->swap(x.get()); } + #else + rbtree(rbtree &&x) + : AllocHolder(x, x.key_comp()) + { this->swap(x); } + #endif + + ~rbtree() + { this->clear(); } + + rbtree& operator=(const rbtree& x) + { + if (this != &x) { + //Transfer all the nodes to a temporary tree + //If anything goes wrong, all the nodes will be destroyed + //automatically + Icont other_tree(this->icont().value_comp()); + other_tree.swap(this->icont()); + + //Now recreate the source tree reusing nodes stored by other_tree + this->icont().clone_from + (x.icont() + , RecyclingCloner(*this, other_tree) + //, AllocHolder::cloner(*this) + , Destroyer(this->node_alloc())); + + //If there are remaining nodes, destroy them + NodePtr p; + while((p = other_tree.unlink_leftmost_without_rebalance())){ + AllocHolder::destroy_node(p); + } + } + return *this; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + rbtree& operator=(const detail::moved_object& mx) + { this->clear(); this->swap(mx.get()); return *this; } + #else + rbtree& operator=(rbtree &&mx) + { this->clear(); this->swap(mx); return *this; } + #endif + + public: + // accessors: + value_compare value_comp() const + { return this->icont().value_comp().value_comp(); } + + key_compare key_comp() const + { return this->icont().value_comp().value_comp().key_comp(); } + + allocator_type get_allocator() const + { return allocator_type(this->node_alloc()); } + + const stored_allocator_type &get_stored_allocator() const + { return this->node_alloc(); } + + stored_allocator_type &get_stored_allocator() + { return this->node_alloc(); } + + iterator begin() + { return iterator(this->icont().begin()); } + + const_iterator begin() const + { return const_iterator(this->non_const_icont().begin()); } + + iterator end() + { return iterator(this->icont().end()); } + + const_iterator end() const + { return const_iterator(this->non_const_icont().end()); } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + bool empty() const + { return !this->size(); } + + size_type size() const + { return this->icont().size(); } + + size_type max_size() const + { return AllocHolder::max_size(); } + + void swap(ThisType& x) + { AllocHolder::swap(x); } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object& mt) + { this->swap(mt.get()); } + #else + void swap(rbtree &&mt) + { this->swap(mt); } + #endif + + public: + + typedef typename Icont::insert_commit_data insert_commit_data; + + // insert/erase + std::pair insert_unique_check + (const key_type& key, insert_commit_data &data) + { + std::pair ret = + this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data); + return std::pair(iterator(ret.first), ret.second); + } + + std::pair insert_unique_check + (const_iterator hint, const key_type& key, insert_commit_data &data) + { + std::pair ret = + this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data); + return std::pair(iterator(ret.first), ret.second); + } + + iterator insert_unique_commit(const value_type& v, insert_commit_data &data) + { + NodePtr tmp = AllocHolder::create_node(v); + iiterator it(this->icont().insert_unique_commit(*tmp, data)); + return iterator(it); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + iterator insert_unique_commit + (const detail::moved_object& mv, insert_commit_data &data) + { + NodePtr tmp = AllocHolder::create_node(mv); + iiterator it(this->icont().insert_unique_commit(*tmp, data)); + return iterator(it); + } + #else + template + iterator insert_unique_commit + (MovableConvertible && mv, insert_commit_data &data) + { + NodePtr tmp = AllocHolder::create_node(forward(mv)); + iiterator it(this->icont().insert_unique_commit(*tmp, data)); + return iterator(it); + } + #endif + + std::pair insert_unique(const value_type& v) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(KeyOfValue()(v), data); + if(!ret.second) + return ret; + return std::pair + (this->insert_unique_commit(v, data), true); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + std::pair insert_unique + (const detail::moved_object& mv) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(KeyOfValue()(mv.get()), data); + if(!ret.second) + return ret; + return std::pair + (this->insert_unique_commit(mv, data), true); + } + #else + template + std::pair insert_unique(MovableConvertible &&mv) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(KeyOfValue()(mv), data); + if(!ret.second) + return ret; + return std::pair + (this->insert_unique_commit(forward(mv), data), true); + } + #endif + + iterator insert_unique(const_iterator hint, const value_type& v) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(hint, KeyOfValue()(v), data); + if(!ret.second) + return ret.first; + return this->insert_unique_commit(v, data); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + iterator insert_unique + (const_iterator hint, const detail::moved_object &mv) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(hint, KeyOfValue()(mv.get()), data); + if(!ret.second) + return ret.first; + return this->insert_unique_commit(mv, data); + } + #else + template + iterator insert_unique + (const_iterator hint, MovableConvertible &&mv) + { + insert_commit_data data; + std::pair ret = + this->insert_unique_check(hint, KeyOfValue()(mv), data); + if(!ret.second) + return ret.first; + return this->insert_unique_commit(forward(mv), data); + } + #endif + + template + void insert_unique(InputIterator first, InputIterator last) + { + if(this->empty()){ + //Insert with end hint, to achieve linear + //complexity if [first, last) is ordered + iterator end(this->end()); + for( ; first != last; ++first) + this->insert_unique(end, *first); + } + else{ + for( ; first != last; ++first) + this->insert_unique(*first); + } + } + + iterator insert_equal(const value_type& v) + { + NodePtr p(AllocHolder::create_node(v)); + return iterator(this->icont().insert_equal(this->icont().end(), *p)); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + iterator insert_equal(const detail::moved_object &mv) + { + NodePtr p(AllocHolder::create_node(mv)); + return iterator(this->icont().insert_equal(this->icont().end(), *p)); + } + #else + template + iterator insert_equal(MovableConvertible &&mv) + { + NodePtr p(AllocHolder::create_node(forward(mv))); + return iterator(this->icont().insert_equal(this->icont().end(), *p)); + } + #endif + + iterator insert_equal(const_iterator hint, const value_type& v) + { + NodePtr p(AllocHolder::create_node(v)); + return iterator(this->icont().insert_equal(hint.get(), *p)); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + iterator insert_equal(const_iterator hint, const detail::moved_object &mv) + { + NodePtr p(AllocHolder::create_node(mv)); + return iterator(this->icont().insert_equal(hint.get(), *p)); + } + #else + template + iterator insert_equal(const_iterator hint, MovableConvertible &&mv) + { + NodePtr p(AllocHolder::create_node(move(mv))); + return iterator(this->icont().insert_equal(hint.get(), *p)); + } + #endif + + template + void insert_equal(InputIterator first, InputIterator last) + { + //Insert with end hint, to achieve linear + //complexity if [first, last) is ordered + iterator end(this->end()); + for( ; first != last; ++first) + this->insert_equal(end, *first); + } + + iterator erase(const_iterator position) + { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); } + + size_type erase(const key_type& k) + { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); } + + iterator erase(const_iterator first, const_iterator last) + { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); } + + void clear() + { AllocHolder::clear(alloc_version()); } + + // set operations: + iterator find(const key_type& k) + { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); } + + const_iterator find(const key_type& k) const + { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); } + + size_type count(const key_type& k) const + { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); } + + iterator lower_bound(const key_type& k) + { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); } + + const_iterator lower_bound(const key_type& k) const + { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); } + + iterator upper_bound(const key_type& k) + { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); } + + const_iterator upper_bound(const key_type& k) const + { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); } + + std::pair equal_range(const key_type& k) + { + std::pair ret = + this->icont().equal_range(k, KeyNodeCompare(value_comp())); + return std::pair(iterator(ret.first), iterator(ret.second)); + } + + std::pair equal_range(const key_type& k) const + { + std::pair ret = + this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp())); + return std::pair + (const_iterator(ret.first), const_iterator(ret.second)); + } + + private: + //Iterator range version + template + void priv_create_and_insert_nodes + (InpIterator beg, InpIterator end, bool unique) + { + typedef typename std::iterator_traits::iterator_category ItCat; + priv_create_and_insert_nodes(beg, end, unique, alloc_version(), ItCat()); + } + + template + void priv_create_and_insert_nodes + (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag) + { + if(unique){ + for (; beg != end; ++beg){ + this->insert_unique(*beg); + } + } + else{ + for (; beg != end; ++beg){ + this->insert_equal(*beg); + } + } + } + + template + void priv_create_and_insert_nodes + (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag) + { //Just forward to the default one + priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag()); + } + + class insertion_functor; + friend class insertion_functor; + + class insertion_functor + { + Icont &icont_; + typename Icont::iterator pos_; + + public: + insertion_functor(Icont &icont) + : icont_(icont) + {} + + void operator()(Node &n) + { this->icont_.insert_equal(this->icont_.end(), n); } + }; + + + template + void priv_create_and_insert_nodes + (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag) + { + if(unique){ + priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag()); + } + else{ + //Optimized allocation and construction + this->allocate_many_and_construct + (beg, std::distance(beg, end), insertion_functor(this->icont())); + } + } +}; + +template +inline bool +operator==(const rbtree& x, + const rbtree& y) +{ + return x.size() == y.size() && + std::equal(x.begin(), x.end(), y.begin()); +} + +template +inline bool +operator<(const rbtree& x, + const rbtree& y) +{ + return std::lexicographical_compare(x.begin(), x.end(), + y.begin(), y.end()); +} + +template +inline bool +operator!=(const rbtree& x, + const rbtree& y) { + return !(x == y); +} + +template +inline bool +operator>(const rbtree& x, + const rbtree& y) { + return y < x; +} + +template +inline bool +operator<=(const rbtree& x, + const rbtree& y) { + return !(y < x); +} + +template +inline bool +operator>=(const rbtree& x, + const rbtree& y) { + return !(x < y); +} + + +template +inline void +swap(rbtree& x, + rbtree& y) +{ + x.swap(y); +} + +} //namespace detail { + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +/* +template +struct is_movable > +{ + enum { value = true }; +}; +*/ + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; + + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_TREE_HPP diff --git a/thirdparty/boost/interprocess/containers/flat_map.hpp b/thirdparty/boost/interprocess/containers/flat_map.hpp new file mode 100644 index 0000000..00df787 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/flat_map.hpp @@ -0,0 +1,1273 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_FLAT_MAP_HPP +#define BOOST_INTERPROCESS_FLAT_MAP_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace interprocess { + +/// @cond +// Forward declarations of operators == and <, needed for friend declarations. +template +class flat_map; + +template +inline bool operator==(const flat_map& x, + const flat_map& y); + +template +inline bool operator<(const flat_map& x, + const flat_map& y); +/// @endcond + +//! A flat_map is a kind of associative container that supports unique keys (contains at +//! most one of each key value) and provides for fast retrieval of values of another +//! type T based on the keys. The flat_map class supports random-access iterators. +//! +//! A flat_map satisfies all of the requirements of a container and of a reversible +//! container and of an associative container. A flat_map also provides +//! most operations described for unique keys. For a +//! flat_map the key_type is Key and the value_type is std::pair +//! (unlike std::map which value_type is std::pair<const Key, T>). +//! +//! Pred is the ordering function for Keys (e.g. std::less). +//! +//! Alloc is the allocator to allocate the value_types +//! (e.g. boost::interprocess:allocator< std::pair). +//! +//! flat_map is similar to std::map but it's implemented like an ordered vector. +//! This means that inserting a new element into a flat_map invalidates +//! previous iterators and references +//! +//! Erasing an element of a flat_map invalidates iterators and references +//! pointing to elements that come after (their keys are bigger) the erased element. +template +class flat_map +{ + /// @cond + private: + //This is the real tree stored here. It's based on a movable pair + typedef detail::flat_tree, + detail::select1st< detail::pair >, + Pred, + typename Alloc::template + rebind >::other> impl_tree_t; + + //This is the tree that we should store if pair was movable + typedef detail::flat_tree, + detail::select1st< std::pair >, + Pred, + Alloc> tree_t; + +// tree_t m_flat_tree; // flat tree representing flat_map + impl_tree_t m_flat_tree; // flat tree representing flat_map + + typedef typename impl_tree_t::value_type impl_value_type; + typedef typename impl_tree_t::pointer impl_pointer; + typedef typename impl_tree_t::const_pointer impl_const_pointer; + typedef typename impl_tree_t::reference impl_reference; + typedef typename impl_tree_t::const_reference impl_const_reference; + typedef typename impl_tree_t::value_compare impl_value_compare; + typedef typename impl_tree_t::iterator impl_iterator; + typedef typename impl_tree_t::const_iterator impl_const_iterator; + typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator; + typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator; + typedef typename impl_tree_t::allocator_type impl_allocator_type; + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + typedef detail::moved_object impl_moved_value_type; + #else + typedef impl_value_type&& impl_moved_value_type; + #endif + + template + static D &force(const S &s) + { return *const_cast((reinterpret_cast(&s))); } + + #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + static D &&force(S &&s) + { return reinterpret_cast(s); } + #endif + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef typename tree_t::value_compare value_compare; + typedef T mapped_type; + typedef typename tree_t::key_compare key_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + //! Effects: Constructs an empty flat_map using the specified + //! comparison object and allocator. + //! + //! Complexity: Constant. + explicit flat_map(const Pred& comp = Pred(), const allocator_type& a = allocator_type()) + : m_flat_tree(comp, force(a)) {} + + //! Effects: Constructs an empty flat_map using the specified comparison object and + //! allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, force(a)) + { m_flat_tree.insert_unique(first, last); } + + //! Effects: Copy constructs a flat_map. + //! + //! Complexity: Linear in x.size(). + flat_map(const flat_map& x) + : m_flat_tree(x.m_flat_tree) {} + + //! Effects: Move constructs a flat_map. + //! Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_map(const detail::moved_object >& x) + : m_flat_tree(move(x.get().m_flat_tree)) {} + + #else + flat_map(flat_map && x) + : m_flat_tree(move(x.m_flat_tree)) {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + flat_map& operator=(const flat_map& x) + { m_flat_tree = x.m_flat_tree; return *this; } + + //! Effects: Move constructs a flat_map. + //! Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_map& operator=(const detail::moved_object >& mx) + { m_flat_tree = move(mx.get().m_flat_tree); return *this; } + #else + flat_map& operator=(flat_map && mx) + { m_flat_tree = move(mx.m_flat_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return force(m_flat_tree.key_comp()); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(force(m_flat_tree.key_comp())); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return force(m_flat_tree.get_allocator()); } + + const stored_allocator_type &get_stored_allocator() const + { return force(m_flat_tree.get_stored_allocator()); } + + stored_allocator_type &get_stored_allocator() + { return force(m_flat_tree.get_stored_allocator()); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return force(m_flat_tree.begin()); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return force(m_flat_tree.begin()); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return force(m_flat_tree.end()); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return force(m_flat_tree.end()); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return force(m_flat_tree.rbegin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return force(m_flat_tree.rbegin()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return force(m_flat_tree.rend()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return force(m_flat_tree.rend()); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_flat_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_flat_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_flat_tree.max_size(); } + + //! Effects: If there is no key equivalent to x in the flat_map, inserts + //! value_type(move(x), T()) into the flat_map (the key is move-constructed) + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + //! Effects: If there is no key equivalent to x in the flat_map, inserts + //! value_type(x, T()) into the flat_map. + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + T &operator[](const key_type& k) + { + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)) + i = insert(i, value_type(k, T())); + return (*i).second; + } + + T &operator[](const detail::moved_object& mk) + { + key_type &k = mk.get(); + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)) + i = insert(i, value_type(k, move(T()))); + return (*i).second; + } + #else + //! Effects: If there is no key equivalent to x in the flat_map, inserts + //! value_type(x, T()) into the flat_map. + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + T &operator[](key_type &&mk) + { + key_type &k = mk; + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)) + i = insert(i, value_type(forward(k), move(T()))); + return (*i).second; + } + #endif + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_map& x) + { m_flat_tree.swap(x.m_flat_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_flat_tree.swap(x.get().m_flat_tree); } + #else + void swap(flat_map && x) + { m_flat_tree.swap(x.m_flat_tree); } + #endif + + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + std::pair insert(const value_type& x) + { return force >( + m_flat_tree.insert_unique(force(x))); } + + //! Effects: Inserts a new value_type move constructed from the pair if and + //! only if there is no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert(const detail::moved_object& x) + { return force >( + m_flat_tree.insert_unique(force(x))); } + #else + std::pair insert(value_type &&x) + { return force >( + m_flat_tree.insert_unique(force(move(x)))); } + #endif + + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(iterator position, const value_type& x) + { return force( + m_flat_tree.insert_unique(force(position), force(x))); } + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object& x) + { return force( + m_flat_tree.insert_unique(force(position), force(x))); } + #else + iterator insert(iterator position, value_type &&x) + { return force( + m_flat_tree.insert_unique(force(position), force(move(x)))); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + //! search time plus N*size() insertion time. + //! + //! Note: If an element it's inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_unique(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Linear to the elements with keys bigger than position + //! + //! Note: Invalidates elements with keys + //! not less than the erased element. + void erase(const_iterator position) + { m_flat_tree.erase(force(position)); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + size_type erase(const key_type& x) + { return m_flat_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: size()*N where N is the distance from first to last. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + void erase(const_iterator first, const_iterator last) + { m_flat_tree.erase(force(first), force(last)); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_flat_tree.clear(); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return force(m_flat_tree.find(x)); } + + //! Returns: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic.s + const_iterator find(const key_type& x) const + { return force(m_flat_tree.find(x)); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return force(m_flat_tree.lower_bound(x)); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return force(m_flat_tree.lower_bound(x)); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return force(m_flat_tree.upper_bound(x)); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return force(m_flat_tree.upper_bound(x)); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) + { return force >(m_flat_tree.equal_range(x)); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) const + { return force >(m_flat_tree.equal_range(x)); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + /// @cond + template + friend bool operator== (const flat_map&, + const flat_map&); + template + friend bool operator< (const flat_map&, + const flat_map&); + /// @endcond +}; + +template +inline bool operator==(const flat_map& x, + const flat_map& y) + { return x.m_flat_tree == y.m_flat_tree; } + +template +inline bool operator<(const flat_map& x, + const flat_map& y) + { return x.m_flat_tree < y.m_flat_tree; } + +template +inline bool operator!=(const flat_map& x, + const flat_map& y) + { return !(x == y); } + +template +inline bool operator>(const flat_map& x, + const flat_map& y) + { return y < x; } + +template +inline bool operator<=(const flat_map& x, + const flat_map& y) + { return !(y < x); } + +template +inline bool operator>=(const flat_map& x, + const flat_map& y) + { return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(flat_map& x, + flat_map& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + flat_map& y) + { x.get().swap(y); } + +template +inline void swap(flat_map& x, + const detail::moved_object >& y) + { x.swap(y.get()); } +#else +template +inline void swap(flat_map&&x, + flat_map&&y) + { x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; + +// Forward declaration of operators < and ==, needed for friend declaration. +template +class flat_multimap; + +template +inline bool operator==(const flat_multimap& x, + const flat_multimap& y); + +template +inline bool operator<(const flat_multimap& x, + const flat_multimap& y); +/// @endcond + +//! A flat_multimap is a kind of associative container that supports equivalent keys +//! (possibly containing multiple copies of the same key value) and provides for +//! fast retrieval of values of another type T based on the keys. The flat_multimap +//! class supports random-access iterators. +//! +//! A flat_multimap satisfies all of the requirements of a container and of a reversible +//! container and of an associative container. For a +//! flat_multimap the key_type is Key and the value_type is std::pair +//! (unlike std::multimap which value_type is std::pair<const Key, T>). +//! +//! Pred is the ordering function for Keys (e.g. std::less). +//! +//! Alloc is the allocator to allocate the value_types +//! (e.g. boost::interprocess:allocator< std::pair). +template +class flat_multimap +{ + /// @cond + private: + //This is the real tree stored here. It's based on a movable pair + typedef detail::flat_tree, + detail::select1st< detail::pair >, + Pred, + typename Alloc::template + rebind >::other> impl_tree_t; + + typedef detail::flat_tree, + detail::select1st< std::pair >, + Pred, + Alloc> tree_t; +// tree_t m_flat_tree; // flat tree representing flat_multimap + impl_tree_t m_flat_tree; // flat tree representing flat_map + + typedef typename impl_tree_t::value_type impl_value_type; + typedef typename impl_tree_t::pointer impl_pointer; + typedef typename impl_tree_t::const_pointer impl_const_pointer; + typedef typename impl_tree_t::reference impl_reference; + typedef typename impl_tree_t::const_reference impl_const_reference; + typedef typename impl_tree_t::value_compare impl_value_compare; + typedef typename impl_tree_t::iterator impl_iterator; + typedef typename impl_tree_t::const_iterator impl_const_iterator; + typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator; + typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator; + typedef typename impl_tree_t::allocator_type impl_allocator_type; + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + typedef detail::moved_object impl_moved_value_type; + #else + typedef impl_value_type&& impl_moved_value_type; + #endif + + template + static D &force(const S &s) + { return *const_cast((reinterpret_cast(&s))); } + + #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + static D &&force(S &&s) + { return reinterpret_cast(s); } + #endif + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef typename tree_t::value_compare value_compare; + typedef T mapped_type; + typedef typename tree_t::key_compare key_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + //! Effects: Constructs an empty flat_multimap using the specified comparison + //! object and allocator. + //! + //! Complexity: Constant. + explicit flat_multimap(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, force(a)) { } + + //! Effects: Constructs an empty flat_multimap using the specified comparison object + //! and allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + flat_multimap(InputIterator first, InputIterator last, + const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, force(a)) + { m_flat_tree.insert_equal(first, last); } + + //! Effects: Copy constructs a flat_multimap. + //! + //! Complexity: Linear in x.size(). + flat_multimap(const flat_multimap& x) + : m_flat_tree(x.m_flat_tree) { } + + //! Effects: Move constructs a flat_multimap. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_multimap(const detail::moved_object >& x) + : m_flat_tree(move(x.get().m_flat_tree)) { } + #else + flat_multimap(flat_multimap && x) + : m_flat_tree(move(x.m_flat_tree)) { } + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + flat_multimap& + operator=(const flat_multimap& x) + { m_flat_tree = x.m_flat_tree; return *this; } + + //! Effects: this->swap(x.get()). + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_multimap& + operator=(const detail::moved_object >& mx) + { m_flat_tree = move(mx.get().m_flat_tree); return *this; } + #else + flat_multimap& + operator=(flat_multimap && mx) + { m_flat_tree = move(mx.m_flat_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return force(m_flat_tree.key_comp()); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(force(m_flat_tree.key_comp())); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return force(m_flat_tree.get_allocator()); } + + const stored_allocator_type &get_stored_allocator() const + { return force(m_flat_tree.get_stored_allocator()); } + + stored_allocator_type &get_stored_allocator() + { return force(m_flat_tree.get_stored_allocator()); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return force(m_flat_tree.begin()); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return force(m_flat_tree.begin()); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return force(m_flat_tree.end()); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return force(m_flat_tree.end()); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return force(m_flat_tree.rbegin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return force(m_flat_tree.rbegin()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return force(m_flat_tree.rend()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return force(m_flat_tree.rend()); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_flat_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_flat_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_flat_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_multimap& x) + { m_flat_tree.swap(x.m_flat_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_flat_tree.swap(x.get().m_flat_tree); } + #else + void swap(flat_multimap && x) + { m_flat_tree.swap(x.m_flat_tree); } + #endif + + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(const value_type& x) + { return force(m_flat_tree.insert_equal(force(x))); } + + //! Effects: Inserts a new value move-constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const detail::moved_object& x) + { return force(m_flat_tree.insert_equal(force(x))); } + #else + iterator insert(value_type &&x) + { return force(m_flat_tree.insert_equal(force(move(x)))); } + #endif + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant time if the value + //! is to be inserted before p) plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(iterator position, const value_type& x) + { return force(m_flat_tree.insert_equal(force(position), force(x))); } + + //! Effects: Inserts a value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant time if the value + //! is to be inserted before p) plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object& x) + { return force(m_flat_tree.insert_equal(force(position), force(x))); } + #else + iterator insert(iterator position, value_type &&x) + { return force(m_flat_tree.insert_equal(force(position), force(move(x)))); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) . + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + //! search time plus N*size() insertion time. + //! + //! Note: If an element it's inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_equal(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Linear to the elements with keys bigger than position + //! + //! Note: Invalidates elements with keys + //! not less than the erased element. + void erase(const_iterator position) + { m_flat_tree.erase(force(position)); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + size_type erase(const key_type& x) + { return m_flat_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: size()*N where N is the distance from first to last. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + void erase(const_iterator first, const_iterator last) + { m_flat_tree.erase(force(first), force(last)); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_flat_tree.clear(); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return force(m_flat_tree.find(x)); } + + //! Returns: An const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const + { return force(m_flat_tree.find(x)); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_flat_tree.count(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + {return force(m_flat_tree.lower_bound(x)); } + + //! Returns: A const iterator pointing to the first element with key + //! not less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return force(m_flat_tree.lower_bound(x)); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + {return force(m_flat_tree.upper_bound(x)); } + + //! Returns: A const iterator pointing to the first element with key + //! not less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return force(m_flat_tree.upper_bound(x)); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) + { return force >(m_flat_tree.equal_range(x)); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return force >(m_flat_tree.equal_range(x)); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + /// @cond + template + friend bool operator== (const flat_multimap& x, + const flat_multimap& y); + + template + friend bool operator< (const flat_multimap& x, + const flat_multimap& y); + /// @endcond +}; + +template +inline bool operator==(const flat_multimap& x, + const flat_multimap& y) + { return x.m_flat_tree == y.m_flat_tree; } + +template +inline bool operator<(const flat_multimap& x, + const flat_multimap& y) + { return x.m_flat_tree < y.m_flat_tree; } + +template +inline bool operator!=(const flat_multimap& x, + const flat_multimap& y) + { return !(x == y); } + +template +inline bool operator>(const flat_multimap& x, + const flat_multimap& y) + { return y < x; } + +template +inline bool operator<=(const flat_multimap& x, + const flat_multimap& y) + { return !(y < x); } + +template +inline bool operator>=(const flat_multimap& x, + const flat_multimap& y) + { return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(flat_multimap& x, + flat_multimap& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + flat_multimap& y) + { x.get().swap(y); } + + +template +inline void swap(flat_multimap& x, + const detail::moved_object > & y) + { x.swap(y.get()); } +#else +template +inline void swap(flat_multimap&&x, + flat_multimap&&y) + { x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_FLAT_MAP_HPP */ diff --git a/thirdparty/boost/interprocess/containers/flat_set.hpp b/thirdparty/boost/interprocess/containers/flat_set.hpp new file mode 100644 index 0000000..832be00 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/flat_set.hpp @@ -0,0 +1,1082 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_FLAT_SET_HPP +#define BOOST_INTERPROCESS_FLAT_SET_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace interprocess { + +/// @cond +// Forward declarations of operators < and ==, needed for friend declaration. + +template +class flat_set; + +template +inline bool operator==(const flat_set& x, + const flat_set& y); + +template +inline bool operator<(const flat_set& x, + const flat_set& y); +/// @endcond + +//! flat_set is a Sorted Associative Container that stores objects of type Key. +//! flat_set is a Simple Associative Container, meaning that its value type, +//! as well as its key type, is Key. It is also a Unique Associative Container, +//! meaning that no two elements are the same. +//! +//! flat_set is similar to std::set but it's implemented like an ordered vector. +//! This means that inserting a new element into a flat_set invalidates +//! previous iterators and references +//! +//! Erasing an element of a flat_set invalidates iterators and references +//! pointing to elements that come after (their keys are bigger) the erased element. +template +class flat_set +{ + /// @cond + private: + typedef detail::flat_tree, Pred, Alloc> tree_t; + tree_t m_flat_tree; // flat tree representing flat_set + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef typename tree_t::key_compare key_compare; + typedef typename tree_t::value_compare value_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + //! Effects: Constructs an empty flat_map using the specified + //! comparison object and allocator. + //! + //! Complexity: Constant. + explicit flat_set(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, a) + {} + + //! Effects: Constructs an empty map using the specified comparison object and + //! allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + flat_set(InputIterator first, InputIterator last, + const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, a) + { m_flat_tree.insert_unique(first, last); } + + //! Effects: Copy constructs a map. + //! + //! Complexity: Linear in x.size(). + flat_set(const flat_set& x) + : m_flat_tree(x.m_flat_tree) {} + + //! Effects: Move constructs a map. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_set(const detail::moved_object >& mx) + : m_flat_tree(move(mx.get().m_flat_tree)) {} + #else + flat_set(flat_set && mx) + : m_flat_tree(move(mx.m_flat_tree)) {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + flat_set& operator=(const flat_set& x) + { m_flat_tree = x.m_flat_tree; return *this; } + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_set& operator=(const detail::moved_object > &mx) + { m_flat_tree = move(mx.get().m_flat_tree); return *this; } + + #else + flat_set& operator=(flat_set &&mx) + { m_flat_tree = move(mx.m_flat_tree); return *this; } + + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_flat_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_flat_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_flat_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return m_flat_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_flat_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_flat_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_flat_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_flat_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_flat_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_flat_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_flat_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_flat_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_flat_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_flat_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_set& x) + { m_flat_tree.swap(x.m_flat_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& mx) + { this->swap(mx.get()); } + #else + void swap(flat_set && mx) + { this->swap(mx); } + #endif + + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + std::pair insert(const value_type& x) + { return m_flat_tree.insert_unique(x); } + + //! Effects: Inserts a new value_type move constructed from the pair if and + //! only if there is no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert(const detail::moved_object& x) + { return m_flat_tree.insert_unique(x); } + #else + std::pair insert(value_type && x) + { return m_flat_tree.insert_unique(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(iterator position, const value_type& x) + { return m_flat_tree.insert_unique(position, x); } + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object& x) + { return m_flat_tree.insert_unique(position, x); } + #else + iterator insert(iterator position, value_type && x) + { return m_flat_tree.insert_unique(position, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + //! search time plus N*size() insertion time. + //! + //! Note: If an element it's inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_unique(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Linear to the elements with keys bigger than position + //! + //! Note: Invalidates elements with keys + //! not less than the erased element. + iterator erase(const_iterator position) + { return m_flat_tree.erase(position); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + size_type erase(const key_type& x) + { return m_flat_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: size()*N where N is the distance from first to last. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + iterator erase(const_iterator first, const_iterator last) + { return m_flat_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_flat_tree.clear(); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_flat_tree.find(x); } + + //! Returns: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic.s + const_iterator find(const key_type& x) const + { return m_flat_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return m_flat_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_flat_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_flat_tree.upper_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_flat_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return m_flat_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) + { return m_flat_tree.equal_range(x); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + /// @cond + template + friend bool operator== (const flat_set&, const flat_set&); + + template + friend bool operator< (const flat_set&, const flat_set&); + /// @endcond +}; + +template +inline bool operator==(const flat_set& x, + const flat_set& y) + { return x.m_flat_tree == y.m_flat_tree; } + +template +inline bool operator<(const flat_set& x, + const flat_set& y) + { return x.m_flat_tree < y.m_flat_tree; } + +template +inline bool operator!=(const flat_set& x, + const flat_set& y) + { return !(x == y); } + +template +inline bool operator>(const flat_set& x, + const flat_set& y) + { return y < x; } + +template +inline bool operator<=(const flat_set& x, + const flat_set& y) + { return !(y < x); } + +template +inline bool operator>=(const flat_set& x, + const flat_set& y) + { return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(flat_set& x, + flat_set& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + flat_set& y) + { x.get().swap(y); } + +template +inline void swap(flat_set& x, + const detail::moved_object >& y) + { x.swap(y.get()); } +#else +template +inline void swap(flat_set&&x, + flat_set&&y) + { x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; + +// Forward declaration of operators < and ==, needed for friend declaration. + +template +class flat_multiset; + +template +inline bool operator==(const flat_multiset& x, + const flat_multiset& y); + +template +inline bool operator<(const flat_multiset& x, + const flat_multiset& y); +/// @endcond + +template +class flat_multiset +{ + /// @cond + private: + typedef detail::flat_tree, Pred, Alloc> tree_t; + tree_t m_flat_tree; // flat tree representing flat_multiset + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef typename tree_t::key_compare key_compare; + typedef typename tree_t::value_compare value_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + // allocation/deallocation + explicit flat_multiset(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, a) {} + + template + flat_multiset(InputIterator first, InputIterator last, + const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_flat_tree(comp, a) + { m_flat_tree.insert_equal(first, last); } + + flat_multiset(const flat_multiset& x) + : m_flat_tree(x.m_flat_tree) {} + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_multiset(const detail::moved_object >& x) + : m_flat_tree(move(x.get().m_flat_tree)) {} + #else + flat_multiset(flat_multiset && x) + : m_flat_tree(move(x.m_flat_tree)) {} + #endif + + flat_multiset& operator=(const flat_multiset& x) + { m_flat_tree = x.m_flat_tree; return *this; } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + flat_multiset& operator=(const detail::moved_object >& mx) + { m_flat_tree = move(mx.get().m_flat_tree); return *this; } + #else + flat_multiset& operator=(flat_multiset && mx) + { m_flat_tree = move(mx.m_flat_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_flat_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_flat_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_flat_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return m_flat_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_flat_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_flat_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_flat_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_flat_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_flat_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_flat_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_flat_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_flat_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_flat_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_flat_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_multiset& x) + { m_flat_tree.swap(x.m_flat_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& mx) + { this->swap(mx.get()); } + #else + void swap(flat_multiset && mx) + { this->swap(mx); } + #endif + + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(const value_type& x) + { return m_flat_tree.insert_equal(x); } + + //! Effects: Inserts a new value_type move constructed from x + //! and returns the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const detail::moved_object& x) + { return m_flat_tree.insert_equal(x); } + #else + iterator insert(value_type && x) + { return m_flat_tree.insert_equal(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + iterator insert(iterator position, const value_type& x) + { return m_flat_tree.insert_equal(position, x); } + + //! Effects: Inserts a new value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element it's inserted it might invalidate elements. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object& x) + { return m_flat_tree.insert_equal(position, x); } + #else + iterator insert(iterator position, value_type && x) + { return m_flat_tree.insert_equal(position, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) . + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + //! search time plus N*size() insertion time. + //! + //! Note: If an element it's inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_equal(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Linear to the elements with keys bigger than position + //! + //! Note: Invalidates elements with keys + //! not less than the erased element. + iterator erase(const_iterator position) + { return m_flat_tree.erase(position); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + size_type erase(const key_type& x) + { return m_flat_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: size()*N where N is the distance from first to last. + //! + //! Complexity: Logarithmic search time plus erasure time + //! linear to the elements with bigger keys. + iterator erase(const_iterator first, const_iterator last) + { return m_flat_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_flat_tree.clear(); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_flat_tree.find(x); } + + //! Returns: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic.s + const_iterator find(const key_type& x) const + { return m_flat_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_flat_tree.count(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return m_flat_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_flat_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_flat_tree.upper_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_flat_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return m_flat_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) + { return m_flat_tree.equal_range(x); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + /// @cond + template + friend bool operator== (const flat_multiset&, + const flat_multiset&); + template + friend bool operator< (const flat_multiset&, + const flat_multiset&); + /// @endcond +}; + +template +inline bool operator==(const flat_multiset& x, + const flat_multiset& y) + { return x.m_flat_tree == y.m_flat_tree; } + +template +inline bool operator<(const flat_multiset& x, + const flat_multiset& y) + { return x.m_flat_tree < y.m_flat_tree; } + +template +inline bool operator!=(const flat_multiset& x, + const flat_multiset& y) + { return !(x == y); } + +template +inline bool operator>(const flat_multiset& x, + const flat_multiset& y) + { return y < x; } + +template +inline bool operator<=(const flat_multiset& x, + const flat_multiset& y) + { return !(y < x); } + +template +inline bool operator>=(const flat_multiset& x, + const flat_multiset& y) +{ return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(flat_multiset& x, + flat_multiset& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + flat_multiset& y) + { x.get().swap(y); } + +template +inline void swap(flat_multiset& x, + const detail::moved_object >& y) + { x.swap(y.get()); } +#else +template +inline void swap(flat_multiset&&x, + flat_multiset&&y) + { x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_FLAT_SET_HPP */ diff --git a/thirdparty/boost/interprocess/containers/list.hpp b/thirdparty/boost/interprocess/containers/list.hpp new file mode 100644 index 0000000..e84d85e --- /dev/null +++ b/thirdparty/boost/interprocess/containers/list.hpp @@ -0,0 +1,1328 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_list.h file. Modified by Ion Gaztanaga 2004 +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_INTERPROCESS_LIST_HPP_ +#define BOOST_INTERPROCESS_LIST_HPP_ + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail { + +template +struct list_node + : public bi::make_list_base_hook + , bi::link_mode >::type +{ + typedef typename bi::make_list_base_hook + , bi::link_mode >::type hook_type; + + list_node() + : m_data() + {} + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + list_node(const Convertible &conv) + : m_data(conv) + {} + #else + template + list_node(Convertible &&conv) + : m_data(forward(conv)) + {} + #endif + + T m_data; +}; + +template +struct intrusive_list_type +{ + typedef typename A::value_type value_type; + typedef typename detail::pointer_to_other + ::type void_pointer; + typedef typename detail::list_node + node_type; + typedef typename bi::make_list + < node_type + , bi::base_hook + , bi::constant_time_size + , bi::size_type + >::type container_type; + typedef container_type type ; +}; + +} //namespace detail { +/// @endcond + +//! A list is a doubly linked list. That is, it is a Sequence that supports both +//! forward and backward traversal, and (amortized) constant time insertion and +//! removal of elements at the beginning or the end, or in the middle. Lists have +//! the important property that insertion and splicing do not invalidate iterators +//! to list elements, and that even removal invalidates only the iterators that point +//! to the elements that are removed. The ordering of iterators may be changed +//! (that is, list::iterator might have a different predecessor or successor +//! after a list operation than it did before), but the iterators themselves will +//! not be invalidated or made to point to different elements unless that invalidation +//! or mutation is explicit. +template +class list + : protected detail::node_alloc_holder + ::type> +{ + /// @cond + typedef typename + detail::intrusive_list_type::type Icont; + typedef detail::node_alloc_holder AllocHolder; + typedef typename AllocHolder::NodePtr NodePtr; + typedef list ThisType; + typedef typename AllocHolder::NodeAlloc NodeAlloc; + typedef typename AllocHolder::ValAlloc ValAlloc; + typedef typename AllocHolder::Node Node; + typedef detail::allocator_destroyer Destroyer; + typedef typename AllocHolder::allocator_v1 allocator_v1; + typedef typename AllocHolder::allocator_v2 allocator_v2; + typedef typename AllocHolder::alloc_version alloc_version; + + class equal_to_value + { + typedef typename AllocHolder::value_type value_type; + const value_type &t_; + + public: + equal_to_value(const value_type &t) + : t_(t) + {} + + bool operator()(const value_type &t)const + { return t_ == t; } + }; + + template + struct ValueCompareToNodeCompare + : Pred + { + ValueCompareToNodeCompare(Pred pred) + : Pred(pred) + {} + + bool operator()(const Node &a, const Node &b) const + { return static_cast(*this)(a.m_data, b.m_data); } + + bool operator()(const Node &a) const + { return static_cast(*this)(a.m_data); } + }; + /// @endcond + + public: + //! The type of object, T, stored in the list + typedef T value_type; + //! Pointer to T + typedef typename A::pointer pointer; + //! Const pointer to T + typedef typename A::const_pointer const_pointer; + //! Reference to T + typedef typename A::reference reference; + //! Const reference to T + typedef typename A::const_reference const_reference; + //! An unsigned integral type + typedef typename A::size_type size_type; + //! A signed integral type + typedef typename A::difference_type difference_type; + //! The allocator type + typedef A allocator_type; + //! The stored allocator type + typedef NodeAlloc stored_allocator_type; + + /// @cond + private: + typedef difference_type list_difference_type; + typedef pointer list_pointer; + typedef const_pointer list_const_pointer; + typedef reference list_reference; + typedef const_reference list_const_reference; + /// @endcond + + public: + //! Const iterator used to iterate through a list. + class const_iterator + /// @cond + : public std::iterator + { + + protected: + typename Icont::iterator m_it; + explicit const_iterator(typename Icont::iterator it) : m_it(it){} + void prot_incr() { ++m_it; } + void prot_decr() { --m_it; } + + private: + typename Icont::iterator get() + { return this->m_it; } + + public: + friend class list; + typedef list_difference_type difference_type; + + //Constructors + const_iterator() + : m_it() + {} + + //Pointer like operators + const_reference operator*() const + { return m_it->m_data; } + + const_pointer operator->() const + { return const_pointer(&m_it->m_data); } + + //Increment / Decrement + const_iterator& operator++() + { prot_incr(); return *this; } + + const_iterator operator++(int) + { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); } + + const_iterator& operator--() + { prot_decr(); return *this; } + + const_iterator operator--(int) + { typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); } + + //Comparison operators + bool operator== (const const_iterator& r) const + { return m_it == r.m_it; } + + bool operator!= (const const_iterator& r) const + { return m_it != r.m_it; } + } + /// @endcond + ; + + //! Iterator used to iterate through a list + class iterator + /// @cond + : public const_iterator + { + + private: + explicit iterator(typename Icont::iterator it) + : const_iterator(it) + {} + + typename Icont::iterator get() + { return this->m_it; } + + public: + friend class list; + typedef list_pointer pointer; + typedef list_reference reference; + + //Constructors + iterator(){} + + //Pointer like operators + reference operator*() const { return this->m_it->m_data; } + pointer operator->() const { return pointer(&this->m_it->m_data); } + + //Increment / Decrement + iterator& operator++() + { this->prot_incr(); return *this; } + + iterator operator++(int) + { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); } + + iterator& operator--() + { this->prot_decr(); return *this; } + + iterator operator--(int) + { iterator tmp = *this; --*this; return tmp; } + } + /// @endcond + ; + + //! Iterator used to iterate backwards through a list. + typedef std::reverse_iterator reverse_iterator; + //! Const iterator used to iterate backwards through a list. + typedef std::reverse_iterator const_reverse_iterator; + + //! Effects: Constructs a list taking the allocator as parameter. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + explicit list(const allocator_type &a = A()) + : AllocHolder(a) + {} + +// list(size_type n) +// : AllocHolder(move(allocator_type())) +// { this->resize(n); } + + //! Effects: Constructs a list that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + list(size_type n, const T& value = T(), const A& a = A()) + : AllocHolder(a) + { this->insert(begin(), n, value); } + + //! Effects: Copy constructs a list. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocator_type's default constructor or copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + list(const list& x) + : AllocHolder(x) + { this->insert(begin(), x.begin(), x.end()); } + + //! Effects: Move constructor. Moves mx's resources to *this. + //! + //! Throws: If allocator_type's default constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + list(const detail::moved_object &x) + : AllocHolder(move((AllocHolder&)x.get())) + {} + #else + list(list &&x) + : AllocHolder(move((AllocHolder&)x)) + {} + #endif + + //! Effects: Constructs a list that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the list. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's constructor taking an dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + list(InpIt first, InpIt last, const A &a = A()) + : AllocHolder(a) + { insert(begin(), first, last); } + + //! Effects: Destroys the list. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~list() + { this->clear(); } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return allocator_type(this->node_alloc()); } + + const stored_allocator_type &get_stored_allocator() const + { return this->node_alloc(); } + + stored_allocator_type &get_stored_allocator() + { return this->node_alloc(); } + + //! Effects: Erases all the elements of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the list. + void clear() + { AllocHolder::clear(alloc_version()); } + + //! Effects: Returns an iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return iterator(this->icont().begin()); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return const_iterator(this->non_const_icont().begin()); } + + //! Effects: Returns an iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return iterator(this->icont().end()); } + + //! Effects: Returns a const_iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return const_iterator(this->non_const_icont().end()); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + //! Effects: Returns true if the list contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return !this->size(); } + + //! Effects: Returns the number of the elements contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return this->icont().size(); } + + //! Effects: Returns the largest possible size of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return AllocHolder::max_size(); } + + //! Effects: Inserts a copy of t in the beginning of the list. + //! + //! Throws: If memory allocation throws or + //! T's copy constructor throws. + //! + //! Complexity: Amortized constant time. + void push_front(const T& x) + { this->insert(this->begin(), x); } + + //! Effects: Constructs a new element in the beginning of the list + //! and moves the resources of t to this new element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_front(const detail::moved_object& x) + { this->insert(this->begin(), x); } + #else + void push_front(T &&x) + { this->insert(this->begin(), move(x)); } + #endif + + //! Effects: Removes the last element from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + void push_back (const T& x) + { this->insert(this->end(), x); } + + //! Effects: Removes the first element from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_back (const detail::moved_object& x) + { this->insert(this->end(), x); } + #else + void push_back (T &&x) + { this->insert(this->end(), move(x)); } + #endif + + //! Effects: Removes the first element from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + void pop_front() + { this->erase(this->begin()); } + + //! Effects: Removes the last element from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + void pop_back() + { iterator tmp = this->end(); this->erase(--tmp); } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() + { return *this->begin(); } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const + { return *this->begin(); } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference back() + { return *(--this->end()); } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference back() const + { return *(--this->end()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size, const T& x) + { + iterator i = this->begin(), iend = this->end(); + size_type len = this->size(); + + if(len > new_size){ + size_type to_erase = len - new_size; + while(to_erase--){ + --iend; + } + this->erase(iend, this->end()); + } + else{ + this->priv_create_and_insert_nodes(iend, new_size - len, x); + } + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default constructed. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size) + { + iterator i = this->begin(), iend = this->end(); + size_type len = this->size(); + + if(len > new_size){ + size_type to_erase = len - new_size; + while(to_erase--){ + --iend; + } + this->erase(iend, this->end()); + } + else{ + this->priv_create_and_insert_nodes(this->end(), new_size - len); + } + } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() + //! allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(ThisType& x) + { AllocHolder::swap(x); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() + //! allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //void swap(const detail::moved_object& x) + //{ this->swap(x.get()); } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to the number of elements in x. + ThisType& operator=(const ThisType& x) + { + if (this != &x) { + this->assign(x.begin(), x.end()); + } + return *this; + } + + //! Effects: Move assignment. All mx's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + ThisType& operator=(const detail::moved_object& mx) + { + this->clear(); + this->swap(mx.get()); + return *this; + } + #else + ThisType& operator=(ThisType &&mx) + { + this->clear(); + this->swap(mx); + return *this; + } + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Inserts n copies of x before p. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + void insert(iterator p, size_type n, const T& x) + { this->priv_create_and_insert_nodes(p, n, x); } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before p. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws. + //! + //! Complexity: Linear to std::distance [first, last). + template + void insert(iterator p, InpIt first, InpIt last) + { + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_insert_dispatch(p, first, last, Result()); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before p. + //! + //! Throws: If memory allocation throws or x's copy constructor throws. + //! + //! Complexity: Amortized constant time. + iterator insert(iterator p, const T& x) + { + NodePtr tmp = AllocHolder::create_node(x); + return iterator(this->icont().insert(p.get(), *tmp)); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a new element before p with mx's resources. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator p, const detail::moved_object& x) + { + NodePtr tmp = AllocHolder::create_node(x); + return iterator(this->icont().insert(p.get(), *tmp)); + } + #else + iterator insert(iterator p, T &&x) + { + NodePtr tmp = AllocHolder::create_node(move(x)); + return iterator(this->icont().insert(p.get(), *tmp)); + } + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Erases the element at p p. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + iterator erase(iterator p) + { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); } + + //! Requires: first and last must be valid iterator to elements in *this. + //! + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last. + iterator erase(iterator first, iterator last) + { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); } + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + void assign(size_type n, const T& val) + { this->priv_fill_assign(n, val); } + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(InpIt first, InpIt last) + { + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_assign_dispatch(first, last, Result()); + } + + //! Requires: p must point to an element contained + //! by the list. x != *this + //! + //! Effects: Transfers all the elements of list x to this list, before the + //! the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of + //! this list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, ThisType& x) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice(p.get(), x.icont()); + } + else{ + throw std::runtime_error("list::splice called with unequal allocators"); + } + } + +// void splice(iterator p, const detail::moved_object& x) +// { this->splice(p, x.get()); } + + //! Requires: p must point to an element contained + //! by this list. i must point to an element contained in list x. + //! + //! Effects: Transfers the value pointed by i, from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! If p == i or p == ++i, this function is a null operation. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, ThisType &x, iterator i) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice(p.get(), x.icont(), i.get()); + } + else{ + throw std::runtime_error("list::splice called with unequal allocators"); + } + } + +// void splice(iterator p, const detail::moved_object &x, iterator i) +// { this->splice(p, x.get(), i); } + + //! Requires: p must point to an element contained + //! by this list. first and last must point to elements contained in list x. + //! + //! Effects: Transfers the range pointed by first and last from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear to the number of elements transferred. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, ThisType &x, iterator first, iterator last) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice(p.get(), x.icont(), first.get(), last.get()); + } + else{ + throw std::runtime_error("list::splice called with unequal allocators"); + } + } + +// void splice(iterator p, detail::moved_object &x, iterator first, iterator last) +// { return this->splice(p, x.get(), first, last); } + + //! Requires: p must point to an element contained + //! by this list. first and last must point to elements contained in list x. + //! n == std::distance(first, last) + //! + //! Effects: Transfers the range pointed by first and last from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, ThisType &x, iterator first, iterator last, size_type n) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n); + } + else{ + throw std::runtime_error("list::splice called with unequal allocators"); + } + } + +// void splice(iterator p, detail::moved_object &x, iterator first, iterator last, size_type n) +// { return this->splice(p, x.get(), first, last, n); } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + //! + //! Note: Iterators and references are not invalidated + void reverse() + { this->icont().reverse(); } + + //! Effects: Removes all the elements that compare equal to value. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void remove(const T& value) + { remove_if(equal_to_value(value)); } + + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. + //! + //! Throws: If pred throws. + //! + //! Complexity: Linear time. It performs exactly size() calls to the predicate. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_if(Pred pred) + { + typedef ValueCompareToNodeCompare Predicate; + this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc())); + } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear time (size()-1 comparisons calls to pred()). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void unique() + { this->unique(value_equal()); } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! + //! Throws: If pred throws. + //! + //! Complexity: Linear time (size()-1 comparisons equality comparisons). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique(BinaryPredicate binary_pred) + { + typedef ValueCompareToNodeCompare Predicate; + this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc())); + } + + //! Requires: The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this according to std::less. The merge is stable; + //! that is, if an element from *this is equivalent to one from x, then the element + //! from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + void merge(list& x) + { this->merge(x, value_less()); } + + //! Effects: This function removes all of moved mx's elements and inserts them + //! in order into *this according to std::less. The merge is stable; + //! that is, if an element from *this is equivalent to one from x, then the element + //! from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references to *this are not invalidated. + //void merge(const detail::moved_object >& x) + //{ this->merge(x.get()); } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references to *this are not invalidated. + template + void merge(list& x, StrictWeakOrdering comp) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().merge(x.icont(), + ValueCompareToNodeCompare(comp)); + } + else{ + throw std::runtime_error("list::merge called with unequal allocators"); + } + } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of moved mx's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references to *this are not invalidated. + //template + //void merge(const detail::moved_object >& x, StrictWeakOrdering comp) + //{ return this->merge(x.get(), comp); } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: Nothing. + //! + //! Notes: Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + void sort() + { this->sort(value_less()); } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: Nothing. + //! + //! Notes: Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + template + void sort(StrictWeakOrdering comp) + { + // nothing if the list has length 0 or 1. + if (this->size() < 2) + return; + this->icont().sort(ValueCompareToNodeCompare(comp)); + } + + /// @cond + private: + + //Iterator range version + template + void priv_create_and_insert_nodes + (const_iterator pos, InpIterator beg, InpIterator end) + { + typedef typename std::iterator_traits::iterator_category ItCat; + priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat()); + } + + template + void priv_create_and_insert_nodes + (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag) + { + for (; beg != end; ++beg){ + this->icont().insert(pos.get(), *this->create_node_from_it(beg)); + } + } + + template + void priv_create_and_insert_nodes + (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag) + { //Just forward to the default one + priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag()); + } + + class insertion_functor; + friend class insertion_functor; + + class insertion_functor + { + Icont &icont_; + typename Icont::iterator pos_; + + public: + insertion_functor(Icont &icont, typename Icont::iterator pos) + : icont_(icont), pos_(pos) + {} + + void operator()(Node &n) + { this->icont_.insert(pos_, n); } + }; + + + template + void priv_create_and_insert_nodes + (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag) + { + //Optimized allocation and construction + this->allocate_many_and_construct + (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get())); + } + + //Default constructed version + void priv_create_and_insert_nodes(const_iterator pos, size_type n) + { + typedef default_construct_iterator default_iterator; + this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator()); + } + + //Copy constructed version + void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x) + { + typedef constant_iterator cvalue_iterator; + this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator()); + } + + //Dispatch to detect iterator range or integer overloads + template + void priv_insert_dispatch(iterator p, + InputIter first, InputIter last, + detail::false_) + { this->priv_create_and_insert_nodes(p, first, last); } + + template + void priv_insert_dispatch(iterator p, Integer n, Integer x, detail::true_) + { this->insert(p, (size_type)n, x); } + + void priv_fill_assign(size_type n, const T& val) + { + iterator i = this->begin(), iend = this->end(); + + for ( ; i != iend && n > 0; ++i, --n) + *i = val; + if (n > 0){ + this->priv_create_and_insert_nodes(this->end(), n, val); + } + else{ + this->erase(i, end()); + } + } + + template + void priv_assign_dispatch(Integer n, Integer val, detail::true_) + { this->priv_fill_assign((size_type) n, (T) val); } + + template + void priv_assign_dispatch(InputIter first2, InputIter last2, + detail::false_) + { + iterator first1 = this->begin(); + iterator last1 = this->end(); + for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) + *first1 = *first2; + if (first2 == last2) + this->erase(first1, last1); + else{ + this->priv_create_and_insert_nodes(last1, first2, last2); + } + } + + //Functors for member algorithm defaults + struct value_less + { + bool operator()(const value_type &a, const value_type &b) const + { return a < b; } + }; + + struct value_equal + { + bool operator()(const value_type &a, const value_type &b) const + { return a == b; } + }; + /// @endcond + +}; + +template +inline bool operator==(const list& x, const list& y) +{ + if(x.size() != y.size()){ + return false; + } + typedef typename list::const_iterator const_iterator; + const_iterator end1 = x.end(); + + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; +} + +template +inline bool operator<(const list& x, + const list& y) +{ + return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +inline bool operator!=(const list& x, const list& y) +{ + return !(x == y); +} + +template +inline bool operator>(const list& x, const list& y) +{ + return y < x; +} + +template +inline bool operator<=(const list& x, const list& y) +{ + return !(y < x); +} + +template +inline bool operator>=(const list& x, const list& y) +{ + return !(x < y); +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(list& x, list& y) +{ + x.swap(y); +} + +template +inline void swap(const detail::moved_object >& x, list& y) +{ + x.get().swap(y); +} + +template +inline void swap(list& x, const detail::moved_object >& y) +{ + x.swap(y.get()); +} +#else +template +inline void swap(list &&x, list &&y) +{ + x.swap(y); +} + +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; +/* +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; +*/ +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = has_trivial_destructor::value }; +}; +/// @endcond + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif // BOOST_INTERPROCESS_LIST_HPP_ diff --git a/thirdparty/boost/interprocess/containers/map.hpp b/thirdparty/boost/interprocess/containers/map.hpp new file mode 100644 index 0000000..cbd3adf --- /dev/null +++ b/thirdparty/boost/interprocess/containers/map.hpp @@ -0,0 +1,1241 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_map/stl_multimap files. Modified by Ion Gazta�ga 2004. +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_INTERPROCESS_MAP_HPP +#define BOOST_INTERPROCESS_MAP_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace interprocess { + +/// @cond +// Forward declarations of operators == and <, needed for friend declarations. +template +inline bool operator==(const map& x, + const map& y); + +template +inline bool operator<(const map& x, + const map& y); +/// @endcond + +//! A map is a kind of associative container that supports unique keys (contains at +//! most one of each key value) and provides for fast retrieval of values of another +//! type T based on the keys. The map class supports bidirectional iterators. +//! +//! A map satisfies all of the requirements of a container and of a reversible +//! container and of an associative container. For a +//! map the key_type is Key and the value_type is std::pair. +//! +//! Pred is the ordering function for Keys (e.g. std::less). +//! +//! Alloc is the allocator to allocate the value_types +//! (e.g. boost::interprocess:allocator< std::pair). +template +class map +{ + /// @cond + private: + typedef detail::rbtree, + detail::select1st< std::pair >, + Pred, + Alloc> tree_t; + tree_t m_tree; // red-black tree representing map + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef T mapped_type; + typedef Pred key_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + /// @cond + class value_compare_impl + : public Pred, + public std::binary_function + { + friend class map; + protected : + value_compare_impl(const Pred &c) : Pred(c) {} + public: + bool operator()(const value_type& x, const value_type& y) const { + return Pred::operator()(x.first, y.first); + } + }; + /// @endcond + typedef value_compare_impl value_compare; + + //! Effects: Constructs an empty map using the specified comparison object + //! and allocator. + //! + //! Complexity: Constant. + explicit map(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(comp, a) + {} + + //! Effects: Constructs an empty map using the specified comparison object and + //! allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + map(InputIterator first, InputIterator last, const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(first, last, comp, a, true) + {} + + //! Effects: Copy constructs a map. + //! + //! Complexity: Linear in x.size(). + map(const map& x) + : m_tree(x.m_tree) + {} + + //! Effects: Move constructs a map. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + map(const detail::moved_object >& x) + : m_tree(move(x.get().m_tree)) + {} + #else + map(map &&x) + : m_tree(move(x.m_tree)) + {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + map& operator=(const map& x) + { m_tree = x.m_tree; return *this; } + + //! Effects: this->swap(x.get()). + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + map& operator=(const detail::moved_object >& x) + { m_tree = move(x.get().m_tree); return *this; } + #else + map& operator=(map &&x) + { m_tree = move(x.m_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(m_tree.key_comp()); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the objects constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_tree.max_size(); } + + //! Effects: If there is no key equivalent to x in the map, inserts + //! value_type(x, T()) into the map. + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + T& operator[](const key_type& k) + { + //we can optimize this + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)){ + value_type val(k, move(T())); + i = insert(i, move(val)); + } + return (*i).second; + } + + //! Effects: If there is no key equivalent to x in the map, inserts + //! value_type(move(x), T()) into the map (the key is move-constructed) + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + T& operator[](const detail::moved_object& mk) + { + key_type &k = mk.get(); + //we can optimize this + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)){ + value_type val(k, move(T())); + i = insert(i, move(val)); + } + return (*i).second; + } + #else + T& operator[](key_type &&mk) + { + key_type &k = mk; + //we can optimize this + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)){ + value_type val(move(k), move(T())); + i = insert(i, move(val)); + } + return (*i).second; + } + #endif + +/* + //! Effects: If there is no key equivalent to x in the map, inserts + //! value_type(move(x), T()) into the map (the key is move-constructed) + //! + //! Returns: A reference to the mapped_type corresponding to x in *this. + //! + //! Complexity: Logarithmic. + T& at(const key_type& x) + { + if(this->find(x) == this->end()){ + + } + key_type &k = mk.get(); + //we can optimize this + iterator i = lower_bound(k); + // i->first is greater than or equivalent to k. + if (i == end() || key_comp()(k, (*i).first)){ + value_type val(k, move(T())); + i = insert(i, move(val)); + } + return (*i).second; + } + +//; +//const T& at(const key_type& x) const; +//4 Returns: A reference to the element whose key is equivalent to x. +//5 Throws: An exception object of type out_of_range if no such element is present. +*/ + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(map& x) + { m_tree.swap(x.m_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_tree.swap(x.get().m_tree); } + #else + void swap(map &&x) + { m_tree.swap(x.m_tree); } + #endif + + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + std::pair insert(const value_type& x) + { return m_tree.insert_unique(x); } + + //! Effects: Inserts a new value_type created from the pair if and only if + //! there is no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + std::pair insert(const std::pair& x) + { return m_tree.insert_unique(x); } + + //! Effects: Inserts a new value_type move constructed from the pair if and + //! only if there is no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert(const detail::moved_object > &x) + { return m_tree.insert_unique(x); } + #else + std::pair insert(std::pair &&x) + { return m_tree.insert_unique(move(x)); } + #endif + + //! Effects: Move constructs a new value from x if and only if there is + //! no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert(const detail::moved_object& x) + { return m_tree.insert_unique(x); } + #else + std::pair insert(value_type &&x) + { return m_tree.insert_unique(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(iterator position, const value_type& x) + { return m_tree.insert_unique(position, x); } + + //! Effects: Move constructs a new value from x if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object > &x) + { return m_tree.insert_unique(position, x); } + #else + iterator insert(iterator position, std::pair &&x) + { return m_tree.insert_unique(position, move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + iterator insert(iterator position, const std::pair& x) + { return m_tree.insert_unique(position, x); } + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object& x) + { return m_tree.insert_unique(position, x); } + #else + iterator insert(iterator position, value_type &&x) + { return m_tree.insert_unique(position, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_unique(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Amortized constant time + iterator erase(const_iterator position) + { return m_tree.erase(position); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: log(size()) + count(k) + size_type erase(const key_type& x) + { return m_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: log(size())+N where N is the distance from first to last. + iterator erase(const_iterator first, const_iterator last) + { return m_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_tree.clear(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_tree.find(x); } + + //! Returns: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const + { return m_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_tree.find(x) == m_tree.end() ? 0 : 1; } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return m_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_tree.upper_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) + { return m_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) const + { return m_tree.equal_range(x); } + + /// @cond + template + friend bool operator== (const map&, + const map&); + template + friend bool operator< (const map&, + const map&); + /// @endcond +}; + +template +inline bool operator==(const map& x, + const map& y) + { return x.m_tree == y.m_tree; } + +template +inline bool operator<(const map& x, + const map& y) + { return x.m_tree < y.m_tree; } + +template +inline bool operator!=(const map& x, + const map& y) + { return !(x == y); } + +template +inline bool operator>(const map& x, + const map& y) + { return y < x; } + +template +inline bool operator<=(const map& x, + const map& y) + { return !(y < x); } + +template +inline bool operator>=(const map& x, + const map& y) + { return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(map& x, + map& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + map& y) + { x.get().swap(y); } + +template +inline void swap(map& x, + const detail::moved_object >& y) + { x.swap(y.get()); } +#else +template +inline void swap(map&&x, + map&&y) + { x.swap(y); } +#endif + + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +// Forward declaration of operators < and ==, needed for friend declaration. + +template +inline bool operator==(const multimap& x, + const multimap& y); + +template +inline bool operator<(const multimap& x, + const multimap& y); + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; +/// @endcond + +//! A multimap is a kind of associative container that supports equivalent keys +//! (possibly containing multiple copies of the same key value) and provides for +//! fast retrieval of values of another type T based on the keys. The multimap class +//! supports bidirectional iterators. +//! +//! A multimap satisfies all of the requirements of a container and of a reversible +//! container and of an associative container. For a +//! map the key_type is Key and the value_type is std::pair. +//! +//! Pred is the ordering function for Keys (e.g. std::less). +//! +//! Alloc is the allocator to allocate the value_types +//!(e.g. boost::interprocess:allocator< std::pair<const Key, T>). +template +class multimap +{ + /// @cond + private: + typedef detail::rbtree, + detail::select1st< std::pair >, + Pred, + Alloc> tree_t; + tree_t m_tree; // red-black tree representing map + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef T mapped_type; + typedef Pred key_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + /// @cond + class value_compare_impl + : public Pred, + public std::binary_function + { + friend class multimap; + protected : + value_compare_impl(const Pred &c) : Pred(c) {} + public: + bool operator()(const value_type& x, const value_type& y) const { + return Pred::operator()(x.first, y.first); + } + }; + /// @endcond + typedef value_compare_impl value_compare; + + //! Effects: Constructs an empty multimap using the specified comparison + //! object and allocator. + //! + //! Complexity: Constant. + explicit multimap(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(comp, a) + {} + + //! Effects: Constructs an empty multimap using the specified comparison object + //! and allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + multimap(InputIterator first, InputIterator last, + const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(first, last, comp, a, false) + {} + + //! Effects: Copy constructs a multimap. + //! + //! Complexity: Linear in x.size(). + multimap(const multimap& x) + : m_tree(x.m_tree) + {} + + //! Effects: Move constructs a multimap. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + multimap(const detail::moved_object >& x) + : m_tree(move(x.get().m_tree)) + {} + #else + multimap(multimap && x) + : m_tree(move(x.m_tree)) + {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + multimap& + operator=(const multimap& x) + { m_tree = x.m_tree; return *this; } + + //! Effects: this->swap(x.get()). + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + multimap& + operator=(const detail::moved_object >& x) + { m_tree = move(x.get().m_tree); return *this; } + #else + multimap& + operator=(multimap && x) + { m_tree = move(x.m_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(m_tree.key_comp()); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the objects constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(multimap& x) + { m_tree.swap(x.m_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_tree.swap(x.get().m_tree); } + #else + void swap(multimap && x) + { m_tree.swap(x.m_tree); } + #endif + + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const value_type& x) + { return m_tree.insert_equal(x); } + + //! Effects: Inserts a new value constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const std::pair& x) + { return m_tree.insert_equal(x); } + + //! Effects: Inserts a new value move-constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const detail::moved_object >& x) + { return m_tree.insert_equal(x); } + #else + iterator insert(std::pair && x) + { return m_tree.insert_equal(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(iterator position, const value_type& x) + { return m_tree.insert_equal(position, x); } + + //! Effects: Inserts a new value constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(iterator position, const std::pair& x) + { return m_tree.insert_equal(position, x); } + + //! Effects: Inserts a new value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object >& x) + { return m_tree.insert_equal(position, x); } + #else + iterator insert(iterator position, std::pair && x) + { return m_tree.insert_equal(position, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) . + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_equal(first, last); } + + //! Effects: Erases the element pointed to by position. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Amortized constant time + iterator erase(const_iterator position) + { return m_tree.erase(position); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: log(size()) + count(k) + size_type erase(const key_type& x) + { return m_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: log(size())+N where N is the distance from first to last. + iterator erase(const_iterator first, const_iterator last) + { return m_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_tree.clear(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_tree.find(x); } + + //! Returns: A const iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const + { return m_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_tree.count(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + {return m_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) + { return m_tree.equal_range(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return m_tree.equal_range(x); } + + /// @cond + template + friend bool operator== (const multimap& x, + const multimap& y); + + template + friend bool operator< (const multimap& x, + const multimap& y); + /// @endcond +}; + +template +inline bool operator==(const multimap& x, + const multimap& y) +{ return x.m_tree == y.m_tree; } + +template +inline bool operator<(const multimap& x, + const multimap& y) +{ return x.m_tree < y.m_tree; } + +template +inline bool operator!=(const multimap& x, + const multimap& y) +{ return !(x == y); } + +template +inline bool operator>(const multimap& x, + const multimap& y) +{ return y < x; } + +template +inline bool operator<=(const multimap& x, + const multimap& y) +{ return !(y < x); } + +template +inline bool operator>=(const multimap& x, + const multimap& y) +{ return !(x < y); } + + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(multimap& x, + multimap& y) +{ x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, + multimap& y) +{ x.get().swap(y); } + +template +inline void swap(multimap& x, + const detail::moved_object >& y) +{ x.swap(y.get()); } +#else +template +inline void swap(multimap&&x, + multimap&&y) +{ x.swap(y); } +#endif + +/// @cond +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_MAP_HPP */ + diff --git a/thirdparty/boost/interprocess/containers/set.hpp b/thirdparty/boost/interprocess/containers/set.hpp new file mode 100644 index 0000000..68a62f6 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/set.hpp @@ -0,0 +1,1043 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_set/stl_multiset files. Modified by Ion Gaztanaga 2004. +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_INTERPROCESS_SET_HPP +#define BOOST_INTERPROCESS_SET_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { namespace interprocess { + +/// @cond +// Forward declarations of operators < and ==, needed for friend declaration. +template +inline bool operator==(const set& x, + const set& y); + +template +inline bool operator<(const set& x, + const set& y); +/// @endcond + +//! A set is a kind of associative container that supports unique keys (contains at +//! most one of each key value) and provides for fast retrieval of the keys themselves. +//! Class set supports bidirectional iterators. +//! +//! A set satisfies all of the requirements of a container and of a reversible container +//! , and of an associative container. A set also provides most operations described in +//! for unique keys. +template +class set +{ + /// @cond + private: + typedef detail::rbtree, Pred, Alloc> tree_t; + tree_t m_tree; // red-black tree representing set + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef Pred key_compare; + typedef Pred value_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + //! Effects: Constructs an empty set using the specified comparison object + //! and allocator. + //! + //! Complexity: Constant. + explicit set(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(comp, a) + {} + + //! Effects: Constructs an empty set using the specified comparison object and + //! allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + set(InputIterator first, InputIterator last, const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(first, last, comp, a, true) + {} + + //! Effects: Copy constructs a set. + //! + //! Complexity: Linear in x.size(). + set(const set& x) + : m_tree(x.m_tree) + {} + + //! Effects: Move constructs a set. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + set(const detail::moved_object >& x) + : m_tree(move(x.get().m_tree)) + {} + #else + set(set &&x) + : m_tree(move(x.m_tree)) + {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + set& operator=(const set& x) + { m_tree = x.m_tree; return *this; } + + //! Effects: this->swap(x.get()). + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + set& operator=(const detail::moved_object >& x) + { m_tree = move(x.get().m_tree); return *this; } + #else + set& operator=(set &&x) + { m_tree = move(x.m_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant + iterator begin() + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(set& x) + { m_tree.swap(x.m_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_tree.swap(x.get().m_tree); } + #else + void swap(set &&x) + { m_tree.swap(x.m_tree); } + #endif + + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + std::pair insert(const value_type& x) + { return m_tree.insert_unique(x); } + + //! Effects: Move constructs a new value from x if and only if there is + //! no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + std::pair insert(const detail::moved_object& x) + { return m_tree.insert_unique(x); } + #else + std::pair insert(value_type &&x) + { return m_tree.insert_unique(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator p, const value_type& x) + { return m_tree.insert_unique(p, x); } + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const_iterator p, const detail::moved_object& x) + { return m_tree.insert_unique(p, x); } + #else + iterator insert(const_iterator p, value_type &&x) + { return m_tree.insert_unique(p, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_unique(first, last); } + + //! Effects: Erases the element pointed to by p. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Amortized constant time + iterator erase(const_iterator p) + { return m_tree.erase(p); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: log(size()) + count(k) + size_type erase(const key_type& x) + { return m_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: log(size())+N where N is the distance from first to last. + iterator erase(const_iterator first, const_iterator last) + { return m_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_tree.clear(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_tree.find(x); } + + //! Returns: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const + { return m_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_tree.find(x) == m_tree.end() ? 0 : 1; } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return m_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_tree.upper_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) + { return m_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return m_tree.equal_range(x); } + + /// @cond + template + friend bool operator== (const set&, const set&); + + template + friend bool operator< (const set&, const set&); + /// @endcond +}; + +template +inline bool operator==(const set& x, + const set& y) +{ return x.m_tree == y.m_tree; } + +template +inline bool operator<(const set& x, + const set& y) +{ return x.m_tree < y.m_tree; } + +template +inline bool operator!=(const set& x, + const set& y) +{ return !(x == y); } + +template +inline bool operator>(const set& x, + const set& y) +{ return y < x; } + +template +inline bool operator<=(const set& x, + const set& y) +{ return !(y < x); } + +template +inline bool operator>=(const set& x, + const set& y) +{ return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(set& x, + set& y) +{ x.swap(y); } + +template +inline void swap(set& x, + detail::moved_object >& y) +{ x.swap(y.get()); } + +template +inline void swap(detail::moved_object >& y, + set& x) +{ y.swap(x.get()); } + +#else +template +inline void swap(set&&x, + set&&y) +{ x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; + +// Forward declaration of operators < and ==, needed for friend declaration. + +template +inline bool operator==(const multiset& x, + const multiset& y); + +template +inline bool operator<(const multiset& x, + const multiset& y); +/// @endcond + +//! A multiset is a kind of associative container that supports equivalent keys +//! (possibly contains multiple copies of the same key value) and provides for +//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators. +//! +//! A multiset satisfies all of the requirements of a container and of a reversible +//! container, and of an associative container). multiset also provides most operations +//! described for duplicate keys. +template +class multiset +{ + /// @cond + private: + typedef detail::rbtree, Pred, Alloc> tree_t; + tree_t m_tree; // red-black tree representing multiset + /// @endcond + + public: + // typedefs: + typedef typename tree_t::key_type key_type; + typedef typename tree_t::value_type value_type; + typedef typename tree_t::pointer pointer; + typedef typename tree_t::const_pointer const_pointer; + typedef typename tree_t::reference reference; + typedef typename tree_t::const_reference const_reference; + typedef Pred key_compare; + typedef Pred value_compare; + typedef typename tree_t::iterator iterator; + typedef typename tree_t::const_iterator const_iterator; + typedef typename tree_t::reverse_iterator reverse_iterator; + typedef typename tree_t::const_reverse_iterator const_reverse_iterator; + typedef typename tree_t::size_type size_type; + typedef typename tree_t::difference_type difference_type; + typedef typename tree_t::allocator_type allocator_type; + typedef typename tree_t::stored_allocator_type stored_allocator_type; + + //! Effects: Constructs an empty multiset using the specified comparison + //! object and allocator. + //! + //! Complexity: Constant. + explicit multiset(const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(comp, a) + {} + + //! Effects: Constructs an empty multiset using the specified comparison object + //! and allocator, and inserts elements from the range [first ,last ). + //! + //! Complexity: Linear in N if the range [first ,last ) is already sorted using + //! comp and otherwise N logN, where N is last - first. + template + multiset(InputIterator first, InputIterator last, + const Pred& comp = Pred(), + const allocator_type& a = allocator_type()) + : m_tree(first, last, comp, a, false) + {} + + //! Effects: Copy constructs a multiset. + //! + //! Complexity: Linear in x.size(). + multiset(const multiset& x) + : m_tree(x.m_tree) + {} + + //! Effects: Move constructs a multiset. Constructs *this using x's resources. + //! + //! Complexity: Construct. + //! + //! Postcondition: x is emptied. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + multiset(const detail::moved_object >& x) + : m_tree(move(x.get().m_tree)) + {} + #else + multiset(multiset &&x) + : m_tree(move(x.m_tree)) + {} + #endif + + //! Effects: Makes *this a copy of x. + //! + //! Complexity: Linear in x.size(). + multiset& operator=(const multiset& x) + { m_tree = x.m_tree; return *this; } + + //! Effects: this->swap(x.get()). + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + multiset& operator=(const detail::moved_object >& x) + { m_tree = move(x.get().m_tree); return *this; } + #else + multiset& operator=(multiset &&x) + { m_tree = move(x.m_tree); return *this; } + #endif + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns a copy of the Allocator that + //! was passed to the object’s constructor. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return m_tree.get_allocator(); } + + const stored_allocator_type &get_stored_allocator() const + { return m_tree.get_stored_allocator(); } + + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns an iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return m_tree.begin(); } + + //! Effects: Returns an iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return m_tree.end(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return m_tree.end(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return m_tree.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return m_tree.rbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return m_tree.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return m_tree.rend(); } + + //! Effects: Returns true if the container contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return m_tree.empty(); } + + //! Effects: Returns the number of the elements contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return m_tree.size(); } + + //! Effects: Returns the largest possible size of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return m_tree.max_size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(multiset& x) + { m_tree.swap(x.m_tree); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& x) + { m_tree.swap(x.get().m_tree); } + #else + void swap(multiset && x) + { m_tree.swap(x.m_tree); } + #endif + + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const value_type& x) + { return m_tree.insert_equal(x); } + + //! Effects: Inserts a copy of x in the container. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const detail::moved_object& x) + { return m_tree.insert_equal(x); } + #else + iterator insert(value_type && x) + { return m_tree.insert_equal(move(x)); } + #endif + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator p, const value_type& x) + { return m_tree.insert_equal(p, x); } + + //! Effects: Inserts a value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(const_iterator p, const detail::moved_object& x) + { return m_tree.insert_equal(p, x); } + #else + iterator insert(const_iterator p, value_type && x) + { return m_tree.insert_equal(p, move(x)); } + #endif + + //! Requires: i, j are not iterators into *this. + //! + //! Effects: inserts each element from the range [i,j) . + //! + //! Complexity: N log(size()+N) (N is the distance from i to j) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_equal(first, last); } + + //! Effects: Erases the element pointed to by p. + //! + //! Returns: Returns an iterator pointing to the element immediately + //! following q prior to the element being erased. If no such element exists, + //! returns end(). + //! + //! Complexity: Amortized constant time + iterator erase(const_iterator p) + { return m_tree.erase(p); } + + //! Effects: Erases all elements in the container with key equivalent to x. + //! + //! Returns: Returns the number of erased elements. + //! + //! Complexity: log(size()) + count(k) + size_type erase(const key_type& x) + { return m_tree.erase(x); } + + //! Effects: Erases all the elements in the range [first, last). + //! + //! Returns: Returns last. + //! + //! Complexity: log(size())+N where N is the distance from first to last. + iterator erase(const_iterator first, const_iterator last) + { return m_tree.erase(first, last); } + + //! Effects: erase(a.begin(),a.end()). + //! + //! Postcondition: size() == 0. + //! + //! Complexity: linear in size(). + void clear() + { m_tree.clear(); } + + //! Returns: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + iterator find(const key_type& x) + { return m_tree.find(x); } + + //! Returns: A const iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const + { return m_tree.find(x); } + + //! Returns: The number of elements with key equivalent to x. + //! + //! Complexity: log(size())+count(k) + size_type count(const key_type& x) const + { return m_tree.count(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator lower_bound(const key_type& x) + { return m_tree.lower_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than k, or a.end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator lower_bound(const key_type& x) const + { return m_tree.lower_bound(x); } + + //! Returns: An iterator pointing to the first element with key not less + //! than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + iterator upper_bound(const key_type& x) + { return m_tree.upper_bound(x); } + + //! Returns: A const iterator pointing to the first element with key not + //! less than x, or end() if such an element is not found. + //! + //! Complexity: Logarithmic + const_iterator upper_bound(const key_type& x) const + { return m_tree.upper_bound(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) + { return m_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair + equal_range(const key_type& x) const + { return m_tree.equal_range(x); } + + /// @cond + template + friend bool operator== (const multiset&, + const multiset&); + template + friend bool operator< (const multiset&, + const multiset&); + /// @endcond +}; + +template +inline bool operator==(const multiset& x, + const multiset& y) +{ return x.m_tree == y.m_tree; } + +template +inline bool operator<(const multiset& x, + const multiset& y) +{ return x.m_tree < y.m_tree; } + +template +inline bool operator!=(const multiset& x, + const multiset& y) +{ return !(x == y); } + +template +inline bool operator>(const multiset& x, + const multiset& y) +{ return y < x; } + +template +inline bool operator<=(const multiset& x, + const multiset& y) +{ return !(y < x); } + +template +inline bool operator>=(const multiset& x, + const multiset& y) +{ return !(x < y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(multiset& x, + multiset& y) +{ x.swap(y); } + +template +inline void swap(multiset& x, + detail::moved_object >& y) +{ x.swap(y.get()); } + +template +inline void swap(detail::moved_object >& y, + multiset& x) +{ y.swap(x.get()); } +#else +template +inline void swap(multiset&&x, + multiset&&y) +{ x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = + has_trivial_destructor::value && + has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_SET_HPP */ + diff --git a/thirdparty/boost/interprocess/containers/slist.hpp b/thirdparty/boost/interprocess/containers/slist.hpp new file mode 100644 index 0000000..af04cb2 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/slist.hpp @@ -0,0 +1,1471 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2004-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008 +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_INTERPROCESS_SLIST_HPP +#define BOOST_INTERPROCESS_SLIST_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost{ namespace interprocess{ + +namespace detail { +/// @cond +template +struct slist_node + : public bi::make_slist_base_hook + , bi::link_mode >::type +{ + typedef typename bi::make_slist_base_hook + , bi::link_mode >::type hook_type; + + slist_node() + : m_data() + {} + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + slist_node(const Convertible &value) + : m_data(value){} + #else + template + slist_node(Convertible &&value) + : m_data(forward(value)){} + #endif + + T m_data; +}; + +template +struct intrusive_slist_type +{ + typedef typename A::value_type value_type; + typedef typename detail::pointer_to_other + ::type void_pointer; + typedef typename detail::slist_node + node_type; + + typedef typename bi::make_slist + + ,bi::constant_time_size + ,bi::size_type + >::type container_type; + typedef container_type type ; +}; + +/// @endcond +} //namespace detail { + +//! An slist is a singly linked list: a list where each element is linked to the next +//! element, but not to the previous element. That is, it is a Sequence that +//! supports forward but not backward traversal, and (amortized) constant time +//! insertion and removal of elements. Slists, like lists, have the important +//! property that insertion and splicing do not invalidate iterators to list elements, +//! and that even removal invalidates only the iterators that point to the elements +//! that are removed. The ordering of iterators may be changed (that is, +//! slist::iterator might have a different predecessor or successor after a list +//! operation than it did before), but the iterators themselves will not be invalidated +//! or made to point to different elements unless that invalidation or mutation is explicit. +//! +//! The main difference between slist and list is that list's iterators are bidirectional +//! iterators, while slist's iterators are forward iterators. This means that slist is +//! less versatile than list; frequently, however, bidirectional iterators are +//! unnecessary. You should usually use slist unless you actually need the extra +//! functionality of list, because singly linked lists are smaller and faster than double +//! linked lists. +//! +//! Important performance note: like every other Sequence, slist defines the member +//! functions insert and erase. Using these member functions carelessly, however, can +//! result in disastrously slow programs. The problem is that insert's first argument is +//! an iterator p, and that it inserts the new element(s) before p. This means that +//! insert must find the iterator just before p; this is a constant-time operation +//! for list, since list has bidirectional iterators, but for slist it must find that +//! iterator by traversing the list from the beginning up to p. In other words: +//! insert and erase are slow operations anywhere but near the beginning of the slist. +//! +//! Slist provides the member functions insert_after and erase_after, which are constant +//! time operations: you should always use insert_after and erase_after whenever +//! possible. If you find that insert_after and erase_after aren't adequate for your +//! needs, and that you often need to use insert and erase in the middle of the list, +//! then you should probably use list instead of slist. +template +class slist + : protected detail::node_alloc_holder + ::type> +{ + /// @cond + typedef typename + detail::intrusive_slist_type::type Icont; + typedef detail::node_alloc_holder AllocHolder; + typedef typename AllocHolder::NodePtr NodePtr; + typedef list ThisType; + typedef typename AllocHolder::NodeAlloc NodeAlloc; + typedef typename AllocHolder::ValAlloc ValAlloc; + typedef typename AllocHolder::Node Node; + typedef detail::allocator_destroyer Destroyer; + typedef typename AllocHolder::allocator_v1 allocator_v1; + typedef typename AllocHolder::allocator_v2 allocator_v2; + typedef typename AllocHolder::alloc_version alloc_version; + + class equal_to_value + { + typedef typename AllocHolder::value_type value_type; + const value_type &t_; + + public: + equal_to_value(const value_type &t) + : t_(t) + {} + + bool operator()(const value_type &t)const + { return t_ == t; } + }; + + template + struct ValueCompareToNodeCompare + : Pred + { + ValueCompareToNodeCompare(Pred pred) + : Pred(pred) + {} + + bool operator()(const Node &a, const Node &b) const + { return static_cast(*this)(a.m_data, b.m_data); } + + bool operator()(const Node &a) const + { return static_cast(*this)(a.m_data); } + }; + /// @endcond + public: + //! The type of object, T, stored in the list + typedef T value_type; + //! Pointer to T + typedef typename A::pointer pointer; + //! Const pointer to T + typedef typename A::const_pointer const_pointer; + //! Reference to T + typedef typename A::reference reference; + //! Const reference to T + typedef typename A::const_reference const_reference; + //! An unsigned integral type + typedef typename A::size_type size_type; + //! A signed integral type + typedef typename A::difference_type difference_type; + //! The allocator type + typedef A allocator_type; + //! The stored allocator type + typedef NodeAlloc stored_allocator_type; + + /// @cond + private: + typedef difference_type list_difference_type; + typedef pointer list_pointer; + typedef const_pointer list_const_pointer; + typedef reference list_reference; + typedef const_reference list_const_reference; + /// @endcond + + public: + //! Const iterator used to iterate through a list. + class const_iterator + /// @cond + : public std::iterator + { + + protected: + typename Icont::iterator m_it; + explicit const_iterator(typename Icont::iterator it) : m_it(it){} + void prot_incr(){ ++m_it; } + + private: + typename Icont::iterator get() + { return this->m_it; } + + public: + friend class slist; + typedef list_difference_type difference_type; + + //Constructors + const_iterator() + : m_it() + {} + + //Pointer like operators + const_reference operator*() const + { return m_it->m_data; } + + const_pointer operator->() const + { return const_pointer(&m_it->m_data); } + + //Increment / Decrement + const_iterator& operator++() + { prot_incr(); return *this; } + + const_iterator operator++(int) + { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); } + + //Comparison operators + bool operator== (const const_iterator& r) const + { return m_it == r.m_it; } + + bool operator!= (const const_iterator& r) const + { return m_it != r.m_it; } + } + /// @endcond + ; + + //! Iterator used to iterate through a list + class iterator + /// @cond + : public const_iterator + { + + private: + explicit iterator(typename Icont::iterator it) + : const_iterator(it) + {} + + typename Icont::iterator get() + { return this->m_it; } + + public: + friend class slist; + typedef list_pointer pointer; + typedef list_reference reference; + + //Constructors + iterator(){} + + //Pointer like operators + reference operator*() const { return this->m_it->m_data; } + pointer operator->() const { return pointer(&this->m_it->m_data); } + + //Increment / Decrement + iterator& operator++() + { this->prot_incr(); return *this; } + + iterator operator++(int) + { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); } + } + /// @endcond + ; + + public: + //! Effects: Constructs a list taking the allocator as parameter. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + explicit slist(const allocator_type& a = allocator_type()) + : AllocHolder(a) + {} + +// explicit slist(size_type n) +// : AllocHolder(move(allocator_type())) +// { this->resize(n); } + + //! Effects: Constructs a list that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + explicit slist(size_type n, const value_type& x = value_type(), + const allocator_type& a = allocator_type()) + : AllocHolder(a) + { this->priv_create_and_insert_nodes(this->before_begin(), n, x); } + + //! Effects: Constructs a list that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the list. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's constructor taking an dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + slist(InpIt first, InpIt last, + const allocator_type& a = allocator_type()) + : AllocHolder(a) + { this->insert_after(this->before_begin(), first, last); } + + //! Effects: Copy constructs a list. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocator_type's default constructor or copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + slist(const slist& x) + : AllocHolder(x) + { this->insert_after(this->before_begin(), x.begin(), x.end()); } + + //! Effects: Move constructor. Moves mx's resources to *this. + //! + //! Throws: If allocator_type's default constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + slist(const detail::moved_object &x) + : AllocHolder(move((AllocHolder&)x.get())) + {} + #else + slist(slist &&x) + : AllocHolder(move((AllocHolder&)x)) + {} + #endif + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to the number of elements in x. + slist& operator= (const slist& x) + { + if (&x != this){ + this->assign(x.begin(), x.end()); + } + return *this; + } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to the number of elements in x. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + slist& operator= (const detail::moved_object& mx) + { + if (&mx.get() != this){ + this->clear(); + this->swap(mx.get()); + } + return *this; + } + #else + slist& operator= (slist && mx) + { + if (&mx != this){ + this->clear(); + this->swap(mx); + } + return *this; + } + #endif + + //! Effects: Destroys the list. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~slist() + { this->clear(); } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return allocator_type(this->node_alloc()); } + + const stored_allocator_type &get_stored_allocator() const + { return this->node_alloc(); } + + stored_allocator_type &get_stored_allocator() + { return this->node_alloc(); } + + public: + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + void assign(size_type n, const T& val) + { this->priv_fill_assign(n, val); } + + //! Effects: Assigns the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(InpIt first, InpIt last) + { + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_assign_dispatch(first, last, Result()); + } + + //! Effects: Returns an iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return iterator(this->icont().begin()); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return const_iterator(this->non_const_icont().begin()); } + + //! Effects: Returns an iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return iterator(this->icont().end()); } + + //! Effects: Returns a const_iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return const_iterator(this->non_const_icont().end()); } + + //! Effects: Returns a non-dereferenceable iterator that, + //! when incremented, yields begin(). This iterator may be used + //! as the argument toinsert_after, erase_after, etc. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator before_begin() + { return iterator(end()); } + + //! Effects: Returns a non-dereferenceable const_iterator + //! that, when incremented, yields begin(). This iterator may be used + //! as the argument toinsert_after, erase_after, etc. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator before_begin() const + { return const_iterator(end()); } + + //! Effects: Returns the number of the elements contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return this->icont().size(); } + + //! Effects: Returns the largest possible size of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return AllocHolder::max_size(); } + + //! Effects: Returns true if the list contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return !this->size(); } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() + //! allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements on *this and x. + void swap(slist& x) + { AllocHolder::swap(x); } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() + { return *this->begin(); } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const + { return *this->begin(); } + + //! Effects: Inserts a copy of t in the beginning of the list. + //! + //! Throws: If memory allocation throws or + //! T's copy constructor throws. + //! + //! Complexity: Amortized constant time. + void push_front(const value_type& x) + { this->icont().push_front(*this->create_node(x)); } + + //! Effects: Constructs a new element in the beginning of the list + //! and moves the resources of t to this new element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_front(const detail::moved_object& x) + { this->icont().push_front(*this->create_node(x)); } + #else + void push_front(T && x) + { this->icont().push_front(*this->create_node(move(x))); } + #endif + + //! Effects: Removes the first element from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Amortized constant time. + void pop_front() + { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); } + + //! Returns: The iterator to the element before i in the sequence. + //! Returns the end-iterator, if either i is the begin-iterator or the + //! sequence is empty. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before i. + iterator previous(iterator p) + { return iterator(this->icont().previous(p.get())); } + + //! Returns: The const_iterator to the element before i in the sequence. + //! Returns the end-const_iterator, if either i is the begin-const_iterator or + //! the sequence is empty. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before i. + const_iterator previous(const_iterator p) + { return const_iterator(this->icont().previous(p.get())); } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Inserts a copy of the value after the p pointed + //! by prev_p. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Amortized constant time. + //! + //! Note: Does not affect the validity of iterators and references of + //! previous values. + iterator insert_after(iterator prev_pos, const value_type& x) + { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); } + + //! Requires: prev_pos must be a valid iterator of *this. + //! + //! Effects: Inserts a move constructed copy object from the value after the + //! p pointed by prev_pos. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + //! + //! Note: Does not affect the validity of iterators and references of + //! previous values. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert_after(iterator prev_pos, const detail::moved_object& x) + { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); } + #else + iterator insert_after(iterator prev_pos, value_type && x) + { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(move(x)))); } + #endif + + //! Requires: prev_pos must be a valid iterator of *this. + //! + //! Effects: Inserts n copies of x after prev_pos. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Does not affect the validity of iterators and references of + //! previous values. + void insert_after(iterator prev_pos, size_type n, const value_type& x) + { this->priv_create_and_insert_nodes(prev_pos, n, x); } + + //! Requires: prev_pos must be a valid iterator of *this. + //! + //! Effects: Inserts the range pointed by [first, last) + //! after the p prev_pos. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws. + //! + //! Complexity: Linear to the number of elements inserted. + //! + //! Note: Does not affect the validity of iterators and references of + //! previous values. + template + void insert_after(iterator prev_pos, InIter first, InIter last) + { + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_insert_after_range_dispatch(prev_pos, first, last, Result()); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before p. + //! + //! Throws: If memory allocation throws or x's copy constructor throws. + //! + //! Complexity: Linear to the elements before p. + iterator insert(iterator p, const value_type& x) + { return this->insert_after(previous(p), x); } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a new element before p with mx's resources. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Linear to the elements before p. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator p, const detail::moved_object& x) + { return this->insert_after(previous(p), x); } + #else + iterator insert(iterator p, value_type && x) + { return this->insert_after(previous(p), move(x)); } + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Inserts n copies of x before p. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n plus linear to the elements before p. + void insert(iterator p, size_type n, const value_type& x) + { return this->insert_after(previous(p), n, x); } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before p. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws. + //! + //! Complexity: Linear to std::distance [first, last) plus + //! linear to the elements before p. + template + void insert(iterator p, InIter first, InIter last) + { return this->insert_after(previous(p), first, last); } + + //! Effects: Erases the element after the element pointed by prev_pos + //! of the list. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not invalidate iterators or references to non erased elements. + iterator erase_after(iterator prev_pos) + { + return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc()))); + } + + //! Effects: Erases the range (before_first, last) from + //! the list. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of erased elements. + //! + //! Note: Does not invalidate iterators or references to non erased elements. + iterator erase_after(iterator before_first, iterator last) + { + return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc()))); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Erases the element at p p. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before p. + iterator erase(iterator p) + { return iterator(this->erase_after(previous(p))); } + + //! Requires: first and last must be valid iterator to elements in *this. + //! + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last plus + //! linear to the elements before first. + iterator erase(iterator first, iterator last) + { return iterator(this->erase_after(previous(first), last)); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size, const T& x) + { + typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next; + while (++(cur_next = cur) != end_n && new_size > 0){ + --new_size; + cur = cur_next; + } + if (cur_next != end_n) + this->erase_after(iterator(cur), iterator(end_n)); + else + this->insert_after(iterator(cur), new_size, x); + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default constructed. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size) + { + typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next; + size_type len = this->size(); + size_type left = new_size; + + while (++(cur_next = cur) != end_n && left > 0){ + --left; + cur = cur_next; + } + if (cur_next != end_n){ + this->erase_after(iterator(cur), iterator(end_n)); + } + else{ + this->priv_create_and_insert_nodes(iterator(cur), new_size - len); + } + } + + //! Effects: Erases all the elements of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the list. + void clear() + { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } + + //! Requires: p must point to an element contained + //! by the list. x != *this + //! + //! Effects: Transfers all the elements of list x to this list, after the + //! the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear to the elements in x. + //! + //! Note: Iterators of values obtained from list x now point to elements of + //! this list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist& x) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice_after(prev_pos.get(), x.icont()); + } + else{ + throw std::runtime_error("slist::splice called with unequal allocators"); + } + } + + //void splice_after(iterator prev_pos, const detail::moved_object& x) + //{ this->splice_after(prev_pos, x.get()); } + + // Moves the element that follows prev to *this, inserting it immediately + // after p. This is constant time. + + //! Requires: prev_pos must be a valid iterator of this. + //! i must point to an element contained in list x. + //! + //! Effects: Transfers the value pointed by i, from list x to this list, + //! after the element pointed by prev_pos. + //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist& x, iterator prev) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice_after(prev_pos.get(), x.icont(), prev.get()); + } + else{ + throw std::runtime_error("slist::splice called with unequal allocators"); + } + } + + //void splice_after(iterator prev_pos, const detail::moved_object& x, iterator prev) + //{ return splice_after(prev_pos, x.get(), prev); } + + // Moves the range [before_first + 1, before_last + 1) to *this, + // inserting it immediately after p. This is constant time. + + + //! Requires: prev_pos must be a valid iterator of this. + //! before_first and before_last must be valid iterators of x. + //! prev_pos must not be contained in [before_first, before_last) range. + //! + //! Effects: Transfers the range [before_first + 1, before_last + 1) + //! from list x to this list, after the element pointed by prev_pos. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear to the number of transferred elements. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist& x, + iterator before_first, iterator before_last) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice_after + (prev_pos.get(), x.icont(), before_first.get(), before_last.get()); + } + else{ + throw std::runtime_error("slist::splice called with unequal allocators"); + } + } + + //void splice_after(iterator prev_pos, const detail::moved_object& x, + // iterator before_first, iterator before_last) + //{ this->splice_after(prev_pos, x.get(), before_first, before_last); } + + //! Requires: prev_pos must be a valid iterator of this. + //! before_first and before_last must be valid iterators of x. + //! prev_pos must not be contained in [before_first, before_last) range. + //! n == std::distance(before_first, before_last) + //! + //! Effects: Transfers the range [before_first + 1, before_last + 1) + //! from list x to this list, after the element pointed by prev_pos. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist& x, + iterator before_first, iterator before_last, + size_type n) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().splice_after + (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n); + } + else{ + throw std::runtime_error("slist::splice called with unequal allocators"); + } + } + + //void splice_after(iterator prev_pos, const detail::moved_object& x, + // iterator before_first, iterator before_last, size_type n) + //{ this->splice_after(prev_pos, x.get(), before_first, before_last, n); } + + //! Requires: p must point to an element contained + //! by the list. x != *this + //! + //! Effects: Transfers all the elements of list x to this list, before the + //! the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear in distance(begin(), p), and linear in x.size(). + //! + //! Note: Iterators of values obtained from list x now point to elements of + //! this list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, slist& x) + { this->splice_after(this->previous(p), x); } + + //void splice(iterator p, const detail::moved_object& x) + //{ return this->splice(p, x.get()); } + + //! Requires: p must point to an element contained + //! by this list. i must point to an element contained in list x. + //! + //! Effects: Transfers the value pointed by i, from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! If p == i or p == ++i, this function is a null operation. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear in distance(begin(), p), and in distance(x.begin(), i). + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, slist& x, iterator i) + { this->splice_after(previous(p), x, i); } + + //void splice(iterator p, const detail::moved_object& x, iterator i) + //{ this->splice(p, x.get(), i); } + + //! Requires: p must point to an element contained + //! by this list. first and last must point to elements contained in list x. + //! + //! Effects: Transfers the range pointed by first and last from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: std::runtime_error if this' allocator and x's allocator + //! are not equal. + //! + //! Complexity: Linear in distance(begin(), p), in distance(x.begin(), first), + //! and in distance(first, last). + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, slist& x, iterator first, iterator last) + { this->splice_after(previous(p), x, previous(first), previous(last)); } + + //void splice(iterator p, const detail::moved_object& x, iterator first, iterator last) + //{ this->splice(p, x.get(), first, last); } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + //! + //! Note: Iterators and references are not invalidated + void reverse() + { this->icont().reverse(); } + + //! Effects: Removes all the elements that compare equal to value. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void remove(const T& value) + { remove_if(equal_to_value(value)); } + + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. + //! + //! Throws: If pred throws. + //! + //! Complexity: Linear time. It performs exactly size() calls to the predicate. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_if(Pred pred) + { + typedef ValueCompareToNodeCompare Predicate; + this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc())); + } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear time (size()-1 comparisons calls to pred()). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void unique() + { this->unique(value_equal()); } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! + //! Throws: If pred throws. + //! + //! Complexity: Linear time (size()-1 comparisons equality comparisons). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique(Pred pred) + { + typedef ValueCompareToNodeCompare Predicate; + this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc())); + } + + //! Requires: The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this according to std::less. The merge is stable; + //! that is, if an element from *this is equivalent to one from x, then the element + //! from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + void merge(slist& x) + { this->merge(x, value_less()); } + + //void merge(const detail::moved_object& x) + //{ this->merge(x.get(), value_less()); } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references to *this are not invalidated. + template + void merge(slist& x, StrictWeakOrdering comp) + { + if((NodeAlloc&)*this == (NodeAlloc&)x){ + this->icont().merge(x.icont(), + ValueCompareToNodeCompare(comp)); + } + else{ + throw std::runtime_error("list::merge called with unequal allocators"); + } + } + + //template + //void merge(const detail::moved_object& x, StrictWeakOrdering comp) + //{ this->merge(x.get(), comp); } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: Nothing. + //! + //! Notes: Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + void sort() + { this->sort(value_less()); } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: Nothing. + //! + //! Notes: Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + template + void sort(StrictWeakOrdering comp) + { + // nothing if the slist has length 0 or 1. + if (this->size() < 2) + return; + this->icont().sort(ValueCompareToNodeCompare(comp)); + } + + /// @cond + private: + + //Iterator range version + template + void priv_create_and_insert_nodes + (const_iterator prev, InpIterator beg, InpIterator end) + { + typedef typename std::iterator_traits::iterator_category ItCat; + priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat()); + } + + template + void priv_create_and_insert_nodes + (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag) + { + for (; beg != end; ++beg){ + this->icont().insert_after(prev.get(), *this->create_node_from_it(beg)); + ++prev; + } + } + + template + void priv_create_and_insert_nodes + (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag) + { //Just forward to the default one + priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag()); + } + + class insertion_functor; + friend class insertion_functor; + + class insertion_functor + { + Icont &icont_; + typename Icont::iterator prev_; + + public: + insertion_functor(Icont &icont, typename Icont::iterator prev) + : icont_(icont), prev_(prev) + {} + + void operator()(Node &n) + { prev_ = this->icont_.insert_after(prev_, n); } + }; + + template + void priv_create_and_insert_nodes + (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag) + { + //Optimized allocation and construction + this->allocate_many_and_construct + (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get())); + } + + //Default constructed version + void priv_create_and_insert_nodes(const_iterator prev, size_type n) + { + typedef default_construct_iterator default_iterator; + this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator()); + } + + //Copy constructed version + void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x) + { + typedef constant_iterator cvalue_iterator; + this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator()); + } + + //Dispatch to detect iterator range or integer overloads + template + void priv_insert_dispatch(iterator prev, + InputIter first, InputIter last, + detail::false_) + { this->priv_create_and_insert_nodes(prev, first, last); } + + template + void priv_insert_dispatch(iterator prev, Integer n, Integer x, detail::true_) + { this->priv_create_and_insert_nodes(prev, n, x); } + + void priv_fill_assign(size_type n, const T& val) + { + iterator end_n(this->end()); + iterator prev(this->before_begin()); + iterator node(this->begin()); + for ( ; node != end_n && n > 0 ; --n){ + *node = val; + prev = node; + ++node; + } + if (n > 0) + this->priv_create_and_insert_nodes(prev, n, val); + else + this->erase_after(prev, end_n); + } + + template + void priv_assign_dispatch(Int n, Int val, detail::true_) + { this->priv_fill_assign((size_type) n, (T)val); } + + template + void priv_assign_dispatch(InpIt first, InpIt last, + detail::false_) + { + iterator end_n(this->end()); + iterator prev(this->before_begin()); + iterator node(this->begin()); + while (node != end_n && first != last){ + *node = *first; + prev = node; + ++node; + ++first; + } + if (first != last) + this->priv_create_and_insert_nodes(prev, first, last); + else + this->erase_after(prev, end_n); + } + + template + void priv_insert_after_range_dispatch(iterator prev_pos, Int n, Int x, detail::true_) + { this->priv_create_and_insert_nodes(prev_pos, n, x); } + + template + void priv_insert_after_range_dispatch(iterator prev_pos, InIter first, InIter last, detail::false_) + { this->priv_create_and_insert_nodes(prev_pos, first, last); } + + //Functors for member algorithm defaults + struct value_less + { + bool operator()(const value_type &a, const value_type &b) const + { return a < b; } + }; + + struct value_equal + { + bool operator()(const value_type &a, const value_type &b) const + { return a == b; } + }; + + struct value_equal_to_this + { + explicit value_equal_to_this(const value_type &ref) + : m_ref(ref){} + + bool operator()(const value_type &val) const + { return m_ref == val; } + + const value_type &m_ref; + }; + /// @endcond +}; + +template +inline bool +operator==(const slist& x, const slist& y) +{ + if(x.size() != y.size()){ + return false; + } + typedef typename slist::const_iterator const_iterator; + const_iterator end1 = x.end(); + + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + while (i1 != end1 && *i1 == *i2){ + ++i1; + ++i2; + } + return i1 == end1; +} + +template +inline bool +operator<(const slist& sL1, const slist& sL2) +{ + return std::lexicographical_compare + (sL1.begin(), sL1.end(), sL2.begin(), sL2.end()); +} + +template +inline bool +operator!=(const slist& sL1, const slist& sL2) + { return !(sL1 == sL2); } + +template +inline bool +operator>(const slist& sL1, const slist& sL2) + { return sL2 < sL1; } + +template +inline bool +operator<=(const slist& sL1, const slist& sL2) + { return !(sL2 < sL1); } + +template +inline bool +operator>=(const slist& sL1, const slist& sL2) + { return !(sL1 < sL2); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(slist& x, slist& y) + { x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, slist& y) + { x.get().swap(y); } + +template +inline void swap(slist& x, const detail::moved_object >& y) + { x.swap(y.get()); } +#else +template +inline void swap(slist&&x, slist&&y) + { x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +/* +template +struct is_movable > +{ + enum { value = true }; +}; +*/ +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost{ namespace interprocess{ + +// Specialization of insert_iterator so that insertions will be constant +// time rather than linear time. + +//iG +//Ummm, I don't like to define things in namespace std, but +//there is no other way +namespace std { + +template +class insert_iterator > +{ + protected: + typedef boost::interprocess::slist Container; + Container* container; + typename Container::iterator iter; + public: + typedef Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(Container& x, + typename Container::iterator i, + bool is_previous = false) + : container(&x), iter(is_previous ? i : x.previous(i)){ } + + insert_iterator& + operator=(const typename Container::value_type& value) + { + iter = container->insert_after(iter, value); + return *this; + } + insert_iterator& operator*(){ return *this; } + insert_iterator& operator++(){ return *this; } + insert_iterator& operator++(int){ return *this; } +}; + +} //namespace std; + + + +#include + +#endif /* BOOST_INTERPROCESS_SLIST_HPP */ diff --git a/thirdparty/boost/interprocess/containers/string.hpp b/thirdparty/boost/interprocess/containers/string.hpp new file mode 100644 index 0000000..56aad59 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/string.hpp @@ -0,0 +1,2489 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008 +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1994 +// Hewlett-Packard Company +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Hewlett-Packard Company makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. + +#ifndef BOOST_INTERPROCESS_STRING_HPP +#define BOOST_INTERPROCESS_STRING_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 + +namespace boost { +namespace interprocess { +namespace detail { + +/// @cond +// ------------------------------------------------------------ +// Class basic_string_base. + +// basic_string_base is a helper class that makes it it easier to write +// an exception-safe version of basic_string. The constructor allocates, +// but does not initialize, a block of memory. The destructor +// deallocates, but does not destroy elements within, a block of +// memory. The destructor assumes that the memory either is the internal buffer, +// or else points to a block of memory that was allocated using _String_base's +// allocator and whose size is this->m_storage. +template +class basic_string_base +{ + basic_string_base(); + public: + typedef A allocator_type; + //! The stored allocator type + typedef allocator_type stored_allocator_type; + typedef typename A::pointer pointer; + typedef typename A::value_type value_type; + typedef typename A::size_type size_type; + + basic_string_base(const allocator_type& a) + : members_(a) + { init(); } + + basic_string_base(const allocator_type& a, std::size_t n) + : members_(a) + { + this->init(); + this->allocate_initial_block(n); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string_base(const detail::moved_object >& b) + : members_(b.get().members_) + { + init(); + this->swap(b.get()); + } + #else + basic_string_base(basic_string_base && b) + : members_(b.members_) + { + init(); + this->swap(b); + } + #endif + + ~basic_string_base() + { + this->deallocate_block(); + if(!this->is_short()){ + static_cast(static_cast(&this->members_.m_repr.r))->~long_t(); + } + } + + private: + + //This is the structure controlling a long string + struct long_t + { + size_type is_short : 1; + size_type length : (sizeof(size_type)*CHAR_BIT - 1); + size_type storage; + pointer start; + + long_t() + {} + + long_t(const long_t &other) + { + this->is_short = other.is_short; + length = other.length; + storage = other.storage; + start = other.start; + } + + long_t &operator =(const long_t &other) + { + this->is_short = other.is_short; + length = other.length; + storage = other.storage; + start = other.start; + return *this; + } + }; + + //This basic type should have the same alignment as long_t +//iG typedef typename type_with_alignment::value>::type +// long_alignment_type; + typedef void *long_alignment_type; + BOOST_STATIC_ASSERT((detail::alignment_of::value % + detail::alignment_of::value) == 0); + + + //This type is the first part of the structure controlling a short string + //The "data" member stores + struct short_header + { + unsigned char is_short : 1; + unsigned char length : (CHAR_BIT - 1); + }; + + //This type has the same alignment and size as long_t but it's POD + //so, unlike long_t, it can be placed in a union + struct long_raw_t + { + long_alignment_type a; + unsigned char b[sizeof(long_t) - sizeof(long_alignment_type)]; + }; + + protected: + static const size_type MinInternalBufferChars = 8; + static const size_type AlignmentOfValueType = + alignment_of::value; + static const size_type ShortDataOffset = + detail::ct_rounded_size::value; + static const size_type ZeroCostInternalBufferChars = + (sizeof(long_t) - ShortDataOffset)/sizeof(value_type); + static const size_type UnalignedFinalInternalBufferChars = + (ZeroCostInternalBufferChars > MinInternalBufferChars) ? + ZeroCostInternalBufferChars : MinInternalBufferChars; + + struct short_t + { + short_header h; + value_type data[UnalignedFinalInternalBufferChars]; + }; + + union repr_t + { + long_raw_t r; + short_t s; + + short_t &short_repr() const + { return *const_cast(&s); } + + long_t &long_repr() const + { return *static_cast(const_cast(static_cast(&r))); } + }; + + struct members_holder + : public A + { + members_holder(const A &a) + : A(a) + {} + + repr_t m_repr; + } members_; + + const A &alloc() const + { return members_; } + + A &alloc() + { return members_; } + + static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); + + private: + + static const size_type MinAllocation = InternalBufferChars*2; + + protected: + bool is_short() const + { return static_cast(this->members_.m_repr.s.h.is_short != 0); } + + void is_short(bool yes) + { + if(yes && !this->is_short()){ + static_cast(static_cast(&this->members_.m_repr.r))->~long_t(); + } + else{ + new(static_cast(&this->members_.m_repr.r))long_t(); + } + this->members_.m_repr.s.h.is_short = yes; + } + + private: + void init() + { + this->members_.m_repr.s.h.is_short = 1; + this->members_.m_repr.s.h.length = 0; + } + + protected: + + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + typedef detail::integral_constant::value> alloc_version; + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, pointer reuse = 0) + { + if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){ + reuse = pointer(0); + command &= ~(expand_fwd | expand_bwd); + } + return this->allocation_command + (command, limit_size, preferred_size, received_size, reuse, alloc_version()); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, + const pointer &reuse, + allocator_v1) + { + (void)limit_size; + (void)reuse; + if(!(command & allocate_new)) + return std::pair(0, 0); + received_size = preferred_size; + return std::make_pair(this->alloc().allocate(received_size), false); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, + pointer reuse, + allocator_v2) + { + return this->alloc().allocation_command(command, limit_size, preferred_size, + received_size, reuse); + } + + size_type next_capacity(size_type additional_objects) const + { return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); } + + void deallocate(pointer p, std::size_t n) + { + if (p && (n > InternalBufferChars)) + this->alloc().deallocate(p, n); + } + + void construct(pointer p, const value_type &value = value_type()) + { new(detail::get_pointer(p)) value_type(value); } + + void destroy(pointer p, size_type n) + { + for(; n--; ++p) + detail::get_pointer(p)->~value_type(); + } + + void destroy(pointer p) + { detail::get_pointer(p)->~value_type(); } + + void allocate_initial_block(std::size_t n) + { + if (n <= this->max_size()) { + if(n > InternalBufferChars){ + size_type new_cap = this->next_capacity(n); + pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first; + this->is_short(false); + this->priv_addr(p); + this->priv_size(0); + this->priv_storage(new_cap); + } + } + else + throw_length_error(); + } + + void deallocate_block() + { this->deallocate(this->priv_addr(), this->priv_storage()); } + + std::size_t max_size() const + { return this->alloc().max_size() - 1; } + + // Helper functions for exception handling. + void throw_length_error() const + { throw(std::length_error("basic_string")); } + + void throw_out_of_range() const + { throw(std::out_of_range("basic_string")); } + + protected: + size_type priv_capacity() const + { return this->priv_storage() - 1; } + + pointer priv_addr() const + { return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start; } + + void priv_addr(pointer addr) + { this->members_.m_repr.long_repr().start = addr; } + + size_type priv_storage() const + { return this->is_short() ? InternalBufferChars : this->members_.m_repr.long_repr().storage; } + + void priv_storage(size_type storage) + { + if(!this->is_short()) + this->members_.m_repr.long_repr().storage = storage; + } + + size_type priv_size() const + { return this->is_short() ? this->members_.m_repr.short_repr().h.length : this->members_.m_repr.long_repr().length; } + + void priv_size(size_type sz) + { + if(this->is_short()) + this->members_.m_repr.s.h.length = (unsigned char)sz; + else + this->members_.m_repr.long_repr().length = static_cast(sz); + } + + void swap(basic_string_base& other) + { + if(this->is_short()){ + if(other.is_short()){ + std::swap(this->members_.m_repr, other.members_.m_repr); + } + else{ + repr_t copied(this->members_.m_repr); + this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr(); + other.members_.m_repr = copied; + } + } + else{ + if(other.is_short()){ + repr_t copied(other.members_.m_repr); + other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr(); + this->members_.m_repr = copied; + } + else{ + std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr()); + } + } + + allocator_type & this_al = this->alloc(), &other_al = other.alloc(); + if(this_al != other_al){ + detail::do_swap(this_al, other_al); + } + } +}; +/// @endcond + +} //namespace detail { + + +//! The basic_string class represents a Sequence of characters. It contains all the +//! usual operations of a Sequence, and, additionally, it contains standard string +//! operations such as search and concatenation. +//! +//! The basic_string class is parameterized by character type, and by that type's +//! Character Traits. +//! +//! This class has performance characteristics very much like vector<>, meaning, +//! for example, that it does not perform reference-count or copy-on-write, and that +//! concatenation of two strings is an O(N) operation. +//! +//! Some of basic_string's member functions use an unusual method of specifying positions +//! and ranges. In addition to the conventional method using iterators, many of +//! basic_string's member functions use a single value pos of type size_type to represent a +//! position (in which case the position is begin() + pos, and many of basic_string's +//! member functions use two values, pos and n, to represent a range. In that case pos is +//! the beginning of the range and n is its size. That is, the range is +//! [begin() + pos, begin() + pos + n). +//! +//! Note that the C++ standard does not specify the complexity of basic_string operations. +//! In this implementation, basic_string has performance characteristics very similar to +//! those of vector: access to a single character is O(1), while copy and concatenation +//! are O(N). +//! +//! In this implementation, begin(), +//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators. +//! In this implementation, iterators are only invalidated by member functions that +//! explicitly change the string's contents. +template +class basic_string + : private detail::basic_string_base +{ + /// @cond + private: + typedef detail::basic_string_base base_t; + static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; + + protected: + // A helper class to use a char_traits as a function object. + + template + struct Eq_traits + : public std::binary_function + { + bool operator()(const typename Tr::char_type& x, + const typename Tr::char_type& y) const + { return Tr::eq(x, y); } + }; + + template + struct Not_within_traits + : public std::unary_function + { + typedef const typename Tr::char_type* Pointer; + const Pointer m_first; + const Pointer m_last; + + Not_within_traits(Pointer f, Pointer l) + : m_first(f), m_last(l) {} + + bool operator()(const typename Tr::char_type& x) const + { + return std::find_if(m_first, m_last, + std::bind1st(Eq_traits(), x)) == m_last; + } + }; + /// @endcond + + public: + //! The allocator type + typedef A allocator_type; + //! The stored allocator type + typedef allocator_type stored_allocator_type; + //! The type of object, CharT, stored in the string + typedef CharT value_type; + //! The second template parameter Traits + typedef Traits traits_type; + //! Pointer to CharT + typedef typename A::pointer pointer; + //! Const pointer to CharT + typedef typename A::const_pointer const_pointer; + //! Reference to CharT + typedef typename A::reference reference; + //! Const reference to CharT + typedef typename A::const_reference const_reference; + //! An unsigned integral type + typedef typename A::size_type size_type; + //! A signed integral type + typedef typename A::difference_type difference_type; + //! Iterator used to iterate through a string. It's a Random Access Iterator + typedef pointer iterator; + //! Const iterator used to iterate through a string. It's a Random Access Iterator + typedef const_pointer const_iterator; + //! Iterator used to iterate backwards through a string + typedef std::reverse_iterator reverse_iterator; + //! Const iterator used to iterate backwards through a string + typedef std::reverse_iterator const_reverse_iterator; + //! The largest possible value of type size_type. That is, size_type(-1). + static const size_type npos; + + /// @cond + private: + typedef constant_iterator cvalue_iterator; + /// @endcond + + public: // Constructor, destructor, assignment. + + struct reserve_t {}; + + basic_string(reserve_t, std::size_t n, + const allocator_type& a = allocator_type()) + : base_t(a, n + 1) + { this->priv_terminate_string(); } + + //! Effects: Constructs a basic_string taking the allocator as parameter. + //! + //! Throws: If allocator_type's copy constructor throws. + explicit basic_string(const allocator_type& a = allocator_type()) + : base_t(a, InternalBufferChars) + { this->priv_terminate_string(); } + + //! Effects: Copy constructs a basic_string. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocator_type's default constructor or copy constructor throws. + basic_string(const basic_string& s) + : base_t(s.alloc()) + { this->priv_range_initialize(s.begin(), s.end()); } + + //! Effects: Move constructor. Moves mx's resources to *this. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string(const detail::moved_object& s) + : base_t(move((base_t&)s.get())) + {} + #else + basic_string(basic_string && s) + : base_t(move((base_t&)s)) + {} + #endif + + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and is initialized by a specific number of characters of the s string. + basic_string(const basic_string& s, size_type pos, size_type n = npos, + const allocator_type& a = allocator_type()) + : base_t(a) + { + if (pos > s.size()) + this->throw_out_of_range(); + else + this->priv_range_initialize + (s.begin() + pos, s.begin() + pos + min_value(n, s.size() - pos)); + } + + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and is initialized by a specific number of characters of the s c-string. + basic_string(const CharT* s, size_type n, + const allocator_type& a = allocator_type()) + : base_t(a) + { this->priv_range_initialize(s, s + n); } + + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and is initialized by the null-terminated s c-string. + basic_string(const CharT* s, + const allocator_type& a = allocator_type()) + : base_t(a) + { this->priv_range_initialize(s, s + Traits::length(s)); } + + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and is initialized by n copies of c. + basic_string(size_type n, CharT c, + const allocator_type& a = allocator_type()) + : base_t(a) + { + this->priv_range_initialize(cvalue_iterator(c, n), + cvalue_iterator()); + } + + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and a range of iterators. + template + basic_string(InputIterator f, InputIterator l, + const allocator_type& a = allocator_type()) + : base_t(a) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_initialize_dispatch(f, l, Result()); + } + + //! Effects: Destroys the basic_string. All used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + ~basic_string() + {} + + //! Effects: Copy constructs a string. + //! + //! Postcondition: x == *this. + //! + //! Complexity: Linear to the elements x contains. + basic_string& operator=(const basic_string& s) + { + if (&s != this) + this->assign(s.begin(), s.end()); + return *this; + } + + //! Effects: Move constructor. Moves mx's resources to *this. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string& operator=(const detail::moved_object& ms) + { + basic_string &s = ms.get(); + if (&s != this){ + this->swap(s); + } + return *this; + } + #else + basic_string& operator=(basic_string && ms) + { + basic_string &s = ms; + if (&s != this){ + this->swap(s); + } + return *this; + } + #endif + + //! Effects: Assignment from a null-terminated c-string. + basic_string& operator=(const CharT* s) + { return this->assign(s, s + Traits::length(s)); } + + //! Effects: Assignment from character. + basic_string& operator=(CharT c) + { return this->assign(static_cast(1), c); } + + //! Effects: Returns an iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return this->priv_addr(); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return this->priv_addr(); } + + //! Effects: Returns an iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return this->priv_addr() + this->priv_size(); } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return this->priv_addr() + this->priv_size(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return reverse_iterator(this->priv_addr() + this->priv_size()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(this->priv_addr() + this->priv_size()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return reverse_iterator(this->priv_addr()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return const_reverse_iterator(this->priv_addr()); } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return this->alloc(); } + + //! Effects: Returns the number of the elements contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return this->priv_size(); } + + //! Effects: Returns the number of the elements contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type length() const + { return this->size(); } + + //! Effects: Returns the largest possible size of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return base_t::max_size(); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type n, CharT c) + { + if (n <= size()) + this->erase(this->begin() + n, this->end()); + else + this->append(n - this->size(), c); + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default constructed. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type n) + { resize(n, this->priv_null()); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + void reserve(size_type res_arg) + { + if (res_arg > this->max_size()) + this->throw_length_error(); + + if (this->capacity() < res_arg){ + size_type n = max_value(res_arg, this->size()) + 1; + size_type new_cap = this->next_capacity(n); + pointer new_start = this->allocation_command + (allocate_new, n, new_cap, new_cap).first; + size_type new_length = 0; + + new_length += priv_uninitialized_copy + (this->priv_addr(), this->priv_addr() + this->priv_size(), new_start); + this->priv_construct_null(new_start + new_length); + this->deallocate_block(); + this->is_short(false); + this->priv_addr(new_start); + this->priv_size(new_length); + this->priv_storage(new_cap); + } + } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return this->priv_capacity(); } + + //! Effects: Erases all the elements of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the vector. + void clear() + { + if (!empty()) { + Traits::assign(*this->priv_addr(), this->priv_null()); + this->priv_size(0); + } + } + + //! Effects: Returns true if the vector contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return !this->priv_size(); } + + //! Requires: size() < n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference operator[](size_type n) + { return *(this->priv_addr() + n); } + + //! Requires: size() < n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference operator[](size_type n) const + { return *(this->priv_addr() + n); } + + //! Requires: size() < n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + reference at(size_type n) { + if (n >= size()) + this->throw_out_of_range(); + return *(this->priv_addr() + n); + } + + //! Requires: size() < n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + const_reference at(size_type n) const { + if (n >= size()) + this->throw_out_of_range(); + return *(this->priv_addr() + n); + } + + //! Effects: Appends string s to *this. + basic_string& operator+=(const basic_string& s) + { return this->append(s); } + + //! Effects: Appends c-string s to *this. + basic_string& operator+=(const CharT* s) + { return this->append(s); } + + //! Effects: Appends character c to *this. + basic_string& operator+=(CharT c) + { this->push_back(c); return *this; } + + //! Effects: Appends string s to *this. + basic_string& append(const basic_string& s) + { return this->append(s.begin(), s.end()); } + + //! Effects: Appends the range [pos, pos + n) from string s to *this. + basic_string& append(const basic_string& s, size_type pos, size_type n) + { + if (pos > s.size()) + this->throw_out_of_range(); + return this->append(s.begin() + pos, + s.begin() + pos + min_value(n, s.size() - pos)); + } + + //! Effects: Appends the range [s, s + n) from c-string s to *this. + basic_string& append(const CharT* s, size_type n) + { return this->append(s, s + n); } + + //! Effects: Appends the c-string s to *this. + basic_string& append(const CharT* s) + { return this->append(s, s + Traits::length(s)); } + + //! Effects: Appends the n times the character c to *this. + basic_string& append(size_type n, CharT c) + { return this->append(cvalue_iterator(c, n), cvalue_iterator()); } + + //! Effects: Appends the range [first, last) *this. + template + basic_string& append(InputIter first, InputIter last) + { this->insert(this->end(), first, last); return *this; } + + //! Effects: Inserts a copy of c at the end of the vector. + void push_back(CharT c) + { + if (this->priv_size() < this->capacity()){ + this->priv_construct_null(this->priv_addr() + (this->priv_size() + 1)); + Traits::assign(this->priv_addr()[this->priv_size()], c); + this->priv_size(this->priv_size()+1); + } + else{ + //No enough memory, insert a new object at the end + this->append((size_type)1, c); + } + } + + //! Effects: Removes the last element from the vector. + void pop_back() + { + Traits::assign(this->priv_addr()[this->priv_size()-1], this->priv_null()); + this->priv_size(this->priv_size()-1);; + } + + //! Effects: Assigns the value s to *this. + basic_string& assign(const basic_string& s) + { return this->operator=(s); } + + //! Effects: Moves the resources from ms *this. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string& assign(const detail::moved_object& ms) + { return this->operator=(ms);} + #else + basic_string& assign(basic_string && ms) + { return this->operator=(ms);} + #endif + + //! Effects: Assigns the range [pos, pos + n) from s to *this. + basic_string& assign(const basic_string& s, + size_type pos, size_type n) { + if (pos > s.size()) + this->throw_out_of_range(); + return this->assign(s.begin() + pos, + s.begin() + pos + min_value(n, s.size() - pos)); + } + + //! Effects: Assigns the range [s, s + n) from s to *this. + basic_string& assign(const CharT* s, size_type n) + { return this->assign(s, s + n); } + + //! Effects: Assigns the c-string s to *this. + basic_string& assign(const CharT* s) + { return this->assign(s, s + Traits::length(s)); } + + //! Effects: Assigns the character c n-times to *this. + basic_string& assign(size_type n, CharT c) + { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); } + + //! Effects: Assigns the range [first, last) to *this. + template + basic_string& assign(InputIter first, InputIter last) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + return this->priv_assign_dispatch(first, last, Result()); + } + + //! Effects: Assigns the range [f, l) to *this. + basic_string& assign(const CharT* f, const CharT* l) + { + const std::ptrdiff_t n = l - f; + if (static_cast(n) <= size()) { + Traits::copy(detail::get_pointer(this->priv_addr()), f, n); + this->erase(this->priv_addr() + n, this->priv_addr() + this->priv_size()); + } + else { + Traits::copy(detail::get_pointer(this->priv_addr()), f, this->priv_size()); + this->append(f + this->priv_size(), l); + } + return *this; + } + + //! Effects: Inserts the string s before pos. + basic_string& insert(size_type pos, const basic_string& s) + { + if (pos > size()) + this->throw_out_of_range(); + if (this->size() > this->max_size() - s.size()) + this->throw_length_error(); + this->insert(this->priv_addr() + pos, s.begin(), s.end()); + return *this; + } + + //! Effects: Inserts the range [pos, pos + n) from string s before pos. + basic_string& insert(size_type pos, const basic_string& s, + size_type beg, size_type n) + { + if (pos > this->size() || beg > s.size()) + this->throw_out_of_range(); + size_type len = min_value(n, s.size() - beg); + if (this->size() > this->max_size() - len) + this->throw_length_error(); + const CharT *beg_ptr = detail::get_pointer(s.begin()) + beg; + const CharT *end_ptr = beg_ptr + len; + this->insert(this->priv_addr() + pos, beg_ptr, end_ptr); + return *this; + } + + //! Effects: Inserts the range [s, s + n) before pos. + basic_string& insert(size_type pos, const CharT* s, size_type n) + { + if (pos > this->size()) + this->throw_out_of_range(); + if (this->size() > this->max_size() - n) + this->throw_length_error(); + this->insert(this->priv_addr() + pos, s, s + n); + return *this; + } + + //! Effects: Inserts the c-string s before pos. + basic_string& insert(size_type pos, const CharT* s) + { + if (pos > size()) + this->throw_out_of_range(); + size_type len = Traits::length(s); + if (this->size() > this->max_size() - len) + this->throw_length_error(); + this->insert(this->priv_addr() + pos, s, s + len); + return *this; + } + + //! Effects: Inserts the character c n-times before pos. + basic_string& insert(size_type pos, size_type n, CharT c) + { + if (pos > this->size()) + this->throw_out_of_range(); + if (this->size() > this->max_size() - n) + this->throw_length_error(); + this->insert(this->priv_addr() + pos, n, c); + return *this; + } + + //! Effects: Inserts the character c before position. + iterator insert(iterator position, CharT c) + { + size_type new_offset = position - this->priv_addr() + 1; + this->insert(position, cvalue_iterator(c, 1), + cvalue_iterator()); + return this->priv_addr() + new_offset; + } + + //! Effects: Inserts the character c n-times before position. + void insert(iterator position, std::size_t n, CharT c) + { + this->insert(position, cvalue_iterator(c, n), + cvalue_iterator()); + } + + //! Effects: Inserts the range [first, last) before position. + template + void insert(iterator p, InputIter first, InputIter last) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_insert_dispatch(p, first, last, Result()); + } + + //! Effects: Inserts the range [pos, pos + n). + basic_string& erase(size_type pos = 0, size_type n = npos) + { + if (pos > size()) + this->throw_out_of_range(); + erase(this->priv_addr() + pos, this->priv_addr() + pos + min_value(n, size() - pos)); + return *this; + } + + //! Effects: Erases the character pointed by position. + iterator erase(iterator position) + { + // The move includes the terminating null. + Traits::move(detail::get_pointer(position), + detail::get_pointer(position + 1), + this->priv_size() - (position - this->priv_addr())); + this->priv_size(this->priv_size()-1); + return position; + } + + //! Effects: Erases the range [first, last). + iterator erase(iterator first, iterator last) + { + if (first != last) { // The move includes the terminating null. + size_type num_erased = last - first; + Traits::move(detail::get_pointer(first), + detail::get_pointer(last), + (this->priv_size() + 1)-(last - this->priv_addr())); + size_type new_length = this->priv_size() - num_erased; + this->priv_size(new_length); + } + return first; + } + + //! Effects: Replaces a substring of *this with the string s. + basic_string& replace(size_type pos, size_type n, + const basic_string& s) + { + if (pos > size()) + this->throw_out_of_range(); + const size_type len = min_value(n, size() - pos); + if (this->size() - len >= this->max_size() - s.size()) + this->throw_length_error(); + return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, + s.begin(), s.end()); + } + + //! Effects: Replaces a substring of *this with a substring of s. + basic_string& replace(size_type pos1, size_type n1, + const basic_string& s, + size_type pos2, size_type n2) + { + if (pos1 > size() || pos2 > s.size()) + this->throw_out_of_range(); + const size_type len1 = min_value(n1, size() - pos1); + const size_type len2 = min_value(n2, s.size() - pos2); + if (this->size() - len1 >= this->max_size() - len2) + this->throw_length_error(); + return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1, + s.priv_addr() + pos2, s.priv_addr() + pos2 + len2); + } + + //! Effects: Replaces a substring of *this with the first n1 characters of s. + basic_string& replace(size_type pos, size_type n1, + const CharT* s, size_type n2) + { + if (pos > size()) + this->throw_out_of_range(); + const size_type len = min_value(n1, size() - pos); + if (n2 > this->max_size() || size() - len >= this->max_size() - n2) + this->throw_length_error(); + return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, + s, s + n2); + } + + //! Effects: Replaces a substring of *this with a null-terminated character array. + basic_string& replace(size_type pos, size_type n1, + const CharT* s) + { + if (pos > size()) + this->throw_out_of_range(); + const size_type len = min_value(n1, size() - pos); + const size_type n2 = Traits::length(s); + if (n2 > this->max_size() || size() - len >= this->max_size() - n2) + this->throw_length_error(); + return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, + s, s + Traits::length(s)); + } + + //! Effects: Replaces a substring of *this with n1 copies of c. + basic_string& replace(size_type pos, size_type n1, + size_type n2, CharT c) + { + if (pos > size()) + this->throw_out_of_range(); + const size_type len = min_value(n1, size() - pos); + if (n2 > this->max_size() || size() - len >= this->max_size() - n2) + this->throw_length_error(); + return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, n2, c); + } + + //! Effects: Replaces a substring of *this with the string s. + basic_string& replace(iterator first, iterator last, + const basic_string& s) + { return this->replace(first, last, s.begin(), s.end()); } + + //! Effects: Replaces a substring of *this with the first n characters of s. + basic_string& replace(iterator first, iterator last, + const CharT* s, size_type n) + { return this->replace(first, last, s, s + n); } + + //! Effects: Replaces a substring of *this with a null-terminated character array. + basic_string& replace(iterator first, iterator last, + const CharT* s) + { return this->replace(first, last, s, s + Traits::length(s)); } + + //! Effects: Replaces a substring of *this with n copies of c. + basic_string& replace(iterator first, iterator last, + size_type n, CharT c) + { + const size_type len = static_cast(last - first); + if (len >= n) { + Traits::assign(detail::get_pointer(first), n, c); + erase(first + n, last); + } + else { + Traits::assign(detail::get_pointer(first), len, c); + insert(last, n - len, c); + } + return *this; + } + + //! Effects: Replaces a substring of *this with the range [f, l) + template + basic_string& replace(iterator first, iterator last, + InputIter f, InputIter l) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + return this->priv_replace_dispatch(first, last, f, l, Result()); + } + + //! Effects: Copies a substring of *this to a buffer. + size_type copy(CharT* s, size_type n, size_type pos = 0) const + { + if (pos > size()) + this->throw_out_of_range(); + const size_type len = min_value(n, size() - pos); + Traits::copy(s, detail::get_pointer(this->priv_addr() + pos), len); + return len; + } + + //! Effects: Swaps the contents of two strings. + void swap(basic_string& s) + { base_t::swap(s); } + + //! Effects: Swaps the contents of two strings. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object& ms) + { this->swap(ms.get()); } + #else + void swap(basic_string && ms) + { this->swap(ms); } + #endif + + //! Returns: Returns a pointer to a null-terminated array of characters + //! representing the string's contents. For any string s it is guaranteed + //! that the first s.size() characters in the array pointed to by s.c_str() + //! are equal to the character in s, and that s.c_str()[s.size()] is a null + //! character. Note, however, that it not necessarily the first null character. + //! Characters within a string are permitted to be null. + const CharT* c_str() const + { return detail::get_pointer(this->priv_addr()); } + + //! Returns: Returns a pointer to an array of characters, not necessarily + //! null-terminated, representing the string's contents. data() is permitted, + //! but not required, to be identical to c_str(). The first size() characters + //! of that array are guaranteed to be identical to the characters in *this. + //! The return value of data() is never a null pointer, even if size() is zero. + const CharT* data() const + { return detail::get_pointer(this->priv_addr()); } + + //! Effects: Searches for s as a substring of *this, beginning at + //! character pos of *this. + size_type find(const basic_string& s, size_type pos = 0) const + { return find(s.c_str(), pos, s.size()); } + + //! Effects: Searches for a null-terminated character array as a + //! substring of *this, beginning at character pos of *this. + size_type find(const CharT* s, size_type pos = 0) const + { return find(s, pos, Traits::length(s)); } + + //! Effects: Searches for the first n characters of s as a substring + //! of *this, beginning at character pos of *this. + size_type find(const CharT* s, size_type pos, size_type n) const + { + if (pos + n > size()) + return npos; + else { + pointer finish = this->priv_addr() + this->priv_size(); + const const_iterator result = + std::search(detail::get_pointer(this->priv_addr() + pos), + detail::get_pointer(finish), + s, s + n, Eq_traits()); + return result != finish ? result - begin() : npos; + } + } + + //! Effects: Searches for the character c, beginning at character + //! position pos. + size_type find(CharT c, size_type pos = 0) const + { + if (pos >= size()) + return npos; + else { + pointer finish = this->priv_addr() + this->priv_size(); + const const_iterator result = + std::find_if(this->priv_addr() + pos, finish, + std::bind2nd(Eq_traits(), c)); + return result != finish ? result - begin() : npos; + } + } + + //! Effects: Searches backward for s as a substring of *this, + //! beginning at character position min(pos, size()) + size_type rfind(const basic_string& s, size_type pos = npos) const + { return rfind(s.c_str(), pos, s.size()); } + + //! Effects: Searches backward for a null-terminated character array + //! as a substring of *this, beginning at character min(pos, size()) + size_type rfind(const CharT* s, size_type pos = npos) const + { return rfind(s, pos, Traits::length(s)); } + + //! Effects: Searches backward for the first n characters of s as a + //! substring of *this, beginning at character position min(pos, size()). + size_type rfind(const CharT* s, size_type pos, size_type n) const + { + const std::size_t len = size(); + + if (n > len) + return npos; + else if (n == 0) + return min_value(len, pos); + else { + const const_iterator last = begin() + min_value(len - n, pos) + n; + const const_iterator result = find_end(begin(), last, + s, s + n, + Eq_traits()); + return result != last ? result - begin() : npos; + } + } + + //! Effects: Searches backward for a null-terminated character array + //! as a substring of *this, beginning at character min(pos, size()). + size_type rfind(CharT c, size_type pos = npos) const + { + const size_type len = size(); + + if (len < 1) + return npos; + else { + const const_iterator last = begin() + min_value(len - 1, pos) + 1; + const_reverse_iterator rresult = + std::find_if(const_reverse_iterator(last), rend(), + std::bind2nd(Eq_traits(), c)); + return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + } + } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is equal to any character within s. + size_type find_first_of(const basic_string& s, size_type pos = 0) const + { return find_first_of(s.c_str(), pos, s.size()); } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is equal to any character within s. + size_type find_first_of(const CharT* s, size_type pos = 0) const + { return find_first_of(s, pos, Traits::length(s)); } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is equal to any character within the first n characters of s. + size_type find_first_of(const CharT* s, size_type pos, + size_type n) const + { + if (pos >= size()) + return npos; + else { + pointer finish = this->priv_addr() + this->priv_size(); + const_iterator result = std::find_first_of(this->priv_addr() + pos, finish, + s, s + n, + Eq_traits()); + return result != finish ? result - begin() : npos; + } + } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is equal to c. + size_type find_first_of(CharT c, size_type pos = 0) const + { return find(c, pos); } + + //! Effects: Searches backward within *this, beginning at min(pos, size()), + //! for the first character that is equal to any character within s. + size_type find_last_of(const basic_string& s, + size_type pos = npos) const + { return find_last_of(s.c_str(), pos, s.size()); } + + //! Effects: Searches backward *this, beginning at min(pos, size()), for + //! the first character that is equal to any character within s. + size_type find_last_of(const CharT* s, size_type pos = npos) const + { return find_last_of(s, pos, Traits::length(s)); } + + //! Effects: Searches backward within *this, beginning at min(pos, size()), + //! for the first character that is equal to any character within the first n + //! characters of s. + size_type find_last_of(const CharT* s, size_type pos, size_type n) const + { + const size_type len = size(); + + if (len < 1) + return npos; + else { + const const_iterator last = this->priv_addr() + min_value(len - 1, pos) + 1; + const const_reverse_iterator rresult = + std::find_first_of(const_reverse_iterator(last), rend(), + s, s + n, + Eq_traits()); + return rresult != rend() ? (rresult.base() - 1) - this->priv_addr() : npos; + } + } + + //! Effects: Searches backward *this, beginning at min(pos, size()), for + //! the first character that is equal to c. + size_type find_last_of(CharT c, size_type pos = npos) const + { return rfind(c, pos); } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is not equal to any character within s. + size_type find_first_not_of(const basic_string& s, + size_type pos = 0) const + { return find_first_not_of(s.c_str(), pos, s.size()); } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is not equal to any character within s. + size_type find_first_not_of(const CharT* s, size_type pos = 0) const + { return find_first_not_of(s, pos, Traits::length(s)); } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is not equal to any character within the first n + //! characters of s. + size_type find_first_not_of(const CharT* s, size_type pos, + size_type n) const + { + if (pos > size()) + return npos; + else { + pointer finish = this->priv_addr() + this->priv_size(); + const_iterator result = std::find_if(this->priv_addr() + pos, finish, + Not_within_traits(s, s + n)); + return result != finish ? result - this->priv_addr() : npos; + } + } + + //! Effects: Searches within *this, beginning at pos, for the first + //! character that is not equal to c. + size_type find_first_not_of(CharT c, size_type pos = 0) const + { + if (pos > size()) + return npos; + else { + pointer finish = this->priv_addr() + this->priv_size(); + const_iterator result + = std::find_if(this->priv_addr() + pos, finish, + std::not1(std::bind2nd(Eq_traits(), c))); + return result != finish ? result - begin() : npos; + } + } + + //! Effects: Searches backward within *this, beginning at min(pos, size()), + //! for the first character that is not equal to any character within s. + size_type find_last_not_of(const basic_string& s, + size_type pos = npos) const + { return find_last_not_of(s.c_str(), pos, s.size()); } + + //! Effects: Searches backward *this, beginning at min(pos, size()), + //! for the first character that is not equal to any character within s. + size_type find_last_not_of(const CharT* s, size_type pos = npos) const + { return find_last_not_of(s, pos, Traits::length(s)); } + + //! Effects: Searches backward within *this, beginning at min(pos, size()), + //! for the first character that is not equal to any character within the first + //! n characters of s. + size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const + { + const size_type len = size(); + + if (len < 1) + return npos; + else { + const const_iterator last = begin() + min_value(len - 1, pos) + 1; + const const_reverse_iterator rresult = + std::find_if(const_reverse_iterator(last), rend(), + Not_within_traits(s, s + n)); + return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + } + } + + //! Effects: Searches backward *this, beginning at min(pos, size()), + //! for the first character that is not equal to c. + size_type find_last_not_of(CharT c, size_type pos = npos) const + { + const size_type len = size(); + + if (len < 1) + return npos; + else { + const const_iterator last = begin() + min_value(len - 1, pos) + 1; + const_reverse_iterator rresult = + std::find_if(const_reverse_iterator(last), rend(), + std::not1(std::bind2nd(Eq_traits(), c))); + return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + } + } + + //! Effects: Returns a substring of *this. + basic_string substr(size_type pos = 0, size_type n = npos) const + { + if (pos > size()) + this->throw_out_of_range(); + return basic_string(this->priv_addr() + pos, + this->priv_addr() + pos + min_value(n, size() - pos), this->alloc()); + } + + //! Effects: Three-way lexicographical comparison of s and *this. + int compare(const basic_string& s) const + { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s.priv_addr(), s.priv_addr() + s.priv_size()); } + + //! Effects: Three-way lexicographical comparison of s and a substring + //! of *this. + int compare(size_type pos1, size_type n1, const basic_string& s) const + { + if (pos1 > size()) + this->throw_out_of_range(); + return s_compare(this->priv_addr() + pos1, + this->priv_addr() + pos1 + min_value(n1, size() - pos1), + s.priv_addr(), s.priv_addr() + s.priv_size()); + } + + //! Effects: Three-way lexicographical comparison of a substring of s + //! and a substring of *this. + int compare(size_type pos1, size_type n1, + const basic_string& s, + size_type pos2, size_type n2) const { + if (pos1 > size() || pos2 > s.size()) + this->throw_out_of_range(); + return s_compare(this->priv_addr() + pos1, + this->priv_addr() + pos1 + min_value(n1, size() - pos1), + s.priv_addr() + pos2, + s.priv_addr() + pos2 + min_value(n2, size() - pos2)); + } + + //! Effects: Three-way lexicographical comparison of s and *this. + int compare(const CharT* s) const + { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s, s + Traits::length(s)); } + + + //! Effects: Three-way lexicographical comparison of the first + //! min(len, traits::length(s) characters of s and a substring of *this. + int compare(size_type pos1, size_type n1, const CharT* s, + size_type n2 = npos) const + { + if (pos1 > size()) + this->throw_out_of_range(); + return s_compare(this->priv_addr() + pos1, + this->priv_addr() + pos1 + min_value(n1, size() - pos1), + s, s + n2); + } + + /// @cond + private: + static int s_compare(const_pointer f1, const_pointer l1, + const_pointer f2, const_pointer l2) + { + const std::ptrdiff_t n1 = l1 - f1; + const std::ptrdiff_t n2 = l2 - f2; + const int cmp = Traits::compare(detail::get_pointer(f1), + detail::get_pointer(f2), + min_value(n1, n2)); + return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)); + } + + void priv_construct_null(pointer p) + { this->construct(p, 0); } + + static CharT priv_null() + { return (CharT) 0; } + + // Helper functions used by constructors. It is a severe error for + // any of them to be called anywhere except from within constructors. + void priv_terminate_string() + { this->priv_construct_null(this->priv_addr() + this->priv_size()); } + + template + void priv_range_initialize(InputIter f, InputIter l, + std::input_iterator_tag) + { + this->allocate_initial_block(InternalBufferChars); + this->priv_construct_null(this->priv_addr() + this->priv_size()); + this->append(f, l); + } + + template + void priv_range_initialize(ForwardIter f, ForwardIter l, + std::forward_iterator_tag) + { + difference_type n = std::distance(f, l); + this->allocate_initial_block(max_value(n+1, InternalBufferChars)); + priv_uninitialized_copy(f, l, this->priv_addr()); + this->priv_size(n); + this->priv_terminate_string(); + } + + template + void priv_range_initialize(InputIter f, InputIter l) + { + typedef typename std::iterator_traits::iterator_category Category; + this->priv_range_initialize(f, l, Category()); + } + + template + void priv_initialize_dispatch(Integer n, Integer x, detail::true_) + { + this->allocate_initial_block(max_value(n+1, InternalBufferChars)); + priv_uninitialized_fill_n(this->priv_addr(), n, x); + this->priv_size(n); + this->priv_terminate_string(); + } + + template + void priv_initialize_dispatch(InputIter f, InputIter l, detail::false_) + { this->priv_range_initialize(f, l); } + + template inline + void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val) + { + //Save initial position + FwdIt init = first; + + BOOST_TRY{ + //Construct objects + for (; count--; ++first){ + this->construct(first, val); + } + } + BOOST_CATCH(...){ + //Call destructors + for (; init != first; ++init){ + this->destroy(init); + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template inline + size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest) + { + //Save initial destination position + FwdIt dest_init = dest; + size_type constructed = 0; + + BOOST_TRY{ + //Try to build objects + for (; first != last; ++dest, ++first, ++constructed){ + this->construct(dest, *first); + } + } + BOOST_CATCH(...){ + //Call destructors + for (; constructed--; ++dest_init){ + this->destroy(dest_init); + } + BOOST_RETHROW + } + BOOST_CATCH_END + return (constructed); + } + + template + basic_string& priv_assign_dispatch(Integer n, Integer x, detail::true_) + { return this->assign((size_type) n, (CharT) x); } + + template + basic_string& priv_assign_dispatch(InputIter f, InputIter l, + detail::false_) + { + size_type cur = 0; + CharT *ptr = detail::get_pointer(this->priv_addr()); + while (f != l && cur != this->priv_size()) { + Traits::assign(*ptr, *f); + ++f; + ++cur; + ++ptr; + } + if (f == l) + this->erase(this->priv_addr() + cur, this->priv_addr() + this->priv_size()); + else + this->append(f, l); + return *this; + } + + template + void priv_insert(iterator p, InputIter first, InputIter last, std::input_iterator_tag) + { + for ( ; first != last; ++first, ++p) { + p = this->insert(p, *first); + } + } + + template + void priv_insert(iterator position, ForwardIter first, + ForwardIter last, std::forward_iterator_tag) + { + if (first != last) { + size_type n = std::distance(first, last); + size_type remaining = this->capacity() - this->priv_size(); + const size_type old_size = this->size(); + pointer old_start = this->priv_addr(); + bool enough_capacity = false; + std::pair allocation_ret; + size_type new_cap = 0; + + //Check if we have enough capacity + if (remaining >= n){ + enough_capacity = true; + } + else { + //Otherwise expand current buffer or allocate new storage + new_cap = this->next_capacity(n); + allocation_ret = this->allocation_command + (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, + new_cap, new_cap, old_start); + + //Check forward expansion + if(old_start == allocation_ret.first){ + enough_capacity = true; + this->priv_storage(new_cap); + } + } + + //Reuse same buffer + if(enough_capacity){ + const size_type elems_after = + this->priv_size() - (position - this->priv_addr()); + size_type old_length = this->priv_size(); + if (elems_after >= n) { + pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1; + priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1), + pointer_past_last, pointer_past_last); + + this->priv_size(this->priv_size()+n); + Traits::move(detail::get_pointer(position + n), + detail::get_pointer(position), + (elems_after - n) + 1); + this->priv_copy(first, last, position); + } + else { + ForwardIter mid = first; + std::advance(mid, elems_after + 1); + + priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1); + this->priv_size(this->priv_size() + (n - elems_after)); + priv_uninitialized_copy + (position, this->priv_addr() + old_length + 1, + this->priv_addr() + this->priv_size()); + this->priv_size(this->priv_size() + elems_after); + this->priv_copy(first, mid, position); + } + } + else{ + pointer new_start = allocation_ret.first; + if(!allocation_ret.second){ + //Copy data to new buffer + size_type new_length = 0; + //This can't throw, since characters are POD + new_length += priv_uninitialized_copy + (this->priv_addr(), position, new_start); + new_length += priv_uninitialized_copy + (first, last, new_start + new_length); + new_length += priv_uninitialized_copy + (position, this->priv_addr() + this->priv_size(), + new_start + new_length); + this->priv_construct_null(new_start + new_length); + + this->deallocate_block(); + this->is_short(false); + this->priv_addr(new_start); + this->priv_size(new_length); + this->priv_storage(new_cap); + } + else{ + //value_type is POD, so backwards expansion is much easier + //than with vector + value_type *oldbuf = detail::get_pointer(old_start); + value_type *newbuf = detail::get_pointer(new_start); + value_type *pos = detail::get_pointer(position); + size_type before = pos - oldbuf; + + //First move old data + Traits::move(newbuf, oldbuf, before); + Traits::move(newbuf + before + n, pos, old_size - before); + //Now initialize the new data + priv_uninitialized_copy(first, last, new_start + before); + this->priv_construct_null(new_start + (old_size + n)); + this->is_short(false); + this->priv_addr(new_start); + this->priv_size(old_size + n); + this->priv_storage(new_cap); + } + } + } + } + + template + void priv_insert_dispatch(iterator p, Integer n, Integer x, + detail::true_) + { insert(p, (size_type) n, (CharT) x); } + + template + void priv_insert_dispatch(iterator p, InputIter first, InputIter last, + detail::false_) + { + typedef typename std::iterator_traits::iterator_category Category; + priv_insert(p, first, last, Category()); + } + + template + void priv_copy(InputIterator first, InputIterator last, iterator result) + { + for ( ; first != last; ++first, ++result) + Traits::assign(*result, *first); + } + + void priv_copy(const CharT* first, const CharT* last, CharT* result) + { Traits::copy(result, first, last - first); } + + template + basic_string& priv_replace_dispatch(iterator first, iterator last, + Integer n, Integer x, + detail::true_) + { return this->replace(first, last, (size_type) n, (CharT) x); } + + template + basic_string& priv_replace_dispatch(iterator first, iterator last, + InputIter f, InputIter l, + detail::false_) + { + typedef typename std::iterator_traits::iterator_category Category; + return this->priv_replace(first, last, f, l, Category()); + } + + + template + basic_string& priv_replace(iterator first, iterator last, + InputIter f, InputIter l, std::input_iterator_tag) + { + for ( ; first != last && f != l; ++first, ++f) + Traits::assign(*first, *f); + + if (f == l) + this->erase(first, last); + else + this->insert(last, f, l); + return *this; + } + + template + basic_string& priv_replace(iterator first, iterator last, + ForwardIter f, ForwardIter l, + std::forward_iterator_tag) + { + difference_type n = std::distance(f, l); + const difference_type len = last - first; + if (len >= n) { + this->priv_copy(f, l, first); + this->erase(first + n, last); + } + else { + ForwardIter m = f; + std::advance(m, len); + this->priv_copy(f, m, first); + this->insert(last, m, l); + } + return *this; + } + /// @endcond +}; + +template +const typename basic_string::size_type +basic_string::npos + = (typename basic_string::size_type) -1; + +// ------------------------------------------------------------ +// Non-member functions. + +// Operator+ + +template +inline basic_string +operator+(const basic_string& x, + const basic_string& y) +{ + typedef basic_string str_t; + typedef typename str_t::reserve_t reserve_t; + reserve_t reserve; + str_t result(reserve, x.size() + y.size(), x.alloc()); + result.append(x); + result.append(y); + return result; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(const detail::moved_object >& mx, + const basic_string& y) +{ + mx.get() += y; + return mx; +} +#else +template +basic_string && +operator+(basic_string && mx, + const basic_string& y) +{ + mx += y; + return move(mx); +} +#endif + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(const basic_string& x, + const detail::moved_object >& my) +{ + typedef typename basic_string::size_type size_type; + return my.get().replace(size_type(0), size_type(0), x); +} +#else +template +inline basic_string && +operator+(const basic_string& x, + basic_string && my) +{ + typedef typename basic_string::size_type size_type; + return my.replace(size_type(0), size_type(0), x); +} +#endif + +template +inline basic_string +operator+(const CharT* s, const basic_string& y) +{ + typedef basic_string str_t; + typedef typename str_t::reserve_t reserve_t; + reserve_t reserve; + const std::size_t n = Traits::length(s); + str_t result(reserve, n + y.size()); + result.append(s, s + n); + result.append(y); + return result; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(const CharT* s, + const detail::moved_object >& my) +{ + typedef typename basic_string::size_type size_type; + return my.get().replace(size_type(0), size_type(0), s); +} +#else +template +inline basic_string && +operator+(const CharT* s, + basic_string && my) +{ + typedef typename basic_string::size_type size_type; + return move(my.get().replace(size_type(0), size_type(0), s)); +} +#endif + +template +inline basic_string +operator+(CharT c, const basic_string& y) +{ + typedef basic_string str_t; + typedef typename str_t::reserve_t reserve_t; + reserve_t reserve; + str_t result(reserve, 1 + y.size()); + result.push_back(c); + result.append(y); + return result; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(CharT c, + const detail::moved_object >& my) +{ + typedef typename basic_string::size_type size_type; + return my.get().replace(size_type(0), size_type(0), &c, &c + 1); +} +#else +template +inline basic_string && +operator+(CharT c, + basic_string && my) +{ + typedef typename basic_string::size_type size_type; + return my.replace(size_type(0), size_type(0), &c, &c + 1); +} +#endif + +template +inline basic_string +operator+(const basic_string& x, const CharT* s) +{ + typedef basic_string str_t; + typedef typename str_t::reserve_t reserve_t; + reserve_t reserve; + const std::size_t n = Traits::length(s); + str_t result(reserve, x.size() + n, x.alloc()); + result.append(x); + result.append(s, s + n); + return result; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(const detail::moved_object >& mx, + const CharT* s) +{ + mx.get() += s; + return mx; +} +#else +template +basic_string && +operator+(basic_string && mx, + const CharT* s) +{ + mx += s; + return move(mx); +} +#endif + +template +inline basic_string +operator+(const basic_string& x, const CharT c) +{ + typedef basic_string str_t; + typedef typename str_t::reserve_t reserve_t; + reserve_t reserve; + str_t result(reserve, x.size() + 1, x.alloc()); + result.append(x); + result.push_back(c); + return result; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline detail::moved_object > +operator+(const detail::moved_object >& mx, + const CharT c) +{ + mx.get() += c; + return mx; +} +#else +template +basic_string && +operator+(basic_string && mx, const CharT c) +{ + mx += c; + return move(mx); +} +#endif + +// Operator== and operator!= + +template +inline bool +operator==(const basic_string& x, + const basic_string& y) +{ + return x.size() == y.size() && + Traits::compare(x.data(), y.data(), x.size()) == 0; +} + +template +inline bool +operator==(const CharT* s, const basic_string& y) +{ + std::size_t n = Traits::length(s); + return n == y.size() && Traits::compare(s, y.data(), n) == 0; +} + +template +inline bool +operator==(const basic_string& x, const CharT* s) +{ + std::size_t n = Traits::length(s); + return x.size() == n && Traits::compare(x.data(), s, n) == 0; +} + +template +inline bool +operator!=(const basic_string& x, + const basic_string& y) + { return !(x == y); } + +template +inline bool +operator!=(const CharT* s, const basic_string& y) + { return !(s == y); } + +template +inline bool +operator!=(const basic_string& x, const CharT* s) + { return !(x == s); } + + +// Operator< (and also >, <=, and >=). + +template +inline bool +operator<(const basic_string& x, + const basic_string& y) +{ + return x.compare(y) < 0; +// return basic_string +// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0; +} + +template +inline bool +operator<(const CharT* s, const basic_string& y) +{ + return y.compare(s) > 0; +// std::size_t n = Traits::length(s); +// return basic_string +// ::s_compare(s, s + n, y.begin(), y.end()) < 0; +} + +template +inline bool +operator<(const basic_string& x, + const CharT* s) +{ + return x.compare(s) < 0; +// std::size_t n = Traits::length(s); +// return basic_string +// ::s_compare(x.begin(), x.end(), s, s + n) < 0; +} + +template +inline bool +operator>(const basic_string& x, + const basic_string& y) { + return y < x; +} + +template +inline bool +operator>(const CharT* s, const basic_string& y) { + return y < s; +} + +template +inline bool +operator>(const basic_string& x, const CharT* s) +{ + return s < x; +} + +template +inline bool +operator<=(const basic_string& x, + const basic_string& y) +{ + return !(y < x); +} + +template +inline bool +operator<=(const CharT* s, const basic_string& y) + { return !(y < s); } + +template +inline bool +operator<=(const basic_string& x, const CharT* s) + { return !(s < x); } + +template +inline bool +operator>=(const basic_string& x, + const basic_string& y) + { return !(x < y); } + +template +inline bool +operator>=(const CharT* s, const basic_string& y) + { return !(s < y); } + +template +inline bool +operator>=(const basic_string& x, const CharT* s) + { return !(x < s); } + +// Swap. +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(basic_string& x, + basic_string& y) +{ x.swap(y); } + +template +inline void swap(const detail::moved_object >& mx, + basic_string& y) +{ mx.get().swap(y); } + +template +inline void swap(basic_string& x, + const detail::moved_object >& my) +{ x.swap(my.get()); } +#else +template +inline void swap(basic_string && x, + basic_string &&y) +{ x.swap(y); } +#endif + +/// @cond +// I/O. +namespace detail { + +template +inline bool +interprocess_string_fill(std::basic_ostream& os, + std::basic_streambuf* buf, + std::size_t n) +{ + CharT f = os.fill(); + std::size_t i; + bool ok = true; + + for (i = 0; i < n; i++) + ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof()); + return ok; +} + +} //namespace detail { +/// @endcond + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + const basic_string& s) + #else + const basic_string&&s) + #endif +{ + typename std::basic_ostream::sentry sentry(os); + bool ok = false; + + if (sentry) { + ok = true; + std::size_t n = s.size(); + std::size_t pad_len = 0; + const bool left = (os.flags() & std::ios::left) != 0; + const std::size_t w = os.width(0); + std::basic_streambuf* buf = os.rdbuf(); + + if (w != 0 && n < w) + pad_len = w - n; + + if (!left) + ok = detail::interprocess_string_fill(os, buf, pad_len); + + ok = ok && + buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n); + + if (left) + ok = ok && detail::interprocess_string_fill(os, buf, pad_len); + } + + if (!ok) + os.setstate(std::ios_base::failbit); + + return os; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const detail::moved_object >& ms) +{ return os << ms.get(); } +#endif + + +template +std::basic_istream& +operator>>(std::basic_istream& is, + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string& s) + #else + basic_string&&s) + #endif +{ + typename std::basic_istream::sentry sentry(is); + + if (sentry) { + std::basic_streambuf* buf = is.rdbuf(); + const std::ctype& ctype = std::use_facet >(is.getloc()); + + s.clear(); + std::size_t n = is.width(0); + if (n == 0) + n = static_cast(-1); + else + s.reserve(n); + + while (n-- > 0) { + typename Traits::int_type c1 = buf->sbumpc(); + + if (Traits::eq_int_type(c1, Traits::eof())) { + is.setstate(std::ios_base::eofbit); + break; + } + else { + CharT c = Traits::to_char_type(c1); + + if (ctype.is(std::ctype::space, c)) { + if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof())) + is.setstate(std::ios_base::failbit); + break; + } + else + s.push_back(c); + } + } + + // If we have read no characters, then set failbit. + if (s.size() == 0) + is.setstate(std::ios_base::failbit); + } + else + is.setstate(std::ios_base::failbit); + + return is; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +std::basic_istream& +operator>>(std::basic_istream& is, + const detail::moved_object >& ms) +{ return is >> ms.get(); } +#endif + +template +std::basic_istream& +getline(std::istream& is, + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_string& s, + #else + basic_string&&s, + #endif + CharT delim) +{ + std::size_t nread = 0; + typename std::basic_istream::sentry sentry(is, true); + if (sentry) { + std::basic_streambuf* buf = is.rdbuf(); + s.clear(); + + int c1; + while (nread < s.max_size()) { + int c1 = buf->sbumpc(); + if (Traits::eq_int_type(c1, Traits::eof())) { + is.setstate(std::ios_base::eofbit); + break; + } + else { + ++nread; + CharT c = Traits::to_char_type(c1); + if (!Traits::eq(c, delim)) + s.push_back(c); + else + break; // Character is extracted but not appended. + } + } + } + if (nread == 0 || nread >= s.max_size()) + is.setstate(std::ios_base::failbit); + + return is; +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +std::basic_istream& +getline(std::istream& is, + const detail::moved_object >& ms, + CharT delim) +{ return getline(is, ms.get(), delim); } +#endif + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline std::basic_istream& +getline(std::basic_istream& is, + basic_string& s) +{ + return getline(is, s, '\n'); +} + +template +std::basic_istream& +getline(std::istream& is, + const detail::moved_object >& ms) +{ return getline(is, ms.get()); } +#else +template +std::basic_istream& +getline(std::istream& is, + basic_string && ms) +{ return getline(is, ms); } +#endif + +template +inline std::size_t hash_value(basic_string, A> const& v) +{ + return hash_range(v.begin(), v.end()); +} + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = has_trivial_destructor::value }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess + +#include + +#endif // BOOST_INTERPROCESS_STRING_HPP diff --git a/thirdparty/boost/interprocess/containers/vector.hpp b/thirdparty/boost/interprocess/containers/vector.hpp new file mode 100644 index 0000000..eaa3ab0 --- /dev/null +++ b/thirdparty/boost/interprocess/containers/vector.hpp @@ -0,0 +1,1879 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's stl_vector.h file. Modified by Ion Gaztanaga. +// Renaming, isolating and porting to generic algorithms. Pointer typedef +// set to allocator::pointer to allow placing it in shared memory. +// +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1994 +// Hewlett-Packard Company +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Hewlett-Packard Company makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +// +// Copyright (c) 1996 +// Silicon Graphics Computer Systems, Inc. +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Silicon Graphics makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. + +#ifndef BOOST_INTERPROCESS_VECTOR_HPP +#define BOOST_INTERPROCESS_VECTOR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { + +/// @cond + +namespace detail { + +//! Const vector_iterator used to iterate through a vector. +template +class vector_const_iterator + : public std::iterator::value_type + ,typename std::iterator_traits::difference_type + ,typename pointer_to_other + ::value_type + >::type + ,const typename std::iterator_traits::value_type &> +{ + public: + typedef const typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename pointer_to_other::type pointer; + typedef value_type& reference; + + /// @cond + protected: + Pointer m_ptr; + + public: + Pointer get_ptr() const { return m_ptr; } + explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){} + /// @endcond + + public: + + //Constructors + vector_const_iterator() : m_ptr(0){} + + //Pointer like operators + reference operator*() const + { return *m_ptr; } + + const value_type * operator->() const + { return detail::get_pointer(m_ptr); } + + reference operator[](difference_type off) const + { return m_ptr[off]; } + + //Increment / Decrement + vector_const_iterator& operator++() + { ++m_ptr; return *this; } + + vector_const_iterator operator++(int) + { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); } + + vector_const_iterator& operator--() + { --m_ptr; return *this; } + + vector_const_iterator operator--(int) + { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); } + + //Arithmetic + vector_const_iterator& operator+=(difference_type off) + { m_ptr += off; return *this; } + + vector_const_iterator operator+(difference_type off) const + { return vector_const_iterator(m_ptr+off); } + + friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right) + { return vector_const_iterator(off + right.m_ptr); } + + vector_const_iterator& operator-=(difference_type off) + { m_ptr -= off; return *this; } + + vector_const_iterator operator-(difference_type off) const + { return vector_const_iterator(m_ptr-off); } + + difference_type operator-(const vector_const_iterator& right) const + { return m_ptr - right.m_ptr; } + + //Comparison operators + bool operator== (const vector_const_iterator& r) const + { return m_ptr == r.m_ptr; } + + bool operator!= (const vector_const_iterator& r) const + { return m_ptr != r.m_ptr; } + + bool operator< (const vector_const_iterator& r) const + { return m_ptr < r.m_ptr; } + + bool operator<= (const vector_const_iterator& r) const + { return m_ptr <= r.m_ptr; } + + bool operator> (const vector_const_iterator& r) const + { return m_ptr > r.m_ptr; } + + bool operator>= (const vector_const_iterator& r) const + { return m_ptr >= r.m_ptr; } +}; + +//! Iterator used to iterate through a vector +template +class vector_iterator + : public vector_const_iterator +{ + public: + explicit vector_iterator(Pointer ptr) + : vector_const_iterator(ptr) + {} + + public: + typedef typename std::iterator_traits::value_type value_type; + typedef typename vector_const_iterator::difference_type difference_type; + typedef Pointer pointer; + typedef value_type& reference; + + //Constructors + vector_iterator() + {} + + //Pointer like operators + reference operator*() const + { return *this->m_ptr; } + + value_type* operator->() const + { return detail::get_pointer(this->m_ptr); } + + reference operator[](difference_type off) const + { return this->m_ptr[off]; } + + //Increment / Decrement + vector_iterator& operator++() + { ++this->m_ptr; return *this; } + + vector_iterator operator++(int) + { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); } + + vector_iterator& operator--() + { --this->m_ptr; return *this; } + + vector_iterator operator--(int) + { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); } + + // Arithmetic + vector_iterator& operator+=(difference_type off) + { this->m_ptr += off; return *this; } + + vector_iterator operator+(difference_type off) const + { return vector_iterator(this->m_ptr+off); } + + friend vector_iterator operator+(difference_type off, const vector_iterator& right) + { return vector_iterator(off + right.m_ptr); } + + vector_iterator& operator-=(difference_type off) + { this->m_ptr -= off; return *this; } + + vector_iterator operator-(difference_type off) const + { return vector_iterator(this->m_ptr-off); } + + difference_type operator-(const vector_const_iterator& right) const + { return static_cast&>(*this) - right; } +}; + +//!This struct deallocates and allocated memory +template +struct vector_alloc_holder +{ + typedef typename A::pointer pointer; + typedef typename A::size_type size_type; + typedef typename A::value_type value_type; + + static const bool trivial_dctr = boost::has_trivial_destructor::value; + static const bool trivial_dctr_after_move = + has_trivial_destructor_after_move::value || trivial_dctr; + static const bool trivial_copy = has_trivial_copy::value; + static const bool nothrow_copy = has_nothrow_copy::value; + static const bool trivial_assign = has_trivial_assign::value; + static const bool nothrow_assign = has_nothrow_assign::value; + + //Constructor, does not throw + vector_alloc_holder(const A &a) + : members_(a) + {} + + //Constructor, does not throw + vector_alloc_holder(const vector_alloc_holder &h) + : members_(h.alloc()) + {} + + //Destructor + ~vector_alloc_holder() + { this->prot_deallocate(); } + + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + typedef detail::integral_constant::value> alloc_version; + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, const pointer &reuse = 0) + { + return allocation_command(command, limit_size, preferred_size, + received_size, reuse, alloc_version()); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, + const pointer &reuse, + allocator_v1) + { + (void)limit_size; + (void)reuse; + if(!(command & allocate_new)) + return std::pair(0, 0); + received_size = preferred_size; + return std::make_pair(this->alloc().allocate(received_size), false); + } + + std::pair + allocation_command(allocation_type command, + size_type limit_size, + size_type preferred_size, + size_type &received_size, + const pointer &reuse, + allocator_v2) + { + return this->alloc().allocation_command(command, limit_size, preferred_size, + received_size, reuse); + } + + size_type next_capacity(size_type additional_objects) const + { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); } + + struct members_holder + : public A + { + private: + members_holder(const members_holder&); + + public: + members_holder(const A &alloc) + : A(alloc), m_start(0), m_size(0), m_capacity(0) + {} + + pointer m_start; + size_type m_size; + size_type m_capacity; + } members_; + + protected: + void prot_deallocate() + { + if(!this->members_.m_capacity) return; + this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); + this->members_.m_start = 0; + this->members_.m_size = 0; + this->members_.m_capacity = 0; + } + + void destroy(value_type* p) + { + if(!trivial_dctr) + detail::get_pointer(p)->~value_type(); + } + + void destroy_n(value_type* p, size_type n) + { + if(!trivial_dctr) + for(; n--; ++p) p->~value_type(); + } + + A &alloc() + { return members_; } + + const A &alloc() const + { return members_; } +}; + +} //namespace detail { +/// @endcond + +//! A vector is a sequence that supports random access to elements, constant +//! time insertion and removal of elements at the end, and linear time insertion +//! and removal of elements at the beginning or in the middle. The number of +//! elements in a vector may vary dynamically; memory management is automatic. +//! boost::interprocess::vector is similar to std::vector but it's compatible +//! with shared memory and memory mapped files. +template +class vector : private detail::vector_alloc_holder +{ + /// @cond + typedef vector self_t; + typedef detail::vector_alloc_holder base_t; + /// @endcond + public: + //! The type of object, T, stored in the vector + typedef T value_type; + //! Pointer to T + typedef typename A::pointer pointer; + //! Const pointer to T + typedef typename A::const_pointer const_pointer; + //! Reference to T + typedef typename A::reference reference; + //! Const reference to T + typedef typename A::const_reference const_reference; + //! An unsigned integral type + typedef typename A::size_type size_type; + //! A signed integral type + typedef typename A::difference_type difference_type; + //! The allocator type + typedef A allocator_type; + //! The random access iterator + typedef detail::vector_iterator iterator; + //! The random access const_iterator + typedef detail::vector_const_iterator const_iterator; + + //! Iterator used to iterate backwards through a vector. + typedef std::reverse_iterator + reverse_iterator; + //! Const iterator used to iterate backwards through a vector. + typedef std::reverse_iterator + const_reverse_iterator; + //! The stored allocator type + typedef allocator_type stored_allocator_type; + + /// @cond + private: + + typedef typename base_t::allocator_v1 allocator_v1; + typedef typename base_t::allocator_v2 allocator_v2; + typedef typename base_t::alloc_version alloc_version; + + typedef constant_iterator cvalue_iterator; + typedef repeat_iterator repeat_it; + typedef detail::move_iterator repeat_move_it; + //This is the anti-exception array destructor + //to deallocate values already constructed + typedef typename detail::if_c + + ,detail::scoped_destructor_n + >::type OldArrayDestructor; + //This is the anti-exception array destructor + //to destroy objects created with copy construction + typedef typename detail::if_c + + ,detail::scoped_destructor_n + >::type UCopiedArrayDestructor; + //This is the anti-exception array deallocator + typedef typename detail::if_c + + ,detail::scoped_array_deallocator + >::type UCopiedArrayDeallocator; + + //This is the optimized move iterator for copy constructors + //so that std::copy and similar can use memcpy + typedef typename detail::if_c + + >::type copy_move_it; + + //This is the optimized move iterator for assignments + //so that std::uninitialized_copy and similar can use memcpy + typedef typename detail::if_c + + >::type assign_move_it; + /// @endcond + + public: + + //! Effects: Constructs a vector taking the allocator as parameter. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + explicit vector(const A& a = A()) + : base_t(a) + {} + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + vector(size_type n, const T& value = T(), + const allocator_type& a = allocator_type()) + : base_t(a) + { this->insert(this->end(), n, value); } + + //! Effects: Copy constructs a vector. + //! + //! Postcondition: x == *this. + //! + //! Complexity: Linear to the elements x contains. + vector(const vector& x) + : base_t((base_t&)x) + { *this = x; } + + //! Effects: Move constructor. Moves mx's resources to *this. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + vector(const detail::moved_object >& mx) + : base_t(mx.get()) + { this->swap(mx.get()); } + #else + vector(vector && mx) + : base_t(mx) + { this->swap(mx); } + #endif + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the vector. + //! + //! Throws: If allocator_type's default constructor or copy constructor + //! throws or T's constructor taking an dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + vector(InIt first, InIt last, const allocator_type& a = allocator_type()) + : base_t(a) + { this->assign(first, last); } + + //! Effects: Destroys the vector. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~vector() + { this->priv_destroy_all(); } + + //! Effects: Returns an iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return iterator(this->members_.m_start); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return const_iterator(this->members_.m_start); } + + //! Effects: Returns an iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return iterator(this->members_.m_start + this->members_.m_size); } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return const_iterator(this->members_.m_start + this->members_.m_size); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin()const + { return const_reverse_iterator(this->end());} + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return reverse_iterator(this->begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return const_reverse_iterator(this->begin()); } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() + { return *this->members_.m_start; } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const + { return *this->members_.m_start; } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference back() + { return this->members_.m_start[this->members_.m_size - 1]; } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference back() const + { return this->members_.m_start[this->members_.m_size - 1]; } + + //! Effects: Returns the number of the elements contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type size() const + { return this->members_.m_size; } + + //! Effects: Returns the largest possible size of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type max_size() const + { return this->alloc().max_size(); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return this->members_.m_capacity; } + + //! Effects: Returns true if the vector contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + bool empty() const + { return !this->members_.m_size; } + + //! Requires: size() < n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference operator[](size_type n) + { return this->members_.m_start[n]; } + + //! Requires: size() < n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference operator[](size_type n) const + { return this->members_.m_start[n]; } + + //! Requires: size() < n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + reference at(size_type n) + { this->priv_check_range(n); return this->members_.m_start[n]; } + + //! Requires: size() < n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + const_reference at(size_type n) const + { this->priv_check_range(n); return this->members_.m_start[n]; } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const + { return this->alloc(); } + + const stored_allocator_type &get_stored_allocator() const + { return this->alloc(); } + + stored_allocator_type &get_stored_allocator() + { return this->alloc(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + void reserve(size_type new_cap) + { + if (this->capacity() < new_cap){ + //There is not enough memory, allocate a new + //buffer or expand the old one. + bool same_buffer_start; + size_type real_cap = 0; + std::pair ret = + this->allocation_command + (allocate_new | expand_fwd | expand_bwd, + new_cap, new_cap, real_cap, this->members_.m_start); + + //Check for forward expansion + same_buffer_start = ret.second && this->members_.m_start == ret.first; + if(same_buffer_start){ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->members_.m_capacity = real_cap; + } + //If there is no forward expansion, move objects + else{ + //We will reuse insert code, so create a dummy input iterator + copy_move_it dummy_it(detail::get_pointer(this->members_.m_start)); + //Backwards (and possibly forward) expansion + if(ret.second){ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_range_insert_expand_backwards + ( detail::get_pointer(ret.first) + , real_cap + , detail::get_pointer(this->members_.m_start) + , dummy_it + , dummy_it + , 0); + } + //New buffer + else{ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_range_insert_new_allocation + ( detail::get_pointer(ret.first) + , real_cap + , detail::get_pointer(this->members_.m_start) + , dummy_it + , dummy_it); + } + } + } + } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to the number of elements in x. + vector& operator=(const vector& x) + { + if (&x != this){ + this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size); + } + return *this; + } + + //! Effects: Move assignment. All mx's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + vector& operator=(const detail::moved_object >& mx) + { + vector &x = mx.get(); + + if (&x != this){ + this->swap(x); + x.clear(); + } + return *this; + } + #else + vector& operator=(vector && mx) + { + vector &x = mx; + + if (&x != this){ + this->swap(x); + x.clear(); + } + return *this; + } + #endif + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + void assign(size_type n, const value_type& val) + { this->assign(cvalue_iterator(val, n), cvalue_iterator()); } + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(InIt first, InIt last) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_assign_dispatch(first, last, Result()); + } + + //! Effects: Inserts a copy of x at the end of the vector. + //! + //! Throws: If memory allocation throws or + //! T's copy constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(const T& x) + { + if (this->members_.m_size < this->members_.m_capacity){ + //There is more memory, just construct a new object at the end + new(detail::get_pointer(this->members_.m_start) + this->members_.m_size)value_type(x); + ++this->members_.m_size; + } + else{ + this->insert(this->end(), x); + } + } + + //! Effects: Constructs a new element in the end of the vector + //! and moves the resources of mx to this new element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void push_back(const detail::moved_object & mx) + { + if (this->members_.m_size < this->members_.m_capacity){ + //There is more memory, just construct a new object at the end + new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx); + ++this->members_.m_size; + } + else{ + this->insert(this->end(), mx); + } + } + #else + void push_back(T && mx) + { + if (this->members_.m_size < this->members_.m_capacity){ + //There is more memory, just construct a new object at the end + new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx)); + ++this->members_.m_size; + } + else{ + this->insert(this->end(), move(mx)); + } + } + #endif + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() + //! allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(vector& x) + { + allocator_type &this_al = this->alloc(), &other_al = x.alloc(); + //Just swap internals + detail::do_swap(this->members_.m_start, x.members_.m_start); + detail::do_swap(this->members_.m_size, x.members_.m_size); + detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); + + if (this_al != other_al){ + detail::do_swap(this_al, other_al); + } + } + + //! Effects: Swaps the contents of *this and x. + //! If this->allocator_type() != x.allocator_type() + //! allocators are also swapped. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object >& mx) + { + vector &x = mx.get(); + this->swap(x); + } + #else + void swap(vector && mx) + { + vector &x = mx; + this->swap(x); + } + #endif + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before position. + //! + //! Throws: If memory allocation throws or x's copy constructor throws. + //! + //! Complexity: If position is begin() or end(), amortized constant time + //! Linear time otherwise. + iterator insert(iterator position, const T& x) + { + //Just call more general insert(pos, size, value) and return iterator + size_type n = position - begin(); + this->insert(position, (size_type)1, x); + return iterator(this->members_.m_start + n); + } + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a new element before position with mx's resources. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: If position is begin() or end(), amortized constant time + //! Linear time otherwise. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + iterator insert(iterator position, const detail::moved_object &mx) + { + //Just call more general insert(pos, size, value) and return iterator + size_type n = position - begin(); + this->insert(position + ,repeat_move_it(repeat_it(mx.get(), 1)) + ,repeat_move_it(repeat_it())); + return iterator(this->members_.m_start + n); + } + #else + iterator insert(iterator position, T &&mx) + { + //Just call more general insert(pos, size, value) and return iterator + size_type n = position - begin(); + this->insert(position + ,repeat_move_it(repeat_it(mx, 1)) + ,repeat_move_it(repeat_it())); + return iterator(this->members_.m_start + n); + } + #endif + + //! Requires: pos must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before pos. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy constructor throws. + //! + //! Complexity: Linear to std::distance [first, last). + template + void insert(iterator pos, InIt first, InIt last) + { + //Dispatch depending on integer/iterator + const bool aux_boolean = detail::is_convertible::value; + typedef detail::bool_ Result; + this->priv_insert_dispatch(pos, first, last, Result()); + } + + //! Requires: pos must be a valid iterator of *this. + //! + //! Effects: Insert n copies of x before pos. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + void insert (iterator p, size_type n, const T& x) + { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); } + + //! Effects: Removes the last element from the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + void pop_back() + { + //Destroy last element + --this->members_.m_size; + this->destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); + } + + //! Effects: Erases the element at position pos. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements between pos and the + //! last element. Constant if pos is the first or the last element. + iterator erase(const_iterator position) + { + T *pos = detail::get_pointer(position.get_ptr()); + T *beg = detail::get_pointer(this->members_.m_start); + + std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos); + --this->members_.m_size; + //Destroy last element + base_t::destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); + return iterator(position.get_ptr()); + } + + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last. + iterator erase(const_iterator first, const_iterator last) + { + if (first != last){ // worth doing, copy down over hole + T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; + T* ptr = detail::get_pointer(std::copy + (assign_move_it(detail::get_pointer(last.get_ptr())) + ,assign_move_it(end_pos) + ,detail::get_pointer(first.get_ptr()) + )); + size_type destroyed = (end_pos - ptr); + this->destroy_n(ptr, destroyed); + this->members_.m_size -= destroyed; + } + return iterator(first.get_ptr()); + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size, const T& x) + { + pointer finish = this->members_.m_start + this->members_.m_size; + if (new_size < size()){ + //Destroy last elements + this->erase(iterator(this->members_.m_start + new_size), this->end()); + } + else{ + //Insert new elements at the end + this->insert(iterator(finish), new_size - this->size(), x); + } + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default constructed. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size) + { + if (new_size < this->size()){ + //Destroy last elements + this->erase(iterator(this->members_.m_start + new_size), this->end()); + } + else{ + size_type n = new_size - this->size(); + this->reserve(new_size); + T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size); + while(n--){ + //Default construct + new(ptr++)T(); + ++this->members_.m_size; + } + } + } + + //! Effects: Erases all the elements of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the vector. + void clear() + { this->priv_destroy_all(); } + + /// @cond + + //! Effects: Tries to deallocate the excess of memory created + //! with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { priv_shrink_to_fit(alloc_version()); } + + private: + void priv_shrink_to_fit(allocator_v1) + { + if(this->members_.m_capacity){ + if(!size()){ + this->prot_deallocate(); + } + else{ + //This would not work with stateful allocators + vector(*this).swap(*this); + } + } + } + + void priv_shrink_to_fit(allocator_v2) + { + if(this->members_.m_capacity){ + if(!size()){ + this->prot_deallocate(); + } + else{ + size_type received_size; + this->alloc().allocation_command(shrink_in_place, this->size(), this->capacity() + ,received_size, this->members_.m_start); + } + } + } + + void priv_destroy_all() + { + this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); + this->members_.m_size = 0; + } + + template + void priv_range_insert(pointer pos, FwdIt first, + FwdIt last, std::forward_iterator_tag) + { + if (first != last){ + size_type n = std::distance(first, last); + //Check if we have enough memory or try to expand current memory + size_type remaining = this->members_.m_capacity - this->members_.m_size; + bool same_buffer_start; + std::pair ret; + size_type real_cap = this->members_.m_capacity; + + //Check if we already have room + if (n <= remaining){ + same_buffer_start = true; + } + else{ + //There is not enough memory, allocate a new + //buffer or expand the old one. + size_type new_cap = this->next_capacity(n); + ret = this->allocation_command + (allocate_new | expand_fwd | expand_bwd, + this->members_.m_size + n, new_cap, real_cap, this->members_.m_start); + + //Check for forward expansion + same_buffer_start = ret.second && this->members_.m_start == ret.first; + if(same_buffer_start){ + this->members_.m_capacity = real_cap; + } + } + + //If we had room or we have expanded forward + if (same_buffer_start){ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->priv_range_insert_expand_forward + (detail::get_pointer(pos), first, last, n); + } + //Backwards (and possibly forward) expansion + else if(ret.second){ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_range_insert_expand_backwards + ( detail::get_pointer(ret.first) + , real_cap + , detail::get_pointer(pos) + , first + , last + , n); + } + //New buffer + else{ + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_range_insert_new_allocation + ( detail::get_pointer(ret.first) + , real_cap + , detail::get_pointer(pos) + , first + , last); + } + } + } + + template + void priv_range_insert_expand_forward + (T* pos, FwdIt first, FwdIt last, size_type n) + { + //There is enough memory + T* old_finish = detail::get_pointer(this->members_.m_start) + this->members_.m_size; + const size_type elems_after = old_finish - pos; + + if (elems_after > n){ + //New elements can be just copied. + //Move to uninitialized memory last objects + std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish); + this->members_.m_size += n; + //Copy previous to last objects to the initialized end + std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish - n), old_finish); + //Insert new objects in the pos + std::copy(first, last, detail::get_pointer(pos)); + } + else { + //The new elements don't fit in the [pos, end()) range. Copy + //to the beginning of the unallocated zone the last new elements. + FwdIt mid = first; + std::advance(mid, elems_after); + std::uninitialized_copy(mid, last, old_finish); + this->members_.m_size += n - elems_after; + //Copy old [pos, end()) elements to the uninitialized memory + std::uninitialized_copy + ( copy_move_it(detail::get_pointer(pos)) + , copy_move_it(old_finish) + , detail::get_pointer(this->members_.m_start) + this->members_.m_size); + this->members_.m_size += elems_after; + //Copy first new elements in pos + std::copy(first, mid, detail::get_pointer(pos)); + } + } + + template + void priv_range_insert_new_allocation + (T* new_start, size_type new_cap, T* pos, FwdIt first, FwdIt last) + { + T* new_finish = new_start; + T *old_finish; + //Anti-exception rollbacks + UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap); + UCopiedArrayDestructor construted_values_destroyer(new_start, 0u); + + //Initialize with [begin(), pos) old buffer + //the start of the new buffer + new_finish = std::uninitialized_copy + ( copy_move_it(detail::get_pointer(this->members_.m_start)) + , copy_move_it(detail::get_pointer(pos)) + , old_finish = new_finish); + construted_values_destroyer.increment_size(new_finish - old_finish); + //Initialize new objects, starting from previous point + new_finish = std::uninitialized_copy + (first, last, old_finish = new_finish); + construted_values_destroyer.increment_size(new_finish - old_finish); + //Initialize from the rest of the old buffer, + //starting from previous point + new_finish = std::uninitialized_copy + ( copy_move_it(detail::get_pointer(pos)) + , copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size) + , detail::get_pointer(new_finish)); + + //All construction successful, disable rollbacks + construted_values_destroyer.release(); + scoped_alloc.release(); + //Destroy and deallocate old elements + //If there is allocated memory, destroy and deallocate + if(this->members_.m_start != 0){ + if(!base_t::trivial_dctr_after_move) + this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); + this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); + } + this->members_.m_start = new_start; + this->members_.m_size = new_finish - new_start; + this->members_.m_capacity = new_cap; + } + + template + void priv_range_insert_expand_backwards + (T* new_start, size_type new_capacity, + T* pos, FwdIt first, FwdIt last, size_type n) + { + //Backup old data + T* old_start = detail::get_pointer(this->members_.m_start); + T* old_finish = old_start + this->members_.m_size; + size_type old_size = this->members_.m_size; + + //We can have 8 possibilities: + const size_type elemsbefore = (size_type)(pos - old_start); + const size_type s_before = (size_type)(old_start - new_start); + + //Update the vector buffer information to a safe state + this->members_.m_start = new_start; + this->members_.m_capacity = new_capacity; + this->members_.m_size = 0; + + //If anything goes wrong, this object will destroy + //all the old objects to fulfill previous vector state + OldArrayDestructor old_values_destroyer(old_start, old_size); + + //Check if s_before is so big that even copying the old data + new data + //there is a gap between the new data and the old data + if(s_before >= (old_size + n)){ + //Old situation: + // _________________________________________________________ + //| raw_mem | old_begin | old_end | + //| __________________________________|___________|_________| + // + //New situation: + // _________________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|________________________| + // + //Copy first old values before pos, after that the + //new objects + boost::interprocess::uninitialized_copy_copy + (copy_move_it(old_start), copy_move_it(detail::get_pointer(pos)), first, last, detail::get_pointer(new_start)); + UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore); + //Now initialize the rest of memory with the last old values + std::uninitialized_copy + ( copy_move_it(detail::get_pointer(pos)) + , copy_move_it(old_finish) + , detail::get_pointer(new_start) + elemsbefore + n); + //All new elements correctly constructed, avoid new element destruction + new_values_destroyer.release(); + this->members_.m_size = old_size + n; + //Old values destroyed automatically with "old_values_destroyer" + //when "old_values_destroyer" goes out of scope unless the have trivial + //destructor after move. + if(base_t::trivial_dctr_after_move) + old_values_destroyer.release(); + } + //Check if s_before is so big that divides old_end + else if(difference_type(s_before) >= difference_type(elemsbefore + n)){ + //Old situation: + // __________________________________________________ + //| raw_mem | old_begin | old_end | + //| ___________________________|___________|_________| + // + //New situation: + // __________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|_________________| + // + //Copy first old values before pos, after that the + //new objects + boost::interprocess::uninitialized_copy_copy + ( copy_move_it(old_start) + , copy_move_it(detail::get_pointer(pos)) + , first, last, detail::get_pointer(new_start)); + UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore); + size_type raw_gap = s_before - (elemsbefore + n); + //Now initialize the rest of s_before memory with the + //first of elements after new values + std::uninitialized_copy + ( copy_move_it(detail::get_pointer(pos)) + , copy_move_it(detail::get_pointer(pos) + raw_gap) + , detail::get_pointer(new_start) + elemsbefore + n); + //All new elements correctly constructed, avoid new element destruction + new_values_destroyer.release(); + //All new elements correctly constructed, avoid old element destruction + old_values_destroyer.release(); + //Update size since we have a contiguous buffer + this->members_.m_size = old_size + s_before; + //Now copy remaining last objects in the old buffer begin + T *to_destroy = std::copy(assign_move_it(detail::get_pointer(pos) + raw_gap), assign_move_it(old_finish), old_start); + //Now destroy redundant elements except if they were moved and + //they have trivial destructor after move + size_type n_destroy = old_finish - to_destroy; + if(!base_t::trivial_dctr_after_move) + this->destroy_n(to_destroy, n_destroy); + this->members_.m_size -= n_destroy; + } + else{ + //Check if we have to do the insertion in two phases + //since maybe s_before is not big enough and + //the buffer was expanded both sides + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin + old_end | raw_mem | + //|_________|_____________________|_________________| + // + //New situation with do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|___________________________________|_____________| + // + //New without do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|____________________________|____________________| + // + bool do_after = n > s_before; + FwdIt before_end = first; + //If we have to expand both sides, + //we will play if the first new values so + //calculate the upper bound of new values + if(do_after){ + std::advance(before_end, s_before); + } + + //Now we can have two situations: the raw_mem of the + //beginning divides the old_begin, or the new elements: + if (s_before <= elemsbefore) { + //The raw memory divides the old_begin group: + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_________|___________|_________|_________________| + // + //New situation with do_after(1): + //This is not definitive situation, the second phase + //will include + // _________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_________|_________|_________________| + // + //New situation without do_after: + // _________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|_____________________| + // + //Copy the first part of old_begin to raw_mem + T *start_n = old_start + difference_type(s_before); + std::uninitialized_copy + ( copy_move_it(old_start) + , copy_move_it(start_n) + , detail::get_pointer(new_start)); + //The buffer is all constructed until old_end, + //release destroyer and update size + old_values_destroyer.release(); + this->members_.m_size = old_size + s_before; + //Now copy the second part of old_begin overwriting himself + T* next = std::copy(assign_move_it(start_n), assign_move_it(detail::get_pointer(pos)), old_start); + if(do_after){ + //Now copy the new_beg elements + std::copy(first, before_end, detail::get_pointer(next)); + } + else{ + //Now copy the all the new elements + T* move_start = std::copy(first, last, detail::get_pointer(next)); + //Now displace old_end elements + T* move_end = std::copy(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish), detail::get_pointer(move_start)); + //Destroy remaining moved elements from old_end except if + //they have trivial destructor after being moved + difference_type n_destroy = s_before - n; + if(!base_t::trivial_dctr_after_move) + this->destroy_n(move_end, n_destroy); + this->members_.m_size -= n_destroy; + } + } + else { + //The raw memory divides the new elements + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_______________|___________|_________|_________________| + // + //New situation with do_after(): + // ____________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_______________|_________|______________| + // + //New situation without do_after: + // ______________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|__________________________| + // + //First copy whole old_begin and part of new to raw_mem + FwdIt mid = first; + size_type n_new_init = difference_type(s_before) - elemsbefore; + std::advance(mid, n_new_init); + boost::interprocess::uninitialized_copy_copy + ( copy_move_it(old_start) + , copy_move_it(detail::get_pointer(pos)) + , first, mid, detail::get_pointer(new_start)); + //The buffer is all constructed until old_end, + //release destroyer and update size + old_values_destroyer.release(); + this->members_.m_size = old_size + s_before; + + if(do_after){ + //Copy new_beg part + std::copy(mid, before_end, old_start); + } + else{ + //Copy all new elements + T* move_start = std::copy(mid, last, old_start); + //Displace old_end + T* move_end = std::copy(copy_move_it(detail::get_pointer(pos)), copy_move_it(old_finish), detail::get_pointer(move_start)); + //Destroy remaining moved elements from old_end except if they + //have trivial destructor after being moved + difference_type n_destroy = s_before - n; + if(!base_t::trivial_dctr_after_move) + this->destroy_n(move_end, n_destroy); + this->members_.m_size -= n_destroy; + } + } + + //This is only executed if two phase construction is needed + //This can be executed without exception handling since we + //have to just copy and append in raw memory and + //old_values_destroyer has been released in phase 1. + if(do_after){ + //The raw memory divides the new elements + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //New situation with do_after(2): + // ______________________________________________________ + //| old_begin + new | old_end |raw | + //|_______________________________________|_________|____| + // + const size_type n_after = n - s_before; + const difference_type elemsafter = old_size - elemsbefore; + + //The new_end part is [first + (n - n_after), last) + std::advance(first, n - n_after); + + //We can have two situations: + if (elemsafter > difference_type(n_after)){ + //The raw_mem from end will divide displaced old_end + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //First copy the part of old_end raw_mem + T* finish_n = old_finish - difference_type(n_after); + std::uninitialized_copy + ( copy_move_it(detail::get_pointer(finish_n)) + , copy_move_it(old_finish) + , old_finish); + this->members_.m_size += n_after; + //Displace the rest of old_end to the new position + std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(detail::get_pointer(finish_n)), old_finish); + //Now overwrite with new_end + std::copy(first, last, detail::get_pointer(pos)); + } + else { + //The raw_mem from end will divide new_end part + // + //Old situation: + // _____________________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|_____________________| + // + //New situation with do_after(2): + // _____________________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_______________|________|_________| + // + FwdIt mid = first; + std::advance(mid, elemsafter); + //First initialize data in raw memory + boost::interprocess::uninitialized_copy_copy + ( mid, last + , copy_move_it(detail::get_pointer(pos)) + , copy_move_it(old_finish) + , old_finish); + this->members_.m_size += n_after; + //Now copy the part of new_end over constructed elements + std::copy(first, mid, detail::get_pointer(pos)); + } + } + } + } + + template + void priv_range_insert(iterator pos, + InIt first, InIt last, + std::input_iterator_tag) + { + //Insert range before the pos position + std::copy(std::inserter(*this, pos), first, last); + } + + template + void priv_assign_aux(InIt first, InIt last, + std::input_iterator_tag) + { + //Overwrite all elements we can from [first, last) + iterator cur = begin(); + for ( ; first != last && cur != end(); ++cur, ++first){ + *cur = *first; + } + + if (first == last){ + //There are no more elements in the sequence, erase remaining + this->erase(cur, end()); + } + else{ + //There are more elements in the range, insert the remaining ones + this->insert(this->end(), first, last); + } + } + + template + void priv_assign_aux(FwdIt first, FwdIt last, + std::forward_iterator_tag) + { + size_type n = std::distance(first, last); + //Check if we have enough memory or try to expand current memory + size_type remaining = this->members_.m_capacity - this->members_.m_size; + bool same_buffer_start; + std::pair ret; + size_type real_cap = this->members_.m_capacity; + + if (n <= remaining){ + same_buffer_start = true; + } + else{ + //There is not enough memory, allocate a new buffer + size_type new_cap = this->next_capacity(n); + ret = this->allocation_command + (allocate_new | expand_fwd | expand_bwd, + this->size() + n, new_cap, real_cap, this->members_.m_start); + same_buffer_start = ret.second && this->members_.m_start == ret.first; + if(same_buffer_start){ + this->members_.m_capacity = real_cap; + } + } + + if(same_buffer_start){ + T *start = detail::get_pointer(this->members_.m_start); + if (this->size() >= n){ + //There is memory, but there are more old elements than new ones + //Overwrite old elements with new ones + std::copy(first, last, start); + //Destroy remaining old elements + this->destroy_n(start + n, this->members_.m_size - n); + this->members_.m_size = n; + } + else{ + //There is memory, but there are less old elements than new ones + //First overwrite some old elements with new ones + FwdIt mid = first; + std::advance(mid, this->size()); + T *end = std::copy(first, mid, start); + //Initialize the remaining new elements in the uninitialized memory + std::uninitialized_copy(mid, last, end); + this->members_.m_size = n; + } + } + else if(!ret.second){ + UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap); + std::uninitialized_copy(first, last, detail::get_pointer(ret.first)); + scoped_alloc.release(); + //Destroy and deallocate old buffer + if(this->members_.m_start != 0){ + this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); + this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); + } + this->members_.m_start = ret.first; + this->members_.m_size = n; + this->members_.m_capacity = real_cap; + } + else{ + //Backwards expansion + //If anything goes wrong, this object will destroy + //all old objects + T *old_start = detail::get_pointer(this->members_.m_start); + size_type old_size = this->members_.m_size; + OldArrayDestructor old_values_destroyer(old_start, old_size); + //If something goes wrong size will be 0 + //but holding the whole buffer + this->members_.m_size = 0; + this->members_.m_start = ret.first; + this->members_.m_capacity = real_cap; + + //Backup old buffer data + size_type old_offset = old_start - detail::get_pointer(ret.first); + size_type first_count = min_value(n, old_offset); + FwdIt mid = boost::interprocess::n_uninitialized_copy_n + (first, first_count, detail::get_pointer(ret.first)); + + if(old_offset > n){ + //All old elements will be destroyed by "old_values_destroyer" + this->members_.m_size = n; + } + else{ + //We have constructed objects from the new begin until + //the old end so release the rollback destruction + old_values_destroyer.release(); + this->members_.m_start = ret.first; + this->members_.m_size = first_count + old_size; + //Now overwrite the old values + size_type second_count = min_value(old_size, n - first_count); + mid = copy_n(mid, second_count, old_start); + + //Check if we still have to append elements in the + //uninitialized end + if(second_count == old_size){ + boost::interprocess::n_uninitialized_copy_n + ( mid + , n - first_count - second_count + , old_start + old_size); + } + else{ + //We have to destroy some old values + this->destroy_n + (old_start + second_count, old_size - second_count); + this->members_.m_size = n; + } + this->members_.m_size = n; + } + } + } + + template + void priv_assign_dispatch(Integer n, Integer val, detail::true_) + { this->assign((size_type) n, (T) val); } + + template + void priv_assign_dispatch(InIt first, InIt last, detail::false_) + { + //Dispatch depending on integer/iterator + typedef typename + std::iterator_traits::iterator_category ItCat; + this->priv_assign_aux(first, last, ItCat()); + } + + template + void priv_insert_dispatch( iterator pos, Integer n, Integer val, detail::true_) + { this->insert(pos, (size_type)n, (T)val); } + + template + void priv_insert_dispatch(iterator pos, InIt first, + InIt last, detail::false_) + { + //Dispatch depending on integer/iterator + typedef typename + std::iterator_traits::iterator_category ItCat; + this->priv_range_insert(pos.get_ptr(), first, last, ItCat()); + } + + void priv_check_range(size_type n) const + { + //If n is out of range, throw an out_of_range exception + if (n >= size()) + throw std::out_of_range("vector::at"); + } + + #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS + public: + unsigned int num_expand_fwd; + unsigned int num_expand_bwd; + unsigned int num_alloc; + void reset_alloc_stats() + { num_expand_fwd = num_expand_bwd = num_alloc = 0; } + #endif + /// @endcond +}; + +template +inline bool +operator==(const vector& x, const vector& y) +{ + //Check first size and each element if needed + return x.size() == y.size() && + std::equal(x.begin(), x.end(), y.begin()); +} + +template +inline bool +operator!=(const vector& x, const vector& y) +{ + //Check first size and each element if needed + return x.size() != y.size() || + !std::equal(x.begin(), x.end(), y.begin()); +} + +template +inline bool +operator<(const vector& x, const vector& y) +{ + return std::lexicographical_compare(x.begin(), x.end(), + y.begin(), y.end()); +} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(vector& x, vector& y) +{ x.swap(y); } + +template +inline void swap(const detail::moved_object >& x, vector& y) +{ x.get().swap(y); } + +template +inline void swap(vector &x, const detail::moved_object >& y) +{ x.swap(y.get()); } +#else +template +inline void swap(vector&&x, vector&&y) +{ x.swap(y); } +#endif + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + enum { value = has_trivial_destructor::value }; +}; +/// @endcond + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif // #ifndef BOOST_INTERPROCESS_VECTOR_HPP + diff --git a/thirdparty/boost/interprocess/creation_tags.hpp b/thirdparty/boost/interprocess/creation_tags.hpp new file mode 100644 index 0000000..d7d10cf --- /dev/null +++ b/thirdparty/boost/interprocess/creation_tags.hpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_CREATION_TAGS_HPP +#define BOOST_INTERPROCESS_CREATION_TAGS_HPP + +#include +#include + +namespace boost { +namespace interprocess { + +//!Tag to indicate that the resource must +//!be only created +struct create_only_t {}; + +//!Tag to indicate that the resource must +//!be only opened +struct open_only_t {}; + +//!Tag to indicate that the resource must +//!be created. If already created, it must be opened. +struct open_or_create_t {}; + +//!Value to indicate that the resource must +//!be only created +static const create_only_t create_only = create_only_t(); + +//!Value to indicate that the resource must +//!be only opened +static const open_only_t open_only = open_only_t(); + +//!Value to indicate that the resource must +//!be created. If already created, it must be opened. +static const open_or_create_t open_or_create = open_or_create_t(); + +namespace detail { + +enum create_enum_t +{ DoCreate, DoOpen, DoOpenOrCreate }; + +} //namespace detail { + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_CREATION_TAGS_HPP + diff --git a/thirdparty/boost/interprocess/detail/algorithms.hpp b/thirdparty/boost/interprocess/detail/algorithms.hpp new file mode 100644 index 0000000..a84bdb6 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/algorithms.hpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP +#define BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { + +template +struct has_own_construct_from_it +{ + static const bool value = false; +}; + +namespace detail { + +template +inline void construct_in_place_impl(T* dest, const InpIt &source, detail::true_) +{ + T::construct(dest, *source); +} + +template +inline void construct_in_place_impl(T* dest, const InpIt &source, detail::false_) +{ + new(dest)T(*source); +} + +} //namespace detail { + +template +inline void construct_in_place(T* dest, InpIt source) +{ + typedef detail::bool_::value> boolean_t; + detail::construct_in_place_impl(dest, source, boolean_t()); +} + +template +inline void construct_in_place(T *dest, default_construct_iterator) +{ + new(dest)T(); +} + +template +InIt copy_n(InIt first, typename std::iterator_traits::difference_type length, OutIt dest) +{ + for (; length--; ++dest, ++first) + *dest = *first; + return first; +} + +template inline +InIt n_uninitialized_copy_n + (InIt first, + typename std::iterator_traits::difference_type count, + FwdIt dest) +{ + typedef typename std::iterator_traits::value_type value_type; + //Save initial destination position + FwdIt dest_init = dest; + typename std::iterator_traits::difference_type new_count = count+1; + + BOOST_TRY{ + //Try to build objects + for (; --new_count; ++dest, ++first){ + construct_in_place(detail::get_pointer(&*dest), first); + } + } + BOOST_CATCH(...){ + //Call destructors + new_count = count - new_count; + for (; new_count--; ++dest_init){ + detail::get_pointer(&*dest_init)->~value_type(); + } + BOOST_RETHROW + } + BOOST_CATCH_END + return first; +} + +// uninitialized_copy_copy +// Copies [first1, last1) into [result, result + (last1 - first1)), and +// copies [first2, last2) into +// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)). +template +FwdIt uninitialized_copy_copy + (InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result) +{ + typedef typename std::iterator_traits::value_type value_type; + FwdIt mid = std::uninitialized_copy(first1, last1, result); + BOOST_TRY { + return std::uninitialized_copy(first2, last2, mid); + } + BOOST_CATCH(...){ + for(;result != mid; ++result){ + result->~value_type(); + } + BOOST_RETHROW + } + BOOST_CATCH_END +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP + diff --git a/thirdparty/boost/interprocess/detail/atomic.hpp b/thirdparty/boost/interprocess/detail/atomic.hpp new file mode 100644 index 0000000..a9ca7d3 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/atomic.hpp @@ -0,0 +1,472 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2008 +// (C) Copyright Markus Schoepflin 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP +#define BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP + +#include +#include +#include + +namespace boost{ +namespace interprocess{ +namespace detail{ + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem); + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem); + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val); + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with": what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp); + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +#include + +namespace boost{ +namespace interprocess{ +namespace detail{ + +//! Atomically decrement an boost::uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ return winapi::interlocked_decrement((volatile long*)mem) + 1; } + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ return winapi::interlocked_increment((volatile long*)mem)-1; } + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ return *mem; } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ winapi::interlocked_exchange((volatile long*)mem, val); } + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with": what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ return winapi::interlocked_compare_exchange((volatile long*)mem, with, cmp); } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +namespace boost { +namespace interprocess { +namespace detail{ + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with" what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ + boost::uint32_t prev = cmp; + asm volatile( "lock\n\t" + "cmpxchg %3,%1" + : "=a" (prev), "=m" (*(mem)) + : "0" (prev), "r" (with) + : "memory", "cc"); + return prev; +/* + boost::uint32_t prev; + + asm volatile ("lock; cmpxchgl %1, %2" + : "=a" (prev) + : "r" (with), "m" (*(mem)), "0"(cmp)); + asm volatile("" : : : "memory"); + + return prev; +*/ +} + +//! Atomically add 'val' to an boost::uint32_t +//! "mem": pointer to the object +//! "val": amount to add +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_add32 + (volatile boost::uint32_t *mem, boost::uint32_t val) +{ + // int r = *pw; + // *mem += val; + // return r; + int r; + + asm volatile + ( + "lock\n\t" + "xadd %1, %0": + "+m"( *mem ), "=r"( r ): // outputs (%0, %1) + "1"( val ): // inputs (%2 == %1) + "memory", "cc" // clobbers + ); + + return r; +/* + asm volatile( "lock\n\t; xaddl %0,%1" + : "=r"(val), "=m"(*mem) + : "0"(val), "m"(*mem)); + asm volatile("" : : : "memory"); + + return val; +*/ +} + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, 1); } + +//! Atomically decrement an boost::uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, (boost::uint32_t)-1); } + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ return *mem; } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ *mem = val; } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#elif defined(__GNUC__) && (defined(__PPC__) || defined(__ppc__)) + +namespace boost { +namespace interprocess { +namespace detail{ + +//! Atomically add 'val' to an boost::uint32_t +//! "mem": pointer to the object +//! "val": amount to add +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ + boost::uint32_t prev, temp; + + asm volatile ("0:\n\t" // retry local label + "lwarx %0,0,%2\n\t" // load prev and reserve + "add %1,%0,%3\n\t" // temp = prev + val + "stwcx. %1,0,%2\n\t" // conditionally store + "bne- 0b" // start over if we lost + // the reservation + //XXX find a cleaner way to define the temp + //it's not an output + : "=&r" (prev), "=&r" (temp) // output, temp + : "b" (mem), "r" (val) // inputs + : "memory", "cc"); // clobbered + return prev; +} + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with" what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ + boost::uint32_t prev; + + asm volatile ("0:\n\t" // retry local label + "lwarx %0,0,%1\n\t" // load prev and reserve + "cmpw %0,%3\n\t" // does it match cmp? + "bne- 1f\n\t" // ...no, bail out + "stwcx. %2,0,%1\n\t" // ...yes, conditionally + // store with + "bne- 0b\n\t" // start over if we lost + // the reservation + "1:" // exit local label + + : "=&r"(prev) // output + : "b" (mem), "r" (with), "r"(cmp) // inputs + : "memory", "cc"); // clobbered + return prev; +} + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, 1); } + +//! Atomically decrement an boost::uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, boost::uint32_t(-1u)); } + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ return *mem; } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ *mem = val; } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +namespace boost { +namespace interprocess { +namespace detail{ + +//! Atomically add 'val' to an boost::uint32_t +//! "mem": pointer to the object +//! "val": amount to add +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_add32 + (volatile boost::uint32_t *mem, boost::uint32_t val) +{ return __sync_fetch_and_add(const_cast(mem), val); } + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, 1); } + +//! Atomically decrement an boost::uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ return atomic_add32(mem, (boost::uint32_t)-1); } + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ return *mem; } + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with" what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ return __sync_val_compare_and_swap(const_cast(mem), with, cmp); } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ *mem = val; } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#elif (defined(sun) || defined(__sun)) + +#include + +namespace boost{ +namespace interprocess{ +namespace detail{ + +//! Atomically add 'val' to an boost::uint32_t +//! "mem": pointer to the object +//! "val": amount to add +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ return atomic_add_32_nv(reinterpret_cast(mem), (int32_t)val) - val; } + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with" what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +inline boost::uint32_t atomic_cas32 + (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ return atomic_cas_32(reinterpret_cast(mem), cmp, with); } + +//! Atomically increment an apr_uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ return atomic_add_32_nv(reinterpret_cast(mem), 1) - 1; } + +//! Atomically decrement an boost::uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ return atomic_add_32_nv(reinterpret_cast(mem), (boost::uint32_t)-1) + 1; } + +//! Atomically read an boost::uint32_t from memory +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ return *mem; } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ *mem = val; } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#elif defined(__osf__) && defined(__DECCXX) + +#include +#include + +namespace boost{ +namespace interprocess{ +namespace detail{ + +//! Atomically decrement a uint32_t by 1 +//! "mem": pointer to the atomic value +//! Returns the old value pointed to by mem +//! Acquire, memory barrier after decrement. +inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) +{ boost::uint32_t old_val = __ATOMIC_DECREMENT_LONG(mem); __MB(); return old_val; } + +//! Atomically increment a uint32_t by 1 +//! "mem": pointer to the object +//! Returns the old value pointed to by mem +//! Release, memory barrier before increment. +inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) +{ __MB(); return __ATOMIC_INCREMENT_LONG(mem); } + +// Rational for the implementation of the atomic read and write functions. +// +// 1. The Alpha Architecture Handbook requires that access to a byte, +// an aligned word, an aligned longword, or an aligned quadword is +// atomic. (See 'Alpha Architecture Handbook', version 4, chapter 5.2.2.) +// +// 2. The CXX User's Guide states that volatile quantities are accessed +// with single assembler instructions, and that a compilation error +// occurs when declaring a quantity as volatile which is not properly +// aligned. + +//! Atomically read an boost::uint32_t from memory +//! Acquire, memory barrier after load. +inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) +{ boost::uint32_t old_val = *mem; __MB(); return old_val; } + +//! Atomically set an boost::uint32_t in memory +//! "mem": pointer to the object +//! "param": val value that the object will assume +//! Release, memory barrier before store. +inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) +{ __MB(); *mem = val; } + +//! Compare an boost::uint32_t's value with "cmp". +//! If they are the same swap the value with "with" +//! "mem": pointer to the value +//! "with" what to swap it with +//! "cmp": the value to compare it to +//! Returns the old value of *mem +//! Memory barrier between load and store. +inline boost::uint32_t atomic_cas32( + volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) +{ + // Note: + // + // Branch prediction prefers backward branches, and the Alpha Architecture + // Handbook explicitely states that the loop should not be implemented like + // it is below. (See chapter 4.2.5.) Therefore the code should probably look + // like this: + // + // return asm( + // "10: ldl_l %v0,(%a0) ;" + // " cmpeq %v0,%a2,%t0 ;" + // " beq %t0,20f ;" + // " mb ;" + // " mov %a1,%t0 ;" + // " stl_c %t0,(%a0) ;" + // " beq %t0,30f ;" + // "20: ret ;" + // "30: br 10b;", + // mem, with, cmp); + // + // But as the compiler always transforms this into the form where a backward + // branch is taken on failure, we can as well implement it in the straight + // forward form, as this is what it will end up in anyway. + + return asm( + "10: ldl_l %v0,(%a0) ;" // load prev value from mem and lock mem + " cmpeq %v0,%a2,%t0 ;" // compare with given value + " beq %t0,20f ;" // if not equal, we're done + " mb ;" // memory barrier + " mov %a1,%t0 ;" // load new value into scratch register + " stl_c %t0,(%a0) ;" // store new value to locked mem (overwriting scratch) + " beq %t0,10b ;" // store failed because lock has been stolen, retry + "20: ", + mem, with, cmp); +} + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#else + +#error No atomic operations implemented for this platform, sorry! + +#endif + +#include + +#endif //BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP diff --git a/thirdparty/boost/interprocess/detail/cast_tags.hpp b/thirdparty/boost/interprocess/detail/cast_tags.hpp new file mode 100644 index 0000000..c361333 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/cast_tags.hpp @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_CAST_TAGS_HPP +#define BOOST_INTERPROCESS_CAST_TAGS_HPP + +#include +#include + +namespace boost { namespace interprocess { namespace detail { + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct reinterpret_cast_tag {}; + +}}} //namespace boost { namespace interprocess { namespace detail { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_CAST_TAGS_HPP + diff --git a/thirdparty/boost/interprocess/detail/config_begin.hpp b/thirdparty/boost/interprocess/detail/config_begin.hpp new file mode 100644 index 0000000..747a2d0 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/config_begin.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_INTERPROCESS_CONFIG_INCLUDED +#define BOOST_INTERPROCESS_CONFIG_INCLUDED +#include +#endif + +#ifdef BOOST_MSVC + #ifndef _CRT_SECURE_NO_DEPRECATE + #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #endif + #pragma warning (push) + #pragma warning (disable : 4702) // unreachable code + #pragma warning (disable : 4706) // assignment within conditional expression + #pragma warning (disable : 4127) // conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4251) // 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' + #pragma warning (disable : 4267) // conversion from 'X' to 'Y', possible loss of data + #pragma warning (disable : 4275) // non – DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' + #pragma warning (disable : 4355) // 'this' : used in base member initializer list + #pragma warning (disable : 4503) // 'identifier' : decorated name length exceeded, name was truncated + #pragma warning (disable : 4511) // copy constructor could not be generated + #pragma warning (disable : 4512) // assignment operator could not be generated + #pragma warning (disable : 4514) // unreferenced inline removed + #pragma warning (disable : 4521) // Disable "multiple copy constructors specified" + #pragma warning (disable : 4522) // 'class' : multiple assignment operators specified + #pragma warning (disable : 4675) // 'method' should be declared 'static' and have exactly one parameter + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // 'function': was declared deprecated +#endif diff --git a/thirdparty/boost/interprocess/detail/config_end.hpp b/thirdparty/boost/interprocess/detail/config_end.hpp new file mode 100644 index 0000000..ac4198c --- /dev/null +++ b/thirdparty/boost/interprocess/detail/config_end.hpp @@ -0,0 +1,8 @@ +#if defined BOOST_MSVC + #pragma warning (pop) + #ifdef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef _CRT_SECURE_NO_DEPRECATE + #endif +#endif + diff --git a/thirdparty/boost/interprocess/detail/file_wrapper.hpp b/thirdparty/boost/interprocess/detail/file_wrapper.hpp new file mode 100644 index 0000000..def32ce --- /dev/null +++ b/thirdparty/boost/interprocess/detail/file_wrapper.hpp @@ -0,0 +1,213 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP +#define BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail{ + +class file_wrapper +{ + public: + + //!Default constructor. + //!Represents an empty file_wrapper. + file_wrapper(); + + //!Creates a file object with name "name" and mode "mode", with the access mode "mode" + //!If the file previously exists, throws an error. + file_wrapper(create_only_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoCreate, name, mode); } + + //!Tries to create a file with name "name" and mode "mode", with the + //!access mode "mode". If the file previously exists, it tries to open it with mode "mode". + //!Otherwise throws an error. + file_wrapper(open_or_create_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode); } + + //!Tries to open a file with name "name", with the access mode "mode". + //!If the file does not previously exist, it throws an error. + file_wrapper(open_only_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoOpen, name, mode); } + + //!Moves the ownership of "moved"'s file to *this. + //!After the call, "moved" does not represent any file. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + file_wrapper + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + file_wrapper(file_wrapper &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s file to *this. + //!After the call, "moved" does not represent any file. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + file_wrapper &operator= + (detail::moved_object &moved) + { + file_wrapper tmp(moved); + this->swap(tmp); + return *this; + } + #else + file_wrapper &operator=(file_wrapper &&moved) + { + file_wrapper tmp(move(moved)); + this->swap(tmp); + return *this; + } + #endif + + //!Swaps to file_wrappers. + //!Does not throw + void swap(file_wrapper &other); + + //!Erases a file from the system. + //!Returns false on error. Never throws + static bool remove(const char *name); + + //!Sets the size of the file + void truncate(offset_t length); + + //!Closes the + //!file + ~file_wrapper(); + + //!Returns the name of the file + //!used in the constructor + const char *get_name() const; + + //!Returns the name of the file + //!used in the constructor + bool get_size(offset_t &size) const; + + //!Returns access mode + //!used in the constructor + mode_t get_mode() const; + + //!Get mapping handle + //!to use with mapped_region + mapping_handle_t get_mapping_handle() const; + + private: + //!Closes a previously opened file mapping. Never throws. + void priv_close(); + //!Closes a previously opened file mapping. Never throws. + bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode); + + file_handle_t m_handle; + mode_t m_mode; + std::string m_filename; +}; + +inline file_wrapper::file_wrapper() + : m_handle(file_handle_t(detail::invalid_file())) +{} + +inline file_wrapper::~file_wrapper() +{ this->priv_close(); } + +inline const char *file_wrapper::get_name() const +{ return m_filename.c_str(); } + +inline bool file_wrapper::get_size(offset_t &size) const +{ return get_file_size((file_handle_t)m_handle, size); } + +inline void file_wrapper::swap(file_wrapper &other) +{ + std::swap(m_handle, other.m_handle); + std::swap(m_mode, other.m_mode); + m_filename.swap(other.m_filename); +} + +inline mapping_handle_t file_wrapper::get_mapping_handle() const +{ return mapping_handle_from_file_handle(m_handle); } + +inline mode_t file_wrapper::get_mode() const +{ return m_mode; } + +inline bool file_wrapper::priv_open_or_create + (detail::create_enum_t type, + const char *filename, + mode_t mode) +{ + m_filename = filename; + + if(mode != read_only && mode != read_write){ + error_info err(mode_error); + throw interprocess_exception(err); + } + + //Open file existing native API to obtain the handle + switch(type){ + case detail::DoOpen: + m_handle = open_existing_file(filename, mode); + break; + case detail::DoCreate: + m_handle = create_new_file(filename, mode); + break; + case detail::DoOpenOrCreate: + m_handle = create_or_open_file(filename, mode); + break; + default: + { + error_info err = other_error; + throw interprocess_exception(err); + } + } + + //Check for error + if(m_handle == invalid_file()){ + throw interprocess_exception(error_info(system_error_code())); + } + + m_mode = mode; + return true; +} + +inline bool file_wrapper::remove(const char *filename) +{ return delete_file(filename); } + +inline void file_wrapper::truncate(offset_t length) +{ + if(!truncate_file(m_handle, length)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline void file_wrapper::priv_close() +{ + if(m_handle != invalid_file()){ + close_file(m_handle); + m_handle = invalid_file(); + } +} + +} //namespace detail{ +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP diff --git a/thirdparty/boost/interprocess/detail/in_place_interface.hpp b/thirdparty/boost/interprocess/detail/in_place_interface.hpp new file mode 100644 index 0000000..148f1a2 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/in_place_interface.hpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP +#define BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include //typeid + +//!\file +//!Describes an abstract interface for placement construction and destruction. + +namespace boost { +namespace interprocess { +namespace detail { + +struct in_place_interface +{ + in_place_interface(std::size_t alignm, std::size_t sz, const char *tname) + : alignment(alignm), size(sz), type_name(tname) + {} + + std::size_t alignment; + std::size_t size; + const char *type_name; + + virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) = 0; + virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed) = 0; + virtual ~in_place_interface(){} +}; + +template +struct placement_destroy : public in_place_interface +{ + placement_destroy() + : in_place_interface(detail::alignment_of::value, sizeof(T), typeid(T).name()) + {} + + virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed) + { + T* memory = static_cast(mem); + for(destroyed = 0; destroyed < num; ++destroyed) + (memory++)->~T(); + } + + virtual void construct_n(void *, std::size_t, std::size_t &) {} + + private: + void destroy(void *mem) + { static_cast(mem)->~T(); } +}; + +} +} +} //namespace boost { namespace interprocess { namespace detail { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP diff --git a/thirdparty/boost/interprocess/detail/interprocess_tester.hpp b/thirdparty/boost/interprocess/detail/interprocess_tester.hpp new file mode 100644 index 0000000..679d0f1 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/interprocess_tester.hpp @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP +#define BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP + +namespace boost{ +namespace interprocess{ +namespace detail{ + +class interprocess_tester +{ + public: + template + static void dont_close_on_destruction(T &t) + { t.dont_close_on_destruction(); } +}; + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP + diff --git a/thirdparty/boost/interprocess/detail/iterators.hpp b/thirdparty/boost/interprocess/detail/iterators.hpp new file mode 100644 index 0000000..0601193 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/iterators.hpp @@ -0,0 +1,475 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP +#define BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include + +#include +#include + +namespace boost { +namespace interprocess { + +template +class constant_iterator + : public std::iterator + +{ + typedef constant_iterator this_type; + + public: + explicit constant_iterator(const T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + constant_iterator() + : m_ptr(0), m_num(0){} + + constant_iterator& operator++() + { increment(); return *this; } + + constant_iterator operator++(int) + { + constant_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const constant_iterator& i, const constant_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const constant_iterator& i, const constant_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const constant_iterator& i, const constant_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + constant_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + constant_iterator operator+(Difference off) const + { + constant_iterator other(*this); + other.advance(off); + return other; + } + + friend constant_iterator operator+(Difference off, const constant_iterator& right) + { return right + off; } + + constant_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + constant_iterator operator-(Difference off) const + { return *this + (-off); } + + const T& operator*() const + { return dereference(); } + + const T* operator->() const + { return &(dereference()); } + + private: + const T * m_ptr; + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { return *m_ptr; } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class default_construct_iterator + : public std::iterator + +{ + typedef default_construct_iterator this_type; + + public: + explicit default_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + default_construct_iterator() + : m_num(0){} + + default_construct_iterator& operator++() + { increment(); return *this; } + + default_construct_iterator operator++(int) + { + default_construct_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + default_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + default_construct_iterator operator+(Difference off) const + { + default_construct_iterator other(*this); + other.advance(off); + return other; + } + + friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) + { return right + off; } + + default_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + default_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + const T& operator*() const + { return dereference(); } + + const T* operator->() const + { return &(dereference()); } + + private: + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { + static T dummy; + return dummy; + } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class repeat_iterator + : public std::iterator + +{ + typedef repeat_iterator this_type; + public: + explicit repeat_iterator(T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + repeat_iterator() + : m_ptr(0), m_num(0){} + + this_type& operator++() + { increment(); return *this; } + + this_type operator++(int) + { + this_type result (*this); + increment(); + return result; + } + + friend bool operator== (const this_type& i, const this_type& i2) + { return i.equal(i2); } + + friend bool operator!= (const this_type& i, const this_type& i2) + { return !(i == i2); } + + friend bool operator< (const this_type& i, const this_type& i2) + { return i.less(i2); } + + friend bool operator> (const this_type& i, const this_type& i2) + { return i2 < i; } + + friend bool operator<= (const this_type& i, const this_type& i2) + { return !(i > i2); } + + friend bool operator>= (const this_type& i, const this_type& i2) + { return !(i < i2); } + + friend Difference operator- (const this_type& i, const this_type& i2) + { return i2.distance_to(i); } + + //Arithmetic + this_type& operator+=(Difference off) + { this->advance(off); return *this; } + + this_type operator+(Difference off) const + { + this_type other(*this); + other.advance(off); + return other; + } + + friend this_type operator+(Difference off, const this_type& right) + { return right + off; } + + this_type& operator-=(Difference off) + { this->advance(-off); return *this; } + + this_type operator-(Difference off) const + { return *this + (-off); } + + T& operator*() const + { return dereference(); } + + T *operator->() const + { return &(dereference()); } + + private: + T * m_ptr; + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + T & dereference() const + { return *m_ptr; } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(const PseudoReference &px) + : m_value(px) + {} + + PseudoReference* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + mutable PseudoReference m_value; +}; + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(T &px) + : m_value(px) + {} + + T* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + mutable T &m_value; +}; + +template +class transform_iterator + : public UnaryFunction + , public std::iterator + < typename Iterator::iterator_category + , typename detail::remove_reference::type + , typename Iterator::difference_type + , operator_arrow_proxy + , typename UnaryFunction::result_type> +{ + public: + explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) + : UnaryFunction(f), m_it(it) + {} + + explicit transform_iterator() + : UnaryFunction(), m_it() + {} + + //Constructors + transform_iterator& operator++() + { increment(); return *this; } + + transform_iterator operator++(int) + { + transform_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const transform_iterator& i, const transform_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) + { return !(i == i2); } + +/* + friend bool operator> (const transform_iterator& i, const transform_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const transform_iterator& i, const transform_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) + { return !(i < i2); } +*/ + friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + transform_iterator& operator+=(typename Iterator::difference_type off) + { this->advance(off); return *this; } + + transform_iterator operator+(typename Iterator::difference_type off) const + { + transform_iterator other(*this); + other.advance(off); + return other; + } + + friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) + { return right + off; } + + transform_iterator& operator-=(typename Iterator::difference_type off) + { this->advance(-off); return *this; } + + transform_iterator operator-(typename Iterator::difference_type off) const + { return *this + (-off); } + + typename UnaryFunction::result_type operator*() const + { return dereference(); } + + operator_arrow_proxy + operator->() const + { return operator_arrow_proxy(dereference()); } + + Iterator & base() + { return m_it; } + + const Iterator & base() const + { return m_it; } + + private: + Iterator m_it; + + void increment() + { ++m_it; } + + void decrement() + { --m_it; } + + bool equal(const transform_iterator &other) const + { return m_it == other.m_it; } + + bool less(const transform_iterator &other) const + { return other.m_it < m_it; } + + typename UnaryFunction::result_type dereference() const + { return UnaryFunction::operator()(*m_it); } + + void advance(typename Iterator::difference_type n) + { std::advance(m_it, n); } + + typename Iterator::difference_type distance_to(const transform_iterator &other)const + { return std::distance(other.m_it, m_it); } +}; + +template +transform_iterator +make_transform_iterator(Iterator it, UnaryFunc fun) +{ + return transform_iterator(it, fun); +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP + diff --git a/thirdparty/boost/interprocess/detail/managed_memory_impl.hpp b/thirdparty/boost/interprocess/detail/managed_memory_impl.hpp new file mode 100644 index 0000000..822da21 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/managed_memory_impl.hpp @@ -0,0 +1,731 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP +#define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include +// +#include +#include +#include +#include + +//!\file +//!Describes a named shared memory allocation user class. +//! + +namespace boost { +namespace interprocess { +namespace detail { + +template +class create_open_func; + +template< + class CharType, + class MemoryAlgorithm, + template class IndexType + > +struct segment_manager_type +{ + typedef segment_manager type; +}; + +//!This class is designed to be a base class to classes that manage +//!creation of objects in a fixed size memory buffer. Apart +//!from allocating raw memory, the user can construct named objects. To +//!achieve this, this class uses the reserved space provided by the allocation +//!algorithm to place a named_allocator_algo, who takes care of name mappings. +//!The class can be customized with the char type used for object names +//!and the memory allocation algorithm to be used.*/ +template < class CharType + , class MemoryAlgorithm + , template class IndexType + , std::size_t Offset = 0 + > +class basic_managed_memory_impl +{ + //Non-copyable + basic_managed_memory_impl(const basic_managed_memory_impl &); + basic_managed_memory_impl &operator=(const basic_managed_memory_impl &); + + template + friend class create_open_func; + + public: + typedef typename segment_manager_type + ::type segment_manager; + typedef CharType char_type; + typedef MemoryAlgorithm memory_algorithm; + typedef typename MemoryAlgorithm::mutex_family mutex_family; + typedef CharType char_t; + typedef std::ptrdiff_t handle_t; + typedef typename segment_manager:: + const_named_iterator const_named_iterator; + typedef typename segment_manager:: + const_unique_iterator const_unique_iterator; + + /// @cond + + //Experimental. Don't use. + + typedef typename segment_manager::multiallocation_iterator multiallocation_iterator; + + /// @endcond + + static const std::size_t PayloadPerAllocation = segment_manager::PayloadPerAllocation; + + private: + typedef basic_managed_memory_impl + self_t; + typedef typename + segment_manager::char_ptr_holder_t char_ptr_holder_t; + + protected: + template + static bool grow(const char *filename, std::size_t extra_bytes) + { + typedef typename ManagedMemory::device_type device_type; + //Increase file size + try{ + offset_t old_size; + { + device_type f(open_or_create, filename, read_write); + if(!f.get_size(old_size)) + return false; + f.truncate(old_size + extra_bytes); + } + ManagedMemory managed_memory(open_only, filename); + //Grow always works + managed_memory.self_t::grow(extra_bytes); + } + catch(...){ + return false; + } + return true; + } + + template + static bool shrink_to_fit(const char *filename) + { + typedef typename ManagedMemory::device_type device_type; + std::size_t new_size, old_size; + try{ + ManagedMemory managed_memory(open_only, filename); + old_size = managed_memory.get_size(); + managed_memory.self_t::shrink_to_fit(); + new_size = managed_memory.get_size(); + } + catch(...){ + return false; + } + + //Decrease file size + { + device_type f(open_or_create, filename, read_write); + f.truncate(new_size); + } + return true; + } + + //!Constructor. Allocates basic resources. Never throws. + basic_managed_memory_impl() + : mp_header(0){} + + //!Destructor. Calls close. Never throws. + ~basic_managed_memory_impl() + { this->close_impl(); } + + //!Places segment manager in the reserved space. This can throw. + bool create_impl (void *addr, std::size_t size) + { + if(mp_header) return false; + + //Check if there is enough space + if(size < segment_manager::get_min_size()) + return false; + + //This function should not throw. The index construction can + //throw if constructor allocates memory. So we must catch it. + BOOST_TRY{ + //Let's construct the allocator in memory + mp_header = new(addr) segment_manager(size); + } + BOOST_CATCH(...){ + return false; + } + BOOST_CATCH_END + return true; + } + + //!Connects to a segment manager in the reserved buffer. Never throws. + bool open_impl (void *addr, std::size_t) + { + if(mp_header) return false; + mp_header = static_cast(addr); + return true; + } + + //!Frees resources. Never throws. + bool close_impl() + { + bool ret = mp_header != 0; + mp_header = 0; + return ret; + } + + //!Frees resources and destroys common resources. Never throws. + bool destroy_impl() + { + if(mp_header == 0) + return false; + mp_header->~segment_manager(); + this->close_impl(); + return true; + } + + //! + void grow(std::size_t extra_bytes) + { mp_header->grow(extra_bytes); } + + void shrink_to_fit() + { mp_header->shrink_to_fit(); } + + public: + + //!Returns segment manager. Never throws. + segment_manager *get_segment_manager() const + { return mp_header; } + + //!Returns the base address of the memory in this process. Never throws. + void * get_address () const + { return (char*)mp_header - Offset; } + + //!Returns the size of memory segment. Never throws. + std::size_t get_size () const + { return mp_header->get_size() + Offset; } + + //!Returns the number of free bytes of the memory + //!segment + std::size_t get_free_memory() const + { return mp_header->get_free_memory(); } + + //!Returns the result of "all_memory_deallocated()" function + //!of the used memory algorithm + bool all_memory_deallocated() + { return mp_header->all_memory_deallocated(); } + + //!Returns the result of "check_sanity()" function + //!of the used memory algorithm + bool check_sanity() + { return mp_header->check_sanity(); } + + //!Writes to zero free memory (memory not yet allocated) of + //!the memory algorithm + void zero_free_memory() + { mp_header->zero_free_memory(); } + + //!Transforms an absolute address into an offset from base address. + //!The address must belong to the memory segment. Never throws. + handle_t get_handle_from_address (const void *ptr) const + { + return detail::char_ptr_cast(ptr) - + detail::char_ptr_cast(this->get_address()); + } + + //!Returns true if the address belongs to the managed memory segment + bool belongs_to_segment (const void *ptr) const + { + return ptr >= this->get_address() && + ptr < (detail::char_ptr_cast(ptr) + this->get_size()); + } + + //!Transforms previously obtained offset into an absolute address in the + //!process space of the current process. Never throws.*/ + void * get_address_from_handle (handle_t offset) const + { return detail::char_ptr_cast(this->get_address()) + offset; } + + //!Searches for nbytes of free memory in the segment, marks the + //!memory as used and return the pointer to the memory. If no + //!memory is available throws a boost::interprocess::bad_alloc exception + void* allocate (std::size_t nbytes) + { return mp_header->allocate(nbytes); } + + //!Searches for nbytes of free memory in the segment, marks the + //!memory as used and return the pointer to the memory. If no memory + //!is available returns 0. Never throws. + void* allocate (std::size_t nbytes, std::nothrow_t nothrow) + { return mp_header->allocate(nbytes, nothrow); } + + //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment" + //!must be power of two. If no memory + //!is available returns 0. Never throws. + void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t nothrow) + { return mp_header->allocate_aligned(nbytes, alignment, nothrow); } + + template + std::pair + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr = 0) + { + return mp_header->allocation_command + (command, limit_size, preferred_size, received_size, reuse_ptr); + } + + //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment" + //!must be power of two. If no + //!memory is available throws a boost::interprocess::bad_alloc exception + void * allocate_aligned(std::size_t nbytes, std::size_t alignment) + { return mp_header->allocate_aligned(nbytes, alignment); } + + /// @cond + + //Experimental. Don't use. + + //!Allocates n_elements of elem_size bytes. + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements) + { return mp_header->allocate_many(elem_bytes, num_elements); } + + //!Allocates n_elements, each one of elem_sizes[i] bytes. + multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements) + { return mp_header->allocate_many(elem_sizes, n_elements); } + + //!Allocates n_elements of elem_size bytes. + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow) + { return mp_header->allocate_many(elem_bytes, num_elements, nothrow); } + + //!Allocates n_elements, each one of elem_sizes[i] bytes. + multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow) + { return mp_header->allocate_many(elem_sizes, n_elements, nothrow); } + + /// @endcond + + //!Marks previously allocated memory as free. Never throws. + void deallocate (void *addr) + { if (mp_header) mp_header->deallocate(addr); } + + //!Tries to find a previous named allocation address. Returns a memory + //!buffer and the object count. If not found returned pointer is 0. + //!Never throws. + template + std::pair find (char_ptr_holder_t name) + { return mp_header->template find(name); } + + //!Creates a named object or array in memory + //! + //!Allocates and constructs a T object or an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. If an array is being constructed all objects are + //!created using the same parameters given to this function. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> Throws boost::interprocess::bad_alloc if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and if an + //!array was being constructed, destructors of created objects are called + //!before freeing the memory. + template + typename segment_manager::template construct_proxy::type + construct(char_ptr_holder_t name) + { return mp_header->template construct(name); } + + //!Finds or creates a named object or array in memory + //! + //!Tries to find an object with the given name in memory. If + //!found, returns the pointer to this pointer. If the object is not found, + //!allocates and constructs a T object or an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. If an array is being constructed all objects are + //!created using the same parameters given to this function. + //! + //!-> Throws boost::interprocess::bad_alloc if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and if an + //!array was being constructed, destructors of created objects are called + //!before freeing the memory. + template + typename segment_manager::template construct_proxy::type + find_or_construct(char_ptr_holder_t name) + { return mp_header->template find_or_construct(name); } + + //!Creates a named object or array in memory + //! + //!Allocates and constructs a T object or an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. If an array is being constructed all objects are + //!created using the same parameters given to this function. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> Returns 0 if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and if an + //!array was being constructed, destructors of created objects are called + //!before freeing the memory. + template + typename segment_manager::template construct_proxy::type + construct(char_ptr_holder_t name, std::nothrow_t nothrow) + { return mp_header->template construct(name, nothrow); } + + //!Finds or creates a named object or array in memory + //! + //!Tries to find an object with the given name in memory. If + //!found, returns the pointer to this pointer. If the object is not found, + //!allocates and constructs a T object or an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. If an array is being constructed all objects are + //!created using the same parameters given to this function. + //! + //!-> Returns 0 if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and if an + //!array was being constructed, destructors of created objects are called + //!before freeing the memory. + template + typename segment_manager::template construct_proxy::type + find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow) + { return mp_header->template find_or_construct(name, nothrow); } + + //!Creates a named array from iterators in memory + //! + //!Allocates and constructs an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. Each element in the array is created using the + //!objects returned when dereferencing iterators as parameters + //!and incrementing all iterators for each element. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> Throws boost::interprocess::bad_alloc if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and + //!destructors of created objects are called before freeing the memory. + template + typename segment_manager::template construct_iter_proxy::type + construct_it(char_ptr_holder_t name) + { return mp_header->template construct_it(name); } + + //!Finds or creates a named array from iterators in memory + //! + //!Tries to find an object with the given name in memory. If + //!found, returns the pointer to this pointer. If the object is not found, + //!allocates and constructs an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. Each element in the array is created using the + //!objects returned when dereferencing iterators as parameters + //!and incrementing all iterators for each element. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> Throws boost::interprocess::bad_alloc if there is no available memory + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and + //!destructors of created objects are called before freeing the memory. + template + typename segment_manager::template construct_iter_proxy::type + find_or_construct_it(char_ptr_holder_t name) + { return mp_header->template find_or_construct_it(name); } + + //!Creates a named array from iterators in memory + //! + //!Allocates and constructs an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. Each element in the array is created using the + //!objects returned when dereferencing iterators as parameters + //!and incrementing all iterators for each element. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> If there is no available memory, returns 0. + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and + //!destructors of created objects are called before freeing the memory.*/ + template + typename segment_manager::template construct_iter_proxy::type + construct_it(char_ptr_holder_t name, std::nothrow_t nothrow) + { return mp_header->template construct_it(name, nothrow); } + + //!Finds or creates a named array from iterators in memory + //! + //!Tries to find an object with the given name in memory. If + //!found, returns the pointer to this pointer. If the object is not found, + //!allocates and constructs an array of T in memory, + //!associates this with the given name and returns a pointer to the + //!created object. Each element in the array is created using the + //!objects returned when dereferencing iterators as parameters + //!and incrementing all iterators for each element. + //! + //!-> If the name was previously used, returns 0. + //! + //!-> If there is no available memory, returns 0. + //! + //!-> If T's constructor throws, the function throws that exception. + //! + //!Memory is freed automatically if T's constructor throws and + //!destructors of created objects are called before freeing the memory.*/ + template + typename segment_manager::template construct_iter_proxy::type + find_or_construct_it(char_ptr_holder_t name, std::nothrow_t nothrow) + { return mp_header->template find_or_construct_it(name, nothrow); } + + //!Calls a functor and guarantees that no new construction, search or + //!destruction will be executed by any process while executing the object + //!function call. If the functor throws, this function throws. + template + void atomic_func(Func &f) + { mp_header->atomic_func(f); } + + //!Destroys a named memory object or array. + //! + //!Finds the object with the given name, calls its destructors, + //!frees used memory and returns true. + //! + //!-> If the object is not found, it returns false. + //! + //!Exception Handling: + //! + //!When deleting a dynamically object or array, the Standard + //!does not guarantee that dynamically allocated memory, will be released. + //!Also, when deleting arrays, the Standard doesn't require calling + //!destructors for the rest of the objects if for one of them the destructor + //!terminated with an exception. + //! + //!Destroying an object: + //! + //!If the destructor throws, the memory will be freed and that exception + //!will be thrown. + //! + //!Destroying an array: + //! + //!When destroying an array, if a destructor throws, the rest of + //!destructors are called. If any of these throws, the exceptions are + //!ignored. The name association will be erased, memory will be freed and + //!the first exception will be thrown. This guarantees the unlocking of + //!mutexes and other resources. + //! + //!For all theses reasons, classes with throwing destructors are not + //!recommended. + template + bool destroy(const CharType *name) + { return mp_header->template destroy(name); } + + //!Destroys the unique instance of type T + //! + //!Calls the destructor, frees used memory and returns true. + //! + //!Exception Handling: + //! + //!When deleting a dynamically object, the Standard does not + //!guarantee that dynamically allocated memory will be released. + //! + //!Destroying an object: + //! + //!If the destructor throws, the memory will be freed and that exception + //!will be thrown. + //! + //!For all theses reasons, classes with throwing destructors are not + //!recommended for memory. + template + bool destroy(const detail::unique_instance_t *const ) + { return mp_header->template destroy(unique_instance); } + + //!Destroys the object (named, unique, or anonymous) + //! + //!Calls the destructor, frees used memory and returns true. + //! + //!Exception Handling: + //! + //!When deleting a dynamically object, the Standard does not + //!guarantee that dynamically allocated memory will be released. + //! + //!Destroying an object: + //! + //!If the destructor throws, the memory will be freed and that exception + //!will be thrown. + //! + //!For all theses reasons, classes with throwing destructors are not + //!recommended for memory. + template + void destroy_ptr(const T *ptr) + { mp_header->template destroy_ptr(ptr); } + + //!Returns the name of an object created with construct/find_or_construct + //!functions. Does not throw + template + static const char_type *get_instance_name(const T *ptr) + { return segment_manager::get_instance_name(ptr); } + + //!Returns is the type an object created with construct/find_or_construct + //!functions. Does not throw. + template + static instance_type get_instance_type(const T *ptr) + { return segment_manager::get_instance_type(ptr); } + + //!Returns the length of an object created with construct/find_or_construct + //!functions (1 if is a single element, >=1 if it's an array). Does not throw. + template + static std::size_t get_instance_length(const T *ptr) + { return segment_manager::get_instance_length(ptr); } + + //!Preallocates needed index resources to optimize the + //!creation of "num" named objects in the memory segment. + //!Can throw boost::interprocess::bad_alloc if there is no enough memory. + void reserve_named_objects(std::size_t num) + { mp_header->reserve_named_objects(num); } + + //!Preallocates needed index resources to optimize the + //!creation of "num" unique objects in the memory segment. + //!Can throw boost::interprocess::bad_alloc if there is no enough memory. + void reserve_unique_objects(std::size_t num) + { mp_header->reserve_unique_objects(num); } + + //!Calls shrink_to_fit in both named and unique object indexes + //to try to free unused memory from those indexes. + void shrink_to_fit_indexes() + { mp_header->shrink_to_fit_indexes(); } + + //!Returns the number of named objects stored + //!in the managed segment. + std::size_t get_num_named_objects() + { return mp_header->get_num_named_objects(); } + + //!Returns the number of unique objects stored + //!in the managed segment. + std::size_t get_num_unique_objects() + { return mp_header->get_num_unique_objects(); } + + //!Returns a constant iterator to the index storing the + //!named allocations. NOT thread-safe. Never throws. + const_named_iterator named_begin() const + { return mp_header->named_begin(); } + + //!Returns a constant iterator to the end of the index + //!storing the named allocations. NOT thread-safe. Never throws. + const_named_iterator named_end() const + { return mp_header->named_end(); } + + //!Returns a constant iterator to the index storing the + //!unique allocations. NOT thread-safe. Never throws. + const_unique_iterator unique_begin() const + { return mp_header->unique_begin(); } + + //!Returns a constant iterator to the end of the index + //!storing the unique allocations. NOT thread-safe. Never throws. + const_unique_iterator unique_end() const + { return mp_header->unique_end(); } + + //!This is the default allocator to allocate types T + //!from this managed segment + template + struct allocator + { + typedef typename segment_manager::template allocator::type type; + }; + + //!Returns an instance of the default allocator for type T + //!initialized that allocates memory from this segment manager. + template + typename allocator::type + get_allocator() + { return mp_header->get_allocator(); } + + //!This is the default deleter to delete types T + //!from this managed segment. + template + struct deleter + { + typedef typename segment_manager::template deleter::type type; + }; + + //!Returns an instance of the default allocator for type T + //!initialized that allocates memory from this segment manager. + template + typename deleter::type + get_deleter() + { return mp_header->get_deleter(); } + + protected: + //!Swaps the segment manager's managed by this managed memory segment. + //!NOT thread-safe. Never throws. + void swap(basic_managed_memory_impl &other) + { std::swap(mp_header, other.mp_header); } + + private: + segment_manager *mp_header; +}; + +template +class create_open_func +{ + public: + create_open_func(BasicManagedMemoryImpl * const frontend, detail::create_enum_t type) + : m_frontend(frontend), m_type(type){} + + bool operator()(void *addr, std::size_t size, bool created) const + { + if(((m_type == detail::DoOpen) && created) || + ((m_type == detail::DoCreate) && !created)) + return false; + + if(created) + return m_frontend->create_impl(addr, size); + else + return m_frontend->open_impl (addr, size); + } + + private: + BasicManagedMemoryImpl *m_frontend; + detail::create_enum_t m_type; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP + diff --git a/thirdparty/boost/interprocess/detail/managed_open_or_create_impl.hpp b/thirdparty/boost/interprocess/detail/managed_open_or_create_impl.hpp new file mode 100644 index 0000000..a29796d --- /dev/null +++ b/thirdparty/boost/interprocess/detail/managed_open_or_create_impl.hpp @@ -0,0 +1,419 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL +#define BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +namespace detail { + +template +class managed_open_or_create_impl +{ + //Non-copyable + managed_open_or_create_impl(); + managed_open_or_create_impl(const managed_open_or_create_impl &); + managed_open_or_create_impl &operator=(const managed_open_or_create_impl &); + + enum + { + UninitializedSegment, + InitializingSegment, + InitializedSegment, + CorruptedSegment + }; + + public: + + static const std::size_t + ManagedOpenOrCreateUserOffset = + detail::ct_rounded_size + < sizeof(boost::uint32_t) + , detail::alignment_of::value>::value; + + managed_open_or_create_impl(create_only_t, + const char *name, + std::size_t size, + mode_t mode = read_write, + const void *addr = 0) + { + m_name = name; + priv_open_or_create + ( detail::DoCreate + , size + , mode + , addr + , null_mapped_region_function()); + } + + managed_open_or_create_impl(open_only_t, + const char *name, + mode_t mode = read_write, + const void *addr = 0) + { + m_name = name; + priv_open_or_create + ( detail::DoOpen + , 0 + , mode + , addr + , null_mapped_region_function()); + } + + + managed_open_or_create_impl(open_or_create_t, + const char *name, + std::size_t size, + mode_t mode = read_write, + const void *addr = 0) + { + m_name = name; + priv_open_or_create + ( detail::DoOpenOrCreate + , size + , mode + , addr + , null_mapped_region_function()); + } + + template + managed_open_or_create_impl(create_only_t, + const char *name, + std::size_t size, + mode_t mode, + const void *addr, + const ConstructFunc &construct_func) + { + m_name = name; + priv_open_or_create + (detail::DoCreate + , size + , mode + , addr + , construct_func); + } + + template + managed_open_or_create_impl(open_only_t, + const char *name, + mode_t mode, + const void *addr, + const ConstructFunc &construct_func) + { + m_name = name; + priv_open_or_create + ( detail::DoOpen + , 0 + , mode + , addr + , construct_func); + } + + template + managed_open_or_create_impl(open_or_create_t, + const char *name, + std::size_t size, + mode_t mode, + const void *addr, + const ConstructFunc &construct_func) + { + m_name = name; + priv_open_or_create + ( detail::DoOpenOrCreate + , size + , mode + , addr + , construct_func); + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + managed_open_or_create_impl + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + managed_open_or_create_impl + (managed_open_or_create_impl &&moved) + { this->swap(moved); } + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + managed_open_or_create_impl &operator= + (detail::moved_object &moved) + { + managed_open_or_create_impl tmp(moved); + this->swap(tmp); + return *this; + } + #else + managed_open_or_create_impl &operator= + (managed_open_or_create_impl &&moved) + { + managed_open_or_create_impl tmp(move(moved)); + this->swap(tmp); + return *this; + } + #endif + + ~managed_open_or_create_impl() + {} + + std::size_t get_user_size() const + { return m_mapped_region.get_size() - ManagedOpenOrCreateUserOffset; } + + void *get_user_address() const + { return (char*)m_mapped_region.get_address() + ManagedOpenOrCreateUserOffset; } + + std::size_t get_real_size() const + { return m_mapped_region.get_size(); } + + void *get_real_address() const + { return (char*)m_mapped_region.get_address(); } + + void swap(managed_open_or_create_impl &other) + { + this->m_name.swap(other.m_name); + this->m_mapped_region.swap(other.m_mapped_region); + } + + const char *get_name() const + { return m_name.c_str(); } + + bool flush() + { return m_mapped_region.flush(); } + + private: + + //These are templatized to allow explicit instantiations + template + static void write_whole_device(DeviceAbstraction &, std::size_t, detail::false_) + {} //Empty + + template + static void write_whole_device(DeviceAbstraction &dev, std::size_t size, detail::true_) + { + file_handle_t hnd = detail::file_handle_from_mapping_handle(dev.get_mapping_handle()); + + if(size <= ManagedOpenOrCreateUserOffset){ + throw interprocess_exception(error_info(system_error_code())); + } + + size -= ManagedOpenOrCreateUserOffset; + + if(!detail::set_file_pointer(hnd, ManagedOpenOrCreateUserOffset, file_begin)){ + throw interprocess_exception(error_info(system_error_code())); + } + + //We will write zeros in the file + for(std::size_t remaining = size, write_size = 0 + ;remaining > 0 + ;remaining -= write_size){ + const std::size_t DataSize = 512; + static char data [DataSize]; + write_size = DataSize < remaining ? DataSize : remaining; + if(!detail::write_file(hnd, data, write_size)){ + error_info err = system_error_code(); + throw interprocess_exception(err); + } + } + } + + //These are templatized to allow explicit instantiations + template + static void truncate_device(DeviceAbstraction &, std::size_t, detail::false_) + {} //Empty + + template + static void truncate_device(DeviceAbstraction &dev, std::size_t size, detail::true_) + { dev.truncate(size); } + + //These are templatized to allow explicit instantiations + template + static void create_device(DeviceAbstraction &dev, const char *name, std::size_t size, detail::false_) + { + DeviceAbstraction tmp(create_only, name, read_write, size); + tmp.swap(dev); + } + + template + static void create_device(DeviceAbstraction &dev, const char *name, std::size_t, detail::true_) + { + DeviceAbstraction tmp(create_only, name, read_write); + tmp.swap(dev); + } + + template inline + void priv_open_or_create + (detail::create_enum_t type, std::size_t size, + mode_t mode, const void *addr, + ConstructFunc construct_func) + { + typedef detail::bool_ file_like_t; + (void)mode; + error_info err; + bool created = false; + DeviceAbstraction dev; + + if(type != detail::DoOpen && size < ManagedOpenOrCreateUserOffset){ + throw interprocess_exception(error_info(size_error)); + } + + if(type == detail::DoOpen){ + DeviceAbstraction tmp(open_only, m_name.c_str(), read_write); + tmp.swap(dev); + created = false; + } + else if(type == detail::DoCreate){ + create_device(dev, m_name.c_str(), size, file_like_t()); + created = true; + } + else if(type == detail::DoOpenOrCreate){ + //This loop is very ugly, but brute force is sometimes better + //than diplomacy. If someone knows how to open or create a + //file and know if we have really created it or just open it + //drop me a e-mail! + bool completed = false; + while(!completed){ + try{ + create_device(dev, m_name.c_str(), size, file_like_t()); + created = true; + completed = true; + } + catch(interprocess_exception &ex){ + if(ex.get_error_code() != already_exists_error){ + throw; + } + else{ + try{ + DeviceAbstraction tmp(open_only, m_name.c_str(), read_write); + dev.swap(tmp); + created = false; + completed = true; + } + catch(interprocess_exception &ex){ + if(ex.get_error_code() != not_found_error){ + throw; + } + } + } + } + detail::thread_yield(); + } + } + + if(created){ + try{ + //If this throws, we are lost + truncate_device(dev, size, file_like_t()); + + //If the following throws, we will truncate the file to 1 + mapped_region region(dev, read_write, 0, 0, addr); + boost::uint32_t *patomic_word = 0; //avoid gcc warning + patomic_word = static_cast(region.get_address()); + boost::uint32_t previous = detail::atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment); + + if(previous == UninitializedSegment){ + try{ + write_whole_device(dev, size, file_like_t()); + construct_func((char*)region.get_address() + ManagedOpenOrCreateUserOffset, size - ManagedOpenOrCreateUserOffset, true); + //All ok, just move resources to the external mapped region + m_mapped_region.swap(region); + } + catch(...){ + detail::atomic_write32(patomic_word, CorruptedSegment); + throw; + } + detail::atomic_write32(patomic_word, InitializedSegment); + } + else if(previous == InitializingSegment || previous == InitializedSegment){ + throw interprocess_exception(error_info(already_exists_error)); + } + else{ + throw interprocess_exception(error_info(corrupted_error)); + } + } + catch(...){ + try{ + truncate_device(dev, 1u, file_like_t()); + } + catch(...){ + } + throw; + } + } + else{ + if(FileBased){ + offset_t filesize = 0; + while(filesize == 0){ + if(!detail::get_file_size(detail::file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){ + throw interprocess_exception(error_info(system_error_code())); + } + detail::thread_yield(); + } + if(filesize == 1){ + throw interprocess_exception(error_info(corrupted_error)); + } + } + + mapped_region region(dev, read_write, 0, 0, addr); + + boost::uint32_t *patomic_word = static_cast(region.get_address()); + boost::uint32_t value = detail::atomic_read32(patomic_word); + + while(value == InitializingSegment || value == UninitializedSegment){ + detail::thread_yield(); + value = detail::atomic_read32(patomic_word); + } + + if(value != InitializedSegment) + throw interprocess_exception(error_info(corrupted_error)); + + construct_func((char*)region.get_address() + ManagedOpenOrCreateUserOffset, region.get_size(), false); + //All ok, just move resources to the external mapped region + m_mapped_region.swap(region); + } + } + + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction() + { detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); } + + mapped_region m_mapped_region; + std::string m_name; +}; + +template +inline void swap(managed_open_or_create_impl &x + ,managed_open_or_create_impl &y) +{ x.swap(y); } + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#endif //#ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL diff --git a/thirdparty/boost/interprocess/detail/math_functions.hpp b/thirdparty/boost/interprocess/detail/math_functions.hpp new file mode 100644 index 0000000..bbd0cea --- /dev/null +++ b/thirdparty/boost/interprocess/detail/math_functions.hpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Stephen Cleary 2000. +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +// This file is a slightly modified file from Boost.Pool +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP +#define BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP + +namespace boost { +namespace interprocess { +namespace detail { + +// Greatest common divisor and least common multiple + +// +// gcd is an algorithm that calculates the greatest common divisor of two +// integers, using Euclid's algorithm. +// +// Pre: A > 0 && B > 0 +// Recommended: A > B +template +inline Integer gcd(Integer A, Integer B) +{ + do + { + const Integer tmp(B); + B = A % B; + A = tmp; + } while (B != 0); + + return A; +} + +// +// lcm is an algorithm that calculates the least common multiple of two +// integers. +// +// Pre: A > 0 && B > 0 +// Recommended: A > B +template +inline Integer lcm(const Integer & A, const Integer & B) +{ + Integer ret = A; + ret /= gcd(A, B); + ret *= B; + return ret; +} + +template +inline Integer log2_ceil(const Integer & A) +{ + Integer i = 0; + Integer power_of_2 = 1; + + while(power_of_2 < A){ + power_of_2 <<= 1; + ++i; + } + return i; +} + +template +inline Integer upper_power_of_2(const Integer & A) +{ + Integer power_of_2 = 1; + + while(power_of_2 < A){ + power_of_2 <<= 1; + } + return power_of_2; +} + +} // namespace detail +} // namespace interprocess +} // namespace boost + +#endif diff --git a/thirdparty/boost/interprocess/detail/min_max.hpp b/thirdparty/boost/interprocess/detail/min_max.hpp new file mode 100644 index 0000000..45c04e6 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/min_max.hpp @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP +#define BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace interprocess { + +template +const T &max_value(const T &a, const T &b) +{ return a > b ? a : b; } + +template +const T &min_value(const T &a, const T &b) +{ return a < b ? a : b; } + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MIN_MAX_HPP + diff --git a/thirdparty/boost/interprocess/detail/move.hpp b/thirdparty/boost/interprocess/detail/move.hpp new file mode 100644 index 0000000..560d281 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/move.hpp @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MOVE_HPP +#define BOOST_INTERPROCESS_MOVE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +//!\file +//!Describes a function and a type to emulate move semantics. + +namespace boost { +namespace interprocess { + +//!Trait class to detect if a type is +//!movable +template +struct is_movable +{ + enum { value = false }; +}; + +} //namespace interprocess { +} //namespace boost { + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +//!An object that represents a +//!moved object. +template +struct moved_object +{ + moved_object(const T &obj) + : m_obj(const_cast(&obj)) + {} + + T &get() const + { return *m_obj; } + + private: + T *m_obj; +}; + +// Metafunction that, given movable T, provides move_source, else T&. +template +struct move_type +{ + public: // metafunction result + typedef typename if_, moved_object, T&>::type type; +}; + +template +class move_return +{ + typedef moved_object moved_type; + private: + mutable T m_moved; + + + public: + typedef T type; + + move_return(T& returned) + : m_moved(moved_object(returned)) + {} + + move_return(const move_return& operand) + : m_moved(const_cast(operand)) + {} + + operator moved_type() const + { return moved_type(m_moved); } +}; + +template +struct return_type +{ + public: // metafunction result + + typedef typename if_, move_return, T>::type type; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +namespace boost { +namespace interprocess { + +//!A function that converts an object to a moved object so that +//!it can match a function taking a detail::moved_object object. +template +typename detail::move_type::type move + (const Object &object) +{ + typedef typename detail::move_type::type type; + return type(object); +} + +} //namespace interprocess { +} //namespace boost { + +#else //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE + +#include + +namespace boost { +namespace interprocess { + +template +inline typename detail::remove_reference::type&& +move(T&& t) +{ return t; } + +template +inline +T&& +forward(typename identity::type&& t) +{ return t; } + +} //namespace interprocess { +} //namespace boost { + +#endif //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MOVE_HPP diff --git a/thirdparty/boost/interprocess/detail/move_iterator.hpp b/thirdparty/boost/interprocess/detail/move_iterator.hpp new file mode 100644 index 0000000..5bdda8f --- /dev/null +++ b/thirdparty/boost/interprocess/detail/move_iterator.hpp @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED +#define BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED + +#include +#include + +namespace boost{ +namespace interprocess{ +namespace detail{ + +template +class move_iterator +{ + public: + typedef It iterator_type; + typedef typename std::iterator_traits::value_type value_type; + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + typedef typename move_type::type reference; + #else + typedef value_type && reference; + #endif + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + + move_iterator() + {} + + explicit move_iterator(It i) + : m_it(i) + {} + + template + move_iterator(const move_iterator& u) + : m_it(u.base()) + {} + + const iterator_type &base() const + { return m_it; } + + iterator_type &base() + { return m_it; } + + reference operator*() const + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + { return move(*m_it); } + #else + { return *m_it; } + #endif + + pointer operator->() const + { return m_it; } + + move_iterator& operator++() + { ++m_it; return *this; } + + move_iterator operator++(int) + { move_iterator tmp(*this); ++(*this); return tmp; } + + move_iterator& operator--() + { --m_it; return *this; } + + move_iterator operator--(int) + { move_iterator tmp(*this); --(*this); return tmp; } + + move_iterator operator+ (difference_type n) const + { return move_iterator(m_it + n); } + + move_iterator& operator+=(difference_type n) + { m_it += n; return *this; } + + move_iterator operator- (difference_type n) const + { return move_iterator(m_it - n); } + + move_iterator& operator-=(difference_type n) + { m_it -= n; return *this; } + + reference operator[](difference_type n) const + { return move(m_it[n]); } + + private: + It m_it; +}; + +template inline +bool operator==(const move_iterator& x, const move_iterator& y) +{ return x.base() == y.base(); } + +template inline +bool operator!=(const move_iterator& x, const move_iterator& y) +{ return x.base() != y.base(); } + +template inline +bool operator< (const move_iterator& x, const move_iterator& y) +{ return x.base() < y.base(); } + +template inline +bool operator<=(const move_iterator& x, const move_iterator& y) +{ return x.base() <= y.base(); } + +template inline +bool operator> (const move_iterator& x, const move_iterator& y) +{ return x.base() > y.base(); } + +template inline +bool operator>=(const move_iterator& x, const move_iterator& y) +{ return x.base() >= y.base(); } + +template inline +typename move_iterator::difference_type + operator-(const move_iterator& x, const move_iterator& y) +{ return x.base() - y.base(); } + +template inline +move_iterator + operator+(typename move_iterator::difference_type n + ,const move_iterator& x) +{ return move_iterator(x.base() + n); } + +template +move_iterator make_move_iterator(const It &it) +{ return move_iterator(it); } + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#endif //#ifndef BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/detail/mpl.hpp b/thirdparty/boost/interprocess/detail/mpl.hpp new file mode 100644 index 0000000..e868c94 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/mpl.hpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_MPL_HPP +#define BOOST_INTERPROCESS_DETAIL_MPL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +//#include + +namespace boost { +namespace interprocess { +namespace detail { + +template +struct integral_constant +{ + static const T value = val; + typedef integral_constant type; +}; + +template< bool C_ > +struct bool_ : integral_constant +{ + static const bool value = C_; +}; + +typedef bool_ true_; +typedef bool_ false_; + +typedef true_ true_type; +typedef false_ false_type; + +typedef char yes_type; +struct no_type +{ + char padding[8]; +}; + +template +struct enable_if_c { + typedef T type; +}; + +template +struct enable_if_c {}; + +template +struct enable_if : public enable_if_c {}; + +template +class is_convertible +{ + typedef char true_t; + class false_t { char dummy[2]; }; + static true_t dispatch(U); + static false_t dispatch(...); + static T trigger(); + public: + enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; +}; + +template< + bool C + , typename T1 + , typename T2 + > +struct if_c +{ + typedef T1 type; +}; + +template< + typename T1 + , typename T2 + > +struct if_c +{ + typedef T2 type; +}; + +template< + typename T1 + , typename T2 + , typename T3 + > +struct if_ +{ + typedef typename if_c<0 != T1::value, T2, T3>::type type; +}; + + +template +struct select1st +// : public std::unary_function +{ + const typename Pair::first_type& operator()(const Pair& x) const + { return x.first; } + + const typename Pair::first_type& operator()(const typename Pair::first_type& x) const + { return x; } +}; + +// identity is an extension: it is not part of the standard. +template +struct identity +// : public std::unary_function +{ + const T& operator()(const T& x) const + { return x; } +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MPL_HPP + diff --git a/thirdparty/boost/interprocess/detail/named_proxy.hpp b/thirdparty/boost/interprocess/detail/named_proxy.hpp new file mode 100644 index 0000000..317cc9d --- /dev/null +++ b/thirdparty/boost/interprocess/detail/named_proxy.hpp @@ -0,0 +1,279 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP +#define BOOST_INTERPROCESS_NAMED_PROXY_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a proxy class that implements named allocation syntax. + +namespace boost { +namespace interprocess { +namespace detail { + +//!Function object that makes placement new +//!without arguments +template +struct Ctor0Arg : public placement_destroy +{ + typedef Ctor0Arg self_t; + + Ctor0Arg(){} + + self_t& operator++() { return *this; } + self_t operator++(int) { return *this; } + + void construct(void *mem) + { new(mem)T; } + + virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) + { + T* memory = static_cast(mem); + for(constructed = 0; constructed < num; ++constructed) + new(memory++)T; + } +}; + +#ifndef BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS +# define BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS 10 +#endif + +//////////////////////////////////////////////////////////////// +// What the macro should generate (n == 2): +// +// template +// struct Ctor2Arg +// { +// typedef detail::bool_ IsIterator; +// typedef Ctor2Arg self_t; +// +// void do_increment(detail::false_) +// { ++m_p1; ++m_p2; } +// +// void do_increment(detail::true_){} +// +// self_t& operator++() +// { +// this->do_increment(IsIterator()); +// return *this; +// } +// +// self_t operator++(int) { return ++*this; *this; } +// +// Ctor2Arg(const P1 &p1, const P2 &p2) +// : p1((P1 &)p_1), p2((P2 &)p_2) {} +// +// void construct(void *mem) +// { new(object)T(m_p1, m_p2); } +// +// virtual void construct_n(void *mem +// , std::size_t num +// , std::size_t &constructed) +// { +// T* memory = static_cast(mem); +// for(constructed = 0; constructed < num; ++constructed){ +// this->construct(memory++, IsIterator()); +// this->do_increment(IsIterator()); +// } +// } +// +// private: +// void construct(void *mem, detail::true_) +// { new(mem)T(*m_p1, *m_p2); } +// +// void construct(void *mem, detail::false_) +// { new(mem)T(m_p1, m_p2); } +// +// P1 &m_p1; P2 &m_p2; +// }; +//////////////////////////////////////////////////////////////// + +//Note: +//We define template parameters as const references to +//be able to bind temporaries. After that we will un-const them. +//This cast is ugly but it is necessary until "perfect forwarding" +//is achieved in C++0x. Meanwhile, if we want to be able to +//bind rvalues with non-const references, we have to be ugly +#define BOOST_INTERPROCESS_AUX_PARAM_LIST(z, n, data) \ + const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \ +//! + +#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \ + BOOST_PP_CAT(m_p, n) (const_cast(BOOST_PP_CAT(p, n))) \ +//! + +#define BOOST_INTERPROCESS_AUX_PARAM_INC(z, n, data) \ + BOOST_PP_CAT(++m_p, n) \ +//! + +#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \ + BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \ +//! + +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \ + : public placement_destroy \ + { \ + typedef detail::bool_ IsIterator; \ + typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \ + \ + void do_increment(detail::true_) \ + { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \ + \ + void do_increment(detail::false_){} \ + \ + self_t& operator++() \ + { \ + this->do_increment(IsIterator()); \ + return *this; \ + } \ + \ + self_t operator++(int) { return ++*this; *this; } \ + \ + BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \ + ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _) ) \ + : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \ + \ + virtual void construct_n(void *mem \ + , std::size_t num \ + , std::size_t &constructed) \ + { \ + T* memory = static_cast(mem); \ + for(constructed = 0; constructed < num; ++constructed){ \ + this->construct(memory++, IsIterator()); \ + this->do_increment(IsIterator()); \ + } \ + } \ + \ + private: \ + void construct(void *mem, detail::true_) \ + { new(mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \ + \ + void construct(void *mem, detail::false_) \ + { new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \ + \ + BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \ + }; \ +//! + + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS) +#include BOOST_PP_LOCAL_ITERATE() + +#undef BOOST_INTERPROCESS_AUX_PARAM_LIST +#undef BOOST_INTERPROCESS_AUX_PARAM_INIT +#undef BOOST_INTERPROCESS_AUX_PARAM_DEFINE +#undef BOOST_INTERPROCESS_AUX_PARAM_INC + +//!Describes a proxy class that implements named +//!allocation syntax. +template + < class SegmentManager //segment manager to construct the object + , class T //type of object to build + , bool is_iterator //passing parameters are normal object or iterators? + > +class named_proxy +{ + typedef typename SegmentManager::char_type char_type; + const char_type * mp_name; + SegmentManager * mp_mngr; + mutable std::size_t m_num; + const bool m_find; + const bool m_dothrow; + + public: + named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow) + : mp_name(name), mp_mngr(mngr), m_num(1) + , m_find(find), m_dothrow(dothrow) + {} + + //!makes a named allocation and calls the + //!default constructor + T *operator()() const + { + Ctor0Arg ctor_obj; + return mp_mngr->template + generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj); + } + //! + + // Boost preprocessor used to create operator() overloads + #define BOOST_INTERPROCESS_AUX_TYPE_LIST(z, n, data) \ + BOOST_PP_CAT(P, n) \ + //! + + #define BOOST_INTERPROCESS_AUX_PARAM_LIST(z, n, data) \ + const BOOST_PP_CAT(P, n) BOOST_PP_CAT(&p, n) \ + //! + + #define BOOST_PP_LOCAL_MACRO(n) \ + template \ + T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _)) const \ + { \ + typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \ + \ + ctor_obj_t; \ + ctor_obj_t ctor_obj (BOOST_PP_ENUM_PARAMS(n, p)); \ + return mp_mngr->template generic_construct \ + (mp_name, m_num, m_find, m_dothrow, ctor_obj); \ + } \ + //! + + #define BOOST_PP_LOCAL_LIMITS ( 1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS ) + #include BOOST_PP_LOCAL_ITERATE() + #undef BOOST_INTERPROCESS_AUX_PARAM_LIST + #undef BOOST_INTERPROCESS_AUX_TYPE_LIST + + //////////////////////////////////////////////////////////////////////// + // What the macro should generate (n == 2) + //////////////////////////////////////////////////////////////////////// + // + // template + // T *operator()(P1 &p1, P2 &p2) const + // { + // typedef Ctor2Arg + // + // ctor_obj_t; + // ctor_obj_t ctor_obj(p1, p2); + // + // return mp_mngr->template generic_construct + // (mp_name, m_num, m_find, m_dothrow, ctor_obj); + // } + // + ////////////////////////////////////////////////////////////////////////// + + //This operator allows --> named_new("Name")[3]; <-- syntax + const named_proxy &operator[](std::size_t num) const + { m_num *= num; return *this; } +}; + +}}} //namespace boost { namespace interprocess { namespace detail { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP diff --git a/thirdparty/boost/interprocess/detail/os_file_functions.hpp b/thirdparty/boost/interprocess/detail/os_file_functions.hpp new file mode 100644 index 0000000..7429f41 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/os_file_functions.hpp @@ -0,0 +1,367 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP +#define BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP + +#include +#include +//#include + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +# include +#else +# ifdef BOOST_HAS_UNISTD_H +# include +# include +# include +# include +# include +# else +# error Unknown platform +# endif +#endif + +#include +#include + +namespace boost { +namespace interprocess { + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +typedef void * file_handle_t; +typedef long long offset_t; +typedef struct{ + void * handle; + bool is_shm; +} mapping_handle_t; + +typedef enum { read_only = winapi::generic_read + , read_write = winapi::generic_read | winapi::generic_write + , copy_on_write + , invalid_mode = 0xffff + } mode_t; + +typedef enum { file_begin = winapi::file_begin + , file_end = winapi::file_end + , file_current = winapi::file_current + } file_pos_t; + +namespace detail{ + +inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd) +{ + mapping_handle_t ret; + ret.handle = hnd; + ret.is_shm = false; + return ret; +} + +inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd) +{ return hnd.handle; } + +inline bool create_directory(const char *path) +{ return winapi::create_directory(path, 0); } + +inline const char *get_temporary_path() +{ return std::getenv("TMP"); } + +inline file_handle_t create_new_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + unsigned long attr = temporary ? winapi::file_attribute_temporary : 0; + return winapi::create_file + (name, (unsigned int)mode, winapi::create_new, attr); +} + +inline file_handle_t create_or_open_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + unsigned long attr = temporary ? winapi::file_attribute_temporary : 0; + return winapi::create_file + (name, (unsigned int)mode, winapi::open_always, attr); +} + +inline file_handle_t open_existing_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + unsigned long attr = temporary ? winapi::file_attribute_temporary : 0; + return winapi::create_file + (name, (unsigned int)mode, winapi::open_existing, attr); +} + +inline bool delete_file(const char *name) +{ return winapi::delete_file(name); } + +inline bool truncate_file (file_handle_t hnd, std::size_t size) +{ + if(!winapi::set_file_pointer_ex(hnd, size, 0, winapi::file_begin)){ + return false; + } + + if(!winapi::set_end_of_file(hnd)){ + return false; + } + return true; +} + +inline bool get_file_size(file_handle_t hnd, offset_t &size) +{ return winapi::get_file_size(hnd, size); } + +inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos) +{ return winapi::set_file_pointer_ex(hnd, off, 0, (unsigned long) pos); } + +inline bool get_file_pointer(file_handle_t hnd, offset_t &off) +{ return winapi::set_file_pointer_ex(hnd, 0, &off, winapi::file_current); } + +inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata) +{ + unsigned long written; + return 0 != winapi::write_file(hnd, data, (unsigned long)numdata, &written, 0); +} + +inline file_handle_t invalid_file() +{ return winapi::invalid_handle_value; } + +inline bool close_file(file_handle_t hnd) +{ return 0 != winapi::close_handle(hnd); } + +inline bool acquire_file_lock(file_handle_t hnd) +{ + static winapi::interprocess_overlapped overlapped; + const unsigned long len = 0xffffffff; +// winapi::interprocess_overlapped overlapped; +// std::memset(&overlapped, 0, sizeof(overlapped)); + return winapi::lock_file_ex + (hnd, winapi::lockfile_exclusive_lock, 0, len, len, &overlapped); +} + +inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired) +{ + const unsigned long len = 0xffffffff; + winapi::interprocess_overlapped overlapped; + std::memset(&overlapped, 0, sizeof(overlapped)); + if(!winapi::lock_file_ex + (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately, + 0, len, len, &overlapped)){ + return winapi::get_last_error() == winapi::error_lock_violation ? + acquired = false, true : false; + + } + return (acquired = true); +} + +inline bool release_file_lock(file_handle_t hnd) +{ + const unsigned long len = 0xffffffff; + winapi::interprocess_overlapped overlapped; + std::memset(&overlapped, 0, sizeof(overlapped)); + return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped); +} + +inline bool acquire_file_lock_sharable(file_handle_t hnd) +{ + const unsigned long len = 0xffffffff; + winapi::interprocess_overlapped overlapped; + std::memset(&overlapped, 0, sizeof(overlapped)); + return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped); +} + +inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired) +{ + const unsigned long len = 0xffffffff; + winapi::interprocess_overlapped overlapped; + std::memset(&overlapped, 0, sizeof(overlapped)); + if(!winapi::lock_file_ex + (hnd, winapi::lockfile_fail_immediately, 0, len, len, &overlapped)){ + return winapi::get_last_error() == winapi::error_lock_violation ? + acquired = false, true : false; + } + return (acquired = true); +} + + + +inline bool release_file_lock_sharable(file_handle_t hnd) +{ return release_file_lock(hnd); } + +#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +typedef int file_handle_t; +typedef off_t offset_t; +typedef file_handle_t mapping_handle_t; + +typedef enum { read_only = O_RDONLY + , read_write = O_RDWR + , copy_on_write + , invalid_mode = 0xffff + } mode_t; + +typedef enum { file_begin = SEEK_SET + , file_end = SEEK_END + , file_current = SEEK_CUR + } file_pos_t; + +namespace detail{ + +inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd) +{ return hnd; } + +inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd) +{ return hnd; } + +inline bool create_directory(const char *path) +{ return ::mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; } + +inline const char *get_temporary_path() +{ + const char *dir = std::getenv("TMPDIR"); + if(!dir){ + dir = std::getenv("TMP"); + if(!dir){ + dir = std::getenv("TEMP"); + if(!dir){ + dir = "/tmp"; + } + } + } + return dir; +} + +inline file_handle_t create_new_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + (void)temporary; + return ::open(name, ((int)mode) | O_EXCL | O_CREAT, S_IRWXG | S_IRWXO | S_IRWXU); +} + +inline file_handle_t create_or_open_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + (void)temporary; + return ::open(name, ((int)mode) | O_CREAT, S_IRWXG | S_IRWXO | S_IRWXU); +} + +inline file_handle_t open_existing_file + (const char *name, mode_t mode = read_write, bool temporary = false) +{ + (void)temporary; + return ::open(name, (int)mode, S_IRWXG | S_IRWXO | S_IRWXU); +} + +inline bool delete_file(const char *name) +{ return ::unlink(name) == 0; } + +inline bool truncate_file (file_handle_t hnd, std::size_t size) +{ return 0 == ::ftruncate(hnd, size); } + +inline bool get_file_size(file_handle_t hnd, offset_t &size) +{ + struct stat data; + bool ret = 0 == ::fstat(hnd, &data); + if(ret){ + size = data.st_size; + } + return ret; +} + +inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos) +{ return off == lseek(hnd, off, (int)pos); } + +inline bool get_file_pointer(file_handle_t hnd, offset_t &off) +{ + off = lseek(hnd, 0, SEEK_CUR); + return off != ((off_t)-1); +} + +inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata) +{ return (ssize_t(numdata)) == ::write(hnd, data, numdata); } + +inline file_handle_t invalid_file() +{ return -1; } + +inline bool close_file(file_handle_t hnd) +{ return ::close(hnd) == 0; } + +inline bool acquire_file_lock(file_handle_t hnd) +{ + struct ::flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + return -1 != ::fcntl(hnd, F_SETLKW, &lock); +} + +inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired) +{ + struct ::flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + int ret = ::fcntl(hnd, F_SETLK, &lock); + if(ret == -1){ + return (errno != EAGAIN && errno != EACCES) ? + acquired = false, true : false; + } + return (acquired = true); +} + +inline bool release_file_lock(file_handle_t hnd) +{ + struct ::flock lock; + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + return -1 != ::fcntl(hnd, F_SETLK, &lock); +} + +inline bool acquire_file_lock_sharable(file_handle_t hnd) +{ + struct ::flock lock; + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + return -1 != ::fcntl(hnd, F_SETLKW, &lock); +} + +inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired) +{ + struct flock lock; + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + int ret = ::fcntl(hnd, F_SETLK, &lock); + if(ret == -1){ + return (errno != EAGAIN && errno != EACCES) ? + acquired = false, true : false; + } + return (acquired = true); +} + + + +inline bool release_file_lock_sharable(file_handle_t hnd) +{ return release_file_lock(hnd); } + +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +} //namespace detail{ +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP diff --git a/thirdparty/boost/interprocess/detail/os_thread_functions.hpp b/thirdparty/boost/interprocess/detail/os_thread_functions.hpp new file mode 100644 index 0000000..400d373 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/os_thread_functions.hpp @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP +#define BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP + +#include +#include + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +# include +#else +# ifdef BOOST_HAS_UNISTD_H +# include +# include +# include +# else +# error Unknown platform +# endif +#endif + +namespace boost { +namespace interprocess { +namespace detail{ + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +typedef unsigned long OS_process_id_t; +typedef unsigned long OS_thread_id_t; + +inline OS_process_id_t get_current_process_id() +{ return winapi::get_current_process_id(); } + +inline OS_thread_id_t get_current_thread_id() +{ return winapi::get_current_thread_id(); } + +inline OS_thread_id_t get_invalid_thread_id() +{ return OS_thread_id_t(0xffffffff); } + +inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2) +{ return id1 == id2; } + +inline void thread_yield() +{ winapi::sched_yield(); } + +#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +typedef pthread_t OS_thread_id_t; +typedef int OS_process_id_t; + +inline OS_process_id_t get_current_process_id() +{ return getpid(); } + +inline pthread_t get_current_thread_id() +{ return pthread_self(); } + +inline OS_thread_id_t get_invalid_thread_id() +{ + static pthread_t invalid_id; + return invalid_id; +} + +inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2) +{ return 0 != pthread_equal(id1, id2); } + +inline void thread_yield() +{ sched_yield(); } + +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +} //namespace detail{ +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP diff --git a/thirdparty/boost/interprocess/detail/pointer_type.hpp b/thirdparty/boost/interprocess/detail/pointer_type.hpp new file mode 100644 index 0000000..249680b --- /dev/null +++ b/thirdparty/boost/interprocess/detail/pointer_type.hpp @@ -0,0 +1,74 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP +#define BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +struct two {char _[2];}; + +namespace pointer_type_imp { + +template static two test(...); +template static char test(typename U::pointer* = 0); + +} //namespace pointer_type_imp { + +template +struct has_pointer_type +{ + static const bool value = sizeof(pointer_type_imp::test(0)) == 1; +}; + +namespace pointer_type_imp { + +template ::value> +struct pointer_type +{ + typedef typename D::pointer type; +}; + +template +struct pointer_type +{ + typedef T* type; +}; + +} //namespace pointer_type_imp { + +template +struct pointer_type +{ + typedef typename pointer_type_imp::pointer_type::type>::type type; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_POINTER_TYPE_HPP + diff --git a/thirdparty/boost/interprocess/detail/posix_time_types_wrk.hpp b/thirdparty/boost/interprocess/detail/posix_time_types_wrk.hpp new file mode 100644 index 0000000..3acef90 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/posix_time_types_wrk.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_POSIX_TIMES_WRK_HPP +#define BOOST_INTERPROCESS_POSIX_TIMES_WRK_HPP + +//workaround to avoid winsock redefines when using date-time + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifndef WIN32_LEAN_AND_MEAN +#endif //#ifdef _WIN32 + +//#include +//#include +#include + +namespace boost { +namespace interprocess { + +typedef boost::date_time::microsec_clock microsec_clock; + +} +} + +#ifdef _WIN32 +#ifdef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifdef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifdef _WIN32 + +#endif //#ifndef BOOST_INTERPROCESS_POSIX_TIMES_WRK_HPP + diff --git a/thirdparty/boost/interprocess/detail/ptime_wrk.hpp b/thirdparty/boost/interprocess/detail/ptime_wrk.hpp new file mode 100644 index 0000000..dbe8177 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/ptime_wrk.hpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_PTIME_WRK_HPP +#define BOOST_INTERPROCESS_PTIME_WRK_HPP + +//workaround to avoid winsock redefines when using date-time + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifndef WIN32_LEAN_AND_MEAN +#endif //#ifdef _WIN32 + +#include + +#ifdef _WIN32 +#ifdef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifdef BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN +#endif //#ifdef _WIN32 + +#endif //#ifndef BOOST_INTERPROCESS_PTIME_WRK_HPP + diff --git a/thirdparty/boost/interprocess/detail/segment_manager_helper.hpp b/thirdparty/boost/interprocess/detail/segment_manager_helper.hpp new file mode 100644 index 0000000..65d2f05 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/segment_manager_helper.hpp @@ -0,0 +1,495 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP +#define BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include //std::size_t +#include //char_traits +#include //std::nothrow +#include //std::pair +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +//!\file +//!Describes the object placed in a memory segment that provides +//!named object allocation capabilities. + +namespace boost{ +namespace interprocess{ + +template +class segment_manager_base; + +//!An integer that describes the type of the +//!instance constructed in memory +enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type }; + +namespace detail{ + +template +class mem_algo_deallocator +{ + void * m_ptr; + MemoryAlgorithm & m_algo; + + public: + mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo) + : m_ptr(ptr), m_algo(algo) + {} + + void release() + { m_ptr = 0; } + + ~mem_algo_deallocator() + { if(m_ptr) m_algo.deallocate(m_ptr); } +}; + +/// @cond +struct block_header +{ + std::size_t m_value_bytes; + unsigned short m_num_char; + unsigned char m_value_alignment; + unsigned char m_alloc_type_sizeof_char; + + block_header(std::size_t value_bytes + ,std::size_t value_alignment + ,std::size_t allocation_type + ,std::size_t sizeof_char + ,std::size_t num_char + ) + : m_value_bytes(value_bytes) + , m_num_char(num_char) + , m_value_alignment(value_alignment) + , m_alloc_type_sizeof_char + ( ((unsigned char)allocation_type << 5u) | + ((unsigned char)sizeof_char & 0x1F) ) + {}; + + + template + block_header &operator= (const T& ) + { return *this; } + + std::size_t total_size() const + { + if(allocation_type() != anonymous_type){ + return name_offset() + (m_num_char+1)*sizeof_char(); + } + else{ + return value_offset() + m_value_bytes; + } + } + + std::size_t value_bytes() const + { return m_value_bytes; } + + template + std::size_t total_size_with_header() const + { + return get_rounded_size + ( sizeof(Header) + , detail::alignment_of::value) + + total_size(); + } + + std::size_t allocation_type() const + { return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; } + + std::size_t sizeof_char() const + { return m_alloc_type_sizeof_char & (unsigned char)0x1F; } + + template + CharType *name() const + { + return reinterpret_cast + (detail::char_ptr_cast(this) + name_offset()); + } + + std::size_t name_length() const + { return m_num_char; } + + std::size_t name_offset() const + { + return value_offset() + get_rounded_size(m_value_bytes, sizeof_char()); + } + + void *value() const + { + return detail::char_ptr_cast(this) + value_offset(); + } + + std::size_t value_offset() const + { + return get_rounded_size(sizeof(block_header), m_value_alignment); + } + + template + bool less_comp(const block_header &b) const + { + return m_num_char < b.m_num_char || + (m_num_char < b.m_num_char && + std::char_traits::compare + (name(), b.name(), m_num_char) < 0); + } + + template + bool equal_comp(const block_header &b) const + { + return m_num_char == b.m_num_char && + std::char_traits::compare + (name(), b.name(), m_num_char) == 0; + } + + template + static block_header *block_header_from_value(T *value) + { return block_header_from_value(value, sizeof(T), detail::alignment_of::value); } + + static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn) + { + block_header * hdr = + reinterpret_cast(detail::char_ptr_cast(value) - + get_rounded_size(sizeof(block_header), algn)); + (void)sz; + //Some sanity checks + assert(hdr->m_value_alignment == algn); + assert(hdr->m_value_bytes % sz == 0); + return hdr; + } + + template + static block_header *from_first_header(Header *header) + { + block_header * hdr = + reinterpret_cast(detail::char_ptr_cast(header) + + get_rounded_size(sizeof(Header), detail::alignment_of::value)); + //Some sanity checks + return hdr; + } + + template + static Header *to_first_header(block_header *bheader) + { + Header * hdr = + reinterpret_cast(detail::char_ptr_cast(bheader) - + get_rounded_size(sizeof(Header), detail::alignment_of::value)); + //Some sanity checks + return hdr; + } +}; + +inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table) +{ + //Try constructors + std::size_t constructed = 0; + BOOST_TRY{ + table.construct_n(mem, num, constructed); + } + //If there is an exception call destructors and erase index node + BOOST_CATCH(...){ + std::size_t destroyed = 0; + table.destroy_n(mem, constructed, destroyed); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +//Anti-exception node eraser +template +class value_eraser +{ + public: + value_eraser(Cont & cont, typename Cont::iterator it) + : m_cont(cont), m_index_it(it), m_erase(true){} + ~value_eraser() + { if(m_erase) m_cont.erase(m_index_it); } + + void release() { m_erase = false; } + + private: + Cont &m_cont; + typename Cont::iterator m_index_it; + bool m_erase; +}; + +template +struct intrusive_compare_key +{ + typedef CharT char_type; + + intrusive_compare_key(const CharT *str, std::size_t len) + : mp_str(str), m_len(len) + {} + + const CharT * mp_str; + std::size_t m_len; +}; + +//!This struct indicates an anonymous object creation +//!allocation +template +class instance_t +{ + instance_t(){} +}; + +template +struct char_if_void +{ + typedef T type; +}; + +template<> +struct char_if_void +{ + typedef char type; +}; + +typedef instance_t anonymous_instance_t; +typedef instance_t unique_instance_t; + +template +struct intrusive_value_type_impl + : public Hook +{ + private: + //Non-copyable + intrusive_value_type_impl(const intrusive_value_type_impl &); + intrusive_value_type_impl& operator=(const intrusive_value_type_impl &); + + public: + typedef CharType char_type; + + intrusive_value_type_impl(){} + + enum { BlockHdrAlignment = detail::alignment_of::value }; + + block_header *get_block_header() const + { + return (block_header *)(detail::char_ptr_cast(this) + + get_rounded_size(sizeof(*this), BlockHdrAlignment)); + } + + bool operator <(const intrusive_value_type_impl & other) const + { return (this->get_block_header())->template less_comp(*other.get_block_header()); } + + bool operator ==(const intrusive_value_type_impl & other) const + { return (this->get_block_header())->template equal_comp(*other.get_block_header()); } + + static intrusive_value_type_impl *get_intrusive_value_type(block_header *hdr) + { + return (intrusive_value_type_impl *)(detail::char_ptr_cast(hdr) - + get_rounded_size(sizeof(intrusive_value_type_impl), BlockHdrAlignment)); + } + + CharType *name() const + { return get_block_header()->template name(); } + + std::size_t name_length() const + { return get_block_header()->name_length(); } + + void *value() const + { return get_block_header()->value(); } +}; + +template +class char_ptr_holder +{ + public: + char_ptr_holder(const CharType *name) + : m_name(name) + {} + + char_ptr_holder(const detail::anonymous_instance_t *) + : m_name((CharType*)0) + {} + + char_ptr_holder(const detail::unique_instance_t *) + : m_name((CharType*)-1) + {} + + operator const CharType *() + { return m_name; } + + private: + const CharType *m_name; +}; + +//!The key of the the named allocation information index. Stores an offset pointer +//!to a null terminated string and the length of the string to speed up sorting +template +struct index_key +{ + typedef typename detail:: + pointer_to_other::type const_char_ptr_t; + typedef CharT char_type; + + private: + //Offset pointer to the object's name + const_char_ptr_t mp_str; + //Length of the name buffer (null NOT included) + std::size_t m_len; + public: + + //!Constructor of the key + index_key (const char_type *name, std::size_t length) + : mp_str(name), m_len(length) {} + + //!Less than function for index ordering + bool operator < (const index_key & right) const + { + return (m_len < right.m_len) || + (m_len == right.m_len && + std::char_traits::compare + (detail::get_pointer(mp_str) + ,detail::get_pointer(right.mp_str), m_len) < 0); + } + + //!Equal to function for index ordering + bool operator == (const index_key & right) const + { + return m_len == right.m_len && + std::char_traits::compare + (detail::get_pointer(mp_str), + detail::get_pointer(right.mp_str), m_len) == 0; + } + + void name(const CharT *name) + { mp_str = name; } + + void name_length(std::size_t len) + { m_len = len; } + + const CharT *name() const + { return detail::get_pointer(mp_str); } + + std::size_t name_length() const + { return m_len; } +}; + +//!The index_data stores a pointer to a buffer and the element count needed +//!to know how many destructors must be called when calling destroy +template +struct index_data +{ + typedef VoidPointer void_pointer; + void_pointer m_ptr; + index_data(void *ptr) : m_ptr(ptr){} + + void *value() const + { return (void*)detail::get_pointer(m_ptr); } +}; + +template +struct segment_manager_base_type +{ typedef segment_manager_base type; }; + +template +struct index_config +{ + typedef typename MemoryAlgorithm::void_pointer void_pointer; + typedef CharT char_type; + typedef detail::index_key key_type; + typedef detail::index_data mapped_type; + typedef typename segment_manager_base_type + ::type segment_manager_base; + + template + struct intrusive_value_type + { typedef detail::intrusive_value_type_impl type; }; + + typedef intrusive_compare_key intrusive_compare_key_type; +}; + +template +class segment_manager_iterator_value_adaptor +{ + typedef typename Iterator::value_type iterator_val_t; + typedef typename iterator_val_t::char_type char_type; + + public: + segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val) + : m_val(&val) + {} + + const char_type *name() const + { return m_val->name(); } + + std::size_t name_length() const + { return m_val->name_length(); } + + const void *value() const + { return m_val->value(); } + + const typename Iterator::value_type *m_val; +}; + + +template +class segment_manager_iterator_value_adaptor +{ + typedef typename Iterator::value_type iterator_val_t; + typedef typename iterator_val_t::first_type first_type; + typedef typename iterator_val_t::second_type second_type; + typedef typename first_type::char_type char_type; + + public: + segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val) + : m_val(&val) + {} + + const char_type *name() const + { return m_val->first.name(); } + + std::size_t name_length() const + { return m_val->first.name_length(); } + + const void *value() const + { + return reinterpret_cast + (detail::get_pointer(m_val->second.m_ptr))->value(); + } + + const typename Iterator::value_type *m_val; +}; + +template +struct segment_manager_iterator_transform + : std::unary_function< typename Iterator::value_type + , segment_manager_iterator_value_adaptor > +{ + typedef segment_manager_iterator_value_adaptor result_type; + + result_type operator()(const typename Iterator::value_type &arg) const + { return result_type(arg); } +}; + +} //namespace detail { + +}} //namespace boost { namespace interprocess + +#include + +#endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP + diff --git a/thirdparty/boost/interprocess/detail/tmp_dir_helpers.hpp b/thirdparty/boost/interprocess/detail/tmp_dir_helpers.hpp new file mode 100644 index 0000000..8663ab2 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/tmp_dir_helpers.hpp @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP +#define BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +inline void tmp_filename(const char *filename, std::string &tmp_name) +{ + const char *tmp_dir = get_temporary_path(); + if(!tmp_dir){ + error_info err = system_error_code(); + throw interprocess_exception(err); + } + tmp_name = tmp_dir; + + //Remove final null. + tmp_name += "/boost_interprocess/"; + tmp_name += filename; +} + +inline void create_tmp_dir_and_get_filename(const char *filename, std::string &tmp_name) +{ + const char *tmp_path = get_temporary_path(); + if(!tmp_path){ + error_info err = system_error_code(); + throw interprocess_exception(err); + } + + tmp_name = tmp_path; + tmp_name += "/boost_interprocess"; + + //Create the temporary directory. + //If fails, check that it's because already exists + if(!create_directory(tmp_name.c_str())){ + error_info info(system_error_code()); + if(info.get_error_code() != already_exists_error){ + throw interprocess_exception(info); + } + } + + //Add filename + tmp_name += '/'; + tmp_name += filename; +} + +inline void add_leading_slash(const char *name, std::string &new_name) +{ + if(name[0] != '/'){ + new_name = '/'; + } + new_name += name; +} + +} //namespace boost { +} //namespace interprocess { +} //namespace detail { + +#include + +#endif //ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP diff --git a/thirdparty/boost/interprocess/detail/type_traits.hpp b/thirdparty/boost/interprocess/detail/type_traits.hpp new file mode 100644 index 0000000..b107051 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/type_traits.hpp @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////////// +// (C) Copyright John Maddock 2000. +// (C) Copyright Ion Gaztanaga 2005-2008. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +// The alignment_of implementation comes from John Maddock's boost::alignment_of code +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP +#define BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include + +namespace boost { +namespace interprocess { +namespace detail { + +struct nat{}; + +//boost::alignment_of yields to 10K lines of preprocessed code, so we +//need an alternative +template struct alignment_of; + +template +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; + +template +struct alignment_logic +{ + enum{ value = A < S ? A : S }; +}; + +template< typename T > +struct alignment_of +{ + enum{ value = alignment_logic + < sizeof(alignment_of_hack) - sizeof(T) + , sizeof(T)>::value }; +}; + +//This is not standard, but should work with all compilers +union max_align +{ + char char_; + short short_; + int int_; + long long_; + #ifdef BOOST_HAS_LONG_LONG + long long long_long_; + #endif + float float_; + double double_; + long double long_double_; + void * void_ptr_; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +template +struct is_reference +{ + enum { value = false }; +}; + +template +struct is_reference +{ + enum { value = true }; +}; + +template +struct is_pointer +{ + enum { value = false }; +}; + +template +struct is_pointer +{ + enum { value = true }; +}; + +template +struct add_reference +{ + typedef T& type; +}; + +template +struct add_reference +{ + typedef T& type; +}; + +template<> +struct add_reference +{ + typedef nat& type; +}; + +template<> +struct add_reference +{ + typedef const nat& type; +}; +template +struct is_same +{ + typedef char yes_type; + struct no_type + { + char padding[8]; + }; + + template + static yes_type is_same_tester(V*, V*); + static no_type is_same_tester(...); + + static T *t; + static U *u; + + static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); +}; +/* +template typename T, template typename U> +struct is_same +{ + typedef char yes_type; + struct no_type + { + char padding[8]; + }; + + template typename V> + static yes_type is_same_tester(V*, V*); + static no_type is_same_tester(...); + + static T *t; + static U *u; + + static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); +};*/ +/* +template< typename T > +struct is_pointer_impl +{ + static const bool value = + (::boost::type_traits::ice_and< + ::boost::detail::is_pointer_helper::type>::value + , ::boost::type_traits::ice_not< + ::boost::is_member_pointer::value + >::value + >::value) + ); +};*/ + +} // namespace detail +} //namespace interprocess { +} //namespace boost { + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP + +#include + diff --git a/thirdparty/boost/interprocess/detail/utilities.hpp b/thirdparty/boost/interprocess/detail/utilities.hpp new file mode 100644 index 0000000..b7b4f91 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/utilities.hpp @@ -0,0 +1,763 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP +#define BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +template +struct smart_ptr_type +{ + typedef typename SmartPtr::value_type value_type; + typedef value_type *pointer; + static pointer get (const SmartPtr &smartptr) + { return smartptr.get();} +}; + +template +struct smart_ptr_type +{ + typedef T value_type; + typedef value_type *pointer; + static pointer get (pointer ptr) + { return ptr;} +}; + +//!Overload for smart pointers to avoid ADL problems with get_pointer +template +inline typename smart_ptr_type::pointer +get_pointer(const Ptr &ptr) +{ return smart_ptr_type::get(ptr); } + +//!To avoid ADL problems with swap +template +inline void do_swap(T& x, T& y) +{ + using std::swap; + swap(x, y); +} + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an object using a STL allocator. +template +struct scoped_ptr_dealloc_functor +{ + typedef typename Allocator::pointer pointer; + typedef detail::integral_constant::value> alloc_version; + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + + private: + void priv_deallocate(const typename Allocator::pointer &p, allocator_v1) + { m_alloc.deallocate(p, 1); } + + void priv_deallocate(const typename Allocator::pointer &p, allocator_v2) + { m_alloc.deallocate_one(p); } + + public: + Allocator& m_alloc; + + scoped_ptr_dealloc_functor(Allocator& a) + : m_alloc(a) {} + + void operator()(pointer ptr) + { if (ptr) priv_deallocate(ptr, alloc_version()); } +}; + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an object using a STL allocator. +template +struct scoped_deallocator +{ + typedef typename Allocator::pointer pointer; + typedef detail::integral_constant::value> alloc_version; + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + + private: + void priv_deallocate(allocator_v1) + { m_alloc.deallocate(m_ptr, 1); } + + void priv_deallocate(allocator_v2) + { m_alloc.deallocate_one(m_ptr); } + + public: + pointer m_ptr; + Allocator& m_alloc; + + scoped_deallocator(pointer p, Allocator& a) + : m_ptr(p), m_alloc(a) {} + + ~scoped_deallocator() + { if (m_ptr)priv_deallocate(alloc_version()); } + + void release() + { m_ptr = 0; } +}; + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an array of objects using a STL allocator. +template +struct scoped_array_deallocator +{ + typedef typename Allocator::pointer pointer; + typedef typename Allocator::size_type size_type; + + scoped_array_deallocator(pointer p, Allocator& a, size_type length) + : m_ptr(p), m_alloc(a), m_length(length) {} + + ~scoped_array_deallocator() + { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } + + void release() + { m_ptr = 0; } + + private: + pointer m_ptr; + Allocator& m_alloc; + size_type m_length; +}; + +template +struct null_scoped_array_deallocator +{ + typedef typename Allocator::pointer pointer; + typedef typename Allocator::size_type size_type; + + null_scoped_array_deallocator(pointer, Allocator&, size_type) + {} + + void release() + {} +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct scoped_destructor_n +{ + typedef typename Allocator::pointer pointer; + typedef typename Allocator::value_type value_type; + typedef typename Allocator::size_type size_type; + + pointer m_p; + size_type m_n; + + scoped_destructor_n(pointer p, size_type n) + : m_p(p), m_n(n) + {} + + void release() + { m_p = 0; } + + void increment_size(size_type inc) + { m_n += inc; } + + ~scoped_destructor_n() + { + if(!m_p) return; + value_type *raw_ptr = detail::get_pointer(m_p); + for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr) + raw_ptr->~value_type(); + } +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct null_scoped_destructor_n +{ + typedef typename Allocator::pointer pointer; + typedef typename Allocator::size_type size_type; + + null_scoped_destructor_n(pointer, size_type) + {} + + void increment_size(size_type) + {} + + void release() + {} +}; + +template +class allocator_destroyer +{ + typedef typename A::value_type value_type; + typedef detail::integral_constant::value> alloc_version; + typedef detail::integral_constant allocator_v1; + typedef detail::integral_constant allocator_v2; + + private: + A & a_; + + private: + void priv_deallocate(const typename A::pointer &p, allocator_v1) + { a_.deallocate(p, 1); } + + void priv_deallocate(const typename A::pointer &p, allocator_v2) + { a_.deallocate_one(p); } + + public: + allocator_destroyer(A &a) + : a_(a) + {} + + void operator()(const typename A::pointer &p) + { + detail::get_pointer(p)->~value_type(); + priv_deallocate(p, alloc_version()); + } +}; + +template +class allocator_destroyer_and_chain_builder +{ + typedef typename A::value_type value_type; + typedef typename A::multiallocation_iterator multiallocation_iterator; + typedef typename A::multiallocation_chain multiallocation_chain; + + A & a_; + multiallocation_chain &c_; + + public: + allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c) + : a_(a), c_(c) + {} + + void operator()(const typename A::pointer &p) + { + value_type *vp = detail::get_pointer(p); + vp->~value_type(); + c_.push_back(vp); + } +}; + +template +class allocator_multialloc_chain_node_deallocator +{ + typedef typename A::value_type value_type; + typedef typename A::multiallocation_iterator multiallocation_iterator; + typedef typename A::multiallocation_chain multiallocation_chain; + typedef allocator_destroyer_and_chain_builder chain_builder; + + A & a_; + multiallocation_chain c_; + + public: + allocator_multialloc_chain_node_deallocator(A &a) + : a_(a), c_() + {} + + chain_builder get_chain_builder() + { return chain_builder(a_, c_); } + + ~allocator_multialloc_chain_node_deallocator() + { + multiallocation_iterator it(c_.get_it()); + if(it != multiallocation_iterator()) + a_.deallocate_individual(it); + } +}; + +template +class allocator_multialloc_chain_array_deallocator +{ + typedef typename A::value_type value_type; + typedef typename A::multiallocation_iterator multiallocation_iterator; + typedef typename A::multiallocation_chain multiallocation_chain; + typedef allocator_destroyer_and_chain_builder chain_builder; + + A & a_; + multiallocation_chain c_; + + public: + allocator_multialloc_chain_array_deallocator(A &a) + : a_(a), c_() + {} + + chain_builder get_chain_builder() + { return chain_builder(a_, c_); } + + ~allocator_multialloc_chain_array_deallocator() + { + multiallocation_iterator it(c_.get_it()); + if(it != multiallocation_iterator()) + a_.deallocate_many(it); + } +}; + +//!A class used for exception-safe multi-allocation + construction. +template +struct multiallocation_destroy_dealloc +{ + typedef typename Allocator::multiallocation_iterator multiallocation_iterator; + typedef typename Allocator::value_type value_type; + + multiallocation_iterator m_itbeg; + Allocator& m_alloc; + + multiallocation_destroy_dealloc(multiallocation_iterator itbeg, Allocator& a) + : m_itbeg(itbeg), m_alloc(a) {} + + ~multiallocation_destroy_dealloc() + { + multiallocation_iterator endit; + while(m_itbeg != endit){ + detail::get_pointer(&*m_itbeg)->~value_type(); + m_alloc.deallocate(&*m_itbeg, 1); + ++m_itbeg; + } + } + + void next() + { ++m_itbeg; } + + void release() + { m_itbeg = multiallocation_iterator(); } +}; + +//!Forces a cast from any pointer to char *pointer +template +inline char* char_ptr_cast(T *ptr) +{ + //This is nasty, but we like it a lot! + return (char*)(ptr); +} + +inline char* char_ptr_cast() +{ + //This is nasty, but we like it a lot! + return (char*)(0); +} + +//Rounds "orig_size" by excess to round_to bytes +inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to) +{ + return ((orig_size-1)/round_to+1)*round_to; +} + +inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multiple) +{ + return orig_size/multiple*multiple; +} + +template +struct ct_rounded_size +{ + enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo }; +}; + +template +struct ct_min +{ + enum { value = (Value1 < Value2)? Value1 : Value2 }; +}; + +template +struct ct_max +{ + enum { value = (Value1 > Value2)? Value1 : Value2 }; +}; + +// Gennaro Prota wrote this. Thanks! +template +struct ct_max_pow2_less +{ + enum { c = 2*n < p }; + + static const std::size_t value = + c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n; +}; + +template <> +struct ct_max_pow2_less<0, 0> +{ + static const std::size_t value = 0; +}; + +//!Obtains a generic pointer of the same type that +//!can point to other pointed type: Ptr -> Ptr +template +struct pointer_to_other; + +template class Sp> +struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template class Sp> +struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template class Sp> +struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template +struct pointer_to_other< T*, U > +{ + typedef U* type; +}; + +} //namespace detail { + +//!Trait class to detect if an index is a node +//!index. This allows more efficient operations +//!when deallocating named objects. +template +struct is_node_index +{ + enum { value = false }; +}; + + +//!Trait class to detect if an index is an intrusive +//!index. This will embed the derivation hook in each +//!allocation header, to provide memory for the intrusive +//!container. +template +struct is_intrusive_index +{ + enum { value = false }; +}; + +template +SizeType + get_next_capacity(const SizeType max_size + ,const SizeType capacity + ,const SizeType n) +{ +// if (n > max_size - capacity) +// throw std::length_error("get_next_capacity"); + + const SizeType m3 = max_size/3; + + if (capacity < m3) + return capacity + max_value(3*(capacity+1)/5, n); + + if (capacity < m3*2) + return capacity + max_value((capacity+1)/2, n); + + return max_size; +} + +namespace detail { + +template +struct pair +{ + typedef T1 first_type; + typedef T2 second_type; + + T1 first; + T2 second; + + pair() + : first(), second() + {} + + pair(const T1& x, const T2& y) + : first(x), second(y) + {} + + template + pair(const std::pair& p) + : first(p.first), second(p.second) + {} + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + pair(const detail::moved_object >& p) + : first(move(p.get().first)), second(move(p.get().second)) + {} + #else + template + pair(std::pair && p) + : first(move(p.first)), second(move(p.second)) + {} + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + pair(const detail::moved_object >& p) + : first(move(p.get().first)), second(move(p.get().second)) + {} + #else + template + pair(pair && p) + : first(move(p.first)), second(move(p.second)) + {} + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + pair(const detail::moved_object &x, const detail::moved_object &y) + : first(move(x.get())), second(move(y.get())) + {} + #else + template + pair(U &&x, V &&y) + : first(move(x)), second(move(y)) + {} + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + pair(const detail::moved_object &p) + : first(move(p.get().first)), second(move(p.get().second)) + {} + #else + pair(pair &&p) + : first(move(p.first)), second(move(p.second)) + {} + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + pair& operator=(const detail::moved_object &p) + { + first = move(p.get().first); + second = move(p.get().second); + return *this; + } + #else + pair& operator=(pair &&p) + { + first = move(p.first); + second = move(p.second); + return *this; + } + #endif + + pair& operator=(const pair &p) + { + first = p.first; + second = p.second; + return *this; + } + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + pair& operator=(const detail::moved_object > &p) + { + first = move(p.get().first); + second = move(p.get().second); + return *this; + } + #else + template + pair& operator=(std::pair &&p) + { + first = move(p.first); + second = move(p.second); + return *this; + } + #endif + + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(const detail::moved_object &p) + { std::swap(*this, p.get()); } + + void swap(pair& p) + { std::swap(*this, p); } + + #else + void swap(pair &&p) + { std::swap(*this, p); } + #endif +}; + +template +inline bool operator==(const pair& x, const pair& y) +{ return static_cast(x.first == y.first && x.second == y.second); } + +template +inline bool operator< (const pair& x, const pair& y) +{ return static_cast(x.first < y.first || + (!(y.first < x.first) && x.second < y.second)); } + +template +inline bool operator!=(const pair& x, const pair& y) +{ return static_cast(!(x == y)); } + +template +inline bool operator> (const pair& x, const pair& y) +{ return y < x; } + +template +inline bool operator>=(const pair& x, const pair& y) +{ return static_cast(!(x < y)); } + +template +inline bool operator<=(const pair& x, const pair& y) +{ return static_cast(!(y < x)); } + +template +inline pair make_pair(T1 x, T2 y) +{ return pair(x, y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +template +inline void swap(const detail::moved_object > &x, pair& y) +{ + swap(x.get().first, y.first); + swap(x.get().second, y.second); +} + +template +inline void swap(pair& x, const detail::moved_object > &y) +{ + swap(x.first, y.get().first); + swap(x.second, y.get().second); +} + +template +inline void swap(pair& x, pair& y) +{ + swap(x.first, y.first); + swap(x.second, y.second); +} + +#else +template +inline void swap(pair&&x, pair&&y) +{ + swap(x.first, y.first); + swap(x.second, y.second); +} +#endif + +template +struct cast_functor +{ + typedef typename detail::add_reference::type result_type; + result_type operator()(char &ptr) const + { return *static_cast(static_cast(&ptr)); } +}; + +template +class multiallocation_chain_adaptor +{ + private: + MultiallocChain chain_; + + multiallocation_chain_adaptor + (const multiallocation_chain_adaptor &); + multiallocation_chain_adaptor &operator= + (const multiallocation_chain_adaptor &); + + public: + typedef transform_iterator + < typename MultiallocChain:: + multiallocation_iterator + , detail::cast_functor > multiallocation_iterator; + + multiallocation_chain_adaptor() + : chain_() + {} + + void push_back(T *mem) + { chain_.push_back(mem); } + + void push_front(T *mem) + { chain_.push_front(mem); } + + void swap(multiallocation_chain_adaptor &other_chain) + { chain_.swap(other_chain.chain_); } + + void splice_back(multiallocation_chain_adaptor &other_chain) + { chain_.splice_back(other_chain.chain_); } + + T *pop_front() + { return static_cast(chain_.pop_front()); } + + bool empty() const + { return chain_.empty(); } + + multiallocation_iterator get_it() const + { return multiallocation_iterator(chain_.get_it()); } + + std::size_t size() const + { return chain_.size(); } +}; + +} //namespace detail { + +//!The pair is movable if any of its members is movable +template +struct is_movable > +{ + enum { value = is_movable::value || is_movable::value }; +}; + +//!The pair is movable if any of its members is movable +template +struct is_movable > +{ + enum { value = is_movable::value || is_movable::value }; +}; + +///has_trivial_destructor_after_move<> == true_type +///specialization for optimizations +template +struct has_trivial_destructor_after_move + : public boost::has_trivial_destructor +{}; + +template T* +addressof(T& v) +{ + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP + diff --git a/thirdparty/boost/interprocess/detail/version_type.hpp b/thirdparty/boost/interprocess/detail/version_type.hpp new file mode 100644 index 0000000..bab6731 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/version_type.hpp @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This code comes from N1953 document by Howard E. Hinnant +// +////////////////////////////////////////////////////////////////////////////// + + +#ifndef BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP +#define BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP + +#include +#include + + +namespace boost{ +namespace interprocess{ +namespace detail{ + +//using namespace boost; + +template +struct version_type + : public detail::integral_constant +{ + typedef T type; + + version_type(const version_type&); +}; + +namespace impl{ + +template , typename T::version>::value> +struct extract_version +{ + static const unsigned value = 1; +}; + +template +struct extract_version +{ + static const unsigned value = T::version::value; +}; + +template +struct has_version +{ + private: + struct two {char _[2];}; + template static two test(...); + template static char test(const typename U::version*); + public: + static const bool value = sizeof(test(0)) == 1; + void dummy(){} +}; + +template ::value> +struct version +{ + static const unsigned value = 1; +}; + +template +struct version +{ + static const unsigned value = extract_version::value; +}; + +} //namespace impl + +template +struct version + : public detail::integral_constant::value> +{ +}; + +} //namespace detail{ +} //namespace interprocess{ +} //namespace boost{ + +#endif //#define BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP diff --git a/thirdparty/boost/interprocess/detail/win32_api.hpp b/thirdparty/boost/interprocess/detail/win32_api.hpp new file mode 100644 index 0000000..acf1fd9 --- /dev/null +++ b/thirdparty/boost/interprocess/detail/win32_api.hpp @@ -0,0 +1,414 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP +#define BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP + +#include +#include +#include + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +# pragma comment( lib, "advapi32.lib" ) +#endif + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +# include +# include +#else +# error "This file can only be included in Windows OS" +#endif + +//The structures used in Interprocess with the +//same binary interface as windows ones +namespace boost { +namespace interprocess { +namespace winapi { + +//Some used constants +static const unsigned long infinite_time = 0xFFFFFFFF; +static const unsigned long error_already_exists = 183L; +static const unsigned long error_file_not_found = 2u; + +static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3; +static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001; + +static const unsigned long page_readonly = 0x02; +static const unsigned long page_readwrite = 0x04; +static const unsigned long page_writecopy = 0x08; + +static const unsigned long standard_rights_required = 0x000F0000L; +static const unsigned long section_query = 0x0001; +static const unsigned long section_map_write = 0x0002; +static const unsigned long section_map_read = 0x0004; +static const unsigned long section_map_execute = 0x0008; +static const unsigned long section_extend_size = 0x0010; +static const unsigned long section_all_access = standard_rights_required | + section_query | + section_map_write | + section_map_read | + section_map_execute | + section_extend_size; + +static const unsigned long file_map_copy = section_query; +static const unsigned long file_map_write = section_map_write; +static const unsigned long file_map_read = section_map_read; +static const unsigned long file_map_all_access = section_all_access; + +static const unsigned long file_share_read = 0x00000001; +static const unsigned long file_share_write = 0x00000002; + +static const unsigned long generic_read = 0x80000000L; +static const unsigned long generic_write = 0x40000000L; + +static const unsigned long wait_object_0 = 0; +static const unsigned long wait_abandoned = 0x00000080L; +static const unsigned long wait_timeout = 258L; +static const unsigned long wait_failed = (unsigned long)0xFFFFFFFF; + +static const unsigned long duplicate_close_source = (unsigned long)0x00000001; +static const unsigned long duplicate_same_access = (unsigned long)0x00000002; + +static const unsigned long format_message_allocate_buffer + = (unsigned long)0x00000100; +static const unsigned long format_message_ignore_inserts + = (unsigned long)0x00000200; +static const unsigned long format_message_from_string + = (unsigned long)0x00000400; +static const unsigned long format_message_from_hmodule + = (unsigned long)0x00000800; +static const unsigned long format_message_from_system + = (unsigned long)0x00001000; +static const unsigned long format_message_argument_array + = (unsigned long)0x00002000; +static const unsigned long format_message_max_width_mask + = (unsigned long)0x000000FF; +static const unsigned long lang_neutral = (unsigned long)0x00; +static const unsigned long sublang_default = (unsigned long)0x01; +static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF; +static void * const invalid_handle_value = (void*)(long*)-1; +static const unsigned long create_new = 1; +static const unsigned long create_always = 2; +static const unsigned long open_existing = 3; +static const unsigned long open_always = 4; +static const unsigned long truncate_existing = 5; + +static const unsigned long file_attribute_temporary = 0x00000100; + +static const unsigned long file_begin = 0; +static const unsigned long file_current = 1; +static const unsigned long file_end = 2; + +static const unsigned long lockfile_fail_immediately = 1; +static const unsigned long lockfile_exclusive_lock = 2; +static const unsigned long error_lock_violation = 33; +static const unsigned long security_descriptor_revision = 1; + +} //namespace winapi { +} //namespace interprocess { +} //namespace boost { + +#if !defined( BOOST_USE_WINDOWS_H ) + +namespace boost { +namespace interprocess { +namespace winapi { + +struct interprocess_overlapped +{ + unsigned long *internal; + unsigned long *internal_high; + union { + struct { + unsigned long offset; + unsigned long offset_high; + }dummy; + void *pointer; + }; + + void *h_event; +}; + +struct interprocess_filetime +{ + unsigned long dwLowDateTime; + unsigned long dwHighDateTime; +}; + +struct interprocess_security_attributes +{ + unsigned long nLength; + void *lpSecurityDescriptor; + int bInheritHandle; +}; + +struct system_info { + union { + unsigned long dwOemId; // Obsolete field...do not use + struct { + unsigned short wProcessorArchitecture; + unsigned short wReserved; + } dummy; + }; + unsigned long dwPageSize; + void * lpMinimumApplicationAddress; + void * lpMaximumApplicationAddress; + unsigned long * dwActiveProcessorMask; + unsigned long dwNumberOfProcessors; + unsigned long dwProcessorType; + unsigned long dwAllocationGranularity; + unsigned short wProcessorLevel; + unsigned short wProcessorRevision; +}; + +struct interprocess_memory_basic_information +{ + void * BaseAddress; + void * AllocationBase; + unsigned long AllocationProtect; + unsigned long RegionSize; + unsigned long State; + unsigned long Protect; + unsigned long Type; +}; + +typedef struct _interprocess_acl +{ + unsigned char AclRevision; + unsigned char Sbz1; + unsigned short AclSize; + unsigned short AceCount; + unsigned short Sbz2; +} interprocess_acl; + +typedef struct _interprocess_security_descriptor +{ + unsigned char Revision; + unsigned char Sbz1; + unsigned short Control; + void *Owner; + void *Group; + interprocess_acl *Sacl; + interprocess_acl *Dacl; +} interprocess_security_descriptor; + +//Some windows API declarations +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); +extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long); +extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError(); +extern "C" __declspec(dllimport) void * __stdcall GetCurrentProcess(); +extern "C" __declspec(dllimport) int __stdcall CloseHandle(void*); +extern "C" __declspec(dllimport) int __stdcall DuplicateHandle + ( void *hSourceProcessHandle, void *hSourceHandle + , void *hTargetProcessHandle, void **lpTargetHandle + , unsigned long dwDesiredAccess, int bInheritHandle + , unsigned long dwOptions); +extern "C" __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(interprocess_filetime*); +extern "C" __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const interprocess_filetime *in, const interprocess_filetime *out); +extern "C" __declspec(dllimport) void * __stdcall CreateMutexA(interprocess_security_attributes*, int, const char *); +extern "C" __declspec(dllimport) void * __stdcall OpenMutexA(unsigned long, int, const char *); +extern "C" __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void *, unsigned long); +extern "C" __declspec(dllimport) int __stdcall ReleaseMutex(void *); +extern "C" __declspec(dllimport) int __stdcall UnmapViewOfFile(void *); +extern "C" __declspec(dllimport) void * __stdcall CreateSemaphoreA(interprocess_security_attributes*, long, long, const char *); +extern "C" __declspec(dllimport) int __stdcall ReleaseSemaphore(void *, long, long *); +extern "C" __declspec(dllimport) void * __stdcall OpenSemaphoreA(unsigned long, int, const char *); +extern "C" __declspec(dllimport) void * __stdcall CreateFileMappingA (void *, interprocess_security_attributes*, unsigned long, unsigned long, unsigned long, const char *); +extern "C" __declspec(dllimport) void * __stdcall MapViewOfFileEx (void *, unsigned long, unsigned long, unsigned long, std::size_t, void*); +extern "C" __declspec(dllimport) void * __stdcall OpenFileMappingA (unsigned long, int, const char *); +extern "C" __declspec(dllimport) void * __stdcall CreateFileA (const char *, unsigned long, unsigned long, struct _SECURITY_ATTRIBUTES*, unsigned long, unsigned long, void *); +extern "C" __declspec(dllimport) int __stdcall DeleteFileA (const char *); +extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *); +extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::size_t); +extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size); +extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA + (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId, + unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize, + std::va_list *Arguments); +extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *); +extern "C" __declspec(dllimport) int __stdcall CreateDirectoryA(const char *, interprocess_security_attributes*); +extern "C" __declspec(dllimport) int __stdcall GetTempPathA(unsigned long length, char *buffer); +extern "C" __declspec(dllimport) int __stdcall CreateDirectory(const char *, interprocess_security_attributes*); +extern "C" __declspec(dllimport) int __stdcall SetFileValidData(void *, __int64 size); +extern "C" __declspec(dllimport) int __stdcall SetEndOfFile(void *); +extern "C" __declspec(dllimport) int __stdcall SetFilePointerEx(void *, __int64 distance, __int64 *new_file_pointer, unsigned long move_method); +extern "C" __declspec(dllimport) int __stdcall LockFile (void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high); +extern "C" __declspec(dllimport) int __stdcall UnlockFile(void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high); +extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped); +extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped); +extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped); +extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision); +extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted); + +} //namespace winapi { +} //namespace interprocess { +} //namespace boost { + +#else +# include +#endif //#if !defined( BOOST_USE_WINDOWS_H ) + +namespace boost { +namespace interprocess { +namespace winapi { + +static inline unsigned long format_message + (unsigned long dwFlags, const void *lpSource, + unsigned long dwMessageId, unsigned long dwLanguageId, + char *lpBuffer, unsigned long nSize, std::va_list *Arguments) +{ + return FormatMessageA + (dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments); +} + +//And now, wrapper functions +static inline void * local_free(void *hmem) +{ return LocalFree(hmem); } + +static inline unsigned long make_lang_id(unsigned long p, unsigned long s) +{ return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); } + +static inline void sched_yield() +{ Sleep(1); } + +static inline unsigned long get_current_thread_id() +{ return GetCurrentThreadId(); } + +static inline unsigned long get_current_process_id() +{ return GetCurrentProcessId(); } + +static inline unsigned int close_handle(void* handle) +{ return CloseHandle(handle); } + +static inline bool duplicate_current_process_handle + (void *hSourceHandle, void **lpTargetHandle) +{ + return 0 != DuplicateHandle + ( GetCurrentProcess(), hSourceHandle, GetCurrentProcess() + , lpTargetHandle, 0, 0 + , duplicate_same_access); +} + +static inline unsigned long get_last_error() +{ return GetLastError(); } + +static inline void get_system_time_as_file_time(interprocess_filetime *filetime) +{ GetSystemTimeAsFileTime(filetime); } + +static inline bool file_time_to_local_file_time + (const interprocess_filetime *in, const interprocess_filetime *out) +{ return 0 != FileTimeToLocalFileTime(in, out); } + +static inline void *create_mutex(const char *name) +{ return CreateMutexA(0, 0, name); } + +static inline void *open_mutex(const char *name) +{ return OpenMutexA(mutex_all_access, 0, name); } + +static inline unsigned long wait_for_single_object(void *handle, unsigned long time) +{ return WaitForSingleObject(handle, time); } + +static inline int release_mutex(void *handle) +{ return ReleaseMutex(handle); } + +static inline int unmap_view_of_file(void *address) +{ return UnmapViewOfFile(address); } + +static inline void *create_semaphore(long initialCount, const char *name) +{ return CreateSemaphoreA(0, initialCount, (long)(((unsigned long)(-1))>>1), name); } + +static inline int release_semaphore(void *handle, long release_count, long *prev_count) +{ return ReleaseSemaphore(handle, release_count, prev_count); } + +static inline void *open_semaphore(const char *name) +{ return OpenSemaphoreA(semaphore_all_access, 1, name); } + +static inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name) +{ + interprocess_security_attributes sa; + interprocess_security_descriptor sd; + + if(!InitializeSecurityDescriptor(&sd, security_descriptor_revision)) + return 0; + if(!SetSecurityDescriptorDacl(&sd, true, 0, false)) + return 0; + sa.lpSecurityDescriptor = &sd; + sa.nLength = sizeof(interprocess_security_attributes); + sa.bInheritHandle = false; + return CreateFileMappingA (handle, &sa, access, high_size, low_size, name); + //return CreateFileMappingA (handle, 0, access, high_size, low_size, name); +} + +static inline void * open_file_mapping (unsigned long access, const char *name) +{ return OpenFileMappingA (access, 0, name); } + +static inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned long highoffset, unsigned long lowoffset, std::size_t numbytes, void *base_addr) +{ return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); } + +static inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0) +{ return CreateFileA(name, access, file_share_read | file_share_write, 0, creation_flags, attributes, 0); } + +static inline bool delete_file(const char *name) +{ return 0 != DeleteFileA(name); } + +static inline void get_system_info(system_info *info) +{ GetSystemInfo(info); } + +static inline int flush_view_of_file(void *base_addr, std::size_t numbytes) +{ return FlushViewOfFile(base_addr, numbytes); } + +static inline bool get_file_size(void *handle, __int64 &size) +{ return 0 != GetFileSizeEx(handle, &size); } + +static inline bool create_directory(const char *name, interprocess_security_attributes* security) +{ return 0 != CreateDirectoryA(name, security); } + +static inline unsigned long get_temp_path(unsigned long length, char *buffer) +{ return GetTempPathA(length, buffer); } + +static inline int set_end_of_file(void *handle) +{ return 0 != SetEndOfFile(handle); } + +static inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method) +{ return 0 != SetFilePointerEx(handle, distance, new_file_pointer, move_method); } + +static inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped) +{ return 0 != LockFileEx(hnd, flags, reserved, size_low, size_high, overlapped); } + +static inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped) +{ return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); } + +static inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped) +{ return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); } + +static inline long interlocked_increment(long volatile *addr) +{ return BOOST_INTERLOCKED_INCREMENT(addr); } + +static inline long interlocked_decrement(long volatile *addr) +{ return BOOST_INTERLOCKED_DECREMENT(addr); } + +static inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2) +{ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); } + +static inline long interlocked_exchange_add(long volatile* addend, long value) +{ return BOOST_INTERLOCKED_EXCHANGE_ADD((long*)addend, value); } + +static inline long interlocked_exchange(long volatile* addend, long value) +{ return BOOST_INTERLOCKED_EXCHANGE((long*)addend, value); } + +} //namespace winapi +} //namespace interprocess +} //namespace boost + +#include + +#endif //#ifdef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP diff --git a/thirdparty/boost/interprocess/detail/workaround.hpp b/thirdparty/boost/interprocess/detail/workaround.hpp new file mode 100644 index 0000000..57c061e --- /dev/null +++ b/thirdparty/boost/interprocess/detail/workaround.hpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_PTR_WRKRND_HPP +#define BOOST_INTERPROCESS_PTR_WRKRND_HPP + +#include + +#if !(defined BOOST_WINDOWS) || (defined BOOST_DISABLE_WIN32) + + #include + + #if defined(_POSIX_THREAD_PROCESS_SHARED) + # if !((_XOPEN_VERSION >= 600) && (_POSIX_THREAD_PROCESS_SHARED - 0 <= 0)) + //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it. + //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work. + # if !defined(__CYGWIN__) && !defined(__APPLE__) + # define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED + # endif + # endif + #endif + + #if defined(_POSIX_BARRIERS) + # if !((_XOPEN_VERSION >= 600) && (_POSIX_BARRIERS - 0 <= 0)) + # define BOOST_INTERPROCESS_POSIX_BARRIERS + # endif + #endif + + #if defined(_POSIX_SEMAPHORES) + # if !((_XOPEN_VERSION >= 600) && (_POSIX_SEMAPHORES - 0 <= 0)) + # define BOOST_INTERPROCESS_POSIX_SEMAPHORES + # if defined(__CYGWIN__) + #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK + # endif + # endif + #endif + + #if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\ + ((defined _V6_LP64_OFF64) &&(_V6_LP64_OFF64 - 0 > 0)) ||\ + ((defined _V6_LPBIG_OFFBIG) &&(_V6_LPBIG_OFFBIG - 0 > 0)) ||\ + ((defined _XBS5_ILP32_OFFBIG)&&(_XBS5_ILP32_OFFBIG - 0 > 0)) ||\ + ((defined _XBS5_LP64_OFF64) &&(_XBS5_LP64_OFF64 - 0 > 0)) ||\ + ((defined _XBS5_LPBIG_OFFBIG)&&(_XBS5_LPBIG_OFFBIG - 0 > 0)) ||\ + ((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64))||\ + ((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64)) + #define BOOST_INTERPROCESS_UNIX_64_BIT_OR_BIGGER_OFF_T + #else + #endif + + #if defined(_POSIX_SHARED_MEMORY_OBJECTS) + # if !((_XOPEN_VERSION >= 600) && (_POSIX_SHARED_MEMORY_OBJECTS - 0 <= 0)) + # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS + # endif + #else + # if defined(__vms) + # if __CRTL_VER >= 70200000 + # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS + # endif + # endif + #endif + + #if defined(_POSIX_TIMEOUTS) + # if !((_XOPEN_VERSION >= 600) && (_POSIX_TIMEOUTS - 0 <= 0)) + # define BOOST_INTERPROCESS_POSIX_TIMEOUTS + # endif + #endif + + #ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS + //Some systems have filesystem-based shared memory, so the + //portable "/shmname" format does not work due to permission issues + //For those systems we need to form a path to a temporary directory: + // hp-ux tru64 vms + #if defined(__hpux) || defined(__osf__) || defined(__vms) + #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY + #endif + #endif + + #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES + //Some systems have filesystem-based shared memory, so the + //portable "/semname" format does not work due to permission issues + //For those systems we need to form a path to a temporary directory: + // hp-ux tru64 vms + #if defined(__hpux) || defined(__osf__) || defined(__vms) + #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES + #endif + #endif + + #if ((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500) + #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES + #endif + +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. Note: __GXX_EXPERIMENTAL_CPP0X__ is +// defined by some very early development versions of GCC 4.3; we will +// remove this part of the check in the near future. +# if defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTERPROCESS_RVALUE_REFERENCE +# define BOOST_INTERPROCESS_VARIADIC_TEMPLATES +# endif +#endif + +#if defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && defined(BOOST_INTERPROCESS_VARIADIC_TEMPLATES) +#define BOOST_INTERPROCESS_PERFECT_FORWARDING +#endif + +//Now declare some Boost.Interprocess features depending on the implementation + +#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK) + +#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES + +#endif + +#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK) + +#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES +#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES + +#endif + +#include + +#endif //#ifndef BOOST_INTERPROCESS_PTR_WRKRND_HPP diff --git a/thirdparty/boost/interprocess/errors.hpp b/thirdparty/boost/interprocess/errors.hpp new file mode 100644 index 0000000..39e8f42 --- /dev/null +++ b/thirdparty/boost/interprocess/errors.hpp @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +// Parts of this code are taken from boost::filesystem library +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright © 2002 Beman Dawes +// Copyright © 2001 Dietmar Kühl +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/filesystem +// +////////////////////////////////////////////////////////////////////////////// + + +#ifndef BOOST_INTERPROCESS_ERRORS_HPP +#define BOOST_INTERPROCESS_ERRORS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +# include +#else +# ifdef BOOST_HAS_UNISTD_H +# include //Errors +# include //strerror +# else //ifdef BOOST_HAS_UNISTD_H +# error Unknown platform +# endif //ifdef BOOST_HAS_UNISTD_H +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +//!\file +//!Describes the error numbering of interprocess classes + +namespace boost { +namespace interprocess { +/// @cond +static inline int system_error_code() // artifact of POSIX and WINDOWS error reporting +{ + #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + return winapi::get_last_error(); + #else + return errno; // GCC 3.1 won't accept ::errno + #endif +} + + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +inline void fill_system_message(int sys_err_code, std::string &str) +{ + void *lpMsgBuf; + winapi::format_message( + winapi::format_message_allocate_buffer | + winapi::format_message_from_system | + winapi::format_message_ignore_inserts, + 0, + sys_err_code, + winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language + (char *) &lpMsgBuf, + 0, + 0 + ); + str += static_cast(lpMsgBuf); + winapi::local_free( lpMsgBuf ); // free the buffer + while ( str.size() + && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) + str.erase( str.size()-1 ); +} +# else +static inline void fill_system_message( int system_error, std::string &str) +{ str = std::strerror(system_error); } +# endif +/// @endcond + +enum error_code_t +{ + no_error = 0, + system_error, // system generated error; if possible, is translated + // to one of the more specific errors below. + other_error, // library generated error + security_error, // includes access rights, permissions failures + read_only_error, + io_error, + path_error, + not_found_error, +// not_directory_error, + busy_error, // implies trying again might succeed + already_exists_error, + not_empty_error, + is_directory_error, + out_of_space_error, + out_of_memory_error, + out_of_resource_error, + lock_error, + sem_error, + mode_error, + size_error, + corrupted_error +}; + +typedef int native_error_t; + +/// @cond +struct ec_xlate +{ + native_error_t sys_ec; + error_code_t ec; +}; + +static const ec_xlate ec_table[] = +{ + #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + { /*ERROR_ACCESS_DENIED*/5L, security_error }, + { /*ERROR_INVALID_ACCESS*/12L, security_error }, + { /*ERROR_SHARING_VIOLATION*/32L, security_error }, + { /*ERROR_LOCK_VIOLATION*/33L, security_error }, + { /*ERROR_LOCKED*/212L, security_error }, + { /*ERROR_NOACCESS*/998L, security_error }, + { /*ERROR_WRITE_PROTECT*/19L, read_only_error }, + { /*ERROR_NOT_READY*/21L, io_error }, + { /*ERROR_SEEK*/25L, io_error }, + { /*ERROR_READ_FAULT*/30L, io_error }, + { /*ERROR_WRITE_FAULT*/29L, io_error }, + { /*ERROR_CANTOPEN*/1011L, io_error }, + { /*ERROR_CANTREAD*/1012L, io_error }, + { /*ERROR_CANTWRITE*/1013L, io_error }, + { /*ERROR_DIRECTORY*/267L, path_error }, + { /*ERROR_INVALID_NAME*/123L, path_error }, + { /*ERROR_FILE_NOT_FOUND*/2L, not_found_error }, + { /*ERROR_PATH_NOT_FOUND*/3L, not_found_error }, + { /*ERROR_DEV_NOT_EXIST*/55L, not_found_error }, + { /*ERROR_DEVICE_IN_USE*/2404L, busy_error }, + { /*ERROR_OPEN_FILES*/2401L, busy_error }, + { /*ERROR_BUSY_DRIVE*/142L, busy_error }, + { /*ERROR_BUSY*/170L, busy_error }, + { /*ERROR_FILE_EXISTS*/80L, already_exists_error }, + { /*ERROR_ALREADY_EXISTS*/183L, already_exists_error }, + { /*ERROR_DIR_NOT_EMPTY*/145L, not_empty_error }, + { /*ERROR_HANDLE_DISK_FULL*/39L, out_of_space_error }, + { /*ERROR_DISK_FULL*/112L, out_of_space_error }, + { /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error }, + { /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error }, + { /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error } + #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + { EACCES, security_error }, + { EROFS, read_only_error }, + { EIO, io_error }, + { ENAMETOOLONG, path_error }, + { ENOENT, not_found_error }, + // { ENOTDIR, not_directory_error }, + { EAGAIN, busy_error }, + { EBUSY, busy_error }, + { ETXTBSY, busy_error }, + { EEXIST, already_exists_error }, + { ENOTEMPTY, not_empty_error }, + { EISDIR, is_directory_error }, + { ENOSPC, out_of_space_error }, + { ENOMEM, out_of_memory_error }, + { EMFILE, out_of_resource_error } + #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +}; + +static inline error_code_t lookup_error(native_error_t err) +{ + const ec_xlate *cur = &ec_table[0], + *end = cur + sizeof(ec_table)/sizeof(ec_xlate); + for (;cur != end; ++cur ){ + if ( err == cur->sys_ec ) return cur->ec; + } + return system_error; // general system error code +} + +struct error_info +{ + error_info(error_code_t ec = other_error ) + : m_nat(0), m_ec(ec) + {} + + error_info(native_error_t sys_err_code) + : m_nat(sys_err_code), m_ec(lookup_error(sys_err_code)) + {} + + error_info & operator =(error_code_t ec) + { + m_nat = 0; + m_ec = ec; + return *this; + } + + error_info & operator =(native_error_t sys_err_code) + { + m_nat = sys_err_code; + m_ec = lookup_error(sys_err_code); + return *this; + } + + native_error_t get_native_error()const + { return m_nat; } + + error_code_t get_error_code()const + { return m_ec; } + + private: + native_error_t m_nat; + error_code_t m_ec; +}; +/// @endcond + +} // namespace interprocess { +} // namespace boost + +#include + +#endif // BOOST_INTERPROCESS_ERRORS_HPP diff --git a/thirdparty/boost/interprocess/exceptions.hpp b/thirdparty/boost/interprocess/exceptions.hpp new file mode 100644 index 0000000..2889321 --- /dev/null +++ b/thirdparty/boost/interprocess/exceptions.hpp @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_EXCEPTIONS_HPP +#define BOOST_INTERPROCESS_EXCEPTIONS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include + +//!\file +//!Describes exceptions thrown by interprocess classes + +namespace boost { + +namespace interprocess { + +//!This class is the base class of all exceptions +//!thrown by boost::interprocess +class interprocess_exception : public std::exception +{ + public: + interprocess_exception(error_code_t ec = other_error ) + : m_err(ec) + { + try { m_str = "boost::interprocess_exception::library_error"; } + catch (...) {} + } + + interprocess_exception(native_error_t sys_err_code) + : m_err(sys_err_code) + { + try { fill_system_message(m_err.get_native_error(), m_str); } + catch (...) {} + } + + interprocess_exception(const error_info &err_info) + : m_err(err_info) + { + try{ + if(m_err.get_native_error() != 0){ + fill_system_message(m_err.get_native_error(), m_str); + }/* + else{ + m_str = "boost::interprocess_exception::library_error"; + }*/ + } + catch(...){} + } + + virtual ~interprocess_exception() throw(){} + + virtual const char * what() const throw() + { return m_str.c_str(); } + + native_error_t get_native_error()const { return m_err.get_native_error(); } + + // Note: a value of other_error implies a library (rather than system) error + error_code_t get_error_code() const { return m_err.get_error_code(); } + + /// @cond + private: + error_info m_err; + std::string m_str; + /// @endcond +}; + +//!This is the exception thrown by shared interprocess_mutex family when a deadlock situation +//!is detected or when using a interprocess_condition the interprocess_mutex is not locked +class lock_exception : public interprocess_exception +{ + public: + lock_exception() + : interprocess_exception(lock_error) + {} + + virtual const char* what() const throw() + { return "boost::interprocess::lock_exception"; } +}; + +//!This is the exception thrown by named interprocess_semaphore when a deadlock situation +//!is detected or when an error is detected in the post/wait operation +/* +class sem_exception : public interprocess_exception +{ + public: + sem_exception() + : interprocess_exception(lock_error) + {} + + virtual const char* what() const throw() + { return "boost::interprocess::sem_exception"; } +}; +*/ +//!This is the exception thrown by synchronization objects when there is +//!an error in a wait() function +/* +class wait_exception : public interprocess_exception +{ + public: + virtual const char* what() const throw() + { return "boost::interprocess::wait_exception"; } +}; +*/ + +//!This exception is thrown when a named object is created +//!in "open_only" mode and the resource was not already created +/* +class not_previously_created : public interprocess_exception +{ + public: + virtual const char* what() const throw() + { return "boost::interprocess::not_previously_created"; } +}; +*/ + +//!This exception is thrown when a memory request can't be +//!fulfilled. +class bad_alloc : public interprocess_exception +{ + public: + virtual const char* what() const throw() + { return "boost::interprocess::bad_alloc"; } +}; + +} // namespace interprocess { + +} // namespace boost + +#include + +#endif // BOOST_INTERPROCESS_EXCEPTIONS_HPP diff --git a/thirdparty/boost/interprocess/file_mapping.hpp b/thirdparty/boost/interprocess/file_mapping.hpp new file mode 100644 index 0000000..2523348 --- /dev/null +++ b/thirdparty/boost/interprocess/file_mapping.hpp @@ -0,0 +1,173 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MAPPED_FILE_HPP +#define BOOST_INTERPROCESS_MAPPED_FILE_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include //std::string +#include //std::remove +#include + +//!\file +//!Describes file_mapping and mapped region classes + +namespace boost { + +namespace interprocess { + +//!A class that wraps a file-mapping that can be used to +//!create mapped regions from the mapped files +class file_mapping +{ + /// @cond + //Non-copyable and non-assignable + file_mapping(const file_mapping &); + file_mapping &operator=(const file_mapping &); + /// @endcond + + public: + //!Constructs an empty file mapping. + //!Does not throw + file_mapping(); + + //!Opens a file mapping of file "filename", starting in offset + //!"file_offset", and the mapping's size will be "size". The mapping + //!can be opened for read-only "read_only" or read-write "read_write" + //!modes. Throws interprocess_exception on error. + file_mapping(const char *filename, mode_t mode); + + //!Moves the ownership of "moved"'s shared memory object to *this. + //!After the call, "moved" does not represent any shared memory object. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + file_mapping(detail::moved_object &moved) + { this->swap(moved.get()); } + #else + file_mapping(file_mapping &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s shared memory to *this. + //!After the call, "moved" does not represent any shared memory. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + file_mapping &operator= + (detail::moved_object &moved) + { + file_mapping tmp(moved); + this->swap(tmp); + return *this; + } + #else + file_mapping &operator=(file_mapping &&moved) + { + file_mapping tmp(move(moved)); + this->swap(tmp); + return *this; + } + #endif + + //!Swaps to file_mappings. + //!Does not throw. + void swap(file_mapping &other); + + //!Returns access mode + //!used in the constructor + mode_t get_mode() const; + + //!Obtains the mapping handle + //!to be used with mapped_region + mapping_handle_t get_mapping_handle() const; + + //!Destroys the file mapping. All mapped regions created from this are still + //!valid. Does not throw + ~file_mapping(); + + //!Returns the name of the file + //!used in the constructor. + const char *get_name() const; + + /// @cond + private: + //!Closes a previously opened file mapping. Never throws. + void priv_close(); + file_handle_t m_handle; + mode_t m_mode; + std::string m_filename; + /// @endcond +}; + +inline file_mapping::file_mapping() + : m_handle(file_handle_t(detail::invalid_file())) +{} + +inline file_mapping::~file_mapping() +{ this->priv_close(); } + +inline const char *file_mapping::get_name() const +{ return m_filename.c_str(); } + +inline void file_mapping::swap(file_mapping &other) +{ + std::swap(m_handle, other.m_handle); + std::swap(m_mode, other.m_mode); + m_filename.swap(other.m_filename); +} + +inline mapping_handle_t file_mapping::get_mapping_handle() const +{ return detail::mapping_handle_from_file_handle(m_handle); } + +inline mode_t file_mapping::get_mode() const +{ return m_mode; } + +inline file_mapping::file_mapping + (const char *filename, mode_t mode) + : m_filename(filename) +{ + //Check accesses + if (mode != read_write && mode != read_only){ + error_info err = other_error; + throw interprocess_exception(err); + } + + //Open file + m_handle = detail::open_existing_file(filename, mode); + + //Check for error + if(m_handle == detail::invalid_file()){ + error_info err = system_error_code(); + this->priv_close(); + throw interprocess_exception(err); + } + m_mode = mode; +} + +inline void file_mapping::priv_close() +{ + if(m_handle != detail::invalid_file()){ + detail::close_file(m_handle); + m_handle = detail::invalid_file(); + } +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MAPPED_FILE_HPP diff --git a/thirdparty/boost/interprocess/indexes/flat_map_index.hpp b/thirdparty/boost/interprocess/indexes/flat_map_index.hpp new file mode 100644 index 0000000..aa03b5d --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/flat_map_index.hpp @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTERPROCESS_FLAT_MAP_INDEX_HPP +#define BOOST_INTERPROCESS_FLAT_MAP_INDEX_HPP + +#include +#include + +#include +#include +#include +#include + +//!\file +//!Describes index adaptor of boost::map container, to use it +//!as name/shared memory index + +//[flat_map_index +namespace boost { namespace interprocess { + +//!Helper class to define typedefs from IndexTraits +template +struct flat_map_index_aux +{ + typedef typename MapConfig::key_type key_type; + typedef typename MapConfig::mapped_type mapped_type; + typedef typename MapConfig:: + segment_manager_base segment_manager_base; + typedef std::less key_less; + typedef std::pair value_type; + typedef allocator allocator_type; + typedef flat_map index_t; +}; + +//!Index type based in flat_map. Just derives from flat_map and +//!defines the interface needed by managed memory segments. +template +class flat_map_index + //Derive class from flat_map specialization + : public flat_map_index_aux::index_t +{ + /// @cond + typedef flat_map_index_aux index_aux; + typedef typename index_aux::index_t base_type; + typedef typename index_aux:: + segment_manager_base segment_manager_base; + /// @endcond + + public: + //!Constructor. Takes a pointer to the segment manager. Can throw + flat_map_index(segment_manager_base *segment_mngr) + : base_type(typename index_aux::key_less(), + typename index_aux::allocator_type(segment_mngr)) + {} + + //!This reserves memory to optimize the insertion of n elements in the index + void reserve(std::size_t n) + { base_type::reserve(n); } + + //!This frees all unnecessary memory + void shrink_to_fit() + { base_type::shrink_to_fit(); } +}; + +}} //namespace boost { namespace interprocess +//] +#include + +#endif //#ifndef BOOST_INTERPROCESS_FLAT_MAP_INDEX_HPP diff --git a/thirdparty/boost/interprocess/indexes/iset_index.hpp b/thirdparty/boost/interprocess/indexes/iset_index.hpp new file mode 100644 index 0000000..dd71a75 --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/iset_index.hpp @@ -0,0 +1,150 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_ISET_INDEX_HPP +#define BOOST_INTERPROCESS_ISET_INDEX_HPP + +#include +#include + +#include +#include +#include +#include +#include + + +//!\file +//!Describes index adaptor of boost::intrusive::set container, to use it +//!as name/shared memory index + +namespace boost { +namespace interprocess { + +/// @cond + +//!Helper class to define typedefs from IndexTraits +template +struct iset_index_aux +{ + typedef typename + MapConfig::segment_manager_base segment_manager_base; + + typedef typename + segment_manager_base::void_pointer void_pointer; + typedef typename bi::make_set_base_hook + < bi::void_pointer + , bi::optimize_size + >::type derivation_hook; + + typedef typename MapConfig::template + intrusive_value_type::type value_type; + typedef std::less value_compare; + typedef typename bi::make_set + < value_type + , bi::base_hook + >::type index_t; +}; +/// @endcond + +//!Index type based in boost::intrusive::set. +//!Just derives from boost::intrusive::set +//!and defines the interface needed by managed memory segments*/ +template +class iset_index + //Derive class from map specialization + : public iset_index_aux::index_t +{ + /// @cond + typedef iset_index_aux index_aux; + typedef typename index_aux::index_t index_type; + typedef typename MapConfig:: + intrusive_compare_key_type intrusive_compare_key_type; + typedef typename MapConfig::char_type char_type; + /// @endcond + + public: + typedef typename index_type::iterator iterator; + typedef typename index_type::const_iterator const_iterator; + typedef typename index_type::insert_commit_data insert_commit_data; + typedef typename index_type::value_type value_type; + + /// @cond + private: + + struct intrusive_key_value_less + { + bool operator()(const intrusive_compare_key_type &i, const value_type &b) const + { + std::size_t blen = b.name_length(); + return (i.m_len < blen) || + (i.m_len == blen && + std::char_traits::compare + (i.mp_str, b.name(), i.m_len) < 0); + } + + bool operator()(const value_type &b, const intrusive_compare_key_type &i) const + { + std::size_t blen = b.name_length(); + return (blen < i.m_len) || + (blen == i.m_len && + std::char_traits::compare + (b.name(), i.mp_str, i.m_len) < 0); + } + }; + + /// @endcond + + public: + + //!Constructor. Takes a pointer to the + //!segment manager. Can throw + iset_index(typename MapConfig::segment_manager_base *) + : index_type(/*typename index_aux::value_compare()*/) + {} + + //!This reserves memory to optimize the insertion of n + //!elements in the index + void reserve(std::size_t) + { /*Does nothing, map has not reserve or rehash*/ } + + //!This frees all unnecessary memory + void shrink_to_fit() + { /*Does nothing, this intrusive index does not allocate memory;*/ } + + iterator find(const intrusive_compare_key_type &key) + { return index_type::find(key, intrusive_key_value_less()); } + + const_iterator find(const intrusive_compare_key_type &key) const + { return index_type::find(key, intrusive_key_value_less()); } + + std::pairinsert_check + (const intrusive_compare_key_type &key, insert_commit_data &commit_data) + { return index_type::insert_check(key, intrusive_key_value_less(), commit_data); } +}; + +/// @cond + +//!Trait class to detect if an index is an intrusive +//!index. +template +struct is_intrusive_index + > +{ + enum{ value = true }; +}; +/// @endcond + +} //namespace interprocess { +} //namespace boost + +#include + +#endif //#ifndef BOOST_INTERPROCESS_ISET_INDEX_HPP diff --git a/thirdparty/boost/interprocess/indexes/iunordered_set_index.hpp b/thirdparty/boost/interprocess/indexes/iunordered_set_index.hpp new file mode 100644 index 0000000..26fee56 --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/iunordered_set_index.hpp @@ -0,0 +1,367 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_IUNORDERED_SET_INDEX_HPP +#define BOOST_INTERPROCESS_IUNORDERED_SET_INDEX_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes index adaptor of boost::intrusive::unordered_set container, to use it +//!as name/shared memory index + +namespace boost { namespace interprocess { + +/// @cond + +//!Helper class to define typedefs +//!from IndexTraits +template +struct iunordered_set_index_aux +{ + typedef typename + MapConfig::segment_manager_base segment_manager_base; + + typedef typename + segment_manager_base::void_pointer void_pointer; + + typedef typename bi::make_unordered_set_base_hook + < bi::void_pointer + >::type derivation_hook; + + typedef typename MapConfig::template + intrusive_value_type::type value_type; + + typedef typename MapConfig:: + intrusive_compare_key_type intrusive_compare_key_type; + + typedef std::equal_to value_equal; + + typedef typename MapConfig::char_type char_type; + + struct equal_function + { + bool operator()(const intrusive_compare_key_type &i, const value_type &b) const + { + return (i.m_len == b.name_length()) && + (std::char_traits::compare + (i.mp_str, b.name(), i.m_len) == 0); + } + + bool operator()(const value_type &b, const intrusive_compare_key_type &i) const + { + return (i.m_len == b.name_length()) && + (std::char_traits::compare + (i.mp_str, b.name(), i.m_len) == 0); + } + + bool operator()(const value_type &b1, const value_type &b2) const + { + return (b1.name_length() == b2.name_length()) && + (std::char_traits::compare + (b1.name(), b2.name(), b1.name_length()) == 0); + } + }; + + struct hash_function + : std::unary_function + { + std::size_t operator()(const value_type &val) const + { + const char_type *beg = detail::get_pointer(val.name()), + *end = beg + val.name_length(); + return boost::hash_range(beg, end); + } + + std::size_t operator()(const intrusive_compare_key_type &i) const + { + const char_type *beg = i.mp_str, + *end = beg + i.m_len; + return boost::hash_range(beg, end); + } + }; + + typedef typename bi::make_unordered_set + < value_type + , bi::hash + , bi::equal + >::type index_t; + typedef typename index_t::bucket_type bucket_type; + typedef allocator + allocator_type; + + struct allocator_holder + { + allocator_holder(segment_manager_base *mngr) + : alloc(mngr) + {} + allocator_type alloc; + bucket_type init_bucket; + }; +}; +/// @endcond + +//!Index type based in boost::intrusive::set. +//!Just derives from boost::intrusive::set +//!and defines the interface needed by managed memory segments +template +class iunordered_set_index + //Derive class from map specialization + : private iunordered_set_index_aux::allocator_holder + , public iunordered_set_index_aux::index_t +{ + /// @cond + typedef iunordered_set_index_aux index_aux; + typedef typename index_aux::index_t index_type; + typedef typename MapConfig:: + intrusive_compare_key_type intrusive_compare_key_type; + typedef typename index_aux::equal_function equal_function; + typedef typename index_aux::hash_function hash_function; + typedef typename MapConfig::char_type char_type; + typedef typename + iunordered_set_index_aux::allocator_type allocator_type; + typedef typename + iunordered_set_index_aux::allocator_holder allocator_holder; + /// @endcond + + public: + typedef typename index_type::iterator iterator; + typedef typename index_type::const_iterator const_iterator; + typedef typename index_type::insert_commit_data insert_commit_data; + typedef typename index_type::value_type value_type; + typedef typename index_type::bucket_ptr bucket_ptr; + typedef typename index_type::bucket_type bucket_type; + typedef typename index_type::bucket_traits bucket_traits; + typedef typename index_type::size_type size_type; + + /// @cond + private: + typedef typename index_aux:: + segment_manager_base segment_manager_base; + + enum { InitBufferSize = 64}; + + static bucket_ptr create_buckets(allocator_type &alloc, std::size_t num) + { + num = index_type::suggested_upper_bucket_count(num); + bucket_ptr buckets = alloc.allocate(num); + bucket_ptr buckets_init = buckets; + for(std::size_t i = 0; i < num; ++i){ + new(get_pointer(buckets_init++))bucket_type(); + } + return buckets; + } + + static std::size_t shrink_buckets + ( bucket_ptr buckets, std::size_t old_size + , allocator_type &alloc, std::size_t new_size) + { + if(old_size <= new_size ) + return old_size; + std::size_t received_size; + if(!alloc.allocation_command + (try_shrink_in_place | nothrow_allocation, old_size, new_size, received_size, buckets).first){ + return old_size; + } + + for( bucket_type *p = detail::get_pointer(buckets) + received_size + , *pend = detail::get_pointer(buckets) + old_size + ; p != pend + ; ++p){ + p->~bucket_type(); + } + + bucket_ptr shunk_p = alloc.allocation_command + (shrink_in_place | nothrow_allocation, received_size, received_size, received_size, buckets).first; + BOOST_ASSERT(buckets == shunk_p); + + bucket_ptr buckets_init = buckets + received_size; + for(std::size_t i = 0; i < (old_size - received_size); ++i){ + get_pointer(buckets_init++)->~bucket_type(); + } + return received_size; + } + + static bucket_ptr expand_or_create_buckets + ( bucket_ptr old_buckets, const std::size_t old_num + , allocator_type &alloc, const std::size_t new_num) + { + std::size_t received_size; + std::pair ret = + alloc.allocation_command + (expand_fwd | allocate_new, new_num, new_num, received_size, old_buckets); + if(ret.first == old_buckets){ + bucket_ptr buckets_init = old_buckets + old_num; + for(std::size_t i = 0; i < (new_num - old_num); ++i){ + new(get_pointer(buckets_init++))bucket_type(); + } + } + else{ + bucket_ptr buckets_init = ret.first; + for(std::size_t i = 0; i < new_num; ++i){ + new(get_pointer(buckets_init++))bucket_type(); + } + } + + return ret.first; + } + + static void destroy_buckets + (allocator_type &alloc, bucket_ptr buckets, std::size_t num) + { + bucket_ptr buckets_destroy = buckets; + for(std::size_t i = 0; i < num; ++i){ + get_pointer(buckets_destroy++)->~bucket_type(); + } + alloc.deallocate(buckets, num); + } + + iunordered_set_index* get_this_pointer() + { return this; } + + /// @endcond + + public: + //!Constructor. Takes a pointer to the + //!segment manager. Can throw + iunordered_set_index(segment_manager_base *mngr) + : allocator_holder(mngr) + , index_type(bucket_traits(&get_this_pointer()->init_bucket, 1)) + {} + + ~iunordered_set_index() + { + index_type::clear(); + if(index_type::bucket_pointer() != bucket_ptr(&this->init_bucket)){ + destroy_buckets(this->alloc, index_type::bucket_pointer(), index_type::bucket_count()); + } + } + + //!This reserves memory to optimize the insertion of n + //!elements in the index + void reserve(std::size_t new_n) + { + //Let's maintain a 1.0f load factor + size_type old_n = this->bucket_count(); + if(new_n <= old_n) + return; + bucket_ptr old_p = this->bucket_pointer(); + new_n = index_type::suggested_upper_bucket_count(new_n); + bucket_ptr new_p; + //This can throw + try{ + if(old_p != bucket_ptr(&this->init_bucket)) + new_p = expand_or_create_buckets(old_p, old_n, this->alloc, new_n); + else + new_p = create_buckets(this->alloc, new_n); + } + catch(...){ + return; + } + //Rehashing does not throw, since neither the hash nor the + //comparison function can throw + this->rehash(bucket_traits(new_p, new_n)); + if(new_p != old_p && old_p != bucket_ptr(&this->init_bucket)){ + destroy_buckets(this->alloc, old_p, old_n); + } + } + + //!This tries to free unused memory + //!previously allocated. + void shrink_to_fit() + { + size_type cur_size = this->size(); + size_type cur_count = this->bucket_count(); + bucket_ptr old_p = this->bucket_pointer(); + + if(!this->size() && old_p != bucket_ptr(&this->init_bucket)){ + this->rehash(bucket_traits(bucket_ptr(&this->init_bucket), 1)); + destroy_buckets(this->alloc, old_p, cur_count); + } + else{ + size_type sug_count = 0; //gcc warning + sug_count = index_type::suggested_upper_bucket_count(cur_size); + + if(sug_count >= cur_count) + return; + + try{ + shrink_buckets(old_p, cur_count, this->alloc, sug_count); + } + catch(...){ + return; + } + + //Rehashing does not throw, since neither the hash nor the + //comparison function can throw + this->rehash(bucket_traits(old_p, sug_count)); + } + } + + iterator find(const intrusive_compare_key_type &key) + { return index_type::find(key, hash_function(), equal_function()); } + + const_iterator find(const intrusive_compare_key_type &key) const + { return index_type::find(key, hash_function(), equal_function()); } + + std::pairinsert_check + (const intrusive_compare_key_type &key, insert_commit_data &commit_data) + { return index_type::insert_check(key, hash_function(), equal_function(), commit_data); } + + iterator insert_commit(value_type &val, insert_commit_data &commit_data) + { + iterator it = index_type::insert_commit(val, commit_data); + size_type cur_size = this->size(); + if(cur_size > this->bucket_count()){ + try{ + this->reserve(cur_size); + } + catch(...){ + //Strong guarantee: if something goes wrong + //we should remove the insertion. + // + //We can use the iterator because the hash function + //can't throw and this means that "reserve" will + //throw only because of the memory allocation: + //the iterator has not been invalidated. + index_type::erase(it); + throw; + } + } + return it; + } +}; + +/// @cond + +//!Trait class to detect if an index is an intrusive +//!index +template +struct is_intrusive_index + > +{ + enum{ value = true }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_IUNORDERED_SET_INDEX_HPP diff --git a/thirdparty/boost/interprocess/indexes/map_index.hpp b/thirdparty/boost/interprocess/indexes/map_index.hpp new file mode 100644 index 0000000..2e2a786 --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/map_index.hpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MAP_INDEX_HPP +#define BOOST_INTERPROCESS_MAP_INDEX_HPP + +#include +#include + +#include +#include +#include +#include + +//!\file +//!Describes index adaptor of boost::map container, to use it +//!as name/shared memory index + +namespace boost { +namespace interprocess { +namespace detail{ + +//!Helper class to define typedefs from IndexTraits +template +struct map_index_aux +{ + typedef typename MapConfig::key_type key_type; + typedef typename MapConfig::mapped_type mapped_type; + typedef std::less key_less; + typedef std::pair value_type; + + typedef private_adaptive_pool + allocator_type; + + typedef boost::interprocess::map + index_t; +}; + +} //namespace detail { + +//!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map +//!and defines the interface needed by managed memory segments +template +class map_index + //Derive class from map specialization + : public detail::map_index_aux::index_t +{ + /// @cond + typedef detail::map_index_aux index_aux; + typedef typename index_aux::index_t base_type; + typedef typename MapConfig:: + segment_manager_base segment_manager_base; + /// @endcond + + public: + //!Constructor. Takes a pointer to the + //!segment manager. Can throw + map_index(segment_manager_base *segment_mngr) + : base_type(typename index_aux::key_less(), + segment_mngr){} + + //!This reserves memory to optimize the insertion of n + //!elements in the index + void reserve(std::size_t) + { /*Does nothing, map has not reserve or rehash*/ } + + //!This tries to free previously allocate + //!unused memory. + void shrink_to_fit() + { base_type::get_stored_allocator().deallocate_free_chunks(); } +}; + +/// @cond + +//!Trait class to detect if an index is a node +//!index. This allows more efficient operations +//!when deallocating named objects. +template +struct is_node_index + > +{ + enum { value = true }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MAP_INDEX_HPP diff --git a/thirdparty/boost/interprocess/indexes/null_index.hpp b/thirdparty/boost/interprocess/indexes/null_index.hpp new file mode 100644 index 0000000..1d9a2e7 --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/null_index.hpp @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTERPROCESS_NULL_INDEX_HPP +#define BOOST_INTERPROCESS_NULL_INDEX_HPP + +#include +#include + +#include + +//!\file +//!Describes a null index adaptor, so that if we don't want to construct +//!named objects, we can use this null index type to save resources. + +namespace boost { +namespace interprocess { + +//!Null index type +//!used to save compilation time when +//!named indexes are not needed. +template +class null_index +{ + /// @cond + typedef typename MapConfig:: + segment_manager_base segment_manager_base; + /// @endcond + + public: + typedef void * iterator; + typedef const void * const_iterator; + + //!begin() is equal + //!to end() + const_iterator begin() const + { return const_iterator(0); } + + //!begin() is equal + //!to end() + iterator begin() + { return iterator(0); } + + //!begin() is equal + //!to end() + const_iterator end() const + { return const_iterator(0); } + + //!begin() is equal + //!to end() + iterator end() + { return iterator(0); } + + //!Empty constructor + null_index(segment_manager_base *){} +}; + +}} //namespace boost { namespace interprocess { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_NULL_INDEX_HPP diff --git a/thirdparty/boost/interprocess/indexes/unordered_map_index.hpp b/thirdparty/boost/interprocess/indexes/unordered_map_index.hpp new file mode 100644 index 0000000..c6c1f2e --- /dev/null +++ b/thirdparty/boost/interprocess/indexes/unordered_map_index.hpp @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_UNORDERED_MAP_INDEX_HPP +#define BOOST_INTERPROCESS_UNORDERED_MAP_INDEX_HPP + +#include +#include + +#include +#include +#include +#include +#include + +//!\file +//!Describes index adaptor of boost::unordered_map container, to use it +//!as name/shared memory index + +namespace boost { +namespace interprocess { + +//!Helper class to define typedefs from +//!IndexTraits +template +struct unordered_map_index_aux +{ + typedef typename MapConfig::key_type key_type; + typedef typename MapConfig::mapped_type mapped_type; + typedef std::equal_to key_equal; + typedef std::pair value_type; + typedef private_adaptive_pool + allocator_type; + struct hasher + : std::unary_function + { + std::size_t operator()(const key_type &val) const + { + typedef typename key_type::char_type char_type; + const char_type *beg = detail::get_pointer(val.mp_str), + *end = beg + val.m_len; + return boost::hash_range(beg, end); + } + }; + typedef unordered_map index_t; +}; + +//!Index type based in unordered_map. Just derives from unordered_map and +//!defines the interface needed by managed memory segments +template +class unordered_map_index + //Derive class from unordered_map specialization + : public unordered_map_index_aux::index_t +{ + /// @cond + typedef unordered_map_index_aux index_aux; + typedef typename index_aux::index_t base_type; + typedef typename + MapConfig::segment_manager_base segment_manager_base; + /// @endcond + + public: + //!Constructor. Takes a pointer to the + //!segment manager. Can throw + unordered_map_index(segment_manager_base *segment_mngr) + : base_type(0, + typename index_aux::hasher(), + typename index_aux::key_equal(), + segment_mngr){} + + //!This reserves memory to optimize the insertion of n + //!elements in the index + void reserve(std::size_t n) + { base_type::rehash(n); } + + //!This tries to free previously allocate + //!unused memory. + void shrink_to_fit() + { base_type::rehash(base_type::size()); } +}; + +/// @cond + +//!Trait class to detect if an index is a node +//!index. This allows more efficient operations +//!when deallocating named objects. +template +struct is_node_index + > +{ + enum { value = true }; +}; +/// @endcond + +}} //namespace boost { namespace interprocess { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_UNORDERED_MAP_INDEX_HPP diff --git a/thirdparty/boost/interprocess/interprocess_fwd.hpp b/thirdparty/boost/interprocess/interprocess_fwd.hpp new file mode 100644 index 0000000..8ad0251 --- /dev/null +++ b/thirdparty/boost/interprocess/interprocess_fwd.hpp @@ -0,0 +1,474 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_FWD_HPP +#define BOOST_INTERPROCESS_FWD_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +//#include +//#include + +#include + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +/// @cond + +namespace boost{ +namespace intrusive{ +}} + +namespace boost{ +namespace interprocess{ +namespace bi = boost::intrusive; +}} + +namespace std { + +template +class allocator; + +template +struct less; + +template +struct pair; + +template +struct char_traits; + +} //namespace std { + +/// @endcond + +namespace boost { namespace interprocess { + +////////////////////////////////////////////////////////////////////////////// +// shared_memory +////////////////////////////////////////////////////////////////////////////// + +class shared_memory_object; + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +class windows_shared_memory; +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +////////////////////////////////////////////////////////////////////////////// +// mapped file/mapped region/mapped_file +////////////////////////////////////////////////////////////////////////////// + +class file_mapping; +class mapped_region; +class mapped_file; + +////////////////////////////////////////////////////////////////////////////// +// Mutexes +////////////////////////////////////////////////////////////////////////////// + +class null_mutex; + +class interprocess_mutex; +class interprocess_recursive_mutex; + +class named_mutex; +class named_recursive_mutex; + +class interprocess_semaphore; +class named_semaphore; + +////////////////////////////////////////////////////////////////////////////// +// Mutex families +////////////////////////////////////////////////////////////////////////////// + +struct mutex_family; +struct null_mutex_family; + +////////////////////////////////////////////////////////////////////////////// +// Other synchronization classes +////////////////////////////////////////////////////////////////////////////// + +class barrier; +class interprocess_sharable_mutex; +class interprocess_condition; + +////////////////////////////////////////////////////////////////////////////// +// Locks +////////////////////////////////////////////////////////////////////////////// + +template +class scoped_lock; + +template +class sharable_lock; + +////////////////////////////////////////////////////////////////////////////// +// STL compatible allocators +////////////////////////////////////////////////////////////////////////////// + +template +class allocator; + +template +class node_allocator; + +template +class private_node_allocator; + +template +class cached_node_allocator; + +template +class adaptive_pool; + +template +class private_adaptive_pool; + +template +class cached_adaptive_pool; + + +////////////////////////////////////////////////////////////////////////////// +// offset_ptr +////////////////////////////////////////////////////////////////////////////// + +template +class offset_ptr; + +////////////////////////////////////////////////////////////////////////////// +// Memory allocation algorithms +////////////////////////////////////////////////////////////////////////////// + +//Single segment memory allocation algorithms +template > +class simple_seq_fit; + +template, std::size_t MemAlignment = 0> +class rbtree_best_fit; + +////////////////////////////////////////////////////////////////////////////// +// Index Types +////////////////////////////////////////////////////////////////////////////// + +template class flat_map_index; +template class iset_index; +template class iunordered_set_index; +template class map_index; +template class null_index; +template class unordered_map_index; + +////////////////////////////////////////////////////////////////////////////// +// Segment manager +////////////////////////////////////////////////////////////////////////////// + +template class IndexType> +class segment_manager; + +////////////////////////////////////////////////////////////////////////////// +// External buffer managed memory classes +////////////////////////////////////////////////////////////////////////////// + +template class IndexType> +class basic_managed_external_buffer; + +typedef basic_managed_external_buffer + + ,iset_index> +managed_external_buffer; + +typedef basic_managed_external_buffer + + ,iset_index> +wmanaged_external_buffer; + +////////////////////////////////////////////////////////////////////////////// +// managed memory classes +////////////////////////////////////////////////////////////////////////////// + +template class IndexType> +class basic_managed_shared_memory; + +typedef basic_managed_shared_memory + + ,iset_index> +managed_shared_memory; + +typedef basic_managed_shared_memory + + ,iset_index> +wmanaged_shared_memory; + + +////////////////////////////////////////////////////////////////////////////// +// Windows shared memory managed memory classes +////////////////////////////////////////////////////////////////////////////// + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +template class IndexType> +class basic_managed_windows_shared_memory; + +typedef basic_managed_windows_shared_memory + + ,iset_index> +managed_windows_shared_memory; + +typedef basic_managed_windows_shared_memory + + ,iset_index> +wmanaged_windows_shared_memory; + +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +////////////////////////////////////////////////////////////////////////////// +// Fixed address shared memory +////////////////////////////////////////////////////////////////////////////// + +typedef basic_managed_shared_memory + + ,iset_index> +fixed_managed_shared_memory; + +typedef basic_managed_shared_memory + + ,iset_index> +wfixed_managed_shared_memory; + +////////////////////////////////////////////////////////////////////////////// +// Heap memory managed memory classes +////////////////////////////////////////////////////////////////////////////// + +template + class IndexType> +class basic_managed_heap_memory; + +typedef basic_managed_heap_memory + + ,iset_index> +managed_heap_memory; + +typedef basic_managed_heap_memory + + ,iset_index> +wmanaged_heap_memory; + +////////////////////////////////////////////////////////////////////////////// +// Mapped file managed memory classes +////////////////////////////////////////////////////////////////////////////// + +template + class IndexType> +class basic_managed_mapped_file; + +typedef basic_managed_mapped_file + + ,iset_index> +managed_mapped_file; + +typedef basic_managed_mapped_file + + ,iset_index> +wmanaged_mapped_file; + +////////////////////////////////////////////////////////////////////////////// +// Exceptions +////////////////////////////////////////////////////////////////////////////// + +class interprocess_exception; +class lock_exception; +class bad_alloc; + +////////////////////////////////////////////////////////////////////////////// +// Bufferstream +////////////////////////////////////////////////////////////////////////////// + +//bufferstream +template > +class basic_bufferbuf; + +template > +class basic_ibufferstream; + +template > +class basic_obufferstream; + +template > +class basic_bufferstream; + +////////////////////////////////////////////////////////////////////////////// +// Vectorstream +////////////////////////////////////////////////////////////////////////////// + +template > +class basic_vectorbuf; + +template > +class basic_ivectorstream; + +template > +class basic_ovectorstream; + +template > +class basic_vectorstream; + +////////////////////////////////////////////////////////////////////////////// +// Smart pointers +////////////////////////////////////////////////////////////////////////////// + +template +class scoped_ptr; + +template +class intrusive_ptr; + +template +class shared_ptr; + +template +class weak_ptr; + +////////////////////////////////////////////////////////////////////////////// +// IPC +////////////////////////////////////////////////////////////////////////////// + +class message_queue; + +////////////////////////////////////////////////////////////////////////////// +// Containers +////////////////////////////////////////////////////////////////////////////// + +//vector class +template > +class vector; + +//list class +template > +class list; + +//slist class +template > +class slist; + +//set class +template + ,class Alloc = std::allocator > +class set; + +//multiset class +template + ,class Alloc = std::allocator > +class multiset; + +//map class +template + ,class Alloc = std::allocator > > +class map; + +//multimap class +template + ,class Alloc = std::allocator > > +class multimap; + +//flat_set class +template + ,class Alloc = std::allocator > +class flat_set; + +//flat_multiset class +template + ,class Alloc = std::allocator > +class flat_multiset; + +//flat_map class +template + ,class Alloc = std::allocator > > +class flat_map; + +//flat_multimap class +template + ,class Alloc = std::allocator > > +class flat_multimap; + +//basic_string class +template + ,class Alloc = std::allocator > +class basic_string; + +//string class +typedef basic_string + + ,std::allocator > +string; + +}} //namespace boost { namespace interprocess { + +//#include + +#endif //#ifndef BOOST_INTERPROCESS_FWD_HPP + diff --git a/thirdparty/boost/interprocess/ipc/message_queue.hpp b/thirdparty/boost/interprocess/ipc/message_queue.hpp new file mode 100644 index 0000000..9994710 --- /dev/null +++ b/thirdparty/boost/interprocess/ipc/message_queue.hpp @@ -0,0 +1,618 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MESSAGE_QUEUE_HPP +#define BOOST_INTERPROCESS_MESSAGE_QUEUE_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //std::lower_bound +#include //std::size_t +#include //memcpy + + +//!\file +//!Describes an inter-process message queue. This class allows sending +//!messages between processes and allows blocking, non-blocking and timed +//!sending and receiving. + +namespace boost{ namespace interprocess{ + +//!A class that allows sending messages +//!between processes. +class message_queue +{ + /// @cond + //Blocking modes + enum block_t { blocking, timed, non_blocking }; + + message_queue(); + /// @endcond + + public: + + //!Creates a process shared message queue with name "name". For this message queue, + //!the maximum number of messages will be "max_num_msg" and the maximum message size + //!will be "max_msg_size". + message_queue(create_only_t create_only, + const char *name, + std::size_t max_num_msg, + std::size_t max_msg_size); + + //!Opens or creates a process shared message queue with name "name". + //!If the queue is created, the maximum number of messages will be "max_num_msg" + //!and the maximum message size will be "max_msg_size". If queue was previously + //!created the queue will be opened and "max_num_msg" and "max_msg_size" parameters + //!are ignored. + message_queue(open_or_create_t open_or_create, + const char *name, + std::size_t max_num_msg, + std::size_t max_msg_size); + + //!Opens a previously created process shared message queue with name "name". + //!If the was not previously created or there are no free resources, the + //!function returns false. + message_queue(open_only_t open_only, + const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. All opened message queues are still + //!valid after destruction. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the message queue from the system + //!use remove(). + ~message_queue(); + + //!Sends a message stored in buffer "buffer" with size "buffer_size" in the + //!message queue with priority "priority". If the message queue is full + //!the sender is blocked. Throws interprocess_error on error.*/ + void send (const void *buffer, std::size_t buffer_size, + unsigned int priority); + + //!Sends a message stored in buffer "buffer" with size "buffer_size" through the + //!message queue with priority "priority". If the message queue is full + //!the sender is not blocked and returns false, otherwise returns true. + //!Throws interprocess_error on error. + bool try_send (const void *buffer, std::size_t buffer_size, + unsigned int priority); + + //!Sends a message stored in buffer "buffer" with size "buffer_size" in the + //!message queue with priority "priority". If the message queue is full + //!the sender is retries until time "abs_time" is reached. Returns true if + //!the message has been successfully sent. Returns false if timeout is reached. + //!Throws interprocess_error on error. + bool timed_send (const void *buffer, std::size_t buffer_size, + unsigned int priority, const boost::posix_time::ptime& abs_time); + + //!Receives a message from the message queue. The message is stored in buffer + //!"buffer", which has size "buffer_size". The received message has size + //!"recvd_size" and priority "priority". If the message queue is full + //!the sender is blocked. Throws interprocess_error on error. + void receive (void *buffer, std::size_t buffer_size, + std::size_t &recvd_size,unsigned int &priority); + + //!Receives a message from the message queue. The message is stored in buffer + //!"buffer", which has size "buffer_size". The received message has size + //!"recvd_size" and priority "priority". If the message queue is full + //!the sender is not blocked and returns false, otherwise returns true. + //!Throws interprocess_error on error. + bool try_receive (void *buffer, std::size_t buffer_size, + std::size_t &recvd_size,unsigned int &priority); + + //!Receives a message from the message queue. The message is stored in buffer + //!"buffer", which has size "buffer_size". The received message has size + //!"recvd_size" and priority "priority". If the message queue is full + //!the sender is retries until time "abs_time" is reached. Returns true if + //!the message has been successfully sent. Returns false if timeout is reached. + //!Throws interprocess_error on error. + bool timed_receive (void *buffer, std::size_t buffer_size, + std::size_t &recvd_size,unsigned int &priority, + const boost::posix_time::ptime &abs_time); + + //!Returns the maximum number of messages allowed by the queue. The message + //!queue must be opened or created previously. Otherwise, returns 0. + //!Never throws + std::size_t get_max_msg() const; + + //!Returns the maximum size of message allowed by the queue. The message + //!queue must be opened or created previously. Otherwise, returns 0. + //!Never throws + std::size_t get_max_msg_size() const; + + //!Returns the number of messages currently stored. + //!Never throws + std::size_t get_num_msg(); + + //!Removes the message queue from the system. + //!Returns false on error. Never throws + static bool remove(const char *name); + + /// @cond + private: + typedef boost::posix_time::ptime ptime; + bool do_receive(block_t block, + void *buffer, std::size_t buffer_size, + std::size_t &recvd_size, unsigned int &priority, + const ptime &abs_time); + + bool do_send(block_t block, + const void *buffer, std::size_t buffer_size, + unsigned int priority, const ptime &abs_time); + + //!Returns the needed memory size for the shared message queue. + //!Never throws + static std::size_t get_mem_size(std::size_t max_msg_size, std::size_t max_num_msg); + + detail::managed_open_or_create_impl m_shmem; + /// @endcond +}; + +/// @cond + +namespace detail { + +//!This header is the prefix of each message in the queue +class msg_hdr_t +{ + public: + std::size_t len; // Message length + unsigned int priority;// Message priority + //!Returns the data buffer associated with this this message + void * data(){ return this+1; } // +}; + +//!This functor is the predicate to order stored messages by priority +class priority_functor +{ + public: + bool operator()(const offset_ptr &msg1, + const offset_ptr &msg2) const + { return msg1->priority < msg2->priority; } +}; + +//!This header is placed in the beginning of the shared memory and contains +//!the data to control the queue. This class initializes the shared memory +//!in the following way: in ascending memory address with proper alignment +//!fillings: +//! +//!-> mq_hdr_t: +//! Main control block that controls the rest of the elements +//! +//!-> offset_ptr index [max_num_msg] +//! An array of pointers with size "max_num_msg" called index. Each pointer +//! points to a preallocated message. The elements of this array are +//! reordered in runtime in the following way: +//! +//! When the current number of messages is "cur_num_msg", the first +//! "cur_num_msg" pointers point to inserted messages and the rest +//! point to free messages. The first "cur_num_msg" pointers are +//! ordered by the priority of the pointed message and by insertion order +//! if two messages have the same priority. So the next message to be +//! used in a "receive" is pointed by index [cur_num_msg-1] and the first free +//! message ready to be used in a "send" operation is index [cur_num_msg]. +//! This transforms index in a fixed size priority queue with an embedded free +//! message queue. +//! +//!-> struct message_t +//! { +//! msg_hdr_t header; +//! char[max_msg_size] data; +//! } messages [max_num_msg]; +//! +//! An array of buffers of preallocated messages, each one prefixed with the +//! msg_hdr_t structure. Each of this message is pointed by one pointer of +//! the index structure. +class mq_hdr_t + : public detail::priority_functor +{ + typedef offset_ptr msg_hdr_ptr_t; + public: + //!Constructor. This object must be constructed in the beginning of the + //!shared memory of the size returned by the function "get_mem_size". + //!This constructor initializes the needed resources and creates + //!the internal structures like the priority index. This can throw.*/ + mq_hdr_t(std::size_t max_num_msg, std::size_t max_msg_size) + : m_max_num_msg(max_num_msg), + m_max_msg_size(max_msg_size), + m_cur_num_msg(0) + { this->initialize_memory(); } + + //!Returns the inserted message with top priority + msg_hdr_t * top_msg() + { return mp_index[m_cur_num_msg-1].get(); } + + //!Returns true if the message queue is full + bool is_full() const + { return m_cur_num_msg == m_max_num_msg; } + + //!Returns true if the message queue is empty + bool is_empty() const + { return !m_cur_num_msg; } + + //!Frees the top priority message and saves it in the free message list + void free_top_msg() + { --m_cur_num_msg; } + + //!Returns the first free msg of the free message queue + msg_hdr_t * free_msg() + { return mp_index[m_cur_num_msg].get(); } + + //!Inserts the first free message in the priority queue + void queue_free_msg() + { + //Get free msg + msg_hdr_ptr_t free = mp_index[m_cur_num_msg]; + //Get priority queue's range + msg_hdr_ptr_t *it = &mp_index[0], *it_end = &mp_index[m_cur_num_msg]; + //Check where the free message should be placed + it = std::lower_bound(it, it_end, free, static_cast(*this)); + //Make room in that position + std::copy_backward(it, it_end, it_end+1); + //Insert the free message in the correct position + *it = free; + ++m_cur_num_msg; + } + + //!Returns the number of bytes needed to construct a message queue with + //!"max_num_size" maximum number of messages and "max_msg_size" maximum + //!message size. Never throws. + static std::size_t get_mem_size + (std::size_t max_msg_size, std::size_t max_num_msg) + { + const std::size_t + msg_hdr_align = detail::alignment_of::value, + index_align = detail::alignment_of::value, + r_hdr_size = detail::ct_rounded_size::value, + r_index_size = detail::get_rounded_size(sizeof(msg_hdr_ptr_t)*max_num_msg, msg_hdr_align), + r_max_msg_size = detail::get_rounded_size(max_msg_size, msg_hdr_align) + sizeof(detail::msg_hdr_t); + return r_hdr_size + r_index_size + (max_num_msg*r_max_msg_size) + + detail::managed_open_or_create_impl::ManagedOpenOrCreateUserOffset; + } + + //!Initializes the memory structures to preallocate messages and constructs the + //!message index. Never throws. + void initialize_memory() + { + const std::size_t + msg_hdr_align = detail::alignment_of::value, + index_align = detail::alignment_of::value, + r_hdr_size = detail::ct_rounded_size::value, + r_index_size = detail::get_rounded_size(sizeof(msg_hdr_ptr_t)*m_max_num_msg, msg_hdr_align), + r_max_msg_size = detail::get_rounded_size(m_max_msg_size, msg_hdr_align) + sizeof(detail::msg_hdr_t); + + //Pointer to the index + msg_hdr_ptr_t *index = reinterpret_cast + (detail::char_ptr_cast(this)+r_hdr_size); + + //Pointer to the first message header + detail::msg_hdr_t *msg_hdr = reinterpret_cast + (detail::char_ptr_cast(this)+r_hdr_size+r_index_size); + + //Initialize the pointer to the index + mp_index = index; + + //Initialize the index so each slot points to a preallocated message + for(std::size_t i = 0; i < m_max_num_msg; ++i){ + index[i] = msg_hdr; + msg_hdr = reinterpret_cast + (detail::char_ptr_cast(msg_hdr)+r_max_msg_size); + } + } + + public: + //Pointer to the index + offset_ptr mp_index; + //Maximum number of messages of the queue + const std::size_t m_max_num_msg; + //Maximum size of messages of the queue + const std::size_t m_max_msg_size; + //Current number of messages + std::size_t m_cur_num_msg; + //Mutex to protect data structures + interprocess_mutex m_mutex; + //Condition block receivers when there are no messages + interprocess_condition m_cond_recv; + //Condition block senders when the queue is full + interprocess_condition m_cond_send; +}; + + +//!This is the atomic functor to be executed when creating or opening +//!shared memory. Never throws +class initialization_func_t +{ + public: + initialization_func_t(std::size_t maxmsg = 0, + std::size_t maxmsgsize = 0) + : m_maxmsg (maxmsg), m_maxmsgsize(maxmsgsize) {} + + bool operator()(void *address, std::size_t, bool created) + { + char *mptr; + + if(created){ + mptr = reinterpret_cast(address); + //Construct the message queue header at the beginning + BOOST_TRY{ + new (mptr) mq_hdr_t(m_maxmsg, m_maxmsgsize); + } + BOOST_CATCH(...){ + return false; + } + BOOST_CATCH_END + } + return true; + } + const std::size_t m_maxmsg; + const std::size_t m_maxmsgsize; +}; + +} //namespace detail { +/// @endcond + +inline message_queue::~message_queue() +{} + +inline std::size_t message_queue::get_mem_size + (std::size_t max_msg_size, std::size_t max_num_msg) +{ return detail::mq_hdr_t::get_mem_size(max_msg_size, max_num_msg); } + +inline message_queue::message_queue(create_only_t create_only, + const char *name, + std::size_t max_num_msg, + std::size_t max_msg_size) + //Create shared memory and execute functor atomically + : m_shmem(create_only, + name, + get_mem_size(max_msg_size, max_num_msg), + read_write, + (void*)0, + //Prepare initialization functor + detail::initialization_func_t (max_num_msg, max_msg_size)) +{} + +inline message_queue::message_queue(open_or_create_t open_or_create, + const char *name, + std::size_t max_num_msg, + std::size_t max_msg_size) + //Create shared memory and execute functor atomically + : m_shmem(open_or_create, + name, + get_mem_size(max_msg_size, max_num_msg), + read_write, + (void*)0, + //Prepare initialization functor + detail::initialization_func_t (max_num_msg, max_msg_size)) +{} + +inline message_queue::message_queue(open_only_t open_only, + const char *name) + //Create shared memory and execute functor atomically + : m_shmem(open_only, + name, + read_write, + (void*)0, + //Prepare initialization functor + detail::initialization_func_t ()) +{} + +inline void message_queue::send + (const void *buffer, std::size_t buffer_size, unsigned int priority) +{ this->do_send(blocking, buffer, buffer_size, priority, ptime()); } + +inline bool message_queue::try_send + (const void *buffer, std::size_t buffer_size, unsigned int priority) +{ return this->do_send(non_blocking, buffer, buffer_size, priority, ptime()); } + +inline bool message_queue::timed_send + (const void *buffer, std::size_t buffer_size + ,unsigned int priority, const boost::posix_time::ptime &abs_time) +{ return this->do_send(timed, buffer, buffer_size, priority, abs_time); } + +inline bool message_queue::do_send(block_t block, + const void *buffer, std::size_t buffer_size, + unsigned int priority, const boost::posix_time::ptime &abs_time) +{ + detail::mq_hdr_t *p_hdr = static_cast(m_shmem.get_user_address()); + //Check if buffer is smaller than maximum allowed + if (buffer_size > p_hdr->m_max_msg_size) { + throw interprocess_exception(size_error); + } + + //--------------------------------------------- + scoped_lock lock(p_hdr->m_mutex); + //--------------------------------------------- + { + //If the queue is full execute blocking logic + if (p_hdr->is_full()) { + + switch(block){ + case non_blocking : + return false; + break; + + case blocking : + do{ + p_hdr->m_cond_send.wait(lock); + } + while (p_hdr->is_full()); + break; + + case timed : + do{ + if(!p_hdr->m_cond_send.timed_wait(lock, abs_time)) + return !p_hdr->is_full(); + } + while (p_hdr->is_full()); + break; + default: + throw interprocess_exception(); + } + } + + //Get the first free message from free message queue + detail::msg_hdr_t *free_msg = p_hdr->free_msg(); + if (free_msg == 0) { + throw interprocess_exception(); + } + + //Copy control data to the free message + free_msg->priority = priority; + free_msg->len = buffer_size; + + //Copy user buffer to the message + std::memcpy(free_msg->data(), buffer, buffer_size); + +// bool was_empty = p_hdr->is_empty(); + //Insert the first free message in the priority queue + p_hdr->queue_free_msg(); + + //If this message changes the queue empty state, notify it to receivers +// if (was_empty){ + p_hdr->m_cond_recv.notify_one(); +// } + } // Lock end + + return true; +} + +inline void message_queue::receive(void *buffer, std::size_t buffer_size, + std::size_t &recvd_size, unsigned int &priority) +{ this->do_receive(blocking, buffer, buffer_size, recvd_size, priority, ptime()); } + +inline bool + message_queue::try_receive(void *buffer, std::size_t buffer_size, + std::size_t &recvd_size, unsigned int &priority) +{ return this->do_receive(non_blocking, buffer, buffer_size, recvd_size, priority, ptime()); } + +inline bool + message_queue::timed_receive(void *buffer, std::size_t buffer_size, + std::size_t &recvd_size, unsigned int &priority, + const boost::posix_time::ptime &abs_time) +{ return this->do_receive(timed, buffer, buffer_size, recvd_size, priority, abs_time); } + +inline bool + message_queue::do_receive(block_t block, + void *buffer, std::size_t buffer_size, + std::size_t &recvd_size, unsigned int &priority, + const boost::posix_time::ptime &abs_time) +{ + detail::mq_hdr_t *p_hdr = static_cast(m_shmem.get_user_address()); + //Check if buffer is big enough for any message + if (buffer_size < p_hdr->m_max_msg_size) { + throw interprocess_exception(size_error); + } + + //--------------------------------------------- + scoped_lock lock(p_hdr->m_mutex); + //--------------------------------------------- + { + //If there are no messages execute blocking logic + if (p_hdr->is_empty()) { + switch(block){ + case non_blocking : + return false; + break; + + case blocking : + do{ + p_hdr->m_cond_recv.wait(lock); + } + while (p_hdr->is_empty()); + break; + + case timed : + do{ + if(!p_hdr->m_cond_recv.timed_wait(lock, abs_time)) + return !p_hdr->is_empty(); + } + while (p_hdr->is_empty()); + break; + + //Paranoia check + default: + throw interprocess_exception(); + } + } + + //Thre is at least message ready to pick, get the top one + detail::msg_hdr_t *top_msg = p_hdr->top_msg(); + + //Paranoia check + if (top_msg == 0) { + throw interprocess_exception(); + } + + //Get data from the message + recvd_size = top_msg->len; + priority = top_msg->priority; + + //Copy data to receiver's bufers + std::memcpy(buffer, top_msg->data(), recvd_size); + +// bool was_full = p_hdr->is_full(); + + //Free top message and put it in the free message list + p_hdr->free_top_msg(); + + //If this reception changes the queue full state, notify senders +// if (was_full){ + p_hdr->m_cond_send.notify_one(); +// } + } //Lock end + + return true; +} + +inline std::size_t message_queue::get_max_msg() const +{ + detail::mq_hdr_t *p_hdr = static_cast(m_shmem.get_user_address()); + return p_hdr ? p_hdr->m_max_num_msg : 0; } + +inline std::size_t message_queue::get_max_msg_size() const +{ + detail::mq_hdr_t *p_hdr = static_cast(m_shmem.get_user_address()); + return p_hdr ? p_hdr->m_max_msg_size : 0; +} + +inline std::size_t message_queue::get_num_msg() +{ + detail::mq_hdr_t *p_hdr = static_cast(m_shmem.get_user_address()); + if(p_hdr){ + //--------------------------------------------- + scoped_lock lock(p_hdr->m_mutex); + //--------------------------------------------- + return p_hdr->m_cur_num_msg; + } + + return 0; +} + +inline bool message_queue::remove(const char *name) +{ return shared_memory_object::remove(name); } + +}} //namespace boost{ namespace interprocess{ + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MESSAGE_QUEUE_HPP diff --git a/thirdparty/boost/interprocess/managed_external_buffer.hpp b/thirdparty/boost/interprocess/managed_external_buffer.hpp new file mode 100644 index 0000000..c052318 --- /dev/null +++ b/thirdparty/boost/interprocess/managed_external_buffer.hpp @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_EXTERNAL_BUFFER_HPP +#define BOOST_INTERPROCESS_MANAGED_EXTERNAL_BUFFER_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named user memory allocation user class. + +namespace boost { +namespace interprocess { + +//!A basic user memory named object creation class. Inherits all +//!basic functionality from +//!basic_managed_memory_impl*/ +template + < + class CharType, + class AllocationAlgorithm, + template class IndexType + > +class basic_managed_external_buffer + : public detail::basic_managed_memory_impl +{ + /// @cond + typedef detail::basic_managed_memory_impl + base_t; + /// @endcond + + public: + //!Creates and places the segment manager. This can throw + basic_managed_external_buffer + (create_only_t, void *addr, std::size_t size) + { + //Check if alignment is correct + assert((0 == (((std::size_t)addr) & (AllocationAlgorithm::Alignment - std::size_t(1u))))); + if(!base_t::create_impl(addr, size)){ + throw interprocess_exception(); + } + } + + //!Creates and places the segment manager. This can throw + basic_managed_external_buffer + (open_only_t, void *addr, std::size_t size) + { + //Check if alignment is correct + assert((0 == (((std::size_t)addr) & (AllocationAlgorithm::Alignment - std::size_t(1u))))); + if(!base_t::open_impl(addr, size)){ + throw interprocess_exception(); + } + } + + //!Moves the ownership of "moved"'s managed memory to *this. Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_external_buffer + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + basic_managed_external_buffer + (basic_managed_external_buffer &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s managed memory to *this. Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_external_buffer &operator= + (detail::moved_object &moved) + { this->swap(moved.get()); return *this; } + #else + basic_managed_external_buffer &operator= + (basic_managed_external_buffer &&moved) + { this->swap(moved); return *this; } + #endif + + void grow(std::size_t extra_bytes) + { base_t::grow(extra_bytes); } + + //!Swaps the ownership of the managed heap memories managed by *this and other. + //!Never throws. + void swap(basic_managed_external_buffer &other) + { base_t::swap(other); } + +}; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MANAGED_EXTERNAL_BUFFER_HPP + diff --git a/thirdparty/boost/interprocess/managed_heap_memory.hpp b/thirdparty/boost/interprocess/managed_heap_memory.hpp new file mode 100644 index 0000000..9f27a89 --- /dev/null +++ b/thirdparty/boost/interprocess/managed_heap_memory.hpp @@ -0,0 +1,149 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_HEAP_MEMORY_HPP +#define BOOST_INTERPROCESS_MANAGED_HEAP_MEMORY_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named heap memory allocation user class. + +namespace boost { +namespace interprocess { + +//!A basic heap memory named object creation class. Initializes the +//!heap memory segment. Inherits all basic functionality from +//!basic_managed_memory_impl*/ +template + < + class CharType, + class AllocationAlgorithm, + template class IndexType + > +class basic_managed_heap_memory + : public detail::basic_managed_memory_impl +{ + /// @cond + private: + + typedef detail::basic_managed_memory_impl + base_t; + /// @endcond + + public: //functions + + //!Constructor. Never throws. + basic_managed_heap_memory(){} + + //!Destructor. Liberates the heap memory holding the managed data. + //!Never throws. + ~basic_managed_heap_memory() + { this->priv_close(); } + + //!Creates heap memory and initializes the segment manager. + //!This can throw. + basic_managed_heap_memory(std::size_t size) + : m_heapmem(size, char(0)) + { + if(!base_t::create_impl(&m_heapmem[0], size)){ + this->priv_close(); + throw interprocess_exception(); + } + } + + //!Moves the ownership of "moved"'s managed memory to *this. Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_heap_memory + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + basic_managed_heap_memory(basic_managed_heap_memory &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s managed memory to *this. Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_heap_memory &operator= + (detail::moved_object &moved) + { this->swap(moved.get()); return *this; } + #else + basic_managed_heap_memory &operator= + (basic_managed_heap_memory &&moved) + { this->swap(moved); return *this; } + #endif + + //!Tries to resize internal heap memory so that + //!we have room for more objects. + //!WARNING: If memory is reallocated, all the objects will + //!be binary-copied to the new buffer. To be able to use + //!this function, all pointers constructed in this buffer + //!must be offset pointers. Otherwise, the result is undefined. + //!Returns true if the growth has been successful, so you will + //!have some extra bytes to allocate new objects. If returns + //!false, the heap allocation has failed. + bool grow(std::size_t extra_bytes) + { + //If memory is reallocated, data will + //be automatically copied + BOOST_TRY{ + m_heapmem.resize(m_heapmem.size()+extra_bytes); + } + BOOST_CATCH(...){ + return false; + } + BOOST_CATCH_END + + //Grow always works + base_t::close_impl(); + base_t::open_impl(&m_heapmem[0], m_heapmem.size()); + base_t::grow(extra_bytes); + return true; + } + + //!Swaps the ownership of the managed heap memories managed by *this and other. + //!Never throws. + void swap(basic_managed_heap_memory &other) + { + base_t::swap(other); + m_heapmem.swap(other.m_heapmem); + } + + /// @cond + private: + //!Frees resources. Never throws. + void priv_close() + { + base_t::destroy_impl(); + std::vector().swap(m_heapmem); + } + + std::vector m_heapmem; + /// @endcond +}; + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MANAGED_HEAP_MEMORY_HPP + diff --git a/thirdparty/boost/interprocess/managed_mapped_file.hpp b/thirdparty/boost/interprocess/managed_mapped_file.hpp new file mode 100644 index 0000000..b37948a --- /dev/null +++ b/thirdparty/boost/interprocess/managed_mapped_file.hpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_MAPPED_FILE_HPP +#define BOOST_INTERPROCESS_MANAGED_MAPPED_FILE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named shared memory object allocation user class. + +namespace boost { +namespace interprocess { + +//!A basic shared memory named object creation class. Initializes the +//!shared memory segment. Inherits all basic functionality from +//!basic_managed_memory_impl +template + < + class CharType, + class AllocationAlgorithm, + template class IndexType + > +class basic_managed_mapped_file + : public detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> +{ + /// @cond + public: + typedef detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> base_t; + typedef detail::file_wrapper device_type; + + private: + + typedef detail::create_open_func create_open_func_t; + typedef detail::managed_open_or_create_impl managed_open_or_create_type; + + basic_managed_mapped_file *get_this_pointer() + { return this; } + /// @endcond + + public: //functions + + //!Creates shared memory and creates and places the segment manager. + //!This can throw. + basic_managed_mapped_file(create_only_t create_only, const char *name, + std::size_t size, const void *addr = 0) + : m_mfile(create_only, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), detail::DoCreate)) + {} + + //!Creates shared memory and creates and places the segment manager if + //!segment was not created. If segment was created it connects to the + //!segment. + //!This can throw. + basic_managed_mapped_file (open_or_create_t open_or_create, + const char *name, std::size_t size, + const void *addr = 0) + : m_mfile(open_or_create, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpenOrCreate)) + {} + + //!Connects to a created shared memory and it's the segment manager. + //!Never throws. + basic_managed_mapped_file (open_only_t open_only, const char* name, + const void *addr = 0) + : m_mfile(open_only, name, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpen)) + {} + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_mapped_file + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + basic_managed_mapped_file(basic_managed_mapped_file &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_mapped_file &operator= + (detail::moved_object &moved) + { this->swap(moved.get()); return *this; } + #else + basic_managed_mapped_file &operator=(basic_managed_mapped_file &&moved) + { this->swap(moved); return *this; } + #endif + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~basic_managed_mapped_file() + {} + + //!Swaps the ownership of the managed mapped memories managed by *this and other. + //!Never throws. + void swap(basic_managed_mapped_file &other) + { + base_t::swap(other); + m_mfile.swap(other.m_mfile); + } + + //!Flushes cached data to file. + //!Never throws + bool flush() + { return m_mfile.flush(); } + + //!Tries to resize mapped file so that we have room for + //!more objects. + //! + //!This function is not synchronized so no other thread or process should + //!be reading or writing the file + static bool grow(const char *filename, std::size_t extra_bytes) + { + return base_t::template grow + (filename, extra_bytes); + } + + //!Tries to resize mapped file to minimized the size of the file. + //! + //!This function is not synchronized so no other thread or process should + //!be reading or writing the file + static bool shrink_to_fit(const char *filename) + { + return base_t::template shrink_to_fit + (filename); + } + + /// @cond + private: + managed_open_or_create_type m_mfile; + /// @endcond +}; + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MANAGED_MAPPED_FILE_HPP diff --git a/thirdparty/boost/interprocess/managed_shared_memory.hpp b/thirdparty/boost/interprocess/managed_shared_memory.hpp new file mode 100644 index 0000000..0988f26 --- /dev/null +++ b/thirdparty/boost/interprocess/managed_shared_memory.hpp @@ -0,0 +1,168 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_SHARED_MEMORY_HPP +#define BOOST_INTERPROCESS_MANAGED_SHARED_MEMORY_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include + +//!\file +//!Describes a named shared memory object allocation user class. + +namespace boost { + +namespace interprocess { + +//!A basic shared memory named object creation class. Initializes the +//!shared memory segment. Inherits all basic functionality from +//!basic_managed_memory_impl*/ +template + < + class CharType, + class AllocationAlgorithm, + template class IndexType + > +class basic_managed_shared_memory + : public detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> + , private detail::managed_open_or_create_impl +{ + /// @cond + public: + typedef shared_memory_object device_type; + + private: + typedef detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> base_t; + typedef detail::managed_open_or_create_impl + base2_t; + + typedef detail::create_open_func create_open_func_t; + + basic_managed_shared_memory(); + + basic_managed_shared_memory *get_this_pointer() + { return this; } + /// @endcond + + public: //functions + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~basic_managed_shared_memory() + {} + + //!Creates shared memory and creates and places the segment manager. + //!This can throw. + basic_managed_shared_memory(create_only_t create_only, const char *name, + std::size_t size, const void *addr = 0) + : base_t() + , base2_t(create_only, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), detail::DoCreate)) + {} + + //!Creates shared memory and creates and places the segment manager if + //!segment was not created. If segment was created it connects to the + //!segment. + //!This can throw. + basic_managed_shared_memory (open_or_create_t open_or_create, + const char *name, std::size_t size, + const void *addr = 0) + : base_t() + , base2_t(open_or_create, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpenOrCreate)) + {} + + //!Connects to a created shared memory and it's the segment manager. + //!Never throws. + basic_managed_shared_memory (open_only_t open_only, const char* name, + const void *addr = 0) + : base_t() + , base2_t(open_only, name, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpen)) + {} + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_shared_memory + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + basic_managed_shared_memory(basic_managed_shared_memory &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_shared_memory &operator= + (detail::moved_object &moved) + { this->swap(moved.get()); return *this; } + #else + basic_managed_shared_memory &operator=(basic_managed_shared_memory &&moved) + { this->swap(moved); return *this; } + #endif + + //!Swaps the ownership of the managed shared memories managed by *this and other. + //!Never throws. + void swap(basic_managed_shared_memory &other) + { + base_t::swap(other); + base2_t::swap(other); + } + + //!Tries to resize the managed shared memory object so that we have + //!room for more objects. + //! + //!This function is not synchronized so no other thread or process should + //!be reading or writing the file + static bool grow(const char *filename, std::size_t extra_bytes) + { + return base_t::template grow + (filename, extra_bytes); + } + + //!Tries to resize the managed shared memory to minimized the size of the file. + //! + //!This function is not synchronized so no other thread or process should + //!be reading or writing the file + static bool shrink_to_fit(const char *filename) + { + return base_t::template shrink_to_fit + (filename); + } +}; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MANAGED_SHARED_MEMORY_HPP + diff --git a/thirdparty/boost/interprocess/managed_windows_shared_memory.hpp b/thirdparty/boost/interprocess/managed_windows_shared_memory.hpp new file mode 100644 index 0000000..4abfff8 --- /dev/null +++ b/thirdparty/boost/interprocess/managed_windows_shared_memory.hpp @@ -0,0 +1,146 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MANAGED_WINDOWS_SHARED_MEMORY_HPP +#define BOOST_INTERPROCESS_MANAGED_WINDOWS_SHARED_MEMORY_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named shared memory object allocation user class. + +namespace boost { +namespace interprocess { + +//!A basic managed windows shared memory creation class. Initializes the +//!shared memory segment. Inherits all basic functionality from +//!basic_managed_memory_impl +//!Unlike basic_managed_shared_memory, it has +//!no kernel persistence and the shared memory is destroyed +//!when all processes destroy all their windows_shared_memory +//!objects and mapped regions for the same shared memory +//!or the processes end/crash. +//! +//!Warning: basic_managed_windows_shared_memory and +//!basic_managed_shared_memory can't communicate between them. +template + < + class CharType, + class AllocationAlgorithm, + template class IndexType + > +class basic_managed_windows_shared_memory + : public detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> +{ + /// @cond + private: + typedef detail::basic_managed_memory_impl + ::ManagedOpenOrCreateUserOffset> base_t; + typedef detail::create_open_func create_open_func_t; + + basic_managed_windows_shared_memory *get_this_pointer() + { return this; } + /// @endcond + + public: //functions + //!Creates shared memory and creates and places the segment manager. + //!This can throw. + basic_managed_windows_shared_memory + (create_only_t create_only, const char *name, + std::size_t size, const void *addr = 0) + : m_wshm(create_only, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), detail::DoCreate)) + {} + + //!Creates shared memory and creates and places the segment manager if + //!segment was not created. If segment was created it connects to the + //!segment. + //!This can throw. + basic_managed_windows_shared_memory + (open_or_create_t open_or_create, + const char *name, std::size_t size, + const void *addr = 0) + : m_wshm(open_or_create, name, size, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpenOrCreate)) + {} + + //!Connects to a created shared memory and it's the segment manager. + //!Never throws. + basic_managed_windows_shared_memory (open_only_t open_only, const char* name, + const void *addr = 0) + : m_wshm(open_only, name, read_write, addr, + create_open_func_t(get_this_pointer(), + detail::DoOpen)) + {} + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_windows_shared_memory + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + basic_managed_windows_shared_memory(basic_managed_windows_shared_memory &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s managed memory to *this. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + basic_managed_windows_shared_memory &operator= + (detail::moved_object &moved) + { this->swap(moved.get()); return *this; } + #else + basic_managed_windows_shared_memory &operator= + (basic_managed_windows_shared_memory &&moved) + { this->swap(moved); return *this; } + #endif + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. All mapped regions are still valid after + //!destruction. When all mapped regions and basic_managed_windows_shared_memory + //!objects referring the shared memory are destroyed, the + //!operating system will destroy the shared memory. + ~basic_managed_windows_shared_memory() + {} + + //!Swaps the ownership of the managed mapped memories managed by *this and other. + //!Never throws. + void swap(basic_managed_windows_shared_memory &other) + { + base_t::swap(other); + m_wshm.swap(other.m_wshm); + } + /// @cond + private: + detail::managed_open_or_create_impl m_wshm; + /// @endcond +}; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MANAGED_WINDOWS_SHARED_MEMORY_HPP diff --git a/thirdparty/boost/interprocess/mapped_region.hpp b/thirdparty/boost/interprocess/mapped_region.hpp new file mode 100644 index 0000000..b462554 --- /dev/null +++ b/thirdparty/boost/interprocess/mapped_region.hpp @@ -0,0 +1,561 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MAPPED_REGION_HPP +#define BOOST_INTERPROCESS_MAPPED_REGION_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) +# include +#else +# ifdef BOOST_HAS_UNISTD_H +# include +# include //mmap +# include +# include +# include +# else +# error Unknown platform +# endif + +#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +//!\file +//!Describes memory_mappable and mapped region classes + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +//!The mapped_region class represents a portion or region created from a +//!memory_mappable object. +class mapped_region +{ + /// @cond + //Non-copyable + mapped_region(const mapped_region &); + mapped_region &operator=(const mapped_region &); + /// @endcond + + public: + + //!Creates a mapping region of the mapped memory "mapping", starting in + //!offset "offset", and the mapping's size will be "size". The mapping + //!can be opened for read-only "read_only" or read-write + //!"read_write. + template + mapped_region(const MemoryMappable& mapping + ,mode_t mode + ,offset_t offset = 0 + ,std::size_t size = 0 + ,const void *address = 0); + + //!Default constructor. Address and size and offset will be 0. + //!Does not throw + mapped_region(); + + //!Move constructor. *this will be constructed taking ownership of "other"'s + //!region and "other" will be left in default constructor state. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + mapped_region(detail::moved_object other); + #else + mapped_region(mapped_region &&other); + #endif + + //!Destroys the mapped region. + //!Does not throw + ~mapped_region(); + + //!Move assignment. If *this owns a memory mapped region, it will be + //!destroyed and it will take ownership of "other"'s memory mapped region. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + mapped_region &operator=(detail::moved_object other); + #else + mapped_region &operator=(mapped_region &&other); + #endif + + //!Returns the size of the mapping. Note for windows users: If + //!windows_shared_memory is mapped using 0 as the size, it returns 0 + //!because the size is unknown. Never throws. + std::size_t get_size() const; + + //!Returns the base address of the mapping. + //!Never throws. + void* get_address() const; + + //!Returns the offset of the mapping from the beginning of the + //!mapped memory. Never throws. + offset_t get_offset() const; + + //!Flushes to the disk a byte range within the mapped memory. + //!Never throws + bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0); + + //!Swaps the mapped_region with another + //!mapped region + void swap(mapped_region &other); + + //!Returns the size of the page. This size is the minimum memory that + //!will be used by the system when mapping a memory mappable source. + static std::size_t get_page_size(); + + /// @cond + private: + //!Closes a previously opened memory mapping. Never throws + void priv_close(); + + template + struct page_size_holder + { + static const std::size_t PageSize; + static std::size_t get_page_size(); + }; + + void* m_base; + std::size_t m_size; + offset_t m_offset; + offset_t m_extra_offset; + #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + file_handle_t m_file_mapping_hnd; + #endif + + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + /// @endcond +}; + +inline void swap(mapped_region &x, mapped_region &y) +{ x.swap(y); } + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +inline mapped_region &mapped_region::operator=(detail::moved_object other) +{ this->swap(other.get()); return *this; } +#else +inline mapped_region &mapped_region::operator=(mapped_region &&other) +{ this->swap(other); return *this; } +#endif + +inline mapped_region::~mapped_region() +{ this->priv_close(); } + +inline std::size_t mapped_region::get_size() const +{ return m_size; } + +inline offset_t mapped_region::get_offset() const +{ return m_offset; } + +inline void* mapped_region::get_address() const +{ return m_base; } + +#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +inline mapped_region::mapped_region() + : m_base(0), m_size(0), m_offset(0), m_extra_offset(0) + , m_file_mapping_hnd(detail::invalid_file()) +{} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +inline mapped_region::mapped_region(detail::moved_object other) + : m_base(0), m_size(0), m_offset(0) + , m_extra_offset(0) + , m_file_mapping_hnd(detail::invalid_file()) +{ this->swap(other.get()); } +#else +inline mapped_region::mapped_region(mapped_region &&other) + : m_base(0), m_size(0), m_offset(0) + , m_extra_offset(0) + , m_file_mapping_hnd(detail::invalid_file()) +{ this->swap(other); } +#endif + +template +inline std::size_t mapped_region::page_size_holder::get_page_size() +{ + winapi::system_info info; + get_system_info(&info); + return std::size_t(info.dwAllocationGranularity); +} + +template +inline mapped_region::mapped_region + (const MemoryMappable &mapping + ,mode_t mode + ,offset_t offset + ,std::size_t size + ,const void *address) + : m_base(0), m_size(0), m_offset(0), m_extra_offset(0) + , m_file_mapping_hnd(detail::invalid_file()) +{ + mapping_handle_t mhandle = mapping.get_mapping_handle(); + file_handle_t native_mapping_handle = 0; + + //Set accesses + unsigned long file_map_access = 0; + unsigned long map_access = 0; + + switch(mode) + { + case read_only: + file_map_access |= winapi::page_readonly; + map_access |= winapi::file_map_read; + break; + case read_write: + file_map_access |= winapi::page_readwrite; + map_access |= winapi::file_map_write; + break; + case copy_on_write: + file_map_access |= winapi::page_writecopy; + map_access |= winapi::file_map_copy; + break; + default: + { + error_info err(mode_error); + throw interprocess_exception(err); + } + break; + } + + if(!mhandle.is_shm){ + //Update mapping size if the user does not specify it + if(size == 0){ + __int64 total_size; + if(!winapi::get_file_size(detail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), total_size)){ + error_info err(winapi::get_last_error()); + throw interprocess_exception(err); + } + #ifdef max + #undef max + #endif + + if(static_cast(total_size) > + std::numeric_limits::max()){ + error_info err(size_error); + throw interprocess_exception(err); + } + size = static_cast(total_size - offset); + } + + //Create file mapping + native_mapping_handle = + winapi::create_file_mapping + (detail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0); + + //Check if all is correct + if(!native_mapping_handle){ + error_info err = winapi::get_last_error(); + this->priv_close(); + throw interprocess_exception(err); + } + } + + //We can't map any offset so we have to obtain system's + //memory granularity + unsigned long granularity = 0; + unsigned long foffset_low; + unsigned long foffset_high; + + winapi::system_info info; + get_system_info(&info); + granularity = info.dwAllocationGranularity; + + //Now we calculate valid offsets + foffset_low = (unsigned long)(offset / granularity) * granularity; + foffset_high = (unsigned long)(((offset / granularity) * granularity) >> 32); + + //We calculate the difference between demanded and valid offset + m_extra_offset = (offset - (offset / granularity) * granularity); + + //Store user values in memory + m_offset = offset; + m_size = size; + + //Update the mapping address + if(address){ + address = static_cast(address) - m_extra_offset; + } + + if(mhandle.is_shm){ + //Windows shared memory needs the duplication of the handle if we want to + //make mapped_region independent from the mappable device + if(!winapi::duplicate_current_process_handle(mhandle.handle, &m_file_mapping_hnd)){ + error_info err = winapi::get_last_error(); + this->priv_close(); + throw interprocess_exception(err); + } + native_mapping_handle = m_file_mapping_hnd; + } + + //Map with new offsets and size + m_base = winapi::map_view_of_file_ex + (native_mapping_handle, + map_access, + foffset_high, + foffset_low, + m_size ? static_cast(m_extra_offset + m_size) : 0, + (void*)address); + + if(!mhandle.is_shm){ + //For files we don't need the file mapping anymore + winapi::close_handle(native_mapping_handle); + } + + //Check error + if(!m_base){ + error_info err = winapi::get_last_error(); + this->priv_close(); + throw interprocess_exception(err); + } + + //Calculate new base for the user + m_base = static_cast(m_base) + m_extra_offset; +} + +inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes) +{ + //Check some errors + if(m_base == 0) + return false; + + if(mapping_offset >= m_size || (mapping_offset + numbytes) > m_size){ + return false; + } + + //Update flush size if the user does not provide it + if(m_size == 0){ + numbytes = 0; + } + else if(numbytes == 0){ + numbytes = m_size - mapping_offset; + } + + //Flush it all + return 0 == winapi::flush_view_of_file + (static_cast(m_base)+mapping_offset, + static_cast(numbytes)); +} + +inline void mapped_region::priv_close() +{ + if(m_base){ + this->flush(); + winapi::unmap_view_of_file(static_cast(m_base) - m_extra_offset); + m_base = 0; + } + #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + if(m_file_mapping_hnd){ + winapi::close_handle(m_file_mapping_hnd); + m_file_mapping_hnd = 0; + } + #endif +} + +inline void mapped_region::dont_close_on_destruction() +{} + +#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +inline mapped_region::mapped_region() + : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0) +{} + +#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE +inline mapped_region::mapped_region(detail::moved_object other) + : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0) +{ this->swap(other.get()); } +#else +inline mapped_region::mapped_region(mapped_region &&other) + : m_base(MAP_FAILED), m_size(0), m_offset(0) + , m_extra_offset(0) +{ this->swap(other); } +#endif + +template +inline std::size_t mapped_region::page_size_holder::get_page_size() +{ return std::size_t(sysconf(_SC_PAGESIZE)); } + +template +inline mapped_region::mapped_region + (const MemoryMappable &mapping, + mode_t mode, + offset_t offset, + std::size_t size, + const void *address) + : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0) +{ + if(size == 0){ +// offset_t filesize = lseek64 + offset_t filesize = lseek + (mapping.get_mapping_handle(), offset, SEEK_END); + + if(filesize == -1 ){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } + if(offset >= filesize){ + error_info err(size_error); + throw interprocess_exception(err); + } + filesize -= offset; + + size = (size_t)filesize; + if((offset_t)size != filesize){ + error_info err(size_error); + throw interprocess_exception(err); + } + } + + //Create new mapping + int prot = 0; + int flags = 0; + + switch(mode) + { + case read_only: + prot |= PROT_READ; + flags |= MAP_SHARED; + break; + + case read_write: + prot |= (PROT_WRITE | PROT_READ); + flags |= MAP_SHARED; + break; + + case copy_on_write: + prot |= PROT_READ; + flags |= MAP_PRIVATE; + break; + + default: + { + error_info err(mode_error); + throw interprocess_exception(err); + } + break; + } + + //We calculate the difference between demanded and valid offset + std::size_t page_size = this->get_page_size(); + m_extra_offset = (offset - (offset / page_size) * page_size); + + //Store user values in memory + m_offset = offset; + m_size = size; + + //Update the mapping address + if(address){ + address = static_cast(address) - m_extra_offset; + } + + //Map it to the address space +// m_base = mmap64( (void*)address + m_base = mmap ( (void*)address + , static_cast(m_extra_offset + m_size) + , prot + , flags + , mapping.get_mapping_handle() + , offset - m_extra_offset); + + //Check if mapping was successful + if(m_base == MAP_FAILED){ + error_info err = system_error_code(); + this->priv_close(); + throw interprocess_exception(err); + } + + //Calculate new base for the user + void *old_base = m_base; + m_base = static_cast(m_base) + m_extra_offset; + m_offset = offset; + m_size = size; + + //Check for fixed mapping error + if(address && (old_base != (void*)address)){ + error_info err = system_error_code(); + this->priv_close(); + throw interprocess_exception(err); + } +} + +inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes) +{ + if(mapping_offset >= m_size || (mapping_offset+numbytes)> m_size){ + return false; + } + + if(numbytes == 0){ + numbytes = m_size - mapping_offset; + } + //Flush it all + return msync(static_cast(m_base)+mapping_offset, + numbytes, MS_SYNC) == 0; +} + +inline void mapped_region::priv_close() +{ + if(m_base != MAP_FAILED){ + this->flush(); + munmap(static_cast(m_base) - m_extra_offset, m_size + m_extra_offset); + m_base = MAP_FAILED; + } +} + +inline void mapped_region::dont_close_on_destruction() +{ m_base = MAP_FAILED; } + +#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + +template +const std::size_t mapped_region::page_size_holder::PageSize + = mapped_region::page_size_holder::get_page_size(); + +inline std::size_t mapped_region::get_page_size() +{ return page_size_holder<0>::PageSize; } + +inline void mapped_region::swap(mapped_region &other) +{ + detail::do_swap(this->m_base, other.m_base); + detail::do_swap(this->m_size, other.m_size); + detail::do_swap(this->m_offset, other.m_offset); + detail::do_swap(this->m_extra_offset, other.m_extra_offset); + #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + detail::do_swap(this->m_file_mapping_hnd, other.m_file_mapping_hnd); + #endif +} + +/// @cond + +//!No-op functor +struct null_mapped_region_function +{ + bool operator()(void *, std::size_t , bool) const + { return true; } +}; +/// @endcond + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_MAPPED_REGION_HPP + diff --git a/thirdparty/boost/interprocess/mem_algo/detail/mem_algo_common.hpp b/thirdparty/boost/interprocess/mem_algo/detail/mem_algo_common.hpp new file mode 100644 index 0000000..ad160bb --- /dev/null +++ b/thirdparty/boost/interprocess/mem_algo/detail/mem_algo_common.hpp @@ -0,0 +1,654 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_MEM_ALGO_COMMON_HPP +#define BOOST_INTERPROCESS_DETAIL_MEM_ALGO_COMMON_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Implements common operations for memory algorithms. + +namespace boost { +namespace interprocess { +namespace detail { + +template +struct multi_allocation_next +{ + typedef typename detail:: + pointer_to_other::type + multi_allocation_next_ptr; + + multi_allocation_next(multi_allocation_next_ptr n) + : next_(n) + {} + multi_allocation_next_ptr next_; +}; + +//!This iterator is returned by "allocate_many" functions so that +//!the user can access the multiple buffers allocated in a single call +template +class basic_multiallocation_iterator + : public std::iterator +{ + void unspecified_bool_type_func() const {} + typedef void (basic_multiallocation_iterator::*unspecified_bool_type)() const; + typedef typename detail:: + pointer_to_other + >::type + multi_allocation_next_ptr; + + public: + typedef char value_type; + typedef value_type & reference; + typedef value_type * pointer; + + basic_multiallocation_iterator() + : next_alloc_(0) + {} + + basic_multiallocation_iterator(multi_allocation_next_ptr next) + : next_alloc_(next) + {} + + basic_multiallocation_iterator &operator=(const basic_multiallocation_iterator &other) + { next_alloc_ = other.next_alloc_; return *this; } + + public: + basic_multiallocation_iterator& operator++() + { next_alloc_.next_ = detail::get_pointer(next_alloc_.next_->next_); return *this; } + + basic_multiallocation_iterator operator++(int) + { + basic_multiallocation_iterator result(next_alloc_.next_); + ++*this; + return result; + } + + bool operator== (const basic_multiallocation_iterator& other) const + { return next_alloc_.next_ == other.next_alloc_.next_; } + + bool operator!= (const basic_multiallocation_iterator& other) const + { return !operator== (other); } + + reference operator*() const + { return *((char*)detail::get_pointer(next_alloc_.next_)); } + + operator unspecified_bool_type() const + { return next_alloc_.next_? &basic_multiallocation_iterator::unspecified_bool_type_func : 0; } + + pointer operator->() const + { return &(*(*this)); } + + static basic_multiallocation_iterator create_simple_range(void *mem) + { + basic_multiallocation_iterator it; + typedef multi_allocation_next next_impl_t; + next_impl_t * tmp_mem = static_cast(mem); + it = basic_multiallocation_iterator(tmp_mem); + tmp_mem->next_ = 0; + return it; + } + + private: + multi_allocation_next next_alloc_; +}; + +template +class basic_multiallocation_chain +{ + private: + basic_multiallocation_iterator it_; + VoidPointer last_mem_; + std::size_t num_mem_; + + basic_multiallocation_chain(const basic_multiallocation_chain &); + basic_multiallocation_chain &operator=(const basic_multiallocation_chain &); + + public: + typedef basic_multiallocation_iterator multiallocation_iterator; + + basic_multiallocation_chain() + : it_(0), last_mem_(0), num_mem_(0) + {} + + void reset() + { + this->it_ = multiallocation_iterator(); + this->last_mem_ = 0; + this->num_mem_ = 0; + } + + void push_back(void *mem) + { + typedef multi_allocation_next next_impl_t; + next_impl_t * tmp_mem = static_cast(mem); + + if(!this->last_mem_){ + this->it_ = basic_multiallocation_iterator(tmp_mem); + } + else{ + static_cast(detail::get_pointer(this->last_mem_))->next_ = tmp_mem; + } + tmp_mem->next_ = 0; + this->last_mem_ = tmp_mem; + ++num_mem_; + } + + void push_front(void *mem) + { + typedef multi_allocation_next next_impl_t; + next_impl_t * tmp_mem = static_cast(mem); + ++num_mem_; + + if(!this->last_mem_){ + this->it_ = basic_multiallocation_iterator(tmp_mem); + tmp_mem->next_ = 0; + this->last_mem_ = tmp_mem; + } + else{ + next_impl_t * old_first = (next_impl_t*)(&*this->it_); + tmp_mem->next_ = old_first; + this->it_ = basic_multiallocation_iterator(tmp_mem); + } + } + + void swap(basic_multiallocation_chain &other_chain) + { + std::swap(this->it_, other_chain.it_); + std::swap(this->last_mem_, other_chain.last_mem_); + std::swap(this->num_mem_, other_chain.num_mem_); + } + + void splice_back(basic_multiallocation_chain &other_chain) + { + typedef multi_allocation_next next_impl_t; + multiallocation_iterator end_it; + multiallocation_iterator other_it = other_chain.get_it(); + multiallocation_iterator this_it = this->get_it(); + if(end_it == other_it){ + return; + } + else if(end_it == this_it){ + this->swap(other_chain); + } + else{ + static_cast(detail::get_pointer(this->last_mem_))->next_ + = (next_impl_t*)&*other_chain.it_; + this->last_mem_ = other_chain.last_mem_; + this->num_mem_ += other_chain.num_mem_; + } + } + + void *pop_front() + { + multiallocation_iterator itend; + if(this->it_ == itend){ + this->last_mem_= 0; + this->num_mem_ = 0; + return 0; + } + else{ + void *addr = &*it_; + ++it_; + --num_mem_; + if(!num_mem_){ + this->last_mem_ = 0; + this->it_ = multiallocation_iterator(); + } + return addr; + } + } + + bool empty() const + { return !num_mem_; } + + multiallocation_iterator get_it() const + { return it_; } + + std::size_t size() const + { return num_mem_; } +}; + + +//!This class implements several allocation functions shared by different algorithms +//!(aligned allocation, multiple allocation...). +template +class memory_algorithm_common +{ + public: + typedef typename MemoryAlgorithm::void_pointer void_pointer; + typedef typename MemoryAlgorithm::block_ctrl block_ctrl; + typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator; + typedef multi_allocation_next multi_allocation_next_t; + typedef typename multi_allocation_next_t:: + multi_allocation_next_ptr multi_allocation_next_ptr; + typedef memory_algorithm_common this_type; + + static const std::size_t Alignment = MemoryAlgorithm::Alignment; + static const std::size_t MinBlockUnits = MemoryAlgorithm::MinBlockUnits; + static const std::size_t AllocatedCtrlBytes = MemoryAlgorithm::AllocatedCtrlBytes; + static const std::size_t AllocatedCtrlUnits = MemoryAlgorithm::AllocatedCtrlUnits; + static const std::size_t BlockCtrlBytes = MemoryAlgorithm::BlockCtrlBytes; + static const std::size_t BlockCtrlUnits = MemoryAlgorithm::BlockCtrlUnits; + static const std::size_t UsableByPreviousChunk = MemoryAlgorithm::UsableByPreviousChunk; + + static void assert_alignment(const void *ptr) + { assert_alignment((std::size_t)ptr); } + + static void assert_alignment(std::size_t uint_ptr) + { + (void)uint_ptr; + BOOST_ASSERT(uint_ptr % Alignment == 0); + } + + static bool check_alignment(const void *ptr) + { return (((std::size_t)ptr) % Alignment == 0); } + + static std::size_t ceil_units(std::size_t size) + { return detail::get_rounded_size(size, Alignment)/Alignment; } + + static std::size_t floor_units(std::size_t size) + { return size/Alignment; } + + static std::size_t multiple_of_units(std::size_t size) + { return detail::get_rounded_size(size, Alignment); } + + static multiallocation_iterator allocate_many + (MemoryAlgorithm *memory_algo, std::size_t elem_bytes, std::size_t n_elements) + { + return this_type::priv_allocate_many(memory_algo, &elem_bytes, n_elements, 0); + } + + static multiallocation_iterator allocate_many + ( MemoryAlgorithm *memory_algo + , const std::size_t *elem_sizes + , std::size_t n_elements + , std::size_t sizeof_element) + { + return this_type::priv_allocate_many(memory_algo, elem_sizes, n_elements, sizeof_element); + } + + static void* allocate_aligned + (MemoryAlgorithm *memory_algo, std::size_t nbytes, std::size_t alignment) + { + + //Ensure power of 2 + if ((alignment & (alignment - std::size_t(1u))) != 0){ + //Alignment is not power of two + BOOST_ASSERT((alignment & (alignment - std::size_t(1u))) == 0); + return 0; + } + + std::size_t real_size; + if(alignment <= Alignment){ + return memory_algo->priv_allocate(allocate_new, nbytes, nbytes, real_size).first; + } + + if(nbytes > UsableByPreviousChunk) + nbytes -= UsableByPreviousChunk; + + //We can find a aligned portion if we allocate a chunk that has alignment + //nbytes + alignment bytes or more. + std::size_t minimum_allocation = max_value + (nbytes + alignment, std::size_t(MinBlockUnits*Alignment)); + //Since we will split that chunk, we must request a bit more memory + //if the alignment is near the beginning of the buffer, because otherwise, + //there is no space for a new chunk before the alignment. + // + // ____ Aligned here + // | + // ----------------------------------------------------- + // | MBU | + // ----------------------------------------------------- + std::size_t request = + minimum_allocation + (2*MinBlockUnits*Alignment - AllocatedCtrlBytes + //prevsize - UsableByPreviousChunk + ); + + //Now allocate the buffer + void *buffer = memory_algo->priv_allocate(allocate_new, request, request, real_size).first; + if(!buffer){ + return 0; + } + else if ((((std::size_t)(buffer)) % alignment) == 0){ + //If we are lucky and the buffer is aligned, just split it and + //return the high part + block_ctrl *first = memory_algo->priv_get_block(buffer); + std::size_t old_size = first->m_size; + const std::size_t first_min_units = + max_value(ceil_units(nbytes) + AllocatedCtrlUnits, std::size_t(MinBlockUnits)); + //We can create a new block in the end of the segment + if(old_size >= (first_min_units + MinBlockUnits)){ + //block_ctrl *second = new((char*)first + Alignment*first_min_units) block_ctrl; + block_ctrl *second = (block_ctrl *)((char*)first + Alignment*first_min_units); + first->m_size = first_min_units; + second->m_size = old_size - first->m_size; + BOOST_ASSERT(second->m_size >= MinBlockUnits); + memory_algo->priv_mark_new_allocated_block(first); + //memory_algo->priv_tail_size(first, first->m_size); + memory_algo->priv_mark_new_allocated_block(second); + memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(second)); + } + return buffer; + } + + //Buffer not aligned, find the aligned part. + // + // ____ Aligned here + // | + // ----------------------------------------------------- + // | MBU +more | ACB | + // ----------------------------------------------------- + char *pos = (char*) + ((std::size_t)((char*)buffer + + //This is the minimum size of (2) + (MinBlockUnits*Alignment - AllocatedCtrlBytes) + + //This is the next MBU for the aligned memory + AllocatedCtrlBytes + + //This is the alignment trick + alignment - 1) & -alignment); + + //Now obtain the address of the blocks + block_ctrl *first = memory_algo->priv_get_block(buffer); + block_ctrl *second = memory_algo->priv_get_block(pos); + assert(pos <= ((char*)first + first->m_size*Alignment)); + assert(first->m_size >= 2*MinBlockUnits); + assert((pos + MinBlockUnits*Alignment - AllocatedCtrlBytes + nbytes*Alignment/Alignment) <= ((char*)first + first->m_size*Alignment)); + //Set the new size of the first block + std::size_t old_size = first->m_size; + first->m_size = ((char*)second - (char*)first)/Alignment; + memory_algo->priv_mark_new_allocated_block(first); + + //Now check if we can create a new buffer in the end + // + // __"second" block + // | __Aligned here + // | | __"third" block + // -----------|-----|-----|------------------------------ + // | MBU +more | ACB | (3) | BCU | + // ----------------------------------------------------- + //This size will be the minimum size to be able to create a + //new chunk in the end. + const std::size_t second_min_units = max_value(std::size_t(MinBlockUnits), + ceil_units(nbytes) + AllocatedCtrlUnits ); + + //Check if we can create a new block (of size MinBlockUnits) in the end of the segment + if((old_size - first->m_size) >= (second_min_units + MinBlockUnits)){ + //Now obtain the address of the end block + block_ctrl *third = new ((char*)second + Alignment*second_min_units)block_ctrl; + second->m_size = second_min_units; + third->m_size = old_size - first->m_size - second->m_size; + BOOST_ASSERT(third->m_size >= MinBlockUnits); + memory_algo->priv_mark_new_allocated_block(second); + memory_algo->priv_mark_new_allocated_block(third); + memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(third)); + } + else{ + second->m_size = old_size - first->m_size; + assert(second->m_size >= MinBlockUnits); + memory_algo->priv_mark_new_allocated_block(second); + } + + memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(first)); + return memory_algo->priv_get_user_buffer(second); + } + + static bool try_shrink + (MemoryAlgorithm *memory_algo, void *ptr + ,const std::size_t max_size, const std::size_t preferred_size + ,std::size_t &received_size) + { + (void)memory_algo; + //Obtain the real block + block_ctrl *block = memory_algo->priv_get_block(ptr); + std::size_t old_block_units = block->m_size; + + //The block must be marked as allocated + BOOST_ASSERT(memory_algo->priv_is_allocated_block(block)); + + //Check if alignment and block size are right + assert_alignment(ptr); + + //Put this to a safe value + received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk; + + //Now translate it to Alignment units + const std::size_t max_user_units = floor_units(max_size - UsableByPreviousChunk); + const std::size_t preferred_user_units = ceil_units(preferred_size - UsableByPreviousChunk); + + //Check if rounded max and preferred are possible correct + if(max_user_units < preferred_user_units) + return false; + + //Check if the block is smaller than the requested minimum + std::size_t old_user_units = old_block_units - AllocatedCtrlUnits; + + if(old_user_units < preferred_user_units) + return false; + + //If the block is smaller than the requested minimum + if(old_user_units == preferred_user_units) + return true; + + std::size_t shrunk_user_units = + ((BlockCtrlUnits - AllocatedCtrlUnits) > preferred_user_units) + ? (BlockCtrlUnits - AllocatedCtrlUnits) + : preferred_user_units; + + //Some parameter checks + if(max_user_units < shrunk_user_units) + return false; + + //We must be able to create at least a new empty block + if((old_user_units - shrunk_user_units) < BlockCtrlUnits ){ + return false; + } + + //Update new size + received_size = shrunk_user_units*Alignment + UsableByPreviousChunk; + return true; + } + + static bool shrink + (MemoryAlgorithm *memory_algo, void *ptr + ,const std::size_t max_size, const std::size_t preferred_size + ,std::size_t &received_size) + { + //Obtain the real block + block_ctrl *block = memory_algo->priv_get_block(ptr); + std::size_t old_block_units = block->m_size; + + if(!try_shrink + (memory_algo, ptr, max_size, preferred_size, received_size)){ + return false; + } + + //Check if the old size was just the shrunk size (no splitting) + if((old_block_units - AllocatedCtrlUnits) == ceil_units(preferred_size - UsableByPreviousChunk)) + return true; + + //Now we can just rewrite the size of the old buffer + block->m_size = (received_size-UsableByPreviousChunk)/Alignment + AllocatedCtrlUnits; + BOOST_ASSERT(block->m_size >= BlockCtrlUnits); + + //We create the new block +// block_ctrl *new_block = new(reinterpret_cast +// (detail::char_ptr_cast(block) + block->m_size*Alignment)) block_ctrl; + block_ctrl *new_block = reinterpret_cast + (detail::char_ptr_cast(block) + block->m_size*Alignment); + //Write control data to simulate this new block was previously allocated + //and deallocate it + new_block->m_size = old_block_units - block->m_size; + BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits); + memory_algo->priv_mark_new_allocated_block(block); + memory_algo->priv_mark_new_allocated_block(new_block); + memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(new_block)); + return true; + } + + private: + static multiallocation_iterator priv_allocate_many + ( MemoryAlgorithm *memory_algo + , const std::size_t *elem_sizes + , std::size_t n_elements + , std::size_t sizeof_element) + { + //Note: sizeof_element == 0 indicates that we want to + //allocate n_elements of the same size "*elem_sizes" + + //Calculate the total size of all requests + std::size_t total_request_units = 0; + std::size_t elem_units = 0; + const std::size_t ptr_size_units = memory_algo->priv_get_total_units(sizeof(multi_allocation_next_ptr)); + if(!sizeof_element){ + elem_units = memory_algo->priv_get_total_units(*elem_sizes); + elem_units = ptr_size_units > elem_units ? ptr_size_units : elem_units; + total_request_units = n_elements*elem_units; + } + else{ + for(std::size_t i = 0; i < n_elements; ++i){ + elem_units = memory_algo->priv_get_total_units(elem_sizes[i]*sizeof_element); + elem_units = ptr_size_units > elem_units ? ptr_size_units : elem_units; + total_request_units += elem_units; + } + } + + multi_allocation_next_ptr first = 0, previous = 0; + std::size_t low_idx = 0; + while(low_idx < n_elements){ + std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk; + std::size_t min_allocation = (!sizeof_element) + ? elem_units + : memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element); + min_allocation = min_allocation*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk; + + std::size_t received_size; + std::pair ret = memory_algo->priv_allocate + (allocate_new, min_allocation, total_bytes, received_size, 0); + if(!ret.first){ + break; + } + + block_ctrl *block = memory_algo->priv_get_block(ret.first); + std::size_t received_units = block->m_size; + char *block_address = (char*)block; + + std::size_t total_used_units = 0; +// block_ctrl *prev_block = 0; + while(total_used_units < received_units){ + if(sizeof_element){ + elem_units = memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element); + elem_units = ptr_size_units > elem_units ? ptr_size_units : elem_units; + } + if(total_used_units + elem_units > received_units) + break; + total_request_units -= elem_units; + //This is the position where the new block must be created +// if(prev_block) +// memory_algo->priv_mark_new_allocated_block(prev_block); + block_ctrl *new_block = (block_ctrl *)(block_address); +// block_ctrl *new_block = new(block_address)block_ctrl; + assert_alignment(new_block); + + //The last block should take all the remaining space + if((low_idx + 1) == n_elements || + (total_used_units + elem_units + + ((!sizeof_element) + ? elem_units + : memory_algo->priv_get_total_units(elem_sizes[low_idx+1]*sizeof_element)) + ) > received_units){ + //By default, the new block will use the rest of the buffer + new_block->m_size = received_units - total_used_units; + memory_algo->priv_mark_new_allocated_block(new_block); + + //If the remaining units are bigger than needed and we can + //split it obtaining a new free memory block do it. + if((received_units - total_used_units) >= (elem_units + MemoryAlgorithm::BlockCtrlUnits)){ + std::size_t shrunk_received; + std::size_t shrunk_request = elem_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk; + bool shrink_ok = shrink + (memory_algo + ,memory_algo->priv_get_user_buffer(new_block) + ,shrunk_request + ,shrunk_request + ,shrunk_received); + (void)shrink_ok; + //Shrink must always succeed with passed parameters + BOOST_ASSERT(shrink_ok); + //Some sanity checks + BOOST_ASSERT(shrunk_request == shrunk_received); + BOOST_ASSERT(elem_units == ((shrunk_request-UsableByPreviousChunk)/Alignment + AllocatedCtrlUnits)); + //"new_block->m_size" must have been reduced to elem_units by "shrink" + BOOST_ASSERT(new_block->m_size == elem_units); + //Now update the total received units with the reduction + received_units = elem_units + total_used_units; + } + } + else{ + new_block->m_size = elem_units; + memory_algo->priv_mark_new_allocated_block(new_block); + } + + block_address += new_block->m_size*Alignment; + total_used_units += new_block->m_size; + //Check we have enough room to overwrite the intrusive pointer + assert((new_block->m_size*Alignment - AllocatedCtrlUnits) >= sizeof(multi_allocation_next_t)); + multi_allocation_next_ptr p = new(memory_algo->priv_get_user_buffer(new_block))multi_allocation_next_t(0); + + if(!first){ + first = p; + } + else{ + previous->next_ = p; + } + previous = p; + ++low_idx; + //prev_block = new_block; + } + //Sanity check + BOOST_ASSERT(total_used_units == received_units); + } + + if(low_idx != n_elements){ + while(first){ + multi_allocation_next_ptr prev = first; + first = first->next_; + memory_algo->priv_deallocate(detail::get_pointer(prev)); + } + return multiallocation_iterator(); + } + else{ + return multiallocation_iterator(first); + } + } +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MEM_ALGO_COMMON_HPP diff --git a/thirdparty/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp b/thirdparty/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp new file mode 100644 index 0000000..1d2ca73 --- /dev/null +++ b/thirdparty/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp @@ -0,0 +1,1098 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MEM_ALGO_DETAIL_SIMPLE_SEQ_FIT_IMPL_HPP +#define BOOST_INTERPROCESS_MEM_ALGO_DETAIL_SIMPLE_SEQ_FIT_IMPL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes sequential fit algorithm used to allocate objects in shared memory. +//!This class is intended as a base class for single segment and multi-segment +//!implementations. + +namespace boost { +namespace interprocess { +namespace detail { + +//!This class implements the simple sequential fit algorithm with a simply +//!linked list of free buffers. +//!This class is intended as a base class for single segment and multi-segment +//!implementations. +template +class simple_seq_fit_impl +{ + //Non-copyable + simple_seq_fit_impl(); + simple_seq_fit_impl(const simple_seq_fit_impl &); + simple_seq_fit_impl &operator=(const simple_seq_fit_impl &); + + public: + + //!Shared interprocess_mutex family used for the rest of the Interprocess framework + typedef MutexFamily mutex_family; + //!Pointer type to be used with the rest of the Interprocess framework + typedef VoidPointer void_pointer; + + typedef detail::basic_multiallocation_iterator + multiallocation_iterator; + typedef detail::basic_multiallocation_chain + multiallocation_chain; + + private: + class block_ctrl; + typedef typename detail:: + pointer_to_other::type block_ctrl_ptr; + + class block_ctrl; + friend class block_ctrl; + + //!Block control structure + class block_ctrl + { + public: + //!Offset pointer to the next block. + block_ctrl_ptr m_next; + //!This block's memory size (including block_ctrl + //!header) in BasicSize units + std::size_t m_size; + + std::size_t get_user_bytes() const + { return this->m_size*Alignment - BlockCtrlBytes; } + + std::size_t get_total_bytes() const + { return this->m_size*Alignment; } + }; + + //!Shared interprocess_mutex to protect memory allocate/deallocate + typedef typename MutexFamily::mutex_type interprocess_mutex; + + //!This struct includes needed data and derives from + //!interprocess_mutex to allow EBO when using null interprocess_mutex + struct header_t : public interprocess_mutex + { + //!Pointer to the first free block + block_ctrl m_root; + //!Allocated bytes for internal checking + std::size_t m_allocated; + //!The size of the memory segment + std::size_t m_size; + //!The extra size required by the segment + std::size_t m_extra_hdr_bytes; + } m_header; + + friend class detail::basic_multiallocation_iterator; + friend class detail::memory_algorithm_common; + + typedef detail::memory_algorithm_common algo_impl_t; + + public: + //!Constructor. "size" is the total size of the managed memory segment, + //!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit_impl) + //!offset that the allocator should not use at all. + simple_seq_fit_impl (std::size_t size, std::size_t extra_hdr_bytes); + + //!Destructor + ~simple_seq_fit_impl(); + + //!Obtains the minimum size needed by the algorithm + static std::size_t get_min_size (std::size_t extra_hdr_bytes); + + //Functions for single segment management + + //!Allocates bytes, returns 0 if there is not more memory + void* allocate (std::size_t nbytes); + + /// @cond + + //!Multiple element allocation, same size + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements); + + //!Multiple element allocation, different size + multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element); + + //!Multiple element deallocation + void deallocate_many(multiallocation_iterator it); + + /// @endcond + + //!Deallocates previously allocated bytes + void deallocate (void *addr); + + //!Returns the size of the memory segment + std::size_t get_size() const; + + //!Returns the number of free bytes of the memory segment + std::size_t get_free_memory() const; + + //!Increases managed memory in extra_size bytes more + void grow(std::size_t extra_size); + + //!Decreases managed memory as much as possible + void shrink_to_fit(); + + //!Returns true if all allocated memory has been deallocated + bool all_memory_deallocated(); + + //!Makes an internal sanity check and returns true if success + bool check_sanity(); + + //!Initializes to zero all the memory that's not in use. + //!This function is normally used for security reasons. + void zero_free_memory(); + + template + std::pair + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr = 0); + + std::pair + raw_allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + void *reuse_ptr = 0, std::size_t sizeof_object = 1); + + //!Returns the size of the buffer previously allocated pointed by ptr + std::size_t size(const void *ptr) const; + + //!Allocates aligned bytes, returns 0 if there is not more memory. + //!Alignment must be power of 2 + void* allocate_aligned (std::size_t nbytes, std::size_t alignment); + + private: + + //!Obtains the pointer returned to the user from the block control + static void *priv_get_user_buffer(const block_ctrl *block); + + //!Obtains the block control structure of the user buffer + static block_ctrl *priv_get_block(const void *ptr); + + //!Real allocation algorithm with min allocation option + std::pair priv_allocate(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr = 0); + + std::pair priv_allocation_command(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,std::size_t sizeof_object); + + //!Returns the number of total units that a user buffer + //!of "userbytes" bytes really occupies (including header) + static std::size_t priv_get_total_units(std::size_t userbytes); + + static std::size_t priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes); + std::size_t priv_block_end_offset() const; + + //!Returns next block if it's free. + //!Returns 0 if next block is not free. + block_ctrl *priv_next_block_if_free(block_ctrl *ptr); + + //!Check if this block is free (not allocated) + bool priv_is_allocated_block(block_ctrl *ptr); + + //!Returns previous block's if it's free. + //!Returns 0 if previous block is not free. + std::pairpriv_prev_block_if_free(block_ctrl *ptr); + + //!Real expand function implementation + bool priv_expand(void *ptr + ,std::size_t min_size, std::size_t preferred_size + ,std::size_t &received_size); + + //!Real expand to both sides implementation + void* priv_expand_both_sides(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,bool only_preferred_backwards); + + //!Real private aligned allocation function + //void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment); + + //!Checks if block has enough memory and splits/unlinks the block + //!returning the address to the users + void* priv_check_and_allocate(std::size_t units + ,block_ctrl* prev + ,block_ctrl* block + ,std::size_t &received_size); + //!Real deallocation algorithm + void priv_deallocate(void *addr); + + //!Makes a new memory portion available for allocation + void priv_add_segment(void *addr, std::size_t size); + + void priv_mark_new_allocated_block(block_ctrl *block); + + public: + static const std::size_t Alignment = detail::alignment_of::value; + private: + static const std::size_t BlockCtrlBytes = detail::ct_rounded_size::value; + static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment; + static const std::size_t MinBlockUnits = BlockCtrlUnits; + static const std::size_t MinBlockSize = MinBlockUnits*Alignment; + static const std::size_t AllocatedCtrlBytes = BlockCtrlBytes; + static const std::size_t AllocatedCtrlUnits = BlockCtrlUnits; + static const std::size_t UsableByPreviousChunk = 0; + + public: + static const std::size_t PayloadPerAllocation = BlockCtrlBytes; +}; + +template +inline std::size_t simple_seq_fit_impl + ::priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes) +{ + //First align "this" pointer + std::size_t uint_this = (std::size_t)this_ptr; + std::size_t uint_aligned_this = uint_this/Alignment*Alignment; + std::size_t this_disalignment = (uint_this - uint_aligned_this); + std::size_t block1_off = + detail::get_rounded_size(sizeof(simple_seq_fit_impl) + extra_hdr_bytes + this_disalignment, Alignment) + - this_disalignment; + algo_impl_t::assert_alignment(this_disalignment + block1_off); + return block1_off; +} + +template +inline std::size_t simple_seq_fit_impl + ::priv_block_end_offset() const +{ + //First align "this" pointer + std::size_t uint_this = (std::size_t)this; + std::size_t uint_aligned_this = uint_this/Alignment*Alignment; + std::size_t this_disalignment = (uint_this - uint_aligned_this); + std::size_t old_end = + detail::get_truncated_size(m_header.m_size + this_disalignment, Alignment) + - this_disalignment; + algo_impl_t::assert_alignment(old_end + this_disalignment); + return old_end; +} + +template +inline simple_seq_fit_impl:: + simple_seq_fit_impl(std::size_t size, std::size_t extra_hdr_bytes) +{ + //Initialize sizes and counters + m_header.m_allocated = 0; + m_header.m_size = size; + m_header.m_extra_hdr_bytes = extra_hdr_bytes; + + //Initialize pointers + std::size_t block1_off = priv_first_block_offset(this, extra_hdr_bytes); + m_header.m_root.m_next = reinterpret_cast + (detail::char_ptr_cast(this) + block1_off); + algo_impl_t::assert_alignment(detail::get_pointer(m_header.m_root.m_next)); + m_header.m_root.m_next->m_size = (size - block1_off)/Alignment; + m_header.m_root.m_next->m_next = &m_header.m_root; +} + +template +inline simple_seq_fit_impl::~simple_seq_fit_impl() +{ + //There is a memory leak! +// assert(m_header.m_allocated == 0); +// assert(m_header.m_root.m_next->m_next == block_ctrl_ptr(&m_header.m_root)); +} + +template +inline void simple_seq_fit_impl::grow(std::size_t extra_size) +{ + //Old highest address block's end offset + std::size_t old_end = this->priv_block_end_offset(); + + //Update managed buffer's size + m_header.m_size += extra_size; + + //We need at least MinBlockSize blocks to create a new block + if((m_header.m_size - old_end) < MinBlockSize){ + return; + } + + //We'll create a new free block with extra_size bytes + block_ctrl *new_block = reinterpret_cast + (detail::char_ptr_cast(this) + old_end); + + algo_impl_t::assert_alignment(new_block); + new_block->m_next = 0; + new_block->m_size = (m_header.m_size - old_end)/Alignment; + m_header.m_allocated += new_block->m_size*Alignment; + this->priv_deallocate(priv_get_user_buffer(new_block)); +} + +template +void simple_seq_fit_impl::shrink_to_fit() +{ + //Get the root and the first memory block + block_ctrl *prev = &m_header.m_root; + block_ctrl *last = &m_header.m_root; + block_ctrl *block = detail::get_pointer(last->m_next); + block_ctrl *root = &m_header.m_root; + + //No free block? + if(block == root) return; + + //Iterate through the free block list + while(block != root){ + prev = last; + last = block; + block = detail::get_pointer(block->m_next); + } + + char *last_free_end_address = (char*)last + last->m_size*Alignment; + if(last_free_end_address != ((char*)this + priv_block_end_offset())){ + //there is an allocated block in the end of this block + //so no shrinking is possible + return; + } + + //Check if have only 1 big free block + void *unique_block = 0; + if(!m_header.m_allocated){ + assert(prev == root); + std::size_t ignore; + unique_block = priv_allocate(allocate_new, 0, 0, ignore).first; + if(!unique_block) + return; + last = detail::get_pointer(m_header.m_root.m_next); + assert(last_free_end_address == ((char*)last + last->m_size*Alignment)); + } + std::size_t last_units = last->m_size; + + std::size_t received_size; + void *addr = priv_check_and_allocate(last_units, prev, last, received_size); + (void)addr; + assert(addr); + assert(received_size == last_units*Alignment - AllocatedCtrlBytes); + + //Shrink it + m_header.m_size /= Alignment; + m_header.m_size -= last->m_size; + m_header.m_size *= Alignment; + m_header.m_allocated -= last->m_size*Alignment; + + if(unique_block) + priv_deallocate(unique_block); +} + +template +inline void simple_seq_fit_impl:: + priv_mark_new_allocated_block(block_ctrl *new_block) +{ + new_block->m_next = 0; +} + +template +inline +typename simple_seq_fit_impl::block_ctrl * + simple_seq_fit_impl::priv_get_block(const void *ptr) +{ + return reinterpret_cast(detail::char_ptr_cast(ptr) - AllocatedCtrlBytes); +} + +template +inline +void *simple_seq_fit_impl:: + priv_get_user_buffer(const typename simple_seq_fit_impl::block_ctrl *block) +{ return detail::char_ptr_cast(block) + AllocatedCtrlBytes; } + +template +inline void simple_seq_fit_impl::priv_add_segment(void *addr, std::size_t size) +{ + algo_impl_t::assert_alignment(addr); + //Check size + assert(!(size < MinBlockSize)); + if(size < MinBlockSize) + return; + //Construct big block using the new segment + block_ctrl *new_block = static_cast(addr); + new_block->m_size = size/Alignment; + new_block->m_next = 0; + //Simulate this block was previously allocated + m_header.m_allocated += new_block->m_size*Alignment; + //Return block and insert it in the free block list + this->priv_deallocate(priv_get_user_buffer(new_block)); +} + +template +inline std::size_t simple_seq_fit_impl::get_size() const + { return m_header.m_size; } + +template +inline std::size_t simple_seq_fit_impl::get_free_memory() const +{ + return m_header.m_size - m_header.m_allocated - + algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes); +} + +template +inline std::size_t simple_seq_fit_impl:: + get_min_size (std::size_t extra_hdr_bytes) +{ + return detail::get_rounded_size(sizeof(simple_seq_fit_impl),Alignment) + + detail::get_rounded_size(extra_hdr_bytes,Alignment) + + MinBlockSize; +} + +template +inline bool simple_seq_fit_impl:: + all_memory_deallocated() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return m_header.m_allocated == 0 && + detail::get_pointer(m_header.m_root.m_next->m_next) == &m_header.m_root; +} + +template +inline void simple_seq_fit_impl::zero_free_memory() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + block_ctrl *block = detail::get_pointer(m_header.m_root.m_next); + + //Iterate through all free portions + do{ + //Just clear user the memory part reserved for the user + std::memset( priv_get_user_buffer(block) + , 0 + , block->get_user_bytes()); + block = detail::get_pointer(block->m_next); + } + while(block != &m_header.m_root); +} + +template +inline bool simple_seq_fit_impl:: + check_sanity() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + block_ctrl *block = detail::get_pointer(m_header.m_root.m_next); + + std::size_t free_memory = 0; + + //Iterate through all blocks obtaining their size + while(block != &m_header.m_root){ + algo_impl_t::assert_alignment(block); + if(!algo_impl_t::check_alignment(block)) + return false; + //Free blocks's next must be always valid + block_ctrl *next = detail::get_pointer(block->m_next); + if(!next){ + return false; + } + free_memory += block->m_size*Alignment; + block = next; + } + + //Check allocated bytes are less than size + if(m_header.m_allocated > m_header.m_size){ + return false; + } + + //Check free bytes are less than size + if(free_memory > m_header.m_size){ + return false; + } + return true; +} + +template +inline void* simple_seq_fit_impl:: + allocate(std::size_t nbytes) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + std::size_t ignore; + return priv_allocate(allocate_new, nbytes, nbytes, ignore).first; +} + +template +inline void* simple_seq_fit_impl:: + allocate_aligned(std::size_t nbytes, std::size_t alignment) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t:: + allocate_aligned(this, nbytes, alignment); +} + +template +template +inline std::pair simple_seq_fit_impl:: + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr) +{ + std::pair ret = priv_allocation_command + (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T)); + + BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of::value)); + return std::pair(static_cast(ret.first), ret.second); +} + +template +inline std::pair simple_seq_fit_impl:: + raw_allocation_command (allocation_type command, std::size_t limit_objects, + std::size_t preferred_objects,std::size_t &received_objects, + void *reuse_ptr, std::size_t sizeof_object) +{ + if(!sizeof_object) + return std::pair(0, 0); + if(command & try_shrink_in_place){ + bool success = algo_impl_t::try_shrink + ( this, reuse_ptr, limit_objects*sizeof_object + , preferred_objects*sizeof_object, received_objects); + received_objects /= sizeof_object; + return std::pair ((success ? reuse_ptr : 0), true); + } + return priv_allocation_command + (command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object); +} + +template +inline std::pair simple_seq_fit_impl:: + priv_allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size, std::size_t &received_size, + void *reuse_ptr, std::size_t sizeof_object) +{ + command &= ~expand_bwd; + if(!command) return std::pair(0, false); + + std::pair ret; + std::size_t max_count = m_header.m_size/sizeof_object; + if(limit_size > max_count || preferred_size > max_count){ + ret.first = 0; return ret; + } + std::size_t l_size = limit_size*sizeof_object; + std::size_t p_size = preferred_size*sizeof_object; + std::size_t r_size; + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + ret = priv_allocate(command, l_size, p_size, r_size, reuse_ptr); + } + received_size = r_size/sizeof_object; + return ret; +} + +template +inline std::size_t simple_seq_fit_impl:: + size(const void *ptr) const +{ + //We need no synchronization since this block is not going + //to be modified + //Obtain the real size of the block + block_ctrl *block = reinterpret_cast + (priv_get_block(detail::char_ptr_cast(const_cast(ptr)))); + return block->get_user_bytes(); +} + +template +void* simple_seq_fit_impl:: + priv_expand_both_sides(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,bool only_preferred_backwards) +{ + typedef std::pair prev_block_t; + block_ctrl *reuse = priv_get_block(reuse_ptr); + received_size = 0; + + if(this->size(reuse_ptr) > min_size){ + received_size = this->size(reuse_ptr); + return reuse_ptr; + } + + if(command & expand_fwd){ + if(priv_expand(reuse_ptr, min_size, preferred_size, received_size)) + return reuse_ptr; + } + else{ + received_size = this->size(reuse_ptr); + } + if(command & expand_bwd){ + std::size_t extra_forward = !received_size ? 0 : received_size + BlockCtrlBytes; + prev_block_t prev_pair = priv_prev_block_if_free(reuse); + block_ctrl *prev = prev_pair.second; + if(!prev){ + return 0; + } + + std::size_t needs_backwards = + detail::get_rounded_size(preferred_size - extra_forward, Alignment); + + if(!only_preferred_backwards){ + max_value(detail::get_rounded_size(min_size - extra_forward, Alignment) + ,min_value(prev->get_user_bytes(), needs_backwards)); + } + + //Check if previous block has enough size + if((prev->get_user_bytes()) >= needs_backwards){ + //Now take all next space. This will succeed + if(!priv_expand(reuse_ptr, received_size, received_size, received_size)){ + assert(0); + } + + //We need a minimum size to split the previous one + if((prev->get_user_bytes() - needs_backwards) > 2*BlockCtrlBytes){ + block_ctrl *new_block = reinterpret_cast + (detail::char_ptr_cast(reuse) - needs_backwards - BlockCtrlBytes); + new_block->m_next = 0; + new_block->m_size = + BlockCtrlUnits + (needs_backwards + extra_forward)/Alignment; + prev->m_size = + (prev->get_total_bytes() - needs_backwards)/Alignment - BlockCtrlUnits; + received_size = needs_backwards + extra_forward; + m_header.m_allocated += needs_backwards + BlockCtrlBytes; + return priv_get_user_buffer(new_block); + } + else{ + //Just merge the whole previous block + block_ctrl *prev_2_block = prev_pair.first; + //Update received size and allocation + received_size = extra_forward + prev->get_user_bytes(); + m_header.m_allocated += prev->get_total_bytes(); + //Now unlink it from previous block + prev_2_block->m_next = prev->m_next; + prev->m_size = reuse->m_size + prev->m_size; + prev->m_next = 0; + priv_get_user_buffer(prev); + } + } + } + return 0; +} + +template +inline typename simple_seq_fit_impl::multiallocation_iterator + simple_seq_fit_impl:: + allocate_many(std::size_t elem_bytes, std::size_t num_elements) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t:: + allocate_many(this, elem_bytes, num_elements); +} + +template +inline void simple_seq_fit_impl:: + deallocate_many(typename simple_seq_fit_impl::multiallocation_iterator it) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + while(it){ + void *addr = &*it; + ++it; + this->priv_deallocate(addr); + } +} + +template +inline typename simple_seq_fit_impl::multiallocation_iterator + simple_seq_fit_impl:: + allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element); +} + +template +inline std::size_t simple_seq_fit_impl:: + priv_get_total_units(std::size_t userbytes) +{ + std::size_t s = detail::get_rounded_size(userbytes, Alignment)/Alignment; + if(!s) ++s; + return BlockCtrlUnits + s; +} + +template +std::pair simple_seq_fit_impl:: + priv_allocate(allocation_type command + ,std::size_t limit_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr) +{ + if(command & shrink_in_place){ + bool success = + algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size); + return std::pair ((success ? reuse_ptr : 0), true); + } + typedef std::pair return_type; + received_size = 0; + + if(limit_size > preferred_size) + return return_type(0, false); + + //Number of units to request (including block_ctrl header) + std::size_t nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits; + + //Get the root and the first memory block + block_ctrl *prev = &m_header.m_root; + block_ctrl *block = detail::get_pointer(prev->m_next); + block_ctrl *root = &m_header.m_root; + block_ctrl *biggest_block = 0; + block_ctrl *prev_biggest_block = 0; + std::size_t biggest_size = 0; + + //Expand in place + //reuse_ptr, limit_size, preferred_size, received_size + // + if(reuse_ptr && (command & (expand_fwd | expand_bwd))){ + void *ret = priv_expand_both_sides + (command, limit_size, preferred_size, received_size, reuse_ptr, true); + if(ret){ + algo_impl_t::assert_alignment(ret); + return return_type(ret, true); + } + } + + if(command & allocate_new){ + received_size = 0; + while(block != root){ + //Update biggest block pointers + if(block->m_size > biggest_size){ + prev_biggest_block = prev; + biggest_size = block->m_size; + biggest_block = block; + } + algo_impl_t::assert_alignment(block); + void *addr = this->priv_check_and_allocate(nunits, prev, block, received_size); + if(addr){ + algo_impl_t::assert_alignment(addr); + return return_type(addr, false); + } + //Bad luck, let's check next block + prev = block; + block = detail::get_pointer(block->m_next); + } + + //Bad luck finding preferred_size, now if we have any biggest_block + //try with this block + if(biggest_block){ + std::size_t limit_units = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits; + if(biggest_block->m_size < limit_units) + return return_type(0, false); + + received_size = biggest_block->m_size*Alignment - BlockCtrlUnits; + void *ret = this->priv_check_and_allocate + (biggest_block->m_size, prev_biggest_block, biggest_block, received_size); + assert(ret != 0); + algo_impl_t::assert_alignment(ret); + return return_type(ret, false); + } + } + //Now try to expand both sides with min size + if(reuse_ptr && (command & (expand_fwd | expand_bwd))){ + return_type ret (priv_expand_both_sides + (command, limit_size, preferred_size, received_size, reuse_ptr, false), true); + algo_impl_t::assert_alignment(ret.first); + return ret; + } + return return_type(0, false); +} + +template inline +bool simple_seq_fit_impl::priv_is_allocated_block + (typename simple_seq_fit_impl::block_ctrl *block) +{ return block->m_next == 0; } + +template +inline typename simple_seq_fit_impl::block_ctrl * + simple_seq_fit_impl:: + priv_next_block_if_free + (typename simple_seq_fit_impl::block_ctrl *ptr) +{ + //Take the address where the next block should go + block_ctrl *next_block = reinterpret_cast + (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment); + + //Check if the adjacent block is in the managed segment + std::size_t distance = (detail::char_ptr_cast(next_block) - detail::char_ptr_cast(this))/Alignment; + if(distance >= (m_header.m_size/Alignment)){ + //"next_block" does not exist so we can't expand "block" + return 0; + } + + if(!next_block->m_next) + return 0; + + return next_block; +} + +template +inline + std::pair::block_ctrl * + ,typename simple_seq_fit_impl::block_ctrl *> + simple_seq_fit_impl:: + priv_prev_block_if_free + (typename simple_seq_fit_impl::block_ctrl *ptr) +{ + typedef std::pair prev_pair_t; + //Take the address where the previous block should go + block_ctrl *root = &m_header.m_root; + block_ctrl *prev_2_block = root; + block_ctrl *prev_block = detail::get_pointer(root->m_next); + while((detail::char_ptr_cast(prev_block) + prev_block->m_size*Alignment) + != (detail::char_ptr_cast(ptr)) + && prev_block != root){ + prev_2_block = prev_block; + prev_block = detail::get_pointer(prev_block->m_next); + } + + if(prev_block == root || !prev_block->m_next) + return prev_pair_t(0, 0); + + //Check if the previous block is in the managed segment + std::size_t distance = (detail::char_ptr_cast(prev_block) - detail::char_ptr_cast(this))/Alignment; + if(distance >= (m_header.m_size/Alignment)){ + //"previous_block" does not exist so we can't expand "block" + return prev_pair_t(0, 0); + } + return prev_pair_t(prev_2_block, prev_block); +} + + +template +inline bool simple_seq_fit_impl:: + priv_expand (void *ptr + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size) +{ + //Obtain the real size of the block + block_ctrl *block = reinterpret_cast(priv_get_block(ptr)); + std::size_t old_block_size = block->m_size; + + //All used blocks' next is marked with 0 so check it + assert(block->m_next == 0); + + //Put this to a safe value + received_size = old_block_size*Alignment - BlockCtrlBytes; + + //Now translate it to Alignment units + min_size = detail::get_rounded_size(min_size, Alignment)/Alignment; + preferred_size = detail::get_rounded_size(preferred_size, Alignment)/Alignment; + + //Some parameter checks + if(min_size > preferred_size) + return false; + + std::size_t data_size = old_block_size - BlockCtrlUnits; + + if(data_size >= min_size) + return true; + + block_ctrl *next_block = priv_next_block_if_free(block); + if(!next_block){ + return false; + } + + //Is "block" + "next_block" big enough? + std::size_t merged_size = old_block_size + next_block->m_size; + + //Now we can expand this block further than before + received_size = merged_size*Alignment - BlockCtrlBytes; + + if(merged_size < (min_size + BlockCtrlUnits)){ + return false; + } + + //We can fill expand. Merge both blocks, + block->m_next = next_block->m_next; + block->m_size = merged_size; + + //Find the previous free block of next_block + block_ctrl *prev = &m_header.m_root; + while(detail::get_pointer(prev->m_next) != next_block){ + prev = detail::get_pointer(prev->m_next); + } + + //Now insert merged block in the free list + //This allows reusing allocation logic in this function + m_header.m_allocated -= old_block_size*Alignment; + prev->m_next = block; + + //Now use check and allocate to do the allocation logic + preferred_size += BlockCtrlUnits; + std::size_t nunits = preferred_size < merged_size ? preferred_size : merged_size; + + //This must success since nunits is less than merged_size! + if(!this->priv_check_and_allocate (nunits, prev, block, received_size)){ + //Something very ugly is happening here. This is a bug + //or there is memory corruption + assert(0); + return false; + } + return true; +} + +template inline +void* simple_seq_fit_impl::priv_check_and_allocate + (std::size_t nunits + ,typename simple_seq_fit_impl::block_ctrl* prev + ,typename simple_seq_fit_impl::block_ctrl* block + ,std::size_t &received_size) +{ + std::size_t upper_nunits = nunits + BlockCtrlUnits; + bool found = false; + + if (block->m_size > upper_nunits){ + //This block is bigger than needed, split it in + //two blocks, the first's size will be "units" + //the second's size will be "block->m_size-units" + std::size_t total_size = block->m_size; + block->m_size = nunits; + block_ctrl *new_block = reinterpret_cast + (detail::char_ptr_cast(block) + Alignment*nunits); + new_block->m_size = total_size - nunits; + new_block->m_next = block->m_next; + prev->m_next = new_block; + found = true; + } + else if (block->m_size >= nunits){ + //This block has exactly the right size with an extra + //unusable extra bytes. + prev->m_next = block->m_next; + found = true; + } + + if(found){ + //We need block_ctrl for deallocation stuff, so + //return memory user can overwrite + m_header.m_allocated += block->m_size*Alignment; + received_size = block->get_user_bytes(); + //Mark the block as allocated + block->m_next = 0; + //Check alignment + algo_impl_t::assert_alignment(block); + return priv_get_user_buffer(block); + } + return 0; +} + +template +void simple_seq_fit_impl::deallocate(void* addr) +{ + if(!addr) return; + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return this->priv_deallocate(addr); +} + +template +void simple_seq_fit_impl::priv_deallocate(void* addr) +{ + if(!addr) return; + + //Let's get free block list. List is always sorted + //by memory address to allow block merging. + //Pointer next always points to the first + //(lower address) block + block_ctrl * prev = &m_header.m_root; + block_ctrl * pos = detail::get_pointer(m_header.m_root.m_next); + block_ctrl * block = reinterpret_cast(priv_get_block(addr)); + + //All used blocks' next is marked with 0 so check it + assert(block->m_next == 0); + + //Check if alignment and block size are right + algo_impl_t::assert_alignment(addr); + + std::size_t total_size = Alignment*block->m_size; + assert(m_header.m_allocated >= total_size); + + //Update used memory count + m_header.m_allocated -= total_size; + + //Let's find the previous and the next block of the block to deallocate + //This ordering comparison must be done with original pointers + //types since their mapping to raw pointers can be different + //in each process + while((detail::get_pointer(pos) != &m_header.m_root) && (block > pos)){ + prev = pos; + pos = detail::get_pointer(pos->m_next); + } + + //Try to combine with upper block + if ((detail::char_ptr_cast(detail::get_pointer(block)) + + Alignment*block->m_size) == + detail::char_ptr_cast(detail::get_pointer(pos))){ + + block->m_size += pos->m_size; + block->m_next = pos->m_next; + } + else{ + block->m_next = pos; + } + + //Try to combine with lower block + if ((detail::char_ptr_cast(detail::get_pointer(prev)) + + Alignment*prev->m_size) == + detail::char_ptr_cast(detail::get_pointer(block))){ + prev->m_size += block->m_size; + prev->m_next = block->m_next; + } + else{ + prev->m_next = block; + } +} + +} //namespace detail { + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MEM_ALGO_DETAIL_SIMPLE_SEQ_FIT_IMPL_HPP + diff --git a/thirdparty/boost/interprocess/mem_algo/rbtree_best_fit.hpp b/thirdparty/boost/interprocess/mem_algo/rbtree_best_fit.hpp new file mode 100644 index 0000000..6f5c52b --- /dev/null +++ b/thirdparty/boost/interprocess/mem_algo/rbtree_best_fit.hpp @@ -0,0 +1,1353 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MEM_ALGO_RBTREE_BEST_FIT_HPP +#define BOOST_INTERPROCESS_MEM_ALGO_RBTREE_BEST_FIT_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//#define BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY + +#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY +#include +#else +//#include +//#include +#include +#endif + +//!\file +//!Describes a best-fit algorithm based in an intrusive red-black tree used to allocate +//!objects in shared memory. This class is intended as a base class for single segment +//!and multi-segment implementations. + +namespace boost { +namespace interprocess { + +//!This class implements an algorithm that stores the free nodes in a red-black tree +//!to have logarithmic search/insert times. +template +class rbtree_best_fit +{ + /// @cond + //Non-copyable + rbtree_best_fit(); + rbtree_best_fit(const rbtree_best_fit &); + rbtree_best_fit &operator=(const rbtree_best_fit &); + /// @endcond + + public: + //!Shared interprocess_mutex family used for the rest of the Interprocess framework + typedef MutexFamily mutex_family; + //!Pointer type to be used with the rest of the Interprocess framework + typedef VoidPointer void_pointer; + typedef detail::basic_multiallocation_iterator + multiallocation_iterator; + typedef detail::basic_multiallocation_chain + multiallocation_chain; + + /// @cond + + private: + struct block_ctrl; + typedef typename detail:: + pointer_to_other::type block_ctrl_ptr; + typedef typename detail:: + pointer_to_other::type char_ptr; + +#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY + typedef typename bi::make_set_base_hook +#else +// typedef typename bi::make_splay_set_base_hook +// typedef typename bi::make_avl_set_base_hook + typedef typename bi::make_sg_set_base_hook +#endif + < bi::void_pointer + , bi::optimize_size + , bi::link_mode >::type TreeHook; + + typedef detail::multi_allocation_next multi_allocation_next_t; + typedef typename multi_allocation_next_t:: + multi_allocation_next_ptr multi_allocation_next_ptr; + + struct SizeHolder + { + //!This block's memory size (including block_ctrl + //!header) in Alignment units + std::size_t m_prev_size : sizeof(std::size_t)*CHAR_BIT; + std::size_t m_size : sizeof(std::size_t)*CHAR_BIT - 2; + std::size_t m_prev_allocated : 1; + std::size_t m_allocated : 1; + }; + + //!Block control structure + struct block_ctrl + : public SizeHolder, public TreeHook + { + block_ctrl() + { this->m_size = 0; this->m_allocated = 0, this->m_prev_allocated = 0; } + + friend bool operator<(const block_ctrl &a, const block_ctrl &b) + { return a.m_size < b.m_size; } + friend bool operator==(const block_ctrl &a, const block_ctrl &b) + { return a.m_size == b.m_size; } + }; + + struct size_block_ctrl_compare + { + bool operator()(std::size_t size, const block_ctrl &block) const + { return size < block.m_size; } + + bool operator()(const block_ctrl &block, std::size_t size) const + { return block.m_size < size; } + }; + + //!Shared interprocess_mutex to protect memory allocate/deallocate + typedef typename MutexFamily::mutex_type interprocess_mutex; +#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY + typedef typename bi::make_multiset +#else + //typedef typename bi::make_splay_multiset + //typedef typename bi::make_avl_multiset + typedef typename bi::make_sg_multiset +#endif + >::type Imultiset; + + typedef typename Imultiset::iterator imultiset_iterator; + + //!This struct includes needed data and derives from + //!interprocess_mutex to allow EBO when using null interprocess_mutex + struct header_t : public interprocess_mutex + { + Imultiset m_imultiset; + + //!The extra size required by the segment + std::size_t m_extra_hdr_bytes; + //!Allocated bytes for internal checking + std::size_t m_allocated; + //!The size of the memory segment + std::size_t m_size; + } m_header; + + friend class detail::basic_multiallocation_iterator; + friend class detail::memory_algorithm_common; + + typedef detail::memory_algorithm_common algo_impl_t; + + public: + /// @endcond + + //!Constructor. "size" is the total size of the managed memory segment, + //!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(rbtree_best_fit) + //!offset that the allocator should not use at all. + rbtree_best_fit (std::size_t size, std::size_t extra_hdr_bytes); + + //!Destructor. + ~rbtree_best_fit(); + + //!Obtains the minimum size needed by the algorithm + static std::size_t get_min_size (std::size_t extra_hdr_bytes); + + //Functions for single segment management + + //!Allocates bytes, returns 0 if there is not more memory + void* allocate (std::size_t nbytes); + + /// @cond + + //Experimental. Dont' use + + //!Multiple element allocation, same size + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements); + + //!Multiple element allocation, different size + multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element); + + //!Multiple element allocation, different size + void deallocate_many(multiallocation_iterator it); + + /// @endcond + + //!Deallocates previously allocated bytes + void deallocate (void *addr); + + //!Returns the size of the memory segment + std::size_t get_size() const; + + //!Returns the number of free bytes of the segment + std::size_t get_free_memory() const; + + //!Initializes to zero all the memory that's not in use. + //!This function is normally used for security reasons. + void zero_free_memory(); + + //!Increases managed memory in + //!extra_size bytes more + void grow(std::size_t extra_size); + + //!Decreases managed memory as much as possible + void shrink_to_fit(); + + //!Returns true if all allocated memory has been deallocated + bool all_memory_deallocated(); + + //!Makes an internal sanity check + //!and returns true if success + bool check_sanity(); + + template + std::pair + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr = 0); + + std::pair + raw_allocation_command (allocation_type command, std::size_t limit_object, + std::size_t preferred_object,std::size_t &received_object, + void *reuse_ptr = 0, std::size_t sizeof_object = 1); + + //!Returns the size of the buffer previously allocated pointed by ptr + std::size_t size(const void *ptr) const; + + //!Allocates aligned bytes, returns 0 if there is not more memory. + //!Alignment must be power of 2 + void* allocate_aligned (std::size_t nbytes, std::size_t alignment); + + /// @cond + private: + static std::size_t priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes); + + std::pair + priv_allocation_command(allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + void *reuse_ptr, std::size_t sizeof_object); + + + //!Real allocation algorithm with min allocation option + std::pair priv_allocate(allocation_type command + ,std::size_t limit_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr = 0 + ,std::size_t backwards_multiple = 1); + + //!Obtains the block control structure of the user buffer + static block_ctrl *priv_get_block(const void *ptr); + + //!Obtains the pointer returned to the user from the block control + static void *priv_get_user_buffer(const block_ctrl *block); + + //!Returns the number of total units that a user buffer + //!of "userbytes" bytes really occupies (including header) + static std::size_t priv_get_total_units(std::size_t userbytes); + + //!Real expand function implementation + bool priv_expand(void *ptr + ,const std::size_t min_size, const std::size_t preferred_size + ,std::size_t &received_size); + + //!Real expand to both sides implementation + void* priv_expand_both_sides(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,bool only_preferred_backwards + ,std::size_t backwards_multiple); + + //!Get poitner of the previous block (previous block must be free) + block_ctrl * priv_prev_block(block_ctrl *ptr); + + //!Returns true if the previous block is allocated + bool priv_is_prev_allocated(block_ctrl *ptr); + + //!Get a pointer of the "end" block from the first block of the segment + block_ctrl * priv_end_block(block_ctrl *first_segment_block); + + //!Get the size in the tail of the previous block + block_ctrl * priv_next_block(block_ctrl *ptr); + + //!Check if this block is free (not allocated) + bool priv_is_allocated_block(block_ctrl *ptr); + + //!Marks the block as allocated + void priv_mark_as_allocated_block(block_ctrl *ptr); + + //!Marks the block as allocated + void priv_mark_as_free_block(block_ctrl *ptr); + + //!Checks if block has enough memory and splits/unlinks the block + //!returning the address to the users + void* priv_check_and_allocate(std::size_t units + ,block_ctrl* block + ,std::size_t &received_size); + //!Real deallocation algorithm + void priv_deallocate(void *addr); + + //!Makes a new memory portion available for allocation + void priv_add_segment(void *addr, std::size_t size); + + void priv_mark_new_allocated_block(block_ctrl *block); + + public: + + static const std::size_t Alignment = !MemAlignment + ? detail::alignment_of::value + : MemAlignment + ; + + private: + //Due to embedded bits in size, Alignment must be at least 2 + BOOST_STATIC_ASSERT((Alignment >= 4)); + //Due to rbtree size optimizations, Alignment must have at least pointer alignment + BOOST_STATIC_ASSERT((Alignment >= detail::alignment_of::value)); + static const std::size_t AlignmentMask = (Alignment - 1); + static const std::size_t BlockCtrlBytes = detail::ct_rounded_size::value; + static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment; + static const std::size_t AllocatedCtrlBytes = detail::ct_rounded_size::value; + static const std::size_t AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment; + static const std::size_t EndCtrlBlockBytes = detail::ct_rounded_size::value; + static const std::size_t EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment; + static const std::size_t MinBlockUnits = BlockCtrlUnits; + static const std::size_t UsableByPreviousChunk = sizeof(std::size_t); + + //Make sure the maximum alignment is power of two + BOOST_STATIC_ASSERT((0 == (Alignment & (Alignment - std::size_t(1u))))); + /// @endcond + public: + static const std::size_t PayloadPerAllocation = AllocatedCtrlBytes - UsableByPreviousChunk; +}; + +template +inline std::size_t rbtree_best_fit + ::priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes) +{ + std::size_t uint_this = (std::size_t)this_ptr; + std::size_t main_hdr_end = uint_this + sizeof(rbtree_best_fit) + extra_hdr_bytes; + std::size_t aligned_main_hdr_end = detail::get_rounded_size(main_hdr_end, Alignment); + std::size_t block1_off = aligned_main_hdr_end - uint_this; + algo_impl_t::assert_alignment(aligned_main_hdr_end); + algo_impl_t::assert_alignment(uint_this + block1_off); + return block1_off; +} + +template +inline rbtree_best_fit:: + rbtree_best_fit(std::size_t size, std::size_t extra_hdr_bytes) +{ + //Initialize the header + m_header.m_allocated = 0; + m_header.m_size = size; + m_header.m_extra_hdr_bytes = extra_hdr_bytes; + + //Now write calculate the offset of the first big block that will + //cover the whole segment + assert(get_min_size(extra_hdr_bytes) <= size); + std::size_t block1_off = priv_first_block_offset(this, extra_hdr_bytes); + priv_add_segment(detail::char_ptr_cast(this) + block1_off, size - block1_off); +} + +template +inline rbtree_best_fit::~rbtree_best_fit() +{ + //There is a memory leak! +// assert(m_header.m_allocated == 0); +// assert(m_header.m_root.m_next->m_next == block_ctrl_ptr(&m_header.m_root)); +} + +template +void rbtree_best_fit::grow(std::size_t extra_size) +{ + //Get the address of the first block + std::size_t block1_off = + priv_first_block_offset(this, m_header.m_extra_hdr_bytes); + + block_ctrl *first_block = reinterpret_cast + (detail::char_ptr_cast(this) + block1_off); + block_ctrl *old_end_block = priv_end_block(first_block); + assert(priv_is_allocated_block(old_end_block)); + std::size_t old_border_offset = (detail::char_ptr_cast(old_end_block) - + detail::char_ptr_cast(this)) + EndCtrlBlockBytes; + + //Update managed buffer's size + m_header.m_size += extra_size; + + //We need at least MinBlockUnits blocks to create a new block +// assert((m_header.m_size - old_end) >= MinBlockUnits); + if((m_header.m_size - old_border_offset) < MinBlockUnits){ + return; + } + + //Now create a new block between the old end and the new end + std::size_t align_offset = (m_header.m_size - old_border_offset)/Alignment; + block_ctrl *new_end_block = reinterpret_cast + (detail::char_ptr_cast(old_end_block) + align_offset*Alignment); + new_end_block->m_size = (detail::char_ptr_cast(first_block) - + detail::char_ptr_cast(new_end_block))/Alignment; + first_block->m_prev_size = new_end_block->m_size; + assert(first_block == priv_next_block(new_end_block)); + priv_mark_new_allocated_block(new_end_block); + + assert(new_end_block == priv_end_block(first_block)); + + //The old end block is the new block + block_ctrl *new_block = old_end_block; + new_block->m_size = (detail::char_ptr_cast(new_end_block) - + detail::char_ptr_cast(new_block))/Alignment; + assert(new_block->m_size >= BlockCtrlUnits); + priv_mark_new_allocated_block(new_block); + assert(priv_next_block(new_block) == new_end_block); + + m_header.m_allocated += new_block->m_size*Alignment; + + //Now deallocate the newly created block + this->priv_deallocate(priv_get_user_buffer(new_block)); +} + +template +void rbtree_best_fit::shrink_to_fit() +{ + //Get the address of the first block + std::size_t block1_off = + priv_first_block_offset(this, m_header.m_extra_hdr_bytes); + + block_ctrl *first_block = reinterpret_cast + (detail::char_ptr_cast(this) + block1_off); + algo_impl_t::assert_alignment(first_block); + + block_ctrl *old_end_block = priv_end_block(first_block); + algo_impl_t::assert_alignment(old_end_block); + assert(priv_is_allocated_block(old_end_block)); + + algo_impl_t::assert_alignment(old_end_block); + + std::size_t old_end_block_size = old_end_block->m_size; + + void *unique_buffer = 0; + block_ctrl *last_block; + if(priv_next_block(first_block) == old_end_block){ + std::size_t ignore; + unique_buffer = priv_allocate(allocate_new, 0, 0, ignore).first; + if(!unique_buffer) + return; + algo_impl_t::assert_alignment(unique_buffer); + block_ctrl *unique_block = priv_get_block(unique_buffer); + assert(priv_is_allocated_block(unique_block)); + algo_impl_t::assert_alignment(unique_block); + last_block = priv_next_block(unique_block); + assert(!priv_is_allocated_block(last_block)); + algo_impl_t::assert_alignment(last_block); + } + else{ + if(priv_is_prev_allocated(old_end_block)) + return; + last_block = priv_prev_block(old_end_block); + } + + std::size_t last_block_size = last_block->m_size; + + //Erase block from the free tree, since we will erase it + m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block)); + + std::size_t shrunk_border_offset = (detail::char_ptr_cast(last_block) - + detail::char_ptr_cast(this)) + EndCtrlBlockBytes; + + block_ctrl *new_end_block = last_block; + algo_impl_t::assert_alignment(new_end_block); + new_end_block->m_size = old_end_block_size + last_block_size; + priv_mark_as_allocated_block(new_end_block); + + //Although the first block might be allocated, we'll + //store the offset to the end block since in the previous + //offset can't be overwritten by a previous block + first_block->m_prev_size = new_end_block->m_size; + assert(priv_end_block(first_block) == new_end_block); + + //Update managed buffer's size + m_header.m_size = shrunk_border_offset; + if(unique_buffer) + priv_deallocate(unique_buffer); +} + +template +void rbtree_best_fit:: + priv_add_segment(void *addr, std::size_t size) +{ + //Check alignment + algo_impl_t::check_alignment(addr); + //Check size + assert(size >= (BlockCtrlBytes + EndCtrlBlockBytes)); + + //Initialize the first big block and the "end" node + block_ctrl *first_big_block = new(addr)block_ctrl; + first_big_block->m_size = size/Alignment - EndCtrlBlockUnits; + assert(first_big_block->m_size >= BlockCtrlUnits); + + //The "end" node is just a node of size 0 with the "end" bit set + block_ctrl *end_block = static_cast + (new (reinterpret_cast + (detail::char_ptr_cast(addr) + first_big_block->m_size*Alignment))SizeHolder); + + //This will overwrite the prev part of the "end" node + priv_mark_as_free_block (first_big_block); + first_big_block->m_prev_size = end_block->m_size = + (detail::char_ptr_cast(first_big_block) - detail::char_ptr_cast(end_block))/Alignment; + priv_mark_as_allocated_block(end_block); + + assert(priv_next_block(first_big_block) == end_block); + assert(priv_next_block(end_block) == first_big_block); + assert(priv_end_block(first_big_block) == end_block); + assert(priv_prev_block(end_block) == first_big_block); + + //Some check to validate the algorithm, since it makes some assumptions + //to optimize the space wasted in bookkeeping: + + //Check that the sizes of the header are placed before the rbtree + assert((void*)(SizeHolder*)first_big_block < (void*)(TreeHook*)first_big_block); + + //Check that the alignment is power of two (we use some optimizations based on this) + //assert((Alignment % 2) == 0); + //Insert it in the intrusive containers + m_header.m_imultiset.insert(*first_big_block); +} + +template +inline void rbtree_best_fit:: + priv_mark_new_allocated_block(block_ctrl *new_block) +{ priv_mark_as_allocated_block(new_block); } + +template +inline std::size_t rbtree_best_fit::get_size() const +{ return m_header.m_size; } + +template +inline std::size_t rbtree_best_fit::get_free_memory() const +{ + return m_header.m_size - m_header.m_allocated - + priv_first_block_offset(this, m_header.m_extra_hdr_bytes); +} + +template +inline std::size_t rbtree_best_fit:: + get_min_size (std::size_t extra_hdr_bytes) +{ + return (algo_impl_t::ceil_units(sizeof(rbtree_best_fit)) + + algo_impl_t::ceil_units(extra_hdr_bytes) + + MinBlockUnits + EndCtrlBlockUnits)*Alignment; +} + +template +inline bool rbtree_best_fit:: + all_memory_deallocated() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + std::size_t block1_off = + priv_first_block_offset(this, m_header.m_extra_hdr_bytes); + + return m_header.m_allocated == 0 && + m_header.m_imultiset.begin() != m_header.m_imultiset.end() && + (++m_header.m_imultiset.begin()) == m_header.m_imultiset.end() + && m_header.m_imultiset.begin()->m_size == + (m_header.m_size - block1_off - EndCtrlBlockBytes)/Alignment; +} + +template +bool rbtree_best_fit:: + check_sanity() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + imultiset_iterator ib(m_header.m_imultiset.begin()), ie(m_header.m_imultiset.end()); + + std::size_t free_memory = 0; + + //Iterate through all blocks obtaining their size + for(; ib != ie; ++ib){ + free_memory += ib->m_size*Alignment; + algo_impl_t::assert_alignment(&*ib); + if(!algo_impl_t::check_alignment(&*ib)) + return false; + } + + //Check allocated bytes are less than size + if(m_header.m_allocated > m_header.m_size){ + return false; + } + + std::size_t block1_off = + priv_first_block_offset(this, m_header.m_extra_hdr_bytes); + + //Check free bytes are less than size + if(free_memory > (m_header.m_size - block1_off)){ + return false; + } + return true; +} + +template +inline void* rbtree_best_fit:: + allocate(std::size_t nbytes) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + std::size_t ignore; + void * ret = priv_allocate(allocate_new, nbytes, nbytes, ignore).first; + return ret; +} + +template +inline void* rbtree_best_fit:: + allocate_aligned(std::size_t nbytes, std::size_t alignment) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t::allocate_aligned(this, nbytes, alignment); +} + +template +template +inline std::pair rbtree_best_fit:: + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr) +{ + std::pair ret = priv_allocation_command + (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T)); + + BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of::value)); + return std::pair(static_cast(ret.first), ret.second); +} + +template +inline std::pair rbtree_best_fit:: + raw_allocation_command (allocation_type command, std::size_t limit_objects, + std::size_t preferred_objects,std::size_t &received_objects, + void *reuse_ptr, std::size_t sizeof_object) +{ + if(!sizeof_object) + return std::pair(0, 0); + if(command & try_shrink_in_place){ + bool success = algo_impl_t::try_shrink + ( this, reuse_ptr, limit_objects*sizeof_object + , preferred_objects*sizeof_object, received_objects); + received_objects /= sizeof_object; + return std::pair ((success ? reuse_ptr : 0), true); + } + return priv_allocation_command + (command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object); +} + + +template +inline std::pair rbtree_best_fit:: + priv_allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + void *reuse_ptr, std::size_t sizeof_object) +{ + std::pair ret; + std::size_t max_count = m_header.m_size/sizeof_object; + if(limit_size > max_count || preferred_size > max_count){ + ret.first = 0; return ret; + } + std::size_t l_size = limit_size*sizeof_object; + std::size_t p_size = preferred_size*sizeof_object; + std::size_t r_size; + { + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + ret = priv_allocate(command, l_size, p_size, r_size, reuse_ptr, sizeof_object); + } + received_size = r_size/sizeof_object; + return ret; +} + +template +inline std::size_t rbtree_best_fit:: + size(const void *ptr) const +{ + //We need no synchronization since this block's size is not going + //to be modified by anyone else + //Obtain the real size of the block + return (priv_get_block(ptr)->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk; +} + +template +inline void rbtree_best_fit::zero_free_memory() +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + imultiset_iterator ib(m_header.m_imultiset.begin()), ie(m_header.m_imultiset.end()); + + //Iterate through all blocks obtaining their size + for(; ib != ie; ++ib){ + //Just clear user the memory part reserved for the user + std::memset( detail::char_ptr_cast(&*ib) + BlockCtrlBytes + , 0 + , ib->m_size*Alignment - BlockCtrlBytes); + } +} + +template +void* rbtree_best_fit:: + priv_expand_both_sides(allocation_type command + ,std::size_t min_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,bool only_preferred_backwards + ,std::size_t backwards_multiple) +{ + algo_impl_t::assert_alignment(reuse_ptr); + if(command & expand_fwd){ + if(priv_expand(reuse_ptr, min_size, preferred_size, received_size)) + return reuse_ptr; + } + else{ + received_size = this->size(reuse_ptr); + if(received_size >= preferred_size || received_size >= min_size) + return reuse_ptr; + } + + if(backwards_multiple){ + BOOST_ASSERT(0 == (min_size % backwards_multiple)); + BOOST_ASSERT(0 == (preferred_size % backwards_multiple)); + } + + if(command & expand_bwd){ + //Obtain the real size of the block + block_ctrl *reuse = priv_get_block(reuse_ptr); + + //Sanity check + //assert(reuse->m_size == priv_tail_size(reuse)); + algo_impl_t::assert_alignment(reuse); + + block_ctrl *prev_block; + + //If the previous block is not free, there is nothing to do + if(priv_is_prev_allocated(reuse)){ + return 0; + } + + prev_block = priv_prev_block(reuse); + assert(!priv_is_allocated_block(prev_block)); + + //Some sanity checks + assert(prev_block->m_size == reuse->m_prev_size); + algo_impl_t::assert_alignment(prev_block); + + //Let's calculate the number of extra bytes of data before the current + //block's begin. The value is a multiple of backwards_multiple + std::size_t needs_backwards = preferred_size - + detail::get_truncated_size(received_size, backwards_multiple); + + const std::size_t lcm = detail::lcm(max_value(backwards_multiple, (std::size_t)Alignment) + ,min_value(backwards_multiple, (std::size_t)Alignment)); + + //If we want to use min_size data to get a buffer between preferred_size + //and min_size if preferred_size can't be achieved, calculate the + //biggest of all possibilities + if(!only_preferred_backwards){ + needs_backwards = min_size - detail::get_truncated_size(received_size, backwards_multiple); + } + + assert((needs_backwards % backwards_multiple) == 0); + + const std::size_t needs_backwards_aligned = + detail::get_rounded_size(needs_backwards, lcm); + + //Check if previous block has enough size + if(std::size_t(prev_block->m_size*Alignment) >= needs_backwards_aligned){ + //Now take all next space. This will succeed + if(command & expand_fwd){ + std::size_t received_size2; + if(!priv_expand(reuse_ptr, received_size, received_size, received_size2)){ + assert(0); + } + assert(received_size = received_size2); + } + //We need a minimum size to split the previous one + if(prev_block->m_size >= (needs_backwards_aligned/Alignment + BlockCtrlUnits)){ + block_ctrl *new_block = reinterpret_cast + (detail::char_ptr_cast(reuse) - needs_backwards_aligned); + + //Free old previous buffer + new_block->m_size = + AllocatedCtrlUnits + (needs_backwards_aligned + (received_size - UsableByPreviousChunk))/Alignment; + assert(new_block->m_size >= BlockCtrlUnits); + priv_mark_new_allocated_block(new_block); + + prev_block->m_size = (detail::char_ptr_cast(new_block) - + detail::char_ptr_cast(prev_block))/Alignment; + assert(prev_block->m_size >= BlockCtrlUnits); + priv_mark_as_free_block(prev_block); + + //Update the old previous block in the free chunks tree + //If the new size fulfills tree invariants do nothing, + //otherwise erase() + insert() + { + imultiset_iterator prev_block_it(Imultiset::s_iterator_to(*prev_block)); + imultiset_iterator was_smaller_it(prev_block_it); + if(prev_block_it != m_header.m_imultiset.begin() && + (--(was_smaller_it = prev_block_it))->m_size > prev_block->m_size){ + m_header.m_imultiset.erase(prev_block_it); + m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *prev_block); + } + } + + received_size = needs_backwards_aligned + received_size; + m_header.m_allocated += needs_backwards_aligned; + + //Check alignment + algo_impl_t::assert_alignment(new_block); + + //If the backwards expansion has remaining bytes in the + //first bytes, fill them with a pattern + void *p = priv_get_user_buffer(new_block); + void *user_ptr = detail::char_ptr_cast(p); + assert(((char*)reuse_ptr - (char*)user_ptr) % backwards_multiple == 0); + algo_impl_t::assert_alignment(user_ptr); + return user_ptr; + } + //Check if there is no place to create a new block and + //the whole new block is multiple of the backwards expansion multiple + else if(prev_block->m_size >= needs_backwards_aligned/Alignment && + 0 == ((prev_block->m_size*Alignment) % lcm)) { + //Erase old previous block, since we will change it + m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block)); + + //Just merge the whole previous block + needs_backwards = detail::get_truncated_size + (prev_block->m_size*Alignment, backwards_multiple); + //received_size = received_size/backwards_multiple*backwards_multiple + needs_backwards; + received_size = received_size + needs_backwards; + + m_header.m_allocated += prev_block->m_size*Alignment; + //Now update sizes + prev_block->m_size = prev_block->m_size + reuse->m_size; + assert(prev_block->m_size >= BlockCtrlUnits); + priv_mark_new_allocated_block(prev_block); + + //If the backwards expansion has remaining bytes in the + //first bytes, fill them with a pattern + void *p = priv_get_user_buffer(prev_block); + void *user_ptr = detail::char_ptr_cast(p); + assert(((char*)reuse_ptr - (char*)user_ptr) % backwards_multiple == 0); + algo_impl_t::assert_alignment(user_ptr); + return user_ptr; + } + else{ + //Alignment issues + } + } + } + return 0; +} + +template +inline typename rbtree_best_fit::multiallocation_iterator + rbtree_best_fit:: + allocate_many(std::size_t elem_bytes, std::size_t num_elements) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t::allocate_many(this, elem_bytes, num_elements); +} + +template +inline void rbtree_best_fit:: + deallocate_many(typename rbtree_best_fit::multiallocation_iterator it) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + while(it){ + void *addr = &*it; + ++it; + this->priv_deallocate(addr); + } +} + +template +inline typename rbtree_best_fit::multiallocation_iterator + rbtree_best_fit:: + allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element) +{ + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element); +} + +template +std::pair rbtree_best_fit:: + priv_allocate(allocation_type command + ,std::size_t limit_size + ,std::size_t preferred_size + ,std::size_t &received_size + ,void *reuse_ptr + ,std::size_t backwards_multiple) +{ + //Remove me. Forbid backwards allocation + //command &= (~expand_bwd); + + if(command & shrink_in_place){ + bool success = + algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size); + return std::pair ((success ? reuse_ptr : 0), true); + } + + typedef std::pair return_type; + received_size = 0; + + if(limit_size > preferred_size) + return return_type(0, false); + + //Number of units to request (including block_ctrl header) + std::size_t preferred_units = priv_get_total_units(preferred_size); + + //Number of units to request (including block_ctrl header) + std::size_t limit_units = priv_get_total_units(limit_size); + + //Expand in place + if(reuse_ptr && (command & (expand_fwd | expand_bwd))){ + void *ret = priv_expand_both_sides + (command, limit_size, preferred_size, received_size, reuse_ptr, true, backwards_multiple); + if(ret) + return return_type(ret, true); + } + + if(command & allocate_new){ + size_block_ctrl_compare comp; + imultiset_iterator it(m_header.m_imultiset.lower_bound(preferred_units, comp)); + + if(it != m_header.m_imultiset.end()){ + return return_type(this->priv_check_and_allocate + (preferred_units, detail::get_pointer(&*it), received_size), false); + } + + if(it != m_header.m_imultiset.begin()&& + (--it)->m_size >= limit_units){ + return return_type(this->priv_check_and_allocate + (it->m_size, detail::get_pointer(&*it), received_size), false); + } + } + + + //Now try to expand both sides with min size + if(reuse_ptr && (command & (expand_fwd | expand_bwd))){ + return return_type(priv_expand_both_sides + (command, limit_size, preferred_size, received_size, reuse_ptr, false, backwards_multiple), true); + } + + return return_type(0, false); +} + +template +inline +typename rbtree_best_fit::block_ctrl * + rbtree_best_fit::priv_get_block(const void *ptr) +{ + return reinterpret_cast(detail::char_ptr_cast(ptr) - AllocatedCtrlBytes); +} + +template +inline +void *rbtree_best_fit:: + priv_get_user_buffer(const typename rbtree_best_fit::block_ctrl *block) +{ return detail::char_ptr_cast(block) + AllocatedCtrlBytes; } + +template +inline +std::size_t rbtree_best_fit:: + priv_get_total_units(std::size_t userbytes) +{ + if(userbytes < UsableByPreviousChunk) + userbytes = UsableByPreviousChunk; + std::size_t units = detail::get_rounded_size(userbytes - UsableByPreviousChunk, Alignment)/Alignment + AllocatedCtrlUnits; + if(units < BlockCtrlUnits) units = BlockCtrlUnits; + return units; +} + +template +bool rbtree_best_fit:: + priv_expand (void *ptr + ,const std::size_t min_size + ,const std::size_t preferred_size + ,std::size_t &received_size) +{ + //Obtain the real size of the block + block_ctrl *block = priv_get_block(ptr); + std::size_t old_block_units = block->m_size; + + //The block must be marked as allocated and the sizes must be equal + assert(priv_is_allocated_block(block)); + //assert(old_block_units == priv_tail_size(block)); + + //Put this to a safe value + received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk; + if(received_size >= preferred_size || received_size >= min_size) + return true; + + //Now translate it to Alignment units + const std::size_t min_user_units = algo_impl_t::ceil_units(min_size - UsableByPreviousChunk); + const std::size_t preferred_user_units = algo_impl_t::ceil_units(preferred_size - UsableByPreviousChunk); + + //Some parameter checks + assert(min_user_units <= preferred_user_units); + + block_ctrl *next_block; + + if(priv_is_allocated_block(next_block = priv_next_block(block))){ + return received_size >= min_size ? true : false; + } + algo_impl_t::assert_alignment(next_block); + + //Is "block" + "next_block" big enough? + const std::size_t merged_units = old_block_units + next_block->m_size; + + //Now get the expansion size + const std::size_t merged_user_units = merged_units - AllocatedCtrlUnits; + + if(merged_user_units < min_user_units){ + received_size = merged_units*Alignment - UsableByPreviousChunk; + return false; + } + + //Now get the maximum size the user can allocate + std::size_t intended_user_units = (merged_user_units < preferred_user_units) ? + merged_user_units : preferred_user_units; + + //These are total units of the merged block (supposing the next block can be split) + const std::size_t intended_units = AllocatedCtrlUnits + intended_user_units; + + //Check if we can split the next one in two parts + if((merged_units - intended_units) >= BlockCtrlUnits){ + //This block is bigger than needed, split it in + //two blocks, the first one will be merged and + //the second's size will be the remaining space + assert(next_block->m_size == priv_next_block(next_block)->m_prev_size); + const std::size_t rem_units = merged_units - intended_units; + + //Check if we we need to update the old next block in the free chunks tree + //If the new size fulfills tree invariants, we just need to replace the node + //(the block start has been displaced), otherwise erase() + insert(). + // + //This fixup must be done in two parts, because the new next chunk might + //overwrite the tree hook of the old next chunk. So we first erase the + //old if needed and we'll insert the new one after creating the new next + imultiset_iterator old_next_block_it(Imultiset::s_iterator_to(*next_block)); + const bool size_invariants_broken = + (next_block->m_size - rem_units ) < BlockCtrlUnits || + (old_next_block_it != m_header.m_imultiset.begin() && + (--imultiset_iterator(old_next_block_it))->m_size > rem_units); + if(size_invariants_broken){ + m_header.m_imultiset.erase(old_next_block_it); + } + //This is the remaining block + block_ctrl *rem_block = new(reinterpret_cast + (detail::char_ptr_cast(block) + intended_units*Alignment))block_ctrl; + rem_block->m_size = rem_units; + algo_impl_t::assert_alignment(rem_block); + assert(rem_block->m_size >= BlockCtrlUnits); + priv_mark_as_free_block(rem_block); + + //Now the second part of the fixup + if(size_invariants_broken) + m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *rem_block); + else + m_header.m_imultiset.replace_node(old_next_block_it, *rem_block); + + //Write the new length + block->m_size = intended_user_units + AllocatedCtrlUnits; + assert(block->m_size >= BlockCtrlUnits); + m_header.m_allocated += (intended_units - old_block_units)*Alignment; + } + //There is no free space to create a new node: just merge both blocks + else{ + //Now we have to update the data in the tree + m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block)); + + //Write the new length + block->m_size = merged_units; + assert(block->m_size >= BlockCtrlUnits); + m_header.m_allocated += (merged_units - old_block_units)*Alignment; + } + priv_mark_as_allocated_block(block); + received_size = (block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk; + return true; +} + +template inline +typename rbtree_best_fit::block_ctrl * + rbtree_best_fit::priv_prev_block + (typename rbtree_best_fit::block_ctrl *ptr) +{ + assert(!ptr->m_prev_allocated); + return reinterpret_cast + (detail::char_ptr_cast(ptr) - ptr->m_prev_size*Alignment); +} + +template inline +bool rbtree_best_fit::priv_is_prev_allocated + (typename rbtree_best_fit::block_ctrl *ptr) +{ + if(ptr->m_prev_allocated){ + return true; + } + else{ + block_ctrl *prev = priv_prev_block(ptr); + (void)prev; + assert(!priv_is_allocated_block(prev)); + return false; + } +} + +template inline +typename rbtree_best_fit::block_ctrl * + rbtree_best_fit::priv_end_block + (typename rbtree_best_fit::block_ctrl *first_segment_block) +{ + assert(first_segment_block->m_prev_allocated); + block_ctrl *end_block = reinterpret_cast + (detail::char_ptr_cast(first_segment_block) - first_segment_block->m_prev_size*Alignment); + (void)end_block; + assert(priv_is_allocated_block(end_block)); + assert(end_block > first_segment_block); + return end_block; +} + +template inline +typename rbtree_best_fit::block_ctrl * + rbtree_best_fit::priv_next_block + (typename rbtree_best_fit::block_ctrl *ptr) +{ + return reinterpret_cast + (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment); +} + +template inline +bool rbtree_best_fit::priv_is_allocated_block + (typename rbtree_best_fit::block_ctrl *block) +{ + bool allocated = block->m_allocated != 0; + block_ctrl *next_block = (block_ctrl *) + (detail::char_ptr_cast(block) + block->m_size*Alignment); + bool next_block_prev_allocated = next_block->m_prev_allocated != 0; + (void)next_block_prev_allocated; + assert(allocated == next_block_prev_allocated); + return allocated; +} + +template inline +void rbtree_best_fit::priv_mark_as_allocated_block + (typename rbtree_best_fit::block_ctrl *block) +{ + //assert(!priv_is_allocated_block(block)); + block->m_allocated = 1; + ((block_ctrl *)(((char*)block) + block->m_size*Alignment))->m_prev_allocated = 1; +} + +template inline +void rbtree_best_fit::priv_mark_as_free_block + (typename rbtree_best_fit::block_ctrl *block) +{ + block->m_allocated = 0; + ((block_ctrl *)(((char*)block) + block->m_size*Alignment))->m_prev_allocated = 0; + //assert(!priv_is_allocated_block(ptr)); + priv_next_block(block)->m_prev_size = block->m_size; +} + +template inline +void* rbtree_best_fit::priv_check_and_allocate + (std::size_t nunits + ,typename rbtree_best_fit::block_ctrl* block + ,std::size_t &received_size) +{ + std::size_t upper_nunits = nunits + BlockCtrlUnits; + imultiset_iterator it_old = Imultiset::s_iterator_to(*block); + algo_impl_t::assert_alignment(block); + + if (block->m_size >= upper_nunits){ + //This block is bigger than needed, split it in + //two blocks, the first's size will be "units" and + //the second's size "block->m_size-units" + std::size_t block_old_size = block->m_size; + block->m_size = nunits; + assert(block->m_size >= BlockCtrlUnits); + + //This is the remaining block + block_ctrl *rem_block = new(reinterpret_cast + (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl; + algo_impl_t::assert_alignment(rem_block); + rem_block->m_size = block_old_size - nunits; + assert(rem_block->m_size >= BlockCtrlUnits); + priv_mark_as_free_block(rem_block); + + imultiset_iterator it_hint; + if(it_old == m_header.m_imultiset.begin() + || (--imultiset_iterator(it_old))->m_size < rem_block->m_size){ + //option a: slow but secure + //m_header.m_imultiset.insert(m_header.m_imultiset.erase(it_old), *rem_block); + //option b: Construct an empty node and swap + //Imultiset::init_node(*rem_block); + //block->swap_nodes(*rem_block); + //option c: replace the node directly + m_header.m_imultiset.replace_node(Imultiset::s_iterator_to(*it_old), *rem_block); + } + else{ + //Now we have to update the data in the tree + m_header.m_imultiset.erase(it_old); + m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *rem_block); + } + + } + else if (block->m_size >= nunits){ + m_header.m_imultiset.erase(it_old); + } + else{ + assert(0); + return 0; + } + //We need block_ctrl for deallocation stuff, so + //return memory user can overwrite + m_header.m_allocated += block->m_size*Alignment; + received_size = (block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk; + + //Mark the block as allocated + priv_mark_as_allocated_block(block); + + //Clear the memory occupied by the tree hook, since this won't be + //cleared with zero_free_memory + TreeHook *t = static_cast(block); + std::memset(t, 0, sizeof(*t)); + this->priv_next_block(block)->m_prev_size = 0; + return priv_get_user_buffer(block); +} + +template +void rbtree_best_fit::deallocate(void* addr) +{ + if(!addr) return; + //----------------------- + boost::interprocess::scoped_lock guard(m_header); + //----------------------- + return this->priv_deallocate(addr); +} + +template +void rbtree_best_fit::priv_deallocate(void* addr) +{ + if(!addr) return; + + block_ctrl *block = priv_get_block(addr); + + //The blocks must be marked as allocated and the sizes must be equal + assert(priv_is_allocated_block(block)); +// assert(block->m_size == priv_tail_size(block)); + + //Check if alignment and block size are right + algo_impl_t::assert_alignment(addr); + + std::size_t block_old_size = Alignment*block->m_size; + assert(m_header.m_allocated >= block_old_size); + + //Update used memory count + m_header.m_allocated -= block_old_size; + + //The block to insert in the tree + block_ctrl *block_to_insert = block; + + //Get the next block + block_ctrl *next_block = priv_next_block(block); + bool merge_with_prev = !priv_is_prev_allocated(block); + bool merge_with_next = !priv_is_allocated_block(next_block); + + //Merge logic. First just update block sizes, then fix free chunks tree + if(merge_with_prev || merge_with_next){ + //Merge if the previous is free + if(merge_with_prev){ + //Get the previous block + block_ctrl *prev_block = priv_prev_block(block); + prev_block->m_size += block->m_size; + assert(prev_block->m_size >= BlockCtrlUnits); + block_to_insert = prev_block; + } + //Merge if the next is free + if(merge_with_next){ + block_to_insert->m_size += next_block->m_size; + assert(block_to_insert->m_size >= BlockCtrlUnits); + if(merge_with_prev) + m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block)); + } + + bool only_merge_next = !merge_with_prev && merge_with_next; + imultiset_iterator free_block_to_check_it + (Imultiset::s_iterator_to(only_merge_next ? *next_block : *block_to_insert)); + imultiset_iterator was_bigger_it(free_block_to_check_it); + + //Now try to shortcut erasure + insertion (O(log(N))) with + //a O(1) operation if merging does not alter tree positions + if(++was_bigger_it != m_header.m_imultiset.end() && + block_to_insert->m_size > was_bigger_it->m_size ){ + m_header.m_imultiset.erase(free_block_to_check_it); + m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *block_to_insert); + } + else if(only_merge_next){ + m_header.m_imultiset.replace_node(free_block_to_check_it, *block_to_insert); + } + } + else{ + m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *block_to_insert); + } + priv_mark_as_free_block(block_to_insert); +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MEM_ALGO_RBTREE_BEST_FIT_HPP + diff --git a/thirdparty/boost/interprocess/mem_algo/simple_seq_fit.hpp b/thirdparty/boost/interprocess/mem_algo/simple_seq_fit.hpp new file mode 100644 index 0000000..bc6be5a --- /dev/null +++ b/thirdparty/boost/interprocess/mem_algo/simple_seq_fit.hpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SIMPLE_SEQ_FIT_HPP +#define BOOST_INTERPROCESS_SIMPLE_SEQ_FIT_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +//!\file +//!Describes sequential fit algorithm used to allocate objects in shared memory. + +namespace boost { +namespace interprocess { + +//!This class implements the simple sequential fit algorithm with a simply +//!linked list of free buffers. +template +class simple_seq_fit + : public detail::simple_seq_fit_impl +{ + /// @cond + typedef detail::simple_seq_fit_impl base_t; + /// @endcond + + public: + //!Constructor. "size" is the total size of the managed memory segment, + //!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit) + //!offset that the allocator should not use at all.*/ + simple_seq_fit (std::size_t size, std::size_t extra_hdr_bytes) + : base_t(size, extra_hdr_bytes){} +}; + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_SIMPLE_SEQ_FIT_HPP + diff --git a/thirdparty/boost/interprocess/offset_ptr.hpp b/thirdparty/boost/interprocess/offset_ptr.hpp new file mode 100644 index 0000000..45202e1 --- /dev/null +++ b/thirdparty/boost/interprocess/offset_ptr.hpp @@ -0,0 +1,478 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_OFFSET_PTR_HPP +#define BOOST_OFFSET_PTR_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a smart pointer that stores the offset between this pointer and +//!target pointee, called offset_ptr. + +namespace boost { + +//Predeclarations +template +struct has_trivial_constructor; + +template +struct has_trivial_destructor; + +namespace interprocess { + +//!A smart pointer that stores the offset between between the pointer and the +//!the object it points. This allows offset allows special properties, since +//!the pointer is independent from the address address of the pointee, if the +//!pointer and the pointee are still separated by the same offset. This feature +//!converts offset_ptr in a smart pointer that can be placed in shared memory and +//!memory mapped files mapped in different addresses in every process. +template +class offset_ptr +{ + /// @cond + typedef offset_ptr self_t; + typedef const PointedType * const_pointer_t; + typedef typename detail::add_reference + ::type const_reference_t; + + void unspecified_bool_type_func() const {} + typedef void (self_t::*unspecified_bool_type)() const; + + #if defined(_MSC_VER) && (_MSC_VER >= 1400) + __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0 + #endif + void set_offset(const volatile void *ptr) + { + const char *p = static_cast(const_cast(ptr)); + //offset == 1 && ptr != 0 is not legal for this pointer + if(!ptr){ + m_offset = 1; + } + else{ + m_offset = p - detail::char_ptr_cast(this); + BOOST_ASSERT(m_offset != 1); + } + } + + #if defined(_MSC_VER) && (_MSC_VER >= 1400) + __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0 + #endif + void* get_pointer() const + { return (m_offset == 1) ? 0 : (detail::char_ptr_cast(this) + m_offset); } + + void inc_offset(std::ptrdiff_t bytes) + { m_offset += bytes; } + + void dec_offset(std::ptrdiff_t bytes) + { m_offset -= bytes; } + + std::ptrdiff_t m_offset; //Distance between this object and pointed address + /// @endcond + + public: + typedef PointedType * pointer; + typedef typename detail:: + add_reference::type reference; + typedef PointedType value_type; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + + public: //Public Functions + + //!Constructor from raw pointer (allows "0" pointer conversion). + //!Never throws. + offset_ptr(pointer ptr = 0) { this->set_offset(ptr); } + + //!Constructor from other pointer. + //!Never throws. + template + offset_ptr(T *ptr) + { pointer p (ptr); (void)p; this->set_offset(p); } + + //!Constructor from other offset_ptr + //!Never throws. + offset_ptr(const offset_ptr& ptr) + { this->set_offset(ptr.get()); } + + //!Constructor from other offset_ptr. If pointers of pointee types are + //!convertible, offset_ptrs will be convertibles. Never throws. + template + offset_ptr(const offset_ptr &ptr) + { pointer p(ptr.get()); (void)p; this->set_offset(p); } + + //!Emulates static_cast operator. + //!Never throws. + template + offset_ptr(const offset_ptr & r, detail::static_cast_tag) + { this->set_offset(static_cast(r.get())); } + + //!Emulates const_cast operator. + //!Never throws. + template + offset_ptr(const offset_ptr & r, detail::const_cast_tag) + { this->set_offset(const_cast(r.get())); } + + //!Emulates dynamic_cast operator. + //!Never throws. + template + offset_ptr(const offset_ptr & r, detail::dynamic_cast_tag) + { this->set_offset(dynamic_cast(r.get())); } + + //!Emulates reinterpret_cast operator. + //!Never throws. + template + offset_ptr(const offset_ptr & r, detail::reinterpret_cast_tag) + { this->set_offset(reinterpret_cast(r.get())); } + + //!Obtains raw pointer from offset. + //!Never throws. + pointer get()const + { return (pointer)this->get_pointer(); } + + std::ptrdiff_t get_offset() + { return m_offset; } + + //!Pointer-like -> operator. It can return 0 pointer. + //!Never throws. + pointer operator->() const + { return this->get(); } + + //!Dereferencing operator, if it is a null offset_ptr behavior + //! is undefined. Never throws. + reference operator* () const + { return *(this->get()); } + + //!Indexing operator. + //!Never throws. + reference operator[](std::ptrdiff_t idx) const + { return this->get()[idx]; } + + //!Assignment from pointer (saves extra conversion). + //!Never throws. + offset_ptr& operator= (pointer from) + { this->set_offset(from); return *this; } + + //!Assignment from other offset_ptr. + //!Never throws. + offset_ptr& operator= (const offset_ptr & pt) + { pointer p(pt.get()); (void)p; this->set_offset(p); return *this; } + + //!Assignment from related offset_ptr. If pointers of pointee types + //! are assignable, offset_ptrs will be assignable. Never throws. + template + offset_ptr& operator= (const offset_ptr & pt) + { pointer p(pt.get()); this->set_offset(p); return *this; } + + //!offset_ptr + std::ptrdiff_t. + //!Never throws. + offset_ptr operator+ (std::ptrdiff_t offset) const + { return offset_ptr(this->get()+offset); } + + //!offset_ptr - std::ptrdiff_t. + //!Never throws. + offset_ptr operator- (std::ptrdiff_t offset) const + { return offset_ptr(this->get()-offset); } + + //!offset_ptr += std::ptrdiff_t. + //!Never throws. + offset_ptr &operator+= (std::ptrdiff_t offset) + { this->inc_offset(offset * sizeof (PointedType)); return *this; } + + //!offset_ptr -= std::ptrdiff_t. + //!Never throws. + offset_ptr &operator-= (std::ptrdiff_t offset) + { this->dec_offset(offset * sizeof (PointedType)); return *this; } + + //!++offset_ptr. + //!Never throws. + offset_ptr& operator++ (void) + { this->inc_offset(sizeof (PointedType)); return *this; } + + //!offset_ptr++. + //!Never throws. + offset_ptr operator++ (int) + { offset_ptr temp(*this); ++*this; return temp; } + + //!--offset_ptr. + //!Never throws. + offset_ptr& operator-- (void) + { this->dec_offset(sizeof (PointedType)); return *this; } + + //!offset_ptr--. + //!Never throws. + offset_ptr operator-- (int) + { offset_ptr temp(*this); --*this; return temp; } + + //!safe bool conversion operator. + //!Never throws. + operator unspecified_bool_type() const + { return this->get()? &self_t::unspecified_bool_type_func : 0; } + + //!Not operator. Not needed in theory, but improves portability. + //!Never throws + bool operator! () const + { return this->get() == 0; } +/* + friend void swap (offset_ptr &pt, offset_ptr &pt2) + { + value_type *ptr = pt.get(); + pt = pt2; + pt2 = ptr; + } +*/ +}; + +//!offset_ptr == offset_ptr. +//!Never throws. +template +inline bool operator== (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() == pt2.get(); } + +//!offset_ptr != offset_ptr. +//!Never throws. +template +inline bool operator!= (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() != pt2.get(); } + +//!offset_ptr < offset_ptr. +//!Never throws. +template +inline bool operator< (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() < pt2.get(); } + +//!offset_ptr <= offset_ptr. +//!Never throws. +template +inline bool operator<= (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() <= pt2.get(); } + +//!offset_ptr > offset_ptr. +//!Never throws. +template +inline bool operator> (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() > pt2.get(); } + +//!offset_ptr >= offset_ptr. +//!Never throws. +template +inline bool operator>= (const offset_ptr &pt1, + const offset_ptr &pt2) +{ return pt1.get() >= pt2.get(); } + +//!operator<< +//!for offset ptr +template +inline std::basic_ostream & operator<< + (std::basic_ostream & os, offset_ptr const & p) +{ return os << p.get_offset(); } + +//!operator>> +//!for offset ptr +template +inline std::basic_istream & operator>> + (std::basic_istream & is, offset_ptr & p) +{ return is >> p.get_offset(); } + +//!std::ptrdiff_t + offset_ptr +//!operation +template +inline offset_ptr operator+(std::ptrdiff_t diff, const offset_ptr& right) +{ return right + diff; } + +//!offset_ptr - offset_ptr +//!operation +template +inline std::ptrdiff_t operator- (const offset_ptr &pt, const offset_ptr &pt2) +{ return pt.get()- pt2.get(); } + +//!swap specialization +//!for offset_ptr +template +inline void swap (boost::interprocess::offset_ptr &pt, + boost::interprocess::offset_ptr &pt2) +{ + typename offset_ptr::value_type *ptr = pt.get(); + pt = pt2; + pt2 = ptr; +} + +//!Simulation of static_cast between pointers. Never throws. +template +inline boost::interprocess::offset_ptr + static_pointer_cast(boost::interprocess::offset_ptr const & r) +{ + return boost::interprocess::offset_ptr + (r, boost::interprocess::detail::static_cast_tag()); +} + +//!Simulation of const_cast between pointers. Never throws. +template +inline boost::interprocess::offset_ptr + const_pointer_cast(boost::interprocess::offset_ptr const & r) +{ + return boost::interprocess::offset_ptr + (r, boost::interprocess::detail::const_cast_tag()); +} + +//!Simulation of dynamic_cast between pointers. Never throws. +template +inline boost::interprocess::offset_ptr + dynamic_pointer_cast(boost::interprocess::offset_ptr const & r) +{ + return boost::interprocess::offset_ptr + (r, boost::interprocess::detail::dynamic_cast_tag()); +} + +//!Simulation of reinterpret_cast between pointers. Never throws. +template +inline boost::interprocess::offset_ptr + reinterpret_pointer_cast(boost::interprocess::offset_ptr const & r) +{ + return boost::interprocess::offset_ptr + (r, boost::interprocess::detail::reinterpret_cast_tag()); +} + +} //namespace interprocess { + +/// @cond + +//!has_trivial_constructor<> == true_type specialization for optimizations +template +struct has_trivial_constructor< boost::interprocess::offset_ptr > +{ + enum { value = true }; +}; + +///has_trivial_destructor<> == true_type specialization for optimizations +template +struct has_trivial_destructor< boost::interprocess::offset_ptr > +{ + enum { value = true }; +}; + +//#if !defined(_MSC_VER) || (_MSC_VER >= 1400) +namespace interprocess { +//#endif +//!get_pointer() enables boost::mem_fn to recognize offset_ptr. +//!Never throws. +template +inline T * get_pointer(boost::interprocess::offset_ptr const & p) +{ return p.get(); } +//#if !defined(_MSC_VER) || (_MSC_VER >= 1400) +} //namespace interprocess +//#endif + +/// @endcond +} //namespace boost { + +/// @cond + +namespace boost{ + +//This is to support embedding a bit in the pointer +//for intrusive containers, saving space +namespace intrusive { + +//Predeclaration to avoid including header +template +struct has_pointer_plus_bit; + +template +struct has_pointer_plus_bit, N> +{ + static const bool value = (N % 4u == 0); +}; + +//Predeclaration +template +struct pointer_plus_bit; + +//Specialization +template +struct pointer_plus_bit > +{ + typedef boost::interprocess::offset_ptr pointer; + + static pointer get_pointer(const pointer &n) + { return (T*)(std::size_t(n.get()) & ~std::size_t(2u)); } + + static void set_pointer(pointer &n, pointer p) + { n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(2u))); } + + static bool get_bit(const pointer &n) + { return 0 != (std::size_t(n.get()) & std::size_t(2u)); } + + static void set_bit(pointer &n, bool c) + { n = (T*)(std::size_t(get_pointer(n).get()) | (std::size_t(c) << 1u)); } +}; + +//Predeclaration to avoid including header +template +struct has_pointer_plus_2_bits; + +template +struct has_pointer_plus_2_bits, N> +{ + static const bool value = (N % 8u == 0); +}; + +//Predeclaration +template +struct pointer_plus_2_bits; + +template +struct pointer_plus_2_bits > +{ + typedef boost::interprocess::offset_ptr pointer; + + static pointer get_pointer(const pointer &n) + { return (T*)(std::size_t(n.get()) & ~std::size_t(6u)); } + + static void set_pointer(pointer &n, pointer p) + { n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(6u))); } + + static std::size_t get_bits(const pointer &n) + { return(std::size_t(n.get()) & std::size_t(6u)) >> 1u; } + + static void set_bits(pointer &n, std::size_t b) + { + assert(b < 4); + n = (T*)(std::size_t(get_pointer(n).get()) | (b << 1u)); + } +}; + +} //namespace intrusive +} //namespace boost{ +/// @endcond + +#include + +#endif //#ifndef BOOST_OFFSET_PTR_HPP + diff --git a/thirdparty/boost/interprocess/segment_manager.hpp b/thirdparty/boost/interprocess/segment_manager.hpp new file mode 100644 index 0000000..d1ee837 --- /dev/null +++ b/thirdparty/boost/interprocess/segment_manager.hpp @@ -0,0 +1,1297 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_HPP +#define BOOST_INTERPROCESS_SEGMENT_MANAGER_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //std::size_t +#include //char_traits +#include //std::nothrow +#include //std::pair +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +//!\file +//!Describes the object placed in a memory segment that provides +//!named object allocation capabilities for single-segment and +//!multi-segment allocations. + +namespace boost{ +namespace interprocess{ + +//!This object is the public base class of segment manager. +//!This class only depends on the memory allocation algorithm +//!and implements all the allocation features not related +//!to named or unique objects. +//! +//!Storing a reference to segment_manager forces +//!the holder class to be dependent on index types and character types. +//!When such dependence is not desirable and only anonymous and raw +//!allocations are needed, segment_manager_base is the correct answer. +template +class segment_manager_base + : private MemoryAlgorithm +{ + public: + typedef segment_manager_base segment_manager_base_type; + typedef typename MemoryAlgorithm::void_pointer void_pointer; + typedef typename MemoryAlgorithm::mutex_family mutex_family; + typedef MemoryAlgorithm memory_algorithm; + + /// @cond + + //Experimental. Don't use + typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator; + typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain; + + /// @endcond + + //!This constant indicates the payload size + //!associated with each allocation of the memory algorithm + static const std::size_t PayloadPerAllocation = MemoryAlgorithm::PayloadPerAllocation; + + //!Constructor of the segment_manager_base + //! + //!"size" is the size of the memory segment where + //!the basic segment manager is being constructed. + //! + //!"reserved_bytes" is the number of bytes + //!after the end of the memory algorithm object itself + //!that the memory algorithm will exclude from + //!dynamic allocation + //! + //!Can throw + segment_manager_base(std::size_t size, std::size_t reserved_bytes) + : MemoryAlgorithm(size, reserved_bytes) + { + assert((sizeof(segment_manager_base) == sizeof(MemoryAlgorithm))); + } + + //!Returns the size of the memory + //!segment + std::size_t get_size() const + { return MemoryAlgorithm::get_size(); } + + //!Returns the number of free bytes of the memory + //!segment + std::size_t get_free_memory() const + { return MemoryAlgorithm::get_free_memory(); } + + //!Obtains the minimum size needed by + //!the segment manager + static std::size_t get_min_size (std::size_t size) + { return MemoryAlgorithm::get_min_size(size); } + + //!Allocates nbytes bytes. This function is only used in + //!single-segment management. Never throws + void * allocate (std::size_t nbytes, std::nothrow_t) + { return MemoryAlgorithm::allocate(nbytes); } + + /// @cond + + //Experimental. Dont' use. + //!Allocates n_elements of + //!elem_size bytes. Throws bad_alloc on failure. + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements) + { + multiallocation_iterator ret = MemoryAlgorithm::allocate_many(elem_bytes, num_elements); + if(!ret) throw bad_alloc(); + return ret; + } + + //!Allocates n_elements, each one of + //!element_lenghts[i]*sizeof_element bytes. Throws bad_alloc on failure. + multiallocation_iterator allocate_many + (const std::size_t *element_lenghts, std::size_t n_elements, std::size_t sizeof_element = 1) + { + multiallocation_iterator ret = MemoryAlgorithm::allocate_many(element_lenghts, n_elements, sizeof_element); + if(!ret) throw bad_alloc(); + return ret; + } + + //!Allocates n_elements of + //!elem_size bytes. Returns a default constructed iterator on failure. + multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t) + { return MemoryAlgorithm::allocate_many(elem_bytes, num_elements); } + + //!Allocates n_elements, each one of + //!element_lenghts[i]*sizeof_element bytes. + //!Returns a default constructed iterator on failure. + multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element, std::nothrow_t) + { return MemoryAlgorithm::allocate_many(elem_sizes, n_elements, sizeof_element); } + + //!Deallocates elements pointed by the + //!multiallocation iterator range. + void deallocate_many(multiallocation_iterator it) + { MemoryAlgorithm::deallocate_many(it); } + + /// @endcond + + //!Allocates nbytes bytes. Throws boost::interprocess::bad_alloc + //!on failure + void * allocate(std::size_t nbytes) + { + void * ret = MemoryAlgorithm::allocate(nbytes); + if(!ret) + throw bad_alloc(); + return ret; + } + + //!Allocates nbytes bytes. This function is only used in + //!single-segment management. Never throws + void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t) + { return MemoryAlgorithm::allocate_aligned(nbytes, alignment); } + + //!Allocates nbytes bytes. This function is only used in + //!single-segment management. Throws bad_alloc when fails + void * allocate_aligned(std::size_t nbytes, std::size_t alignment) + { + void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment); + if(!ret) + throw bad_alloc(); + return ret; + } + + template + std::pair + allocation_command (allocation_type command, std::size_t limit_size, + std::size_t preferred_size,std::size_t &received_size, + T *reuse_ptr = 0) + { + std::pair ret = MemoryAlgorithm::allocation_command + ( command | nothrow_allocation, limit_size, preferred_size, received_size + , reuse_ptr); + if(!(command & nothrow_allocation) && !ret.first) + throw bad_alloc(); + return ret; + } + + std::pair + raw_allocation_command (allocation_type command, std::size_t limit_objects, + std::size_t preferred_objects,std::size_t &received_objects, + void *reuse_ptr = 0, std::size_t sizeof_object = 1) + { + std::pair ret = MemoryAlgorithm::raw_allocation_command + ( command | nothrow_allocation, limit_objects, preferred_objects, received_objects + , reuse_ptr, sizeof_object); + if(!(command & nothrow_allocation) && !ret.first) + throw bad_alloc(); + return ret; + } + + //!Deallocates the bytes allocated with allocate/allocate_many() + //!pointed by addr + void deallocate (void *addr) + { MemoryAlgorithm::deallocate(addr); } + + //!Increases managed memory in extra_size bytes more. This only works + //!with single-segment management. + void grow(std::size_t extra_size) + { MemoryAlgorithm::grow(extra_size); } + + //!Decreases managed memory to the minimum. This only works + //!with single-segment management. + void shrink_to_fit() + { MemoryAlgorithm::shrink_to_fit(); } + + //!Returns the result of "all_memory_deallocated()" function + //!of the used memory algorithm + bool all_memory_deallocated() + { return MemoryAlgorithm::all_memory_deallocated(); } + + //!Returns the result of "check_sanity()" function + //!of the used memory algorithm + bool check_sanity() + { return MemoryAlgorithm::check_sanity(); } + + //!Writes to zero free memory (memory not yet allocated) + //!of the memory algorithm + void zero_free_memory() + { MemoryAlgorithm::zero_free_memory(); } + + //!Returns the size of the buffer previously allocated pointed by ptr + std::size_t size(const void *ptr) const + { return MemoryAlgorithm::size(ptr); } + + /// @cond + protected: + void * prot_anonymous_construct + (std::size_t num, bool dothrow, detail::in_place_interface &table) + { + typedef detail::block_header block_header_t; + block_header_t block_info ( table.size*num + , table.alignment + , anonymous_type + , 1 + , 0); + + //Allocate memory + void *ptr_struct = this->allocate(block_info.total_size(), std::nothrow_t()); + + //Check if there is enough memory + if(!ptr_struct){ + if(dothrow){ + throw bad_alloc(); + } + else{ + return 0; + } + } + + //Build scoped ptr to avoid leaks with constructor exception + detail::mem_algo_deallocator mem(ptr_struct, *this); + + //Now construct the header + block_header_t * hdr = new(ptr_struct) block_header_t(block_info); + void *ptr = 0; //avoid gcc warning + ptr = hdr->value(); + + //Now call constructors + detail::array_construct(ptr, num, table); + + //All constructors successful, we don't want erase memory + mem.release(); + return ptr; + } + + //!Calls the destructor and makes an anonymous deallocate + void prot_anonymous_destroy(const void *object, detail::in_place_interface &table) + { + + //Get control data from associated with this object + typedef detail::block_header block_header_t; + block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment); + + //------------------------------- + //boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + + if(ctrl_data->allocation_type() != anonymous_type){ + //This is not an anonymous object, the pointer is wrong! + assert(0); + } + + //Call destructors and free memory + //Build scoped ptr to avoid leaks with destructor exception + std::size_t destroyed = 0; + table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, destroyed); + this->deallocate(ctrl_data); + } + /// @endcond +}; + +//These pointers are the ones the user will use to +//indicate previous allocation types +static const detail::anonymous_instance_t * anonymous_instance = 0; +static const detail::unique_instance_t * unique_instance = 0; + +//!This object is placed in the beginning of memory segment and +//!implements the allocation (named or anonymous) of portions +//!of the segment. This object contains two indexes that +//!maintain an association between a name and a portion of the segment. +//! +//!The first index contains the mappings for normal named objects using the +//!char type specified in the template parameter. +//! +//!The second index contains the association for unique instances. The key will +//!be the const char * returned from type_info.name() function for the unique +//!type to be constructed. +//! +//!segment_manager inherits publicly +//!from segment_manager_base and inherits from it +//!many public functions related to anonymous object and raw memory allocation. +//!See segment_manager_base reference to know about those functions. +template class IndexType> +class segment_manager + : public segment_manager_base +{ + /// @cond + //Non-copyable + segment_manager(); + segment_manager(const segment_manager &); + segment_manager &operator=(const segment_manager &); + typedef segment_manager_base Base; + typedef detail::block_header block_header_t; + /// @endcond + + public: + typedef MemoryAlgorithm memory_algorithm; + typedef typename Base::void_pointer void_pointer; + typedef CharType char_type; + typedef typename Base::multiallocation_iterator multiallocation_iterator; + + typedef segment_manager_base segment_manager_base_type; + + static const std::size_t PayloadPerAllocation = Base::PayloadPerAllocation; + + /// @cond + private: + typedef detail::index_config index_config_named; + typedef detail::index_config index_config_unique; + typedef IndexType index_type; + typedef detail::bool_::value > is_intrusive_t; + typedef detail::bool_::value> is_node_index_t; + + public: + typedef IndexType named_index_t; + typedef IndexType unique_index_t; + typedef detail::char_ptr_holder char_ptr_holder_t; + typedef detail::segment_manager_iterator_transform + ::value> named_transform; + + typedef detail::segment_manager_iterator_transform + ::value> unique_transform; + /// @endcond + + typedef typename Base::mutex_family mutex_family; + + typedef transform_iterator + const_named_iterator; + typedef transform_iterator + const_unique_iterator; + + /// @cond + + //!Constructor proxy object definition helper class + template + struct construct_proxy + { + typedef detail::named_proxy type; + }; + + //!Constructor proxy object definition helper class + template + struct construct_iter_proxy + { + typedef detail::named_proxy type; + }; + + /// @endcond + + //!Constructor of the segment manager + //!"size" is the size of the memory segment where + //!the segment manager is being constructed. + //!Can throw + segment_manager(std::size_t size) + : Base(size, priv_get_reserved_bytes()) + , m_header(static_cast(get_this_pointer())) + { (void) anonymous_instance; (void) unique_instance; } + + //!Tries to find a previous named allocation. Returns the address + //!and the object count. On failure the first member of the + //!returned pair is 0. + template + std::pair find (const CharType* name) + { + //The name can't be null, no anonymous object can be found by name + assert(name != 0); + detail::placement_destroy table; + std::size_t size; + void *ret; + + if(name == reinterpret_cast(-1)){ + ret = priv_generic_find (typeid(T).name(), m_header.m_unique_index, table, size, is_intrusive_t()); + } + else{ + ret = priv_generic_find (name, m_header.m_named_index, table, size, is_intrusive_t()); + } + return std::pair(static_cast(ret), size); + } + + //!Tries to find a previous unique allocation. Returns the address + //!and the object count. On failure the first member of the + //!returned pair is 0. + template + std::pair find (const detail::unique_instance_t* name) + { + detail::placement_destroy table; + std::size_t size; + void *ret = priv_generic_find(name, m_header.m_unique_index, table, size, is_intrusive_t()); + return std::pair(static_cast(ret), size); + } + + //!Returns throwing "construct" proxy + //!object + template + typename construct_proxy::type + construct(char_ptr_holder_t name) + { return typename construct_proxy::type (this, name, false, true); } + + //!Returns throwing "search or construct" proxy + //!object + template + typename construct_proxy::type find_or_construct(char_ptr_holder_t name) + { return typename construct_proxy::type (this, name, true, true); } + + //!Returns no throwing "construct" proxy + //!object + template + typename construct_proxy::type + construct(char_ptr_holder_t name, std::nothrow_t) + { return typename construct_proxy::type (this, name, false, false); } + + //!Returns no throwing "search or construct" + //!proxy object + template + typename construct_proxy::type + find_or_construct(char_ptr_holder_t name, std::nothrow_t) + { return typename construct_proxy::type (this, name, true, false); } + + //!Returns throwing "construct from iterators" proxy object + template + typename construct_iter_proxy::type + construct_it(char_ptr_holder_t name) + { return typename construct_iter_proxy::type (this, name, false, true); } + + //!Returns throwing "search or construct from iterators" + //!proxy object + template + typename construct_iter_proxy::type + find_or_construct_it(char_ptr_holder_t name) + { return typename construct_iter_proxy::type (this, name, true, true); } + + //!Returns no throwing "construct from iterators" + //!proxy object + template + typename construct_iter_proxy::type + construct_it(char_ptr_holder_t name, std::nothrow_t) + { return typename construct_iter_proxy::type (this, name, false, false); } + + //!Returns no throwing "search or construct from iterators" + //!proxy object + template + typename construct_iter_proxy::type + find_or_construct_it(char_ptr_holder_t name, std::nothrow_t) + { return typename construct_iter_proxy::type (this, name, true, false); } + + //!Calls object function blocking recursive interprocess_mutex and guarantees that + //!no new named_alloc or destroy will be executed by any process while + //!executing the object function call*/ + template + void atomic_func(Func &f) + { boost::interprocess::scoped_lock guard(m_header); f(); } + + //!Destroys a previously created unique instance. + //!Returns false if the object was not present. + template + bool destroy(const detail::unique_instance_t *) + { + detail::placement_destroy dtor; + return this->priv_generic_named_destroy + (typeid(T).name(), m_header.m_unique_index, dtor, is_intrusive_t()); + } + + //!Destroys the named object with + //!the given name. Returns false if that object can't be found. + template + bool destroy(const CharType *name) + { + detail::placement_destroy dtor; + return this->priv_generic_named_destroy + (name, m_header.m_named_index, dtor, is_intrusive_t()); + } + + //!Destroys an anonymous, unique or named object + //!using it's address + template + void destroy_ptr(const T *p) + { + //If T is void transform it to char + typedef typename detail::char_if_void::type data_t; + detail::placement_destroy dtor; + priv_destroy_ptr(p, dtor); + } + + //!Returns the name of an object created with construct/find_or_construct + //!functions. Does not throw + template + static const CharType *get_instance_name(const T *ptr) + { return priv_get_instance_name(block_header_t::block_header_from_value(ptr)); } + + //!Returns the length of an object created with construct/find_or_construct + //!functions. Does not throw. + template + static std::size_t get_instance_length(const T *ptr) + { return priv_get_instance_length(block_header_t::block_header_from_value(ptr), sizeof(T)); } + + //!Returns is the the name of an object created with construct/find_or_construct + //!functions. Does not throw + template + static instance_type get_instance_type(const T *ptr) + { return priv_get_instance_type(block_header_t::block_header_from_value(ptr)); } + + //!Preallocates needed index resources to optimize the + //!creation of "num" named objects in the managed memory segment. + //!Can throw boost::interprocess::bad_alloc if there is no enough memory. + void reserve_named_objects(std::size_t num) + { + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + m_header.m_named_index.reserve(num); + } + + //!Preallocates needed index resources to optimize the + //!creation of "num" unique objects in the managed memory segment. + //!Can throw boost::interprocess::bad_alloc if there is no enough memory. + void reserve_unique_objects(std::size_t num) + { + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + m_header.m_unique_index.reserve(num); + } + + //!Calls shrink_to_fit in both named and unique object indexes + //!to try to free unused memory from those indexes. + void shrink_to_fit_indexes() + { + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + m_header.m_named_index.shrink_to_fit(); + m_header.m_unique_index.shrink_to_fit(); + } + + //!Returns the number of named objects stored in + //!the segment. + std::size_t get_num_named_objects() + { + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + return m_header.m_named_index.size(); + } + + //!Returns the number of unique objects stored in + //!the segment. + std::size_t get_num_unique_objects() + { + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + return m_header.m_unique_index.size(); + } + + //!Obtains the minimum size needed by the + //!segment manager + static std::size_t get_min_size() + { return Base::get_min_size(priv_get_reserved_bytes()); } + + //!Returns a constant iterator to the beginning of the information about + //!the named allocations performed in this segment manager + const_named_iterator named_begin() const + { + return make_transform_iterator + (m_header.m_named_index.begin(), named_transform()); + } + + //!Returns a constant iterator to the end of the information about + //!the named allocations performed in this segment manager + const_named_iterator named_end() const + { + return make_transform_iterator + (m_header.m_named_index.end(), named_transform()); + } + + //!Returns a constant iterator to the beginning of the information about + //!the unique allocations performed in this segment manager + const_unique_iterator unique_begin() const + { + return make_transform_iterator + (m_header.m_unique_index.begin(), unique_transform()); + } + + //!Returns a constant iterator to the end of the information about + //!the unique allocations performed in this segment manager + const_unique_iterator unique_end() const + { + return make_transform_iterator + (m_header.m_unique_index.end(), unique_transform()); + } + + //!This is the default allocator to allocate types T + //!from this managed segment + template + struct allocator + { + typedef boost::interprocess::allocator type; + }; + + //!Returns an instance of the default allocator for type T + //!initialized that allocates memory from this segment manager. + template + typename allocator::type + get_allocator() + { return typename allocator::type(this); } + + //!This is the default deleter to delete types T + //!from this managed segment. + template + struct deleter + { + typedef boost::interprocess::deleter type; + }; + + //!Returns an instance of the default allocator for type T + //!initialized that allocates memory from this segment manager. + template + typename deleter::type + get_deleter() + { return typename deleter::type(this); } + /// @cond + + //!Generic named/anonymous new function. Offers all the possibilities, + //!such as throwing, search before creating, and the constructor is + //!encapsulated in an object function. + template + T *generic_construct(const CharType *name, + std::size_t num, + bool try2find, + bool dothrow, + detail::in_place_interface &table) + { + return static_cast + (priv_generic_construct(name, num, try2find, dothrow, table)); + } + + private: + void *priv_generic_construct(const CharType *name, + std::size_t num, + bool try2find, + bool dothrow, + detail::in_place_interface &table) + { + void *ret; + //Security overflow check + if(num > ((std::size_t)-1)/table.size){ + if(dothrow) + throw bad_alloc(); + else + return 0; + } + if(name == 0){ + ret = this->prot_anonymous_construct(num, dothrow, table); + } + else if(name == reinterpret_cast(-1)){ + ret = this->priv_generic_named_construct + (unique_type, table.type_name, num, try2find, dothrow, table, m_header.m_unique_index, is_intrusive_t()); + } + else{ + ret = this->priv_generic_named_construct + (named_type, name, num, try2find, dothrow, table, m_header.m_named_index, is_intrusive_t()); + } + return ret; + } + + void priv_destroy_ptr(const void *ptr, detail::in_place_interface &dtor) + { + block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr, dtor.size, dtor.alignment); + switch(ctrl_data->allocation_type()){ + case anonymous_type: + this->prot_anonymous_destroy(ptr, dtor); + break; + + case named_type: + this->priv_generic_named_destroy + (ctrl_data, m_header.m_named_index, dtor, is_node_index_t()); + break; + + case unique_type: + this->priv_generic_named_destroy + (ctrl_data, m_header.m_unique_index, dtor, is_node_index_t()); + break; + + default: + //This type is unknown, bad pointer passed to this function! + assert(0); + break; + } + } + + //!Returns the name of an object created with construct/find_or_construct + //!functions. Does not throw + static const CharType *priv_get_instance_name(block_header_t *ctrl_data) + { + allocation_type type = ctrl_data->allocation_type(); + if(type != named_type){ + assert((type == anonymous_type && ctrl_data->m_num_char == 0) || + (type == unique_type && ctrl_data->m_num_char != 0) ); + return 0; + } + CharType *name = static_cast(ctrl_data->template name()); + + //Sanity checks + assert(ctrl_data->sizeof_char() == sizeof(CharType)); + assert(ctrl_data->m_num_char == std::char_traits::length(name)); + return name; + } + + static std::size_t priv_get_instance_length(block_header_t *ctrl_data, std::size_t sizeofvalue) + { + //Get header + assert((ctrl_data->value_bytes() %sizeofvalue) == 0); + return ctrl_data->value_bytes()/sizeofvalue; + } + + //!Returns is the the name of an object created with construct/find_or_construct + //!functions. Does not throw + static instance_type priv_get_instance_type(block_header_t *ctrl_data) + { + //Get header + assert((instance_type)ctrl_data->allocation_type() < max_allocation_type); + return (instance_type)ctrl_data->allocation_type(); + } + + static std::size_t priv_get_reserved_bytes() + { + //Get the number of bytes until the end of (*this) + //beginning in the end of the Base base. + return (detail::char_ptr_cast((segment_manager*)0) + sizeof(segment_manager)) - + (detail::char_ptr_cast(static_cast((segment_manager*)0)) + sizeof(Base)); + } + + template + void *priv_generic_find + (const CharT* name, + IndexType > &index, + detail::in_place_interface &table, + std::size_t &length, + detail::true_ is_intrusive) + { + (void)is_intrusive; + typedef IndexType > index_type; + typedef detail::index_key index_key_t; + typedef typename index_type::iterator index_it; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Find name in index + detail::intrusive_compare_key key + (name, std::char_traits::length(name)); + index_it it = index.find(key); + + //Initialize return values + void *ret_ptr = 0; + length = 0; + + //If found, assign values + if(it != index.end()){ + //Get header + block_header_t *ctrl_data = it->get_block_header(); + + //Sanity check + assert((ctrl_data->m_value_bytes % table.size) == 0); + assert(ctrl_data->sizeof_char() == sizeof(CharT)); + ret_ptr = ctrl_data->value(); + length = ctrl_data->m_value_bytes/table.size; + } + return ret_ptr; + } + + template + void *priv_generic_find + (const CharT* name, + IndexType > &index, + detail::in_place_interface &table, + std::size_t &length, + detail::false_ is_intrusive) + { + (void)is_intrusive; + typedef IndexType > index_type; + typedef typename index_type::key_type key_type; + typedef typename index_type::iterator index_it; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Find name in index + index_it it = index.find(key_type(name, std::char_traits::length(name))); + + //Initialize return values + void *ret_ptr = 0; + length = 0; + + //If found, assign values + if(it != index.end()){ + //Get header + block_header_t *ctrl_data = reinterpret_cast + (detail::get_pointer(it->second.m_ptr)); + + //Sanity check + assert((ctrl_data->m_value_bytes % table.size) == 0); + assert(ctrl_data->sizeof_char() == sizeof(CharT)); + ret_ptr = ctrl_data->value(); + length = ctrl_data->m_value_bytes/table.size; + } + return ret_ptr; + } + + template + bool priv_generic_named_destroy + (block_header_t *block_header, + IndexType > &index, + detail::in_place_interface &table, + detail::true_ is_node_index) + { + (void)is_node_index; + typedef typename IndexType >::iterator index_it; + + index_it *ihdr = block_header_t::to_first_header(block_header); + return this->priv_generic_named_destroy_impl(*ihdr, index, table); + } + + template + bool priv_generic_named_destroy + (block_header_t *block_header, + IndexType > &index, + detail::in_place_interface &table, + detail::false_ is_node_index) + { + (void)is_node_index; + CharT *name = static_cast(block_header->template name()); + return this->priv_generic_named_destroy(name, index, table, is_intrusive_t()); + } + + template + bool priv_generic_named_destroy(const CharT *name, + IndexType > &index, + detail::in_place_interface &table, + detail::true_ is_intrusive_index) + { + (void)is_intrusive_index; + typedef IndexType > index_type; + typedef detail::index_key index_key_t; + typedef typename index_type::iterator index_it; + typedef typename index_type::value_type intrusive_value_type; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Find name in index + detail::intrusive_compare_key key + (name, std::char_traits::length(name)); + index_it it = index.find(key); + + //If not found, return false + if(it == index.end()){ + //This name is not present in the index, wrong pointer or name! + //assert(0); + return false; + } + + block_header_t *ctrl_data = it->get_block_header(); + intrusive_value_type *iv = intrusive_value_type::get_intrusive_value_type(ctrl_data); + void *memory = iv; + void *values = ctrl_data->value(); + std::size_t num = ctrl_data->m_value_bytes/table.size; + + //Sanity check + assert((ctrl_data->m_value_bytes % table.size) == 0); + assert(sizeof(CharT) == ctrl_data->sizeof_char()); + + //Erase node from index + index.erase(it); + + //Destroy the headers + ctrl_data->~block_header_t(); + iv->~intrusive_value_type(); + + //Call destructors and free memory + std::size_t destroyed; + table.destroy_n(values, num, destroyed); + this->deallocate(memory); + return true; + } + + template + bool priv_generic_named_destroy(const CharT *name, + IndexType > &index, + detail::in_place_interface &table, + detail::false_ is_intrusive_index) + { + (void)is_intrusive_index; + typedef IndexType > index_type; + typedef typename index_type::iterator index_it; + typedef typename index_type::key_type key_type; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Try to find the name in the index + index_it it = index.find(key_type (name, + std::char_traits::length(name))); + + //If not found, return false + if(it == index.end()){ + //This name is not present in the index, wrong pointer or name! + assert(0); + return false; + } + return this->priv_generic_named_destroy_impl(it, index, table); + } + + template + bool priv_generic_named_destroy_impl + (const typename IndexType >::iterator &it, + IndexType > &index, + detail::in_place_interface &table) + { + typedef IndexType > index_type; + typedef typename index_type::iterator index_it; + + //Get allocation parameters + block_header_t *ctrl_data = reinterpret_cast + (detail::get_pointer(it->second.m_ptr)); + char *stored_name = detail::char_ptr_cast(it->first.name()); + (void)stored_name; + + //Check if the distance between the name pointer and the memory pointer + //is correct (this can detect incorrect type in destruction) + std::size_t num = ctrl_data->m_value_bytes/table.size; + void *values = ctrl_data->value(); + + //Sanity check + assert((ctrl_data->m_value_bytes % table.size) == 0); + assert((void*)stored_name == ctrl_data->template name()); + assert(sizeof(CharT) == ctrl_data->sizeof_char()); + + //Erase node from index + index.erase(it); + + //Destroy the header + ctrl_data->~block_header_t(); + + void *memory; + if(is_node_index_t::value){ + index_it *ihdr = block_header_t:: + to_first_header(ctrl_data); + ihdr->~index_it(); + memory = ihdr; + } + else{ + memory = ctrl_data; + } + + //Call destructors and free memory + std::size_t destroyed; + table.destroy_n(values, num, destroyed); + this->deallocate(memory); + return true; + } + + template + void * priv_generic_named_construct(std::size_t type, + const CharT *name, + std::size_t num, + bool try2find, + bool dothrow, + detail::in_place_interface &table, + IndexType > &index, + detail::true_ is_intrusive) + { + (void)is_intrusive; + std::size_t namelen = std::char_traits::length(name); + + block_header_t block_info ( table.size*num + , table.alignment + , type + , sizeof(CharT) + , namelen); + + typedef IndexType > index_type; + typedef typename index_type::iterator index_it; + typedef std::pair index_ib; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Insert the node. This can throw. + //First, we want to know if the key is already present before + //we allocate any memory, and if the key is not present, we + //want to allocate all memory in a single buffer that will + //contain the name and the user buffer. + // + //Since equal_range(key) + insert(hint, value) approach is + //quite inefficient in container implementations + //(they re-test if the position is correct), I've chosen + //to insert the node, do an ugly un-const cast and modify + //the key (which is a smart pointer) to an equivalent one + index_ib insert_ret; + + typename index_type::insert_commit_data commit_data; + typedef typename index_type::value_type intrusive_value_type; + + BOOST_TRY{ + detail::intrusive_compare_key key(name, namelen); + insert_ret = index.insert_check(key, commit_data); + } + //Ignore exceptions + BOOST_CATCH(...){ + if(dothrow) + BOOST_RETHROW + return 0; + } + BOOST_CATCH_END + + index_it it = insert_ret.first; + + //If found and this is find or construct, return data + //else return null + if(!insert_ret.second){ + if(try2find){ + return it->get_block_header()->value(); + } + return 0; + } + + //Allocates buffer for name + data, this can throw (it hurts) + void *buffer_ptr; + + //Check if there is enough memory + if(dothrow){ + buffer_ptr = this->allocate + (block_info.total_size_with_header()); + } + else{ + buffer_ptr = this->allocate + (block_info.total_size_with_header(), std::nothrow_t()); + if(!buffer_ptr) + return 0; + } + + //Now construct the intrusive hook plus the header + intrusive_value_type * intrusive_hdr = new(buffer_ptr) intrusive_value_type(); + block_header_t * hdr = new(intrusive_hdr->get_block_header())block_header_t(block_info); + void *ptr = 0; //avoid gcc warning + ptr = hdr->value(); + + //Copy name to memory segment and insert data + CharT *name_ptr = static_cast(hdr->template name()); + std::char_traits::copy(name_ptr, name, namelen+1); + + BOOST_TRY{ + //Now commit the insertion using previous context data + it = index.insert_commit(*intrusive_hdr, commit_data); + } + //Ignore exceptions + BOOST_CATCH(...){ + if(dothrow) + BOOST_RETHROW + return 0; + } + BOOST_CATCH_END + + //Initialize the node value_eraser to erase inserted node + //if something goes wrong + detail::value_eraser value_eraser(index, it); + + //Avoid constructions if constructor is trivial + //Build scoped ptr to avoid leaks with constructor exception + detail::mem_algo_deallocator mem + (buffer_ptr, *static_cast(this)); + + //Construct array, this can throw + detail::array_construct(ptr, num, table); + + //All constructors successful, we don't want to release memory + mem.release(); + //Release node value_eraser since construction was successful + value_eraser.release(); + return ptr; + } + + //!Generic named new function for + //!named functions + template + void * priv_generic_named_construct(std::size_t type, + const CharT *name, + std::size_t num, + bool try2find, + bool dothrow, + detail::in_place_interface &table, + IndexType > &index, + detail::false_ is_intrusive) + { + (void)is_intrusive; + std::size_t namelen = std::char_traits::length(name); + + block_header_t block_info ( table.size*num + , table.alignment + , type + , sizeof(CharT) + , namelen); + + typedef IndexType > index_type; + typedef typename index_type::key_type key_type; + typedef typename index_type::mapped_type mapped_type; + typedef typename index_type::value_type value_type; + typedef typename index_type::iterator index_it; + typedef std::pair index_ib; + + //------------------------------- + boost::interprocess::scoped_lock guard(m_header); + //------------------------------- + //Insert the node. This can throw. + //First, we want to know if the key is already present before + //we allocate any memory, and if the key is not present, we + //want to allocate all memory in a single buffer that will + //contain the name and the user buffer. + // + //Since equal_range(key) + insert(hint, value) approach is + //quite inefficient in container implementations + //(they re-test if the position is correct), I've chosen + //to insert the node, do an ugly un-const cast and modify + //the key (which is a smart pointer) to an equivalent one + index_ib insert_ret; + BOOST_TRY{ + insert_ret = index.insert(value_type(key_type (name, namelen), + mapped_type(0))); + } + //Ignore exceptions + BOOST_CATCH(...){ + if(dothrow) + BOOST_RETHROW; + return 0; + } + BOOST_CATCH_END + + index_it it = insert_ret.first; + + //If found and this is find or construct, return data + //else return null + if(!insert_ret.second){ + if(try2find){ + block_header_t *hdr = static_cast + (detail::get_pointer(it->second.m_ptr)); + return hdr->value(); + } + return 0; + } + //Initialize the node value_eraser to erase inserted node + //if something goes wrong + detail::value_eraser value_eraser(index, it); + + //Allocates buffer for name + data, this can throw (it hurts) + void *buffer_ptr; + block_header_t * hdr; + + //Allocate and construct the headers + if(is_node_index_t::value){ + std::size_t total_size = block_info.total_size_with_header(); + if(dothrow){ + buffer_ptr = this->allocate(total_size); + } + else{ + buffer_ptr = this->allocate(total_size, std::nothrow_t()); + if(!buffer_ptr) + return 0; + } + index_it *idr = new(buffer_ptr) index_it(it); + hdr = block_header_t::from_first_header(idr); + } + else{ + if(dothrow){ + buffer_ptr = this->allocate(block_info.total_size()); + } + else{ + buffer_ptr = this->allocate(block_info.total_size(), std::nothrow_t()); + if(!buffer_ptr) + return 0; + } + hdr = static_cast(buffer_ptr); + } + + hdr = new(hdr)block_header_t(block_info); + void *ptr = 0; //avoid gcc warning + ptr = hdr->value(); + + //Copy name to memory segment and insert data + CharT *name_ptr = static_cast(hdr->template name()); + std::char_traits::copy(name_ptr, name, namelen+1); + + //Do the ugly cast, please mama, forgive me! + //This new key points to an identical string, so it must have the + //same position than the overwritten key according to the predicate + const_cast(it->first).name(name_ptr); + it->second.m_ptr = hdr; + + //Build scoped ptr to avoid leaks with constructor exception + detail::mem_algo_deallocator mem + (buffer_ptr, *static_cast(this)); + + //Construct array, this can throw + detail::array_construct(ptr, num, table); + + //All constructors successful, we don't want to release memory + mem.release(); + + //Release node value_eraser since construction was successful + value_eraser.release(); + return ptr; + } + + private: + //!Returns the this pointer + segment_manager *get_this_pointer() + { return this; } + + typedef typename MemoryAlgorithm::mutex_family::recursive_mutex_type rmutex; + + //!This struct includes needed data and derives from + //!rmutex to allow EBO when using null interprocess_mutex + struct header_t + : public rmutex + { + named_index_t m_named_index; + unique_index_t m_unique_index; + + header_t(Base *restricted_segment_mngr) + : m_named_index (restricted_segment_mngr) + , m_unique_index(restricted_segment_mngr) + {} + } m_header; + /// @endcond +}; + + +}} //namespace boost { namespace interprocess + +#include + +#endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_HPP + diff --git a/thirdparty/boost/interprocess/shared_memory_object.hpp b/thirdparty/boost/interprocess/shared_memory_object.hpp new file mode 100644 index 0000000..71478a9 --- /dev/null +++ b/thirdparty/boost/interprocess/shared_memory_object.hpp @@ -0,0 +1,349 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP +#define BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //std::remove +#include + +#ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS +# include //O_CREAT, O_*... +# include //shm_xxx +# include //ftruncate, close +# include //mode_t, S_IRWXG, S_IRWXO, S_IRWXU, +#else +// +#endif + +//!\file +//!Describes a shared memory object management class. + +namespace boost { +namespace interprocess { + +//!A class that wraps a shared memory mapping that can be used to +//!create mapped regions from the mapped files +class shared_memory_object +{ + /// @cond + //Non-copyable and non-assignable + shared_memory_object(const shared_memory_object &); + shared_memory_object &operator=(const shared_memory_object &); + /// @endcond + + public: + + //!Default constructor. Represents an empty shared_memory_object. + shared_memory_object(); + + //!Creates a shared memory object with name "name" and mode "mode", with the access mode "mode" + //!If the file previously exists, throws an error.*/ + shared_memory_object(create_only_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoCreate, name, mode); } + + //!Tries to create a shared memory object with name "name" and mode "mode", with the + //!access mode "mode". If the file previously exists, it tries to open it with mode "mode". + //!Otherwise throws an error. + shared_memory_object(open_or_create_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode); } + + //!Tries to open a shared memory object with name "name", with the access mode "mode". + //!If the file does not previously exist, it throws an error. + shared_memory_object(open_only_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoOpen, name, mode); } + + //!Moves the ownership of "moved"'s shared memory object to *this. + //!After the call, "moved" does not represent any shared memory object. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + shared_memory_object + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + shared_memory_object(shared_memory_object &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s shared memory to *this. + //!After the call, "moved" does not represent any shared memory. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + shared_memory_object &operator= + (detail::moved_object &moved) + { + shared_memory_object tmp(moved); + this->swap(tmp); + return *this; + } + #else + shared_memory_object &operator=(shared_memory_object &&moved) + { + shared_memory_object tmp(move(moved)); + this->swap(tmp); + return *this; + } + #endif + + //!Swaps the shared_memory_objects. Does not throw + void swap(shared_memory_object &other); + + //!Erases a shared memory object from the system. + //!Returns false on error. Never throws + static bool remove(const char *name); + + //!Sets the size of the shared memory mapping + void truncate(offset_t length); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. All mapped regions are still + //!valid after destruction. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~shared_memory_object(); + + //!Returns the name of the file. + const char *get_name() const; + + //!Returns the name of the file + //!used in the constructor + bool get_size(offset_t &size) const; + + //!Returns access mode + mode_t get_mode() const; + + //!Returns mapping handle. Never throws. + mapping_handle_t get_mapping_handle() const; + + /// @cond + private: + + //!Closes a previously opened file mapping. Never throws. + void priv_close(); + + //!Closes a previously opened file mapping. Never throws. + bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode); + + file_handle_t m_handle; + mode_t m_mode; + std::string m_filename; + /// @endcond +}; + +inline shared_memory_object::shared_memory_object() + : m_handle(file_handle_t(detail::invalid_file())) +{} + +inline shared_memory_object::~shared_memory_object() +{ this->priv_close(); } + + +inline const char *shared_memory_object::get_name() const +{ return m_filename.c_str(); } + +inline bool shared_memory_object::get_size(offset_t &size) const +{ return detail::get_file_size((file_handle_t)m_handle, size); } + +inline void shared_memory_object::swap(shared_memory_object &other) +{ + std::swap(m_handle, other.m_handle); + std::swap(m_mode, other.m_mode); + m_filename.swap(other.m_filename); +} + +inline mapping_handle_t shared_memory_object::get_mapping_handle() const +{ return detail::mapping_handle_from_file_handle(m_handle); } + +inline mode_t shared_memory_object::get_mode() const +{ return m_mode; } + +#if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS) + +inline bool shared_memory_object::priv_open_or_create + (detail::create_enum_t type, const char *filename, mode_t mode) +{ + m_filename = filename; + std::string shmfile; + detail::create_tmp_dir_and_get_filename(filename, shmfile); + + //Set accesses + if (mode != read_write && mode != read_only){ + error_info err = other_error; + throw interprocess_exception(err); + } + + switch(type){ + case detail::DoOpen: + m_handle = detail::open_existing_file(shmfile.c_str(), mode, true); + break; + case detail::DoCreate: + m_handle = detail::create_new_file(shmfile.c_str(), mode, true); + break; + case detail::DoOpenOrCreate: + m_handle = detail::create_or_open_file(shmfile.c_str(), mode, true); + break; + default: + { + error_info err = other_error; + throw interprocess_exception(err); + } + } + + //Check for error + if(m_handle == detail::invalid_file()){ + error_info err = system_error_code(); + this->priv_close(); + throw interprocess_exception(err); + } + + m_mode = mode; + return true; +} + +inline bool shared_memory_object::remove(const char *filename) +{ + try{ + //Make sure a temporary path is created for shared memory + std::string shmfile; + detail::tmp_filename(filename, shmfile); + return std::remove(shmfile.c_str()) == 0; + } + catch(...){ + return false; + } +} + +inline void shared_memory_object::truncate(offset_t length) +{ + if(!detail::truncate_file(m_handle, length)){ + error_info err = system_error_code(); + throw interprocess_exception(err); + } +} + +inline void shared_memory_object::priv_close() +{ + if(m_handle != detail::invalid_file()){ + detail::close_file(m_handle); + m_handle = detail::invalid_file(); + } +} + +#else //!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS) + +inline bool shared_memory_object::priv_open_or_create + (detail::create_enum_t type, + const char *filename, + mode_t mode) +{ + #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY + detail::add_leading_slash(filename, m_filename); + #else + detail::create_tmp_dir_and_get_filename(filename, m_filename); + #endif + + //Create new mapping + int oflag = 0; + if(mode == read_only){ + oflag |= O_RDONLY; + } + else if(mode == read_write){ + oflag |= O_RDWR; + } + else{ + error_info err(mode_error); + throw interprocess_exception(err); + } + + switch(type){ + case detail::DoOpen: + //No addition + break; + case detail::DoCreate: + oflag |= (O_CREAT | O_EXCL); + break; + case detail::DoOpenOrCreate: + oflag |= O_CREAT; + break; + default: + { + error_info err = other_error; + throw interprocess_exception(err); + } + } + + //Open file using POSIX API + m_handle = shm_open(m_filename.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU); + + //Check for error + if(m_handle == -1){ + error_info err = errno; + this->priv_close(); + throw interprocess_exception(err); + } + + m_filename = filename; + m_mode = mode; + return true; +} + +inline bool shared_memory_object::remove(const char *filename) +{ + try{ + std::string file_str; + #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY + detail::add_leading_slash(filename, file_str); + #else + detail::tmp_filename(filename, file_str); + #endif + return 0 != shm_unlink(file_str.c_str()); + } + catch(...){ + return false; + } +} + +inline void shared_memory_object::truncate(offset_t length) +{ + if(0 != ftruncate(m_handle, length)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline void shared_memory_object::priv_close() +{ + if(m_handle != -1){ + ::close(m_handle); + m_handle = -1; + } +} + +#endif + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP diff --git a/thirdparty/boost/interprocess/smart_ptr/deleter.hpp b/thirdparty/boost/interprocess/smart_ptr/deleter.hpp new file mode 100644 index 0000000..14fe0cf --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/deleter.hpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DELETER_HPP +#define BOOST_INTERPROCESS_DELETER_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include + +//!\file +//!Describes the functor to delete objects from the segment. + +namespace boost { +namespace interprocess { + +//!A deleter that uses the segment manager's destroy_ptr +//!function to destroy the passed pointer resource. +//! +//!This deleter is used +template +class deleter +{ + public: + typedef typename detail::pointer_to_other + ::type pointer; + + private: + typedef typename detail::pointer_to_other + ::type segment_manager_pointer; + + segment_manager_pointer mp_mngr; + + public: + deleter(segment_manager_pointer pmngr) + : mp_mngr(pmngr) + {} + + void operator()(const pointer &p) + { mp_mngr->destroy_ptr(detail::get_pointer(p)); } +}; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_DELETER_HPP diff --git a/thirdparty/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp new file mode 100644 index 0000000..b02912b --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/detail/bad_weak_ptr.hpp +// +// (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003 +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +namespace boost{ +namespace interprocess{ + +class bad_weak_ptr + : public std::exception +{ + public: + + virtual char const * what() const throw() + { return "boost::interprocess::bad_weak_ptr"; } +}; + +} // namespace interprocess +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_BAD_WEAK_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/detail/shared_count.hpp b/thirdparty/boost/interprocess/smart_ptr/detail/shared_count.hpp new file mode 100644 index 0000000..228555a --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,315 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/detail/shared_count.hpp +// +// (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003 +// (C) Copyright Peter Dimov 2004-2005 +// (C) Copyright Ion Gaztanaga 2006-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED +#define BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include // std::less + +namespace boost { +namespace interprocess { +namespace detail{ + +template +class weak_count; + +template +class shared_count +{ + public: + typedef typename detail::pointer_to_other + ::type pointer; + + private: + typedef sp_counted_impl_pd counted_impl; + typedef typename detail::pointer_to_other + ::type counted_impl_ptr; + typedef typename detail::pointer_to_other + ::type counted_base_ptr; + typedef typename VoidAllocator::template rebind + ::other counted_impl_allocator; + typedef typename detail::pointer_to_other + ::type const_deleter_pointer; + typedef typename detail::pointer_to_other + ::type const_allocator_pointer; + + pointer m_px; + counted_impl_ptr m_pi; + + template + friend class weak_count; + + template + friend class shared_count; + + public: + + shared_count() + : m_px(0), m_pi(0) // nothrow + {} + + template + shared_count(const Ptr &p, const VoidAllocator &a, Deleter d) + : m_px(p), m_pi(0) + { + BOOST_TRY{ + if(p){ + counted_impl_allocator alloc(a); + m_pi = alloc.allocate(1); + //Anti-exception deallocator + scoped_ptr > + deallocator(m_pi, alloc); + //It's more correct to use VoidAllocator::construct but + //this needs copy constructor and we don't like it + new(detail::get_pointer(m_pi))counted_impl(p, a, d); + deallocator.release(); + } + } + BOOST_CATCH (...){ + d(p); // delete p + BOOST_RETHROW + } + BOOST_CATCH_END + } + + ~shared_count() // nothrow + { + if( m_pi != 0 ) + m_pi->release(); + } + + shared_count(shared_count const & r) + : m_px(r.m_px), m_pi(r.m_pi) // nothrow + { if( m_pi != 0 ) m_pi->add_ref_copy(); } + + //this is a test + template + explicit shared_count(shared_count const & r) + : m_px(r.m_px), m_pi(r.m_pi) // nothrow + { if( m_pi != 0 ) m_pi->add_ref_copy(); } + + //this is a test + template + explicit shared_count(const pointer & ptr, shared_count const & r) + : m_px(ptr), m_pi(r.m_pi) // nothrow + { if( m_pi != 0 ) m_pi->add_ref_copy(); } + +/* + explicit shared_count(weak_count const & r) + // throws bad_weak_ptr when r.use_count() == 0 + : m_pi( r.m_pi ) + { + if( m_pi == 0 || !m_pi->add_ref_lock() ){ + boost::throw_exception( boost::interprocess::bad_weak_ptr() ); + } + } +*/ + template + explicit shared_count(weak_count const & r) + // throws bad_weak_ptr when r.use_count() == 0 + : m_px(r.m_px), m_pi( r.m_pi ) + { + if( m_pi == 0 || !m_pi->add_ref_lock() ){ + throw( boost::interprocess::bad_weak_ptr() ); + } + } + + const pointer &get_pointer() const + { return m_px; } + + pointer &get_pointer() + { return m_px; } + + shared_count & operator= (shared_count const & r) // nothrow + { + m_px = r.m_px; + counted_impl_ptr tmp = r.m_pi; + if( tmp != m_pi ){ + if(tmp != 0) tmp->add_ref_copy(); + if(m_pi != 0) m_pi->release(); + m_pi = tmp; + } + return *this; + } + + template + shared_count & operator= (shared_count const & r) // nothrow + { + m_px = r.m_px; + counted_impl_ptr tmp = r.m_pi; + if( tmp != m_pi ){ + if(tmp != 0) tmp->add_ref_copy(); + if(m_pi != 0) m_pi->release(); + m_pi = tmp; + } + return *this; + } + + void swap(shared_count & r) // nothrow + { detail::do_swap(m_px, r.m_px); detail::do_swap(m_pi, r.m_pi); } + + long use_count() const // nothrow + { return m_pi != 0? m_pi->use_count(): 0; } + + bool unique() const // nothrow + { return use_count() == 1; } + + const_deleter_pointer get_deleter() const + { return m_pi ? m_pi->get_deleter() : 0; } + +// const_allocator_pointer get_allocator() const +// { return m_pi ? m_pi->get_allocator() : 0; } + + template + bool internal_equal (shared_count const & other) const + { return this->m_pi == other.m_pi; } + + template + bool internal_less (shared_count const & other) const + { return std::less()(this->m_pi, other.m_pi); } +}; + +template inline +bool operator==(shared_count const & a, shared_count const & b) +{ return a.internal_equal(b); } + +template inline +bool operator<(shared_count const & a, shared_count const & b) +{ return a.internal_less(b); } + + +template +class weak_count +{ + public: + typedef typename detail::pointer_to_other + ::type pointer; + + private: + typedef sp_counted_impl_pd counted_impl; + typedef typename detail::pointer_to_other + ::type counted_impl_ptr; + typedef typename detail::pointer_to_other + ::type counted_base_ptr; + + pointer m_px; + counted_impl_ptr m_pi; + + template + friend class weak_count; + + template + friend class shared_count; + + public: + + weak_count(): m_px(0), m_pi(0) // nothrow + {} + + template + explicit weak_count(shared_count const & r) + : m_px(r.m_px), m_pi(r.m_pi) // nothrow + { if(m_pi != 0) m_pi->weak_add_ref(); } + + weak_count(weak_count const & r) + : m_px(r.m_px), m_pi(r.m_pi) // nothrow + { if(m_pi != 0) m_pi->weak_add_ref(); } + + template + weak_count(weak_count const & r) + : m_px(r.m_px), m_pi(r.m_pi) // nothrow + { if(m_pi != 0) m_pi->weak_add_ref(); } + + ~weak_count() // nothrow + { if(m_pi != 0) m_pi->weak_release(); } + + template + weak_count & operator= (shared_count const & r) // nothrow + { + m_px = r.m_px; + counted_impl_ptr tmp = r.m_pi; + if(tmp != 0) tmp->weak_add_ref(); + if(m_pi != 0) m_pi->weak_release(); + m_pi = tmp; + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + counted_impl_ptr tmp = r.m_pi; + if(tmp != 0) tmp->weak_add_ref(); + if(m_pi != 0) m_pi->weak_release(); + m_pi = tmp; + return *this; + } + + void set_pointer(const pointer &ptr) + { m_px = ptr; } + + template + weak_count & operator= (weak_count const& r) // nothrow + { + counted_impl_ptr tmp = r.m_pi; + if(tmp != 0) tmp->weak_add_ref(); + if(m_pi != 0) m_pi->weak_release(); + m_pi = tmp; + return *this; + } + + void swap(weak_count & r) // nothrow + { detail::do_swap(m_px, r.m_px); detail::do_swap(m_pi, r.m_pi); } + + long use_count() const // nothrow + { return m_pi != 0? m_pi->use_count() : 0; } + + template + bool internal_equal (weak_count const & other) const + { return this->m_pi == other.m_pi; } + + template + bool internal_less (weak_count const & other) const + { return std::less()(this->m_pi, other.m_pi); } +}; + +template inline +bool operator==(weak_count const & a, weak_count const & b) +{ return a.internal_equal(b); } + +template inline +bool operator<(weak_count const & a, weak_count const & b) +{ return a.internal_less(b); } + +} // namespace detail +} // namespace interprocess +} // namespace boost + + +#include + + +#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 0000000..7cb5866 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,7 @@ +#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED +#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED + +# include + +#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED + diff --git a/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp new file mode 100644 index 0000000..1333468 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED +#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2007-2008 Ion Gaztanaga +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include + +#include +#include + +namespace boost { + +namespace interprocess { + +namespace detail { + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + boost::uint32_t use_count_; // #shared + boost::uint32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + {} + + ~sp_counted_base() // nothrow + {} + + void add_ref_copy() + { + detail::atomic_inc32( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + if( detail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp ) + return true; + } + } + + bool ref_release() // nothrow + { return 1 == detail::atomic_dec32( &use_count_ ); } + + void weak_add_ref() // nothrow + { detail::atomic_inc32( &weak_count_ ); } + + bool weak_release() // nothrow + { return 1 == detail::atomic_dec32( &weak_count_ ); } + + long use_count() const // nothrow + { return (long)static_cast( use_count_ ); } +}; + +} // namespace detail + +} // namespace interprocess + +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..6410df5 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,117 @@ +#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED +#define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// This file is the adaptation for shared memory memory mapped +// files of boost/detail/sp_counted_impl.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Ion Gaztanaga +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +#include +#include +#include + +namespace boost { + +namespace interprocess { + +namespace detail { + +template +class sp_counted_impl_pd + : public sp_counted_base + , A::template rebind< sp_counted_impl_pd >::other + , D // copy constructor must not throw +{ + private: + typedef sp_counted_impl_pd this_type; + typedef typename A::template rebind + ::other this_allocator; + typedef typename A::template rebind + ::other const_this_allocator; + typedef typename this_allocator::pointer this_pointer; + + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); + + typedef typename detail::pointer_to_other + ::type const_deleter_pointer; + + typedef typename detail::pointer_to_other + ::type const_allocator_pointer; + + typedef typename D::pointer pointer; + pointer m_ptr; + + public: + // pre: d(p) must not throw + template + sp_counted_impl_pd(const Ptr & p, const A &a, const D &d ) + : this_allocator(a), D(d), m_ptr(p) + {} + + const_deleter_pointer get_deleter() const + { return const_deleter_pointer(&static_cast(*this)); } + + const_allocator_pointer get_allocator() const + { return const_allocator_pointer(&static_cast(*this)); } + + void dispose() // nothrow + { static_cast(*this)(m_ptr); } + + void destroy() // nothrow + { + //Self destruction, so get a copy of the allocator + //(in the future we could move it) + this_allocator a_copy(*this); + BOOST_ASSERT(a_copy == *this); + this_pointer this_ptr (this); + //Do it now! + scoped_ptr >(this_ptr, a_copy); + typedef typename this_allocator::value_type value_type; + detail::get_pointer(this_ptr)->~value_type(); + } + + void release() // nothrow + { + if(this->ref_release()){ + this->dispose(); + this->weak_release(); + } + } + + void weak_release() // nothrow + { + if(sp_counted_base::weak_release()){ + this->destroy(); + } + } +}; + + +} // namespace detail + +} // namespace interprocess + +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/enable_shared_from_this.hpp b/thirdparty/boost/interprocess/smart_ptr/enable_shared_from_this.hpp new file mode 100644 index 0000000..4712c7b --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/enable_shared_from_this.hpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/enable_shared_from_this.hpp +// +// (C) Copyright Peter Dimov 2002 +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_INTERPROCESS_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +#include +#include + +#include +#include +#include + +//!\file +//!Describes an utility to form a shared pointer from this + +namespace boost{ +namespace interprocess{ + +template +class enable_shared_from_this +{ + /// @cond + protected: + enable_shared_from_this() + {} + + enable_shared_from_this(enable_shared_from_this const &) + {} + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { return *this; } + + ~enable_shared_from_this() + {} + /// @endcond + + public: + shared_ptr shared_from_this() + { + shared_ptr p(_internal_weak_this); + BOOST_ASSERT(detail::get_pointer(p.get()) == this); + return p; + } + + shared_ptr shared_from_this() const + { + shared_ptr p(_internal_weak_this); + BOOST_ASSERT(detail::get_pointer(p.get()) == this); + return p; + } + + private: + /// @cond + typedef T element_type; + mutable weak_ptr _internal_weak_this; + /// @endcond +}; + +} // namespace interprocess +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + diff --git a/thirdparty/boost/interprocess/smart_ptr/intrusive_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/intrusive_ptr.hpp new file mode 100644 index 0000000..b60c58a --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/intrusive_ptr.hpp @@ -0,0 +1,293 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp +// +// (C) Copyright Peter Dimov 2001, 2002 +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED + +//!\file +//!Describes an intrusive ownership pointer. + +#include +#include + +#include +#include + +#include // for std::less +#include // for std::basic_ostream + + +namespace boost { +namespace interprocess { + +//!The intrusive_ptr class template stores a pointer to an object +//!with an embedded reference count. intrusive_ptr is parameterized on +//!T (the type of the object pointed to) and VoidPointer(a void pointer type +//!that defines the type of pointer that intrusive_ptr will store). +//!intrusive_ptr defines a class with a T* member whereas +//!intrusive_ptr > defines a class with a offset_ptr member. +//!Relies on unqualified calls to: +//! +//! void intrusive_ptr_add_ref(T * p); +//! void intrusive_ptr_release(T * p); +//! +//! with (p != 0) +//! +//!The object is responsible for destroying itself. +template +class intrusive_ptr +{ + public: + //!Provides the type of the internal stored pointer. + typedef typename detail::pointer_to_other::type pointer; + //!Provides the type of the stored pointer. + typedef T element_type; + + /// @cond + private: + typedef VoidPointer VP; + typedef intrusive_ptr this_type; + typedef pointer this_type::*unspecified_bool_type; + /// @endcond + + public: + //!Constructor. Initializes internal pointer to 0. + //!Does not throw + intrusive_ptr(): m_ptr(0) + {} + + //!Constructor. Copies pointer and if "p" is not zero and + //!"add_ref" is true calls intrusive_ptr_add_ref(get_pointer(p)). + //!Does not throw + intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p) + { + if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(detail::get_pointer(m_ptr)); + } + + //!Copy constructor. Copies the internal pointer and if "p" is not + //!zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw + intrusive_ptr(intrusive_ptr const & rhs) + : m_ptr(rhs.m_ptr) + { + if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr)); + } + + //!Constructor from related. Copies the internal pointer and if "p" is not + //!zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw + template intrusive_ptr + (intrusive_ptr const & rhs) + : m_ptr(rhs.get()) + { + if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr)); + } + + //!Destructor. If internal pointer is not 0, calls + //!intrusive_ptr_release(get_pointer(m_ptr)). Does not throw + ~intrusive_ptr() + { + if(m_ptr != 0) intrusive_ptr_release(detail::get_pointer(m_ptr)); + } + + //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + template intrusive_ptr & operator= + (intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + intrusive_ptr & operator=(pointer rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Returns a reference to the internal pointer. + //!Does not throw + pointer &get() + { return m_ptr; } + + //!Returns a reference to the internal pointer. + //!Does not throw + const pointer &get() const + { return m_ptr; } + + //!Returns *get(). + //!Does not throw + T & operator*() const + { return *m_ptr; } + + //!Returns *get(). + //!Does not throw + const pointer &operator->() const + { return m_ptr; } + + //!Returns get(). + //!Does not throw + pointer &operator->() + { return m_ptr; } + + //!Conversion to boolean. + //!Does not throw + operator unspecified_bool_type () const + { return m_ptr == 0? 0: &this_type::m_ptr; } + + //!Not operator. + //!Does not throw + bool operator! () const + { return m_ptr == 0; } + + //!Exchanges the contents of the two smart pointers. + //!Does not throw + void swap(intrusive_ptr & rhs) + { detail::do_swap(m_ptr, rhs.m_ptr); } + + /// @cond + private: + pointer m_ptr; + /// @endcond +}; + +//!Returns a.get() == b.get(). +//!Does not throw +template inline +bool operator==(intrusive_ptr const & a, + intrusive_ptr const & b) +{ return a.get() == b.get(); } + +//!Returns a.get() != b.get(). +//!Does not throw +template inline +bool operator!=(intrusive_ptr const & a, + intrusive_ptr const & b) +{ return a.get() != b.get(); } + +//!Returns a.get() == b. +//!Does not throw +template inline +bool operator==(intrusive_ptr const & a, + const typename intrusive_ptr::pointer &b) +{ return a.get() == b; } + +//!Returns a.get() != b. +//!Does not throw +template inline +bool operator!=(intrusive_ptr const & a, + const typename intrusive_ptr::pointer &b) +{ return a.get() != b; } + +//!Returns a == b.get(). +//!Does not throw +template inline +bool operator==(const typename intrusive_ptr::pointer &a, + intrusive_ptr const & b) +{ return a == b.get(); } + +//!Returns a != b.get(). +//!Does not throw +template inline +bool operator!=(const typename intrusive_ptr::pointer &a, + intrusive_ptr const & b) +{ return a != b.get(); } + +//!Returns a.get() < b.get(). +//!Does not throw +template inline +bool operator<(intrusive_ptr const & a, + intrusive_ptr const & b) +{ + return std::less::pointer>() + (a.get(), b.get()); +} + +//!Exchanges the contents of the two intrusive_ptrs. +//!Does not throw +template inline +void swap(intrusive_ptr & lhs, + intrusive_ptr & rhs) +{ lhs.swap(rhs); } + +// operator<< +template +inline std::basic_ostream & operator<< + (std::basic_ostream & os, intrusive_ptr const & p) +{ os << p.get(); return os; } + +//!Returns p.get(). +//!Does not throw +template +inline typename boost::interprocess::intrusive_ptr::pointer + get_pointer(intrusive_ptr p) +{ return p.get(); } + +/*Emulates static cast operator. Does not throw*/ +/* +template +inline boost::interprocess::intrusive_ptr static_pointer_cast + (boost::interprocess::intrusive_ptr const & p) +{ return do_static_cast(p.get()); } +*/ +/*Emulates const cast operator. Does not throw*/ +/* +template +inline boost::interprocess::intrusive_ptr const_pointer_cast + (boost::interprocess::intrusive_ptr const & p) +{ return do_const_cast(p.get()); } +*/ + +/*Emulates dynamic cast operator. Does not throw*/ +/* +template +inline boost::interprocess::intrusive_ptr dynamic_pointer_cast + (boost::interprocess::intrusive_ptr const & p) +{ return do_dynamic_cast(p.get()); } +*/ + +/*Emulates reinterpret cast operator. Does not throw*/ +/* +template +inline boost::interprocess::intrusive_ptrreinterpret_pointer_cast + (boost::interprocess::intrusive_ptr const & p) +{ return do_reinterpret_cast(p.get()); } +*/ + +} // namespace interprocess + +/// @cond + +#if defined(_MSC_VER) && (_MSC_VER < 1400) +//!Returns p.get(). +//!Does not throw +template +inline T *get_pointer(boost::interprocess::intrusive_ptr p) +{ return p.get(); } +#endif + +/// @endcond + +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/scoped_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/scoped_ptr.hpp new file mode 100644 index 0000000..26a16d8 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/scoped_ptr.hpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/scoped_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// (C) Copyright Peter Dimov 2001, 2002 +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SCOPED_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_SCOPED_PTR_HPP_INCLUDED + +#include +#include +#include +#include + +//!\file +//!Describes the smart pointer scoped_ptr + +namespace boost { +namespace interprocess { + +//!scoped_ptr stores a pointer to a dynamically allocated object. +//!The object pointed to is guaranteed to be deleted, either on destruction +//!of the scoped_ptr, or via an explicit reset. The user can avoid this +//!deletion using release(). +//!scoped_ptr is parameterized on T (the type of the object pointed to) and +//!Deleter (the functor to be executed to delete the internal pointer). +//!The internal pointer will be of the same pointer type as typename +//!Deleter::pointer type (that is, if typename Deleter::pointer is +//!offset_ptr, the internal pointer will be offset_ptr). +template +class scoped_ptr + : private Deleter +{ + /// @cond + scoped_ptr(scoped_ptr const &); + scoped_ptr & operator=(scoped_ptr const &); + + typedef scoped_ptr this_type; + typedef typename detail::add_reference::type reference; + /// @endcond + + public: + + typedef T element_type; + typedef Deleter deleter_type; + typedef typename detail::pointer_type::type pointer; + + //!Provides the type of the internal stored pointer +// typedef typename detail::pointer_to_other +// ::type pointer; + + //!Constructs a scoped_ptr, storing a copy of p(which can be 0) and d. + //!Does not throw. + explicit scoped_ptr(const pointer &p = 0, const Deleter &d = Deleter()) + : Deleter(d), m_ptr(p) // throws if pointer/Deleter copy ctor throws + {} + + //!If the stored pointer is not 0, destroys the object pointed to by the stored pointer. + //!calling the operator() of the stored deleter. Never throws + ~scoped_ptr() + { + if(m_ptr){ + Deleter &del = static_cast(*this); + del(m_ptr); + } + } + + //!Deletes the object pointed to by the stored pointer and then + //!stores a copy of p. Never throws + void reset(const pointer &p = 0) // never throws + { BOOST_ASSERT(p == 0 || p != m_ptr); this_type(p).swap(*this); } + + //!Deletes the object pointed to by the stored pointer and then + //!stores a copy of p and a copy of d. + void reset(const pointer &p, const Deleter &d) // never throws + { BOOST_ASSERT(p == 0 || p != m_ptr); this_type(p).swap(*this); } + + //!Assigns internal pointer as 0 and returns previous pointer. This will + //!avoid deletion on destructor + pointer release() + { pointer tmp(m_ptr); m_ptr = 0; return tmp; } + + //!Returns a reference to the object pointed to by the stored pointer. + //!Never throws. + reference operator*() const + { BOOST_ASSERT(m_ptr != 0); return *m_ptr; } + + //!Returns the internal stored pointer. + //!Never throws. + pointer &operator->() + { BOOST_ASSERT(m_ptr != 0); return m_ptr; } + + //!Returns the internal stored pointer. + //!Never throws. + const pointer &operator->() const + { BOOST_ASSERT(m_ptr != 0); return m_ptr; } + + //!Returns the stored pointer. + //!Never throws. + pointer & get() + { return m_ptr; } + + //!Returns the stored pointer. + //!Never throws. + const pointer & get() const + { return m_ptr; } + + typedef pointer this_type::*unspecified_bool_type; + + //!Conversion to bool + //!Never throws + operator unspecified_bool_type() const + { return m_ptr == 0? 0: &this_type::m_ptr; } + + //!Returns true if the stored pointer is 0. + //!Never throws. + bool operator! () const // never throws + { return m_ptr == 0; } + + //!Exchanges the internal pointer and deleter with other scoped_ptr + //!Never throws. + void swap(scoped_ptr & b) // never throws + { detail::do_swap(*this, b); detail::do_swap(m_ptr, b.m_ptr); } + + /// @cond + private: + pointer m_ptr; + /// @endcond +}; + +//!Exchanges the internal pointer and deleter with other scoped_ptr +//!Never throws. +template inline +void swap(scoped_ptr & a, scoped_ptr & b) +{ a.swap(b); } + +//!Returns a copy of the stored pointer +//!Never throws +template inline +typename scoped_ptr::pointer get_pointer(scoped_ptr const & p) +{ return p.get(); } + +} // namespace interprocess + +/// @cond + +#if defined(_MSC_VER) && (_MSC_VER < 1400) +template inline +T *get_pointer(boost::interprocess::scoped_ptr const & p) +{ return p.get(); } +#endif + +/// @endcond + +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_SCOPED_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/shared_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/shared_ptr.hpp new file mode 100644 index 0000000..4ef5449 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/shared_ptr.hpp @@ -0,0 +1,353 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// (C) Copyright Peter Dimov 2001, 2002, 2003 +// (C) Copyright Ion Gaztanaga 2006-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::basic_ostream + +//!\file +//!Describes the smart pointer shared_ptr + +namespace boost{ +namespace interprocess{ + +template class weak_ptr; +template class enable_shared_from_this; + +namespace detail{ + +template +inline void sp_enable_shared_from_this + (shared_count const & pn, + const typename pointer_to_other ::pointer, + enable_shared_from_this >::type &pe, + const typename shared_count::pointer &px) +{ + if(pe != 0) + pe->_internal_weak_this._internal_assign(pn); +} +/* +template +inline void sp_enable_shared_from_this(shared_count const &, ...) +{} +*/ +} // namespace detail + +//!shared_ptr stores a pointer to a dynamically allocated object. +//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to +//!it is destroyed or reset. +//! +//!shared_ptr is parameterized on +//!T (the type of the object pointed to), VoidAllocator (the void allocator to be used +//!to allocate the auxiliary data) and Deleter (the deleter whose +//!operator() will be used to delete the object. +//! +//!The internal pointer will be of the same pointer type as typename +//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is +//!offset_ptr, the internal pointer will be offset_ptr). +//! +//!Because the implementation uses reference counting, cycles of shared_ptr +//!instances will not be reclaimed. For example, if main() holds a +//!shared_ptr to A, which directly or indirectly holds a shared_ptr back +//!to A, A's use count will be 2. Destruction of the original shared_ptr +//!will leave A dangling with a use count of 1. +//!Use weak_ptr to "break cycles." +template +class shared_ptr +{ + /// @cond + private: + typedef shared_ptr this_type; + /// @endcond + + public: + + typedef T element_type; + typedef T value_type; + typedef typename detail::pointer_to_other + ::type pointer; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + typedef typename detail::pointer_to_other + ::type const_deleter_pointer; + typedef typename detail::pointer_to_other + ::type const_allocator_pointer; + + public: + //!Constructs an empty shared_ptr. + //!Use_count() == 0 && get()== 0. + shared_ptr() + : m_pn() // never throws + {} + + //!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated + //!with a copy of a and the object will be deleted with a copy of d. + //!Requirements: Deleter and A's copy constructor must not throw. + explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter()) + : m_pn(p, a, d) + { + //Check that the pointer passed is of the same type that + //the pointer the allocator defines or it's a raw pointer + typedef typename detail::pointer_to_other::type ParameterPointer; + BOOST_STATIC_ASSERT((detail::is_same::value) || + (detail::is_pointer::value)); + //detail::sp_enable_shared_from_this( m_pn, p, p ); + } + + //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs + //!a shared_ptr that shares ownership with r. Never throws. + template + shared_ptr(shared_ptr const & r) + : m_pn(r.m_pn) // never throws + {} + + //!Constructs a shared_ptr that shares ownership with r and stores + //!a copy of the pointer stored in r. + template + explicit shared_ptr(weak_ptr const & r) + : m_pn(r.m_pn) // may throw + {} + + /// @cond + template + shared_ptr(shared_ptr const & r, detail::static_cast_tag) + : m_pn( pointer(static_cast(detail::get_pointer(r.m_pn.get_pointer()))) + , r.m_pn) + {} + + template + shared_ptr(shared_ptr const & r, detail::const_cast_tag) + : m_pn( pointer(const_cast(detail::get_pointer(r.m_pn.get_pointer()))) + , r.m_pn) + {} + + template + shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag) + : m_pn( pointer(dynamic_cast(detail::get_pointer(r.m_pn.get_pointer()))) + , r.m_pn) + { + if(!m_pn.get_pointer()){ // need to allocate new counter -- the cast failed + m_pn = detail::shared_count(); + } + } + /// @endcond + + //!Equivalent to shared_ptr(r).swap(*this). + //!Never throws + template + shared_ptr & operator=(shared_ptr const & r) + { + m_pn = r.m_pn; // shared_count::op= doesn't throw + return *this; + } + + //!This is equivalent to: + //!this_type().swap(*this); + void reset() + { + this_type().swap(*this); + } + + //!This is equivalent to: + //!this_type(p, a, d).swap(*this); + template + void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter()) + { + //Check that the pointer passed is of the same type that + //the pointer the allocator defines or it's a raw pointer + typedef typename detail::pointer_to_other::type ParameterPointer; + BOOST_STATIC_ASSERT((detail::is_same::value) || + (detail::is_pointer::value)); + this_type(p, a, d).swap(*this); + } + + //!Returns a reference to the + //!pointed type + reference operator* () const // never throws + { BOOST_ASSERT(m_pn.get_pointer() != 0); return *m_pn.get_pointer(); } + + //!Returns the pointer pointing + //!to the owned object + pointer operator-> () const // never throws + { BOOST_ASSERT(m_pn.get_pointer() != 0); return m_pn.get_pointer(); } + + //!Returns the pointer pointing + //!to the owned object + pointer get() const // never throws + { return m_pn.get_pointer(); } + + /// @cond + // implicit conversion to "bool" + void unspecified_bool_type_func() const {} + typedef void (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { return !m_pn.get_pointer() ? 0 : &this_type::unspecified_bool_type_func; } + /// @endcond + + //!Not operator. + //!Returns true if this->get() != 0, false otherwise + bool operator! () const // never throws + { return !m_pn.get_pointer(); } + + //!Returns use_count() == 1. + //!unique() might be faster than use_count() + bool unique() const // never throws + { return m_pn.unique(); } + + //!Returns the number of shared_ptr objects, *this included, + //!that share ownership with *this, or an unspecified nonnegative + //!value when *this is empty. + //!use_count() is not necessarily efficient. Use only for + //!debugging and testing purposes, not for production code. + long use_count() const // never throws + { return m_pn.use_count(); } + + //!Exchanges the contents of the two + //!smart pointers. + void swap(shared_ptr & other) // never throws + { m_pn.swap(other.m_pn); } + + /// @cond + + template + bool _internal_less(shared_ptr const & rhs) const + { return m_pn < rhs.m_pn; } + + const_deleter_pointer get_deleter() const + { return m_pn.get_deleter(); } + +// const_allocator_pointer get_allocator() const +// { return m_pn.get_allocator(); } + + private: + + template friend class shared_ptr; + template friend class weak_ptr; + + detail::shared_count m_pn; // reference counter + /// @endcond +}; // shared_ptr + +template inline +bool operator==(shared_ptr const & a, shared_ptr const & b) +{ return a.get() == b.get(); } + +template inline +bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ return a.get() != b.get(); } + +template inline +bool operator<(shared_ptr const & a, shared_ptr const & b) +{ return a._internal_less(b); } + +template inline +void swap(shared_ptr & a, shared_ptr & b) +{ a.swap(b); } + +template inline +shared_ptr static_pointer_cast(shared_ptr const & r) +{ return shared_ptr(r, detail::static_cast_tag()); } + +template inline +shared_ptr const_pointer_cast(shared_ptr const & r) +{ return shared_ptr(r, detail::const_cast_tag()); } + +template inline +shared_ptr dynamic_pointer_cast(shared_ptr const & r) +{ return shared_ptr(r, detail::dynamic_cast_tag()); } + +// get_pointer() enables boost::mem_fn to recognize shared_ptr +template inline +T * get_pointer(shared_ptr const & p) +{ return p.get(); } + +// operator<< +template inline +std::basic_ostream & operator<< + (std::basic_ostream & os, shared_ptr const & p) +{ os << p.get(); return os; } + +//!Returns the type of a shared pointer +//!of type T with the allocator boost::interprocess::allocator allocator +//!and boost::interprocess::deleter deleter +//!that can be constructed in the given managed segment type. +template +struct managed_shared_ptr +{ + typedef typename ManagedMemory::template allocator::type void_allocator; + typedef typename ManagedMemory::template deleter::type deleter; + typedef shared_ptr< T, void_allocator, deleter> type; +}; + +//!Returns an instance of a shared pointer constructed +//!with the default allocator and deleter from a pointer +//!of type T that has been allocated in the passed managed segment +template +inline typename managed_shared_ptr::type + make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory) +{ + return typename managed_shared_ptr::type + ( constructed_object + , managed_memory.template get_allocator() + , managed_memory.template get_deleter() + ); +} + + +/* +// get_deleter (experimental) +template +typename detail::pointer_to_other, Deleter>::type + get_deleter(shared_ptr const & p) +{ return static_cast(p._internal_get_deleter(typeid(Deleter))); } +*/ +} // namespace interprocess + +/// @cond + +#if defined(_MSC_VER) && (_MSC_VER < 1400) +// get_pointer() enables boost::mem_fn to recognize shared_ptr +template inline +T * get_pointer(boost::interprocess::shared_ptr const & p) +{ return p.get(); } +#endif + +/// @endcond + +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/unique_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/unique_ptr.hpp new file mode 100644 index 0000000..b4cb31b --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/unique_ptr.hpp @@ -0,0 +1,617 @@ +////////////////////////////////////////////////////////////////////////////// +// I, Howard Hinnant, hereby place this code in the public domain. +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of +// Howard Hinnant's unique_ptr emulation code. +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes the smart pointer unique_ptr + +namespace boost{ +namespace interprocess{ + +/// @cond +template class unique_ptr; + +namespace detail { + +template struct unique_ptr_error; + +template +struct unique_ptr_error > +{ + typedef unique_ptr type; +}; + +} //namespace detail { +/// @endcond + +//!Template unique_ptr stores a pointer to an object and deletes that object +//!using the associated deleter when it is itself destroyed (such as when +//!leaving block scope. +//! +//!The unique_ptr provides a semantics of strict ownership. A unique_ptr owns the +//!object it holds a pointer to. +//! +//!A unique_ptr is not CopyConstructible, nor CopyAssignable, however it is +//!MoveConstructible and Move-Assignable. +//! +//!The uses of unique_ptr include providing exception safety for dynamically +//!allocated memory, passing ownership of dynamically allocated memory to a +//!function, and returning dynamically allocated memory from a function +//! +//!A client-supplied template argument D must be a +//!function pointer or functor for which, given a value d of type D and a pointer +//!ptr to a type T*, the expression d(ptr) is +//!valid and has the effect of deallocating the pointer as appropriate for that +//!deleter. D may also be an lvalue-reference to a deleter. +//! +//!If the deleter D maintains state, it is intended that this state stay with +//!the associated pointer as ownership is transferred +//!from unique_ptr to unique_ptr. The deleter state need never be copied, +//!only moved or swapped as pointer ownership +//!is moved around. That is, the deleter need only be MoveConstructible, +//!MoveAssignable, and Swappable, and need not be CopyConstructible +//!(unless copied into the unique_ptr) nor CopyAssignable. +template +class unique_ptr +{ + /// @cond + struct nat {int for_bool_;}; + typedef typename detail::add_reference::type deleter_reference; + typedef typename detail::add_reference::type deleter_const_reference; + /// @endcond + + public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + + //!Requires: D must be default constructible, and that construction must not + //!throw an exception. D must not be a reference type. + //! + //!Effects: Constructs a unique_ptr which owns nothing. + //! + //!Postconditions: get() == 0. get_deleter() returns a reference to a + //!default constructed deleter D. + //! + //!Throws: nothing. + unique_ptr() + : ptr_(pointer(0)) + {} + + //!Requires: The expression D()(p) must be well formed. The default constructor + //!of D must not throw an exception. + //! + //!D must not be a reference type. + //! + //!Effects: Constructs a unique_ptr which owns p. + //! + //!Postconditions: get() == p. get_deleter() returns a reference to a default constructed deleter D. + //! + //!Throws: nothing. + explicit unique_ptr(pointer p) + : ptr_(p) + {} + + //!Requires: The expression d(p) must be well formed. + //! + //!Postconditions: get() == p. get_deleter() returns a reference to the + //!internally stored deleter. If D is a + //!reference type then get_deleter() returns a reference to the lvalue d. + //! + //!Throws: nothing. + unique_ptr(pointer p + ,typename detail::if_ + ,D + ,typename detail::add_reference::type>::type d) + : ptr_(p, d) + {} + + //!Requires: If the deleter is not a reference type, construction of the + //!deleter D from an lvalue D must not throw an exception. + //! + //!Effects: Constructs a unique_ptr which owns the pointer which u owns + //!(if any). If the deleter is not a reference type, it is move constructed + //!from u’s deleter, otherwise the reference is copy constructed from u’s deleter. + //! + //!After the construction, u no longer owns a pointer. + //![ Note: The deleter constructor can be implemented with + //!std::forward. —end note ] + //! + //!Postconditions: get() == value u.get() had before the construction. + //!get_deleter() returns a reference to the internally stored deleter which + //!was constructed from u.get_deleter(). If D is a reference type then get_- + //!deleter() and u.get_deleter() both reference the same lvalue deleter. + //! + //!Throws: nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + unique_ptr(detail::moved_object u) + : ptr_(u.get().release(), move(u.get().get_deleter())) + {} + #else + unique_ptr(unique_ptr &&u) + : ptr_(u.release(), forward(u.get_deleter())) + {} + #endif + + //!Requires: If D is not a reference type, construction of the deleter + //!D from an rvalue of type E must be well formed + //!and not throw an exception. If D is a reference type, then E must be + //!the same type as D (diagnostic required). unique_ptr::pointer + //!must be implicitly convertible to pointer. + //! + //!Effects: Constructs a unique_ptr which owns the pointer which u owns + //!(if any). If the deleter is not a reference + //!type, it is move constructed from u’s deleter, otherwise the reference + //!is copy constructed from u’s deleter. + //! + //!After the construction, u no longer owns a pointer. + //! + //!postconditions get() == value u.get() had before the construction, + //!modulo any required offset adjustments + //!resulting from the cast from U* to T*. get_deleter() returns a reference to the internally stored deleter which + //!was constructed from u.get_deleter(). + //! + //!Throws: nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + template + unique_ptr(const detail::moved_object >& u, + typename detail::enable_if_c< + detail::is_convertible::pointer, pointer>::value && + detail::is_convertible::value && + ( + !detail::is_reference::value || + detail::is_same::value + ) + , + nat + >::type = nat()) + : ptr_(const_cast&>(u.get()).release(), move(u.get().get_deleter())) + {} + #else + template + unique_ptr(unique_ptr && u, + typename boost::enable_if_c< + detail::is_convertible::pointer, pointer>::value && + detail::is_convertible::value && + ( + !detail::is_reference::value || + detail::is_same::value + ) + , + nat + >::type = nat()) + : ptr_(const_cast&>(u).release(), forward(u.get_deleter())) + {} + #endif + + //!Effects: If get() == 0 there are no effects. Otherwise get_deleter()(get()). + //! + //!Throws: nothing. + ~unique_ptr() + { reset(); } + + // assignment + + //!Requires: Assignment of the deleter D from an rvalue D must not throw an exception. + //! + //!Effects: reset(u.release()) followed by a move assignment from u’s deleter to + //!this deleter. + //! + //!Postconditions: This unique_ptr now owns the pointer which u owned, and u no + //!longer owns it. + //! + //!Returns: *this. + //! + //!Throws: nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + unique_ptr& operator=(const detail::moved_object& u) + { + reset(u.get().release()); + ptr_.second() = move(u.get().get_deleter()); + return *this; + } + #else + unique_ptr(unique_ptr && u) + { + reset(u.release()); + ptr_.second() = move(u.get_deleter()); + return *this; + } + #endif + + //!Requires: Assignment of the deleter D from an rvalue D must not + //!throw an exception. U* must be implicitly convertible to T*. + //! + //!Effects: reset(u.release()) followed by a move assignment from + //!u’s deleter to this deleter. If either D or E is + //!a reference type, then the referenced lvalue deleter participates + //!in the move assignment. + //! + //!Postconditions: This unique_ptr now owns the pointer which u owned, + //!and u no longer owns it. + //! + //!Returns: *this. + //! + //!Throws: nothing. + template + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + unique_ptr& operator=(const detail::moved_object >& mu) + { + reset(mu.get().release()); + ptr_.second() = move(mu.get().get_deleter()); + return *this; + } + #else + unique_ptr(unique_ptr && u) + { + reset(u.release()); + ptr_.second() = move(u.get_deleter()); + return *this; + } + #endif + + //!Assigns from the literal 0 or NULL. + //! + //!Effects: reset(). + //! + //!Postcondition: get() == 0 + //! + //!Returns: *this. + //! + //!Throws: nothing. + unique_ptr& operator=(int nat::*) + { + reset(); + return *this; + } + + //!Requires: get() != 0. + //!Returns: *get(). + //!Throws: nothing. + typename detail::add_reference::type operator*() const + { return *ptr_.first(); } + + //!Requires: get() != 0. + //!Returns: get(). + //!Throws: nothing. + pointer operator->() const + { return ptr_.first(); } + + //!Returns: The stored pointer. + //!Throws: nothing. + pointer get() const + { return ptr_.first(); } + + //!Returns: A reference to the stored deleter. + //! + //!Throws: nothing. + deleter_reference get_deleter() + { return ptr_.second(); } + + //!Returns: A const reference to the stored deleter. + //! + //!Throws: nothing. + deleter_const_reference get_deleter() const + { return ptr_.second(); } + + //!Returns: An unspecified value that, when used in boolean + //!contexts, is equivalent to get() != 0. + //! + //!Throws: nothing. + operator int nat::*() const + { return ptr_.first() ? &nat::for_bool_ : 0; } + + //!Postcondition: get() == 0. + //! + //!Returns: The value get() had at the start of the call to release. + //! + //!Throws: nothing. + pointer release() + { + pointer tmp = ptr_.first(); + ptr_.first() = 0; + return tmp; + } + + //!Effects: If p == get() there are no effects. Otherwise get_deleter()(get()). + //! + //!Postconditions: get() == p. + //! + //!Throws: nothing. + void reset(pointer p = 0) + { + if (ptr_.first() != p){ + if (ptr_.first()) + ptr_.second()(ptr_.first()); + ptr_.first() = p; + } + } + + //!Requires: The deleter D is Swappable and will not throw an exception under swap. + //! + //!Effects: The stored pointers of this and u are exchanged. The stored deleters are swap’d (unqualified). + //! + //!Throws: nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(unique_ptr& u) + { ptr_.swap(u.ptr_); } + + void swap(detail::moved_object mu) + { ptr_.swap(mu.get().ptr_); } + #else + void swap(unique_ptr&&u) + { ptr_.swap(u.ptr_); } + #endif + + /// @cond + private: + boost::compressed_pair ptr_; + + //This private constructor avoids moving from non-const lvalues + unique_ptr(const unique_ptr&); + template unique_ptr(unique_ptr&); + template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); + + unique_ptr& operator=(unique_ptr&); + template unique_ptr& operator=(unique_ptr&); + template typename detail::unique_ptr_error::type operator=(U&); + /// @endcond +}; +/* +template +class unique_ptr +{ + struct nat {int for_bool_;}; + typedef typename detail::add_reference::type deleter_reference; + typedef typename detail::add_reference::type deleter_const_reference; +public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + + // constructors + unique_ptr() : ptr_(pointer()) {} + explicit unique_ptr(pointer p) : ptr_(p) {} + unique_ptr(pointer p, typename if_< + boost::is_reference, + D, + typename detail::add_reference::type>::type d) + : ptr_(p, d) {} + unique_ptr(const unique_ptr& u) + : ptr_(const_cast(u).release(), u.get_deleter()) {} + + // destructor + ~unique_ptr() {reset();} + + // assignment + unique_ptr& operator=(const unique_ptr& cu) + { + unique_ptr& u = const_cast(cu); + reset(u.release()); + ptr_.second() = u.get_deleter(); + return *this; + } + unique_ptr& operator=(int nat::*) + { + reset(); + return *this; + } + + // observers + typename detail::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} + pointer get() const {return ptr_.first();} + deleter_reference get_deleter() {return ptr_.second();} + deleter_const_reference get_deleter() const {return ptr_.second();} + operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} + + // modifiers + pointer release() + { + pointer tmp = ptr_.first(); + ptr_.first() = 0; + return tmp; + } + void reset(pointer p = 0) + { + if (ptr_.first() != p) + { + if (ptr_.first()) + ptr_.second()(ptr_.first()); + ptr_.first() = p; + } + } + void swap(unique_ptr& u) {ptr_.swap(u.ptr_);} +private: + boost::compressed_pair ptr_; + + template unique_ptr(U p, E, + typename boost::enable_if >::type* = 0); + template explicit unique_ptr(U, + typename boost::enable_if >::type* = 0); + + unique_ptr(unique_ptr&); + template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); + + unique_ptr& operator=(unique_ptr&); + template typename detail::unique_ptr_error::type operator=(U&); +}; + +template +class unique_ptr +{ + struct nat {int for_bool_;}; + typedef typename detail::add_reference::type deleter_reference; + typedef typename detail::add_reference::type deleter_const_reference; +public: + typedef T element_type; + typedef D deleter_type; + typedef typename detail::pointer_type::type pointer; + static const std::size_t size = N; + + // constructors + unique_ptr() : ptr_(0) {} + explicit unique_ptr(pointer p) : ptr_(p) {} + unique_ptr(pointer p, typename if_< + boost::is_reference, + D, + typename detail::add_reference::type>::type d) + : ptr_(p, d) {} + unique_ptr(const unique_ptr& u) + : ptr_(const_cast(u).release(), u.get_deleter()) {} + + // destructor + ~unique_ptr() {reset();} + + // assignment + unique_ptr& operator=(const unique_ptr& cu) + { + unique_ptr& u = const_cast(cu); + reset(u.release()); + ptr_.second() = u.get_deleter(); + return *this; + } + unique_ptr& operator=(int nat::*) + { + reset(); + return *this; + } + + // observers + typename detail::add_reference::type operator[](std::size_t i) const {return ptr_.first()[i];} + pointer get() const {return ptr_.first();} + deleter_reference get_deleter() {return ptr_.second();} + deleter_const_reference get_deleter() const {return ptr_.second();} + operator int nat::*() const {return ptr_.first() ? &nat::for_bool_ : 0;} + + // modifiers + pointer release() + { + pointer tmp = ptr_.first(); + ptr_.first() = 0; + return tmp; + } + void reset(pointer p = 0) + { + if (ptr_.first() != p) + { + if (ptr_.first()) + ptr_.second()(ptr_.first(), N); + ptr_.first() = p; + } + } + void swap(unique_ptr& u) {ptr_.swap(u.ptr_);} +private: + boost::compressed_pair ptr_; + + template unique_ptr(U p, E, + typename boost::enable_if >::type* = 0); + template explicit unique_ptr(U, + typename boost::enable_if >::type* = 0); + + unique_ptr(unique_ptr&); + template unique_ptr(U&, typename detail::unique_ptr_error::type = 0); + + unique_ptr& operator=(unique_ptr&); + template typename detail::unique_ptr_error::type operator=(U&); +}; +*/ +template inline +void swap(unique_ptr& x, unique_ptr& y) +{ x.swap(y); } + +template inline +bool operator==(const unique_ptr& x, const unique_ptr& y) +{ return x.get() == y.get(); } + +template inline +bool operator!=(const unique_ptr& x, const unique_ptr& y) +{ return x.get() != y.get(); } + +template inline +bool operator <(const unique_ptr& x, const unique_ptr& y) +{ return x.get() < y.get(); } + +template inline +bool operator<=(const unique_ptr& x, const unique_ptr& y) +{ return x.get() <= y.get(); } + +template inline +bool operator >(const unique_ptr& x, const unique_ptr& y) +{ return x.get() > y.get(); } + +template inline +bool operator>=(const unique_ptr& x, const unique_ptr& y) +{ return x.get() >= y.get(); } + +/// @cond + +//!This class has move constructor +template +struct is_movable > +{ + enum { value = true }; +}; +/// @endcond + + +//!Returns the type of a unique pointer +//!of type T with boost::interprocess::deleter deleter +//!that can be constructed in the given managed segment type. +template +struct managed_unique_ptr +{ + typedef unique_ptr + < T + , typename ManagedMemory::template deleter::type + > type; +}; + +//!Returns an instance of the a unique pointer constructed +//!with boost::interproces::deleter from a pointer +//!of type T that has been allocated in the passed managed segment +template +inline typename detail::return_type + ::type + >::type + make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory) +{ + typename managed_unique_ptr::type to_return + ( constructed_object + , managed_memory.template get_deleter() + ); + return to_return; +} + +} //namespace interprocess{ +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_INTERPROCESS_UNIQUE_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/smart_ptr/weak_ptr.hpp b/thirdparty/boost/interprocess/smart_ptr/weak_ptr.hpp new file mode 100644 index 0000000..177c851 --- /dev/null +++ b/thirdparty/boost/interprocess/smart_ptr/weak_ptr.hpp @@ -0,0 +1,255 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/weak_ptr.hpp +// +// (C) Copyright Peter Dimov 2001, 2002, 2003 +// (C) Copyright Ion Gaztanaga 2006-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED + +#include +#include + +#include +#include +#include +#include + +//!\file +//!Describes the smart pointer weak_ptr. + +namespace boost{ +namespace interprocess{ + +//!The weak_ptr class template stores a "weak reference" to an object +//!that's already managed by a shared_ptr. To access the object, a weak_ptr +//!can be converted to a shared_ptr using the shared_ptr constructor or the +//!member function lock. When the last shared_ptr to the object goes away +//!and the object is deleted, the attempt to obtain a shared_ptr from the +//!weak_ptr instances that refer to the deleted object will fail: the constructor +//!will throw an exception of type bad_weak_ptr, and weak_ptr::lock will +//!return an empty shared_ptr. +//! +//!Every weak_ptr meets the CopyConstructible and Assignable requirements +//!of the C++ Standard Library, and so can be used in standard library containers. +//!Comparison operators are supplied so that weak_ptr works with the standard +//!library's associative containers. +//! +//!weak_ptr operations never throw exceptions. +//! +//!The class template is parameterized on T, the type of the object pointed to. +template +class weak_ptr +{ + /// @cond + private: + // Borland 5.5.1 specific workarounds + typedef weak_ptr this_type; + typedef typename detail::pointer_to_other + ::type pointer; + typedef typename detail::add_reference + ::type reference; + typedef typename detail::add_reference + ::type const_reference; + /// @endcond + + public: + typedef T element_type; + typedef T value_type; + + //!Effects: Constructs an empty weak_ptr. + //!Postconditions: use_count() == 0. + weak_ptr() + : m_pn() // never throws + {} + // generated copy constructor, assignment, destructor are fine + // + // The "obvious" converting constructor implementation: + // + // template + // weak_ptr(weak_ptr const & r): m_px(r.m_px), m_pn(r.m_pn) // never throws + // { + // } + // + // has a serious problem. + // + // r.m_px may already have been invalidated. The m_px(r.m_px) + // conversion may require access to *r.m_px (virtual inheritance). + // + // It is not possible to avoid spurious access violations since + // in multithreaded programs r.m_px may be invalidated at any point. + + //!Effects: If r is empty, constructs an empty weak_ptr; otherwise, + //!constructs a weak_ptr that shares ownership with r as if by storing a + //!copy of the pointer stored in r. + //! + //!Postconditions: use_count() == r.use_count(). + //! + //!Throws: nothing. + template + weak_ptr(weak_ptr const & r) + : m_pn(r.m_pn) // never throws + { + //Construct a temporary shared_ptr so that nobody + //can destroy the value while constructing this + const shared_ptr &ref = r.lock(); + m_pn.set_pointer(ref.get()); + } + + //!Effects: If r is empty, constructs an empty weak_ptr; otherwise, + //!constructs a weak_ptr that shares ownership with r as if by storing a + //!copy of the pointer stored in r. + //! + //!Postconditions: use_count() == r.use_count(). + //! + //!Throws: nothing. + template + weak_ptr(shared_ptr const & r) + : m_pn(r.m_pn) // never throws + {} + + //!Effects: Equivalent to weak_ptr(r).swap(*this). + //! + //!Throws: nothing. + //! + //!Notes: The implementation is free to meet the effects (and the + //!implied guarantees) via different means, without creating a temporary. + template + weak_ptr & operator=(weak_ptr const & r) // never throws + { + //Construct a temporary shared_ptr so that nobody + //can destroy the value while constructing this + const shared_ptr &ref = r.lock(); + m_pn = r.m_pn; + m_pn.set_pointer(ref.get()); + return *this; + } + + //!Effects: Equivalent to weak_ptr(r).swap(*this). + //! + //!Throws: nothing. + //! + //!Notes: The implementation is free to meet the effects (and the + //!implied guarantees) via different means, without creating a temporary. + template + weak_ptr & operator=(shared_ptr const & r) // never throws + { m_pn = r.m_pn; return *this; } + + //!Returns: expired()? shared_ptr(): shared_ptr(*this). + //! + //!Throws: nothing. + shared_ptr lock() const // never throws + { + // optimization: avoid throw overhead + if(expired()){ + return shared_ptr(); + } + BOOST_TRY{ + return shared_ptr(*this); + } + BOOST_CATCH(bad_weak_ptr const &){ + // Q: how can we get here? + // A: another thread may have invalidated r after the use_count test above. + return shared_ptr(); + } + BOOST_CATCH_END + } + + //!Returns: 0 if *this is empty; otherwise, the number of shared_ptr objects + //!that share ownership with *this. + //! + //!Throws: nothing. + //! + //!Notes: use_count() is not necessarily efficient. Use only for debugging and + //!testing purposes, not for production code. + long use_count() const // never throws + { return m_pn.use_count(); } + + //!Returns: Returns: use_count() == 0. + //! + //!Throws: nothing. + //! + //!Notes: expired() may be faster than use_count(). + bool expired() const // never throws + { return m_pn.use_count() == 0; } + + //!Effects: Equivalent to: + //!weak_ptr().swap(*this). + void reset() // never throws in 1.30+ + { this_type().swap(*this); } + + //!Effects: Exchanges the contents of the two + //!smart pointers. + //! + //!Throws: nothing. + void swap(this_type & other) // never throws + { detail::do_swap(m_pn, other.m_pn); } + + /// @cond + template + bool _internal_less(weak_ptr const & rhs) const + { return m_pn < rhs.m_pn; } + + template + void _internal_assign(const detail::shared_count & pn2) + { m_pn = pn2; } + + private: + + template friend class shared_ptr; + template friend class weak_ptr; + + detail::weak_count m_pn; // reference counter + /// @endcond +}; // weak_ptr + +template inline +bool operator<(weak_ptr const & a, weak_ptr const & b) +{ return a._internal_less(b); } + +template inline +void swap(weak_ptr & a, weak_ptr & b) +{ a.swap(b); } + +//!Returns the type of a weak pointer +//!of type T with the allocator boost::interprocess::allocator allocator +//!and boost::interprocess::deleter deleter +//!that can be constructed in the given managed segment type. +template +struct managed_weak_ptr +{ + typedef weak_ptr + < T + , typename ManagedMemory::template allocator::type + , typename ManagedMemory::template deleter::type + > type; +}; + +//!Returns an instance of the a weak pointer constructed +//!with the default allocator and deleter from a pointer +//!of type T that has been allocated in the passed managed segment +template +inline typename managed_weak_ptr::type + make_managed_weak_ptr(T *constructed_object, ManagedMemory &managed_memory) +{ + return typename managed_weak_ptr::type + ( constructed_object + , managed_memory.template get_allocator() + , managed_memory.template get_deleter() + ); +} + +} // namespace interprocess +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/interprocess/streams/bufferstream.hpp b/thirdparty/boost/interprocess/streams/bufferstream.hpp new file mode 100644 index 0000000..3e5cfc1 --- /dev/null +++ b/thirdparty/boost/interprocess/streams/bufferstream.hpp @@ -0,0 +1,444 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005. +// Changed internal SGI string to a buffer. Added efficient +// internal buffer get/set/swap functions, so that we can obtain/establish the +// internal buffer without any reallocation or copy. Kill those temporaries! +/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +//!\file +//!This file defines basic_bufferbuf, basic_ibufferstream, +//!basic_obufferstream, and basic_bufferstream classes. These classes +//!represent streamsbufs and streams whose sources or destinations +//!are fixed size character buffers. + +#ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP +#define BOOST_INTERPROCESS_BUFFERSTREAM_HPP + +#include +#include + +#include +#include +#include +#include +#include // char traits +#include // ptrdiff_t +#include +#include + +namespace boost { namespace interprocess { + +//!A streambuf class that controls the transmission of elements to and from +//!a basic_xbufferstream. The elements are transmitted from a to a fixed +//!size buffer +template +class basic_bufferbuf + : public std::basic_streambuf +{ + public: + typedef CharT char_type; + typedef typename CharTraits::int_type int_type; + typedef typename CharTraits::pos_type pos_type; + typedef typename CharTraits::off_type off_type; + typedef CharTraits traits_type; + typedef std::basic_streambuf base_t; + + public: + //!Constructor. + //!Does not throw. + explicit basic_bufferbuf(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : base_t(), m_mode(mode), m_buffer(0), m_length(0) + {} + + //!Constructor. Assigns formatting buffer. + //!Does not throw. + explicit basic_bufferbuf(CharT *buffer, std::size_t length, + std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : base_t(), m_mode(mode), m_buffer(buffer), m_length(length) + { this->set_pointers(); } + + virtual ~basic_bufferbuf(){} + + public: + //!Returns the pointer and size of the internal buffer. + //!Does not throw. + std::pair buffer() const + { return std::pair(m_buffer, m_length); } + + //!Sets the underlying buffer to a new value + //!Does not throw. + void buffer(CharT *buffer, std::size_t length) + { m_buffer = buffer; m_length = length; this->set_pointers(); } + + /// @cond + private: + void set_pointers() + { + // The initial read position is the beginning of the buffer. + if(m_mode & std::ios_base::in) + this->setg(m_buffer, m_buffer, m_buffer + m_length); + + // The initial write position is the beginning of the buffer. + if(m_mode & std::ios_base::out) + this->setp(m_buffer, m_buffer + m_length); + } + + protected: + virtual int_type underflow() + { + // Precondition: gptr() >= egptr(). Returns a character, if available. + return this->gptr() != this->egptr() ? + CharTraits::to_int_type(*this->gptr()) : CharTraits::eof(); + } + + virtual int_type pbackfail(int_type c = CharTraits::eof()) + { + if(this->gptr() != this->eback()) { + if(!CharTraits::eq_int_type(c, CharTraits::eof())) { + if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { + this->gbump(-1); + return c; + } + else if(m_mode & std::ios_base::out) { + this->gbump(-1); + *this->gptr() = c; + return c; + } + else + return CharTraits::eof(); + } + else { + this->gbump(-1); + return CharTraits::not_eof(c); + } + } + else + return CharTraits::eof(); + } + + virtual int_type overflow(int_type c = CharTraits::eof()) + { + if(m_mode & std::ios_base::out) { + if(!CharTraits::eq_int_type(c, CharTraits::eof())) { +// if(!(m_mode & std::ios_base::in)) { +// if(this->pptr() != this->epptr()) { +// *this->pptr() = CharTraits::to_char_type(c); +// this->pbump(1); +// return c; +// } +// else +// return CharTraits::eof(); +// } +// else { + if(this->pptr() == this->epptr()) { + //We can't append to a static buffer + return CharTraits::eof(); + } + else { + *this->pptr() = CharTraits::to_char_type(c); + this->pbump(1); + return c; + } +// } + } + else // c is EOF, so we don't have to do anything + return CharTraits::not_eof(c); + } + else // Overflow always fails if it's read-only. + return CharTraits::eof(); + } + + virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, + std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + { + bool in = false; + bool out = false; + + const std::ios_base::openmode inout = + std::ios_base::in | std::ios_base::out; + + if((mode & inout) == inout) { + if(dir == std::ios_base::beg || dir == std::ios_base::end) + in = out = true; + } + else if(mode & std::ios_base::in) + in = true; + else if(mode & std::ios_base::out) + out = true; + + if(!in && !out) + return pos_type(off_type(-1)); + else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || + (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) + return pos_type(off_type(-1)); + + std::streamoff newoff; + switch(dir) { + case std::ios_base::beg: + newoff = 0; + break; + case std::ios_base::end: + newoff = static_cast(m_length); + break; + case std::ios_base::cur: + newoff = in ? static_cast(this->gptr() - this->eback()) + : static_cast(this->pptr() - this->pbase()); + break; + default: + return pos_type(off_type(-1)); + } + + off += newoff; + + if(in) { + std::ptrdiff_t n = this->egptr() - this->eback(); + + if(off < 0 || off > n) + return pos_type(off_type(-1)); + else + this->setg(this->eback(), this->eback() + off, this->eback() + n); + } + + if(out) { + std::ptrdiff_t n = this->epptr() - this->pbase(); + + if(off < 0 || off > n) + return pos_type(off_type(-1)); + else { + this->setp(this->pbase(), this->pbase() + n); + this->pbump(off); + } + } + + return pos_type(off); + } + + virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } + + private: + std::ios_base::openmode m_mode; + CharT * m_buffer; + std::size_t m_length; + /// @endcond +}; + +//!A basic_istream class that uses a fixed size character buffer +//!as its formatting buffer. +template +class basic_ibufferstream + : public std::basic_istream +{ + public: // Typedefs + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_istream base_t; + + public: + //!Constructor. + //!Does not throw. + basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in) + : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Assigns formatting buffer. + //!Does not throw. + basic_ibufferstream(const CharT *buffer, std::size_t length, + std::ios_base::openmode mode = std::ios_base::in) + : basic_ios_t(), base_t(0), + m_buf(const_cast(buffer), length, mode | std::ios_base::in) + { basic_ios_t::init(&m_buf); } + + ~basic_ibufferstream(){}; + + public: + //!Returns the address of the stored + //!stream buffer. + basic_bufferbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Returns the pointer and size of the internal buffer. + //!Does not throw. + std::pair buffer() const + { return m_buf.buffer(); } + + //!Sets the underlying buffer to a new value. Resets + //!stream position. Does not throw. + void buffer(const CharT *buffer, std::size_t length) + { m_buf.buffer(const_cast(buffer), length); } + + /// @cond + private: + basic_bufferbuf m_buf; + /// @endcond +}; + +//!A basic_ostream class that uses a fixed size character buffer +//!as its formatting buffer. +template +class basic_obufferstream + : public std::basic_ostream +{ + public: + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + /// @cond + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_ostream base_t; + /// @endcond + public: + //!Constructor. + //!Does not throw. + basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Assigns formatting buffer. + //!Does not throw. + basic_obufferstream(CharT *buffer, std::size_t length, + std::ios_base::openmode mode = std::ios_base::out) + : basic_ios_t(), base_t(0), + m_buf(buffer, length, mode | std::ios_base::out) + { basic_ios_t::init(&m_buf); } + + ~basic_obufferstream(){} + + public: + //!Returns the address of the stored + //!stream buffer. + basic_bufferbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Returns the pointer and size of the internal buffer. + //!Does not throw. + std::pair buffer() const + { return m_buf.buffer(); } + + //!Sets the underlying buffer to a new value. Resets + //!stream position. Does not throw. + void buffer(CharT *buffer, std::size_t length) + { m_buf.buffer(buffer, length); } + + /// @cond + private: + basic_bufferbuf m_buf; + /// @endcond +}; + + +//!A basic_iostream class that uses a fixed size character buffer +//!as its formatting buffer. +template +class basic_bufferstream + : public std::basic_iostream + +{ + public: // Typedefs + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + /// @cond + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_iostream base_t; + /// @endcond + + public: + //!Constructor. + //!Does not throw. + basic_bufferstream(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(mode) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Assigns formatting buffer. + //!Does not throw. + basic_bufferstream(CharT *buffer, std::size_t length, + std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(buffer, length, mode) + { basic_ios_t::init(&m_buf); } + + ~basic_bufferstream(){} + + public: + //!Returns the address of the stored + //!stream buffer. + basic_bufferbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Returns the pointer and size of the internal buffer. + //!Does not throw. + std::pair buffer() const + { return m_buf.buffer(); } + + //!Sets the underlying buffer to a new value. Resets + //!stream position. Does not throw. + void buffer(CharT *buffer, std::size_t length) + { m_buf.buffer(buffer, length); } + + /// @cond + private: + basic_bufferbuf m_buf; + /// @endcond +}; + +//Some typedefs to simplify usage +typedef basic_bufferbuf bufferbuf; +typedef basic_bufferstream bufferstream; +typedef basic_ibufferstream ibufferstream; +typedef basic_obufferstream obufferstream; + +typedef basic_bufferbuf wbufferbuf; +typedef basic_bufferstream wbufferstream; +typedef basic_ibufferstream wibufferstream; +typedef basic_obufferstream wobufferstream; + + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */ diff --git a/thirdparty/boost/interprocess/streams/vectorstream.hpp b/thirdparty/boost/interprocess/streams/vectorstream.hpp new file mode 100644 index 0000000..8785cbc --- /dev/null +++ b/thirdparty/boost/interprocess/streams/vectorstream.hpp @@ -0,0 +1,593 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005. +// Changed internal SGI string to a generic, templatized vector. Added efficient +// internal buffer get/set/swap functions, so that we can obtain/establish the +// internal buffer without any reallocation or copy. Kill those temporaries! +/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +//!\file +//!This file defines basic_vectorbuf, basic_ivectorstream, +//!basic_ovectorstream, and basic_vectorstreamclasses. These classes +//!represent streamsbufs and streams whose sources or destinations are +//!STL-like vectors that can be swapped with external vectors to avoid +//!unnecessary allocations/copies. + +#ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP +#define BOOST_INTERPROCESS_VECTORSTREAM_HPP + +#include +#include + +#include +#include +#include +#include +#include // char traits +#include // ptrdiff_t +#include +#include + +namespace boost { namespace interprocess { + +//!A streambuf class that controls the transmission of elements to and from +//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream. +//!It holds a character vector specified by CharVector template parameter +//!as its formatting buffer. The vector must have contiguous storage, like +//!std::vector, boost::interprocess::vector or boost::interprocess::basic_string +template +class basic_vectorbuf + : public std::basic_streambuf +{ + public: + typedef CharVector vector_type; + typedef typename CharVector::value_type char_type; + typedef typename CharTraits::int_type int_type; + typedef typename CharTraits::pos_type pos_type; + typedef typename CharTraits::off_type off_type; + typedef CharTraits traits_type; + + /// @cond + private: + typedef std::basic_streambuf base_t; + + basic_vectorbuf(const basic_vectorbuf&); + basic_vectorbuf & operator =(const basic_vectorbuf&); + /// @endcond + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + explicit basic_vectorbuf(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : base_t(), m_mode(mode) + { this->initialize_pointers(); } + + //!Constructor. Throws if + //!vector_type(const VectorParameter ¶m) throws. + template + explicit basic_vectorbuf(const VectorParameter ¶m, + std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : base_t(), m_mode(mode), m_vect(param) + { this->initialize_pointers(); } + + virtual ~basic_vectorbuf(){} + + public: + + //!Swaps the underlying vector with the passed vector. + //!This function resets the read/write position in the stream. + //!Does not throw. + void swap_vector(vector_type &vect) + { + if (this->m_mode & std::ios_base::out){ + //Update high water if necessary + //And resize vector to remove extra size + if (mp_high_water < base_t::pptr()){ + //Restore the vector's size if necessary + mp_high_water = base_t::pptr(); + } + m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)); + + //Now swap vector + m_vect.swap(vect); + + //If the stream is writable put the high water mark + //and maximize the size. + typename vector_type::size_type old_size = m_vect.size(); + m_vect.resize(m_vect.capacity()); + this->initialize_pointers(); + mp_high_water = old_size ? &m_vect[0] + old_size : 0; + } + else{ + //Now swap vector + m_vect.swap(vect); + this->initialize_pointers(); + } + } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { + if (this->m_mode & std::ios_base::out){ + if (mp_high_water < base_t::pptr()){ + //Restore the vector's size if necessary + mp_high_water = base_t::pptr(); + } + m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)); + const_cast(this)->initialize_pointers(); + } + return m_vect; + } + + //!Preallocates memory from the internal vector. + //!Resets the stream to the first position. + //!Throws if the internals vector's memory allocation throws. + void reserve(typename vector_type::size_type size) + { + m_vect.reserve(size); + //Now update pointer data + typename vector_type::size_type old_size = m_vect.size(); + m_vect.resize(m_vect.capacity()); + this->initialize_pointers(); + mp_high_water = old_size ? &m_vect[0] + old_size : 0; + } + + //!Calls clear() method of the internal vector. + //!Resets the stream to the first position. + void clear() + { m_vect.clear(); this->initialize_pointers(); } + + /// @cond + private: + void initialize_pointers() + { + // The initial read position is the beginning of the vector. + if(m_mode & std::ios_base::in){ + if(m_vect.empty()){ + this->setg(0, 0, 0); + } + else{ + this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size()); + } + } + + // The initial write position is the beginning of the vector. + if(m_mode & std::ios_base::out){ + if(m_vect.empty()){ + this->setp(0, 0); + } + else{ + this->setp(&m_vect[0], &m_vect[0] + m_vect.size()); + } + + if (m_mode & (std::ios_base::app | std::ios_base::ate)) + base_t::pbump((int)m_vect.size()); + } + mp_high_water = m_vect.empty() ? 0 : (&m_vect[0] + m_vect.size()); + } + + protected: + virtual int_type underflow() + { + if (base_t::gptr() == 0) + return CharTraits::eof(); + if (mp_high_water < base_t::pptr()) + mp_high_water = base_t::pptr(); + if (base_t::egptr() < mp_high_water) + base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); + if (base_t::gptr() < base_t::egptr()) + return CharTraits::to_int_type(*base_t::gptr()); + return CharTraits::eof(); + } + + virtual int_type pbackfail(int_type c = CharTraits::eof()) + { + if(this->gptr() != this->eback()) { + if(!CharTraits::eq_int_type(c, CharTraits::eof())) { + if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { + this->gbump(-1); + return c; + } + else if(m_mode & std::ios_base::out) { + this->gbump(-1); + *this->gptr() = c; + return c; + } + else + return CharTraits::eof(); + } + else { + this->gbump(-1); + return CharTraits::not_eof(c); + } + } + else + return CharTraits::eof(); + } + + virtual int_type overflow(int_type c = CharTraits::eof()) + { + if(m_mode & std::ios_base::out) { + if(!CharTraits::eq_int_type(c, CharTraits::eof())) { +// if(!(m_mode & std::ios_base::in)) { +// if(this->pptr() < this->epptr()) { +// *this->pptr() = CharTraits::to_char_type(c); +// this->pbump(1); +// if (mp_high_water < base_t::pptr()) +// mp_high_water = base_t::pptr(); +// if ((m_mode & std::ios_base::in) && base_t::egptr() < mp_high_water) +// base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); +// return c; +// } +// else +// return CharTraits::eof(); +// } +// else { +// try{ + typedef typename vector_type::difference_type dif_t; + dif_t inpos = base_t::gptr() - base_t::eback(); + //The new output position is the previous one plus one + //because 'overflow' requires putting 'c' on the buffer + dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1; + //Adjust high water if necessary + dif_t hipos = mp_high_water - base_t::pbase(); + if (hipos < new_outpos) + hipos = new_outpos; + //Insert the new data + m_vect.push_back(CharTraits::to_char_type(c)); + m_vect.resize(m_vect.capacity()); + char_type* p = const_cast(&m_vect[0]); + //A reallocation has happened, update pointers + if (m_mode & std::ios_base::in) + base_t::setg(p, p + inpos, p + hipos); + base_t::setp(p, p + (dif_t)m_vect.size()); + //Update write position to the old position + 1 + base_t::pbump((int)new_outpos); + //Update high water pointer, since the buffer has been reallocated + mp_high_water = base_t::pbase() + hipos; + return c; +// } +// catch(...){ +// return CharTraits::eof(); +// } +// } + } + else // c is EOF, so we don't have to do anything + return CharTraits::not_eof(c); + } + else // Overflow always fails if it's read-only. + return CharTraits::eof(); + } + + virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, + std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + { + bool in = false, out = false; + + const std::ios_base::openmode inout = + std::ios_base::in | std::ios_base::out; + + if((mode & inout) == inout) { + if(dir == std::ios_base::beg || dir == std::ios_base::end) + in = out = true; + } + else if(mode & std::ios_base::in) + in = true; + else if(mode & std::ios_base::out) + out = true; + + if(!in && !out) + return pos_type(off_type(-1)); + else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || + (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) + return pos_type(off_type(-1)); + + off_type newoff; + //Just calculate the end of the stream. If the stream is read-only + //the limit is the size of the vector. Otherwise, the high water mark + //will mark the real size. + off_type limit = static_cast (mode & std::ios_base::out ? + mp_high_water - base_t::pbase() : m_vect.size()/*mp_high_water - base_t::eback()*/); + + switch(dir) { + case std::ios_base::beg: + newoff = 0; + break; + case std::ios_base::end: + newoff = limit; + break; + case std::ios_base::cur: + newoff = in ? static_cast(this->gptr() - this->eback()) + : static_cast(this->pptr() - this->pbase()); + break; + default: + return pos_type(off_type(-1)); + } + + newoff += off; + + if (newoff < 0 || newoff > limit) + return pos_type(-1); + if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit) + return pos_type(-1); + if (in) + base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr()); + if (out){ + base_t::setp(base_t::pbase(), base_t::epptr()); + base_t::pbump(newoff); + } + return pos_type(newoff); + } + + virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } + + private: + std::ios_base::openmode m_mode; + mutable vector_type m_vect; + mutable char_type* mp_high_water; + /// @endcond +}; + +//!A basic_istream class that holds a character vector specified by CharVector +//!template parameter as its formatting buffer. The vector must have +//!contiguous storage, like std::vector, boost::interprocess::vector or +//!boost::interprocess::basic_string +template +class basic_ivectorstream + : public std::basic_istream +{ + public: + typedef CharVector vector_type; + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + /// @cond + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_istream base_t; + /// @endcond + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) + : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Throws if vector_type(const VectorParameter ¶m) + //!throws. + template + basic_ivectorstream(const VectorParameter ¶m, + std::ios_base::openmode mode = std::ios_base::in) + : basic_ios_t(), base_t(0), + m_buf(param, mode | std::ios_base::in) + { basic_ios_t::init(&m_buf); } + + ~basic_ivectorstream(){}; + + public: + //!Returns the address of the stored + //!stream buffer. + basic_vectorbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Swaps the underlying vector with the passed vector. + //!This function resets the read position in the stream. + //!Does not throw. + void swap_vector(vector_type &vect) + { m_buf.swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return m_buf.vector(); } + + //!Calls reserve() method of the internal vector. + //!Resets the stream to the first position. + //!Throws if the internals vector's reserve throws. + void reserve(typename vector_type::size_type size) + { m_buf.reserve(size); } + + //!Calls clear() method of the internal vector. + //!Resets the stream to the first position. + void clear() + { m_buf.clear(); } + + /// @cond + private: + basic_vectorbuf m_buf; + /// @endcond +}; + +//!A basic_ostream class that holds a character vector specified by CharVector +//!template parameter as its formatting buffer. The vector must have +//!contiguous storage, like std::vector, boost::interprocess::vector or +//!boost::interprocess::basic_string +template +class basic_ovectorstream + : public std::basic_ostream +{ + public: + typedef CharVector vector_type; + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + /// @cond + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_ostream base_t; + /// @endcond + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Throws if vector_type(const VectorParameter ¶m) + //!throws. + template + basic_ovectorstream(const VectorParameter ¶m, + std::ios_base::openmode mode = std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(param, mode | std::ios_base::out) + { basic_ios_t::init(&m_buf); } + + ~basic_ovectorstream(){} + + public: + //!Returns the address of the stored + //!stream buffer. + basic_vectorbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Swaps the underlying vector with the passed vector. + //!This function resets the write position in the stream. + //!Does not throw. + void swap_vector(vector_type &vect) + { m_buf.swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return m_buf.vector(); } + + //!Calls reserve() method of the internal vector. + //!Resets the stream to the first position. + //!Throws if the internals vector's reserve throws. + void reserve(typename vector_type::size_type size) + { m_buf.reserve(size); } + + /// @cond + private: + basic_vectorbuf m_buf; + /// @endcond +}; + + +//!A basic_iostream class that holds a character vector specified by CharVector +//!template parameter as its formatting buffer. The vector must have +//!contiguous storage, like std::vector, boost::interprocess::vector or +//!boost::interprocess::basic_string +template +class basic_vectorstream + : public std::basic_iostream + +{ + public: + typedef CharVector vector_type; + typedef typename std::basic_ios + ::char_type char_type; + typedef typename std::basic_ios::int_type int_type; + typedef typename std::basic_ios::pos_type pos_type; + typedef typename std::basic_ios::off_type off_type; + typedef typename std::basic_ios::traits_type traits_type; + + /// @cond + private: + typedef std::basic_ios basic_ios_t; + typedef std::basic_iostream base_t; + /// @endcond + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_vectorstream(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(mode) + { basic_ios_t::init(&m_buf); } + + //!Constructor. Throws if vector_type(const VectorParameter ¶m) + //!throws. + template + basic_vectorstream(const VectorParameter ¶m, std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : basic_ios_t(), base_t(0), m_buf(param, mode) + { basic_ios_t::init(&m_buf); } + + ~basic_vectorstream(){} + + public: + //Returns the address of the stored stream buffer. + basic_vectorbuf* rdbuf() const + { return const_cast*>(&m_buf); } + + //!Swaps the underlying vector with the passed vector. + //!This function resets the read/write position in the stream. + //!Does not throw. + void swap_vector(vector_type &vect) + { m_buf.swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return m_buf.vector(); } + + //!Calls reserve() method of the internal vector. + //!Resets the stream to the first position. + //!Throws if the internals vector's reserve throws. + void reserve(typename vector_type::size_type size) + { m_buf.reserve(size); } + + //!Calls clear() method of the internal vector. + //!Resets the stream to the first position. + void clear() + { m_buf.clear(); } + + /// @cond + private: + basic_vectorbuf m_buf; + /// @endcond +}; + +//Some typedefs to simplify usage +//! +//!typedef basic_vectorbuf > vectorbuf; +//!typedef basic_vectorstream > vectorstream; +//!typedef basic_ivectorstream > ivectorstream; +//!typedef basic_ovectorstream > ovectorstream; +//! +//!typedef basic_vectorbuf > wvectorbuf; +//!typedef basic_vectorstream > wvectorstream; +//!typedef basic_ivectorstream > wivectorstream; +//!typedef basic_ovectorstream > wovectorstream; + +}} //namespace boost { namespace interprocess { + +#include + +#endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */ diff --git a/thirdparty/boost/interprocess/sync/emulation/interprocess_barrier.hpp b/thirdparty/boost/interprocess/sync/emulation/interprocess_barrier.hpp new file mode 100644 index 0000000..2a889df --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/interprocess_barrier.hpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +namespace boost { +namespace interprocess { + +inline barrier::barrier(unsigned int count) + : m_threshold(count), m_count(count), m_generation(0) +{ + if (count == 0) + throw std::invalid_argument("count cannot be zero."); +} + +inline barrier::~barrier(){} + +inline bool barrier::wait() +{ + scoped_lock lock(m_mutex); + unsigned int gen = m_generation; + + if (--m_count == 0){ + m_generation++; + m_count = m_threshold; + m_cond.notify_all(); + return true; + } + + while (gen == m_generation){ + m_cond.wait(lock); + } + return false; +} + +} //namespace interprocess { +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/emulation/interprocess_condition.hpp b/thirdparty/boost/interprocess/sync/emulation/interprocess_condition.hpp new file mode 100644 index 0000000..3ec923a --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/interprocess_condition.hpp @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include + +namespace boost { +namespace interprocess { + +inline interprocess_condition::interprocess_condition() +{ + //Note that this class is initialized to zero. + //So zeroed memory can be interpreted as an initialized + //condition variable + m_command = SLEEP; + m_num_waiters = 0; +} + +inline interprocess_condition::~interprocess_condition() +{ + //Trivial destructor +} + +inline void interprocess_condition::notify_one() +{ + this->notify(NOTIFY_ONE); +} + +inline void interprocess_condition::notify_all() +{ + this->notify(NOTIFY_ALL); +} + +inline void interprocess_condition::notify(boost::uint32_t command) +{ + //This interprocess_mutex guarantees that no other thread can enter to the + //do_timed_wait method logic, so that thread count will be + //constant until the function writes a NOTIFY_ALL command. + //It also guarantees that no other notification can be signaled + //on this interprocess_condition before this one ends + m_enter_mut.lock(); + + //Return if there are no waiters + if(!detail::atomic_read32(&m_num_waiters)) { + m_enter_mut.unlock(); + return; + } + + //Notify that all threads should execute wait logic + while(SLEEP != detail::atomic_cas32((boost::uint32_t*)&m_command, command, SLEEP)){ + detail::thread_yield(); + } +/* + //Wait until the threads are woken + while(SLEEP != detail::atomic_cas32((boost::uint32_t*)&m_command, 0)){ + detail::thread_yield(); + } +*/ + //The enter interprocess_mutex will rest locked until the last waiting thread unlocks it +} + +inline void interprocess_condition::do_wait(interprocess_mutex &mut) +{ + this->do_timed_wait(false, boost::posix_time::ptime(), mut); +} + +inline bool interprocess_condition::do_timed_wait + (const boost::posix_time::ptime &abs_time, interprocess_mutex &mut) +{ + return this->do_timed_wait(true, abs_time, mut); +} + +inline bool interprocess_condition::do_timed_wait(bool tout_enabled, + const boost::posix_time::ptime &abs_time, + interprocess_mutex &mut) +{ + boost::posix_time::ptime now = microsec_clock::universal_time(); + + if(tout_enabled){ + if(now >= abs_time) return false; + } + + //The enter interprocess_mutex guarantees that while executing a notification, + //no other thread can execute the do_timed_wait method. + { + //--------------------------------------------------------------- + boost::interprocess::scoped_lock lock(m_enter_mut); + //--------------------------------------------------------------- + //We increment the waiting thread count protected so that it will be + //always constant when another thread enters the notification logic. + //The increment marks this thread as "waiting on interprocess_condition" + detail::atomic_inc32((boost::uint32_t*)&m_num_waiters); + + //We unlock the external interprocess_mutex atomically with the increment + mut.unlock(); + } + + //By default, we suppose that no timeout has happened + bool timed_out = false, unlock_enter_mut= false; + + //Loop until a notification indicates that the thread should + //exit or timeout occurs + while(1){ + //The thread sleeps/spins until a interprocess_condition commands a notification + //Notification occurred, we will lock the checking interprocess_mutex so that + while(detail::atomic_read32(&m_command) == SLEEP){ + detail::thread_yield(); + + //Check for timeout + if(tout_enabled){ + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + //If we can lock the interprocess_mutex it means that no notification + //is being executed in this interprocess_condition variable + timed_out = m_enter_mut.try_lock(); + + //If locking fails, indicates that another thread is executing + //notification, so we play the notification game + if(!timed_out){ + //There is an ongoing notification, we will try again later + continue; + } + //No notification in execution, since enter interprocess_mutex is locked. + //We will execute time-out logic, so we will decrement count, + //release the enter interprocess_mutex and return false. + break; + } + } + } + + //If a timeout occurred, the interprocess_mutex will not execute checking logic + if(tout_enabled && timed_out){ + //Decrement wait count + detail::atomic_dec32((boost::uint32_t*)&m_num_waiters); + unlock_enter_mut = true; + break; + } + else{ + //Notification occurred, we will lock the checking interprocess_mutex so that + //if a notify_one notification occurs, only one thread can exit + //--------------------------------------------------------------- + boost::interprocess::scoped_lock lock(m_check_mut); + //--------------------------------------------------------------- + boost::uint32_t result = detail::atomic_cas32 + ((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ONE); + if(result == SLEEP){ + //Other thread has been notified and since it was a NOTIFY one + //command, this thread must sleep again + continue; + } + else if(result == NOTIFY_ONE){ + //If it was a NOTIFY_ONE command, only this thread should + //exit. This thread has atomically marked command as sleep before + //so no other thread will exit. + //Decrement wait count. + unlock_enter_mut = true; + detail::atomic_dec32((boost::uint32_t*)&m_num_waiters); + break; + } + else{ + //If it is a NOTIFY_ALL command, all threads should return + //from do_timed_wait function. Decrement wait count. + unlock_enter_mut = 1 == detail::atomic_dec32((boost::uint32_t*)&m_num_waiters); + //Check if this is the last thread of notify_all waiters + //Only the last thread will release the interprocess_mutex + if(unlock_enter_mut){ + detail::atomic_cas32((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ALL); + } + break; + } + } + } + + //Unlock the enter interprocess_mutex if it is a single notification, if this is + //the last notified thread in a notify_all or a timeout has occurred + if(unlock_enter_mut){ + m_enter_mut.unlock(); + } + + //Lock external again before returning from the method + mut.lock(); + return !timed_out; +} + +} //namespace interprocess +} // namespace boost diff --git a/thirdparty/boost/interprocess/sync/emulation/interprocess_mutex.hpp b/thirdparty/boost/interprocess/sync/emulation/interprocess_mutex.hpp new file mode 100644 index 0000000..36dc4e6 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/interprocess_mutex.hpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include + +namespace boost { + +namespace interprocess { + +inline interprocess_mutex::interprocess_mutex() + : m_s(0) +{ + //Note that this class is initialized to zero. + //So zeroed memory can be interpreted as an + //initialized mutex +} + +inline interprocess_mutex::~interprocess_mutex() +{ + //Trivial destructor +} + +inline void interprocess_mutex::lock(void) +{ + do{ + boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0); + + if (m_s == 1 && prev_s == 0){ + break; + } + // relinquish current timeslice + detail::thread_yield(); + }while (true); +} + +inline bool interprocess_mutex::try_lock(void) +{ + boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0); + return m_s == 1 && prev_s == 0; +} + +inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + + if(now >= abs_time) return false; + + do{ + if(this->try_lock()){ + break; + } + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + return false; + } + // relinquish current time slice + detail::thread_yield(); + }while (true); + + return true; +} + +inline void interprocess_mutex::unlock(void) +{ detail::atomic_cas32((boost::uint32_t*)&m_s, 0, 1); } + +} //namespace interprocess { + +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp b/thirdparty/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp new file mode 100644 index 0000000..bec57bd --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Parts of the pthread code come from Boost Threads code: +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2003 +// William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +namespace boost { + +namespace interprocess { + +inline interprocess_recursive_mutex::interprocess_recursive_mutex() + : m_nLockCount(0), m_nOwner(detail::get_invalid_thread_id()){} + +inline interprocess_recursive_mutex::~interprocess_recursive_mutex(){} + +inline void interprocess_recursive_mutex::lock() +{ + detail::OS_thread_id_t th_id = detail::get_current_thread_id(); + if(detail::equal_thread_id(th_id, m_nOwner)){ + if((unsigned int)(m_nLockCount+1) == 0){ + //Overflow, throw an exception + throw interprocess_exception(); + } + ++m_nLockCount; + } + else{ + m_mutex.lock(); + m_nOwner = th_id; + m_nLockCount = 1; + } +} + +inline bool interprocess_recursive_mutex::try_lock() +{ + detail::OS_thread_id_t th_id = detail::get_current_thread_id(); + if(detail::equal_thread_id(th_id, m_nOwner)) { // we own it + if((unsigned int)(m_nLockCount+1) == 0){ + //Overflow, throw an exception + throw interprocess_exception(); + } + ++m_nLockCount; + return true; + } + if(m_mutex.try_lock()){ + m_nOwner = th_id; + m_nLockCount = 1; + return true; + } + return false; +} + +inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ + detail::OS_thread_id_t th_id = detail::get_current_thread_id(); + if(detail::equal_thread_id(th_id, m_nOwner)) { // we own it + if((unsigned int)(m_nLockCount+1) == 0){ + //Overflow, throw an exception + throw interprocess_exception(); + } + ++m_nLockCount; + return true; + } + if(m_mutex.timed_lock(abs_time)){ + m_nOwner = th_id; + m_nLockCount = 1; + return true; + } + return false; +} + +inline void interprocess_recursive_mutex::unlock() +{ + assert(detail::equal_thread_id(detail::get_current_thread_id(), m_nOwner)); + --m_nLockCount; + if(!m_nLockCount){ + m_nOwner = detail::get_invalid_thread_id(); + m_mutex.unlock(); + } +} + +} //namespace interprocess { + +} //namespace boost { + diff --git a/thirdparty/boost/interprocess/sync/emulation/interprocess_semaphore.hpp b/thirdparty/boost/interprocess/sync/emulation/interprocess_semaphore.hpp new file mode 100644 index 0000000..3cc9345 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/interprocess_semaphore.hpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +namespace boost { +namespace interprocess { + +inline interprocess_semaphore::~interprocess_semaphore() +{} + +inline interprocess_semaphore::interprocess_semaphore(int initialCount) + : m_mut(), m_cond(), m_count(initialCount) +{} + +inline void interprocess_semaphore::post() +{ + scoped_lock lock(m_mut); + if(m_count == 0){ + m_cond.notify_one(); + } + ++m_count; +} + +inline void interprocess_semaphore::wait() +{ + scoped_lock lock(m_mut); + while(m_count == 0){ + m_cond.wait(lock); + } + --m_count; +} + +inline bool interprocess_semaphore::try_wait() +{ + scoped_lock lock(m_mut); + if(m_count == 0){ + return false; + } + --m_count; + return true; +} + +inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) +{ + scoped_lock lock(m_mut); + while(m_count == 0){ + if(!m_cond.timed_wait(lock, abs_time)) + return m_count != 0; + } + --m_count; + return true; +} +/* +inline int interprocess_semaphore::get_count() const +{ + scoped_lock lock(m_mut); + return count; +}*/ + +} //namespace interprocess { +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/emulation/named_creation_functor.hpp b/thirdparty/boost/interprocess/sync/emulation/named_creation_functor.hpp new file mode 100644 index 0000000..85e4b1e --- /dev/null +++ b/thirdparty/boost/interprocess/sync/emulation/named_creation_functor.hpp @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP +#define BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP + +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail { + +struct named_creation_functor_no_arg{}; + +template +class named_creation_functor +{ + typedef named_creation_functor_no_arg no_arg_t; + public: + named_creation_functor(detail::create_enum_t type, Arg arg = Arg()) + : m_creation_type(type), m_arg(arg){} + + template + void construct(void *address, typename enable_if_c::value>::type * = 0) const + { new(address)T; } + + template + void construct(void *address, typename enable_if_c::value>::type * = 0) const + { new(address)T(m_arg); } + + bool operator()(void *address, std::size_t, bool created) const + { + switch(m_creation_type){ + case detail::DoOpen: + return true; + break; + case detail::DoCreate: + case detail::DoOpenOrCreate: + if(created){ + construct(address); + } + return true; + break; + + default: + return false; + break; + } + } + private: + detail::create_enum_t m_creation_type; + Arg m_arg; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#endif //BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP diff --git a/thirdparty/boost/interprocess/sync/file_lock.hpp b/thirdparty/boost/interprocess/sync/file_lock.hpp new file mode 100644 index 0000000..f96d5f1 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/file_lock.hpp @@ -0,0 +1,319 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_FILE_LOCK_HPP +#define BOOST_INTERPROCESS_FILE_LOCK_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a class that wraps file locking capabilities. + +namespace boost { +namespace interprocess { + +//!A file lock, is a mutual exclusion utility similar to a mutex using a +//!file. A file lock has sharable and exclusive locking capabilities and +//!can be used with scoped_lock and sharable_lock classes. +class file_lock +{ + /// @cond + //Non-copyable + file_lock(); + file_lock(const file_lock &); + file_lock &operator=(const file_lock &); + /// @endcond + public: + //!Opens a file lock. Throws interprocess_exception if the file does not + //!exist or there are no operating system resources. + file_lock(const char *name); + + //!Closes a file lock. Does not throw. + ~file_lock(); + + //Exclusive locking + + //!Effects: The calling thread tries to obtain exclusive ownership of the mutex, + //! and if another thread has exclusive, or sharable ownership of + //! the mutex, it waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! without waiting. If no other thread has exclusive, or sharable + //! ownership of the mutex this succeeds. + //!Returns: If it can acquire exclusive ownership immediately returns true. + //! If it has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! waiting if necessary until no other thread has has exclusive, or sharable + //! ownership of the mutex or abs_time is reached. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The calling thread releases the exclusive ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock(); + + //Sharable locking + + //!Effects: The calling thread tries to obtain sharable ownership of the mutex, + //! and if another thread has exclusive ownership of the mutex, waits until + //! it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! without waiting. If no other thread has has exclusive ownership of the + //! mutex this succeeds. + //!Returns: If it can acquire sharable ownership immediately returns true. If it + //! has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! waiting if necessary until no other thread has has exclusive ownership of + //! the mutex or abs_time is reached. + //!Returns: If acquires sharable ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock_sharable(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The calling thread releases the sharable ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_sharable(); + /// @cond + private: + file_handle_t m_file_hnd; + + bool timed_acquire_file_lock + (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time) + { + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + using namespace boost::detail; + + if(now >= abs_time) return false; + + do{ + if(!try_acquire_file_lock(hnd, acquired)) + return false; + + if(acquired) + return true; + else{ + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + acquired = false; + return true; + } + // relinquish current time slice + winapi::sched_yield(); + } + }while (true); + } + + bool timed_acquire_file_lock_sharable + (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time) + { + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + using namespace boost::detail; + + if(now >= abs_time) return false; + + do{ + if(!try_acquire_file_lock_sharable(hnd, acquired)) + return false; + + if(acquired) + return true; + else{ + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + acquired = false; + return true; + } + // relinquish current time slice + winapi::sched_yield(); + } + }while (true); + } + + bool timed_acquire_file_lock + (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time) + { + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + using namespace boost::detail; + + if(now >= abs_time) return false; + + do{ + if(!try_acquire_file_lock(hnd, acquired)) + return false; + + if(acquired) + return true; + else{ + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + acquired = false; + return true; + } + // relinquish current time slice + sleep(0); + } + }while (true); + } + + bool timed_acquire_file_lock_sharable + (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time) + { + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + using namespace boost::detail; + + if(now >= abs_time) return false; + + do{ + if(!try_acquire_file_lock_sharable(hnd, acquired)) + return false; + + if(acquired) + return true; + else{ + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + acquired = false; + return true; + } + // relinquish current time slice + ::sleep(0); + } + }while (true); + } + /// @endcond +}; + +inline file_lock::file_lock(const char *name) +{ + m_file_hnd = detail::open_existing_file(name); + + if(m_file_hnd == detail::invalid_file()){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline file_lock::~file_lock() +{ + if(m_file_hnd != detail::invalid_file()){ + detail::close_file(m_file_hnd); + m_file_hnd = detail::invalid_file(); + } +} + +inline void file_lock::lock() +{ + if(!detail::acquire_file_lock(m_file_hnd)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline bool file_lock::try_lock() +{ + bool result; + if(!detail::try_acquire_file_lock(m_file_hnd, result)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } + return result; +} + +inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time) +{ + bool result; + if(!detail::timed_acquire_file_lock(m_file_hnd, result, abs_time)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } + return result; +} + +inline void file_lock::unlock() +{ + if(!detail::release_file_lock(m_file_hnd)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline void file_lock::lock_sharable() +{ + if(!detail::acquire_file_lock_sharable(m_file_hnd)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +inline bool file_lock::try_lock_sharable() +{ + bool result; + if(!detail::try_acquire_file_lock_sharable(m_file_hnd, result)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } + return result; +} + +inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time) +{ + bool result; + if(!detail::timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } + return result; +} + +inline void file_lock::unlock_sharable() +{ + if(!detail::release_file_lock_sharable(m_file_hnd)){ + error_info err(system_error_code()); + throw interprocess_exception(err); + } +} + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_FILE_LOCK_HPP diff --git a/thirdparty/boost/interprocess/sync/interprocess_barrier.hpp b/thirdparty/boost/interprocess/sync/interprocess_barrier.hpp new file mode 100644 index 0000000..b8bab2b --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_barrier.hpp @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// barrier is a modified version of Boost Threads barrier +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2002-2003 +// David Moore, William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. + +#ifndef BOOST_INTERPROCESS_BARRIER_HPP +#define BOOST_INTERPROCESS_BARRIER_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED && defined BOOST_INTERPROCESS_POSIX_BARRIERS +# include +# include +# include +# define BOOST_INTERPROCESS_USE_POSIX +#else +# include +# include +# include +# include +# define BOOST_INTERPROCESS_USE_GENERIC_EMULATION +#endif + +# include + +namespace boost { +namespace interprocess { + +//!An object of class barrier is a synchronization primitive that +//!can be placed in shared memory used to cause a set of threads from +//!different processes to wait until they each perform a certain +//!function or each reach a particular point in their execution. +class barrier +{ + public: + //!Constructs a barrier object that will cause count threads + //!to block on a call to wait(). + barrier(unsigned int count); + + //!Destroys *this. If threads are still executing their wait() + //!operations, the behavior for these threads is undefined. + ~barrier(); + + //!Effects: Wait until N threads call wait(), where N equals the count + //!provided to the constructor for the barrier object. + //!Note that if the barrier is destroyed before wait() can return, + //!the behavior is undefined. + //!Returns: Exactly one of the N threads will receive a return value + //!of true, the others will receive a value of false. Precisely which + //!thread receives the return value of true will be implementation-defined. + //!Applications can use this value to designate one thread as a leader that + //!will take a certain action, and the other threads emerging from the barrier + //!can wait for that action to take place. + bool wait(); + + /// @cond + private: + #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + interprocess_mutex m_mutex; + interprocess_condition m_cond; + unsigned int m_threshold; + unsigned int m_count; + unsigned int m_generation; + #else //#if defined BOOST_INTERPROCESS_USE_POSIX + pthread_barrier_t m_barrier; + #endif//#if defined BOOST_INTERPROCESS_USE_POSIX + /// @endcond +}; + +} // namespace interprocess +} // namespace boost + + +#ifdef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# include +#endif + +#ifdef BOOST_INTERPROCESS_USE_POSIX +# undef BOOST_INTERPROCESS_USE_POSIX +# include +#endif + +#include + +#endif diff --git a/thirdparty/boost/interprocess/sync/interprocess_condition.hpp b/thirdparty/boost/interprocess/sync/interprocess_condition.hpp new file mode 100644 index 0000000..945a376 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_condition.hpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_CONDITION_HPP +#define BOOST_INTERPROCESS_CONDITION_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED + #include + #include + #include + #define BOOST_INTERPROCESS_USE_POSIX +#else + #include + #include + #include + #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION +#endif + +//!\file +//!Describes process-shared variables interprocess_condition class + +namespace boost { + +namespace posix_time +{ class ptime; } + +namespace interprocess { + +class named_condition; + +class interprocess_condition +{ + /// @cond + //Non-copyable + interprocess_condition(const interprocess_condition &); + interprocess_condition &operator=(const interprocess_condition &); + friend class named_condition; + /// @endcond + public: + //!Constructs a interprocess_condition. On error throws interprocess_exception. + interprocess_condition(); + + //!Destroys *this + //!liberating system resources. + ~interprocess_condition(); + + //!If there is a thread waiting on *this, change that + //!thread's state to ready. Otherwise there is no effect. + void notify_one(); + + //!Change the state of all threads waiting on *this to ready. + //!If there are no waiting threads, notify_all() has no effect. + void notify_all(); + + //!Releases the lock on the interprocess_mutex object associated with lock, blocks + //!the current thread of execution until readied by a call to + //!this->notify_one() or this->notify_all(), and then reacquires the lock. + template + void wait(L& lock) + { + if (!lock) + throw lock_exception(); + do_wait(*lock.mutex()); + } + + //!The same as: + //!while (!pred()) wait(lock) + template + void wait(L& lock, Pr pred) + { + if (!lock) + throw lock_exception(); + + while (!pred()) + do_wait(*lock.mutex()); + } + + //!Releases the lock on the interprocess_mutex object associated with lock, blocks + //!the current thread of execution until readied by a call to + //!this->notify_one() or this->notify_all(), or until time abs_time is reached, + //!and then reacquires the lock. + //!Returns: false if time abs_time is reached, otherwise true. + template + bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time) + { + if (!lock) + throw lock_exception(); + + return do_timed_wait(abs_time, *lock.mutex()); + } + + //!The same as: while (!pred()) { + //! if (!timed_wait(lock, abs_time)) return pred(); + //! } return true; + template + bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred) + { + if (!lock) + throw lock_exception(); + + while (!pred()){ + if (!do_timed_wait(abs_time, *lock.mutex())) + return pred(); + } + + return true; + } + + /// @cond + private: + void do_wait(interprocess_mutex &mut); + + bool do_timed_wait(const boost::posix_time::ptime &abs_time, interprocess_mutex &mut); + + #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + enum { SLEEP = 0, NOTIFY_ONE, NOTIFY_ALL }; + interprocess_mutex m_enter_mut; + interprocess_mutex m_check_mut; + volatile boost::uint32_t m_command; + volatile boost::uint32_t m_num_waiters; + bool do_timed_wait(bool tout_enabled, const boost::posix_time::ptime &abs_time, interprocess_mutex &mut); + void notify(boost::uint32_t command); + #elif defined(BOOST_INTERPROCESS_USE_POSIX) + pthread_cond_t m_condition; + #endif + /// @endcond +}; + +} //namespace interprocess + +} // namespace boost + +#ifdef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# include +#endif + +#ifdef BOOST_INTERPROCESS_USE_POSIX +# undef BOOST_INTERPROCESS_USE_POSIX +# include +#endif + +#include + +#endif // BOOST_INTERPROCESS_CONDITION_HPP diff --git a/thirdparty/boost/interprocess/sync/interprocess_mutex.hpp b/thirdparty/boost/interprocess/sync/interprocess_mutex.hpp new file mode 100644 index 0000000..0989c76 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_mutex.hpp @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Parts of the pthread code come from Boost Threads code. +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2003 +// William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MUTEX_HPP +#define BOOST_INTERPROCESS_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include + +#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED + #include + #include + #include + #define BOOST_INTERPROCESS_USE_POSIX +#else + #include + #include + #include + #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION +#endif + +//!\file +//!Describes a mutex class that can be placed in memory shared by +//!several processes. + +namespace boost { +namespace interprocess { + +class interprocess_condition; + +//!Wraps a interprocess_mutex that can be placed in shared memory and can be +//!shared between processes. Allows timed lock tries +class interprocess_mutex +{ + /// @cond + //Non-copyable + interprocess_mutex(const interprocess_mutex &); + interprocess_mutex &operator=(const interprocess_mutex &); + friend class interprocess_condition; + /// @endcond + public: + + //!Constructor. + //!Throws interprocess_exception on error. + interprocess_mutex(); + + //!Destructor. If any process uses the mutex after the destructor is called + //!the result is undefined. Does not throw. + ~interprocess_mutex(); + + //!Effects: The calling thread tries to obtain ownership of the mutex, and + //! if another thread has ownership of the mutex, it waits until it can + //! obtain the ownership. If a thread takes ownership of the mutex the + //! mutex must be unlocked by the same mutex. + //!Throws: interprocess_exception on error. + void lock(); + + //!Effects: The calling thread tries to obtain ownership of the mutex, and + //! if another thread has ownership of the mutex returns immediately. + //!Returns: If the thread acquires ownership of the mutex, returns true, if + //! the another thread has ownership of the mutex, returns false. + //!Throws: interprocess_exception on error. + bool try_lock(); + + //!Effects: The calling thread will try to obtain exclusive ownership of the + //! mutex if it can do so in until the specified time is reached. If the + //! mutex supports recursive locking, the mutex must be unlocked the same + //! number of times it is locked. + //!Returns: If the thread acquires ownership of the mutex, returns true, if + //! the timeout expires returns false. + //!Throws: interprocess_exception on error. + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Effects: The calling thread releases the exclusive ownership of the mutex. + //!Throws: interprocess_exception on error. + void unlock(); + /// @cond + private: + + #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + volatile boost::uint32_t m_s; + #elif defined(BOOST_INTERPROCESS_USE_POSIX) + pthread_mutex_t m_mut; + #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + /// @endcond +}; + +} //namespace interprocess { + +} //namespace boost { + +#ifdef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# include +#endif + +#ifdef BOOST_INTERPROCESS_USE_POSIX +# undef BOOST_INTERPROCESS_USE_POSIX +# include +#endif + +#include + +#endif //BOOST_INTERPROCESS_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/interprocess_recursive_mutex.hpp b/thirdparty/boost/interprocess/sync/interprocess_recursive_mutex.hpp new file mode 100644 index 0000000..4aaad44 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_recursive_mutex.hpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Parts of the pthread code come from Boost Threads code: +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2003 +// William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP +#define BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include + +#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED && defined BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES + #include + #include + #include + #define BOOST_INTERPROCESS_USE_POSIX +#else + #include + #include + #include + #include + #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION +#endif + +//!\file +//!Describes interprocess_recursive_mutex and shared_recursive_try_mutex classes + +namespace boost { + +namespace interprocess { + +//!Wraps a interprocess_mutex that can be placed in shared memory and can be +//!shared between processes. Allows several locking calls by the same +//!process. Allows timed lock tries +class interprocess_recursive_mutex +{ + /// @cond + //Non-copyable + interprocess_recursive_mutex(const interprocess_recursive_mutex &); + interprocess_recursive_mutex &operator=(const interprocess_recursive_mutex &); + /// @endcond + public: + //!Constructor. + //!Throws interprocess_exception on error. + interprocess_recursive_mutex(); + + //!Destructor. If any process uses the mutex after the destructor is called + //!the result is undefined. Does not throw. + ~interprocess_recursive_mutex(); + + //!Effects: The calling thread tries to obtain ownership of the mutex, and + //! if another thread has ownership of the mutex, it waits until it can + //! obtain the ownership. If a thread takes ownership of the mutex the + //! mutex must be unlocked by the same mutex. The mutex must be unlocked + //! the same number of times it is locked. + //!Throws: interprocess_exception on error. + void lock(void); + + //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex + //!is already locked, returns true when success. The mutex must be unlocked + //!the same number of times it is locked. + //!Throws: interprocess_exception if a severe error is found + bool try_lock(void); + + //!Tries to lock the interprocess_mutex, if interprocess_mutex can't be locked before + //!abs_time time, returns false. The mutex must be unlocked + //! the same number of times it is locked. + //!Throws: interprocess_exception if a severe error is found + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Effects: The calling thread releases the exclusive ownership of the mutex. + //! If the mutex supports recursive locking, the mutex must be unlocked the + //! same number of times it is locked. + //!Throws: interprocess_exception on error. + void unlock(void); + /// @cond + private: + #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + interprocess_mutex m_mutex; + unsigned int m_nLockCount; + detail::OS_thread_id_t m_nOwner; + #else //#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + pthread_mutex_t m_mut; + #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32) + /// @endcond +}; + +} //namespace interprocess { + +} //namespace boost { + +#ifdef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# include +#endif + +#ifdef BOOST_INTERPROCESS_USE_POSIX +# undef BOOST_INTERPROCESS_USE_POSIX +# include +#endif + +#include + +#endif //BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/interprocess_semaphore.hpp b/thirdparty/boost/interprocess/sync/interprocess_semaphore.hpp new file mode 100644 index 0000000..f9f6dcd --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_semaphore.hpp @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP +#define BOOST_INTERPROCESS_SEMAPHORE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include + +#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED &&\ + defined BOOST_INTERPROCESS_POSIX_SEMAPHORES + #include //O_CREAT, O_*... + #include //close + #include //std::string + #include //sem_* family, SEM_VALUE_MAX + #include //mode_t, S_IRWXG, S_IRWXO, S_IRWXU, + #include + #define BOOST_INTERPROCESS_USE_POSIX +#else + #include + #include + #include + #include + #include + #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION +#endif + +//!\file +//!Describes a interprocess_semaphore class for inter-process synchronization + +namespace boost { + +namespace interprocess { + +//!Wraps a interprocess_semaphore that can be placed in shared memory and can be +//!shared between processes. Allows timed lock tries +class interprocess_semaphore +{ + /// @cond + //Non-copyable + interprocess_semaphore(const interprocess_semaphore &); + interprocess_semaphore &operator=(const interprocess_semaphore &); + /// @endcond + public: + //!Creates a interprocess_semaphore with the given initial count. + //!interprocess_exception if there is an error.*/ + interprocess_semaphore(int initialCount); + + //!Destroys the interprocess_semaphore. + //!Does not throw + ~interprocess_semaphore(); + + //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting + //!for the interprocess_semaphore, then one of these processes will return successfully from + //!its wait function. If there is an error an interprocess_exception exception is thrown. + void post(); + + //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero, + //!then the calling process/thread blocks until it can decrement the counter. + //!If there is an error an interprocess_exception exception is thrown. + void wait(); + + //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero + //!and returns true. If the value is not greater than zero returns false. + //!If there is an error an interprocess_exception exception is thrown. + bool try_wait(); + + //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater + //!than zero and returns true. Otherwise, waits for the interprocess_semaphore + //!to the posted or the timeout expires. If the timeout expires, the + //!function returns false. If the interprocess_semaphore is posted the function + //!returns true. If there is an error throws sem_exception + bool timed_wait(const boost::posix_time::ptime &abs_time); + + //!Returns the interprocess_semaphore count +// int get_count() const; + /// @cond + private: + #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + interprocess_mutex m_mut; + interprocess_condition m_cond; + int m_count; + #else + detail::semaphore_wrapper m_sem; + #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) + /// @endcond +}; + +} //namespace interprocess { + +} //namespace boost { + +#ifdef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION +# include +#endif + +#ifdef BOOST_INTERPROCESS_USE_POSIX +# undef BOOST_INTERPROCESS_USE_POSIX +# include +#endif + +#include + +#endif //BOOST_INTERPROCESS_SEMAPHORE_HPP diff --git a/thirdparty/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/thirdparty/boost/interprocess/sync/interprocess_upgradable_mutex.hpp new file mode 100644 index 0000000..c1a2875 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/interprocess_upgradable_mutex.hpp @@ -0,0 +1,643 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP +#define BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + + +//!\file +//!Describes interprocess_upgradable_mutex class + +namespace boost { +namespace interprocess { + +//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be +//!shared between processes. Allows timed lock tries +class interprocess_upgradable_mutex +{ + //Non-copyable + interprocess_upgradable_mutex(const interprocess_upgradable_mutex &); + interprocess_upgradable_mutex &operator=(const interprocess_upgradable_mutex &); + + friend class interprocess_condition; + public: + + //!Constructs the upgradable lock. + //!Throws interprocess_exception on error. + interprocess_upgradable_mutex(); + + //!Destroys the upgradable lock. + //!Does not throw. + ~interprocess_upgradable_mutex(); + + //Exclusive locking + + //!Effects: The calling thread tries to obtain exclusive ownership of the mutex, + //! and if another thread has exclusive, sharable or upgradable ownership of + //! the mutex, it waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! without waiting. If no other thread has exclusive, sharable or upgradable + //! ownership of the mutex this succeeds. + //!Returns: If it can acquire exclusive ownership immediately returns true. + //! If it has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! waiting if necessary until no other thread has has exclusive, sharable or + //! upgradable ownership of the mutex or abs_time is reached. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The calling thread releases the exclusive ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock(); + + //Sharable locking + + //!Effects: The calling thread tries to obtain sharable ownership of the mutex, + //! and if another thread has exclusive or upgradable ownership of the mutex, + //! waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! without waiting. If no other thread has has exclusive or upgradable ownership + //! of the mutex this succeeds. + //!Returns: If it can acquire sharable ownership immediately returns true. If it + //! has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! waiting if necessary until no other thread has has exclusive or upgradable + //! ownership of the mutex or abs_time is reached. + //!Returns: If acquires sharable ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock_sharable(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The calling thread releases the sharable ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_sharable(); + + //Upgradable locking + + //!Effects: The calling thread tries to obtain upgradable ownership of the mutex, + //! and if another thread has exclusive or upgradable ownership of the mutex, + //! waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock_upgradable(); + + //!Effects: The calling thread tries to acquire upgradable ownership of the mutex + //! without waiting. If no other thread has has exclusive or upgradable ownership + //! of the mutex this succeeds. + //!Returns: If it can acquire upgradable ownership immediately returns true. + //! If it has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock_upgradable(); + + //!Effects: The calling thread tries to acquire upgradable ownership of the mutex + //! waiting if necessary until no other thread has has exclusive or upgradable + //! ownership of the mutex or abs_time is reached. + //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The calling thread releases the upgradable ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable(); + + //Demotions + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The thread atomically releases exclusive ownership and acquires + //! upgradable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_and_lock_upgradable(); + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The thread atomically releases exclusive ownership and acquires + //! sharable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_and_lock_sharable(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and acquires + //! sharable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable_and_lock_sharable(); + + //Promotions + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and acquires + //! exclusive ownership. This operation will block until all threads with + //! sharable ownership release their sharable lock. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable_and_lock(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and tries to + //! acquire exclusive ownership. This operation will fail if there are threads + //! with sharable ownership, but it will maintain upgradable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool try_unlock_upgradable_and_lock(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and tries to acquire + //! exclusive ownership, waiting if necessary until abs_time. This operation will + //! fail if there are threads with sharable ownership or timeout reaches, but it + //! will maintain upgradable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. */ + bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The thread atomically releases sharable ownership and tries to acquire + //! exclusive ownership. This operation will fail if there are threads with sharable + //! or upgradable ownership, but it will maintain sharable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool try_unlock_sharable_and_lock(); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The thread atomically releases sharable ownership and tries to acquire + //! upgradable ownership. This operation will fail if there are threads with sharable + //! or upgradable ownership, but it will maintain sharable ownership. + //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool try_unlock_sharable_and_lock_upgradable(); + + /// @cond + private: + typedef scoped_lock scoped_lock_t; + + //Pack all the control data in a word to be able + //to use atomic instructions in the future + struct control_word_t + { + unsigned exclusive_in : 1; + unsigned upgradable_in : 1; + unsigned num_upr_shar : sizeof(unsigned)*CHAR_BIT-2; + } m_ctrl; + + interprocess_mutex m_mut; + interprocess_condition m_first_gate; + interprocess_condition m_second_gate; + + private: + //Rollback structures for exceptions or failure return values + struct exclusive_rollback + { + exclusive_rollback(control_word_t &ctrl + ,interprocess_condition &first_gate) + : mp_ctrl(&ctrl), m_first_gate(first_gate) + {} + + void release() + { mp_ctrl = 0; } + + ~exclusive_rollback() + { + if(mp_ctrl){ + mp_ctrl->exclusive_in = 0; + m_first_gate.notify_all(); + } + } + control_word_t *mp_ctrl; + interprocess_condition &m_first_gate; + }; + + struct upgradable_to_exclusive_rollback + { + upgradable_to_exclusive_rollback(control_word_t &ctrl) + : mp_ctrl(&ctrl) + {} + + void release() + { mp_ctrl = 0; } + + ~upgradable_to_exclusive_rollback() + { + if(mp_ctrl){ + //Recover upgradable lock + mp_ctrl->upgradable_in = 1; + ++mp_ctrl->num_upr_shar; + //Execute the second half of exclusive locking + mp_ctrl->exclusive_in = 0; + } + } + control_word_t *mp_ctrl; + }; + + template + struct base_constants_t + { + static const unsigned max_readers + = ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2)); + }; + typedef base_constants_t<0> constants; + /// @endcond +}; + +template +const unsigned interprocess_upgradable_mutex::base_constants_t::max_readers; + +inline interprocess_upgradable_mutex::interprocess_upgradable_mutex() +{ + this->m_ctrl.exclusive_in = 0; + this->m_ctrl.upgradable_in = 0; + this->m_ctrl.num_upr_shar = 0; +} + +inline interprocess_upgradable_mutex::~interprocess_upgradable_mutex() +{} + +inline void interprocess_upgradable_mutex::lock() +{ + scoped_lock_t lock(m_mut); + + //The exclusive lock must block in the first gate + //if an exclusive or upgradable lock has been acquired + while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){ + this->m_first_gate.wait(lock); + } + + //Mark that exclusive lock has been acquired + this->m_ctrl.exclusive_in = 1; + + //Prepare rollback + exclusive_rollback rollback(this->m_ctrl, this->m_first_gate); + + //Now wait until all readers are gone + while (this->m_ctrl.num_upr_shar){ + this->m_second_gate.wait(lock); + } + rollback.release(); +} + +inline bool interprocess_upgradable_mutex::try_lock() +{ + scoped_lock_t lock(m_mut, try_to_lock); + + //If we can't lock or any has there is any exclusive, upgradable + //or sharable mark return false; + if(!lock.owns() + || this->m_ctrl.exclusive_in + || this->m_ctrl.num_upr_shar){ + return false; + } + this->m_ctrl.exclusive_in = 1; + return true; +} + +inline bool interprocess_upgradable_mutex::timed_lock + (const boost::posix_time::ptime &abs_time) +{ + scoped_lock_t lock(m_mut, abs_time); + if(!lock.owns()) return false; + + //The exclusive lock must block in the first gate + //if an exclusive or upgradable lock has been acquired + while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){ + if(!this->m_first_gate.timed_wait(lock, abs_time)) + return !(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in); + } + + //Mark that exclusive lock has been acquired + this->m_ctrl.exclusive_in = 1; + + //Prepare rollback + exclusive_rollback rollback(this->m_ctrl, this->m_first_gate); + + //Now wait until all readers are gone + while (this->m_ctrl.num_upr_shar){ + if(!this->m_second_gate.timed_wait(lock, abs_time)){ + return !(this->m_ctrl.num_upr_shar); + } + } + rollback.release(); + return true; +} + +inline void interprocess_upgradable_mutex::unlock() +{ + scoped_lock_t lock(m_mut); + this->m_ctrl.exclusive_in = 0; + this->m_first_gate.notify_all(); +} + +//Upgradable locking + +inline void interprocess_upgradable_mutex::lock_upgradable() +{ + scoped_lock_t lock(m_mut); + + //The upgradable lock must block in the first gate + //if an exclusive or upgradable lock has been acquired + //or there are too many sharable locks + while(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + this->m_first_gate.wait(lock); + } + + //Mark that upgradable lock has been acquired + //And add upgradable to the sharable count + this->m_ctrl.upgradable_in = 1; + ++this->m_ctrl.num_upr_shar; +} + +inline bool interprocess_upgradable_mutex::try_lock_upgradable() +{ + scoped_lock_t lock(m_mut, try_to_lock); + + //The upgradable lock must fail + //if an exclusive or upgradable lock has been acquired + //or there are too many sharable locks + if(!lock.owns() + || this->m_ctrl.exclusive_in + || this->m_ctrl.upgradable_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + return false; + } + + //Mark that upgradable lock has been acquired + //And add upgradable to the sharable count + this->m_ctrl.upgradable_in = 1; + ++this->m_ctrl.num_upr_shar; + return true; +} + +inline bool interprocess_upgradable_mutex::timed_lock_upgradable + (const boost::posix_time::ptime &abs_time) +{ + scoped_lock_t lock(m_mut, abs_time); + if(!lock.owns()) return false; + + //The upgradable lock must block in the first gate + //if an exclusive or upgradable lock has been acquired + //or there are too many sharable locks + while(this->m_ctrl.exclusive_in + || this->m_ctrl.upgradable_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + if(!this->m_first_gate.timed_wait(lock, abs_time)){ + return!(this->m_ctrl.exclusive_in + || this->m_ctrl.upgradable_in + || this->m_ctrl.num_upr_shar == constants::max_readers); + } + } + + //Mark that upgradable lock has been acquired + //And add upgradable to the sharable count + this->m_ctrl.upgradable_in = 1; + ++this->m_ctrl.num_upr_shar; + return true; +} + +inline void interprocess_upgradable_mutex::unlock_upgradable() +{ + scoped_lock_t lock(m_mut); + //Mark that upgradable lock has been acquired + //And add upgradable to the sharable count + this->m_ctrl.upgradable_in = 0; + --this->m_ctrl.num_upr_shar; + this->m_first_gate.notify_all(); +} + +//Sharable locking + +inline void interprocess_upgradable_mutex::lock_sharable() +{ + scoped_lock_t lock(m_mut); + + //The sharable lock must block in the first gate + //if an exclusive lock has been acquired + //or there are too many sharable locks + while(this->m_ctrl.exclusive_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + this->m_first_gate.wait(lock); + } + + //Increment sharable count + ++this->m_ctrl.num_upr_shar; +} + +inline bool interprocess_upgradable_mutex::try_lock_sharable() +{ + scoped_lock_t lock(m_mut, try_to_lock); + + //The sharable lock must fail + //if an exclusive lock has been acquired + //or there are too many sharable locks + if(!lock.owns() + || this->m_ctrl.exclusive_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + return false; + } + + //Increment sharable count + ++this->m_ctrl.num_upr_shar; + return true; +} + +inline bool interprocess_upgradable_mutex::timed_lock_sharable + (const boost::posix_time::ptime &abs_time) +{ + scoped_lock_t lock(m_mut, abs_time); + if(!lock.owns()) return false; + + //The sharable lock must block in the first gate + //if an exclusive lock has been acquired + //or there are too many sharable locks + while (this->m_ctrl.exclusive_in + || this->m_ctrl.num_upr_shar == constants::max_readers){ + if(!this->m_first_gate.timed_wait(lock, abs_time)){ + return!(this->m_ctrl.exclusive_in + || this->m_ctrl.num_upr_shar == constants::max_readers); + } + } + + //Increment sharable count + ++this->m_ctrl.num_upr_shar; + return true; +} + +inline void interprocess_upgradable_mutex::unlock_sharable() +{ + scoped_lock_t lock(m_mut); + //Decrement sharable count + --this->m_ctrl.num_upr_shar; + if (this->m_ctrl.num_upr_shar == 0){ + this->m_second_gate.notify_one(); + } + //Check if there are blocked sharables because of + //there were too many sharables + else if(this->m_ctrl.num_upr_shar == (constants::max_readers-1)){ + this->m_first_gate.notify_all(); + } +} + +//Downgrading + +inline void interprocess_upgradable_mutex::unlock_and_lock_upgradable() +{ + scoped_lock_t lock(m_mut); + //Unmark it as exclusive + this->m_ctrl.exclusive_in = 0; + //Mark it as upgradable + this->m_ctrl.upgradable_in = 1; + //The sharable count should be 0 so increment it + this->m_ctrl.num_upr_shar = 1; + //Notify readers that they can enter + m_first_gate.notify_all(); +} + +inline void interprocess_upgradable_mutex::unlock_and_lock_sharable() +{ + scoped_lock_t lock(m_mut); + //Unmark it as exclusive + this->m_ctrl.exclusive_in = 0; + //The sharable count should be 0 so increment it + this->m_ctrl.num_upr_shar = 1; + //Notify readers that they can enter + m_first_gate.notify_all(); +} + +inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock_sharable() +{ + scoped_lock_t lock(m_mut); + //Unmark it as upgradable (we don't have to decrement count) + this->m_ctrl.upgradable_in = 0; + //Notify readers/upgradable that they can enter + m_first_gate.notify_all(); +} + +//Upgrading + +inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock() +{ + scoped_lock_t lock(m_mut); + //Simulate unlock_upgradable() without + //notifying sharables. + this->m_ctrl.upgradable_in = 0; + --this->m_ctrl.num_upr_shar; + //Execute the second half of exclusive locking + this->m_ctrl.exclusive_in = 1; + + //Prepare rollback + upgradable_to_exclusive_rollback rollback(m_ctrl); + + while (this->m_ctrl.num_upr_shar){ + this->m_second_gate.wait(lock); + } + rollback.release(); +} + +inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock() +{ + scoped_lock_t lock(m_mut, try_to_lock); + //Check if there are no readers + if(!lock.owns() + || this->m_ctrl.num_upr_shar != 1){ + return false; + } + //Now unlock upgradable and mark exclusive + this->m_ctrl.upgradable_in = 0; + --this->m_ctrl.num_upr_shar; + this->m_ctrl.exclusive_in = 1; + return true; +} + +inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock + (const boost::posix_time::ptime &abs_time) +{ + scoped_lock_t lock(m_mut, abs_time); + if(!lock.owns()) return false; + + //Simulate unlock_upgradable() without + //notifying sharables. + this->m_ctrl.upgradable_in = 0; + --this->m_ctrl.num_upr_shar; + //Execute the second half of exclusive locking + this->m_ctrl.exclusive_in = 1; + + //Prepare rollback + upgradable_to_exclusive_rollback rollback(m_ctrl); + + while (this->m_ctrl.num_upr_shar){ + if(!this->m_second_gate.timed_wait(lock, abs_time)){ + return !(this->m_ctrl.num_upr_shar); + } + } + rollback.release(); + return true; +} + +inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock() +{ + scoped_lock_t lock(m_mut, try_to_lock); + + //If we can't lock or any has there is any exclusive, upgradable + //or sharable mark return false; + if(!lock.owns() + || this->m_ctrl.exclusive_in + || this->m_ctrl.upgradable_in + || this->m_ctrl.num_upr_shar != 1){ + return false; + } + this->m_ctrl.exclusive_in = 1; + this->m_ctrl.num_upr_shar = 0; + return true; +} + +inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradable() +{ + scoped_lock_t lock(m_mut, try_to_lock); + + //The upgradable lock must fail + //if an exclusive or upgradable lock has been acquired + if(!lock.owns() + || this->m_ctrl.exclusive_in + || this->m_ctrl.upgradable_in){ + return false; + } + + //Mark that upgradable lock has been acquired + this->m_ctrl.upgradable_in = 1; + return true; +} + +} //namespace interprocess { + +} //namespace boost { + + +#include + +#endif //BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/lock_options.hpp b/thirdparty/boost/interprocess/sync/lock_options.hpp new file mode 100644 index 0000000..d1929c8 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/lock_options.hpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_LOCK_OPTIONS_HPP +#define BOOST_INTERPROCESS_LOCK_OPTIONS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +//!\file +//!Describes the lock options with associated with interprocess_mutex lock constructors. + +namespace boost { + +namespace posix_time +{ class ptime; } + +namespace interprocess { + +namespace detail{ + //!Type to indicate to a mutex lock constructor that must not lock the mutex. + struct defer_lock_type{}; + //!Type to indicate to a mutex lock constructor that must try to lock the mutex. + struct try_to_lock_type {}; + //!Type to indicate to a mutex lock constructor that the mutex is already locked. + struct accept_ownership_type{}; +} //namespace detail{ + +//!An object indicating that the locking +//!must be deferred. +static const detail::defer_lock_type defer_lock = detail::defer_lock_type(); + +//!An object indicating that the a try_lock() +//!operation must be executed. +static const detail::try_to_lock_type try_to_lock = detail::try_to_lock_type(); + +//!An object indicating that the ownership of lockable +//!object must be accepted by the new owner. +static const detail::accept_ownership_type accept_ownership = detail::accept_ownership_type(); + +} // namespace interprocess { +} // namespace boost{ + +#include + +#endif // BOOST_INTERPROCESS_LOCK_OPTIONS_HPP diff --git a/thirdparty/boost/interprocess/sync/mutex_family.hpp b/thirdparty/boost/interprocess/sync/mutex_family.hpp new file mode 100644 index 0000000..e2191b8 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/mutex_family.hpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_MUTEX_FAMILY_HPP +#define BOOST_INTERPROCESS_MUTEX_FAMILY_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +//!\file +//!Describes a shared interprocess_mutex family fit algorithm used to allocate objects in shared memory. + +namespace boost { + +namespace interprocess { + +//!Describes interprocess_mutex family to use with Interprocess framework +//!based on boost::interprocess synchronization objects. +struct mutex_family +{ + typedef boost::interprocess::interprocess_mutex mutex_type; + typedef boost::interprocess::interprocess_recursive_mutex recursive_mutex_type; +}; + +//!Describes interprocess_mutex family to use with Interprocess frameworks +//!based on null operation synchronization objects. +struct null_mutex_family +{ + typedef boost::interprocess::null_mutex mutex_type; + typedef boost::interprocess::null_mutex recursive_mutex_type; +}; + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTERPROCESS_MUTEX_FAMILY_HPP + + diff --git a/thirdparty/boost/interprocess/sync/named_condition.hpp b/thirdparty/boost/interprocess/sync/named_condition.hpp new file mode 100644 index 0000000..22bc57a --- /dev/null +++ b/thirdparty/boost/interprocess/sync/named_condition.hpp @@ -0,0 +1,328 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NAMED_CONDITION_HPP +#define BOOST_INTERPROCESS_NAMED_CONDITION_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES +#include +#include +#endif + + +//!\file +//!Describes process-shared variables interprocess_condition class + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +class named_condition +{ + /// @cond + //Non-copyable + named_condition(); + named_condition(const named_condition &); + named_condition &operator=(const named_condition &); + /// @endcond + public: + //!Creates a global condition with a name. + //!If the condition can't be created throws interprocess_exception + named_condition(create_only_t create_only, const char *name); + + //!Opens or creates a global condition with a name. + //!If the condition is created, this call is equivalent to + //!named_condition(create_only_t, ... ) + //!If the condition is already created, this call is equivalent + //!named_condition(open_only_t, ... ) + //!Does not throw + named_condition(open_or_create_t open_or_create, const char *name); + + //!Opens a global condition with a name if that condition is previously + //!created. If it is not previously created this function throws + //!interprocess_exception. + named_condition(open_only_t open_only, const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~named_condition(); + + //!If there is a thread waiting on *this, change that + //!thread's state to ready. Otherwise there is no effect.*/ + void notify_one(); + + //!Change the state of all threads waiting on *this to ready. + //!If there are no waiting threads, notify_all() has no effect. + void notify_all(); + + //!Releases the lock on the interprocess_mutex object associated with lock, blocks + //!the current thread of execution until readied by a call to + //!this->notify_one() or this->notify_all(), and then reacquires the lock. + template + void wait(L& lock); + + //!The same as: + //!while (!pred()) wait(lock) + template + void wait(L& lock, Pr pred); + + //!Releases the lock on the interprocess_mutex object associated with lock, blocks + //!the current thread of execution until readied by a call to + //!this->notify_one() or this->notify_all(), or until time abs_time is reached, + //!and then reacquires the lock. + //!Returns: false if time abs_time is reached, otherwise true. + template + bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time); + + //!The same as: while (!pred()) { + //! if (!timed_wait(lock, abs_time)) return pred(); + //! } return true; + template + bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred); + + //!Erases a named condition from the system. + //!Returns false on error. Never throws. + static bool remove(const char *name); + + /// @cond + private: + + struct condition_holder + { + interprocess_condition cond_; + //If named_mutex is implemented using semaphores + //we need to store an additional mutex + #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + interprocess_mutex mutex_; + #endif + }; + + interprocess_condition *condition() const + { return &static_cast(m_shmem.get_user_address())->cond_; } + + template + class lock_inverter + { + Lock &l_; + public: + lock_inverter(Lock &l) + : l_(l) + {} + void lock() { l_.unlock(); } + void unlock() { l_.lock(); } + }; + + #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + interprocess_mutex *mutex() const + { return &static_cast(m_shmem.get_user_address())->mutex_; } + + template + void do_wait(Lock& lock) + { + lock_inverter inverted_lock(lock); + //unlock internal first to avoid deadlock with near simultaneous waits + scoped_lock > external_unlock(inverted_lock); + scoped_lock internal_lock(*this->mutex()); + this->condition()->wait(internal_lock); + } + + template + bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time) + { + //unlock internal first to avoid deadlock with near simultaneous waits + lock_inverter inverted_lock(lock); + scoped_lock > external_unlock(inverted_lock); + scoped_lock internal_lock(*this->mutex()); + return this->condition()->timed_wait(internal_lock, abs_time); + } + #endif + + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + + detail::managed_open_or_create_impl m_shmem; + + template friend class boost::interprocess::detail::named_creation_functor; + typedef detail::named_creation_functor construct_func_t; + /// @endcond +}; + +inline named_condition::~named_condition() +{} + +inline named_condition::named_condition(create_only_t, const char *name) + : m_shmem (create_only + ,name + ,sizeof(condition_holder) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoCreate)) +{} + +inline named_condition::named_condition(open_or_create_t, const char *name) + : m_shmem (open_or_create + ,name + ,sizeof(condition_holder) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoOpenOrCreate)) +{} + +inline named_condition::named_condition(open_only_t, const char *name) + : m_shmem (open_only + ,name + ,read_write + ,0 + ,construct_func_t(detail::DoOpen)) +{} + +inline void named_condition::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); } + +#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + +inline void named_condition::notify_one() +{ + scoped_lock internal_lock(*this->mutex()); + this->condition()->notify_one(); +} + +inline void named_condition::notify_all() +{ + scoped_lock internal_lock(*this->mutex()); + this->condition()->notify_all(); +} + +template +inline void named_condition::wait(L& lock) +{ + if (!lock) + throw lock_exception(); + this->do_wait(lock); +} + +template +inline void named_condition::wait(L& lock, Pr pred) +{ + if (!lock) + throw lock_exception(); + while (!pred()) + this->do_wait(lock); +} + +template +inline bool named_condition::timed_wait + (L& lock, const boost::posix_time::ptime &abs_time) +{ + if (!lock) + throw lock_exception(); + return this->do_timed_wait(lock, abs_time); +} + +template +inline bool named_condition::timed_wait + (L& lock, const boost::posix_time::ptime &abs_time, Pr pred) +{ + if (!lock) + throw lock_exception(); + + while (!pred()){ + if(!this->do_timed_wait(lock, abs_time)){ + return pred(); + } + } + return true; +} + +#else + +inline void named_condition::notify_one() +{ this->condition()->notify_one(); } + +inline void named_condition::notify_all() +{ this->condition()->notify_all(); } + +template +inline void named_condition::wait(L& lock) +{ + if (!lock) + throw lock_exception(); + this->condition()->do_wait(*lock.mutex()->mutex()); +} + +template +inline void named_condition::wait(L& lock, Pr pred) +{ + if (!lock) + throw lock_exception(); + + while (!pred()) + this->condition()->do_wait(*lock.mutex()->mutex()); +} + +template +inline bool named_condition::timed_wait + (L& lock, const boost::posix_time::ptime &abs_time) +{ + if (!lock) + throw lock_exception(); + return this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex()); +} + +template +inline bool named_condition::timed_wait + (L& lock, const boost::posix_time::ptime &abs_time, Pr pred) +{ + if (!lock) + throw lock_exception(); + + while (!pred()){ + if (!this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex())) + return pred(); + } + + return true; +} + +#endif + +inline bool named_condition::remove(const char *name) +{ return shared_memory_object::remove(name); } + +} //namespace interprocess +} //namespace boost + +#include + +#endif // BOOST_INTERPROCESS_NAMED_CONDITION_HPP diff --git a/thirdparty/boost/interprocess/sync/named_mutex.hpp b/thirdparty/boost/interprocess/sync/named_mutex.hpp new file mode 100644 index 0000000..e033646 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/named_mutex.hpp @@ -0,0 +1,220 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NAMED_MUTEX_HPP +#define BOOST_INTERPROCESS_NAMED_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + #include +#else + #include + #include + #include + #include +#endif + +//!\file +//!Describes a named mutex class for inter-process synchronization + +namespace boost { +namespace interprocess { + +class named_condition; + +//!A mutex with a global name, so it can be found from different +//!processes. This mutex can't be placed in shared memory, and +//!each process should have it's own named_mutex. +class named_mutex +{ + /// @cond + + //Non-copyable + named_mutex(); + named_mutex(const named_mutex &); + named_mutex &operator=(const named_mutex &); + friend class named_condition; + /// @endcond + + public: + //!Creates a global interprocess_mutex with a name. + //!Throws interprocess_exception on error. + named_mutex(create_only_t create_only, const char *name); + + //!Opens or creates a global mutex with a name. + //!If the mutex is created, this call is equivalent to + //!named_mutex(create_only_t, ... ) + //!If the mutex is already created, this call is equivalent + //!named_mutex(open_only_t, ... ) + //!Does not throw + named_mutex(open_or_create_t open_or_create, const char *name); + + //!Opens a global mutex with a name if that mutex is previously + //!created. If it is not previously created this function throws + //!interprocess_exception. + named_mutex(open_only_t open_only, const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~named_mutex(); + + //!Unlocks a previously locked + //!interprocess_mutex. + void unlock(); + + //!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked. + //!Throws interprocess_exception if a severe error is found + void lock(); + + //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex + //!is already locked, returns true when success. + //!Throws interprocess_exception if a severe error is found + bool try_lock(); + + //!Tries to lock the interprocess_mutex until time abs_time, + //!Returns false when timeout expires, returns true when locks. + //!Throws interprocess_exception if a severe error is found + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Erases a named mutex from the system. + //!Returns false on error. Never throws. + static bool remove(const char *name); + + /// @cond + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + + #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + detail::named_semaphore_wrapper m_sem; + #else + interprocess_mutex *mutex() const + { return static_cast(m_shmem.get_user_address()); } + + detail::managed_open_or_create_impl m_shmem; + typedef detail::named_creation_functor construct_func_t; + #endif + /// @endcond +}; + +/// @cond + +#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + +inline named_mutex::named_mutex(create_only_t, const char *name) + : m_sem(detail::DoCreate, name, read_write, 1) +{} + +inline named_mutex::named_mutex(open_or_create_t, const char *name) + : m_sem(detail::DoOpenOrCreate, name, read_write, 1) +{} + +inline named_mutex::named_mutex(open_only_t, const char *name) + : m_sem(detail::DoOpen, name, read_write, 1) +{} + +inline void named_mutex::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_sem); } + +inline named_mutex::~named_mutex() +{} + +inline void named_mutex::lock() +{ m_sem.wait(); } + +inline void named_mutex::unlock() +{ m_sem.post(); } + +inline bool named_mutex::try_lock() +{ return m_sem.try_wait(); } + +inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ return m_sem.timed_wait(abs_time); } + +inline bool named_mutex::remove(const char *name) +{ return detail::named_semaphore_wrapper::remove(name); } + +#else + +inline void named_mutex::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); } + +inline named_mutex::~named_mutex() +{} + +inline named_mutex::named_mutex(create_only_t, const char *name) + : m_shmem (create_only + ,name + ,sizeof(interprocess_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoCreate)) +{} + +inline named_mutex::named_mutex(open_or_create_t, const char *name) + : m_shmem (open_or_create + ,name + ,sizeof(interprocess_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoOpenOrCreate)) +{} + +inline named_mutex::named_mutex(open_only_t, const char *name) + : m_shmem (open_only + ,name + ,read_write + ,0 + ,construct_func_t(detail::DoOpen)) +{} + +inline void named_mutex::lock() +{ this->mutex()->lock(); } + +inline void named_mutex::unlock() +{ this->mutex()->unlock(); } + +inline bool named_mutex::try_lock() +{ return this->mutex()->try_lock(); } + +inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_lock(abs_time); } + +inline bool named_mutex::remove(const char *name) +{ return shared_memory_object::remove(name); } + +#endif + +/// @endcond + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_NAMED_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/named_recursive_mutex.hpp b/thirdparty/boost/interprocess/sync/named_recursive_mutex.hpp new file mode 100644 index 0000000..178e405 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/named_recursive_mutex.hpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NAMED_RECURSIVE_MUTEX_HPP +#define BOOST_INTERPROCESS_NAMED_RECURSIVE_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named named_recursive_mutex class for inter-process synchronization + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +//!A recursive mutex with a global name, so it can be found from different +//!processes. This mutex can't be placed in shared memory, and +//!each process should have it's own named_recursive_mutex. +class named_recursive_mutex +{ + /// @cond + //Non-copyable + named_recursive_mutex(); + named_recursive_mutex(const named_recursive_mutex &); + named_recursive_mutex &operator=(const named_recursive_mutex &); + /// @endcond + public: + + //!Creates a global recursive_mutex with a name. + //!If the recursive_mutex can't be created throws interprocess_exception + named_recursive_mutex(create_only_t create_only, const char *name); + + //!Opens or creates a global recursive_mutex with a name. + //!If the recursive_mutex is created, this call is equivalent to + //!named_recursive_mutex(create_only_t, ... ) + //!If the recursive_mutex is already created, this call is equivalent + //!named_recursive_mutex(open_only_t, ... ) + //!Does not throw + named_recursive_mutex(open_or_create_t open_or_create, const char *name); + + //!Opens a global recursive_mutex with a name if that recursive_mutex is previously + //!created. If it is not previously created this function throws + //!interprocess_exception. + named_recursive_mutex(open_only_t open_only, const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~named_recursive_mutex(); + + //!Unlocks a previously locked + //!named_recursive_mutex. + void unlock(); + + //!Locks named_recursive_mutex, sleeps when named_recursive_mutex is already locked. + //!Throws interprocess_exception if a severe error is found. + void lock(); + + //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex + //!is already locked, returns true when success. + //!Throws interprocess_exception if a severe error is found. + bool try_lock(); + + //!Tries to lock the named_recursive_mutex until time abs_time, + //!Returns false when timeout expires, returns true when locks. + //!Throws interprocess_exception if a severe error is found + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Erases a named recursive mutex + //!from the system + static bool remove(const char *name); + + /// @cond + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + + interprocess_recursive_mutex *mutex() const + { return static_cast(m_shmem.get_user_address()); } + + detail::managed_open_or_create_impl m_shmem; + typedef detail::named_creation_functor construct_func_t; + /// @endcond +}; + +inline named_recursive_mutex::~named_recursive_mutex() +{} + +inline void named_recursive_mutex::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); } + +inline named_recursive_mutex::named_recursive_mutex(create_only_t, const char *name) + : m_shmem (create_only + ,name + ,sizeof(interprocess_recursive_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoCreate)) +{} + +inline named_recursive_mutex::named_recursive_mutex(open_or_create_t, const char *name) + : m_shmem (open_or_create + ,name + ,sizeof(interprocess_recursive_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoOpenOrCreate)) +{} + +inline named_recursive_mutex::named_recursive_mutex(open_only_t, const char *name) + : m_shmem (open_only + ,name + ,read_write + ,0 + ,construct_func_t(detail::DoOpen)) +{} + +inline void named_recursive_mutex::lock() +{ this->mutex()->lock(); } + +inline void named_recursive_mutex::unlock() +{ this->mutex()->unlock(); } + +inline bool named_recursive_mutex::try_lock() +{ return this->mutex()->try_lock(); } + +inline bool named_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_lock(abs_time); } + +inline bool named_recursive_mutex::remove(const char *name) +{ return shared_memory_object::remove(name); } + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_NAMED_RECURSIVE_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/named_semaphore.hpp b/thirdparty/boost/interprocess/sync/named_semaphore.hpp new file mode 100644 index 0000000..977b88e --- /dev/null +++ b/thirdparty/boost/interprocess/sync/named_semaphore.hpp @@ -0,0 +1,228 @@ + ////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP +#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES) +#include +#else +#include +#include +#include +#include +#endif + +//!\file +//!Describes a named semaphore class for inter-process synchronization + +namespace boost { +namespace interprocess { + +//!A semaphore with a global name, so it can be found from different +//!processes. Allows several resource sharing patterns and efficient +//!acknowledgment mechanisms. +class named_semaphore +{ + /// @cond + + //Non-copyable + named_semaphore(); + named_semaphore(const named_semaphore &); + named_semaphore &operator=(const named_semaphore &); + /// @endcond + + public: + //!Creates a global semaphore with a name, and an initial count. + //!If the semaphore can't be created throws interprocess_exception + named_semaphore(create_only_t, const char *name, int initialCount); + + //!Opens or creates a global semaphore with a name, and an initial count. + //!If the semaphore is created, this call is equivalent to + //!named_semaphore(create_only_t, ...) + //!If the semaphore is already created, this call is equivalent to + //!named_semaphore(open_only_t, ... ) + //!and initialCount is ignored. + named_semaphore(open_or_create_t, const char *name, int initialCount); + + //!Opens a global semaphore with a name if that semaphore is previously. + //!created. If it is not previously created this function throws + //!interprocess_exception. + named_semaphore(open_only_t, const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~named_semaphore(); + + //!Increments the semaphore count. If there are processes/threads blocked waiting + //!for the semaphore, then one of these processes will return successfully from + //!its wait function. If there is an error an interprocess_exception exception is thrown. + void post(); + + //!Decrements the semaphore. If the semaphore value is not greater than zero, + //!then the calling process/thread blocks until it can decrement the counter. + //!If there is an error an interprocess_exception exception is thrown. + void wait(); + + //!Decrements the semaphore if the semaphore's value is greater than zero + //!and returns true. If the value is not greater than zero returns false. + //!If there is an error an interprocess_exception exception is thrown. + bool try_wait(); + + //!Decrements the semaphore if the semaphore's value is greater + //!than zero and returns true. Otherwise, waits for the semaphore + //!to the posted or the timeout expires. If the timeout expires, the + //!function returns false. If the semaphore is posted the function + //!returns true. If there is an error throws sem_exception + bool timed_wait(const boost::posix_time::ptime &abs_time); + + //!Erases a named semaphore from the system. + //!Returns false on error. Never throws. + static bool remove(const char *name); + + /// @cond + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + + #if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES) + detail::named_semaphore_wrapper m_sem; + #else + interprocess_semaphore *semaphore() const + { return static_cast(m_shmem.get_user_address()); } + + detail::managed_open_or_create_impl m_shmem; + typedef detail::named_creation_functor construct_func_t; + #endif + /// @endcond +}; + +/// @cond + +#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES) + +inline named_semaphore::named_semaphore + (create_only_t, const char *name, int initialCount) + : m_sem(detail::DoCreate, name, read_write, initialCount) +{} + +inline named_semaphore::named_semaphore + (open_or_create_t, const char *name, int initialCount) + : m_sem(detail::DoOpenOrCreate, name, read_write, initialCount) +{} + +inline named_semaphore::named_semaphore + (open_only_t, const char *name) + : m_sem(detail::DoOpen, name, read_write, 1) +{} + +inline named_semaphore::~named_semaphore() +{} + +inline void named_semaphore::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_sem); } + +inline void named_semaphore::wait() +{ m_sem.wait(); } + +inline void named_semaphore::post() +{ m_sem.post(); } + +inline bool named_semaphore::try_wait() +{ return m_sem.try_wait(); } + +inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) +{ return m_sem.timed_wait(abs_time); } + +inline bool named_semaphore::remove(const char *name) +{ return detail::named_semaphore_wrapper::remove(name); } + +#else + +inline named_semaphore::~named_semaphore() +{} + +inline void named_semaphore::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); } + +inline named_semaphore::named_semaphore + (create_only_t, const char *name, int initialCount) + : m_shmem (create_only + ,name + ,sizeof(interprocess_semaphore) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoCreate, initialCount)) +{} + +inline named_semaphore::named_semaphore + (open_or_create_t, const char *name, int initialCount) + : m_shmem (open_or_create + ,name + ,sizeof(interprocess_semaphore) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoOpenOrCreate, initialCount)) +{} + +inline named_semaphore::named_semaphore + (open_only_t, const char *name) + : m_shmem (open_only + ,name + ,read_write + ,0 + ,construct_func_t(detail::DoOpen, 0)) +{} + +inline void named_semaphore::post() +{ semaphore()->post(); } + +inline void named_semaphore::wait() +{ semaphore()->wait(); } + +inline bool named_semaphore::try_wait() +{ return semaphore()->try_wait(); } + +inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) +{ return semaphore()->timed_wait(abs_time); } + +inline bool named_semaphore::remove(const char *name) +{ return shared_memory_object::remove(name); } + +#endif + +/// @endcond + +} //namespace interprocess { +} //namespace boost { + + +#include + +#endif //BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP diff --git a/thirdparty/boost/interprocess/sync/named_upgradable_mutex.hpp b/thirdparty/boost/interprocess/sync/named_upgradable_mutex.hpp new file mode 100644 index 0000000..9d89d5f --- /dev/null +++ b/thirdparty/boost/interprocess/sync/named_upgradable_mutex.hpp @@ -0,0 +1,348 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_named_upgradable_mutex_HPP +#define BOOST_INTERPROCESS_named_upgradable_mutex_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a named upgradable mutex class for inter-process synchronization + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +class named_condition; + +//!A upgradable mutex with a global name, so it can be found from different +//!processes. This mutex can't be placed in shared memory, and +//!each process should have it's own named upgradable mutex. +class named_upgradable_mutex +{ + /// @cond + //Non-copyable + named_upgradable_mutex(); + named_upgradable_mutex(const named_upgradable_mutex &); + named_upgradable_mutex &operator=(const named_upgradable_mutex &); + friend class named_condition; + /// @endcond + public: + + //!Creates a global upgradable mutex with a name. + //!If the upgradable mutex can't be created throws interprocess_exception + named_upgradable_mutex(create_only_t create_only, const char *name); + + //!Opens or creates a global upgradable mutex with a name, and an initial count. + //!If the upgradable mutex is created, this call is equivalent to + //!named_upgradable_mutex(create_only_t, ...) + //!If the upgradable mutex is already created, this call is equivalent to + //!named_upgradable_mutex(open_only_t, ... ). + named_upgradable_mutex(open_or_create_t open_or_create, const char *name); + + //!Opens a global upgradable mutex with a name if that upgradable mutex + //!is previously. + //!created. If it is not previously created this function throws + //!interprocess_exception. + named_upgradable_mutex(open_only_t open_only, const char *name); + + //!Destroys *this and indicates that the calling process is finished using + //!the resource. The destructor function will deallocate + //!any system resources allocated by the system for use by this process for + //!this resource. The resource can still be opened again calling + //!the open constructor overload. To erase the resource from the system + //!use remove(). + ~named_upgradable_mutex(); + + //Exclusive locking + + //!Effects: The calling thread tries to obtain exclusive ownership of the mutex, + //! and if another thread has exclusive, sharable or upgradable ownership of + //! the mutex, it waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! without waiting. If no other thread has exclusive, sharable or upgradable + //! ownership of the mutex this succeeds. + //!Returns: If it can acquire exclusive ownership immediately returns true. + //! If it has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock(); + + //!Effects: The calling thread tries to acquire exclusive ownership of the mutex + //! waiting if necessary until no other thread has has exclusive, sharable or + //! upgradable ownership of the mutex or abs_time is reached. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The calling thread releases the exclusive ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock(); + + //Sharable locking + + //!Effects: The calling thread tries to obtain sharable ownership of the mutex, + //! and if another thread has exclusive or upgradable ownership of the mutex, + //! waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! without waiting. If no other thread has has exclusive or upgradable ownership + //! of the mutex this succeeds. + //!Returns: If it can acquire sharable ownership immediately returns true. If it + //! has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock_sharable(); + + //!Effects: The calling thread tries to acquire sharable ownership of the mutex + //! waiting if necessary until no other thread has has exclusive or upgradable + //! ownership of the mutex or abs_time is reached. + //!Returns: If acquires sharable ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock_sharable(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The calling thread releases the sharable ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_sharable(); + + //Upgradable locking + + //!Effects: The calling thread tries to obtain upgradable ownership of the mutex, + //! and if another thread has exclusive or upgradable ownership of the mutex, + //! waits until it can obtain the ownership. + //!Throws: interprocess_exception on error. + void lock_upgradable(); + + //!Effects: The calling thread tries to acquire upgradable ownership of the mutex + //! without waiting. If no other thread has has exclusive or upgradable ownership + //! of the mutex this succeeds. + //!Returns: If it can acquire upgradable ownership immediately returns true. + //! If it has to wait, returns false. + //!Throws: interprocess_exception on error. + bool try_lock_upgradable(); + + //!Effects: The calling thread tries to acquire upgradable ownership of the mutex + //! waiting if necessary until no other thread has has exclusive or upgradable + //! ownership of the mutex or abs_time is reached. + //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false. + //!Throws: interprocess_exception on error. + bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The calling thread releases the upgradable ownership of the mutex. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable(); + + //Demotions + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The thread atomically releases exclusive ownership and acquires + //! upgradable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_and_lock_upgradable(); + + //!Precondition: The thread must have exclusive ownership of the mutex. + //!Effects: The thread atomically releases exclusive ownership and acquires + //! sharable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_and_lock_sharable(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and acquires + //! sharable ownership. This operation is non-blocking. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable_and_lock_sharable(); + + //Promotions + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and acquires + //! exclusive ownership. This operation will block until all threads with + //! sharable ownership releas it. + //!Throws: An exception derived from interprocess_exception on error. + void unlock_upgradable_and_lock(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and tries to + //! acquire exclusive ownership. This operation will fail if there are threads + //! with sharable ownership, but it will maintain upgradable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool try_unlock_upgradable_and_lock(); + + //!Precondition: The thread must have upgradable ownership of the mutex. + //!Effects: The thread atomically releases upgradable ownership and tries to acquire + //! exclusive ownership, waiting if necessary until abs_time. This operation will + //! fail if there are threads with sharable ownership or timeout reaches, but it + //! will maintain upgradable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time); + + //!Precondition: The thread must have sharable ownership of the mutex. + //!Effects: The thread atomically releases sharable ownership and tries to acquire + //! exclusive ownership. This operation will fail if there are threads with sharable + //! or upgradable ownership, but it will maintain sharable ownership. + //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. + //!Throws: An exception derived from interprocess_exception on error. + bool try_unlock_sharable_and_lock(); + + bool try_unlock_sharable_and_lock_upgradable(); + + //!Erases a named upgradable mutex from the system. + //!Returns false on error. Never throws. + static bool remove(const char *name); + + /// @cond + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction(); + + interprocess_upgradable_mutex *mutex() const + { return static_cast(m_shmem.get_user_address()); } + + detail::managed_open_or_create_impl m_shmem; + typedef detail::named_creation_functor construct_func_t; + /// @endcond +}; + +inline named_upgradable_mutex::~named_upgradable_mutex() +{} + +inline named_upgradable_mutex::named_upgradable_mutex + (create_only_t, const char *name) + : m_shmem (create_only + ,name + ,sizeof(interprocess_upgradable_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoCreate)) +{} + +inline named_upgradable_mutex::named_upgradable_mutex + (open_or_create_t, const char *name) + : m_shmem (open_or_create + ,name + ,sizeof(interprocess_upgradable_mutex) + + detail::managed_open_or_create_impl:: + ManagedOpenOrCreateUserOffset + ,read_write + ,0 + ,construct_func_t(detail::DoOpenOrCreate)) +{} + +inline named_upgradable_mutex::named_upgradable_mutex + (open_only_t, const char *name) + : m_shmem (open_only + ,name + ,read_write + ,0 + ,construct_func_t(detail::DoOpen)) +{} + +inline void named_upgradable_mutex::dont_close_on_destruction() +{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); } + +inline void named_upgradable_mutex::lock() +{ this->mutex()->lock(); } + +inline void named_upgradable_mutex::unlock() +{ this->mutex()->unlock(); } + +inline bool named_upgradable_mutex::try_lock() +{ return this->mutex()->try_lock(); } + +inline bool named_upgradable_mutex::timed_lock + (const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_lock(abs_time); } + +inline void named_upgradable_mutex::lock_upgradable() +{ this->mutex()->lock_upgradable(); } + +inline void named_upgradable_mutex::unlock_upgradable() +{ this->mutex()->unlock_upgradable(); } + +inline bool named_upgradable_mutex::try_lock_upgradable() +{ return this->mutex()->try_lock_upgradable(); } + +inline bool named_upgradable_mutex::timed_lock_upgradable + (const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_lock_upgradable(abs_time); } + +inline void named_upgradable_mutex::lock_sharable() +{ this->mutex()->lock_sharable(); } + +inline void named_upgradable_mutex::unlock_sharable() +{ this->mutex()->unlock_sharable(); } + +inline bool named_upgradable_mutex::try_lock_sharable() +{ return this->mutex()->try_lock_sharable(); } + +inline bool named_upgradable_mutex::timed_lock_sharable + (const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_lock_sharable(abs_time); } + +inline void named_upgradable_mutex::unlock_and_lock_upgradable() +{ this->mutex()->unlock_and_lock_upgradable(); } + +inline void named_upgradable_mutex::unlock_and_lock_sharable() +{ this->mutex()->unlock_and_lock_sharable(); } + +inline void named_upgradable_mutex::unlock_upgradable_and_lock_sharable() +{ this->mutex()->unlock_upgradable_and_lock_sharable(); } + +inline void named_upgradable_mutex::unlock_upgradable_and_lock() +{ this->mutex()->unlock_upgradable_and_lock(); } + +inline bool named_upgradable_mutex::try_unlock_upgradable_and_lock() +{ return this->mutex()->try_unlock_upgradable_and_lock(); } + +inline bool named_upgradable_mutex::timed_unlock_upgradable_and_lock + (const boost::posix_time::ptime &abs_time) +{ return this->mutex()->timed_unlock_upgradable_and_lock(abs_time); } + +inline bool named_upgradable_mutex::try_unlock_sharable_and_lock() +{ return this->mutex()->try_unlock_sharable_and_lock(); } + +inline bool named_upgradable_mutex::try_unlock_sharable_and_lock_upgradable() +{ return this->mutex()->try_unlock_sharable_and_lock_upgradable(); } + +inline bool named_upgradable_mutex::remove(const char *name) +{ return shared_memory_object::remove(name); } + +} //namespace interprocess { + +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_named_upgradable_mutex_HPP diff --git a/thirdparty/boost/interprocess/sync/null_mutex.hpp b/thirdparty/boost/interprocess/sync/null_mutex.hpp new file mode 100644 index 0000000..508272a --- /dev/null +++ b/thirdparty/boost/interprocess/sync/null_mutex.hpp @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_NULL_MUTEX_HPP +#define BOOST_INTERPROCESS_NULL_MUTEX_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + + +//!\file +//!Describes null_mutex classes + +namespace boost { + +namespace posix_time +{ class ptime; } + +namespace interprocess { + +//!Implements a mutex that simulates a mutex without doing any operation and +//!simulates a successful operation. +class null_mutex +{ + /// @cond + null_mutex(const null_mutex&); + null_mutex &operator= (const null_mutex&); + /// @endcond + public: + + //!Constructor. + //!Empty. + null_mutex(){} + + //!Destructor. + //!Empty. + ~null_mutex(){} + + //!Simulates a mutex lock() operation. Empty function. + void lock(){} + + //!Simulates a mutex try_lock() operation. + //!Equivalent to "return true;" + bool try_lock() + { return true; } + + //!Simulates a mutex timed_lock() operation. + //!Equivalent to "return true;" + bool timed_lock(const boost::posix_time::ptime &) + { return true; } + + //!Simulates a mutex unlock() operation. + //!Empty function. + void unlock(){} + + //!Simulates a mutex lock_sharable() operation. + //!Empty function. + void lock_sharable(){} + + //!Simulates a mutex try_lock_sharable() operation. + //!Equivalent to "return true;" + bool try_lock_sharable() + { return true; } + + //!Simulates a mutex timed_lock_sharable() operation. + //!Equivalent to "return true;" + bool timed_lock_sharable(const boost::posix_time::ptime &) + { return true; } + + //!Simulates a mutex unlock_sharable() operation. + //!Empty function. + void unlock_sharable(){} + + //!Simulates a mutex lock_upgradable() operation. + //!Empty function. + void lock_upgradable(){} + + //!Simulates a mutex try_lock_upgradable() operation. + //!Equivalent to "return true;" + bool try_lock_upgradable() + { return true; } + + //!Simulates a mutex timed_lock_upgradable() operation. + //!Equivalent to "return true;" + bool timed_lock_upgradable(const boost::posix_time::ptime &) + { return true; } + + //!Simulates a mutex unlock_upgradable() operation. + //!Empty function. + void unlock_upgradable(){} + + //!Simulates unlock_and_lock_upgradable(). + //!Empty function. + void unlock_and_lock_upgradable(){} + + //!Simulates unlock_and_lock_sharable(). + //!Empty function. + void unlock_and_lock_sharable(){} + + //!Simulates unlock_upgradable_and_lock_sharable(). + //!Empty function. + void unlock_upgradable_and_lock_sharable(){} + + //Promotions + + //!Simulates unlock_upgradable_and_lock(). + //!Empty function. + void unlock_upgradable_and_lock(){} + + //!Simulates try_unlock_upgradable_and_lock(). + //!Equivalent to "return true;" + bool try_unlock_upgradable_and_lock() + { return true; } + + //!Simulates timed_unlock_upgradable_and_lock(). + //!Equivalent to "return true;" + bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &) + { return true; } + + //!Simulates try_unlock_sharable_and_lock(). + //!Equivalent to "return true;" + bool try_unlock_sharable_and_lock() + { return true; } + + //!Simulates try_unlock_sharable_and_lock_upgradable(). + //!Equivalent to "return true;" + bool try_unlock_sharable_and_lock_upgradable() + { return true; } +}; + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_NULL_MUTEX_HPP diff --git a/thirdparty/boost/interprocess/sync/posix/interprocess_barrier.hpp b/thirdparty/boost/interprocess/sync/posix/interprocess_barrier.hpp new file mode 100644 index 0000000..707f6ea --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/interprocess_barrier.hpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include + +namespace boost { +namespace interprocess { + +inline barrier::barrier(unsigned int count) +{ + if (count == 0) + throw std::invalid_argument("count cannot be zero."); + detail::barrierattr_wrapper barrier_attr; + detail::barrier_initializer barrier + (m_barrier, barrier_attr, static_cast(count)); + barrier.release(); +} + +inline barrier::~barrier() +{ + int res = pthread_barrier_destroy(&m_barrier); + assert(res == 0);(void)res; +} + +inline bool barrier::wait() +{ + int res = pthread_barrier_wait(&m_barrier); + + if (res != PTHREAD_BARRIER_SERIAL_THREAD && res != 0){ + throw interprocess_exception(res); + } + return res == PTHREAD_BARRIER_SERIAL_THREAD; +} + +} //namespace interprocess { +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/posix/interprocess_condition.hpp b/thirdparty/boost/interprocess/sync/posix/interprocess_condition.hpp new file mode 100644 index 0000000..63cc32d --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/interprocess_condition.hpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include + +namespace boost { + +namespace interprocess { + +inline interprocess_condition::interprocess_condition() +{ + int res; + pthread_condattr_t cond_attr; + res = pthread_condattr_init(&cond_attr); + if(res != 0){ + throw interprocess_exception(); + } + res = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); + if(res != 0){ + pthread_condattr_destroy(&cond_attr); + throw interprocess_exception(res); + } + res = pthread_cond_init(&m_condition, &cond_attr); + pthread_condattr_destroy(&cond_attr); + if(res != 0){ + throw interprocess_exception(res); + } +} + +inline interprocess_condition::~interprocess_condition() +{ + int res = 0; + res = pthread_cond_destroy(&m_condition); + assert(res == 0); +} + +inline void interprocess_condition::notify_one() +{ + int res = 0; + res = pthread_cond_signal(&m_condition); + assert(res == 0); +} + +inline void interprocess_condition::notify_all() +{ + int res = 0; + res = pthread_cond_broadcast(&m_condition); + assert(res == 0); +} + +inline void interprocess_condition::do_wait(interprocess_mutex &mut) +{ + pthread_mutex_t* pmutex = &mut.m_mut; + int res = 0; + res = pthread_cond_wait(&m_condition, pmutex); + assert(res == 0); +} + +inline bool interprocess_condition::do_timed_wait + (const boost::posix_time::ptime &abs_time, interprocess_mutex &mut) +{ + timespec ts = detail::ptime_to_timespec(abs_time); + pthread_mutex_t* pmutex = &mut.m_mut; + int res = 0; + res = pthread_cond_timedwait(&m_condition, pmutex, &ts); + assert(res == 0 || res == ETIMEDOUT); + + return res != ETIMEDOUT; +} + +} //namespace interprocess + +} // namespace boost diff --git a/thirdparty/boost/interprocess/sync/posix/interprocess_mutex.hpp b/thirdparty/boost/interprocess/sync/posix/interprocess_mutex.hpp new file mode 100644 index 0000000..63a20ee --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/interprocess_mutex.hpp @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Parts of the pthread code come from Boost Threads code: +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2003 +// William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS +# include +#endif + +namespace boost { +namespace interprocess { + +inline interprocess_mutex::interprocess_mutex() +{ + detail::mutexattr_wrapper mut_attr; + detail::mutex_initializer mut(m_mut, mut_attr); + mut.release(); +} + +inline interprocess_mutex::~interprocess_mutex() +{ + int res = pthread_mutex_destroy(&m_mut); + assert(res == 0);(void)res; +} + +inline void interprocess_mutex::lock() +{ + if (pthread_mutex_lock(&m_mut) != 0) + throw lock_exception(); +} + +inline bool interprocess_mutex::try_lock() +{ + int res = pthread_mutex_trylock(&m_mut); + if (!(res == 0 || res == EBUSY)) + throw lock_exception(); + return res == 0; +} + +inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ + #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS + + timespec ts = detail::ptime_to_timespec(abs_time); + int res = pthread_mutex_timedlock(&m_mut, &ts); + if (res != 0 && res != ETIMEDOUT) + throw lock_exception(); + return res == 0; + + #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS + + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + + if(now >= abs_time) return false; + + do{ + if(this->try_lock()){ + break; + } + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + return false; + } + // relinquish current time slice + detail::thread_yield(); + }while (true); + return true; + + #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS +} + +inline void interprocess_mutex::unlock() +{ + int res = 0; + res = pthread_mutex_unlock(&m_mut); + assert(res == 0); +} + +} //namespace interprocess { +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp b/thirdparty/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp new file mode 100644 index 0000000..7671472 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Parts of the pthread code come from Boost Threads code: +// +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2003 +// William E. Kempf +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. William E. Kempf makes no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS +# include +#endif + +namespace boost { + +namespace interprocess { + +inline interprocess_recursive_mutex::interprocess_recursive_mutex() +{ + detail::mutexattr_wrapper mut_attr(true); + detail::mutex_initializer mut(m_mut, mut_attr); + mut.release(); +} + +inline interprocess_recursive_mutex::~interprocess_recursive_mutex() +{ + int res = pthread_mutex_destroy(&m_mut); + assert(res == 0);(void)res; +} + +inline void interprocess_recursive_mutex::lock() +{ + if (pthread_mutex_lock(&m_mut) != 0) + throw lock_exception(); +} + +inline bool interprocess_recursive_mutex::try_lock() +{ + int res = pthread_mutex_trylock(&m_mut); + if (!(res == 0 || res == EBUSY)) + throw lock_exception(); + return res == 0; +} + +inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) +{ + #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS + + timespec ts = detail::ptime_to_timespec(abs_time); + int res = pthread_mutex_timedlock(&m_mut, &ts); + if (res != 0 && res != ETIMEDOUT) + throw lock_exception(); + return res == 0; + + #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS + + //Obtain current count and target time + boost::posix_time::ptime now = microsec_clock::universal_time(); + + if(now >= abs_time) return false; + + do{ + if(this->try_lock()){ + break; + } + now = microsec_clock::universal_time(); + + if(now >= abs_time){ + return false; + } + // relinquish current time slice + detail::thread_yield(); + }while (true); + return true; + + #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS +} + +inline void interprocess_recursive_mutex::unlock() +{ + int res = 0; + res = pthread_mutex_unlock(&m_mut); + assert(res == 0); +} + +} //namespace interprocess { +} //namespace boost { diff --git a/thirdparty/boost/interprocess/sync/posix/interprocess_semaphore.hpp b/thirdparty/boost/interprocess/sync/posix/interprocess_semaphore.hpp new file mode 100644 index 0000000..ad115e7 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/interprocess_semaphore.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include + +namespace boost { + +namespace interprocess { + +inline interprocess_semaphore::~interprocess_semaphore() +{} + +inline interprocess_semaphore::interprocess_semaphore(int initialCount) + : m_sem(initialCount) +{} + +inline void interprocess_semaphore::post() +{ m_sem.post(); } + +inline void interprocess_semaphore::wait() +{ m_sem.wait(); } + +inline bool interprocess_semaphore::try_wait() +{ return m_sem.try_wait(); } + +inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) +{ return m_sem.timed_wait(abs_time); } +/* +inline int interprocess_semaphore::get_count() const +{ return m_sem.get_count(); } +*/ +} //namespace interprocess { + +} //namespace boost { + diff --git a/thirdparty/boost/interprocess/sync/posix/pthread_helpers.hpp b/thirdparty/boost/interprocess/sync/posix/pthread_helpers.hpp new file mode 100644 index 0000000..920e7e9 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/pthread_helpers.hpp @@ -0,0 +1,168 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP +#define BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +namespace boost { +namespace interprocess { +namespace detail{ + + #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED + + //!Makes pthread_mutexattr_t cleanup easy when using exceptions + struct mutexattr_wrapper + { + //!Constructor + mutexattr_wrapper(bool recursive = false) + { + if(pthread_mutexattr_init(&m_attr)!=0 || + pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 || + (recursive && + pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 )) + throw boost::interprocess::interprocess_exception(); + } + + //!Destructor + ~mutexattr_wrapper() { pthread_mutexattr_destroy(&m_attr); } + + //!This allows using mutexattr_wrapper as pthread_mutexattr_t + operator pthread_mutexattr_t&() { return m_attr; } + + pthread_mutexattr_t m_attr; + }; + + //!Makes pthread_condattr_t cleanup easy when using exceptions + struct condattr_wrapper + { + //!Constructor + condattr_wrapper() + { + if(pthread_condattr_init(&m_attr)!=0 || + pthread_condattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0) + throw boost::interprocess::interprocess_exception(); + } + + //!Destructor + ~condattr_wrapper() { pthread_condattr_destroy(&m_attr); } + + //!This allows using condattr_wrapper as pthread_condattr_t + operator pthread_condattr_t&(){ return m_attr; } + + pthread_condattr_t m_attr; + }; + + //!Makes initialized pthread_mutex_t cleanup easy when using exceptions + class mutex_initializer + { + public: + //!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex + mutex_initializer(pthread_mutex_t &mut, pthread_mutexattr_t &mut_attr) + : mp_mut(&mut) + { + if(pthread_mutex_init(mp_mut, &mut_attr) != 0) + throw boost::interprocess::interprocess_exception(); + } + + ~mutex_initializer() { if(mp_mut) pthread_mutex_destroy(mp_mut); } + + void release() {mp_mut = 0; } + + private: + pthread_mutex_t *mp_mut; + }; + + //!Makes initialized pthread_cond_t cleanup easy when using exceptions + class condition_initializer + { + public: + condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr) + : mp_cond(&cond) + { + if(pthread_cond_init(mp_cond, &cond_attr)!= 0) + throw boost::interprocess::interprocess_exception(); + } + + ~condition_initializer() { if(mp_cond) pthread_cond_destroy(mp_cond); } + + void release() { mp_cond = 0; } + + private: + pthread_cond_t *mp_cond; + }; + + #endif // #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED + + #if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) + + //!Makes pthread_barrierattr_t cleanup easy when using exceptions + struct barrierattr_wrapper + { + //!Constructor + barrierattr_wrapper() + { + if(pthread_barrierattr_init(&m_attr)!=0 || + pthread_barrierattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0) + throw boost::interprocess::interprocess_exception(); + } + + //!Destructor + ~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); } + + //!This allows using mutexattr_wrapper as pthread_barrierattr_t + operator pthread_barrierattr_t&() { return m_attr; } + + pthread_barrierattr_t m_attr; + }; + + //!Makes initialized pthread_barrier_t cleanup easy when using exceptions + class barrier_initializer + { + public: + //!Constructor. Takes barrier attributes to initialize the barrier + barrier_initializer(pthread_barrier_t &mut, + pthread_barrierattr_t &mut_attr, + int count) + : mp_barrier(&mut) + { + if(pthread_barrier_init(mp_barrier, &mut_attr, count) != 0) + throw boost::interprocess::interprocess_exception(); + } + + ~barrier_initializer() { if(mp_barrier) pthread_barrier_destroy(mp_barrier); } + + void release() {mp_barrier = 0; } + + private: + pthread_barrier_t *mp_barrier; + }; + + #endif //#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) + +}//namespace detail + +}//namespace interprocess + +}//namespace boost + +#include + +#endif //ifdef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP diff --git a/thirdparty/boost/interprocess/sync/posix/ptime_to_timespec.hpp b/thirdparty/boost/interprocess/sync/posix/ptime_to_timespec.hpp new file mode 100644 index 0000000..bc6d215 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/ptime_to_timespec.hpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP +#define BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP + +#include + +namespace boost { + +namespace interprocess { + +namespace detail { + +inline timespec ptime_to_timespec (const boost::posix_time::ptime &tm) +{ + const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); + boost::posix_time::time_duration duration (tm - epoch); + timespec ts; + ts.tv_sec = duration.total_seconds(); + ts.tv_nsec = duration.total_nanoseconds() % 1000000000; + return ts; +} + +} //namespace detail { + +} //namespace interprocess { + +} //namespace boost { + +#endif //ifndef BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP diff --git a/thirdparty/boost/interprocess/sync/posix/semaphore_wrapper.hpp b/thirdparty/boost/interprocess/sync/posix/semaphore_wrapper.hpp new file mode 100644 index 0000000..1dcf9a5 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/posix/semaphore_wrapper.hpp @@ -0,0 +1,274 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP +#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef SEM_FAILED +#define BOOST_INTERPROCESS_POSIX_SEM_FAILED SEM_FAILED +#else +#define BOOST_INTERPROCESS_POSIX_SEM_FAILED ((sem_t*)(-1)) +#endif + +#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS +#include +#else +#include +#endif + +namespace boost { +namespace interprocess { + +/// @cond +namespace detail{ class interprocess_tester; } +/// @endcond + +namespace detail { + +inline bool semaphore_open + (sem_t *&handle, detail::create_enum_t type, const char *origname, mode_t mode, + unsigned int count) +{ + std::string name; + #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES + detail::add_leading_slash(origname, name); + #else + detail::create_tmp_dir_and_get_filename(origname, name); + #endif + + //Create new mapping + int oflag = 0; + if(mode == read_only){ + oflag |= O_RDONLY; + } + else if(mode == read_write){ + oflag |= O_RDWR; + } + else{ + error_info err(mode_error); + throw interprocess_exception(err); + } + + switch(type){ + case detail::DoOpen: + //No addition + break; + case detail::DoCreate: + oflag |= (O_CREAT | O_EXCL); + break; + case detail::DoOpenOrCreate: + oflag |= O_CREAT; + break; + default: + { + error_info err = other_error; + throw interprocess_exception(err); + } + } + + //Open file using POSIX API + if(oflag & O_CREAT) + handle = sem_open(name.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU, count); + else + handle = sem_open(name.c_str(), oflag); + + //Check for error + if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){ + throw interprocess_exception(error_info(errno)); + } + + return true; +} + +inline void semaphore_close(sem_t *handle) +{ + int ret = sem_close(handle); + if(ret != 0){ + assert(0); + } +} + +inline bool semaphore_unlink(const char *semname) +{ + try{ + std::string sem_str; + #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES + detail::add_leading_slash(semname, sem_str); + #else + detail::tmp_filename(semname, sem_str); + #endif + return 0 != sem_unlink(sem_str.c_str()); + } + catch(...){ + return false; + } +} + +inline void semaphore_init(sem_t *handle, int initialCount) +{ + int ret = sem_init(handle, 1, initialCount); + //According to SUSV3 version 2003 edition, the return value of a successful + //sem_init call is not defined, but -1 is returned on failure. + //In the future, a successful call might be required to return 0. + if(ret == -1){ + throw interprocess_exception(system_error_code()); + } +} + +inline void semaphore_destroy(sem_t *handle) +{ + int ret = sem_destroy(handle); + if(ret != 0){ + assert(0); + } +} + +inline void semaphore_post(sem_t *handle) +{ + int ret = sem_post(handle); + if(ret != 0){ + throw interprocess_exception(system_error_code()); + } +} + +inline void semaphore_wait(sem_t *handle) +{ + int ret = sem_wait(handle); + if(ret != 0){ + throw interprocess_exception(system_error_code()); + } +} + +inline bool semaphore_try_wait(sem_t *handle) +{ + int res = sem_trywait(handle); + if(res == 0) + return true; + if(system_error_code() == EAGAIN){ + return false; + } + throw interprocess_exception(system_error_code()); + return false; +} + +inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time) +{ + #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS + timespec tspec = detail::ptime_to_timespec(abs_time); + for (;;){ + int res = sem_timedwait(handle, &tspec); + if(res == 0) + return true; + if (res > 0){ + //buggy glibc, copy the returned error code to errno + errno = res; + } + if(system_error_code() == ETIMEDOUT){ + return false; + } + throw interprocess_exception(system_error_code()); + } + return false; + #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS + boost::posix_time::ptime now; + while((now = microsec_clock::universal_time()) < abs_time){ + if(semaphore_try_wait(handle)) + return true; + thread_yield(); + } + return false; + #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS +} + + +class named_semaphore_wrapper +{ + named_semaphore_wrapper(); + named_semaphore_wrapper(const named_semaphore_wrapper&); + named_semaphore_wrapper &operator= (const named_semaphore_wrapper &); + + public: + named_semaphore_wrapper + (detail::create_enum_t type, const char *name, mode_t mode, unsigned int count) + { semaphore_open(mp_sem, type, name, mode, count); } + + ~named_semaphore_wrapper() + { + if(mp_sem != BOOST_INTERPROCESS_POSIX_SEM_FAILED) + semaphore_close(mp_sem); + } + + void post() + { semaphore_post(mp_sem); } + + void wait() + { semaphore_wait(mp_sem); } + + bool try_wait() + { return semaphore_try_wait(mp_sem); } + + bool timed_wait(const boost::posix_time::ptime &abs_time) + { return semaphore_timed_wait(mp_sem, abs_time); } + + static bool remove(const char *name) + { return semaphore_unlink(name); } + + private: + friend class detail::interprocess_tester; + void dont_close_on_destruction() + { mp_sem = BOOST_INTERPROCESS_POSIX_SEM_FAILED; } + + sem_t *mp_sem; +}; + +class semaphore_wrapper +{ + semaphore_wrapper(); + semaphore_wrapper(const semaphore_wrapper&); + semaphore_wrapper &operator= (const semaphore_wrapper &); + + public: + semaphore_wrapper(int initialCount) + { semaphore_init(&m_sem, initialCount); } + + ~semaphore_wrapper() + { semaphore_destroy(&m_sem); } + + void post() + { semaphore_post(&m_sem); } + + void wait() + { semaphore_wait(&m_sem); } + + bool try_wait() + { return semaphore_try_wait(&m_sem); } + + bool timed_wait(const boost::posix_time::ptime &abs_time) + { return semaphore_timed_wait(&m_sem, abs_time); } + + private: + sem_t m_sem; +}; + +} //namespace detail { +} //namespace interprocess { +} //namespace boost { + +#undef BOOST_INTERPROCESS_POSIX_SEM_FAILED + +#endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP diff --git a/thirdparty/boost/interprocess/sync/scoped_lock.hpp b/thirdparty/boost/interprocess/sync/scoped_lock.hpp new file mode 100644 index 0000000..78058e0 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/scoped_lock.hpp @@ -0,0 +1,468 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This interface is inspired by Howard Hinnant's lock proposal. +// http://home.twcny.rr.com/hinnant/cpp_extensions/threads_move.html +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SCOPED_LOCK_HPP +#define BOOST_INTERPROCESS_SCOPED_LOCK_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes the scoped_lock class. + +namespace boost { +namespace interprocess { + +template +class sharable_lock; + +template +class upgradable_lock; + +//!scoped_lock is meant to carry out the tasks for locking, unlocking, try-locking +//!and timed-locking (recursive or not) for the Mutex. The Mutex need not supply all +//!of this functionality. If the client of scoped_lock does not use +//!functionality which the Mutex does not supply, no harm is done. Mutex ownership +//!transfer is supported through the syntax of move semantics. Ownership transfer +//!is allowed both by construction and assignment. The scoped_lock does not support +//!copy semantics. A compile time error results if copy construction or copy +//!assignment is attempted. Mutex ownership can also be moved from an +//!upgradable_lock and sharable_lock via constructor. In this role, scoped_lock +//!shares the same functionality as a write_lock. +template +class scoped_lock +{ + /// @cond + private: + typedef scoped_lock this_type; + scoped_lock(scoped_lock const&); + scoped_lock& operator= (scoped_lock const&); + typedef bool this_type::*unspecified_bool_type; + /// @endcond + public: + typedef Mutex mutex_type; + + //!Effects: Default constructs a scoped_lock. + //!Postconditions: owns() == false and mutex() == 0. + scoped_lock() + : mp_mutex(0), m_locked(false) + {} + + //!Effects: m.lock(). + //!Postconditions: owns() == true and mutex() == &m. + //!Notes: The constructor will take ownership of the mutex. If another thread + //! already owns the mutex, this thread will block until the mutex is released. + //! Whether or not this constructor handles recursive locking depends upon the mutex. + explicit scoped_lock(mutex_type& m) + : mp_mutex(&m), m_locked(false) + { mp_mutex->lock(); m_locked = true; } + + //!Postconditions: owns() == false, and mutex() == &m. + //!Notes: The constructor will not take ownership of the mutex. There is no effect + //! required on the referenced mutex. + scoped_lock(mutex_type& m, detail::defer_lock_type) + : mp_mutex(&m), m_locked(false) + {} + + //!Postconditions: owns() == true, and mutex() == &m. + //!Notes: The constructor will suppose that the mutex is already locked. There + //! is no effect required on the referenced mutex. + scoped_lock(mutex_type& m, detail::accept_ownership_type) + : mp_mutex(&m), m_locked(true) + {} + + //!Effects: m.try_lock(). + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.try_lock() executed within the constructor. + //!Notes: The constructor will take ownership of the mutex if it can do + //! so without waiting. Whether or not this constructor handles recursive + //! locking depends upon the mutex. If the mutex_type does not support try_lock, + //! this constructor will fail at compile time if instantiated, but otherwise + //! have no effect. + scoped_lock(mutex_type& m, detail::try_to_lock_type) + : mp_mutex(&m), m_locked(mp_mutex->try_lock()) + {} + + //!Effects: m.timed_lock(abs_time). + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.timed_lock(abs_time) executed within the constructor. + //!Notes: The constructor will take ownership of the mutex if it can do + //! it until abs_time is reached. Whether or not this constructor + //! handles recursive locking depends upon the mutex. If the mutex_type + //! does not support try_lock, this constructor will fail at compile + //! time if instantiated, but otherwise have no effect. + scoped_lock(mutex_type& m, const boost::posix_time::ptime& abs_time) + : mp_mutex(&m), m_locked(mp_mutex->timed_lock(abs_time)) + {} + + //!Postconditions: mutex() == the value scop.mutex() had before the + //! constructor executes. s1.mutex() == 0. owns() == the value of + //! scop.owns() before the constructor executes. scop.owns(). + //!Notes: If the scop scoped_lock owns the mutex, ownership is moved + //! to thisscoped_lock with no blocking. If the scop scoped_lock does not + //! own the mutex, then neither will this scoped_lock. Only a moved + //! scoped_lock's will match this signature. An non-moved scoped_lock + //! can be moved with the expression: "move(lock);". This + //! constructor does not alter the state of the mutex, only potentially + //! who owns it. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit scoped_lock(detail::moved_object > scop) + : mp_mutex(0), m_locked(scop.get().owns()) + { mp_mutex = scop.get().release(); } + #else + explicit scoped_lock(scoped_lock &&scop) + : mp_mutex(0), m_locked(scop.owns()) + { mp_mutex = scop.release(); } + #endif + + //!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the + //! referenced mutex. upgr.release() is called. + //!Postconditions: mutex() == the value upgr.mutex() had before the construction. + //! upgr.mutex() == 0. owns() == upgr.owns() before the construction. + //! upgr.owns() == false after the construction. + //!Notes: If upgr is locked, this constructor will lock this scoped_lock while + //! unlocking upgr. If upgr is unlocked, then this scoped_lock will be + //! unlocked as well. Only a moved upgradable_lock's will match this + //! signature. An non-moved upgradable_lock can be moved with + //! the expression: "move(lock);" This constructor may block if + //! other threads hold a sharable_lock on this mutex (sharable_lock's can + //! share ownership with an upgradable_lock). + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit scoped_lock(detail::moved_object > upgr) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr.get(); + if(u_lock.owns()){ + u_lock.mutex()->unlock_upgradable_and_lock(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #else + explicit scoped_lock(upgradable_lock &&upgr) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr; + if(u_lock.owns()){ + u_lock.mutex()->unlock_upgradable_and_lock(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #endif + + //!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the + //!referenced mutex: + //! a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains + //! the value from upgr.release() and owns() is set to true. + //! b)if try_unlock_upgradable_and_lock() returns false then upgr is + //! unaffected and this scoped_lock construction as the same effects as + //! a default construction. + //! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release() + //! and owns() is set to false + //!Notes: This construction will not block. It will try to obtain mutex + //! ownership from upgr immediately, while changing the lock type from a + //! "read lock" to a "write lock". If the "read lock" isn't held in the + //! first place, the mutex merely changes type to an unlocked "write lock". + //! If the "read lock" is held, then mutex transfer occurs only if it can + //! do so in a non-blocking manner.*/ + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + scoped_lock(detail::moved_object > upgr + ,detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr.get(); + if(u_lock.owns()){ + if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){ + mp_mutex = u_lock.release(); + } + } + else{ + u_lock.release(); + } + } + #else + scoped_lock(upgradable_lock &&upgr + ,detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr; + if(u_lock.owns()){ + if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){ + mp_mutex = u_lock.release(); + } + } + else{ + u_lock.release(); + } + } + #endif + + //!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time) + //! on the referenced mutex: + //! a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex() + //! obtains the value from upgr.release() and owns() is set to true. + //! b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr + //! is unaffected and this scoped_lock construction as the same effects + //! as a default construction. + //! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release() + //! and owns() is set to false + //!Notes: This construction will not block. It will try to obtain mutex ownership + //! from upgr immediately, while changing the lock type from a "read lock" to a + //! "write lock". If the "read lock" isn't held in the first place, the mutex + //! merely changes type to an unlocked "write lock". If the "read lock" is held, + //! then mutex transfer occurs only if it can do so in a non-blocking manner. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + scoped_lock(detail::moved_object > upgr + ,boost::posix_time::ptime &abs_time) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr.get(); + if(u_lock.owns()){ + if((m_locked = u_lock.mutex()->timed_unlock_upgradable_and_lock(abs_time)) == true){ + mp_mutex = u_lock.release(); + } + } + else{ + u_lock.release(); + } + } + #else + scoped_lock(upgradable_lock &&upgr + ,boost::posix_time::ptime &abs_time) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr; + if(u_lock.owns()){ + if((m_locked = u_lock.mutex()->timed_unlock_upgradable_and_lock(abs_time)) == true){ + mp_mutex = u_lock.release(); + } + } + else{ + u_lock.release(); + } + } + #endif + + //!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the + //!referenced mutex. + //! a)if try_unlock_sharable_and_lock() returns true then mutex() obtains + //! the value from shar.release() and owns() is set to true. + //! b)if try_unlock_sharable_and_lock() returns false then shar is + //! unaffected and this scoped_lock construction has the same + //! effects as a default construction. + //! c)Else shar.owns() is false. mutex() obtains the value from + //! shar.release() and owns() is set to false + //!Notes: This construction will not block. It will try to obtain mutex + //! ownership from shar immediately, while changing the lock type from a + //! "read lock" to a "write lock". If the "read lock" isn't held in the + //! first place, the mutex merely changes type to an unlocked "write lock". + //! If the "read lock" is held, then mutex transfer occurs only if it can + //! do so in a non-blocking manner. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + scoped_lock(detail::moved_object > shar + ,detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + sharable_lock &s_lock = shar.get(); + if(s_lock.owns()){ + if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock()) == true){ + mp_mutex = s_lock.release(); + } + } + else{ + s_lock.release(); + } + } + #else + scoped_lock(sharable_lock &&shar + ,detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + sharable_lock &s_lock = shar; + if(s_lock.owns()){ + if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock()) == true){ + mp_mutex = s_lock.release(); + } + } + else{ + s_lock.release(); + } + } + #endif + + //!Effects: if (owns()) mp_mutex->unlock(). + //!Notes: The destructor behavior ensures that the mutex lock is not leaked.*/ + ~scoped_lock() + { + try{ if(m_locked && mp_mutex) mp_mutex->unlock(); } + catch(...){} + } + + //!Effects: If owns() before the call, then unlock() is called on mutex(). + //! *this gets the state of scop and scop gets set to a default constructed state. + //!Notes: With a recursive mutex it is possible that both this and scop own + //! the same mutex before the assignment. In this case, this will own the + //! mutex after the assignment (and scop will not), but the mutex's lock + //! count will be decremented by one. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + scoped_lock &operator=(detail::moved_object > scop) + { + if(this->owns()) + this->unlock(); + m_locked = scop.get().owns(); + mp_mutex = scop.get().release(); + return *this; + } + #else + scoped_lock &operator=(scoped_lock &&scop) + { + if(this->owns()) + this->unlock(); + m_locked = scop.owns(); + mp_mutex = scop.release(); + return *this; + } + #endif + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls lock() on the referenced mutex. + //!Postconditions: owns() == true. + //!Notes: The scoped_lock changes from a state of not owning the mutex, to + //! owning the mutex, blocking if necessary. + void lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + mp_mutex->lock(); + m_locked = true; + } + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls try_lock() on the referenced mutex. + //!Postconditions: owns() == the value returned from mutex()->try_lock(). + //!Notes: The scoped_lock changes from a state of not owning the mutex, to + //! owning the mutex, but only if blocking was not required. If the + //! mutex_type does not support try_lock(), this function will fail at + //! compile time if instantiated, but otherwise have no effect.*/ + bool try_lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->try_lock(); + return m_locked; + } + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls timed_lock(abs_time) on the referenced mutex. + //!Postconditions: owns() == the value returned from mutex()-> timed_lock(abs_time). + //!Notes: The scoped_lock changes from a state of not owning the mutex, to + //! owning the mutex, but only if it can obtain ownership by the specified + //! time. If the mutex_type does not support timed_lock (), this function + //! will fail at compile time if instantiated, but otherwise have no effect.*/ + bool timed_lock(const boost::posix_time::ptime& abs_time) + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->timed_lock(abs_time); + return m_locked; + } + + //!Effects: If mutex() == 0 or if not locked, throws a lock_exception() + //! exception. Calls unlock() on the referenced mutex. + //!Postconditions: owns() == false. + //!Notes: The scoped_lock changes from a state of owning the mutex, to not + //! owning the mutex.*/ + void unlock() + { + if(!mp_mutex || !m_locked) + throw lock_exception(); + mp_mutex->unlock(); + m_locked = false; + } + + //!Effects: Returns true if this scoped_lock has acquired + //!the referenced mutex. + bool owns() const + { return m_locked && mp_mutex; } + + //!Conversion to bool. + //!Returns owns(). + operator unspecified_bool_type() const + { return m_locked? &this_type::m_locked : 0; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if + //!there is no mutex to reference. + mutex_type* mutex() const + { return mp_mutex; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no + //! mutex to reference. + //!Postconditions: mutex() == 0 and owns() == false. + mutex_type* release() + { + mutex_type *mut = mp_mutex; + mp_mutex = 0; + m_locked = false; + return mut; + } + + //!Effects: Swaps state with moved lock. + //!Throws: Nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(detail::moved_object > other) + { + std::swap(mp_mutex, other.get().mp_mutex); + std::swap(m_locked, other.get().m_locked); + } + #else + void swap(scoped_lock &&other) + { + std::swap(mp_mutex, other.mp_mutex); + std::swap(m_locked, other.m_locked); + } + #endif + + /// @cond + private: + mutex_type *mp_mutex; + bool m_locked; + /// @endcond +}; + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; +/// @endcond + +} // namespace interprocess +} // namespace boost + +#include + +#endif // BOOST_INTERPROCESS_SCOPED_LOCK_HPP diff --git a/thirdparty/boost/interprocess/sync/sharable_lock.hpp b/thirdparty/boost/interprocess/sync/sharable_lock.hpp new file mode 100644 index 0000000..ced8e63 --- /dev/null +++ b/thirdparty/boost/interprocess/sync/sharable_lock.hpp @@ -0,0 +1,367 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This interface is inspired by Howard Hinnant's lock proposal. +// http://home.twcny.rr.com/hinnant/cpp_extensions/threads_move.html +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_SHARABLE_LOCK_HPP +#define BOOST_INTERPROCESS_SHARABLE_LOCK_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +//Ig#include +#include + +//!\file +//!Describes the upgradable_lock class that serves to acquire the upgradable +//!lock of a mutex. + +namespace boost { +namespace interprocess { + +template +class scoped_lock; + +template +class upgradable_lock; + +//!sharable_lock is meant to carry out the tasks for sharable-locking +//!(such as read-locking), unlocking, try-sharable-locking and timed-sharable-locking +//!(recursive or not) for the Mutex. The Mutex need not supply all of this +//!functionality. If the client of sharable_lock does not use functionality which +//!the Mutex does not supply, no harm is done. Mutex ownership can be shared among +//!sharable_locks, and a single upgradable_lock. sharable_lock does not support +//!copy semantics. But sharable_lock supports ownership transfer from an sharable_lock, +//!upgradable_lock and scoped_lock via trasfer_lock syntax.*/ +template +class sharable_lock +{ + public: + typedef SharableMutex mutex_type; + /// @cond + private: + typedef sharable_lock this_type; + sharable_lock(sharable_lock const&); + explicit sharable_lock(scoped_lock const&); + typedef bool this_type::*unspecified_bool_type; + sharable_lock& operator=(sharable_lock const&); + sharable_lock& operator=(scoped_lock const&); + /// @endcond + public: + + //!Effects: Default constructs a sharable_lock. + //!Postconditions: owns() == false and mutex() == 0. + sharable_lock() + : mp_mutex(0), m_locked(false) + {} + + //!Effects: m.lock_sharable(). + //!Postconditions: owns() == true and mutex() == &m. + //!Notes: The constructor will take sharable-ownership of the mutex. If + //! another thread already owns the mutex with exclusive ownership + //! (scoped_lock), this thread will block until the mutex is released. + //! If another thread owns the mutex with sharable or upgradable ownership, + //! then no blocking will occur. Whether or not this constructor handles + //! recursive locking depends upon the mutex. + explicit sharable_lock(mutex_type& m) + : mp_mutex(&m), m_locked(false) + { mp_mutex->lock_sharable(); m_locked = true; } + + //!Postconditions: owns() == false, and mutex() == &m. + //!Notes: The constructor will not take ownership of the mutex. There is no effect + //! required on the referenced mutex. + sharable_lock(mutex_type& m, detail::defer_lock_type) + : mp_mutex(&m), m_locked(false) + {} + + //!Postconditions: owns() == true, and mutex() == &m. + //!Notes: The constructor will suppose that the mutex is already sharable + //! locked. There is no effect required on the referenced mutex. + sharable_lock(mutex_type& m, detail::accept_ownership_type) + : mp_mutex(&m), m_locked(true) + {} + + //!Effects: m.try_lock_sharable() + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.try_lock_sharable() executed within the constructor. + //!Notes: The constructor will take sharable-ownership of the mutex if it + //! can do so without waiting. Whether or not this constructor handles + //! recursive locking depends upon the mutex. If the mutex_type does not + //! support try_lock_sharable, this constructor will fail at compile + //! time if instantiated, but otherwise have no effect. + sharable_lock(mutex_type& m, detail::try_to_lock_type) + : mp_mutex(&m), m_locked(false) + { m_locked = mp_mutex->try_lock_sharable(); } + + //!Effects: m.timed_lock_sharable(abs_time) + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.timed_lock_sharable() executed within the constructor. + //!Notes: The constructor will take sharable-ownership of the mutex if it + //! can do so within the time specified. Whether or not this constructor + //! handles recursive locking depends upon the mutex. If the mutex_type + //! does not support timed_lock_sharable, this constructor will fail at + //! compile time if instantiated, but otherwise have no effect. + sharable_lock(mutex_type& m, const boost::posix_time::ptime& abs_time) + : mp_mutex(&m), m_locked(false) + { m_locked = mp_mutex->timed_lock_sharable(abs_time); } + + //!Postconditions: mutex() == upgr.mutex(). owns() == the value of upgr.owns() + //! before the construction. upgr.owns() == false after the construction. + //!Notes: If the upgr sharable_lock owns the mutex, ownership is moved to this + //! sharable_lock with no blocking. If the upgr sharable_lock does not own the mutex, then + //! neither will this sharable_lock. Only a moved sharable_lock's will match this + //! signature. An non-moved sharable_lock can be moved with the expression: + //! "move(lock);". This constructor does not alter the state of the mutex, + //! only potentially who owns it. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit sharable_lock(detail::moved_object > upgr) + : mp_mutex(0), m_locked(upgr.get().owns()) + { mp_mutex = upgr.get().release(); } + #else + explicit sharable_lock(sharable_lock &&upgr) + : mp_mutex(0), m_locked(upgr.owns()) + { mp_mutex = upgr.release(); } + #endif + + //!Effects: If upgr.owns() then calls unlock_upgradable_and_lock_sharable() on the + //! referenced mutex. + //!Postconditions: mutex() == the value upgr.mutex() had before the construction. + //! upgr.mutex() == 0 owns() == the value of upgr.owns() before construction. + //! upgr.owns() == false after the construction. + //!Notes: If upgr is locked, this constructor will lock this sharable_lock while + //! unlocking upgr. Only a moved sharable_lock's will match this + //! signature. An non-moved upgradable_lock can be moved with the expression: + //! "move(lock);".*/ + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit sharable_lock(detail::moved_object > upgr) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr.get(); + if(u_lock.owns()){ + u_lock.mutex()->unlock_upgradable_and_lock_sharable(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #else + explicit sharable_lock(upgradable_lock &&upgr) + : mp_mutex(0), m_locked(false) + { + upgradable_lock &u_lock = upgr; + if(u_lock.owns()){ + u_lock.mutex()->unlock_upgradable_and_lock_sharable(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #endif + + //!Effects: If scop.owns() then calls unlock_and_lock_sharable() on the + //! referenced mutex. + //!Postconditions: mutex() == the value scop.mutex() had before the construction. + //! scop.mutex() == 0 owns() == scop.owns() before the constructor. After the + //! construction, scop.owns() == false. + //!Notes: If scop is locked, this constructor will transfer the exclusive ownership + //! to a sharable-ownership of this sharable_lock. + //! Only a moved scoped_lock's will match this + //! signature. An non-moved scoped_lock can be moved with the expression: + //! "move(lock);".*/ + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit sharable_lock(detail::moved_object > scop) + : mp_mutex(0), m_locked(false) + { + scoped_lock &e_lock = scop.get(); + if(e_lock.owns()){ + e_lock.mutex()->unlock_and_lock_sharable(); + m_locked = true; + } + mp_mutex = e_lock.release(); + } + #else + explicit sharable_lock(scoped_lock &&scop) + : mp_mutex(0), m_locked(false) + { + scoped_lock &e_lock = scop; + if(e_lock.owns()){ + e_lock.mutex()->unlock_and_lock_sharable(); + m_locked = true; + } + mp_mutex = e_lock.release(); + } + #endif + + //!Effects: if (owns()) mp_mutex->unlock_sharable(). + //!Notes: The destructor behavior ensures that the mutex lock is not leaked. + ~sharable_lock() + { + try{ + if(m_locked && mp_mutex) mp_mutex->unlock_sharable(); + } + catch(...){} + } + + //!Effects: If owns() before the call, then unlock_sharable() is called on mutex(). + //! *this gets the state of upgr and upgr gets set to a default constructed state. + //!Notes: With a recursive mutex it is possible that both this and upgr own the mutex + //! before the assignment. In this case, this will own the mutex after the assignment + //! (and upgr will not), but the mutex's lock count will be decremented by one. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + sharable_lock &operator=(detail::moved_object > upgr) + { + if(this->owns()) + this->unlock(); + m_locked = upgr.get().owns(); + mp_mutex = upgr.get().release(); + return *this; + } + #else + sharable_lock &operator=(sharable_lock &&upgr) + { + if(this->owns()) + this->unlock(); + m_locked = upgr.owns(); + mp_mutex = upgr.release(); + return *this; + } + #endif + + //!Effects: If mutex() == 0 or already locked, throws a lock_exception() + //! exception. Calls lock_sharable() on the referenced mutex. + //!Postconditions: owns() == true. + //!Notes: The sharable_lock changes from a state of not owning the + //! mutex, to owning the mutex, blocking if necessary. + void lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + mp_mutex->lock_sharable(); + m_locked = true; + } + + //!Effects: If mutex() == 0 or already locked, throws a lock_exception() + //! exception. Calls try_lock_sharable() on the referenced mutex. + //!Postconditions: owns() == the value returned from + //! mutex()->try_lock_sharable(). + //!Notes: The sharable_lock changes from a state of not owning the mutex, + //! to owning the mutex, but only if blocking was not required. If the + //! mutex_type does not support try_lock_sharable(), this function will + //! fail at compile time if instantiated, but otherwise have no effect. + bool try_lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->try_lock_sharable(); + return m_locked; + } + + //!Effects: If mutex() == 0 or already locked, throws a lock_exception() + //! exception. Calls timed_lock_sharable(abs_time) on the referenced mutex. + //!Postconditions: owns() == the value returned from + //! mutex()->timed_lock_sharable(elps_time). + //!Notes: The sharable_lock changes from a state of not owning the mutex, + //! to owning the mutex, but only if it can obtain ownership within the + //! specified time interval. If the mutex_type does not support + //! timed_lock_sharable(), this function will fail at compile time if + //! instantiated, but otherwise have no effect. + bool timed_lock(const boost::posix_time::ptime& abs_time) + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->timed_lock_sharable(abs_time); + return m_locked; + } + + //!Effects: If mutex() == 0 or not locked, throws a lock_exception() exception. + //! Calls unlock_sharable() on the referenced mutex. + //!Postconditions: owns() == false. + //!Notes: The sharable_lock changes from a state of owning the mutex, to + //! not owning the mutex. + void unlock() + { + if(!mp_mutex || !m_locked) + throw lock_exception(); + mp_mutex->unlock_sharable(); + m_locked = false; + } + + //!Effects: Returns true if this scoped_lock has + //!acquired the referenced mutex. + bool owns() const + { return m_locked && mp_mutex; } + + //!Conversion to bool. + //!Returns owns(). + operator unspecified_bool_type() const + { return m_locked? &this_type::m_locked : 0; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if + //!there is no mutex to reference. + mutex_type* mutex() const + { return mp_mutex; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no + //! mutex to reference. + //!Postconditions: mutex() == 0 and owns() == false. + mutex_type* release() + { + mutex_type *mut = mp_mutex; + mp_mutex = 0; + m_locked = false; + return mut; + } + + //!Effects: Swaps state with moved lock. + //!Throws: Nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(detail::moved_object > other) + { + std::swap(mp_mutex, other.get().mp_mutex); + std::swap(m_locked, other.get().m_locked); + } + #else + void swap(sharable_lock &&other) + { + std::swap(mp_mutex, other.mp_mutex); + std::swap(m_locked, other.m_locked); + } + #endif + + /// @cond + private: + mutex_type *mp_mutex; + bool m_locked; + /// @endcond +}; + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; +/// @endcond + +} // namespace interprocess +} // namespace boost + +#include + +#endif // BOOST_INTERPROCESS_SHARABLE_LOCK_HPP diff --git a/thirdparty/boost/interprocess/sync/upgradable_lock.hpp b/thirdparty/boost/interprocess/sync/upgradable_lock.hpp new file mode 100644 index 0000000..de9bb1a --- /dev/null +++ b/thirdparty/boost/interprocess/sync/upgradable_lock.hpp @@ -0,0 +1,375 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This interface is inspired by Howard Hinnant's lock proposal. +// http://home.twcny.rr.com/hinnant/cpp_extensions/threads_move.html +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_UPGRADABLE_LOCK_HPP +#define BOOST_INTERPROCESS_UPGRADABLE_LOCK_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes the upgradable_lock class that serves to acquire the upgradable +//!lock of a mutex. + +namespace boost { +namespace interprocess { + +template +class scoped_lock; + +template +class sharable_lock; + +//!upgradable_lock is meant to carry out the tasks for read-locking, unlocking, +//!try-read-locking and timed-read-locking (recursive or not) for the Mutex. +//!Additionally the upgradable_lock can transfer ownership to a scoped_lock +//!using trasfer_lock syntax. The Mutex need not supply all of the functionality. +//!If the client of upgradable_lock does not use functionality which the +//!Mutex does not supply, no harm is done. Mutex ownership can be shared among +//!read_locks, and a single upgradable_lock. upgradable_lock does not support +//!copy semantics. However upgradable_lock supports ownership transfer from +//!a upgradable_locks or scoped_locks via trasfer_lock syntax. +template +class upgradable_lock +{ + public: + typedef UpgradableMutex mutex_type; + /// @cond + private: + typedef upgradable_lock this_type; + upgradable_lock(upgradable_lock const&); + explicit upgradable_lock(scoped_lock const&); + typedef bool this_type::*unspecified_bool_type; + upgradable_lock& operator=(upgradable_lock const&); + upgradable_lock& operator=(scoped_lock const&); + /// @endcond + public: + + //!Effects: Default constructs a upgradable_lock. + //!Postconditions: owns() == false and mutex() == 0. + upgradable_lock() + : mp_mutex(0), m_locked(false) + {} + + explicit upgradable_lock(mutex_type& m) + : mp_mutex(&m), m_locked(false) + { mp_mutex->lock_upgradable(); m_locked = true; } + + //!Postconditions: owns() == false, and mutex() == &m. + //!Notes: The constructor will not take ownership of the mutex. There is no effect + //! required on the referenced mutex. + upgradable_lock(mutex_type& m, detail::defer_lock_type) + : mp_mutex(&m), m_locked(false) + {} + + //!Postconditions: owns() == true, and mutex() == &m. + //!Notes: The constructor will suppose that the mutex is already upgradable + //! locked. There is no effect required on the referenced mutex. + upgradable_lock(mutex_type& m, detail::accept_ownership_type) + : mp_mutex(&m), m_locked(true) + {} + + //!Effects: m.try_lock_upgradable(). + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.try_lock_upgradable() executed within the constructor. + //!Notes: The constructor will take upgradable-ownership of the mutex + //! if it can do so without waiting. Whether or not this constructor + //! handles recursive locking depends upon the mutex. If the mutex_type + //! does not support try_lock_upgradable, this constructor will fail at + //! compile time if instantiated, but otherwise have no effect. + upgradable_lock(mutex_type& m, detail::try_to_lock_type) + : mp_mutex(&m), m_locked(false) + { m_locked = mp_mutex->try_lock_upgradable(); } + + //!Effects: m.timed_lock_upgradable(abs_time) + //!Postconditions: mutex() == &m. owns() == the return value of the + //! m.timed_lock_upgradable() executed within the constructor. + //!Notes: The constructor will take upgradable-ownership of the mutex if it + //! can do so within the time specified. Whether or not this constructor + //! handles recursive locking depends upon the mutex. If the mutex_type + //! does not support timed_lock_upgradable, this constructor will fail + //! at compile time if instantiated, but otherwise have no effect. + upgradable_lock(mutex_type& m, const boost::posix_time::ptime& abs_time) + : mp_mutex(&m), m_locked(false) + { m_locked = mp_mutex->timed_lock_upgradable(abs_time); } + + //!Effects: No effects on the underlying mutex. + //!Postconditions: mutex() == the value upgr.mutex() had before the + //! construction. upgr.mutex() == 0. owns() == upgr.owns() before the + //! construction. upgr.owns() == false. + //!Notes: If upgr is locked, this constructor will lock this upgradable_lock + //! while unlocking upgr. If upgr is unlocked, then this upgradable_lock will + //! be unlocked as well. Only a moved upgradable_lock's will match this + //! signature. An non-moved upgradable_lock can be moved with the + //! expression: "move(lock);". This constructor does not alter the + //! state of the mutex, only potentially who owns it. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit upgradable_lock(detail::moved_object > upgr) + : mp_mutex(0), m_locked(upgr.get().owns()) + { mp_mutex = upgr.get().release(); } + #else + explicit upgradable_lock(upgradable_lock &&upgr) + : mp_mutex(0), m_locked(upgr.owns()) + { mp_mutex = upgr.release(); } + #endif + + //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable(). + //!Postconditions: mutex() == the value scop.mutex() had before the construction. + //! scop.mutex() == 0. owns() == scop.owns() before the constructor. After the + //! construction, scop.owns() == false. + //!Notes: If scop is locked, this constructor will transfer the exclusive-ownership + //! to an upgradable-ownership of this upgradable_lock. + //! Only a moved sharable_lock's will match this + //! signature. An non-moved sharable_lock can be moved with the + //! expression: "move(lock);". + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + explicit upgradable_lock(detail::moved_object > scop) + : mp_mutex(0), m_locked(false) + { + scoped_lock &u_lock = scop.get(); + if(u_lock.owns()){ + u_lock.mutex()->unlock_and_lock_upgradable(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #else + explicit upgradable_lock(scoped_lock &&scop) + : mp_mutex(0), m_locked(false) + { + scoped_lock &u_lock = scop; + if(u_lock.owns()){ + u_lock.mutex()->unlock_and_lock_upgradable(); + m_locked = true; + } + mp_mutex = u_lock.release(); + } + #endif + + //!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable() + //! on the referenced mutex. + //! a)if try_unlock_sharable_and_lock_upgradable() returns true then mutex() + //! obtains the value from shar.release() and owns() is set to true. + //! b)if try_unlock_sharable_and_lock_upgradable() returns false then shar is + //! unaffected and this upgradable_lock construction has the same + //! effects as a default construction. + //! c)Else shar.owns() is false. mutex() obtains the value from shar.release() + //! and owns() is set to false. + //!Notes: This construction will not block. It will try to obtain mutex + //! ownership from shar immediately, while changing the lock type from a + //! "read lock" to an "upgradable lock". If the "read lock" isn't held + //! in the first place, the mutex merely changes type to an unlocked + //! "upgradable lock". If the "read lock" is held, then mutex transfer + //! occurs only if it can do so in a non-blocking manner. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + upgradable_lock( detail::moved_object > shar + , detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + sharable_lock &s_lock = shar.get(); + if(s_lock.owns()){ + if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock_upgradable()) == true){ + mp_mutex = s_lock.release(); + } + } + else{ + s_lock.release(); + } + } + #else + upgradable_lock( sharable_lock &&shar + , detail::try_to_lock_type) + : mp_mutex(0), m_locked(false) + { + sharable_lock &s_lock = shar; + if(s_lock.owns()){ + if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock_upgradable()) == true){ + mp_mutex = s_lock.release(); + } + } + else{ + s_lock.release(); + } + } + #endif + + //!Effects: if (owns()) m_->unlock_upgradable(). + //!Notes: The destructor behavior ensures that the mutex lock is not leaked. + ~upgradable_lock() + { + try{ + if(m_locked && mp_mutex) mp_mutex->unlock_upgradable(); + } + catch(...){} + } + + //!Effects: If owns(), then unlock_upgradable() is called on mutex(). + //! *this gets the state of upgr and upgr gets set to a default constructed state. + //!Notes: With a recursive mutex it is possible that both this and upgr own the + //! mutex before the assignment. In this case, this will own the mutex + //! after the assignment (and upgr will not), but the mutex's upgradable lock + //! count will be decremented by one. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + upgradable_lock &operator=(detail::moved_object > upgr) + { + if(this->owns()) + this->unlock(); + m_locked = upgr.get().owns(); + mp_mutex = upgr.get().release(); + return *this; + } + #else + upgradable_lock &operator=(upgradable_lock &&upgr) + { + if(this->owns()) + this->unlock(); + m_locked = upgr.owns(); + mp_mutex = upgr.release(); + return *this; + } + #endif + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls lock_upgradable() on the referenced mutex. + //!Postconditions: owns() == true. + //!Notes: The sharable_lock changes from a state of not owning the mutex, + //! to owning the mutex, blocking if necessary. + void lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + mp_mutex->lock_upgradable(); + m_locked = true; + } + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls try_lock_upgradable() on the referenced mutex. + //!Postconditions: owns() == the value returned from + //! mutex()->try_lock_upgradable(). + //!Notes: The upgradable_lock changes from a state of not owning the mutex, + //! to owning the mutex, but only if blocking was not required. If the + //! mutex_type does not support try_lock_upgradable(), this function will + //! fail at compile time if instantiated, but otherwise have no effect. + bool try_lock() + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->try_lock_upgradable(); + return m_locked; + } + + //!Effects: If mutex() == 0 or if already locked, throws a lock_exception() + //! exception. Calls timed_lock_upgradable(abs_time) on the referenced mutex. + //!Postconditions: owns() == the value returned from + //! mutex()->timed_lock_upgradable(abs_time). + //!Notes: The upgradable_lock changes from a state of not owning the mutex, + //! to owning the mutex, but only if it can obtain ownership within the + //! specified time. If the mutex_type does not support + //! timed_lock_upgradable(abs_time), this function will fail at compile + //! time if instantiated, but otherwise have no effect. + bool timed_lock(const boost::posix_time::ptime& abs_time) + { + if(!mp_mutex || m_locked) + throw lock_exception(); + m_locked = mp_mutex->timed_lock_upgradable(abs_time); + return m_locked; + } + + //!Effects: If mutex() == 0 or if not locked, throws a lock_exception() + //! exception. Calls unlock_upgradable() on the referenced mutex. + //!Postconditions: owns() == false. + //!Notes: The upgradable_lock changes from a state of owning the mutex, + //! to not owning the mutex. + void unlock() + { + if(!mp_mutex || !m_locked) + throw lock_exception(); + mp_mutex->unlock_upgradable(); + m_locked = false; + } + + //!Effects: Returns true if this scoped_lock has acquired the + //!referenced mutex. + bool owns() const + { return m_locked && mp_mutex; } + + //!Conversion to bool. + //!Returns owns(). + operator unspecified_bool_type() const + { return m_locked? &this_type::m_locked : 0; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if + //!there is no mutex to reference. + mutex_type* mutex() const + { return mp_mutex; } + + //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no + //! mutex to reference. + //!Postconditions: mutex() == 0 and owns() == false. + mutex_type* release() + { + mutex_type *mut = mp_mutex; + mp_mutex = 0; + m_locked = false; + return mut; + } + + //!Effects: Swaps state with moved lock. + //!Throws: Nothing. + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + void swap(detail::moved_object > other) + { + std::swap(mp_mutex, other.get().mp_mutex); + std::swap(m_locked, other.get().m_locked); + } + #else + void swap(upgradable_lock &&other) + { + std::swap(mp_mutex, other.mp_mutex); + std::swap(m_locked, other.m_locked); + } + #endif + + /// @cond + private: + mutex_type *mp_mutex; + bool m_locked; + /// @endcond +}; + +/// @cond + +//!This class is movable +template +struct is_movable > +{ + enum { value = true }; +}; +/// @endcond + +} // namespace interprocess +} // namespace boost + +#include + +#endif // BOOST_INTERPROCESS_UPGRADABLE_LOCK_HPP diff --git a/thirdparty/boost/interprocess/windows_shared_memory.hpp b/thirdparty/boost/interprocess/windows_shared_memory.hpp new file mode 100644 index 0000000..89542af --- /dev/null +++ b/thirdparty/boost/interprocess/windows_shared_memory.hpp @@ -0,0 +1,243 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP +#define BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP + +#include +#include +#include + +#if !defined(BOOST_WINDOWS) || defined(BOOST_DISABLE_WIN32) +#error "This header can only be used in Windows operating systems" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//!\file +//!Describes a class representing a native windows shared memory. + +namespace boost { +namespace interprocess { + +//!A class that wraps the native Windows shared memory +//!that is implemented as a file mapping of the paging file. +//!Unlike shared_memory_object, windows_shared_memory has +//!no kernel persistence and the shared memory is destroyed +//!when all processes destroy all their windows_shared_memory +//!objects and mapped regions for the same shared memory +//!or the processes end/crash. +//! +//!Warning: Windows native shared memory and interprocess portable +//!shared memory (boost::interprocess::shared_memory_object) +//!can't communicate between them. +class windows_shared_memory +{ + /// @cond + //Non-copyable and non-assignable + windows_shared_memory(const windows_shared_memory &); + windows_shared_memory &operator=(const windows_shared_memory &); + /// @endcond + + public: + + //!Default constructor. + //!Represents an empty windows_shared_memory. + windows_shared_memory(); + + //!Creates a new native shared memory with name "name" and mode "mode", + //!with the access mode "mode". + //!If the file previously exists, throws an error. + windows_shared_memory(create_only_t, const char *name, mode_t mode, std::size_t size) + { this->priv_open_or_create(detail::DoCreate, name, mode, size); } + + //!Tries to create a shared memory object with name "name" and mode "mode", with the + //!access mode "mode". If the file previously exists, it tries to open it with mode "mode". + //!Otherwise throws an error. + windows_shared_memory(open_or_create_t, const char *name, mode_t mode, std::size_t size) + { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, size); } + + //!Tries to open a shared memory object with name "name", with the access mode "mode". + //!If the file does not previously exist, it throws an error. + windows_shared_memory(open_only_t, const char *name, mode_t mode) + { this->priv_open_or_create(detail::DoOpen, name, mode, 0); } + + //!Moves the ownership of "moved"'s shared memory object to *this. + //!After the call, "moved" does not represent any shared memory object. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + windows_shared_memory + (detail::moved_object &moved) + { this->swap(moved.get()); } + #else + windows_shared_memory(windows_shared_memory &&moved) + { this->swap(moved); } + #endif + + //!Moves the ownership of "moved"'s shared memory to *this. + //!After the call, "moved" does not represent any shared memory. + //!Does not throw + #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE + windows_shared_memory &operator= + (detail::moved_object &moved) + { + windows_shared_memory tmp(moved); + this->swap(tmp); + return *this; + } + #else + windows_shared_memory &operator=(windows_shared_memory &&moved) + { + windows_shared_memory tmp(move(moved)); + this->swap(tmp); + return *this; + } + #endif + + //!Swaps to shared_memory_objects. Does not throw + void swap(windows_shared_memory &other); + + //!Destroys *this. All mapped regions are still valid after + //!destruction. When all mapped regions and windows_shared_memory + //!objects referring the shared memory are destroyed, the + //!operating system will destroy the shared memory. + ~windows_shared_memory(); + + //!Returns the name of the shared memory. + const char *get_name() const; + + //!Returns access mode + mode_t get_mode() const; + + //!Returns the mapping handle. Never throws + mapping_handle_t get_mapping_handle() const; + + /// @cond + private: + + //!Closes a previously opened file mapping. Never throws. + void priv_close(); + + //!Closes a previously opened file mapping. Never throws. + bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size); + + void * m_handle; + mode_t m_mode; + std::string m_name; + /// @endcond +}; + +inline windows_shared_memory::windows_shared_memory() + : m_handle(0) +{} + +inline windows_shared_memory::~windows_shared_memory() +{ this->priv_close(); } + +inline const char *windows_shared_memory::get_name() const +{ return m_name.c_str(); } + +inline void windows_shared_memory::swap(windows_shared_memory &other) +{ + std::swap(m_handle, other.m_handle); + std::swap(m_mode, other.m_mode); + m_name.swap(other.m_name); +} + +inline mapping_handle_t windows_shared_memory::get_mapping_handle() const +{ mapping_handle_t mhnd = { m_handle, true}; return mhnd; } + +inline mode_t windows_shared_memory::get_mode() const +{ return m_mode; } + +inline bool windows_shared_memory::priv_open_or_create + (detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size) +{ + m_name = filename; + + unsigned long file_map_access = 0; + unsigned long map_access = 0; + + switch(mode) + { + case read_only: + file_map_access |= winapi::page_readonly; + map_access |= winapi::file_map_read; + break; + case read_write: + file_map_access |= winapi::page_readwrite; + map_access |= winapi::file_map_write; + break; + case copy_on_write: + file_map_access |= winapi::page_writecopy; + map_access |= winapi::file_map_copy; + break; + default: + { + error_info err(mode_error); + throw interprocess_exception(err); + } + break; + } + + switch(type){ + case detail::DoOpen: + m_handle = winapi::open_file_mapping + (map_access, filename); + break; + case detail::DoCreate: + case detail::DoOpenOrCreate: + { + __int64 s = size; + unsigned long high_size(s >> 32), low_size((boost::uint32_t)s); + m_handle = winapi::create_file_mapping + (winapi::invalid_handle_value, file_map_access, high_size, low_size, filename); + } + break; + default: + { + error_info err = other_error; + throw interprocess_exception(err); + } + } + + if(!m_handle || (type == detail::DoCreate && winapi::get_last_error() == winapi::error_already_exists)){ + error_info err = system_error_code(); + this->priv_close(); + throw interprocess_exception(err); + } + + m_mode = mode; + return true; +} + +inline void windows_shared_memory::priv_close() +{ + if(m_handle){ + winapi::close_handle(m_handle); + m_handle = 0; + } +} + +} //namespace interprocess { +} //namespace boost { + +#include + +#endif //BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP diff --git a/thirdparty/boost/intrusive/avl_set.hpp b/thirdparty/boost/intrusive/avl_set.hpp new file mode 100644 index 0000000..8a95dcd --- /dev/null +++ b/thirdparty/boost/intrusive/avl_set.hpp @@ -0,0 +1,2069 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_AVL_SET_HPP +#define BOOST_INTRUSIVE_AVL_SET_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! The class template avl_set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class avl_set_impl +{ + /// @cond + typedef avltree_impl tree_type; + //! This class is + //! non-copyable + avl_set_impl (const avl_set_impl&); + + //! This class is + //! non-assignable + avl_set_impl &operator =(const avl_set_impl&); + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the value_compare object throws. + avl_set_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty avl_set and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is std::distance(last, first). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + avl_set_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(true, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the avl_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~avl_set_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of avl_set. + //! + //! Effects: Returns a const reference to the avl_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static avl_set_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &avl_set_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of avl_set. + //! + //! Effects: Returns a const reference to the avl_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const avl_set_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &avl_set_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the avl_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the avl_set. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two sets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(avl_set_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the avl_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert(reference value) + { return tree_.insert_unique(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to to insert x into the avl_set, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: An iterator that points to the position where the + //! new element was inserted into the avl_set. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_unique(hint, value); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an aavlitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the avl_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the avl_set. + template + std::pair insert_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(key, key_value_comp, commit_data); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an aavlitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the avl_set, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the avl_set. + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the avl_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the avl_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return tree_.insert_unique_commit(value, commit_data); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the avl_set. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_unique(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size()) + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If the comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: If the internal value_compare ordering function throws. + //! + //! Complexity: O(log(size() + this->count(value)). Basic guarantee. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.find(value) != end(); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp) != end(); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a avl_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the avl_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! avl_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the avl_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! avl_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a avl_set/avl_multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + /// @cond + friend bool operator==(const avl_set_impl &x, const avl_set_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const avl_set_impl &x, const avl_set_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_set_impl &x, const avl_set_impl &y) +#else +(const avl_set_impl &x, const avl_set_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_set_impl &x, const avl_set_impl &y) +#else +(const avl_set_impl &x, const avl_set_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_set_impl &x, const avl_set_impl &y) +#else +(const avl_set_impl &x, const avl_set_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_set_impl &x, const avl_set_impl &y) +#else +(const avl_set_impl &x, const avl_set_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(avl_set_impl &x, avl_set_impl &y) +#else +(avl_set_impl &x, avl_set_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c avl_set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_avl_set +{ + /// @cond + typedef avl_set_impl + < typename make_avltree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class avl_set + : public make_avl_set::type +{ + typedef typename make_avl_set + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + avl_set( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + avl_set( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static avl_set &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const avl_set &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +//! The class template avl_multiset is an intrusive container, that mimics most of +//! the interface of std::avl_multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class avl_multiset_impl +{ + /// @cond + typedef avltree_impl tree_type; + + //Non-copyable and non-assignable + avl_multiset_impl (const avl_multiset_impl&); + avl_multiset_impl &operator =(const avl_multiset_impl&); + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + avl_multiset_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty avl_multiset and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + avl_multiset_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(false, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the avl_multiset + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~avl_multiset_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of avl_multiset. + //! + //! Effects: Returns a const reference to the avl_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static avl_multiset_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &avl_multiset_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of avl_multiset. + //! + //! Effects: Returns a const reference to the avl_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const avl_multiset_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &avl_multiset_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the avl_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the avl_multiset. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two avl_multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(avl_multiset_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the avl_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(reference value) + { return tree_.insert_equal(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts x into the avl_multiset, using pos as a hint to + //! where it will be inserted. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_equal(hint, value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the avl_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_equal(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.count(value); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.count(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a avl_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the avl_multiset + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! avl_multiset that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the avl_multiset + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a avl_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! avl_multiset that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a avl_multiset/avl_multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + /// @cond + friend bool operator==(const avl_multiset_impl &x, const avl_multiset_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const avl_multiset_impl &x, const avl_multiset_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#else +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#else +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#else +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#else +(const avl_multiset_impl &x, const avl_multiset_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(avl_multiset_impl &x, avl_multiset_impl &y) +#else +(avl_multiset_impl &x, avl_multiset_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c avl_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_avl_multiset +{ + /// @cond + typedef avl_multiset_impl + < typename make_avltree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class avl_multiset + : public make_avl_multiset::type +{ + typedef typename make_avl_multiset + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + avl_multiset( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + avl_multiset( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static avl_multiset &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const avl_multiset &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVL_SET_HPP diff --git a/thirdparty/boost/intrusive/avl_set_hook.hpp b/thirdparty/boost/intrusive/avl_set_hook.hpp new file mode 100644 index 0000000..d00f84f --- /dev/null +++ b/thirdparty/boost/intrusive/avl_set_hook.hpp @@ -0,0 +1,273 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_AVL_SET_HOOK_HPP +#define BOOST_INTRUSIVE_AVL_SET_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_avl_set_node_algo +{ + typedef avltree_algorithms > type; +}; +/// @endcond + +//! Helper metafunction to define a \c avl_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_avl_set_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_avl_set_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::AvlSetBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from avl_set_base_hook in order to store objects in +//! in an avl_set/avl_multiset. avl_set_base_hook holds the data necessary to maintain +//! the avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class avl_set_base_hook + : public make_avl_set_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + avl_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + avl_set_base_hook(const avl_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + avl_set_base_hook& operator=(const avl_set_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~avl_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(avl_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c avl_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_avl_set_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_avl_set_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member avl_set_member_hook in order to store objects of this class in +//! an avl_set/avl_multiset. avl_set_member_hook holds the data necessary for maintaining the +//! avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset. +//! +//! The hook admits the following options: \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class avl_set_member_hook + : public make_avl_set_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + avl_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + avl_set_member_hook(const avl_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + avl_set_member_hook& operator=(const avl_set_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~avl_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(avl_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVL_SET_HOOK_HPP diff --git a/thirdparty/boost/intrusive/avltree.hpp b/thirdparty/boost/intrusive/avltree.hpp new file mode 100644 index 0000000..28eefce --- /dev/null +++ b/thirdparty/boost/intrusive/avltree.hpp @@ -0,0 +1,1439 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_AVLTREE_HPP +#define BOOST_INTRUSIVE_AVLTREE_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct internal_default_avl_set_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_avl_set_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_avl_set_hook +{ + typedef typename T::default_avl_set_hook type; +}; + +template +struct avl_setopt +{ + typedef ValueTraits value_traits; + typedef Compare compare; + typedef SizeType size_type; + static const bool constant_time_size = ConstantTimeSize; +}; + +template +struct avl_set_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_avl_set_hook::value + , get_default_avl_set_hook + , detail::identity + >::type + > + , constant_time_size + , size_type + , compare > + >::type +{}; + +/// @endcond + +//! The class template avltree is an intrusive AVL tree container, that +//! is used to construct intrusive avl_set and avl_multiset containers. +//! The no-throw guarantee holds only, if the value_compare object +//! doesn't throw. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class avltree_impl +{ + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef value_type key_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef typename Config::compare value_compare; + typedef value_compare key_compare; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef avltree_algorithms node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + + /// @cond + private: + typedef detail::size_holder size_traits; + + //noncopyable + avltree_impl (const avltree_impl&); + avltree_impl operator =(const avltree_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + struct header_plus_size : public size_traits + { node header_; }; + + struct node_plus_pred_t : public detail::ebo_functor_holder + { + node_plus_pred_t(const value_compare &comp) + : detail::ebo_functor_holder(comp) + {} + header_plus_size header_plus_size_; + }; + + struct data_t : public avltree_impl::value_traits + { + typedef typename avltree_impl::value_traits value_traits; + data_t(const value_compare & comp, const value_traits &val_traits) + : value_traits(val_traits), node_plus_pred_(comp) + {} + node_plus_pred_t node_plus_pred_; + } data_; + + const value_compare &priv_comp() const + { return data_.node_plus_pred_.get(); } + + value_compare &priv_comp() + { return data_.node_plus_pred_.get(); } + + const node &priv_header() const + { return data_.node_plus_pred_.header_plus_size_.header_; } + + node &priv_header() + { return data_.node_plus_pred_.header_plus_size_.header_; } + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(detail::get_pointer(ptr))); + } + + size_traits &priv_size_traits() + { return data_.node_plus_pred_.header_plus_size_; } + + const size_traits &priv_size_traits() const + { return data_.node_plus_pred_.header_plus_size_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + avltree_impl( value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty tree and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + template + avltree_impl( bool unique, Iterator b, Iterator e + , value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + ~avltree_impl() + { this->clear(); } + + //! Effects: Returns an iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return cbegin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns an iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return iterator (node_ptr(&priv_header()), this); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return cend(); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return const_iterator (uncast(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + //! Precondition: end_iterator must be a valid end iterator + //! of avltree. + //! + //! Effects: Returns a const reference to the avltree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static avltree_impl &container_from_end_iterator(iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of avltree. + //! + //! Effects: Returns a const reference to the avltree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const avltree_impl &container_from_end_iterator(const_iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the value_compare object used by the tree. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return priv_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return node_algorithms::unique(const_node_ptr(&priv_header())); } + + //! Effects: Returns the number of elements stored in the tree. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else{ + return (size_type)node_algorithms::size(const_node_ptr(&priv_header())); + } + } + + //! Effects: Swaps the contents of two multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(avltree_impl& other) + { + //This can throw + using std::swap; + swap(priv_comp(), priv_comp()); + //These can't throw + node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header())); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree before the upper bound. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal_upper_bound + (node_ptr(&priv_header()), to_insert, key_node_comp), this); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal + (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the tree + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + iterator end(this->end()); + for (; b != e; ++b) + this->insert_equal(end, *b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree if the value + //! is not already present. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(value, commit_data); + if(!ret.second) + return ret; + return std::pair (insert_unique_commit(value, commit_data), true); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the tree, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(hint, value, commit_data); + if(!ret.second) + return ret.first; + return insert_unique_commit(value, commit_data); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the tree. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + if(this->empty()){ + iterator end(this->end()); + for (; b != e; ++b) + this->insert_unique(end, *b); + } + else{ + for (; b != e; ++b) + this->insert_unique(*b); + } + } + + std::pair insert_unique_check + (const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + std::pair insert_unique_check + (const_iterator hint, const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(hint, value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + node_algorithms::insert_unique_commit + (node_ptr(&priv_header()), to_insert, commit_data); + return iterator(to_insert, this); + } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { + iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + node_algorithms::erase(&priv_header(), to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret; + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { size_type n; return private_erase(b, e, n); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, priv_comp()); } + + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + return ret; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { size_type n; return private_erase(b, e, n, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { + std::pair p = this->equal_range(value); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Average complexity for is at most O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. Calls N times to disposer functor. + template + void clear_and_dispose(Disposer disposer) + { + node_algorithms::clear_and_dispose(node_ptr(&priv_header()) + , detail::node_disposer(disposer, this)); + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count(const_reference value) const + { return this->count(value, priv_comp()); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + return std::distance(ret.first, ret.second); + } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator lower_bound(const_reference value) + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator lower_bound(const_reference value) const + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator upper_bound(const_reference value) + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator upper_bound(const_reference value) const + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator find(const_reference value) + { return this->find(value, priv_comp()); } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator find(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator find(const_reference value) const + { return this->find(value, priv_comp()); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator find(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair equal_range(const_reference value) + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair + equal_range(const_reference value) const + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair + equal_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + node_algorithms::clone + (const_node_ptr(&src.priv_header()) + ,node_ptr(&this->priv_header()) + ,detail::node_cloner(cloner, this) + ,detail::node_disposer(disposer, this)); + this->priv_size_traits().set_size(src.priv_size_traits().get_size()); + } + } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { + node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance + (node_ptr(&priv_header()))); + if(!to_be_disposed) + return 0; + this->priv_size_traits().decrement(); + if(safemode_or_autounlink)//If this is commented does not work with normal_link + node_algorithms::init(to_be_disposed); + return get_real_value_traits().to_value_ptr(to_be_disposed); + } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + , node_ptr(&priv_header()) + , get_real_value_traits().to_node_ptr(with_this)); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return iterator (value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return iterator (value_traits::to_node_ptr(value), this); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } + + //! Requires: value shall not be in a tree. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + +/* + //! Effects: removes x from a tree of the appropriate type. It has no effect, + //! if x is not in such a tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This static function is only usable with the "safe mode" + //! hook and non-constant time size lists. Otherwise, the user must use + //! the non-static "erase(reference )" member. If the user calls + //! this function with a non "safe mode" or constant time size list + //! a compilation error will be issued. + template + static void remove_node(T& value) + { + //This function is only usable for safe mode hooks and non-constant + //time lists. + //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size))); + BOOST_STATIC_ASSERT((!constant_time_size)); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink_and_rebalance(to_remove); + if(safemode_or_autounlink) + node_algorithms::init(to_remove); + } +*/ + + /// @cond + private: + template + iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer) + { + for(n = 0; b != e; ++n) + this->erase_and_dispose(b++, disposer); + return b; + } + + iterator private_erase(iterator b, iterator e, size_type &n) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b; + } + /// @endcond + + private: + static avltree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + header_plus_size *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + node_plus_pred_t *n = detail::parent_from_member + (r, &node_plus_pred_t::header_plus_size_); + data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); + avltree_impl *avl = detail::parent_from_member(d, &avltree_impl::data_); + return *avl; + } +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ + typedef avltree_impl tree_type; + typedef typename tree_type::const_iterator const_iterator; + + if(tree_type::constant_time_size && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(tree_type::constant_time_size){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const avltree_impl &x, const avltree_impl &y) +#else +(const avltree_impl &x, const avltree_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(avltree_impl &x, avltree_impl &y) +#else +(avltree_impl &x, avltree_impl &y) +#endif +{ x.swap(y); } + +/// @cond +template +struct make_avltree_opt +{ + typedef typename pack_options + < avl_set_defaults, O1, O2, O3, O4>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + + typedef avl_setopt + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > type; +}; +/// @endcond + +//! Helper metafunction to define a \c avltree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_avltree +{ + /// @cond + typedef avltree_impl + < typename make_avltree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class avltree + : public make_avltree::type +{ + typedef typename make_avltree + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + avltree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + avltree( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + static avltree &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const avltree &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_HPP diff --git a/thirdparty/boost/intrusive/avltree_algorithms.hpp b/thirdparty/boost/intrusive/avltree_algorithms.hpp new file mode 100644 index 0000000..dd67cf9 --- /dev/null +++ b/thirdparty/boost/intrusive/avltree_algorithms.hpp @@ -0,0 +1,985 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Daniel K. O. 2005. +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP + +#include + +#include +#include + +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! balance: The type of the balance factor +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +//! +//! static balance get_balance(const_node_ptr n); +//! +//! static void set_balance(node_ptr n, balance b); +//! +//! static balance negative(); +//! +//! static balance zero(); +//! +//! static balance positive(); +template +class avltree_algorithms +{ + public: + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef typename NodeTraits::balance balance; + + /// @cond + private: + + typedef typename NodeTraits::node node; + typedef detail::tree_algorithms tree_algorithms; + + template + struct avltree_node_cloner + : private detail::ebo_functor_holder + { + typedef detail::ebo_functor_holder base_t; + + avltree_node_cloner(F f) + : base_t(f) + {} + + node_ptr operator()(node_ptr p) + { + node_ptr n = base_t::get()(p); + NodeTraits::set_balance(n, NodeTraits::get_balance(p)); + return n; + } + }; + + struct avltree_erase_fixup + { + void operator()(node_ptr to_erase, node_ptr successor) + { NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); } + }; + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + } + /// @endcond + + public: + static node_ptr begin_node(const_node_ptr header) + { return tree_algorithms::begin_node(header); } + + static node_ptr end_node(const_node_ptr header) + { return tree_algorithms::end_node(header); } + + //! This type is the information that will be + //! filled by insert_unique_check + typedef typename tree_algorithms::insert_commit_data insert_commit_data; + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) + { return tree_algorithms::swap_tree(header1, header2); } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) + { + if(node1 == node2) + return; + + node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + { + if(node1 == node2) return; + + tree_algorithms::swap_nodes(node1, header1, node2, header2); + //Swap balance + balance c = NodeTraits::get_balance(node1); + NodeTraits::set_balance(node1, NodeTraits::get_balance(node2)); + NodeTraits::set_balance(node2, c); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing and comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + { + tree_algorithms::replace_node(node_to_be_replaced, header, new_node); + NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced)); + } + + //! Requires: node is a tree node but not the header. + //! + //! Effects: Unlinks the node and rebalances the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + static void unlink(node_ptr node) + { + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, node); + } + } + + //! Requires: header is the header of a tree. + //! + //! Effects: Unlinks the leftmost node from the tree, and + //! updates the header link to the new leftmost node. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + { return tree_algorithms::unlink_leftmost_without_rebalance(header); } + + //! Requires: node is a node of the tree or an node initialized + //! by init(...). + //! + //! Effects: Returns true if the node is initialized by init(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + static bool unique(const_node_ptr node) + { return tree_algorithms::unique(node); } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr node) + { return tree_algorithms::count(node); } + + //! Requires: header is the header node of the tree. + //! + //! Effects: Returns the number of nodes above the header. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) + { return tree_algorithms::size(header); } + + //! Requires: p is a node from the tree except the header. + //! + //! Effects: Returns the next node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr next_node(node_ptr p) + { return tree_algorithms::next_node(p); } + + //! Requires: p is a node from the tree except the leftmost node. + //! + //! Effects: Returns the previous node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr prev_node(node_ptr p) + { return tree_algorithms::prev_node(p); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr node) + { tree_algorithms::init(node); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) + { + tree_algorithms::init_header(header); + NodeTraits::set_balance(header, NodeTraits::zero()); + } + + //! Requires: header must be the header of a tree, z a node + //! of that tree and z != header. + //! + //! Effects: Erases node "z" from the tree with header "header". + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static node_ptr erase(node_ptr header, node_ptr z) + { + typename tree_algorithms::data_for_rebalance info; + tree_algorithms::erase(header, z, avltree_erase_fixup(), info); + node_ptr x = info.x; + node_ptr x_parent = info.x_parent; + + //Rebalance avltree + rebalance_after_erasure(header, x, x_parent); + return z; + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Then, duplicates the entire tree pointed by "source_header" cloning each + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! are disposed using void disposer(node_ptr). + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { + avltree_node_cloner new_cloner(cloner); + tree_algorithms::clone(source_header, target_header, new_cloner, disposer); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) + { tree_algorithms::clear_and_dispose(header, disposer); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::lower_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::upper_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::find(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if they there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::equal_range(header, key, comp); } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the upper bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal_upper_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the lower bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal_lower_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal(header, hint, new_node, comp); + rebalance_after_insertion(header, new_node); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { return tree_algorithms::insert_unique_check(header, key, comp, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! "hint" is node from the "header"'s tree. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" using "hint" as a hint to where it should be + //! inserted and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! If "hint" is the upper_bound the function has constant time + //! complexity (two comparisons in the worst case). + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic, but it is + //! amortized constant time if new_node should be inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, node_ptr hint, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + static void insert_unique_commit + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + { + tree_algorithms::insert_unique_commit(header, new_value, commit_data); + rebalance_after_insertion(header, new_value); + } + + /// @cond + private: + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_header(const_node_ptr p) + { return NodeTraits::get_balance(p) == NodeTraits::zero() && tree_algorithms::is_header(p); } + + static void rebalance_after_erasure(node_ptr header, node_ptr x, node_ptr x_parent) + { + node_ptr root = NodeTraits::get_parent(header); + while (x != root) { + const balance x_parent_balance = NodeTraits::get_balance(x_parent); + if(x_parent_balance == NodeTraits::zero()){ + NodeTraits::set_balance(x_parent, + (x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive())); + break; // the height didn't change, let's stop here + } + else if(x_parent_balance == NodeTraits::negative()){ + if (x == NodeTraits::get_left(x_parent)) { + NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced + x = x_parent; + x_parent = NodeTraits::get_parent(x_parent); + } + else { + // x is right child + // a is left child + node_ptr a = NodeTraits::get_left(x_parent); + assert(a); + if (NodeTraits::get_balance(a) == NodeTraits::positive()) { + // a MUST have a right child + assert(NodeTraits::get_right(a)); + rotate_left_right(x_parent, root); + + x = NodeTraits::get_parent(x_parent); + x_parent = NodeTraits::get_parent(x); + } + else { + rotate_right(x_parent, root); + x = NodeTraits::get_parent(x_parent); + x_parent = NodeTraits::get_parent(x); + + } + + // if changed from negative to NodeTraits::positive(), no need to check above + if (NodeTraits::get_balance(x) == NodeTraits::positive()){ + break; + } + } + } + else if(x_parent_balance == NodeTraits::positive()){ + if (x == NodeTraits::get_right(x_parent)) { + NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced + x = x_parent; + x_parent = NodeTraits::get_parent(x_parent); + } + else { + // x is left child + // a is right child + node_ptr a = NodeTraits::get_right(x_parent); + assert(a); + if (NodeTraits::get_balance(a) == NodeTraits::negative()) { + // a MUST have then a left child + assert(NodeTraits::get_left(a)); + rotate_right_left(x_parent, root); + + x = NodeTraits::get_parent(x_parent); + x_parent = NodeTraits::get_parent(x); + } + else { + rotate_left(x_parent, root); + x = NodeTraits::get_parent(x_parent); + x_parent = NodeTraits::get_parent(x); + } + // if changed from NodeTraits::positive() to negative, no need to check above + if (NodeTraits::get_balance(x) == NodeTraits::negative()){ + break; + } + } + } + else{ + assert(false); // never reached + } + } + NodeTraits::set_parent(header, root); + } + + + static void rebalance_after_insertion(node_ptr header, node_ptr x) + { + node_ptr root = NodeTraits::get_parent(header); + NodeTraits::set_balance(x, NodeTraits::zero()); + + // Rebalance. + while (x != root){ + const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x)); + + if(x_parent_balance == NodeTraits::zero()){ + // if x is left, parent will have parent->bal_factor = negative + // else, parent->bal_factor = NodeTraits::positive() + NodeTraits::set_balance( NodeTraits::get_parent(x) + , x == NodeTraits::get_left(NodeTraits::get_parent(x)) + ? NodeTraits::negative() : NodeTraits::positive() ); + x = NodeTraits::get_parent(x); + } + else if(x_parent_balance == NodeTraits::positive()){ + // if x is a left child, parent->bal_factor = zero + if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) + NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero()); + else{ // x is a right child, needs rebalancing + if (NodeTraits::get_balance(x) == NodeTraits::negative()) + rotate_right_left(NodeTraits::get_parent(x), root); + else + rotate_left(NodeTraits::get_parent(x), root); + } + break; + } + else if(x_parent_balance == NodeTraits::negative()){ + // if x is a left child, needs rebalancing + if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) { + if (NodeTraits::get_balance(x) == NodeTraits::positive()) + rotate_left_right(NodeTraits::get_parent(x), root); + else + rotate_right(NodeTraits::get_parent(x), root); + } + else + NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero()); + break; + } + else{ + assert(false); // never reached + } + } + NodeTraits::set_parent(header, root); + } + + static void rotate_left_right(node_ptr a, node_ptr &root) + { + // | | // + // a(-2) c // + // / \ / \ // + // / \ ==> / \ // + // (pos)b [g] b a // + // / \ / \ / \ // + // [d] c [d] e f [g] // + // / \ // + // e f // + node_ptr b = NodeTraits::get_left(a), c = NodeTraits::get_right(b); + + // switch + NodeTraits::set_left(a, NodeTraits::get_right(c)); + NodeTraits::set_right(b, NodeTraits::get_left(c)); + + NodeTraits::set_right(c, a); + NodeTraits::set_left(c, b); + + // set the parents + NodeTraits::set_parent(c, NodeTraits::get_parent(a)); + NodeTraits::set_parent(a, c); + NodeTraits::set_parent(b, c); + + if (NodeTraits::get_left(a)) // do we have f? + NodeTraits::set_parent(NodeTraits::get_left(a), a); + if (NodeTraits::get_right(b)) // do we have e? + NodeTraits::set_parent(NodeTraits::get_right(b), b); + + if (a==root) root = c; + else // a had a parent, his child is now c + if (a == NodeTraits::get_left(NodeTraits::get_parent(c))) + NodeTraits::set_left(NodeTraits::get_parent(c), c); + else + NodeTraits::set_right(NodeTraits::get_parent(c), c); + + // balancing... + const balance c_balance = NodeTraits::get_balance(c); + if(c_balance == NodeTraits::negative()){ + NodeTraits::set_balance(a, NodeTraits::positive()); + NodeTraits::set_balance(b, NodeTraits::zero()); + } + else if(c_balance == NodeTraits::zero()){ + NodeTraits::set_balance(a, NodeTraits::zero()); + NodeTraits::set_balance(b, NodeTraits::zero()); + } + else if(c_balance == NodeTraits::positive()){ + NodeTraits::set_balance(a, NodeTraits::zero()); + NodeTraits::set_balance(b, NodeTraits::negative()); + } + else{ + assert(false); // never reached + } + NodeTraits::set_balance(c, NodeTraits::zero()); + } + + static void rotate_right_left(node_ptr a, node_ptr &root) + { + // | | // + // a(pos) c // + // / \ / \ // + // / \ / \ // + // [d] b(neg) ==> a b // + // / \ / \ / \ // + // c [g] [d] e f [g] // + // / \ // + // e f // + node_ptr b = NodeTraits::get_right(a), c = NodeTraits::get_left(b); + + // switch + NodeTraits::set_right(a, NodeTraits::get_left(c)); + NodeTraits::set_left(b, NodeTraits::get_right(c)); + + NodeTraits::set_left(c, a); + NodeTraits::set_right(c, b); + + // set the parents + NodeTraits::set_parent(c, NodeTraits::get_parent(a)); + NodeTraits::set_parent(a, c); + NodeTraits::set_parent(b, c); + + if (NodeTraits::get_right(a)) // do we have e? + NodeTraits::set_parent(NodeTraits::get_right(a), a); + if (NodeTraits::get_left(b)) // do we have f? + NodeTraits::set_parent(NodeTraits::get_left(b), b); + + if (a==root) root = c; + else // a had a parent, his child is now c + if (a == NodeTraits::get_left(NodeTraits::get_parent(c))) + NodeTraits::set_left(NodeTraits::get_parent(c), c); + else + NodeTraits::set_right(NodeTraits::get_parent(c), c); + + // balancing... + const balance c_balance = NodeTraits::get_balance(c); + if(c_balance == NodeTraits::negative()){ + NodeTraits::set_balance(a, NodeTraits::zero()); + NodeTraits::set_balance(b, NodeTraits::positive()); + } + else if(c_balance == NodeTraits::zero()){ + NodeTraits::set_balance(a, NodeTraits::zero()); + NodeTraits::set_balance(b, NodeTraits::zero()); + } + else if(c_balance == NodeTraits::positive()){ + NodeTraits::set_balance(a, NodeTraits::negative()); + NodeTraits::set_balance(b, NodeTraits::zero()); + } + else{ + assert(false); + } + NodeTraits::set_balance(c, NodeTraits::zero()); + } + + static void rotate_left(node_ptr x, node_ptr & root) + { + // | | // + // x(2) y(0) // + // / \ ==> / \ // + // n[a] y(1)n+2 n+1(0)x [c]n+1 // + // / \ / \ // + // n[b] [c]n+1 n[a] [b]n // + node_ptr y = NodeTraits::get_right(x); + + // switch + NodeTraits::set_right(x, NodeTraits::get_left(y)); + NodeTraits::set_left(y, x); + + // rearrange parents + NodeTraits::set_parent(y, NodeTraits::get_parent(x)); + NodeTraits::set_parent(x, y); + + // do we have [b]? + if (NodeTraits::get_right(x)) + NodeTraits::set_parent(NodeTraits::get_right(x), x); + + if (x == root) + root = y; + else + // need to reparent y + if (NodeTraits::get_left(NodeTraits::get_parent(y)) == x) + NodeTraits::set_left(NodeTraits::get_parent(y), y); + else + NodeTraits::set_right(NodeTraits::get_parent(y), y); + + // reset the balancing factor + if (NodeTraits::get_balance(y) == NodeTraits::positive()) { + NodeTraits::set_balance(x, NodeTraits::zero()); + NodeTraits::set_balance(y, NodeTraits::zero()); + } + else { // this doesn't happen during insertions + NodeTraits::set_balance(x, NodeTraits::positive()); + NodeTraits::set_balance(y, NodeTraits::negative()); + } + } + + static void rotate_right(node_ptr x, node_ptr &root) + { + node_ptr y = NodeTraits::get_left(x); + + // switch + NodeTraits::set_left(x, NodeTraits::get_right(y)); + NodeTraits::set_right(y, x); + + // rearrange parents + NodeTraits::set_parent(y, NodeTraits::get_parent(x)); + NodeTraits::set_parent(x, y); + + // do we have [b]? + if (NodeTraits::get_left(x)) + NodeTraits::set_parent(NodeTraits::get_left(x), x); + + if (x == root) + root = y; + else + // need to reparent y + if (NodeTraits::get_left(NodeTraits::get_parent(y)) == x) + NodeTraits::set_left(NodeTraits::get_parent(y), y); + else + NodeTraits::set_right(NodeTraits::get_parent(y), y); + + // reset the balancing factor + if (NodeTraits::get_balance(y) == NodeTraits::negative()) { + NodeTraits::set_balance(x, NodeTraits::zero()); + NodeTraits::set_balance(y, NodeTraits::zero()); + } + else { // this doesn't happen during insertions + NodeTraits::set_balance(x, NodeTraits::negative()); + NodeTraits::set_balance(y, NodeTraits::positive()); + } + } + + /// @endcond +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/bs_set_hook.hpp b/thirdparty/boost/intrusive/bs_set_hook.hpp new file mode 100644 index 0000000..ece4639 --- /dev/null +++ b/thirdparty/boost/intrusive/bs_set_hook.hpp @@ -0,0 +1,288 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_BS_SET_HOOK_HPP +#define BOOST_INTRUSIVE_BS_SET_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_bs_set_node_algo +{ + typedef detail::tree_algorithms > type; +}; +/// @endcond + +//! Helper metafunction to define a \c bs_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_bs_set_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + //Scapegoat trees can't be auto unlink trees + BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink)); + + typedef detail::generic_hook + < get_bs_set_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::BsSetBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from bs_set_base_hook in order to store objects in +//! in a bs_set/bs_multiset. bs_set_base_hook holds the data necessary to maintain +//! the bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class bs_set_base_hook + : public make_bs_set_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + bs_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + bs_set_base_hook(const bs_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + bs_set_base_hook& operator=(const bs_set_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~bs_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(bs_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c bs_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_bs_set_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + //Scapegoat trees can't be auto unlink trees + BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink)); + + typedef detail::generic_hook + < get_bs_set_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member bs_set_member_hook in order to store objects of this class in +//! a bs_set/bs_multiset. bs_set_member_hook holds the data necessary for maintaining the +//! bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset. +//! +//! The hook admits the following options: \c void_pointer<>, \c link_mode<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class bs_set_member_hook + : public make_bs_set_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + bs_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + bs_set_member_hook(const bs_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + bs_set_member_hook& operator=(const bs_set_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~bs_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(bs_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +/// @cond + +template +struct internal_default_bs_set_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_bs_set_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_bs_set_hook +{ + typedef typename T::default_bs_set_hook type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BS_SET_HOOK_HPP diff --git a/thirdparty/boost/intrusive/circular_list_algorithms.hpp b/thirdparty/boost/intrusive/circular_list_algorithms.hpp new file mode 100644 index 0000000..0fdd052 --- /dev/null +++ b/thirdparty/boost/intrusive/circular_list_algorithms.hpp @@ -0,0 +1,406 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP + +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! circular_list_algorithms provides basic algorithms to manipulate nodes +//! forming a circular doubly linked list. An empty circular list is formed by a node +//! whose pointers point to itself. +//! +//! circular_list_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_previous(const_node_ptr n); +//! +//! static void set_previous(node_ptr n, node_ptr prev); +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class circular_list_algorithms +{ + public: + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + //! Effects: Constructs an non-used list element, so that + //! inited(this_node) == true + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node) + { + NodeTraits::set_next(this_node, 0); + NodeTraits::set_previous(this_node, 0); + } + + //! Effects: Returns true is "this_node" is in a non-used state + //! as if it was initialized by the "init" function. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool inited(const_node_ptr this_node) + { return !NodeTraits::get_next(this_node); } + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node) + //! == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init_header(node_ptr this_node) + { + NodeTraits::set_next(this_node, this_node); + NodeTraits::set_previous(this_node, this_node); + } + + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! return NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node) + { + node_ptr next = NodeTraits::get_next(this_node); + return !next || next == this_node; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the number of nodes in a circular list. If the circular list + //! is empty, returns 1. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + }while (p != this_node); + return result; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static node_ptr unlink(node_ptr this_node) + { + if(NodeTraits::get_next(this_node)){ + node_ptr next(NodeTraits::get_next(this_node)); + node_ptr prev(NodeTraits::get_previous(this_node)); + NodeTraits::set_next(prev, next); + NodeTraits::set_previous(next, prev); + return next; + } + else{ + return this_node; + } + } + + //! Requires: b and e must be nodes of the same circular list or an empty range. + //! + //! Effects: Unlinks the node [b, e) from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink(node_ptr b, node_ptr e) + { + if (b != e) { + node_ptr prevb(NodeTraits::get_previous(b)); + NodeTraits::set_previous(e, prevb); + NodeTraits::set_next(prevb, e); + } + } + + //! Requires: nxt_node must be a node of a circular list. + //! + //! Effects: Links this_node before nxt_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_before(node_ptr nxt_node, node_ptr this_node) + { + node_ptr prev(NodeTraits::get_previous(nxt_node)); + NodeTraits::set_previous(this_node, prev); + NodeTraits::set_next(prev, this_node); + NodeTraits::set_previous(nxt_node, this_node); + NodeTraits::set_next(this_node, nxt_node); + } + + //! Requires: prev_node must be a node of a circular list. + //! + //! Effects: Links this_node after prev_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_after(node_ptr prev_node, node_ptr this_node) + { + node_ptr next(NodeTraits::get_next(prev_node)); + NodeTraits::set_previous(this_node, prev_node); + NodeTraits::set_next(this_node, next); + NodeTraits::set_previous(next, this_node); + NodeTraits::set_next(prev_node, this_node); + } + + //! Requires: this_node and other_node must be nodes inserted + //! in circular lists or be empty circular lists. + //! + //! Effects: Swaps the position of the nodes: this_node is inserted in + //! other_nodes position in the second circular list and the other_node is inserted + //! in this_node's position in the first circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. +/* + static void swap_nodes(node_ptr this_node, node_ptr other_node) + { + + if (other_node == this_node) + return; + bool empty1 = unique(this_node); + bool empty2 = unique(other_node); + + node_ptr next_this(NodeTraits::get_next(this_node)); + node_ptr prev_this(NodeTraits::get_previous(this_node)); + node_ptr next_other(NodeTraits::get_next(other_node)); + node_ptr prev_other(NodeTraits::get_previous(other_node)); + + //Do the swap + NodeTraits::set_next(this_node, next_other); + NodeTraits::set_next(other_node, next_this); + + NodeTraits::set_previous(this_node, prev_other); + NodeTraits::set_previous(other_node, prev_this); + + if (empty2){ + init(this_node); + } + else{ + NodeTraits::set_next(prev_other, this_node); + NodeTraits::set_previous(next_other, this_node); + } + if (empty1){ + init(other_node); + } + else{ + NodeTraits::set_next(prev_this, other_node); + NodeTraits::set_previous(next_this, other_node); + } + } +*/ + + //Watanabe version + private: + static void swap_prev(node_ptr this_node, node_ptr other_node) + { + node_ptr temp(NodeTraits::get_previous(this_node)); + NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node)); + NodeTraits::set_previous(other_node, temp); + } + static void swap_next(node_ptr this_node, node_ptr other_node) + { + node_ptr temp(NodeTraits::get_next(this_node)); + NodeTraits::set_next(this_node, NodeTraits::get_next(other_node)); + NodeTraits::set_next(other_node, temp); + } + + public: + static void swap_nodes(node_ptr this_node, node_ptr other_node) + { + if (other_node == this_node) + return; + bool this_inited = inited(this_node); + bool other_inited = inited(other_node); + if(this_inited){ + init_header(this_node); + } + if(other_inited){ + init_header(other_node); + } + + node_ptr next_this(NodeTraits::get_next(this_node)); + node_ptr prev_this(NodeTraits::get_previous(this_node)); + node_ptr next_other(NodeTraits::get_next(other_node)); + node_ptr prev_other(NodeTraits::get_previous(other_node)); + //these first two swaps must happen before the other two + swap_prev(next_this, next_other); + swap_next(prev_this, prev_other); + swap_next(this_node, other_node); + swap_prev(this_node, other_node); + + if(this_inited){ + init(other_node); + } + if(other_inited){ + init(this_node); + } + } + + //! Requires: b and e must be nodes of the same circular list or an empty range. + //! and p must be a node of a different circular list or may not be an iterator in + // [b, e). + //! + //! Effects: Removes the nodes from [b, e) range from their circular list and inserts + //! them before p in p's circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer(node_ptr p, node_ptr b, node_ptr e) + { + if (b != e) { + node_ptr prev_p(NodeTraits::get_previous(p)); + node_ptr prev_b(NodeTraits::get_previous(b)); + node_ptr prev_e(NodeTraits::get_previous(e)); + NodeTraits::set_next(prev_e, p); + NodeTraits::set_previous(p, prev_e); + NodeTraits::set_next(prev_b, e); + NodeTraits::set_previous(e, prev_b); + NodeTraits::set_next(prev_p, b); + NodeTraits::set_previous(b, prev_p); + } + } + + //! Requires: i must a node of a circular list + //! and p must be a node of a different circular list. + //! + //! Effects: Removes the node i from its circular list and inserts + //! it before p in p's circular list. + //! If p == i or p == NodeTraits::get_next(i), this function is a null operation. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer(node_ptr p, node_ptr i) + { + node_ptr n(NodeTraits::get_next(i)); + if(n != p && i != p){ + node_ptr prev_p(NodeTraits::get_previous(p)); + node_ptr prev_i(NodeTraits::get_previous(i)); + NodeTraits::set_next(prev_p, i); + NodeTraits::set_previous(i, prev_p); + NodeTraits::set_next(i, p); + NodeTraits::set_previous(p, i); + NodeTraits::set_previous(n, prev_i); + NodeTraits::set_next(prev_i, n); + + } + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + static void reverse(node_ptr p) + { + node_ptr f(NodeTraits::get_next(p)); + node_ptr i(NodeTraits::get_next(f)), e(p); + + while(i != e) { + node_ptr n = i; + i = NodeTraits::get_next(i); + transfer(f, n, i); + f = n; + } + } + + //! Effects: Moves the node p n positions towards the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of moved positions. + static void move_backwards(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return; + node_ptr first = NodeTraits::get_next(p); + //size() == 0 or 1, nothing to do + if(first == NodeTraits::get_previous(p)) return; + unlink(p); + //Now get the new first node + while(n--){ + first = NodeTraits::get_next(first); + } + link_before(first, p); + } + + //! Effects: Moves the node p n positions towards the beginning of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of moved positions. + static void move_forward(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return; + node_ptr last = NodeTraits::get_previous(p); + //size() == 0 or 1, nothing to do + if(last == NodeTraits::get_next(p)) return; + + unlink(p); + //Now get the new last node + while(n--){ + last = NodeTraits::get_previous(last); + } + link_after(last, p); + } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/circular_slist_algorithms.hpp b/thirdparty/boost/intrusive/circular_slist_algorithms.hpp new file mode 100644 index 0000000..4669345 --- /dev/null +++ b/thirdparty/boost/intrusive/circular_slist_algorithms.hpp @@ -0,0 +1,404 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! circular_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a circular singly linked list. An empty circular list is formed by a node +//! whose pointer to the next node points to itself. +//! +//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class circular_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == 0 + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node); + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node); + + //! Effects: Returns true is "this_node" has the same state as + //! if it was inited using "init(node_ptr)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool inited(const_node_ptr this_node); + + //! Requires: prev_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node); + + //! Requires: prev_node and last_node must be in a circular list + //! or be an empty circular list. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node, node_ptr last_node); + + //! Requires: prev_node must be a node of a circular list. + //! + //! Effects: Links this_node after prev_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_after(node_ptr prev_node, node_ptr this_node); + + //! Requires: b and e must be nodes of the same circular list or an empty range. + //! and p must be a node of a different circular list. + //! + //! Effects: Removes the nodes from (b, e] range from their circular list and inserts + //! them after p in p's circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer_after(node_ptr p, node_ptr b, node_ptr e); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init_header(node_ptr this_node) + { NodeTraits::set_next(this_node, this_node); } + + //! Requires: this_node and prev_init_node must be in the same circular list. + //! + //! Effects: Returns the previous node of this_node in the circular list starting. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! Complexity: Linear to the number of elements between prev_init_node and this_node. + //! + //! Throws: Nothing. + static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) + { return base_t::get_previous_node(prev_init_node, this_node); } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + static node_ptr get_previous_node(node_ptr this_node) + { return base_t::get_previous_node(this_node, this_node); } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the previous node of the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + static node_ptr get_previous_previous_node(node_ptr this_node) + { return get_previous_previous_node(this_node, this_node); } + + //! Requires: this_node and prev_prev_init_node must be in the same circular list. + //! + //! Effects: Returns the previous node of the previous node of this_node in the + //! circular list starting. the search from prev_init_node. The first node checked + //! for equality is NodeTraits::get_next((NodeTraits::get_next(prev_prev_init_node)). + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + static node_ptr get_previous_previous_node(node_ptr prev_prev_init_node, node_ptr this_node) + { + node_ptr p = prev_prev_init_node; + node_ptr p_next = NodeTraits::get_next(p); + node_ptr p_next_next = NodeTraits::get_next(p_next); + while (this_node != p_next_next){ + p = p_next; + p_next = p_next_next; + p_next_next = NodeTraits::get_next(p_next); + } + return p; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the number of nodes in a circular list. If the circular list + //! is empty, returns 1. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p != this_node); + return result; + } + + //! Requires: this_node must be in a circular list, be an empty circular list or be inited. + //! + //! Effects: Unlinks the node from the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list + //! + //! Throws: Nothing. + static void unlink(node_ptr this_node) + { + if(NodeTraits::get_next(this_node)) + base_t::unlink_after(get_previous_node(this_node)); + } + + //! Requires: nxt_node must be a node of a circular list. + //! + //! Effects: Links this_node before nxt_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + static void link_before (node_ptr nxt_node, node_ptr this_node) + { base_t::link_after(get_previous_node(nxt_node), this_node); } + + //! Requires: this_node and other_node must be nodes inserted + //! in circular lists or be empty circular lists. + //! + //! Effects: Swaps the position of the nodes: this_node is inserted in + //! other_nodes position in the second circular list and the other_node is inserted + //! in this_node's position in the first circular list. + //! + //! Complexity: Linear to number of elements of both lists + //! + //! Throws: Nothing. + static void swap_nodes(node_ptr this_node, node_ptr other_node) + { + if (other_node == this_node) + return; + bool this_inited = base_t::inited(this_node); + bool other_inited = base_t::inited(other_node); + if(this_inited){ + base_t::init_header(this_node); + } + if(other_inited){ + base_t::init_header(other_node); + } + + bool empty1 = base_t::unique(this_node); + bool empty2 = base_t::unique(other_node); + node_ptr prev_this (get_previous_node(this_node)); + node_ptr prev_other(get_previous_node(other_node)); + + node_ptr this_next (NodeTraits::get_next(this_node)); + node_ptr other_next(NodeTraits::get_next(other_node)); + NodeTraits::set_next(this_node, other_next); + NodeTraits::set_next(other_node, this_next); + NodeTraits::set_next(empty1 ? other_node : prev_this, other_node); + NodeTraits::set_next(empty2 ? this_node : prev_other, this_node); + + if(this_inited){ + base_t::init(other_node); + } + if(other_inited){ + base_t::init(this_node); + } + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static void reverse(node_ptr p) + { + node_ptr i = NodeTraits::get_next(p), e(p); + for (;;) { + node_ptr nxt(NodeTraits::get_next(i)); + if (nxt == e) + break; + base_t::transfer_after(e, i, nxt); + } + } + + //! Effects: Moves the node p n positions towards the end of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_ptr move_backwards(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return 0; + node_ptr first = NodeTraits::get_next(p); + + //count() == 1 or 2, nothing to do + if(NodeTraits::get_next(first) == p) + return 0; + + bool end_found = false; + node_ptr new_last(0); + + //Now find the new last node according to the shift count. + //If we find p before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == p){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) + return 0; + i = 0; + //Unlink p and continue the new first node search + first = NodeTraits::get_next(p); + base_t::unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + base_t::unlink_after(base_t::get_previous_node(first, p)); + } + + //Now link p after the new last node + base_t::link_after(new_last, p); + return new_last; + } + + //! Effects: Moves the node p n positions towards the beginning of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads equals to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_ptr move_forward(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return 0; + node_ptr first = node_traits::get_next(p); + + //count() == 1 or 2, nothing to do + if(node_traits::get_next(first) == p) return 0; + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(p != (next_to_it = node_traits::get_next(old_last))){ + if(++distance > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) return 0; + + for( new_last = p + ; new_before_last_pos-- + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Now unlink p and link it after the new last node + base_t::unlink_after(old_last); + base_t::link_after(new_last, p); + return new_last; + } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/derivation_value_traits.hpp b/thirdparty/boost/intrusive/derivation_value_traits.hpp new file mode 100644 index 0000000..31522a3 --- /dev/null +++ b/thirdparty/boost/intrusive/derivation_value_traits.hpp @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP + +#include +#include + +namespace boost { +namespace intrusive { + +//!This value traits template is used to create value traits +//!from user defined node traits where value_traits::value_type will +//!derive from node_traits::node +template +struct derivation_value_traits +{ + public: + typedef NodeTraits node_traits; + typedef T value_type; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename boost::pointer_to_other::type pointer; + typedef typename boost::pointer_to_other::type const_pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + static const link_mode_type link_mode = LinkMode; + + static node_ptr to_node_ptr(reference value) + { return node_ptr(&value); } + + static const_node_ptr to_node_ptr(const_reference value) + { return node_ptr(&value); } + + static pointer to_value_ptr(node_ptr n) + { return pointer(static_cast(detail::get_pointer(n))); } + + static const_pointer to_value_ptr(const_node_ptr n) + { return const_pointer(static_cast(detail::get_pointer(n))); } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP diff --git a/thirdparty/boost/intrusive/detail/assert.hpp b/thirdparty/boost/intrusive/detail/assert.hpp new file mode 100644 index 0000000..2bb97d0 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/assert.hpp @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP +#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT) +#include +#define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT) +#include +#define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT) +#include +#define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT +#endif + +#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP diff --git a/thirdparty/boost/intrusive/detail/avltree_node.hpp b/thirdparty/boost/intrusive/detail/avltree_node.hpp new file mode 100644 index 0000000..3d535d1 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/avltree_node.hpp @@ -0,0 +1,179 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_AVLTREE_NODE_HPP +#define BOOST_INTRUSIVE_AVLTREE_NODE_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +///////////////////////////////////////////////////////////////////////////// +// // +// Generic node_traits for any pointer type // +// // +///////////////////////////////////////////////////////////////////////////// + +//This is the compact representation: 3 pointers +template +struct compact_avltree_node +{ + typedef typename pointer_to_other + >::type node_ptr; + enum balance { negative_t, zero_t, positive_t }; + node_ptr parent_, left_, right_; +}; + +//This is the normal representation: 3 pointers + enum +template +struct avltree_node +{ + typedef typename pointer_to_other + >::type node_ptr; + enum balance { negative_t, zero_t, positive_t }; + node_ptr parent_, left_, right_; + balance balance_; +}; + +//This is the default node traits implementation +//using a node with 3 generic pointers plus an enum +template +struct default_avltree_node_traits_impl +{ + typedef avltree_node node; + + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef typename node::balance balance; + + static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + static void set_parent(node_ptr n, node_ptr p) + { n->parent_ = p; } + + static node_ptr get_left(const_node_ptr n) + { return n->left_; } + + static void set_left(node_ptr n, node_ptr l) + { n->left_ = l; } + + static node_ptr get_right(const_node_ptr n) + { return n->right_; } + + static void set_right(node_ptr n, node_ptr r) + { n->right_ = r; } + + static balance get_balance(const_node_ptr n) + { return n->balance_; } + + static void set_balance(node_ptr n, balance b) + { n->balance_ = b; } + + static balance negative() + { return node::negative_t; } + + static balance zero() + { return node::zero_t; } + + static balance positive() + { return node::positive_t; } +}; + +//This is the compact node traits implementation +//using a node with 3 generic pointers +template +struct compact_avltree_node_traits_impl +{ + typedef compact_avltree_node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef typename node::balance balance; + + typedef pointer_plus_2_bits ptr_bit; + + static node_ptr get_parent(const_node_ptr n) + { return ptr_bit::get_pointer(n->parent_); } + + static void set_parent(node_ptr n, node_ptr p) + { ptr_bit::set_pointer(n->parent_, p); } + + static node_ptr get_left(const_node_ptr n) + { return n->left_; } + + static void set_left(node_ptr n, node_ptr l) + { n->left_ = l; } + + static node_ptr get_right(const_node_ptr n) + { return n->right_; } + + static void set_right(node_ptr n, node_ptr r) + { n->right_ = r; } + + static balance get_balance(const_node_ptr n) + { return (balance)ptr_bit::get_bits(n->parent_); } + + static void set_balance(node_ptr n, balance b) + { ptr_bit::set_bits(n->parent_, (std::size_t)b); } + + static balance negative() + { return node::negative_t; } + + static balance zero() + { return node::zero_t; } + + static balance positive() + { return node::positive_t; } +}; + +//Dispatches the implementation based on the boolean +template +struct avltree_node_traits_dispatch + : public default_avltree_node_traits_impl +{}; + +template +struct avltree_node_traits_dispatch + : public compact_avltree_node_traits_impl +{}; + +//Inherit from the detail::link_dispatch depending on the embedding capabilities +template +struct avltree_node_traits + : public avltree_node_traits_dispatch + < VoidPointer + , OptimizeSize && + has_pointer_plus_2_bits + < VoidPointer + , detail::alignment_of >::value + >::value + > +{}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_AVLTREE_NODE_HPP diff --git a/thirdparty/boost/intrusive/detail/common_slist_algorithms.hpp b/thirdparty/boost/intrusive/detail/common_slist_algorithms.hpp new file mode 100644 index 0000000..8e86719 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/common_slist_algorithms.hpp @@ -0,0 +1,95 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class common_slist_algorithms +{ + public: + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) + { + node_ptr p = prev_init_node; + for( node_ptr p_next + ; this_node != (p_next = NodeTraits::get_next(p)) + ; p = p_next){ + //Logic error: possible use of linear lists with + //operations only permitted with lists + BOOST_INTRUSIVE_INVARIANT_ASSERT(p); + } + return p; + } + + static void init_header(node_ptr this_node) + { NodeTraits::set_next(this_node, this_node); } + + static void init(node_ptr this_node) + { NodeTraits::set_next(this_node, 0); } + + static bool unique(const_node_ptr this_node) + { + node_ptr next = NodeTraits::get_next(this_node); + return !next || next == this_node; + } + + static bool inited(const_node_ptr this_node) + { return !NodeTraits::get_next(this_node); } + + static void unlink_after(node_ptr prev_node) + { + node_ptr this_node(NodeTraits::get_next(prev_node)); + NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node)); + } + + static void unlink_after(node_ptr prev_node, node_ptr last_node) + { NodeTraits::set_next(prev_node, last_node); } + + static void link_after(node_ptr prev_node, node_ptr this_node) + { + NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); + NodeTraits::set_next(prev_node, this_node); + } + + static void transfer_after(node_ptr p, node_ptr b, node_ptr e) + { + if (p != b && p != e) { + node_ptr next_b = NodeTraits::get_next(b); + node_ptr next_e = NodeTraits::get_next(e); + node_ptr next_p = NodeTraits::get_next(p); + NodeTraits::set_next(b, next_e); + NodeTraits::set_next(e, next_p); + NodeTraits::set_next(p, next_b); + } + } +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/detail/config_begin.hpp b/thirdparty/boost/intrusive/detail/config_begin.hpp new file mode 100644 index 0000000..2205666 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/config_begin.hpp @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_CONFIG_INCLUDED +#define BOOST_INTRUSIVE_CONFIG_INCLUDED +#include +#endif + +#ifdef BOOST_MSVC + + #pragma warning (push) + // + //'function' : resolved overload was found by argument-dependent lookup + //A function found by argument-dependent lookup (Koenig lookup) was eventually + //chosen by overload resolution. + // + //In Visual C++ .NET and earlier compilers, a different function would have + //been called. To pick the original function, use an explicitly qualified name. + // + + //warning C4275: non dll-interface class 'x' used as base for + //dll-interface class 'Y' + #pragma warning (disable : 4275) + //warning C4251: 'x' : class 'y' needs to have dll-interface to + //be used by clients of class 'z' + #pragma warning (disable : 4251) + #pragma warning (disable : 4675) + #pragma warning (disable : 4996) + #pragma warning (disable : 4503) + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4521) ////Disable "multiple copy constructors specified" + #pragma warning (disable : 4522) + #pragma warning (disable : 4146) + #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data + #pragma warning (disable : 4127) //conditional expression is constant + #pragma warning (disable : 4706) //assignment within conditional expression +#endif + +//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE +//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE diff --git a/thirdparty/boost/intrusive/detail/config_end.hpp b/thirdparty/boost/intrusive/detail/config_end.hpp new file mode 100644 index 0000000..f21303a --- /dev/null +++ b/thirdparty/boost/intrusive/detail/config_end.hpp @@ -0,0 +1,15 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#if defined BOOST_MSVC + #pragma warning (pop) +#endif diff --git a/thirdparty/boost/intrusive/detail/ebo_functor_holder.hpp b/thirdparty/boost/intrusive/detail/ebo_functor_holder.hpp new file mode 100644 index 0000000..014d74d --- /dev/null +++ b/thirdparty/boost/intrusive/detail/ebo_functor_holder.hpp @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Joaquín M López Muñoz 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class ebo_functor_holder_impl +{ + public: + ebo_functor_holder_impl(){} + ebo_functor_holder_impl(const T& t):t(t){} + + T& get(){return t;} + const T& get()const{return t;} + + private: + T t; +}; + +template +class ebo_functor_holder_impl + : public T +{ + public: + ebo_functor_holder_impl(){} + ebo_functor_holder_impl(const T& t):T(t){} + + T& get(){return *this;} + const T& get()const{return *this;} +}; + +template +class ebo_functor_holder + : public ebo_functor_holder_impl::value> +{ + private: + typedef ebo_functor_holder_impl::value> super; + + public: + ebo_functor_holder(){} + ebo_functor_holder(const T& t):super(t){} + + ebo_functor_holder& operator=(const ebo_functor_holder& x) + { + this->get()=x.get(); + return *this; + } +}; + + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP diff --git a/thirdparty/boost/intrusive/detail/generic_hook.hpp b/thirdparty/boost/intrusive/detail/generic_hook.hpp new file mode 100644 index 0000000..9d13e03 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/generic_hook.hpp @@ -0,0 +1,200 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP +#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +/// @cond + +enum +{ NoBaseHook +, ListBaseHook +, SlistBaseHook +, SetBaseHook +, UsetBaseHook +, SplaySetBaseHook +, AvlSetBaseHook +, BsSetBaseHook +}; + +struct no_default_definer{}; + +template +struct default_definer; + +template +struct default_definer +{ typedef Hook default_list_hook; }; + +template +struct default_definer +{ typedef Hook default_slist_hook; }; + +template +struct default_definer +{ typedef Hook default_set_hook; }; + +template +struct default_definer +{ typedef Hook default_uset_hook; }; + +template +struct default_definer +{ typedef Hook default_splay_set_hook; }; + +template +struct default_definer +{ typedef Hook default_avl_set_hook; }; + +template +struct default_definer +{ typedef Hook default_bs_set_hook; }; + +template +struct make_default_definer +{ + typedef typename detail::if_c + < BaseHookType != 0 + , default_definer + , no_default_definer>::type type; +}; + +template + < class GetNodeAlgorithms + , class Tag + , link_mode_type LinkMode + , int HookType + > +struct make_node_holder +{ + typedef typename detail::if_c + ::value + , detail::node_holder + < typename GetNodeAlgorithms::type::node_traits::node + , Tag + , LinkMode + , HookType> + , typename GetNodeAlgorithms::type::node_traits::node + >::type type; +}; + +/// @endcond + +template + < class GetNodeAlgorithms + , class Tag + , link_mode_type LinkMode + , int HookType + > +class generic_hook + /// @cond + + //If the hook is a base hook, derive generic hook from detail::node_holder + //so that a unique base class is created to convert from the node + //to the type. This mechanism will be used by base_hook_traits. + // + //If the hook is a member hook, generic hook will directly derive + //from the hook. + : public make_default_definer + < generic_hook + , detail::is_same::value*HookType + >::type + , public make_node_holder::type + /// @endcond +{ + public: + /// @cond + struct boost_intrusive_tags + { + static const int hook_type = HookType; + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef typename GetNodeAlgorithms::type node_algorithms; + typedef typename node_algorithms::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + static const bool is_base_hook = !detail::is_same::value; + enum { safemode_or_autounlink = + (int)link_mode == (int)auto_unlink || + (int)link_mode == (int)safe_link }; + }; + /// @endcond + + generic_hook() + { + if(boost_intrusive_tags::safemode_or_autounlink){ + boost_intrusive_tags::node_algorithms::init + (static_cast(this)); + } + } + + generic_hook(const generic_hook& ) + { + if(boost_intrusive_tags::safemode_or_autounlink){ + boost_intrusive_tags::node_algorithms::init + (static_cast(this)); + } + } + + generic_hook& operator=(const generic_hook& ) + { return *this; } + + ~generic_hook() + { + destructor_impl + (*this, detail::link_dispatch()); + } + + void swap_nodes(generic_hook &other) + { + boost_intrusive_tags::node_algorithms::swap_nodes + ( static_cast(this) + , static_cast(&other)); + } + + bool is_linked() const + { + //is_linked() can be only used in safe-mode or auto-unlink + BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink )); + return !boost_intrusive_tags::node_algorithms::unique + (static_cast(this)); + } + + void unlink() + { + BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink )); + boost_intrusive_tags::node_algorithms::unlink + (static_cast(this)); + boost_intrusive_tags::node_algorithms::init + (static_cast(this)); + } +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP diff --git a/thirdparty/boost/intrusive/detail/hashtable_node.hpp b/thirdparty/boost/intrusive/detail/hashtable_node.hpp new file mode 100644 index 0000000..f7501bc --- /dev/null +++ b/thirdparty/boost/intrusive/detail/hashtable_node.hpp @@ -0,0 +1,216 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP +#define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include //remove-me +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct prime_list_holder +{ + static const std::size_t prime_list[]; + static const std::size_t prime_list_size; +}; + +template +const std::size_t prime_list_holder::prime_list[] = { + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul }; + +template +const std::size_t prime_list_holder::prime_list_size + = sizeof(prime_list)/sizeof(std::size_t); + +template +struct bucket_impl : public Slist +{ + bucket_impl() + {} + + bucket_impl(const bucket_impl &) + {} + + ~bucket_impl() + { + //This bucket is still being used! + BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); + } + + bucket_impl &operator=(const bucket_impl&) + { + //This bucket is still in use! + BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); + //Slist::clear(); + return *this; + } + + static typename Slist::difference_type get_bucket_num + ( typename Slist::const_iterator it + , const bucket_impl &first_bucket + , const bucket_impl &last_bucket) + { + typename Slist::const_iterator + first(first_bucket.cend()), last(last_bucket.cend()); + + //The end node is embedded in the singly linked list: + //iterate until we reach it. + while(!(first.pointed_node() <= it.pointed_node() && + it.pointed_node() <= last.pointed_node())){ + ++it; + } + //Now get the bucket_impl from the iterator + const bucket_impl &b = static_cast + (Slist::container_from_end_iterator(it)); + + //Now just calculate the index b has in the bucket array + return &b - &first_bucket; + } +}; + +template +struct bucket_traits_impl +{ + /// @cond + typedef typename boost::pointer_to_other + < typename Slist::pointer, bucket_impl >::type bucket_ptr; + typedef typename Slist::size_type size_type; + /// @endcond + + bucket_traits_impl(bucket_ptr buckets, size_type len) + : buckets_(buckets), buckets_len_(len) + {} + + bucket_ptr bucket_begin() const + { return buckets_; } + + size_type bucket_count() const + { return buckets_len_; } + + private: + bucket_ptr buckets_; + size_type buckets_len_; +}; + +template +class hashtable_iterator + : public std::iterator + < std::forward_iterator_tag + , typename detail::add_const_if_c + ::type + > +{ + typedef typename Container::real_value_traits real_value_traits; + typedef typename Container::siterator siterator; + typedef typename Container::const_siterator const_siterator; + typedef typename Container::bucket_type bucket_type; + typedef typename boost::pointer_to_other + < typename Container::pointer, const Container>::type const_cont_ptr; + typedef typename Container::size_type size_type; + + public: + typedef typename detail::add_const_if_c + ::type value_type; + + hashtable_iterator () + {} + + explicit hashtable_iterator(siterator ptr, const Container *cont) + : slist_it_ (ptr), cont_ (cont) + {} + + hashtable_iterator(const hashtable_iterator &other) + : slist_it_(other.slist_it()), cont_(other.get_container()) + {} + + const siterator &slist_it() const + { return slist_it_; } + + public: + hashtable_iterator& operator++() + { this->increment(); return *this; } + + hashtable_iterator operator++(int) + { + hashtable_iterator result (*this); + this->increment(); + return result; + } + + friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2) + { return i.slist_it_ == i2.slist_it_; } + + friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2) + { return !(i == i2); } + + value_type& operator*() const + { return *this->operator ->(); } + + value_type* operator->() const + { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(slist_it_.pointed_node())); } + + const Container *get_container() const + { return detail::get_pointer(cont_); } + + const real_value_traits *get_real_value_traits() const + { return &this->get_container()->get_real_value_traits(); } + + private: + void increment() + { + const Container *cont = detail::get_pointer(cont_); + bucket_type* buckets = detail::get_pointer(cont->bucket_pointer()); + size_type buckets_len = cont->bucket_count(); + const_siterator first(buckets[0].cend()); + const_siterator last (buckets[buckets_len].cend()); + + ++slist_it_; + if(first.pointed_node() <= slist_it_.pointed_node() && + slist_it_.pointed_node()<= last.pointed_node() ){ + size_type n_bucket = (size_type) + bucket_type::get_bucket_num(slist_it_, buckets[0], buckets[buckets_len]); + do{ + if (++n_bucket == buckets_len){ + slist_it_ = buckets->end(); + break; + } + slist_it_ = buckets[n_bucket].begin(); + } + while (slist_it_ == buckets[n_bucket].end()); + } + } + + siterator slist_it_; + const_cont_ptr cont_; +}; + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif diff --git a/thirdparty/boost/intrusive/detail/list_node.hpp b/thirdparty/boost/intrusive/detail/list_node.hpp new file mode 100644 index 0000000..3d6b2be --- /dev/null +++ b/thirdparty/boost/intrusive/detail/list_node.hpp @@ -0,0 +1,185 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LIST_NODE_HPP +#define BOOST_INTRUSIVE_LIST_NODE_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +// list_node_traits can be used with circular_list_algorithms and supplies +// a list_node holding the pointers needed for a double-linked list +// it is used by list_derived_node and list_member_node + +template +struct list_node +{ + typedef typename boost::pointer_to_other + ::type node_ptr; + node_ptr prev_, next_; +}; + +template +struct list_node_traits +{ + typedef list_node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + static node_ptr get_previous(const_node_ptr n) + { return n->prev_; } + + static void set_previous(node_ptr n, node_ptr prev) + { n->prev_ = prev; } + + static node_ptr get_next(const_node_ptr n) + { return n->next_; } + + static void set_next(node_ptr n, node_ptr next) + { n->next_ = next; } +}; + +// list_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class list_iterator + : public std::iterator + < std::bidirectional_iterator_tag + , typename detail::add_const_if_c + ::type + > +{ + protected: + typedef typename Container::real_value_traits real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename boost::pointer_to_other + ::type void_pointer; + static const bool store_container_ptr = + detail::store_cont_ptr_on_it::value; + + public: + typedef typename detail::add_const_if_c + + ::type value_type; + typedef value_type & reference; + typedef value_type * pointer; + + list_iterator() + : members_ (0, 0) + {} + + explicit list_iterator(node_ptr node, const Container *cont_ptr) + : members_ (node, cont_ptr) + {} + + list_iterator(list_iterator const& other) + : members_(other.pointed_node(), other.get_container()) + {} + + const node_ptr &pointed_node() const + { return members_.nodeptr_; } + + list_iterator &operator=(const node_ptr &node) + { members_.nodeptr_ = node; return static_cast(*this); } + + public: + list_iterator& operator++() + { + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return static_cast (*this); + } + + list_iterator operator++(int) + { + list_iterator result (*this); + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return result; + } + + list_iterator& operator--() + { + members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); + return static_cast (*this); + } + + list_iterator operator--(int) + { + list_iterator result (*this); + members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); + return result; + } + + bool operator== (const list_iterator& i) const + { return members_.nodeptr_ == i.pointed_node(); } + + bool operator!= (const list_iterator& i) const + { return !operator== (i); } + + value_type& operator*() const + { return *operator->(); } + + pointer operator->() const + { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + + const Container *get_container() const + { + if(store_container_ptr){ + const Container* c = static_cast(members_.get_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(c != 0); + return c; + } + else{ + return 0; + } + } + + const real_value_traits *get_real_value_traits() const + { + if(store_container_ptr) + return &this->get_container()->get_real_value_traits(); + else + return 0; + } + + private: + struct members + : public detail::select_constptr + ::type + { + typedef typename detail::select_constptr + ::type Base; + + members(const node_ptr &n_ptr, const void *cont) + : Base(cont), nodeptr_(n_ptr) + {} + + node_ptr nodeptr_; + } members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LIST_NODE_HPP diff --git a/thirdparty/boost/intrusive/detail/mpl.hpp b/thirdparty/boost/intrusive/detail/mpl.hpp new file mode 100644 index 0000000..579a44b --- /dev/null +++ b/thirdparty/boost/intrusive/detail/mpl.hpp @@ -0,0 +1,297 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP +#define BOOST_INTRUSIVE_DETAIL_MPL_HPP + +namespace boost { +namespace intrusive { +namespace detail { + +typedef char one; +struct two {one _[2];}; + +template< bool C_ > +struct bool_ +{ + static const bool value = C_; +}; + +typedef bool_ true_; +typedef bool_ false_; + +typedef true_ true_type; +typedef false_ false_type; + +typedef char yes_type; +struct no_type +{ + char padding[8]; +}; + +template +struct enable_if_c { + typedef T type; +}; + +template +struct enable_if_c {}; + +template +struct enable_if : public enable_if_c{}; + +template +class is_convertible +{ + typedef char true_t; + class false_t { char dummy[2]; }; + static true_t dispatch(U); + static false_t dispatch(...); + static T trigger(); + public: + static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); +}; + +template< + bool C + , typename T1 + , typename T2 + > +struct if_c +{ + typedef T1 type; +}; + +template< + typename T1 + , typename T2 + > +struct if_c +{ + typedef T2 type; +}; + +template< + typename C + , typename T1 + , typename T2 + > +struct if_ +{ + typedef typename if_c<0 != C::value, T1, T2>::type type; +}; + +template< + bool C + , typename F1 + , typename F2 + > +struct eval_if_c + : if_c::type +{}; + +template< + typename C + , typename T1 + , typename T2 + > +struct eval_if + : if_::type +{}; + +// identity is an extension: it is not part of the standard. +template +struct identity +{ + typedef T type; +}; + +#if defined(BOOST_MSVC) || defined(__BORLANDC_) +#define BOOST_INTRUSIVE_TT_DECL __cdecl +#else +#define BOOST_INTRUSIVE_TT_DECL +#endif + +#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) +#define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +#endif + +no_type BOOST_INTRUSIVE_TT_DECL is_function_ptr_tester(...); + +template +yes_type is_function_ptr_tester(R (*)()); + +template +yes_type is_function_ptr_tester(R (*)( ...)); + +#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)()); +template +yes_type is_function_ptr_tester(R (__stdcall*)( ...)); + +template +yes_type is_function_ptr_tester(R (__fastcall*)()); +template +yes_type is_function_ptr_tester(R (__fastcall*)( ...)); + +template +yes_type is_function_ptr_tester(R (__cdecl*)()); +template +yes_type is_function_ptr_tester(R (__cdecl*)( ...)); +#endif + +template +yes_type is_function_ptr_tester(R (*)( T0)); + +template +yes_type is_function_ptr_tester(R (*)( T0 ...)); + +#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0)); +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 ...)); + +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0)); +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 ...)); + +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1)); + +#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1)); + +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1)); + +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1)); +#endif + +template +struct is_unary_or_binary_function_impl +{ + static T* t; + static const bool value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type); +}; + +template +struct is_unary_or_binary_function_impl +{ + static const bool value = false; +}; + +template +struct is_unary_or_binary_function +{ + static const bool value = is_unary_or_binary_function_impl::value; +}; + +//boost::alignment_of yields to 10K lines of preprocessed code, so we +//need an alternative +template struct alignment_of; + +template +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; + +template +struct alignment_logic +{ + static const std::size_t value = A < S ? A : S; +}; + +template< typename T > +struct alignment_of +{ + static const std::size_t value = alignment_logic + < sizeof(alignment_of_hack) - sizeof(T) + , sizeof(T) + >::value; +}; + +template +struct is_same +{ + typedef char yes_type; + struct no_type + { + char padding[8]; + }; + + template + static yes_type is_same_tester(V*, V*); + static no_type is_same_tester(...); + + static T *t; + static U *u; + + static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); +}; + +template +struct add_const +{ typedef const T type; }; + +template +struct remove_const +{ typedef T type; }; + +template +struct remove_const +{ typedef T type; }; + +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +template +class is_empty_class +{ + template + struct empty_helper_t1 : public T + { + empty_helper_t1(); + int i[256]; + }; + + struct empty_helper_t2 + { int i[256]; }; + + public: + static const bool value = sizeof(empty_helper_t1) == sizeof(empty_helper_t2); +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP diff --git a/thirdparty/boost/intrusive/detail/no_exceptions_support.hpp b/thirdparty/boost/intrusive/detail/no_exceptions_support.hpp new file mode 100644 index 0000000..1789bff --- /dev/null +++ b/thirdparty/boost/intrusive/detail/no_exceptions_support.hpp @@ -0,0 +1,28 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP + +#if !(defined BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING) +# include +# define BOOST_INTRUSIVE_TRY BOOST_TRY +# define BOOST_INTRUSIVE_CATCH(x) BOOST_CATCH(x) +# define BOOST_INTRUSIVE_RETHROW BOOST_RETHROW +# define BOOST_INTRUSIVE_CATCH_END BOOST_CATCH_END +#else +# define BOOST_INTRUSIVE_TRY { if (true) +# define BOOST_INTRUSIVE_CATCH(x) else if (false) +# define BOOST_INTRUSIVE_RETHROW +# define BOOST_INTRUSIVE_CATCH_END } +#endif + +#endif //#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP diff --git a/thirdparty/boost/intrusive/detail/parent_from_member.hpp b/thirdparty/boost/intrusive/detail/parent_from_member.hpp new file mode 100644 index 0000000..8068c97 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/parent_from_member.hpp @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +inline std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) +{ + //BOOST_STATIC_ASSERT(( sizeof(std::ptrdiff_t) == sizeof(ptr_to_member) )); + //The implementation of a pointer to member is compiler dependent. + #if defined(BOOST_MSVC) || (defined (BOOST_WINDOWS) && defined(BOOST_INTEL)) + //This works with gcc, msvc, ac++, ibmcpp + return *(const std::ptrdiff_t*)(void*)&ptr_to_member; + #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || defined (__IBMCPP__) || defined (__DECCXX) + const Parent * const parent = 0; + const char *const member = reinterpret_cast(&(parent->*ptr_to_member)); + return std::size_t(member - reinterpret_cast(parent)); + #else + //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC + return (*(const std::ptrdiff_t*)(void*)&ptr_to_member) - 1; + #endif +} + +template +inline Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) +{ + return (Parent*)((char*)member - + offset_from_pointer_to_member(ptr_to_member)); +} + +template +inline const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +{ + return (const Parent*)((const char*)member - + offset_from_pointer_to_member(ptr_to_member)); +} + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP diff --git a/thirdparty/boost/intrusive/detail/pointer_to_other.hpp b/thirdparty/boost/intrusive/detail/pointer_to_other.hpp new file mode 100644 index 0000000..4d4dfa3 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/pointer_to_other.hpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_POINTER_TO_OTHER_HPP +#define BOOST_INTRUSIVE_POINTER_TO_OTHER_HPP + +#include +#include + +#if (BOOST_VERSION < 103400) + +#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED +#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED + +namespace boost { + +template + struct pointer_to_other; + +template class Sp> + struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template class Sp> + struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template class Sp> +struct pointer_to_other< Sp, U > +{ + typedef Sp type; +}; + +template +struct pointer_to_other< T*, U > +{ + typedef U* type; +}; + +} // namespace boost + +#endif + +#else + +#include + +#endif //#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED + +#include + +#endif //#ifndef BOOST_INTRUSIVE_POINTER_TO_OTHER_HPP diff --git a/thirdparty/boost/intrusive/detail/rbtree_node.hpp b/thirdparty/boost/intrusive/detail/rbtree_node.hpp new file mode 100644 index 0000000..fad58df --- /dev/null +++ b/thirdparty/boost/intrusive/detail/rbtree_node.hpp @@ -0,0 +1,177 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_RBTREE_NODE_HPP +#define BOOST_INTRUSIVE_RBTREE_NODE_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +///////////////////////////////////////////////////////////////////////////// +// // +// Generic node_traits for any pointer type // +// // +///////////////////////////////////////////////////////////////////////////// + +//This is the compact representation: 3 pointers +template +struct compact_rbtree_node +{ + typedef typename pointer_to_other + >::type node_ptr; + enum color { red_t, black_t }; + node_ptr parent_, left_, right_; +}; + +//This is the normal representation: 3 pointers + enum +template +struct rbtree_node +{ + typedef typename pointer_to_other + >::type node_ptr; + + enum color { red_t, black_t }; + node_ptr parent_, left_, right_; + color color_; +}; + +//This is the default node traits implementation +//using a node with 3 generic pointers plus an enum +template +struct default_rbtree_node_traits_impl +{ + typedef rbtree_node node; + + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + typedef typename node::color color; + + static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + static void set_parent(node_ptr n, node_ptr p) + { n->parent_ = p; } + + static node_ptr get_left(const_node_ptr n) + { return n->left_; } + + static void set_left(node_ptr n, node_ptr l) + { n->left_ = l; } + + static node_ptr get_right(const_node_ptr n) + { return n->right_; } + + static void set_right(node_ptr n, node_ptr r) + { n->right_ = r; } + + static color get_color(const_node_ptr n) + { return n->color_; } + + static void set_color(node_ptr n, color c) + { n->color_ = c; } + + static color black() + { return node::black_t; } + + static color red() + { return node::red_t; } +}; + +//This is the compact node traits implementation +//using a node with 3 generic pointers +template +struct compact_rbtree_node_traits_impl +{ + typedef compact_rbtree_node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + typedef pointer_plus_bit ptr_bit; + + typedef typename node::color color; + + static node_ptr get_parent(const_node_ptr n) + { return ptr_bit::get_pointer(n->parent_); } + + static void set_parent(node_ptr n, node_ptr p) + { ptr_bit::set_pointer(n->parent_, p); } + + static node_ptr get_left(const_node_ptr n) + { return n->left_; } + + static void set_left(node_ptr n, node_ptr l) + { n->left_ = l; } + + static node_ptr get_right(const_node_ptr n) + { return n->right_; } + + static void set_right(node_ptr n, node_ptr r) + { n->right_ = r; } + + static color get_color(const_node_ptr n) + { return (color)ptr_bit::get_bit(n->parent_); } + + static void set_color(node_ptr n, color c) + { ptr_bit::set_bit(n->parent_, c != 0); } + + static color black() + { return node::black_t; } + + static color red() + { return node::red_t; } +}; + +//Dispatches the implementation based on the boolean +template +struct rbtree_node_traits_dispatch + : public default_rbtree_node_traits_impl +{}; + +template +struct rbtree_node_traits_dispatch + : public compact_rbtree_node_traits_impl +{}; + +//Inherit from the detail::link_dispatch depending on the embedding capabilities +template +struct rbtree_node_traits + : public rbtree_node_traits_dispatch + < VoidPointer + , OptimizeSize && + has_pointer_plus_bit + < VoidPointer + , detail::alignment_of >::value + >::value + > +{}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_RBTREE_NODE_HPP diff --git a/thirdparty/boost/intrusive/detail/slist_node.hpp b/thirdparty/boost/intrusive/detail/slist_node.hpp new file mode 100644 index 0000000..7b5b402 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/slist_node.hpp @@ -0,0 +1,161 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SLIST_NODE_HPP +#define BOOST_INTRUSIVE_SLIST_NODE_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct slist_node +{ + typedef typename boost::pointer_to_other + ::type node_ptr; + node_ptr next_; +}; + +// slist_node_traits can be used with circular_slist_algorithms and supplies +// a slist_node holding the pointers needed for a singly-linked list +// it is used by slist_base_hook and slist_member_hook +template +struct slist_node_traits +{ + typedef slist_node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + static node_ptr get_next(const_node_ptr n) + { return n->next_; } + + static void set_next(node_ptr n, node_ptr next) + { n->next_ = next; } +}; + +// slist_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class slist_iterator + : public std::iterator + < std::forward_iterator_tag + , typename detail::add_const_if_c + ::type + > +{ + protected: + typedef typename Container::real_value_traits real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename boost::pointer_to_other + ::type void_pointer; + static const bool store_container_ptr = + detail::store_cont_ptr_on_it::value; + + public: + typedef typename detail::add_const_if_c + + ::type value_type; + typedef value_type & reference; + typedef value_type * pointer; + + slist_iterator() + : members_ (0, 0) + {} + + explicit slist_iterator(node_ptr node, const Container *cont_ptr) + : members_ (node, cont_ptr) + {} + + slist_iterator(slist_iterator const& other) + : members_(other.pointed_node(), other.get_container()) + {} + + const node_ptr &pointed_node() const + { return members_.nodeptr_; } + + slist_iterator &operator=(const node_ptr &node) + { members_.nodeptr_ = node; return static_cast(*this); } + + public: + slist_iterator& operator++() + { + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return static_cast (*this); + } + + slist_iterator operator++(int) + { + slist_iterator result (*this); + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return result; + } + + bool operator== (const slist_iterator& i) const + { return members_.nodeptr_ == i.pointed_node(); } + + bool operator!= (const slist_iterator& i) const + { return !operator== (i); } + + value_type& operator*() const + { return *operator->(); } + + pointer operator->() const + { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + + const Container *get_container() const + { + if(store_container_ptr) + return static_cast(members_.get_ptr()); + else + return 0; + } + + const real_value_traits *get_real_value_traits() const + { + if(store_container_ptr) + return &this->get_container()->get_real_value_traits(); + else + return 0; + } + + private: + struct members + : public detail::select_constptr + ::type + { + typedef typename detail::select_constptr + ::type Base; + + members(const node_ptr &n_ptr, const void *cont) + : Base(cont), nodeptr_(n_ptr) + {} + + node_ptr nodeptr_; + } members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_NODE_HPP diff --git a/thirdparty/boost/intrusive/detail/transform_iterator.hpp b/thirdparty/boost/intrusive/detail/transform_iterator.hpp new file mode 100644 index 0000000..35ba419 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/transform_iterator.hpp @@ -0,0 +1,173 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(const PseudoReference &px) + : m_value(px) + {} + + PseudoReference* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + mutable PseudoReference m_value; +}; + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(T &px) + : m_value(px) + {} + + T* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 +// operator T*() const { return &m_value; } + mutable T &m_value; +}; + +template +class transform_iterator + : public std::iterator + < typename Iterator::iterator_category + , typename detail::remove_reference::type + , typename Iterator::difference_type + , operator_arrow_proxy + , typename UnaryFunction::result_type> +{ + public: + explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) + : members_(it, f) + {} + + explicit transform_iterator() + : members_() + {} + + Iterator get_it() const + { return members_.m_it; } + + //Constructors + transform_iterator& operator++() + { increment(); return *this; } + + transform_iterator operator++(int) + { + transform_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const transform_iterator& i, const transform_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) + { return !(i == i2); } + +/* + friend bool operator> (const transform_iterator& i, const transform_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const transform_iterator& i, const transform_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) + { return !(i < i2); } +*/ + friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + transform_iterator& operator+=(typename Iterator::difference_type off) + { this->advance(off); return *this; } + + transform_iterator operator+(typename Iterator::difference_type off) const + { + transform_iterator other(*this); + other.advance(off); + return other; + } + + friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) + { return right + off; } + + transform_iterator& operator-=(typename Iterator::difference_type off) + { this->advance(-off); return *this; } + + transform_iterator operator-(typename Iterator::difference_type off) const + { return *this + (-off); } + + typename UnaryFunction::result_type operator*() const + { return dereference(); } + + operator_arrow_proxy + operator->() const + { return operator_arrow_proxy(dereference()); } + + private: + struct members + : UnaryFunction + { + members(const Iterator &it, const UnaryFunction &f) + : UnaryFunction(f), m_it(it) + {} + + members() + {} + + Iterator m_it; + } members_; + + + void increment() + { ++members_.m_it; } + + void decrement() + { --members_.m_it; } + + bool equal(const transform_iterator &other) const + { return members_.m_it == other.members_.m_it; } + + bool less(const transform_iterator &other) const + { return other.members_.m_it < members_.m_it; } + + typename UnaryFunction::result_type dereference() const + { return members_(*members_.m_it); } + + void advance(typename Iterator::difference_type n) + { std::advance(members_.m_it, n); } + + typename Iterator::difference_type distance_to(const transform_iterator &other)const + { return std::distance(other.members_.m_it, members_.m_it); } +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP diff --git a/thirdparty/boost/intrusive/detail/tree_algorithms.hpp b/thirdparty/boost/intrusive/detail/tree_algorithms.hpp new file mode 100644 index 0000000..48003de --- /dev/null +++ b/thirdparty/boost/intrusive/detail/tree_algorithms.hpp @@ -0,0 +1,1581 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +//! This is an implementation of a binary search tree. +//! A node in the search tree has references to its children and its parent. This +//! is to allow traversal of the whole tree from a given node making the +//! implementation of iterator a pointer to a node. +//! At the top of the tree a node is used specially. This node's parent pointer +//! is pointing to the root of the tree. Its left pointer points to the +//! leftmost node in the tree and the right pointer to the rightmost one. +//! This node is used to represent the end-iterator. +//! +//! +---------+ +//! header------------------------------>| | +//! | | +//! +----------(left)--------| |--------(right)---------+ +//! | +---------+ | +//! | | | +//! | | (parent) | +//! | | | +//! | | | +//! | +---------+ | +//! root of tree ..|......................> | | | +//! | | D | | +//! | | | | +//! | +-------+---------+-------+ | +//! | | | | +//! | | | | +//! | | | | +//! | | | | +//! | | | | +//! | +---------+ +---------+ | +//! | | | | | | +//! | | B | | F | | +//! | | | | | | +//! | +--+---------+--+ +--+---------+--+ | +//! | | | | | | +//! | | | | | | +//! | | | | | | +//! | +---+-----+ +-----+---+ +---+-----+ +-----+---+ | +//! +-->| | | | | | | |<--+ +//! | A | | C | | E | | G | +//! | | | | | | | | +//! +---------+ +---------+ +---------+ +---------+ +//! + +//! tree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +template +class tree_algorithms +{ + /// @cond + private: + typedef typename NodeTraits::node node; + /// @endcond + + public: + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + + //! This type is the information that will be filled by insert_unique_check + struct insert_commit_data + { + insert_commit_data() + : link_left(false) + , node(0) + {} + bool link_left; + node_ptr node; + }; + + struct nop_erase_fixup + { + void operator()(node_ptr, node_ptr){} + }; + + /// @cond + private: + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + } + /// @endcond + + public: + static node_ptr begin_node(const_node_ptr header) + { return node_traits::get_left(header); } + + static node_ptr end_node(const_node_ptr header) + { return uncast(header); } + + //! Requires: node is a node of the tree or an node initialized + //! by init(...) or init_node. + //! + //! Effects: Returns true if the node is initialized by init() or init_node(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + static bool unique(const_node_ptr node) + { return NodeTraits::get_parent(node) == 0; } + + static node_ptr get_header(const_node_ptr node) + { + node_ptr h = uncast(node); + if(NodeTraits::get_parent(node)){ + h = NodeTraits::get_parent(node); + while(!is_header(h)) + h = NodeTraits::get_parent(h); + } + return h; + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) + { + if(node1 == node2) + return; + + node_ptr header1(get_header(node1)), header2(get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + { + if(node1 == node2) + return; + + //node1 and node2 must not be header nodes + //BOOST_INTRUSIVE_INVARIANT_ASSERT((header1 != node1 && header2 != node2)); + if(header1 != header2){ + //Update header1 if necessary + if(node1 == NodeTraits::get_left(header1)){ + NodeTraits::set_left(header1, node2); + } + + if(node1 == NodeTraits::get_right(header1)){ + NodeTraits::set_right(header1, node2); + } + + if(node1 == NodeTraits::get_parent(header1)){ + NodeTraits::set_parent(header1, node2); + } + + //Update header2 if necessary + if(node2 == NodeTraits::get_left(header2)){ + NodeTraits::set_left(header2, node1); + } + + if(node2 == NodeTraits::get_right(header2)){ + NodeTraits::set_right(header2, node1); + } + + if(node2 == NodeTraits::get_parent(header2)){ + NodeTraits::set_parent(header2, node1); + } + } + else{ + //If both nodes are from the same tree + //Update header if necessary + if(node1 == NodeTraits::get_left(header1)){ + NodeTraits::set_left(header1, node2); + } + else if(node2 == NodeTraits::get_left(header2)){ + NodeTraits::set_left(header2, node1); + } + + if(node1 == NodeTraits::get_right(header1)){ + NodeTraits::set_right(header1, node2); + } + else if(node2 == NodeTraits::get_right(header2)){ + NodeTraits::set_right(header2, node1); + } + + if(node1 == NodeTraits::get_parent(header1)){ + NodeTraits::set_parent(header1, node2); + } + else if(node2 == NodeTraits::get_parent(header2)){ + NodeTraits::set_parent(header2, node1); + } + + //Adjust data in nodes to be swapped + //so that final link swap works as expected + if(node1 == NodeTraits::get_parent(node2)){ + NodeTraits::set_parent(node2, node2); + + if(node2 == NodeTraits::get_right(node1)){ + NodeTraits::set_right(node1, node1); + } + else{ + NodeTraits::set_left(node1, node1); + } + } + else if(node2 == NodeTraits::get_parent(node1)){ + NodeTraits::set_parent(node1, node1); + + if(node1 == NodeTraits::get_right(node2)){ + NodeTraits::set_right(node2, node2); + } + else{ + NodeTraits::set_left(node2, node2); + } + } + } + + //Now swap all the links + node_ptr temp; + //swap left link + temp = NodeTraits::get_left(node1); + NodeTraits::set_left(node1, NodeTraits::get_left(node2)); + NodeTraits::set_left(node2, temp); + //swap right link + temp = NodeTraits::get_right(node1); + NodeTraits::set_right(node1, NodeTraits::get_right(node2)); + NodeTraits::set_right(node2, temp); + //swap parent link + temp = NodeTraits::get_parent(node1); + NodeTraits::set_parent(node1, NodeTraits::get_parent(node2)); + NodeTraits::set_parent(node2, temp); + + //Now adjust adjacent nodes for newly inserted node 1 + if((temp = NodeTraits::get_left(node1))){ + NodeTraits::set_parent(temp, node1); + } + if((temp = NodeTraits::get_right(node1))){ + NodeTraits::set_parent(temp, node1); + } + if((temp = NodeTraits::get_parent(node1)) && + //The header has been already updated so avoid it + temp != header2){ + if(NodeTraits::get_left(temp) == node2){ + NodeTraits::set_left(temp, node1); + } + if(NodeTraits::get_right(temp) == node2){ + NodeTraits::set_right(temp, node1); + } + } + //Now adjust adjacent nodes for newly inserted node 2 + if((temp = NodeTraits::get_left(node2))){ + NodeTraits::set_parent(temp, node2); + } + if((temp = NodeTraits::get_right(node2))){ + NodeTraits::set_parent(temp, node2); + } + if((temp = NodeTraits::get_parent(node2)) && + //The header has been already updated so avoid it + temp != header1){ + if(NodeTraits::get_left(temp) == node1){ + NodeTraits::set_left(temp, node2); + } + if(NodeTraits::get_right(temp) == node1){ + NodeTraits::set_right(temp, node2); + } + } + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing and comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + + //Update header if necessary + if(node_to_be_replaced == NodeTraits::get_left(header)){ + NodeTraits::set_left(header, new_node); + } + + if(node_to_be_replaced == NodeTraits::get_right(header)){ + NodeTraits::set_right(header, new_node); + } + + if(node_to_be_replaced == NodeTraits::get_parent(header)){ + NodeTraits::set_parent(header, new_node); + } + + //Now set data from the original node + node_ptr temp; + NodeTraits::set_left(new_node, NodeTraits::get_left(node_to_be_replaced)); + NodeTraits::set_right(new_node, NodeTraits::get_right(node_to_be_replaced)); + NodeTraits::set_parent(new_node, NodeTraits::get_parent(node_to_be_replaced)); + + //Now adjust adjacent nodes for newly inserted node + if((temp = NodeTraits::get_left(new_node))){ + NodeTraits::set_parent(temp, new_node); + } + if((temp = NodeTraits::get_right(new_node))){ + NodeTraits::set_parent(temp, new_node); + } + if((temp = NodeTraits::get_parent(new_node)) && + //The header has been already updated so avoid it + temp != header){ + if(NodeTraits::get_left(temp) == node_to_be_replaced){ + NodeTraits::set_left(temp, new_node); + } + if(NodeTraits::get_right(temp) == node_to_be_replaced){ + NodeTraits::set_right(temp, new_node); + } + } + } + + //! Requires: p is a node from the tree except the header. + //! + //! Effects: Returns the next node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr next_node(node_ptr p) + { + node_ptr p_right(NodeTraits::get_right(p)); + if(p_right){ + return minimum(p_right); + } + else { + node_ptr x = NodeTraits::get_parent(p); + while(p == NodeTraits::get_right(x)){ + p = x; + x = NodeTraits::get_parent(x); + } + return NodeTraits::get_right(p) != x ? x : uncast(p); + } + } + + //! Requires: p is a node from the tree except the leftmost node. + //! + //! Effects: Returns the previous node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr prev_node(node_ptr p) + { + if(is_header(p)){ + return maximum(NodeTraits::get_parent(p)); + } + else if(NodeTraits::get_left(p)){ + return maximum(NodeTraits::get_left(p)); + } + else { + node_ptr x = NodeTraits::get_parent(p); + while(p == NodeTraits::get_left(x)){ + p = x; + x = NodeTraits::get_parent(x); + } + return x; + } + } + + //! Requires: p is a node of a tree but not the header. + //! + //! Effects: Returns the minimum node of the subtree starting at p. + //! + //! Complexity: Logarithmic to the size of the subtree. + //! + //! Throws: Nothing. + static node_ptr minimum (node_ptr p) + { + for(node_ptr p_left = NodeTraits::get_left(p) + ;p_left + ;p_left = NodeTraits::get_left(p)){ + p = p_left; + } + return p; + } + + //! Requires: p is a node of a tree but not the header. + //! + //! Effects: Returns the maximum node of the subtree starting at p. + //! + //! Complexity: Logarithmic to the size of the subtree. + //! + //! Throws: Nothing. + static node_ptr maximum(node_ptr p) + { + for(node_ptr p_right = NodeTraits::get_right(p) + ;p_right + ;p_right = NodeTraits::get_right(p)){ + p = p_right; + } + return p; + } + + //! Requires: node must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr node) + { + NodeTraits::set_parent(node, 0); + NodeTraits::set_left(node, 0); + NodeTraits::set_right(node, 0); + }; + + //! Requires: node must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) + { + NodeTraits::set_parent(header, 0); + NodeTraits::set_left(header, header); + NodeTraits::set_right(header, header); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) + { + node_ptr source_root = NodeTraits::get_parent(header); + if(!source_root) + return; + dispose_subtree(source_root, disposer); + init_header(header); + } + + //! Requires: header is the header of a tree. + //! + //! Effects: Unlinks the leftmost node from the tree, and + //! updates the header link to the new leftmost node. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + { + node_ptr leftmost = NodeTraits::get_left(header); + if (leftmost == header) + return 0; + node_ptr leftmost_parent(NodeTraits::get_parent(leftmost)); + node_ptr leftmost_right (NodeTraits::get_right(leftmost)); + bool is_root = leftmost_parent == header; + + if (leftmost_right){ + NodeTraits::set_parent(leftmost_right, leftmost_parent); + NodeTraits::set_left(header, tree_algorithms::minimum(leftmost_right)); + + if (is_root) + NodeTraits::set_parent(header, leftmost_right); + else + NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right); + } + else if (is_root){ + NodeTraits::set_parent(header, 0); + NodeTraits::set_left(header, header); + NodeTraits::set_right(header, header); + } + else{ + NodeTraits::set_left(leftmost_parent, 0); + NodeTraits::set_left(header, leftmost_parent); + } + return leftmost; + } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr subtree) + { + if(!subtree) return 0; + std::size_t count = 0; + node_ptr p = minimum(uncast(subtree)); + bool continue_looping = true; + while(continue_looping){ + ++count; + node_ptr p_right(NodeTraits::get_right(p)); + if(p_right){ + p = minimum(p_right); + } + else { + for(;;){ + node_ptr q; + if (p == subtree){ + continue_looping = false; + break; + } + q = p; + p = NodeTraits::get_parent(p); + if (NodeTraits::get_left(p) == q) + break; + } + } + } + return count; + } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) + { + node_ptr beg(begin_node(header)); + node_ptr end(end_node(header)); + std::size_t i = 0; + for(;beg != end; beg = next_node(beg)) ++i; + return i; + } + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) + { + if(header1 == header2) + return; + + node_ptr tmp; + + //Parent swap + tmp = NodeTraits::get_parent(header1); + NodeTraits::set_parent(header1, NodeTraits::get_parent(header2)); + NodeTraits::set_parent(header2, tmp); + //Left swap + tmp = NodeTraits::get_left(header1); + NodeTraits::set_left(header1, NodeTraits::get_left(header2)); + NodeTraits::set_left(header2, tmp); + //Right swap + tmp = NodeTraits::get_right(header1); + NodeTraits::set_right(header1, NodeTraits::get_right(header2)); + NodeTraits::set_right(header2, tmp); + + //Now test parent + node_ptr h1_parent(NodeTraits::get_parent(header1)); + if(h1_parent){ + NodeTraits::set_parent(h1_parent, header1); + } + else{ + NodeTraits::set_left(header1, header1); + NodeTraits::set_right(header1, header1); + } + + node_ptr h2_parent(NodeTraits::get_parent(header2)); + if(h2_parent){ + NodeTraits::set_parent(h2_parent, header2); + } + else{ + NodeTraits::set_left(header2, header2); + NodeTraits::set_right(header2, header2); + } + } + + static bool is_header(const_node_ptr p) + { +/* + node_ptr p_parent = NodeTraits::get_parent(p); + if(!p_parent) + return true; + if(!NodeTraits::get_parent(p_parent) != p) + return false; + if(NodeTraits::get_left(p) != 0){ + if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){ + is_header = true; + } + if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){ + is_header = true; + } + } +*/ + + bool is_header = false; + if(NodeTraits::get_parent(p) == p){ + is_header = true; + } + else if(NodeTraits::get_parent(NodeTraits::get_parent(p)) == p){ + if(NodeTraits::get_left(p) != 0){ + if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){ + is_header = true; + } + if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){ + is_header = true; + } + } + } + return is_header; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr end = uncast(header); + node_ptr y = lower_bound(header, key, comp); + return (y == end || comp(key, y)) ? end : y; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if they there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr y = uncast(header); + node_ptr x = NodeTraits::get_parent(header); + + while(x){ + if(comp(x, key)){ + x = NodeTraits::get_right(x); + } + else if(comp(key, x)){ + y = x; + x = NodeTraits::get_left(x); + } + else{ + node_ptr xu(x), yu(y); + y = x, x = NodeTraits::get_left(x); + xu = NodeTraits::get_right(xu); + + while(x){ + if(comp(x, key)){ + x = NodeTraits::get_right(x); + } + else { + y = x; + x = NodeTraits::get_left(x); + } + } + + while(xu){ + if(comp(key, xu)){ + yu = xu; + xu = NodeTraits::get_left(xu); + } + else { + xu = NodeTraits::get_right(xu); + } + } + return std::pair (y, yu); + } + } + return std::pair (y, y); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr y = uncast(header); + node_ptr x = NodeTraits::get_parent(header); + while(x){ + if(comp(x, key)){ + x = NodeTraits::get_right(x); + } + else { + y = x; + x = NodeTraits::get_left(x); + } + } + return y; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr y = uncast(header); + node_ptr x = NodeTraits::get_parent(header); + while(x){ + if(comp(key, x)){ + y = x; + x = NodeTraits::get_left(x); + } + else { + x = NodeTraits::get_right(x); + } + } + return y; + } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + static void insert_unique_commit + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + { + //Check if commit_data has not been initialized by a insert_unique_check call. + BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0); + link(header, new_value, commit_data.node, commit_data.link_left); + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) + { + std::size_t depth = 0; + node_ptr h(uncast(header)); + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + node_ptr prev(0); + + //Find the upper bound, cache the previous value and if we should + //store it in the left or right node + bool left_child = true; + while(x){ + ++depth; + y = x; + x = (left_child = comp(key, x)) ? + NodeTraits::get_left(x) : (prev = y, NodeTraits::get_right(x)); + } + + if(pdepth) *pdepth = depth; + + //Since we've found the upper bound there is no other value with the same key if: + // - There is no previous node + // - The previous node is less than the key + if(!prev || comp(prev, key)){ + commit_data.link_left = left_child; + commit_data.node = y; + return std::pair(node_ptr(), true); + } + //If the previous value was not less than key, it means that it's equal + //(because we've checked the upper bound) + else{ + return std::pair(prev, false); + } + } + + template + static std::pair insert_unique_check + (const_node_ptr header, node_ptr hint, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) + { + //hint must be bigger than the key + if(hint == header || comp(key, hint)){ + node_ptr prev = hint; + //The previous value should be less than the key + if(prev == NodeTraits::get_left(header) || comp((prev = prev_node(hint)), key)){ + commit_data.link_left = unique(header) || !NodeTraits::get_left(hint); + commit_data.node = commit_data.link_left ? hint : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + return std::pair(node_ptr(), true); + } + else{ + return insert_unique_check(header, key, comp, commit_data, pdepth); + } + } + //The hint was wrong, use hintless insert + else{ + return insert_unique_check(header, key, comp, commit_data, pdepth); + } + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + { + if(hint == header || !comp(hint, new_node)){ + node_ptr prev(hint); + if(hint == NodeTraits::get_left(header) || + !comp(new_node, (prev = prev_node(hint)))){ + bool link_left = unique(header) || !NodeTraits::get_left(hint); + link(header, new_node, link_left ? hint : prev, link_left); + if(pdepth) *pdepth = depth(new_node) + 1; + return new_node; + } + else{ + return insert_equal_upper_bound(header, new_node, comp, pdepth); + } + } + else{ + return insert_equal_lower_bound(header, new_node, comp, pdepth); + } + } + + //! Requires: p can't be a header node. + //! + //! Effects: Calculates the depth of a node: the depth of a + //! node is the length (number of edges) of the path from the root + //! to that node. (The root node is at depth 0.) + //! + //! Complexity: Logarithmic to the number of nodes in the tree. + //! + //! Throws: Nothing. + static std::size_t depth(const_node_ptr p) + { + std::size_t depth = 0; + node_ptr p_parent; + while(p != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(p))){ + ++depth; + p = p_parent; + } + return depth; + } + + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + { + std::size_t depth = 0; + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + + while(x){ + ++depth; + y = x; + x = comp(new_node, x) ? + NodeTraits::get_left(x) : NodeTraits::get_right(x); + } + + bool link_left = (y == h) || comp(new_node, y); + link(h, new_node, y, link_left); + if(pdepth) *pdepth = depth; + return new_node; + } + + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + { + std::size_t depth = 0; + node_ptr y(h); + node_ptr x(NodeTraits::get_parent(y)); + + while(x){ + ++depth; + y = x; + x = !comp(x, new_node) ? + NodeTraits::get_left(x) : NodeTraits::get_right(x); + } + + bool link_left = (y == h) || !comp(y, new_node); + link(h, new_node, y, link_left); + if(pdepth) *pdepth = depth; + return new_node; + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Then, duplicates the entire tree pointed by "source_header" cloning each + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! are disposed using void disposer(node_ptr). + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { + if(!unique(target_header)){ + clear_and_dispose(target_header, disposer); + } + + node_ptr leftmost, rightmost; + node_ptr new_root = clone_subtree + (source_header, target_header, cloner, disposer, leftmost, rightmost); + + //Now update header node + NodeTraits::set_parent(target_header, new_root); + NodeTraits::set_left (target_header, leftmost); + NodeTraits::set_right (target_header, rightmost); + } + + template + static node_ptr clone_subtree + ( const_node_ptr source_parent, node_ptr target_parent + , Cloner cloner, Disposer disposer + , node_ptr &leftmost_out, node_ptr &rightmost_out + ) + { + node_ptr target_sub_root = target_parent; + node_ptr source_root = NodeTraits::get_parent(source_parent); + if(!source_root){ + leftmost_out = rightmost_out = source_root; + } + else{ + //We'll calculate leftmost and rightmost nodes while iterating + node_ptr current = source_root; + node_ptr insertion_point = target_sub_root = cloner(current); + + //We'll calculate leftmost and rightmost nodes while iterating + node_ptr leftmost = target_sub_root; + node_ptr rightmost = target_sub_root; + + //First set the subroot + NodeTraits::set_left(target_sub_root, 0); + NodeTraits::set_right(target_sub_root, 0); + NodeTraits::set_parent(target_sub_root, target_parent); + + try { + while(true) { + //First clone left nodes + if( NodeTraits::get_left(current) && + !NodeTraits::get_left(insertion_point)) { + current = NodeTraits::get_left(current); + node_ptr temp = insertion_point; + //Clone and mark as leaf + insertion_point = cloner(current); + NodeTraits::set_left (insertion_point, 0); + NodeTraits::set_right (insertion_point, 0); + //Insert left + NodeTraits::set_parent(insertion_point, temp); + NodeTraits::set_left (temp, insertion_point); + //Update leftmost + if(rightmost == target_sub_root) + leftmost = insertion_point; + } + //Then clone right nodes + else if( NodeTraits::get_right(current) && + !NodeTraits::get_right(insertion_point)){ + current = NodeTraits::get_right(current); + node_ptr temp = insertion_point; + //Clone and mark as leaf + insertion_point = cloner(current); + NodeTraits::set_left (insertion_point, 0); + NodeTraits::set_right (insertion_point, 0); + //Insert right + NodeTraits::set_parent(insertion_point, temp); + NodeTraits::set_right (temp, insertion_point); + //Update rightmost + rightmost = insertion_point; + } + //If not, go up + else if(current == source_root){ + break; + } + else{ + //Branch completed, go up searching more nodes to clone + current = NodeTraits::get_parent(current); + insertion_point = NodeTraits::get_parent(insertion_point); + } + } + } + catch(...) { + dispose_subtree(target_sub_root, disposer); + throw; + } + leftmost_out = leftmost; + rightmost_out = rightmost; + } + return target_sub_root; + } + + template + static void dispose_subtree(node_ptr x, Disposer disposer) + { + node_ptr save; + while (x){ + save = NodeTraits::get_left(x); + if (save) { + // Right rotation + NodeTraits::set_left(x, NodeTraits::get_right(save)); + NodeTraits::set_right(save, x); + } + else { + save = NodeTraits::get_right(x); + init(x); + disposer(x); + } + x = save; + } + } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is a left child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_left_child(node_ptr p) + { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is a right child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_right_child (node_ptr p) + { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } + + static void replace_own (node_ptr own, node_ptr x, node_ptr header) + { + if(NodeTraits::get_parent(header) == own) + NodeTraits::set_parent(header, x); + else if(is_left_child(own)) + NodeTraits::set_left(NodeTraits::get_parent(own), x); + else + NodeTraits::set_right(NodeTraits::get_parent(own), x); + } + + static void rotate_left(node_ptr p, node_ptr header) + { + node_ptr x = NodeTraits::get_right(p); + NodeTraits::set_right(p, NodeTraits::get_left(x)); + if(NodeTraits::get_left(x) != 0) + NodeTraits::set_parent(NodeTraits::get_left(x), p); + NodeTraits::set_parent(x, NodeTraits::get_parent(p)); + replace_own (p, x, header); + NodeTraits::set_left(x, p); + NodeTraits::set_parent(p, x); + } + + static void rotate_right(node_ptr p, node_ptr header) + { + node_ptr x(NodeTraits::get_left(p)); + node_ptr x_right(NodeTraits::get_right(x)); + NodeTraits::set_left(p, x_right); + if(x_right) + NodeTraits::set_parent(x_right, p); + NodeTraits::set_parent(x, NodeTraits::get_parent(p)); + replace_own (p, x, header); + NodeTraits::set_right(x, p); + NodeTraits::set_parent(p, x); + } + + // rotate node t with left child | complexity : constant | exception : nothrow + static node_ptr rotate_left(node_ptr t) + { + node_ptr x = NodeTraits::get_right(t); + NodeTraits::set_right(t, NodeTraits::get_left(x)); + + if( NodeTraits::get_right(t) != 0 ){ + NodeTraits::set_parent(NodeTraits::get_right(t), t ); + } + NodeTraits::set_left(x, t); + NodeTraits::set_parent(t, x); + return x; + } + + // rotate node t with right child | complexity : constant | exception : nothrow + static node_ptr rotate_right(node_ptr t) + { + node_ptr x = NodeTraits::get_left(t); + NodeTraits::set_left(t, NodeTraits::get_right(x)); + if( NodeTraits::get_left(t) != 0 ){ + NodeTraits::set_parent(NodeTraits::get_left(t), t); + } + NodeTraits::set_right(x, t); + NodeTraits::set_parent(t, x); + return x; + } + + static void link(node_ptr header, node_ptr z, node_ptr par, bool left) + { + if(par == header){ + NodeTraits::set_parent(header, z); + NodeTraits::set_right(header, z); + NodeTraits::set_left(header, z); + } + else if(left){ + NodeTraits::set_left(par, z); + if(par == NodeTraits::get_left(header)) + NodeTraits::set_left(header, z); + } + else{ + NodeTraits::set_right(par, z); + if(par == NodeTraits::get_right(header)) + NodeTraits::set_right(header, z); + } + NodeTraits::set_parent(z, par); + NodeTraits::set_right(z, 0); + NodeTraits::set_left(z, 0); + } + + static void erase(node_ptr header, node_ptr z) + { + data_for_rebalance ignored; + erase(header, z, nop_erase_fixup(), ignored); + } + + struct data_for_rebalance + { + node_ptr x; + node_ptr x_parent; + node_ptr y; + }; + + template + static void erase(node_ptr header, node_ptr z, F z_and_successor_fixup, data_for_rebalance &info) + { + erase_impl(header, z, info); + if(info.y != z){ + z_and_successor_fixup(z, info.y); + } + } + + static void unlink(node_ptr node) + { + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, node); + } + } + + static void tree_to_vine(node_ptr header) + { subtree_to_vine(NodeTraits::get_parent(header)); } + + static void vine_to_tree(node_ptr header, std::size_t count) + { vine_to_subtree(NodeTraits::get_parent(header), count); } + + static void rebalance(node_ptr header) + { + //Taken from: + //"Tree rebalancing in optimal time and space" + //Quentin F. Stout and Bette L. Warren + std::size_t len; + subtree_to_vine(NodeTraits::get_parent(header), &len); + vine_to_subtree(NodeTraits::get_parent(header), len); + } + + static node_ptr rebalance_subtree(node_ptr old_root) + { + std::size_t len; + node_ptr new_root = subtree_to_vine(old_root, &len); + return vine_to_subtree(new_root, len); + } + + static node_ptr subtree_to_vine(node_ptr old_root, std::size_t *plen = 0) + { + std::size_t len; + len = 0; + if(!old_root) return 0; + + //To avoid irregularities in the algorithm (old_root can be a + //left or right child or even the root of the tree) just put the + //root as the right child of its parent. Before doing this backup + //information to restore the original relationship after + //the algorithm is applied. + node_ptr super_root = NodeTraits::get_parent(old_root); + assert(super_root); + + //Get info + node_ptr super_root_right_backup = NodeTraits::get_right(super_root); + bool super_root_is_header = is_header(super_root); + bool old_root_is_right = is_right_child(old_root); + + node_ptr x(old_root); + node_ptr new_root(x); + node_ptr save; + bool moved_to_right = false; + for( ; x; x = save){ + save = NodeTraits::get_left(x); + if(save){ + // Right rotation + node_ptr save_right = NodeTraits::get_right(save); + node_ptr x_parent = NodeTraits::get_parent(x); + NodeTraits::set_parent(save, x_parent); + NodeTraits::set_right (x_parent, save); + NodeTraits::set_parent(x, save); + NodeTraits::set_right (save, x); + NodeTraits::set_left(x, save_right); + if(save_right) + NodeTraits::set_parent(save_right, x); + if(!moved_to_right) + new_root = save; + } + else{ + moved_to_right = true; + save = NodeTraits::get_right(x); + ++len; + } + } + + if(super_root_is_header){ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_parent(super_root, new_root); + } + else if(old_root_is_right){ + NodeTraits::set_right(super_root, new_root); + } + else{ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_left(super_root, new_root); + } + if(plen) *plen = len; + return new_root; + } + + static node_ptr vine_to_subtree(node_ptr old_root, std::size_t count) + { + std::size_t leaf_nodes = count + 1 - ((size_t) 1 << floor_log2 (count + 1)); + std::size_t vine_nodes = count - leaf_nodes; + + node_ptr new_root = compress_subtree(old_root, leaf_nodes); + while(vine_nodes > 1){ + vine_nodes /= 2; + new_root = compress_subtree(new_root, vine_nodes); + } + return new_root; + } + + static node_ptr compress_subtree(node_ptr old_root, std::size_t count) + { + if(!old_root) return old_root; + + //To avoid irregularities in the algorithm (old_root can be + //left or right child or even the root of the tree) just put the + //root as the right child of its parent. First obtain + //information to restore the original relationship after + //the algorithm is applied. + node_ptr super_root = NodeTraits::get_parent(old_root); + assert(super_root); + + //Get info + node_ptr super_root_right_backup = NodeTraits::get_right(super_root); + bool super_root_is_header = is_header(super_root); + bool old_root_is_right = is_right_child(old_root); + + //Put old_root as right child + NodeTraits::set_right(super_root, old_root); + + //Start the compression algorithm + node_ptr even_parent = super_root; + node_ptr new_root = old_root; + + while(count--){ + node_ptr even = NodeTraits::get_right(even_parent); + node_ptr odd = NodeTraits::get_right(even); + + if(new_root == old_root) + new_root = odd; + + node_ptr even_right = NodeTraits::get_left(odd); + NodeTraits::set_right(even, even_right); + if (even_right) + NodeTraits::set_parent(even_right, even); + + NodeTraits::set_right(even_parent, odd); + NodeTraits::set_parent(odd, even_parent); + NodeTraits::set_left(odd, even); + NodeTraits::set_parent(even, odd); + even_parent = odd; + } + + if(super_root_is_header){ + NodeTraits::set_parent(super_root, new_root); + NodeTraits::set_right(super_root, super_root_right_backup); + } + else if(old_root_is_right){ + NodeTraits::set_right(super_root, new_root); + } + else{ + NodeTraits::set_left(super_root, new_root); + NodeTraits::set_right(super_root, super_root_right_backup); + } + return new_root; + } + + private: + static void erase_impl(node_ptr header, node_ptr z, data_for_rebalance &info) + { + node_ptr y(z); + node_ptr x; + node_ptr x_parent(0); + node_ptr z_left(NodeTraits::get_left(z)); + node_ptr z_right(NodeTraits::get_right(z)); + if(!z_left){ + x = z_right; // x might be null. + } + else if(!z_right){ // z has exactly one non-null child. y == z. + x = z_left; // x is not null. + } + else{ + // find z's successor + y = tree_algorithms::minimum (z_right); + x = NodeTraits::get_right(y); // x might be null. + } + + if(y != z){ + // relink y in place of z. y is z's successor + NodeTraits::set_parent(NodeTraits::get_left(z), y); + NodeTraits::set_left(y, NodeTraits::get_left(z)); + if(y != NodeTraits::get_right(z)){ + x_parent = NodeTraits::get_parent(y); + if(x) + NodeTraits::set_parent(x, x_parent); + NodeTraits::set_left(x_parent, x); // y must be a child of left_ + NodeTraits::set_right(y, NodeTraits::get_right(z)); + NodeTraits::set_parent(NodeTraits::get_right(z), y); + } + else + x_parent = y; + tree_algorithms::replace_own (z, y, header); + NodeTraits::set_parent(y, NodeTraits::get_parent(z)); + } + else { // y == z --> z has only one child, or none + x_parent = NodeTraits::get_parent(z); + if(x) + NodeTraits::set_parent(x, x_parent); + tree_algorithms::replace_own (z, x, header); + if(NodeTraits::get_left(header) == z){ + NodeTraits::set_left(header, NodeTraits::get_right(z) == 0 ? // z->get_left() must be null also + NodeTraits::get_parent(z) : // makes leftmost == header if z == root + tree_algorithms::minimum (x)); + } + if(NodeTraits::get_right(header) == z){ + NodeTraits::set_right(header, NodeTraits::get_left(z) == 0 ? // z->get_right() must be null also + NodeTraits::get_parent(z) : // makes rightmost == header if z == root + tree_algorithms::maximum(x)); + } + } + + info.x = x; + info.x_parent = x_parent; + info.y = y; + } + +}; + +} //namespace detail { +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/detail/tree_node.hpp b/thirdparty/boost/intrusive/detail/tree_node.hpp new file mode 100644 index 0000000..c293086 --- /dev/null +++ b/thirdparty/boost/intrusive/detail/tree_node.hpp @@ -0,0 +1,192 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_TREE_NODE_HPP +#define BOOST_INTRUSIVE_TREE_NODE_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct tree_node +{ + typedef typename pointer_to_other + >::type node_ptr; + + node_ptr parent_, left_, right_; +}; + +template +struct tree_node_traits +{ + typedef tree_node node; + + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + static node_ptr get_parent(const_node_ptr n) + { return n->parent_; } + + static void set_parent(node_ptr n, node_ptr p) + { n->parent_ = p; } + + static node_ptr get_left(const_node_ptr n) + { return n->left_; } + + static void set_left(node_ptr n, node_ptr l) + { n->left_ = l; } + + static node_ptr get_right(const_node_ptr n) + { return n->right_; } + + static void set_right(node_ptr n, node_ptr r) + { n->right_ = r; } +}; + +///////////////////////////////////////////////////////////////////////////// +// // +// Implementation of the tree iterator // +// // +///////////////////////////////////////////////////////////////////////////// + +// tree_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class tree_iterator + : public std::iterator + < std::bidirectional_iterator_tag + , typename detail::add_const_if_c + ::type + > +{ + protected: + typedef typename Container::real_value_traits real_value_traits; + typedef typename Container::node_algorithms node_algorithms; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename boost::pointer_to_other + ::type void_pointer; + static const bool store_container_ptr = + detail::store_cont_ptr_on_it::value; + + public: + public: + typedef typename detail::add_const_if_c + + ::type value_type; + typedef value_type & reference; + typedef value_type * pointer; + + tree_iterator() + : members_ (0, 0) + {} + + explicit tree_iterator(node_ptr node, const Container *cont_ptr) + : members_ (node, cont_ptr) + {} + + tree_iterator(tree_iterator const& other) + : members_(other.pointed_node(), other.get_container()) + {} + + const node_ptr &pointed_node() const + { return members_.nodeptr_; } + + tree_iterator &operator=(const node_ptr &node) + { members_.nodeptr_ = node; return static_cast(*this); } + + public: + tree_iterator& operator++() + { + members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); + return static_cast (*this); + } + + tree_iterator operator++(int) + { + tree_iterator result (*this); + members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); + return result; + } + + tree_iterator& operator--() + { + members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); + return static_cast (*this); + } + + tree_iterator operator--(int) + { + tree_iterator result (*this); + members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); + return result; + } + + bool operator== (const tree_iterator& i) const + { return members_.nodeptr_ == i.pointed_node(); } + + bool operator!= (const tree_iterator& i) const + { return !operator== (i); } + + value_type& operator*() const + { return *operator->(); } + + pointer operator->() const + { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + + const Container *get_container() const + { + if(store_container_ptr) + return static_cast(members_.get_ptr()); + else + return 0; + } + + const real_value_traits *get_real_value_traits() const + { + if(store_container_ptr) + return &this->get_container()->get_real_value_traits(); + else + return 0; + } + + private: + struct members + : public detail::select_constptr + ::type + { + typedef typename detail::select_constptr + ::type Base; + + members(const node_ptr &n_ptr, const void *cont) + : Base(cont), nodeptr_(n_ptr) + {} + + node_ptr nodeptr_; + } members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_TREE_NODE_HPP diff --git a/thirdparty/boost/intrusive/detail/utilities.hpp b/thirdparty/boost/intrusive/detail/utilities.hpp new file mode 100644 index 0000000..c9e44ac --- /dev/null +++ b/thirdparty/boost/intrusive/detail/utilities.hpp @@ -0,0 +1,557 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP +#define BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct internal_member_value_traits +{ + template static detail::one test(...); + template static detail::two test(typename U::member_value_traits* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct internal_base_hook_bool +{ + template + struct two_or_three {one _[2 + Add];}; + template static one test(...); + template static two_or_three + test (detail::bool_* = 0); + static const std::size_t value = sizeof(test(0)); +}; + +template +struct internal_base_hook_bool_is_true +{ + static const bool value = internal_base_hook_bool::value > sizeof(one)*2; +}; + +template +struct external_value_traits_bool +{ + template + struct two_or_three {one _[2 + Add];}; + template static one test(...); + template static two_or_three + test (detail::bool_* = 0); + static const std::size_t value = sizeof(test(0)); +}; + +template +struct external_bucket_traits_bool +{ + template + struct two_or_three {one _[2 + Add];}; + template static one test(...); + template static two_or_three + test (detail::bool_* = 0); + static const std::size_t value = sizeof(test(0)); +}; + +template +struct external_value_traits_is_true +{ + static const bool value = external_value_traits_bool::value > sizeof(one)*2; +}; + +template +struct node_holder + : public Node +{}; + +template +struct smart_ptr_type +{ + typedef typename SmartPtr::value_type value_type; + typedef value_type *pointer; + static pointer get (const SmartPtr &smartptr) + { return smartptr.get();} +}; + +template +struct smart_ptr_type +{ + typedef T value_type; + typedef value_type *pointer; + static pointer get (pointer ptr) + { return ptr;} +}; + +//!Overload for smart pointers to avoid ADL problems with get_pointer +template +inline typename smart_ptr_type::pointer +get_pointer(const Ptr &ptr) +{ return smart_ptr_type::get(ptr); } + +//This functor compares a stored value +//and the one passed as an argument +template +class equal_to_value +{ + ConstReference t_; + + public: + equal_to_value(ConstReference t) + : t_(t) + {} + + bool operator()(ConstReference t)const + { return t_ == t; } +}; + +class null_disposer +{ + public: + template + void operator()(Pointer) + {} +}; + +template +class init_disposer +{ + typedef typename NodeAlgorithms::node_ptr node_ptr; + + public: + void operator()(node_ptr p) + { NodeAlgorithms::init(p); } +}; + +template +struct size_holder +{ + static const bool constant_time_size = ConstantSize; + typedef SizeType size_type; + + SizeType get_size() const + { return size_; } + + void set_size(SizeType size) + { size_ = size; } + + void decrement() + { --size_; } + + void increment() + { ++size_; } + + SizeType size_; +}; + +template +struct size_holder +{ + static const bool constant_time_size = false; + typedef SizeType size_type; + + size_type get_size() const + { return 0; } + + void set_size(size_type) + {} + + void decrement() + {} + + void increment() + {} +}; + +template +struct key_nodeptr_comp + : private detail::ebo_functor_holder +{ + typedef typename Container::real_value_traits real_value_traits; + typedef typename real_value_traits::node_ptr node_ptr; + typedef detail::ebo_functor_holder base_t; + key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont) + : base_t(kcomp), cont_(cont) + {} + + template + bool operator()(node_ptr node, const KeyType &key) const + { return base_t::get()(*cont_->get_real_value_traits().to_value_ptr(node), key); } + + template + bool operator()(const KeyType &key, node_ptr node) const + { return base_t::get()(key, *cont_->get_real_value_traits().to_value_ptr(node)); } + + bool operator()(node_ptr node1, node_ptr node2) const + { + return base_t::get() + ( *cont_->get_real_value_traits().to_value_ptr(node1) + , *cont_->get_real_value_traits().to_value_ptr(node2) + ); + } + + const Container *cont_; +}; + +template +struct node_cloner + : private detail::ebo_functor_holder +{ + typedef typename Container::real_value_traits real_value_traits; + typedef typename Container::node_algorithms node_algorithms; + typedef typename real_value_traits::value_type value_type; + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::node_traits::node node; + typedef typename real_value_traits::node_ptr node_ptr; + typedef typename real_value_traits::const_node_ptr const_node_ptr; + typedef detail::ebo_functor_holder base_t; + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + node_cloner(F f, const Container *cont) + : base_t(f), cont_(cont) + {} + + node_ptr operator()(node_ptr p) + { + node_ptr n = cont_->get_real_value_traits().to_node_ptr + (*base_t::get()(*cont_->get_real_value_traits().to_value_ptr(p))); + //Cloned node must be in default mode if the linking mode requires it + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + return n; + } + + node_ptr operator()(const node &to_clone) + { + const value_type &v = + *cont_->get_real_value_traits().to_value_ptr(const_node_ptr(&to_clone)); + node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v)); + //Cloned node must be in default mode if the linking mode requires it + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + return n; + } + + const Container *cont_; +}; + +template +struct node_disposer + : private detail::ebo_functor_holder +{ + typedef typename Container::real_value_traits real_value_traits; + typedef typename real_value_traits::node_ptr node_ptr; + typedef detail::ebo_functor_holder base_t; + typedef typename Container::node_algorithms node_algorithms; + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + node_disposer(F f, const Container *cont) + : base_t(f), cont_(cont) + {} + + void operator()(node_ptr p) + { + if(safemode_or_autounlink) + node_algorithms::init(p); + base_t::get()(cont_->get_real_value_traits().to_value_ptr(p)); + } + const Container *cont_; +}; + +struct dummy_constptr +{ + dummy_constptr(const void *) + {} + + const void *get_ptr() const + { return 0; } +}; + +template +struct constptr +{ + typedef typename boost::pointer_to_other + ::type ConstVoidPtr; + + constptr(const void *ptr) + : const_void_ptr_(ptr) + {} + + const void *get_ptr() const + { return detail::get_pointer(const_void_ptr_); } + + ConstVoidPtr const_void_ptr_; +}; + +template +struct select_constptr +{ + typedef typename detail::if_c + < store_ptr + , constptr + , dummy_constptr + >::type type; +}; + +template +struct store_cont_ptr_on_it +{ + typedef typename Container::value_traits value_traits; + static const bool value = + !detail::is_empty_class::value + || detail::external_value_traits_is_true::value + ; +}; + +template +struct add_const_if_c +{ + typedef typename detail::if_c + < Add + , typename detail::add_const::type + , T + >::type type; +}; + +template +struct node_to_value + : public detail::select_constptr + < typename boost::pointer_to_other + ::type + , detail::store_cont_ptr_on_it::value + >::type +{ + static const bool store_container_ptr = + detail::store_cont_ptr_on_it::value; + + typedef typename Container::real_value_traits real_value_traits; + typedef typename real_value_traits::value_type value_type; + typedef typename detail::select_constptr + < typename boost::pointer_to_other + ::type + , store_container_ptr >::type Base; + typedef typename real_value_traits::node_traits::node node; + typedef typename detail::add_const_if_c + ::type vtype; + typedef typename detail::add_const_if_c + ::type ntype; + typedef typename boost::pointer_to_other + ::type npointer; + + node_to_value(const Container *cont) + : Base(cont) + {} + + typedef vtype & result_type; + typedef ntype & first_argument_type; + + const Container *get_container() const + { + if(store_container_ptr) + return static_cast(Base::get_ptr()); + else + return 0; + } + + const real_value_traits *get_real_value_traits() const + { + if(store_container_ptr) + return &this->get_container()->get_real_value_traits(); + else + return 0; + } + + result_type operator()(first_argument_type arg) const + { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); } +}; + +template +struct link_dispatch +{}; + +template +void destructor_impl(Container &cont, detail::link_dispatch) +{ (void)cont; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!cont.is_linked()); } + +template +void destructor_impl(Container &cont, detail::link_dispatch) +{ cont.unlink(); } + +template +void destructor_impl(Container &, detail::link_dispatch) +{} + +template +struct base_hook_traits +{ + public: + typedef detail::node_holder + node_holder; + typedef NodeTraits node_traits; + typedef T value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename boost::pointer_to_other::type pointer; + typedef typename boost::pointer_to_other::type const_pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + static const link_mode_type link_mode = LinkMode; + + static node_ptr to_node_ptr(reference value) + { return static_cast(&value); } + + static const_node_ptr to_node_ptr(const_reference value) + { return static_cast(&value); } + + static pointer to_value_ptr(node_ptr n) + { return static_cast(static_cast(&*n)); } + + static const_pointer to_value_ptr(const_node_ptr n) + { return static_cast(static_cast(&*n)); } +}; + +template +struct member_hook_traits +{ + public: + typedef Hook hook_type; + typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; + typedef typename node_traits::node node; + typedef T value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename boost::pointer_to_other::type pointer; + typedef typename boost::pointer_to_other::type const_pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode; + + static node_ptr to_node_ptr(reference value) + { + return reinterpret_cast(&(value.*P)); + } + + static const_node_ptr to_node_ptr(const_reference value) + { + return static_cast(&(value.*P)); + } + + static pointer to_value_ptr(node_ptr n) + { + return detail::parent_from_member + (static_cast(detail::get_pointer(n)), P); + } + + static const_pointer to_value_ptr(const_node_ptr n) + { + return detail::parent_from_member + (static_cast(detail::get_pointer(n)), P); + } +}; + +//This function uses binary search to discover the +//highest set bit of the integer +inline std::size_t floor_log2 (std::size_t x) +{ + const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; + const bool Size_t_Bits_Power_2= !(Bits & (Bits-1)); + BOOST_STATIC_ASSERT(Size_t_Bits_Power_2); + + std::size_t n = x; + std::size_t log2 = 0; + + for(std::size_t shift = Bits >> 1; shift; shift >>= 1){ + std::size_t tmp = n >> shift; + if (tmp) + log2 += shift, n = tmp; + } + + return log2; +} + +inline float fast_log2 (float val) +{ + boost::uint32_t * exp_ptr = + static_cast(static_cast(&val)); + boost::uint32_t x = *exp_ptr; + const int log_2 = (int)(((x >> 23) & 255) - 128); + x &= ~(255 << 23); + x += 127 << 23; + *exp_ptr = x; + + val = ((-1.0f/3) * val + 2) * val - 2.0f/3; + + return (val + log_2); +} + +inline std::size_t ceil_log2 (std::size_t x) +{ + return ((x & (x-1))!= 0) + floor_log2(x); +} + +template +struct numbits_eq +{ + static const bool value = sizeof(SizeType)*CHAR_BIT == N; +}; + +template +struct sqrt2_pow_max; + +template +struct sqrt2_pow_max >::type> +{ + static const boost::uint32_t value = 0xb504f334; + static const std::size_t pow = 31; +}; + +template +struct sqrt2_pow_max >::type> +{ + static const boost::uint64_t value = 0xb504f333f9de6484ull; + static const std::size_t pow = 63; +}; + +// Returns floor(pow(sqrt(2), x * 2 + 1)). +// Defined for X from 0 up to the number of bits in size_t minus 1. +inline std::size_t sqrt2_pow_2xplus1 (std::size_t x) +{ + const std::size_t value = (std::size_t)sqrt2_pow_max::value; + const std::size_t pow = (std::size_t)sqrt2_pow_max::pow; + return (value >> (pow - x)) + 1; +} + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP diff --git a/thirdparty/boost/intrusive/hashtable.hpp b/thirdparty/boost/intrusive/hashtable.hpp new file mode 100644 index 0000000..047c1af --- /dev/null +++ b/thirdparty/boost/intrusive/hashtable.hpp @@ -0,0 +1,1979 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_HASHTABLE_HPP +#define BOOST_INTRUSIVE_HASHTABLE_HPP + +#include +//std C++ +#include +#include +#include +#include +//boost +#include +#include +#include +#include +//General intrusive utilities +#include +#include +#include +#include +#include +#include +//Implementation utilities +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +namespace detail{ + +template +struct store_hash_bool +{ + template + struct two_or_three {one _[2 + Add];}; + template static one test(...); + template static two_or_three + test (detail::bool_* = 0); + static const std::size_t value = sizeof(test(0)); +}; + +template +struct store_hash_is_true +{ + static const bool value = store_hash_bool::value > sizeof(one)*2; +}; + +template +struct bucket_plus_size + : public detail::size_holder + < Config::constant_time_size + , typename Config::size_type> +{ + typedef detail::size_holder + < Config::constant_time_size + , typename Config::size_type> size_traits; + typedef typename Config::bucket_traits bucket_traits; + + bucket_plus_size(const bucket_traits &b_traits) + : bucket_traits_(b_traits) + {} + bucket_traits bucket_traits_; +}; + +template +struct bucket_hash_t : public detail::ebo_functor_holder +{ + typedef typename Config::hash hasher; + typedef detail::size_holder + < Config::constant_time_size + , typename Config::size_type> size_traits; + typedef typename Config::bucket_traits bucket_traits; + + bucket_hash_t(const bucket_traits &b_traits, const hasher & h) + : detail::ebo_functor_holder(h), bucket_plus_size_(b_traits) + {} + + bucket_plus_size bucket_plus_size_; +}; + +template +struct bucket_hash_equal_t : public detail::ebo_functor_holder +{ + typedef typename Config::equal equal; + typedef typename Config::hash hasher; + typedef typename Config::bucket_traits bucket_traits; + + bucket_hash_equal_t(const bucket_traits &b_traits, const hasher & h, const equal &e) + : detail::ebo_functor_holder(e), bucket_hash(b_traits, h) + {} + bucket_hash_t bucket_hash; +}; + +template +struct data_t : public Config::value_traits +{ + typedef typename Config::value_traits value_traits; + typedef typename Config::equal equal; + typedef typename Config::hash hasher; + typedef typename Config::bucket_traits bucket_traits; + + data_t( const bucket_traits &b_traits, const hasher & h + , const equal &e, const value_traits &val_traits) + : Config::value_traits(val_traits), bucket_hash_equal_(b_traits, h, e) + {} + bucket_hash_equal_t bucket_hash_equal_; +}; + +} //namespace detail { + +template +struct internal_default_uset_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_uset_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_uset_hook +{ + typedef typename T::default_uset_hook type; +}; + +template < class ValueTraits + , class Hash + , class Equal + , class SizeType + , bool ConstantTimeSize + , class BucketTraits + , bool Power2Buckets + > +struct usetopt +{ + typedef ValueTraits value_traits; + typedef Hash hash; + typedef Equal equal; + typedef SizeType size_type; + typedef BucketTraits bucket_traits; + static const bool constant_time_size = ConstantTimeSize; + static const bool power_2_buckets = Power2Buckets; +}; + +struct default_bucket_traits; + +template +struct uset_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_uset_hook::value + , get_default_uset_hook + , detail::identity + >::type + > + , constant_time_size + , size_type + , equal > + , hash > + , bucket_traits + , power_2_buckets + >::type +{}; + +template +struct get_slist_impl +{ + typedef trivial_value_traits trivial_traits; + + //Reducing symbol length + struct type : make_slist + < typename NodeTraits::node + , boost::intrusive::value_traits + , boost::intrusive::constant_time_size + , boost::intrusive::size_type + >::type + {}; +}; + +/// @endcond + +template +struct unordered_bucket +{ + /// @cond + typedef typename ValueTraitsOrHookOption:: + template pack::value_traits supposed_value_traits; + + typedef typename detail::eval_if_c + < detail::external_value_traits_is_true + ::value + , detail::eval_value_traits + + , detail::identity + + >::type real_value_traits; + + typedef typename detail::get_node_traits + ::type node_traits; + typedef typename get_slist_impl + ::type slist_impl; + typedef detail::bucket_impl implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +template +struct unordered_bucket_ptr +{ + /// @cond + typedef typename ValueTraitsOrHookOption:: + template pack::value_traits supposed_value_traits; + typedef typename detail::eval_if_c + < detail::external_value_traits_is_true + ::value + , detail::eval_value_traits + + , detail::identity + + >::type real_value_traits; + typedef typename detail::get_node_traits + ::type::node_ptr node_ptr; + typedef typename unordered_bucket + ::type bucket_type; + typedef typename boost::pointer_to_other + ::type implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! The class template hashtable is an intrusive hash table container, that +//! is used to construct intrusive unordered_set and unordered_multiset containers. The +//! no-throw guarantee holds only, if the Equal object and Hasher don't throw. +//! +//! hashtable is a pseudo-intrusive container: each object to be stored in the +//! container must contain a proper hook, but the container also needs +//! additional auxiliary memory to work: hashtable needs a pointer to an array +//! of type `bucket_type` to be passed in the constructor. This bucket array must +//! have at least the same lifetime as the container. This makes the use of +//! hashtable more complicated than purely intrusive containers. +//! `bucket_type` is default-constructible, copyable and assignable +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> . +//! +//! hashtable only provides forward iterators but it provides 4 iterator types: +//! iterator and const_iterator to navigate through the whole container and +//! local_iterator and const_local_iterator to navigate through the values +//! stored in a single bucket. Local iterators are faster and smaller. +//! +//! It's not recommended to use non constant-time size hashtables because several +//! key functions, like "empty()", become non-constant time functions. Non +//! constant_time size hashtables are mainly provided to support auto-unlink hooks. +//! +//! hashtables, does not make automatic rehashings nor +//! offers functions related to a load factor. Rehashing can be explicitly requested +//! and the user must provide a new bucket array that will be used from that moment. +//! +//! Since no automatic rehashing is done, iterators are never invalidated when +//! inserting or erasing elements. Iterators are only invalidated when rehashing. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class hashtable_impl + : private detail::data_t +{ + public: + typedef typename Config::value_traits value_traits; + + /// @cond + + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + typedef typename Config::bucket_traits bucket_traits; + static const bool external_bucket_traits = + detail::external_bucket_traits_is_true::value; + typedef typename detail::eval_if_c + < external_bucket_traits + , detail::eval_bucket_traits + , detail::identity + >::type real_bucket_traits; + typedef typename get_slist_impl + ::type slist_impl; + /// @endcond + + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef value_type key_type; + typedef typename Config::equal key_equal; + typedef typename Config::hash hasher; + typedef detail::bucket_impl bucket_type; + typedef typename boost::pointer_to_other + ::type bucket_ptr; + typedef typename slist_impl::iterator siterator; + typedef typename slist_impl::const_iterator const_siterator; + typedef detail::hashtable_iterator iterator; + typedef detail::hashtable_iterator const_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef typename slist_impl::node_algorithms node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + static const bool store_hash = detail::store_hash_is_true::value; + + /// @cond + private: + typedef detail::bool_ store_hash_t; + typedef detail::size_holder size_traits; + typedef detail::data_t base_type; + typedef detail::transform_iterator + < typename slist_impl::iterator + , detail::node_to_value > local_iterator_impl; + typedef detail::transform_iterator + < typename slist_impl::iterator + , detail::node_to_value > const_local_iterator_impl; + + //noncopyable + hashtable_impl (const hashtable_impl&); + hashtable_impl operator =(const hashtable_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + static const bool power_2_buckets = Config::power_2_buckets; + + std::size_t from_hash_to_bucket(std::size_t hash_value) const + { return from_hash_to_bucket(hash_value, detail::bool_()); } + + std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_) const + { return hash_value % this->get_real_bucket_traits().bucket_count(); } + + std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_) const + { return hash_value & (this->get_real_bucket_traits().bucket_count() - 1); } + + const key_equal &priv_equal() const + { return static_cast(this->bucket_hash_equal_.get()); } + + key_equal &priv_equal() + { return static_cast(this->bucket_hash_equal_.get()); } + + const real_bucket_traits &get_real_bucket_traits(detail::bool_) const + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; } + + const real_bucket_traits &get_real_bucket_traits(detail::bool_) const + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); } + + real_bucket_traits &get_real_bucket_traits(detail::bool_) + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; } + + real_bucket_traits &get_real_bucket_traits(detail::bool_) + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); } + + const real_bucket_traits &get_real_bucket_traits() const + { return this->get_real_bucket_traits(detail::bool_()); } + + real_bucket_traits &get_real_bucket_traits() + { return this->get_real_bucket_traits(detail::bool_()); } + + const hasher &priv_hasher() const + { return static_cast(this->bucket_hash_equal_.bucket_hash.get()); } + + hasher &priv_hasher() + { return static_cast(this->bucket_hash_equal_.bucket_hash.get()); } + + bucket_ptr priv_buckets() const + { return this->get_real_bucket_traits().bucket_begin(); } + + size_type priv_buckets_len() const + { return this->get_real_bucket_traits().bucket_count(); } + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(detail::get_pointer(ptr))); + } + + node &from_value_to_node(value_type &v) + { return *this->get_real_value_traits().to_node_ptr(v); } + + const node &from_value_to_node(const value_type &v) const + { return *this->get_real_value_traits().to_node_ptr(v); } + + size_traits &priv_size_traits() + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; } + + const size_traits &priv_size_traits() const + { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; } + + struct insert_commit_data_impl + { + size_type hash; + }; + /// @endcond + + public: + + class local_iterator + : public local_iterator_impl + { + public: + local_iterator() + {} + + local_iterator(siterator sit, const hashtable_impl *cont) + : local_iterator_impl(sit, cont) + {} + }; + + class const_local_iterator + : public const_local_iterator_impl + { + public: + const_local_iterator() + {} + + const_local_iterator(siterator sit, const hashtable_impl *cont) + : const_local_iterator_impl(sit, cont) + {} + }; + + typedef insert_commit_data_impl insert_commit_data; + + /// @cond + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return *this; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return base_type::get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return *this; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return base_type::get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + //! Requires: buckets must not be being used by any other resource. + //! + //! Effects: Constructs an empty unordered_set, storing a reference + //! to the bucket array and copies of the key_hasher and equal_func functors. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of hash_func or equal_func throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + hashtable_impl ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : base_type(b_traits, hash_func, equal_func, v_traits) + { + priv_clear_buckets(); + this->priv_size_traits().set_size(size_type(0)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_buckets_len() != 0); + //Check power of two bucket array if the option is activated + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (this->priv_buckets_len() & (this->priv_buckets_len()-1)))); + } + + //! Effects: Detaches all elements from this. The objects in the unordered_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements in the unordered_set, if + //! it's a safe-mode or auto-unlink value. Otherwise constant. + //! + //! Throws: Nothing. + ~hashtable_impl() + { this->clear(); } + + //! Effects: Returns an iterator pointing to the beginning of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + iterator begin() + { + size_type bucket_num; + return iterator(this->priv_begin(bucket_num), this); + } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator begin() const + { return this->cbegin(); } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator cbegin() const + { + size_type bucket_num; + return const_iterator(this->priv_begin(bucket_num), this); + } + + //! Effects: Returns an iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return iterator(invalid_local_it(this->get_real_bucket_traits()), 0); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return this->cend(); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return const_iterator(invalid_local_it(this->get_real_bucket_traits()), 0); } + + //! Effects: Returns the hasher object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If hasher copy-constructor throws. + hasher hash_function() const + { return this->priv_hasher(); } + + //! Effects: Returns the key_equal object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_equal copy-constructor throws. + key_equal key_eq() const + { return this->priv_equal(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: if constant_time_size is false, average constant time + //! (worst case, with empty() == true): O(this->bucket_count()). + //! Otherwise constant. + //! + //! Throws: Nothing. + bool empty() const + { + if(constant_time_size){ + return !this->size(); + } + else{ + size_type buckets_len = this->priv_buckets_len(); + const bucket_type *b = detail::get_pointer(this->priv_buckets()); + for (size_type n = 0; n < buckets_len; ++n, ++b){ + if(!b->empty()){ + return false; + } + } + return true; + } + } + + //! Effects: Returns the number of elements stored in the unordered_set. + //! + //! Complexity: Linear to elements contained in *this if + //! constant_time_size is false. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else{ + size_type len = 0; + size_type buckets_len = this->priv_buckets_len(); + const bucket_type *b = detail::get_pointer(this->priv_buckets()); + for (size_type n = 0; n < buckets_len; ++n, ++b){ + len += b->size(); + } + return len; + } + } + + //! Requires: the hasher and the equality function unqualified swap + //! call should not throw. + //! + //! Effects: Swaps the contents of two unordered_sets. + //! Swaps also the contained bucket array and equality and hasher functors. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison or hash functors + //! found using ADL throw. Basic guarantee. + void swap(hashtable_impl& other) + { + using std::swap; + //These can throw + swap(this->priv_equal(), other.priv_equal()); + swap(this->priv_hasher(), other.priv_hasher()); + //These can't throw + swap(this->get_real_bucket_traits(), other.get_real_bucket_traits()); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!constant_time_size || !src.empty()){ + const size_type src_bucket_count = src.bucket_count(); + const size_type dst_bucket_count = this->bucket_count(); + //Check power of two bucket array if the option is activated + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1)))); + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1)))); + + //If src bucket count is bigger or equal, structural copy is possible + if(src_bucket_count >= dst_bucket_count){ + //First clone the first ones + const bucket_ptr src_buckets = src.priv_buckets(); + const bucket_ptr dst_buckets = this->priv_buckets(); + size_type constructed; + BOOST_INTRUSIVE_TRY{ + for( constructed = 0 + ; constructed < dst_bucket_count + ; ++constructed){ + dst_buckets[constructed].clone_from + ( src_buckets[constructed] + , detail::node_cloner(cloner, this) + , detail::node_disposer(disposer, this) + ); + } + if(src_bucket_count != dst_bucket_count){ + //Now insert the remaining ones using the modulo trick + for(//"constructed" comes from the previous loop + ; constructed < src_bucket_count + ; ++constructed){ + bucket_type &dst_b = (power_2_buckets) + ? dst_buckets[constructed & (dst_bucket_count-1)] + : dst_buckets[constructed % dst_bucket_count]; + bucket_type &src_b = src_buckets[constructed]; + for( siterator b(src_b.begin()), e(src_b.end()) + ; b != e + ; ++b){ + dst_b.push_front(*detail::node_cloner + (cloner, this)(b.pointed_node())); + } + } + } + } + BOOST_INTRUSIVE_CATCH(...){ + while(constructed--){ + dst_buckets[constructed].clear_and_dispose + (detail::node_disposer(disposer, this)); + } + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + this->priv_size_traits().set_size(src.priv_size_traits().get_size()); + } + else{ + //Unlike previous cloning algorithm, this can throw + //if cloner, the hasher or comparison functor throw + const_iterator b(src.begin()), e(src.end()); + BOOST_INTRUSIVE_TRY{ + for(; b != e; ++b){ + this->insert_equal(*cloner(*b)); + } + } + BOOST_INTRUSIVE_CATCH(...){ + this->clear_and_dispose(disposer); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + } + } + } + + iterator insert_equal(reference value) + { + size_type bucket_num, hash_value; + siterator it = this->priv_find + (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value); + bucket_type &b = this->priv_buckets()[bucket_num]; + if(it == invalid_local_it(this->get_real_bucket_traits())){ + it = b.before_begin(); + } + node_ptr n = node_ptr(&from_value_to_node(value)); + this->priv_store_hash(n, hash_value, store_hash_t()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + this->priv_size_traits().increment(); + return iterator(b.insert_after(it, *n), this); + } + + template + void insert_equal(Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert_equal(*b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the unordered_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = this->insert_unique_check + (value, this->priv_hasher(), this->priv_equal(), commit_data); + if(!ret.second) + return ret; + return std::pair + (this->insert_unique_commit(value, commit_data), true); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Equivalent to this->insert(t) for each element in [b, e). + //! + //! Complexity: Average case O(N), where N is std::distance(b, e). + //! Worst case O(N*this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert_unique(*b); + } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the unordered_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the hash or the equality is much cheaper to + //! construct than the value_type and this function offers the possibility to + //! use that the part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the unordered_set. + //! + //! After a successful rehashing insert_commit_data remains valid. + template + std::pair insert_unique_check + ( const KeyType &key + , KeyHasher hash_func + , KeyValueEqual equal_func + , insert_commit_data &commit_data) + { + size_type bucket_num; + siterator prev_pos = + this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash); + bool success = prev_pos == invalid_local_it(this->get_real_bucket_traits()); + if(success){ + prev_pos = this->priv_buckets()[bucket_num].before_begin(); + } + return std::pair(iterator(prev_pos, this),success); + } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the unordered_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the unordered_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + //! + //! After a successful rehashing insert_commit_data remains valid. + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + size_type bucket_num = from_hash_to_bucket(commit_data.hash); + bucket_type &b = this->priv_buckets()[bucket_num]; + this->priv_size_traits().increment(); + node_ptr n = node_ptr(&from_value_to_node(value)); + this->priv_store_hash(n, commit_data.hash, store_hash_t()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + return iterator( b.insert_after(b.before_begin(), *n), this); + } + + //! Effects: Erases the element pointed to by i. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased element. No destructors are called. + void erase(const_iterator i) + { this->erase_and_dispose(i, detail::null_disposer()); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void erase(const_iterator b, const_iterator e) + { this->erase_and_dispose(b, e, detail::null_disposer()); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Erases all the elements that have the same hash and + //! compare equal with the given key. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return this->erase_and_dispose(key, hash_func, equal_func, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by i. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + void erase_and_dispose(const_iterator i, Disposer disposer) + { + siterator to_erase(i.slist_it()); + bucket_ptr f(priv_buckets()), l(f + priv_buckets_len()); + bucket_type &b = this->priv_buckets()[bucket_type::get_bucket_num(to_erase, *f, *l)]; + b.erase_after_and_dispose + (b.previous(to_erase), detail::node_disposer(disposer, this)); + this->priv_size_traits().decrement(); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { + if(b == e) return; + + //Get the bucket number and local iterator for both iterators + bucket_ptr f(priv_buckets()), l(f + priv_buckets_len()); + size_type first_bucket_num = bucket_type::get_bucket_num(b.slist_it(), *f, *l); + + siterator before_first_local_it + = priv_buckets()[first_bucket_num].previous(b.slist_it()); + size_type last_bucket_num; + siterator last_local_it; + + //For the end iterator, we will assign the end iterator + //of the last bucket + if(e == end()){ + last_bucket_num = this->bucket_count() - 1; + last_local_it = priv_buckets()[last_bucket_num].end(); + } + else{ + last_local_it = e.slist_it(); + last_bucket_num = bucket_type::get_bucket_num(last_local_it, *f, *l); + } + + const bucket_ptr buckets = priv_buckets(); + //First erase the nodes of the first bucket + { + bucket_type &first_b = buckets[first_bucket_num]; + siterator nxt(before_first_local_it); ++nxt; + siterator end = first_b.end(); + while(nxt != end){ + nxt = first_b.erase_after_and_dispose + ( before_first_local_it + , detail::node_disposer(disposer, this)); + this->priv_size_traits().decrement(); + } + } + + //Now fully clear the intermediate buckets + for(size_type i = first_bucket_num+1; i < last_bucket_num; ++i){ + bucket_type &b = buckets[i]; + if(b.empty()) + continue; + siterator b_begin(b.before_begin()); + siterator nxt(b_begin); ++nxt; + siterator end = b.end(); + while(nxt != end){ + nxt = b.erase_after_and_dispose + (b_begin, detail::node_disposer(disposer, this)); + this->priv_size_traits().decrement(); + } + } + + //Now erase nodes from the last bucket + { + bucket_type &last_b = buckets[last_bucket_num]; + siterator b_begin(last_b.before_begin()); + siterator nxt(b_begin); ++nxt; + while(nxt != last_local_it){ + nxt = last_b.erase_after_and_dispose + (b_begin, detail::node_disposer + (disposer, this)); + this->priv_size_traits().decrement(); + } + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return this->erase_and_dispose(value, priv_hasher(), priv_equal(), disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "equal_func". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func + ,KeyValueEqual equal_func, Disposer disposer) + { + size_type count(0); + + if(constant_time_size && this->empty()){ + return 0; + } + + bucket_type &b = this->priv_buckets()[from_hash_to_bucket(hash_func(key))]; + siterator it = b.begin(); + siterator prev = b.before_begin(); + + bool found = false; + //Find equal value + while(it != b.end()){ + const value_type &v = + *this->get_real_value_traits().to_value_ptr(it.pointed_node()); + if(equal_func(key, v)){ + found = true; + break; + } + ++prev; + ++it; + } + + if(!found) + return 0; + + //If found erase all equal values + for(siterator end = b.end(); it != end && + equal_func(key, *this->get_real_value_traits().to_value_ptr(it.pointed_node())) + ; ++count){ + it = b.erase_after_and_dispose + (prev, detail::node_disposer(disposer, this)); + this->priv_size_traits().decrement(); + } + return count; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + priv_clear_buckets(); + this->priv_size_traits().set_size(size_type(0)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { + if(!constant_time_size || !this->empty()){ + size_type num_buckets = this->bucket_count(); + bucket_ptr b = this->priv_buckets(); + for(; num_buckets--; ++b){ + b->clear_and_dispose + (detail::node_disposer(disposer, this)); + } + this->priv_size_traits().set_size(size_type(0)); + } + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + size_type count(const_reference value) const + { return this->count(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal throw. + template + size_type count(const KeyType &key, const KeyHasher &hash_func, const KeyValueEqual &equal_func) const + { + size_type bucket_n1, bucket_n2, count; + this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, count); + return count; + } + + //! Effects: Finds an iterator to the first element is equal to + //! "value" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + iterator find(const_reference value) + { return this->find(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hash and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) + { + size_type bucket_n, hash; + siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash); + return iterator(local_it, this); + } + + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + const_iterator find(const_reference value) const + { return this->find(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find + (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const + { + size_type bucket_n, hash_value; + siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash_value); + return const_iterator(sit, this); + } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair equal_range(const_reference value) + { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or the equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range + (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) + { + size_type bucket_n1, bucket_n2, count; + std::pair ret = this->priv_equal_range + (key, hash_func, equal_func, bucket_n1, bucket_n2, count); + return std::pair + (iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair + equal_range(const_reference value) const + { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If the hasher or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range + (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const + { + size_type bucket_n1, bucket_n2, count; + std::pair ret = + this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, count); + return std::pair + (const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + iterator iterator_to(reference value) + { + return iterator(bucket_type::s_iterator_to(from_value_to_node(value)), this); + } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator belonging to the + //! unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + const_iterator iterator_to(const_reference value) const + { + return const_iterator(bucket_type::s_iterator_to(from_value_to_node(const_cast(value))), this); + } + + + + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static local_iterator s_local_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(value)); + return local_iterator(sit, (hashtable_impl*)0); + } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_local_iterator s_local_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(const_cast(value))); + return const_local_iterator(sit, (hashtable_impl*)0); + } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + local_iterator local_iterator_to(reference value) + { + siterator sit = bucket_type::s_iterator_to(this->from_value_to_node(value)); + return local_iterator(sit, this); + } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_local_iterator local_iterator_to(const_reference value) const + { + siterator sit = bucket_type::s_iterator_to + (const_cast(this->from_value_to_node(value))); + return const_local_iterator(sit, this); + } + + //! Effects: Returns the number of buckets passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_count() const + { return this->priv_buckets_len(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns the number of elements in the nth bucket. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_size(size_type n) const + { return this->priv_buckets()[n].size(); } + + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If the hash functor throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + size_type bucket(const key_type& k) const + { return this->bucket(k, this->priv_hasher()); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If hash_func throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + template + size_type bucket(const KeyType& k, const KeyHasher &hash_func) const + { return from_hash_to_bucket(hash_func(k)); } + + //! Effects: Returns the bucket array pointer passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bucket_ptr bucket_pointer() const + { return this->priv_buckets(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator begin(size_type n) + { return local_iterator(this->priv_buckets()[n].begin(), this); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator begin(size_type n) const + { return this->cbegin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cbegin(size_type n) const + { + siterator sit = const_cast(this->priv_buckets()[n]).begin(); + return const_local_iterator(sit, this); + } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator end(size_type n) + { return local_iterator(this->priv_buckets()[n].end(), this); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator end(size_type n) const + { return this->cend(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cend(size_type n) const + { return const_local_iterator(const_cast(this->priv_buckets()[n]).end(), this); } + + //! Requires: new_buckets must be a pointer to a new bucket array + //! or the same as the old bucket array. new_size is the length of the + //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer() + //! n can be bigger or smaller than this->bucket_count(). + //! + //! Effects: Updates the internal reference with the new bucket erases + //! the values from the old bucket and inserts then in the new one. + //! + //! Complexity: Average case linear in this->size(), worst case quadratic. + //! + //! Throws: If the hasher functor throws. Basic guarantee. + void rehash(const bucket_traits &new_bucket_traits) + { + bucket_ptr new_buckets = new_bucket_traits.bucket_begin(); + size_type new_buckets_len = new_bucket_traits.bucket_count(); + bucket_ptr old_buckets = this->priv_buckets(); + size_type old_buckets_len = this->priv_buckets_len(); + //Check power of two bucket array if the option is activated + BOOST_INTRUSIVE_INVARIANT_ASSERT + (!power_2_buckets || (0 == (new_buckets_len & (new_buckets_len-1u)))); + + BOOST_INTRUSIVE_TRY{ + size_type n = 0; + const bool same_buffer = old_buckets == new_buckets; + //If the new bucket length is a common factor + //of the old one we can avoid hash calculations. + const bool fast_shrink = (old_buckets_len > new_buckets_len) && + (power_2_buckets ||(old_buckets_len % new_buckets_len) == 0); + //If we are shrinking the same bucket array and it's + //is a fast shrink, just rehash the last nodes + if(same_buffer && fast_shrink){ + n = new_buckets_len; + } + + //Iterate through nodes + for(; n < old_buckets_len; ++n){ + bucket_type &old_bucket = old_buckets[n]; + + if(!fast_shrink){ + siterator before_i(old_bucket.before_begin()); + siterator end(old_bucket.end()); + siterator i(old_bucket.begin()); + for(;i != end; ++i){ + const value_type &v = *this->get_real_value_traits().to_value_ptr(i.pointed_node()); + const std::size_t hash_value = this->priv_hash_when_rehashing(v, store_hash_t()); + const size_type new_n = (power_2_buckets) + ? (hash_value & (new_buckets_len-1)) : (hash_value % new_buckets_len); + //If this is a buffer expansion don't move if it's not necessary + if(same_buffer && new_n == n){ + ++before_i; + } + else{ + bucket_type &new_b = new_buckets[new_n]; + new_b.splice_after(new_b.before_begin(), old_bucket, before_i); + i = before_i; + } + } + } + else{ + const size_type new_n = (power_2_buckets) + ? (n & (new_buckets_len-1)) + : (n % new_buckets_len); + bucket_type &new_b = new_buckets[new_n]; + new_b.splice_after(new_b.before_begin(), old_bucket); + } + } + + this->get_real_bucket_traits()= new_bucket_traits; + } + BOOST_INTRUSIVE_CATCH(...){ + for(size_type n = 0; n < new_buckets_len; ++n){ + if(safemode_or_autounlink){ + new_buckets[n].clear_and_dispose + (detail::init_disposer()); + old_buckets[n].clear_and_dispose + (detail::init_disposer()); + } + else{ + new_buckets[n].clear(); + old_buckets[n].clear(); + } + } + this->priv_size_traits().set_size(size_type(0)); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is bigger than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! higher possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_upper_bucket_count(size_type n) + { + const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; + const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; + size_type const* bound = + std::lower_bound(primes, primes_end, n); + if(bound == primes_end) + bound--; + return size_type(*bound); + } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is smaller than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! lower possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_lower_bucket_count(size_type n) + { + const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; + const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; + size_type const* bound = + std::upper_bound(primes, primes_end, n); + if(bound != primes_end) + bound--; + return size_type(*bound); + } + + /// @cond + private: + + std::size_t priv_hash_when_rehashing(const value_type &v, detail::true_) + { return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); } + + std::size_t priv_hash_when_rehashing(const value_type &v, detail::false_) + { return priv_hasher()(v); } + + void priv_store_hash(node_ptr p, std::size_t h, detail::true_) + { return node_traits::set_hash(p, h); } + + void priv_store_hash(node_ptr, std::size_t, detail::false_) + {} + + static siterator invalid_local_it(const real_bucket_traits &b) + { return b.bucket_begin()->end(); } + + siterator priv_begin(size_type &bucket_num) const + { + size_type buckets_len = this->priv_buckets_len(); + for (bucket_num = 0; bucket_num < buckets_len; ++bucket_num){ + bucket_type &b = this->priv_buckets()[bucket_num]; + if(!b.empty()) + return b.begin(); + } + return invalid_local_it(this->get_real_bucket_traits()); + } + + void priv_clear_buckets() + { priv_clear_buckets(this->priv_buckets(), this->priv_buckets_len()); } + + static void priv_clear_buckets(bucket_ptr buckets_ptr, size_type buckets_len) + { + for(; buckets_len--; ++buckets_ptr){ + if(safemode_or_autounlink){ + buckets_ptr->clear_and_dispose(detail::init_disposer()); + } + else{ + buckets_ptr->clear(); + } + } + } + + template + siterator priv_find + ( const KeyType &key, KeyHasher hash_func + , KeyValueEqual equal_func, size_type &bucket_number, size_type &h) const + { + bucket_number = from_hash_to_bucket((h = hash_func(key))); + + if(constant_time_size && this->empty()){ + return invalid_local_it(this->get_real_bucket_traits()); + } + + bucket_type &b = this->priv_buckets()[bucket_number]; + siterator it = b.begin(); + + while(it != b.end()){ + const value_type &v = + *this->get_real_value_traits().to_value_ptr(it.pointed_node()); + if(equal_func(key, v)){ + return it; + } + ++it; + } + + return invalid_local_it(this->get_real_bucket_traits()); + } + + template + std::pair priv_equal_range + ( const KeyType &key + , KeyHasher hash_func + , KeyValueEqual equal_func + , size_type &bucket_number_first + , size_type &bucket_number_second + , size_type &count) const + { + size_type h; + count = 0; + //Let's see if the element is present + std::pair to_return + ( priv_find(key, hash_func, equal_func, bucket_number_first, h) + , invalid_local_it(this->get_real_bucket_traits())); + if(to_return.first == to_return.second){ + bucket_number_second = bucket_number_first; + return to_return; + } + ++count; + //If it's present, find the first that it's not equal in + //the same bucket + bucket_type &b = this->priv_buckets()[bucket_number_first]; + siterator it = to_return.first; + ++it; + + while(it != b.end()){ + const value_type &v = + *this->get_real_value_traits().to_value_ptr(it.pointed_node()); + if(!equal_func(key, v)){ + to_return.second = it; + bucket_number_second = bucket_number_first; + return to_return; + } + ++it; + ++count; + } + + //If we reached the end, find the first, non-empty bucket + for(bucket_number_second = bucket_number_first+1 + ; bucket_number_second != this->priv_buckets_len() + ; ++bucket_number_second){ + bucket_type &b = this->priv_buckets()[bucket_number_second]; + if(!b.empty()){ + to_return.second = b.begin(); + return to_return; + } + } + + //Otherwise, return the end node + to_return.second = invalid_local_it(this->get_real_bucket_traits()); + return to_return; + } + /// @endcond +}; + +/// @cond +template +struct make_hashtable_opt +{ + typedef typename pack_options + < uset_defaults, O1, O2, O3, O4, O5, O6, O7>::type packed_options; + + //Real value traits must be calculated from options + typedef typename detail::get_value_traits + ::type value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + typedef typename packed_options::bucket_traits specified_bucket_traits; + /// @endcond + //Real bucket traits must be calculated from options and calculated valute_traits + typedef typename get_slist_impl + ::type slist_impl; + typedef typename + detail::if_c< detail::is_same + < specified_bucket_traits + , default_bucket_traits + >::value + , detail::bucket_traits_impl + , specified_bucket_traits + >::type real_bucket_traits; + + typedef usetopt + < value_traits + , typename packed_options::hash + , typename packed_options::equal + , typename packed_options::size_type + , packed_options::constant_time_size + , real_bucket_traits + , packed_options::power_2_buckets + > type; +}; +/// @endcond + +//! Helper metafunction to define a \c hashtable that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_hashtable +{ + /// @cond + typedef hashtable_impl + < typename make_hashtable_opt + ::type + > implementation_defined; + + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class hashtable + : public make_hashtable::type +{ + typedef typename make_hashtable + ::type Base; + + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::bucket_ptr bucket_ptr; + typedef typename Base::size_type size_type; + typedef typename Base::hasher hasher; + typedef typename Base::bucket_traits bucket_traits; + typedef typename Base::key_equal key_equal; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + hashtable ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b_traits, hash_func, equal_func, v_traits) + {} +}; + +#endif + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_HASHTABLE_HPP diff --git a/thirdparty/boost/intrusive/intrusive_fwd.hpp b/thirdparty/boost/intrusive/intrusive_fwd.hpp new file mode 100644 index 0000000..4e4d220 --- /dev/null +++ b/thirdparty/boost/intrusive/intrusive_fwd.hpp @@ -0,0 +1,345 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_FWD_HPP +#define BOOST_INTRUSIVE_FWD_HPP + +#include +#include + +/// @cond + +//std predeclarations +namespace std{ + +template +struct equal_to; + +template +struct less; + +} //namespace std{ + +namespace boost { + +//Hash predeclaration +template +struct hash; + +namespace intrusive { + +struct none; + +} //namespace intrusive{ +} //namespace boost{ + +namespace boost { +namespace intrusive { + +//////////////////////////// +// Node algorithms +//////////////////////////// + +//Algorithms predeclarations +template +class circular_list_algorithms; + +template +class circular_slist_algorithms; + +template +class rbtree_algorithms; + +//////////////////////////// +// Containers +//////////////////////////// + +//slist +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + , class O5 = none + > +class slist; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class slist_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class slist_member_hook; + +//list +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + > +class list; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class list_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class list_member_hook; + +//rbtree/set/multiset +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class rbtree; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class set; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class multiset; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class set_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class set_member_hook; + +//splaytree/splay_set/splay_multiset +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class splaytree; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class splay_set; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class splay_multiset; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class splay_set_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class splay_set_member_hook; + +//avltree/avl_set/avl_multiset +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class avltree; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class avl_set; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class avl_multiset; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class avl_set_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class avl_set_member_hook; + +//sgtree/sg_set/sg_multiset +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class sgtree; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class sg_set; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class sg_multiset; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class bs_set_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + > +class bs_set_member_hook; + +//hash/unordered +//rbtree/set/multiset +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + , class O5 = none + , class O6 = none + , class O7 = none + > +class hashtable; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + , class O5 = none + , class O6 = none + , class O7 = none + > +class unordered_set; + +template + < class T + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + , class O5 = none + , class O6 = none + , class O7 = none + > +class unordered_multiset; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class unordered_set_base_hook; + +template + < class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + > +class unordered_set_member_hook; + +} //namespace intrusive { +} //namespace boost { + +/// @endcond + +#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP diff --git a/thirdparty/boost/intrusive/linear_slist_algorithms.hpp b/thirdparty/boost/intrusive/linear_slist_algorithms.hpp new file mode 100644 index 0000000..7e1ced9 --- /dev/null +++ b/thirdparty/boost/intrusive/linear_slist_algorithms.hpp @@ -0,0 +1,326 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! linear_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a linear singly linked list. +//! +//! linear_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the linear list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class linear_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == 0 + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node); + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node); + + //! Effects: Returns true is "this_node" has the same state as if + //! it was inited using "init(node_ptr)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool inited(const_node_ptr this_node); + + //! Requires: prev_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node); + + //! Requires: prev_node and last_node must be in a circular list + //! or be an empty circular list. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node, node_ptr last_node); + + //! Requires: prev_node must be a node of a linear list. + //! + //! Effects: Links this_node after prev_node in the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_after(node_ptr prev_node, node_ptr this_node); + + //! Requires: b and e must be nodes of the same linear list or an empty range. + //! and p must be a node of a different linear list. + //! + //! Effects: Removes the nodes from (b, e] range from their linear list and inserts + //! them after p in p's linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer_after(node_ptr p, node_ptr b, node_ptr e); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init_header(node_ptr this_node) + { NodeTraits::set_next(this_node, 0); } + + //! Requires: this_node and prev_init_node must be in the same linear list. + //! + //! Effects: Returns the previous node of this_node in the linear list starting. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! Complexity: Linear to the number of elements between prev_init_node and this_node. + //! + //! Throws: Nothing. + static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) + { return base_t::get_previous_node(prev_init_node, this_node); } + + //! Requires: this_node must be in a linear list or be an empty linear list. + //! + //! Effects: Returns the number of nodes in a linear list. If the linear list + //! is empty, returns 1. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr this_node) + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p); + return result; + } + + //! Requires: this_node and other_node must be nodes inserted + //! in linear lists or be empty linear lists. + //! + //! Effects: Moves all the nodes previously chained after this_node after other_node + //! and vice-versa. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) + { + node_ptr this_nxt = NodeTraits::get_next(this_node); + node_ptr other_nxt = NodeTraits::get_next(other_node); + NodeTraits::set_next(this_node, other_nxt); + NodeTraits::set_next(other_node, this_nxt); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Returns: The new first node of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static node_ptr reverse(node_ptr p) + { + if(!p) return 0; + node_ptr i = NodeTraits::get_next(p); + node_ptr first(p); + while(i){ + node_ptr nxti(NodeTraits::get_next(i)); + base_t::unlink_after(p); + NodeTraits::set_next(i, first); + first = i; + i = nxti; + } + return first; + } + + //! Effects: Moves the first n nodes starting at p to the end of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static std::pair move_first_n_backwards(node_ptr p, std::size_t n) + { + std::pair ret(0, 0); + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)){ + return ret; + } + + node_ptr first = p; + bool end_found = false; + node_ptr new_last(0); + node_ptr old_last(0); + + //Now find the new last node according to the shift count. + //If we find 0 before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == 0){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) return ret; + old_last = new_last; + i = 0; + //Unlink p and continue the new first node search + first = p; + //unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + old_last = base_t::get_previous_node(first, 0); + } + + //Now link p after the new last node + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, 0); + ret.first = first; + ret.second = new_last; + return ret; + } + + //! Effects: Moves the first n nodes starting at p to the beginning of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static std::pair move_first_n_forward(node_ptr p, std::size_t n) + { + std::pair ret(0, 0); + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)) + return ret; + + node_ptr first = p; + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(!!(next_to_it = node_traits::get_next(old_last))){ + if(distance++ > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) + return ret; + + for( new_last = p + ; --new_before_last_pos + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Get the first new node + node_ptr new_first(node_traits::get_next(new_last)); + //Now put the old beginning after the old end + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, 0); + ret.first = new_first; + ret.second = new_last; + return ret; + } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/link_mode.hpp b/thirdparty/boost/intrusive/link_mode.hpp new file mode 100644 index 0000000..80ff7de --- /dev/null +++ b/thirdparty/boost/intrusive/link_mode.hpp @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP +#define BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP + +namespace boost { +namespace intrusive { + +//!This enumeration defines the type of value_traits that can be defined +//!for Boost.Intrusive containers +enum link_mode_type{ + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits won't set the hooks + //!of the erased values to a default state. Containers also won't + //!check that the hooks of the new values are default initialized. + normal_link, + + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits will set the hooks + //!of the erased values to a default state. Containers also will + //!check that the hooks of the new values are default initialized. + safe_link, + + //!Same as "safe_link" but the user type is an auto-unlink + //!type, so the containers with constant-time size features won't be + //!compatible with value_traits configured with this policy. + //!Containers also know that the a value can be silently erased from + //!the container without using any function provided by the containers. + auto_unlink +}; +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP diff --git a/thirdparty/boost/intrusive/list.hpp b/thirdparty/boost/intrusive/list.hpp new file mode 100644 index 0000000..b8c7187 --- /dev/null +++ b/thirdparty/boost/intrusive/list.hpp @@ -0,0 +1,1443 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LIST_HPP +#define BOOST_INTRUSIVE_LIST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct internal_default_list_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_list_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_list_hook +{ + typedef typename T::default_list_hook type; +}; + +template +struct listopt +{ + typedef ValueTraits value_traits; + typedef SizeType size_type; + static const bool constant_time_size = ConstantTimeSize; +}; + +template +struct list_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_list_hook::value + , get_default_list_hook + , detail::identity + >::type + > + , constant_time_size + , size_type + >::type +{}; + +/// @endcond + +//! The class template list is an intrusive container that mimics most of the +//! interface of std::list as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<> and \c size_type<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class list_impl +{ + //Public typedefs + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef list_iterator iterator; + typedef list_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef circular_list_algorithms node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + + /// @cond + + private: + typedef detail::size_holder size_traits; + + //Non-copyable and non-moveable + list_impl (const list_impl&); + list_impl &operator =(const list_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && + ((int)real_value_traits::link_mode == (int)auto_unlink) + )); + + //Const cast emulation for smart pointers + static node_ptr uncast(const_node_ptr ptr) + { + //return node_ptr(detail::get_pointer(ptr))); + return const_cast(detail::get_pointer(ptr)); + } + + node_ptr get_root_node() + { return node_ptr(&data_.root_plus_size_.root_); } + + const_node_ptr get_root_node() const + { return const_node_ptr(&data_.root_plus_size_.root_); } + + struct root_plus_size : public size_traits + { + node root_; + }; + + struct data_t : public value_traits + { + typedef typename list_impl::value_traits value_traits; + data_t(const value_traits &val_traits) + : value_traits(val_traits) + {} + + root_plus_size root_plus_size_; + } data_; + + size_traits &priv_size_traits() + { return data_.root_plus_size_; } + + const size_traits &priv_size_traits() const + { return data_.root_plus_size_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + //! Effects: constructs an empty list. + //! + //! Complexity: Constant + //! + //! Throws: If real_value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + list_impl(const value_traits &v_traits = value_traits()) + : data_(v_traits) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! + //! Effects: Constructs a list equal to the range [first,last). + //! + //! Complexity: Linear in std::distance(b, e). No copy constructors are called. + //! + //! Throws: If real_value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + template + list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : data_(v_traits) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + this->insert(this->end(), b, e); + } + + //! Effects: If it's not a safe-mode or an auto-unlink value_type + //! the destructor does nothing + //! (ie. no code is generated). Otherwise it detaches all elements from this. + //! In this case the objects in the list are not deleted (i.e. no destructors + //! are called), but the hooks according to the ValueTraits template parameter + //! are set to their default value. + //! + //! Complexity: Linear to the number of elements in the list, if + //! it's a safe-mode or auto-unlink value . Otherwise constant. + ~list_impl() + { + if(safemode_or_autounlink){ + this->clear(); + } + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the back of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + void push_back(reference value) + { + node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); + node_algorithms::link_before(this->get_root_node(), to_insert); + this->priv_size_traits().increment(); + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the front of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + void push_front(reference value) + { + node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); + node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); + this->priv_size_traits().increment(); + } + + //! Effects: Erases the last element of the list. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the erased element. + void pop_back() + { return this->pop_back_and_dispose(detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the last element of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + void pop_back_and_dispose(Disposer disposer) + { + node_ptr to_erase = node_traits::get_previous(this->get_root_node()); + node_algorithms::unlink(to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + } + + //! Effects: Erases the first element of the list. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the erased element. + void pop_front() + { return this->pop_front_and_dispose(detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the first element of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + void pop_front_and_dispose(Disposer disposer) + { + node_ptr to_erase = node_traits::get_next(this->get_root_node()); + node_algorithms::unlink(to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + } + + //! Effects: Returns a reference to the first element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() + { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } + + //! Effects: Returns a const_reference to the first element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const + { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); } + + //! Effects: Returns a reference to the last element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference back() + { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } + + //! Effects: Returns a const_reference to the last element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference back() const + { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_previous(this->get_root_node()))); } + + //! Effects: Returns an iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return iterator(node_traits::get_next(this->get_root_node()), this); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return this->cbegin(); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const + { return const_iterator(node_traits::get_next(this->get_root_node()), this); } + + //! Effects: Returns an iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return iterator(this->get_root_node(), this); } + + //! Effects: Returns a const_iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return this->cend(); } + + //! Effects: Returns a constant iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const + { return const_iterator(uncast(this->get_root_node()), this); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rbegin() + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rbegin() const + { return this->crbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator rend() const + { return this->crend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crend() const + { return const_reverse_iterator(this->begin()); } + + //! Precondition: end_iterator must be a valid end iterator + //! of list. + //! + //! Effects: Returns a const reference to the list associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static list_impl &container_from_end_iterator(iterator end_iterator) + { return list_impl::priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of list. + //! + //! Effects: Returns a const reference to the list associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const list_impl &container_from_end_iterator(const_iterator end_iterator) + { return list_impl::priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the number of the elements contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements contained in the list. + //! if constant-time size option is disabled. Constant time otherwise. + //! + //! Note: Does not affect the validity of iterators and references. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else + return node_algorithms::count(this->get_root_node()) - 1; + } + + //! Effects: Returns true if the list contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + bool empty() const + { return node_algorithms::unique(this->get_root_node()); } + + //! Effects: Swaps the elements of x and *this. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + void swap(list_impl& other) + { + node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node()); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Effects: Moves backwards all the elements, so that the first + //! element becomes the second, the second becomes the third... + //! the last element becomes the first one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of shifts. + //! + //! Note: Does not affect the validity of iterators and references. + void shift_backwards(size_type n = 1) + { node_algorithms::move_forward(this->get_root_node(), n); } + + //! Effects: Moves forward all the elements, so that the second + //! element becomes the first, the third becomes the second... + //! the first element becomes the last one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of shifts. + //! + //! Note: Does not affect the validity of iterators and references. + void shift_forward(size_type n = 1) + { node_algorithms::move_backwards(this->get_root_node(), n); } + + //! Effects: Erases the element pointed by i of the list. + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + iterator erase(iterator i) + { return this->erase_and_dispose(i, detail::null_disposer()); } + + //! Requires: first and last must be valid iterator to elements in *this. + //! + //! Effects: Erases the element range pointed by b and e + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements erased if it's a safe-mode + //! or auto-unlink value. Constant time otherwise. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased elements. + iterator erase(iterator b, iterator e) + { + if(safemode_or_autounlink || constant_time_size){ + return this->erase_and_dispose(b, e, detail::null_disposer()); + } + else{ + node_algorithms::unlink(b.pointed_node(), e.pointed_node()); + return e; + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed by i of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + ++i; + node_algorithms::unlink(to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(this->get_real_value_traits().to_value_ptr(to_erase)); + return i; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element range pointed by b and e + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements erased. + //! + //! Note: Invalidates the iterators to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { + node_ptr bp(b.pointed_node()), ep(e.pointed_node()); + node_algorithms::unlink(bp, ep); + while(bp != ep){ + node_ptr to_erase(bp); + bp = node_traits::get_next(bp); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + this->priv_size_traits().decrement(); + } + return e; + } + + //! Effects: Erases all the elements of the container. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Note: Invalidates the iterators (but not the references) to the erased elements. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(this->get_root_node()); + this->priv_size_traits().set_size(size_type(0)); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! + //! Note: Invalidates the iterators to the erased elements. + template + void clear_and_dispose(Disposer disposer) + { + iterator it(this->begin()), itend(this->end()); + while(it != itend){ + node_ptr to_erase(it.pointed_node()); + ++it; + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + } + node_algorithms::init_header(this->get_root_node()); + this->priv_size_traits().set_size(0); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const list_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + BOOST_INTRUSIVE_TRY{ + const_iterator b(src.begin()), e(src.end()); + for(; b != e; ++b){ + this->push_back(*cloner(*b)); + } + } + BOOST_INTRUSIVE_CATCH(...){ + this->clear_and_dispose(disposer); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + } + + //! Requires: value must be an lvalue and p must be a valid iterator of *this. + //! + //! Effects: Inserts the value before the position pointed by p. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. No copy constructors are called. + //! + //! Note: Does not affect the validity of iterators and references. + iterator insert(iterator p, reference value) + { + node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); + node_algorithms::link_before(p.pointed_node(), to_insert); + this->priv_size_traits().increment(); + return iterator(to_insert, this); + } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type and p must be a valid iterator of *this. + //! + //! Effects: Inserts the range pointed by b and e before the position p. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted. + //! + //! Note: Does not affect the validity of iterators and references. + template + void insert(iterator p, Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert(p, *b); + } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list if it's a safe-mode + //! or auto-unlink value. + //! Linear to the number of elements inserted in the list otherwise. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void assign(Iterator b, Iterator e) + { + this->clear(); + this->insert(this->end(), b, e); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) + { + this->clear_and_dispose(disposer); + this->insert(this->end(), b, e); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Transfers all the elements of list x to this list, before the + //! the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of + //! this list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, list_impl& x) + { + if(!x.empty()){ + size_traits &thist = this->priv_size_traits(); + size_traits &xt = x.priv_size_traits(); + node_algorithms::transfer + (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node()); + thist.set_size(thist.get_size() + xt.get_size()); + xt.set_size(size_type(0)); + } + } + + //! Requires: p must be a valid iterator of *this. + //! new_ele must point to an element contained in list x. + //! + //! Effects: Transfers the value pointed by new_ele, from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! If p == new_ele or p == ++new_ele, this function is a null operation. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, list_impl&x, iterator new_ele) + { + node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node()); + x.priv_size_traits().decrement(); + this->priv_size_traits().increment(); + } + + //! Requires: p must be a valid iterator of *this. + //! start and end must point to elements contained in list x. + //! + //! Effects: Transfers the range pointed by start and end from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements transferred + //! if constant-time size option is enabled. Constant-time otherwise. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, list_impl&x, iterator start, iterator end) + { + if(constant_time_size) + this->splice(p, x, start, end, std::distance(start, end)); + else + this->splice(p, x, start, end, 1);//distance is a dummy value + } + + //! Requires: p must be a valid iterator of *this. + //! start and end must point to elements contained in list x. + //! n == std::distance(start, end) + //! + //! Effects: Transfers the range pointed by start and end from list x to this list, + //! before the the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator p, list_impl&x, iterator start, iterator end, difference_type n) + { + if(n){ + if(constant_time_size){ + size_traits &thist = this->priv_size_traits(); + size_traits &xt = x.priv_size_traits(); + BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(start, end)); + node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node()); + thist.set_size(thist.get_size() + n); + xt.set_size(xt.get_size() - n); + } + else{ + node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node()); + } + } + } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: If real_value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or std::less throws. Basic guarantee. + //! + //! Notes: Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + void sort() + { this->sort(std::less()); } + + //! Requires: p must be a comparison function that induces a strict weak ordering + //! + //! Effects: This function sorts the list *this according to p. The sort is + //! stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: If real_value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the predicate throws. Basic guarantee. + //! + //! Notes: This won't throw if list_base_hook<> or + //! list_member_hook are used. + //! Iterators and references are not invalidated. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + template + void sort(Predicate p) + { + if(node_traits::get_next(this->get_root_node()) + != node_traits::get_previous(this->get_root_node())){ + list_impl carry; + list_impl counter[64]; + int fill = 0; + while(!this->empty()){ + carry.splice(carry.begin(), *this, this->begin()); + int i = 0; + while(i < fill && !counter[i].empty()) { + carry.merge(counter[i++], p); + } + carry.swap(counter[i]); + if(i == fill) + ++fill; + } + for (int i = 1; i < fill; ++i) + counter[i].merge(counter[i-1], p); + this->swap(counter[fill-1]); + } + } + + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this according to std::less. The merge is stable; + //! that is, if an element from *this is equivalent to one from x, then the element + //! from *this will precede the one from x. + //! + //! Throws: If std::less throws. Basic guarantee. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references are not invalidated + void merge(list_impl& x) + { this->merge(x, std::less()); } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Throws: If the predicate throws. Basic guarantee. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references are not invalidated. + template + void merge(list_impl& x, Predicate p) + { + iterator e(this->end()); + iterator bx(x.begin()); + iterator ex(x.end()); + + for (iterator b = this->begin(); b != e; ++b) { + size_type n(0); + iterator ix(bx); + while(ix != ex && p(*ix, *b)){ + ++ix; ++n; + } + this->splice(b, x, bx, ix, n); + bx = ix; + } + //Now transfer the rest at the end of the container + this->splice(e, x); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear time. + //! + //! Note: Iterators and references are not invalidated + void reverse() + { node_algorithms::reverse(this->get_root_node()); } + + //! Effects: Removes all the elements that compare equal to value. + //! No destructors are called. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void remove(const_reference value) + { this->remove_if(detail::equal_to_value(value)); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements that compare equal to value. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_and_dispose(const_reference value, Disposer disposer) + { this->remove_and_dispose_if(detail::equal_to_value(value), disposer); } + + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. No destructors are called. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() calls to the predicate. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_if(Pred pred) + { this->remove_and_dispose_if(pred, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_and_dispose_if(Pred pred, Disposer disposer) + { + iterator cur(this->begin()); + iterator last(this->end()); + while(cur != last) { + if(pred(*cur)){ + cur = this->erase_and_dispose(cur, disposer); + } + else{ + ++cur; + } + } + } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. No destructors are called. + //! + //! Throws: If std::equal_toComplexity: Linear time (size()-1 comparisons calls to pred()). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void unique() + { this->unique_and_dispose(std::equal_to(), detail::null_disposer()); } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! No destructors are called. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1 comparisons equality comparisons). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique(BinaryPredicate pred) + { this->unique_and_dispose(pred, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If std::equal_toComplexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(Disposer disposer) + { this->unique_and_dispose(std::equal_to(), disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(BinaryPredicate pred, Disposer disposer) + { + iterator itend(this->end()); + iterator cur(this->begin()); + + if(cur != itend){ + iterator after(cur); + ++after; + while(after != itend){ + if(pred(*cur, *after)){ + after = this->erase_and_dispose(after, disposer); + } + else{ + cur = after; + ++after; + } + } + } + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + //! This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); + return iterator(real_value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + //! This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast (value)))); + return const_iterator(real_value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + iterator iterator_to(reference value) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); + return iterator(real_value_traits::to_node_ptr(value), this); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + const_iterator iterator_to(const_reference value) const + { + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast (value)))); + return const_iterator(real_value_traits::to_node_ptr(const_cast (value)), this); + } + + /// @cond + + private: + static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + root_plus_size *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), &root_plus_size::root_); + data_t *d = detail::parent_from_member + ( r, &data_t::root_plus_size_); + list_impl *s = detail::parent_from_member(d, &list_impl::data_); + return *s; + } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ + typedef list_impl list_type; + typedef typename list_type::const_iterator const_iterator; + const bool C = list_type::constant_time_size; + if(C && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(C){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const list_impl &x, const list_impl &y) +#else +(const list_impl &x, const list_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(list_impl &x, list_impl &y) +#else +(list_impl &x, list_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c list that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_list +{ + /// @cond + typedef typename pack_options + < list_defaults, O1, O2, O3>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + + typedef list_impl + < + listopt + < value_traits + , typename packed_options::size_type + , packed_options::constant_time_size + > + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class list + : public make_list::type +{ + typedef typename make_list + ::type Base; + typedef typename Base::real_value_traits real_value_traits; + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + list(const value_traits &v_traits = value_traits()) + : Base(v_traits) + {} + + template + list(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : Base(b, e, v_traits) + {} + + static list &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const list &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LIST_HPP diff --git a/thirdparty/boost/intrusive/list_hook.hpp b/thirdparty/boost/intrusive/list_hook.hpp new file mode 100644 index 0000000..e43aa6f --- /dev/null +++ b/thirdparty/boost/intrusive/list_hook.hpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LIST_HOOK_HPP +#define BOOST_INTRUSIVE_LIST_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_list_node_algo +{ + typedef circular_list_algorithms > type; +}; +/// @endcond + +//! Helper metafunction to define a \c \c list_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_list_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_list_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::ListBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from this hook in order to store objects of that class +//! in an list. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class list_base_hook + : public make_list_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + list_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + list_base_hook(const list_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + list_base_hook& operator=(const list_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an list an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~list_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(list_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c list::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c \c list_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_list_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_list_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Store this hook in a class to be inserted +//! in an list. +//! +//! The hook admits the following options: \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class list_member_hook + : public make_list_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + list_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + list_member_hook(const list_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + list_member_hook& operator=(const list_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an list an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~list_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(list_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c list::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LIST_HOOK_HPP diff --git a/thirdparty/boost/intrusive/member_value_traits.hpp b/thirdparty/boost/intrusive/member_value_traits.hpp new file mode 100644 index 0000000..8d90b67 --- /dev/null +++ b/thirdparty/boost/intrusive/member_value_traits.hpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP + +#include +#include +#include + +namespace boost { +namespace intrusive { + +//!This value traits template is used to create value traits +//!from user defined node traits where value_traits::value_type will +//!store a node_traits::node +template< class T, class NodeTraits + , typename NodeTraits::node T::* PtrToMember + , link_mode_type LinkMode = safe_link> +struct member_value_traits +{ + public: + typedef NodeTraits node_traits; + typedef T value_type; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename boost::pointer_to_other::type pointer; + typedef typename boost::pointer_to_other::type const_pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + static const link_mode_type link_mode = LinkMode; + + static node_ptr to_node_ptr(reference value) + { return node_ptr(&(value.*PtrToMember)); } + + static const_node_ptr to_node_ptr(const_reference value) + { return node_ptr(&(value.*PtrToMember)); } + + static pointer to_value_ptr(node_ptr n) + { + return pointer(detail::parent_from_member + (detail::get_pointer(n), PtrToMember)); + } + + static const_pointer to_value_ptr(const_node_ptr n) + { + return pointer(detail::parent_from_member + (detail::get_pointer(n), PtrToMember)); + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP diff --git a/thirdparty/boost/intrusive/options.hpp b/thirdparty/boost/intrusive/options.hpp new file mode 100644 index 0000000..ad45fbd --- /dev/null +++ b/thirdparty/boost/intrusive/options.hpp @@ -0,0 +1,513 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_OPTIONS_HPP +#define BOOST_INTRUSIVE_OPTIONS_HPP + +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +/// @cond + +struct default_tag; +struct member_tag; + +namespace detail{ + +template +struct eval_value_traits +{ + typedef typename ValueTraits::value_traits type; +}; + +template +struct external_bucket_traits_is_true +{ + static const bool value = external_bucket_traits_bool::value == 3; +}; + +template +struct eval_bucket_traits +{ + typedef typename BucketTraits::bucket_traits type; +}; + +template +struct get_base_value_traits +{ + typedef detail::base_hook_traits + < T + , typename BaseHook::boost_intrusive_tags::node_traits + , BaseHook::boost_intrusive_tags::link_mode + , typename BaseHook::boost_intrusive_tags::tag + , BaseHook::boost_intrusive_tags::hook_type> type; +}; + +template +struct get_member_value_traits +{ + typedef typename MemberHook::member_value_traits type; +}; + +template +struct get_value_traits +{ + typedef SupposedValueTraits supposed_value_traits; + //...if it's a base hook + typedef typename detail::eval_if_c + < internal_base_hook_bool_is_true::value + //...get it's internal value traits using + //the provided T value type. + , get_base_value_traits + //...else use it's internal value traits tag + //(member hooks and custom value traits are in this group) + , detail::eval_if_c + < internal_member_value_traits::value + , get_member_value_traits + , detail::identity + > + >::type type; +}; + +template +struct get_base_node_traits +{ + typedef typename BaseHook::boost_intrusive_tags::node_traits type; +}; + +template +struct get_member_node_traits +{ + typedef typename MemberHook::member_value_traits::node_traits type; +}; + +template +struct get_explicit_node_traits +{ + typedef typename ValueTraits::node_traits type; +}; + + +template +struct get_node_traits +{ + typedef SupposedValueTraits supposed_value_traits; + //...if it's a base hook + typedef typename detail::eval_if_c + < internal_base_hook_bool_is_true::value + //...get it's internal value traits using + //the provided T value type. + , get_base_node_traits + //...else use it's internal value traits tag + //(member hooks and custom value traits are in this group) + , detail::eval_if_c + < internal_member_value_traits::value + , get_member_node_traits + , get_explicit_node_traits + > + >::type type; +}; + + +} //namespace detail{ + + +//!This type indicates that no option is being used +//!and that the default options should be used +struct none +{ + template + struct pack : Base + { }; +}; + +/// @endcond + +//!This option setter specifies if the intrusive +//!container stores its size as a member to +//!obtain constant-time size() member. +template +struct constant_time_size +{ +/// @cond + template + struct pack : Base + { + static const bool constant_time_size = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies the type that +//!the container will use to store its size. +template +struct size_type +{ +/// @cond + template + struct pack : Base + { + typedef SizeType size_type; + }; +/// @endcond +}; + +//!This option setter specifies the strict weak ordering +//!comparison functor for the value type +template +struct compare +{ +/// @cond + template + struct pack : Base + { + typedef Compare compare; + }; +/// @endcond +}; + +//!This option setter for scapegoat containers specifies if +//!the intrusive scapegoat container should use a non-variable +//!alpha value that does not need floating-point operations. +//! +//!If activated, the fixed alpha value is 1/sqrt(2). This +//!option also saves some space in the container since +//!the alpha value and some additional data does not need +//!to be stored in the container. +//! +//!If the user only needs an alpha value near 1/sqrt(2), this +//!option also improves performance since avoids logarithm +//!and division operations when rebalancing the tree. +template +struct floating_point +{ +/// @cond + template + struct pack : Base + { + static const bool floating_point = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies the equality +//!functor for the value type +template +struct equal +{ +/// @cond + template + struct pack : Base + { + typedef Equal equal; + }; +/// @endcond +}; + +//!This option setter specifies the hash +//!functor for the value type +template +struct hash +{ +/// @cond + template + struct pack : Base + { + typedef Hash hash; + }; +/// @endcond +}; + +//!This option setter specifies the relationship between the type +//!to be managed by the container (the value type) and the node to be +//!used in the node algorithms. It also specifies the linking policy. +template +struct value_traits +{ +/// @cond + template + struct pack : Base + { + typedef ValueTraits value_traits; + }; +/// @endcond +}; + +//!This option setter specifies the member hook the +//!container must use. +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook +{ +/// @cond + typedef char Parent::* GenericPtrToMember; + typedef detail::member_hook_traits + < Parent + , MemberHook + , PtrToMember + > member_value_traits; + template + struct pack : Base + { + typedef member_value_traits value_traits; + }; +/// @endcond +}; + +//!This option setter specifies that the container +//!must use the specified base hook +template +struct base_hook +{ +/// @cond + template + struct pack : Base + { + typedef BaseHook value_traits; + }; +/// @endcond +}; + +//!This option setter specifies the type of +//!a void pointer. This will instruct the hook +//!to use this type of pointer instead of the +//!default one +template +struct void_pointer +{ +/// @cond + template + struct pack : Base + { + typedef VoidPointer void_pointer; + }; +/// @endcond +}; + +//!This option setter specifies the type of +//!the tag of a base hook. A type can not have two +//!base hooks of the same type, so a tag can be used +//!to differentiate two base hooks with otherwise same type +template +struct tag +{ +/// @cond + template + struct pack : Base + { + typedef Tag tag; + }; +/// @endcond +}; + +//!This option setter specifies the link mode +//!(normal_link, safe_link or auto_unlink) +template +struct link_mode +{ +/// @cond + template + struct pack : Base + { + static const link_mode_type link_mode = LinkType; + }; +/// @endcond +}; + +//!This option setter specifies if the hook +//!should be optimized for size instead of for speed. +template +struct optimize_size +{ +/// @cond + template + struct pack : Base + { + static const bool optimize_size = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies if the list container should +//!use a linear implementation instead of a circular one. +template +struct linear +{ +/// @cond + template + struct pack : Base + { + static const bool linear = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies if the list container should +//!use a linear implementation instead of a circular one. +template +struct cache_last +{ +/// @cond + template + struct pack : Base + { + static const bool cache_last = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies the bucket traits +//!class for unordered associative containers. When this option is specified, +//!instead of using the default bucket traits, a user defined holder will be defined +template +struct bucket_traits +{ +/// @cond + template + struct pack : Base + { + typedef BucketTraits bucket_traits; + }; +/// @endcond +}; + +//!This option setter specifies if the unordered hook +//!should offer room to store the hash value. +//!Storing the hash in the hook will speed up rehashing +//!processes in applications where rehashing is frequent, +//!rehashing might throw or the value is heavy to hash. +template +struct store_hash +{ +/// @cond + template + struct pack : Base + { + static const bool store_hash = Enabled; + }; +/// @endcond +}; + +//!This option setter specifies if the bucket array will be always power of two. +//!This allows using masks instead of the default modulo operation to determine +//!the bucket number from the hash value, leading to better performance. +//!In debug mode, if power of two buckets mode is activated, the bucket length +//!will be checked to through assertions to assure the bucket length is power of two. +template +struct power_2_buckets +{ +/// @cond + template + struct pack : Base + { + static const bool power_2_buckets = Enabled; + }; +/// @endcond +}; + +/// @cond + +template +struct do_pack +{ + //Use "pack" member template to pack options + typedef typename Next::template pack type; +}; + +template +struct do_pack +{ + //Avoid packing "none" to shorten template names + typedef Prev type; +}; + + +template + < class DefaultOptions + , class O1 = none + , class O2 = none + , class O3 = none + , class O4 = none + , class O5 = none + , class O6 = none + , class O7 = none + , class O8 = none + , class O9 = none + , class Option10 = none + > +struct pack_options +{ + // join options + typedef + typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < DefaultOptions + , O1 + >::type + , O2 + >::type + , O3 + >::type + , O4 + >::type + , O5 + >::type + , O6 + >::type + , O7 + >::type + , O8 + >::type + , O9 + >::type + , Option10 + >::type + type; +}; + +struct hook_defaults + : public pack_options + < none + , void_pointer + , link_mode + , tag + , optimize_size + , store_hash + , linear + >::type +{}; + +/// @endcond + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP diff --git a/thirdparty/boost/intrusive/pointer_plus_2_bits.hpp b/thirdparty/boost/intrusive/pointer_plus_2_bits.hpp new file mode 100644 index 0000000..0b7273c --- /dev/null +++ b/thirdparty/boost/intrusive/pointer_plus_2_bits.hpp @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP +#define BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP + +namespace boost { +namespace intrusive { + +//!This trait class is used to know if a pointer +//!can embed 2 extra bits of information if +//!it's going to be used to point to objects +//!with an alignment of "Alignment" bytes. +template +struct has_pointer_plus_2_bits +{ + static const bool value = false; +}; + +//!This is an specialization for raw pointers. +//!Raw pointers can embed two extra bits in the lower bits +//!if the alignment is multiple of 4. +template +struct has_pointer_plus_2_bits +{ + static const bool value = (N % 4u == 0); +}; + +//!This is class that is supposed to have static methods +//!to embed 2 extra bits of information in a pointer. +//! +//!This is a declaration and there is no default implementation, +//!because operations to embed bits change with every pointer type. +//! +//!An implementation that detects that a pointer type whose +//!has_pointer_plus_2_bits<>::value is non-zero can make use of these +//!operations to embed bits in the pointer. +template +struct pointer_plus_2_bits +{ + static const bool value = false; +}; + +//!This is the specialization to embed 2 extra bits of information +//!in a raw pointer. Extra bits are stored in the lower bits of the pointer. +template +struct pointer_plus_2_bits +{ + typedef T* pointer; + + static pointer get_pointer(pointer n) + { return pointer(std::size_t(n) & ~std::size_t(3u)); } + + static void set_pointer(pointer &n, pointer p) + { + assert(0 == (std::size_t(p) & std::size_t(3u))); + n = pointer(std::size_t(p) | (std::size_t(n) & std::size_t(3u))); + } + + static std::size_t get_bits(pointer n) + { return (std::size_t(n) & std::size_t(3u)); } + + static void set_bits(pointer &n, std::size_t c) + { + assert(c < 4); + n = pointer(std::size_t(get_pointer(n)) | c); + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP diff --git a/thirdparty/boost/intrusive/pointer_plus_bit.hpp b/thirdparty/boost/intrusive/pointer_plus_bit.hpp new file mode 100644 index 0000000..1306198 --- /dev/null +++ b/thirdparty/boost/intrusive/pointer_plus_bit.hpp @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP +#define BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP + +namespace boost { +namespace intrusive { + +//!This trait class is used to know if a pointer +//!can embed an extra bit of information if +//!it's going to be used to point to objects +//!with an alignment of "Alignment" bytes. +template +struct has_pointer_plus_bit +{ + static const bool value = false; +}; + +//!This is an specialization for raw pointers. +//!Raw pointers can embed an extra bit in the lower bit +//!if the alignment is multiple of 2. +template +struct has_pointer_plus_bit +{ + static const bool value = (N % 2u == 0); +}; + +//!This is class that is supposed to have static methods +//!to embed an extra bit of information in a pointer. +//!This is a declaration and there is no default implementation, +//!because operations to embed the bit change with every pointer type. +//! +//!An implementation that detects that a pointer type whose +//!has_pointer_plus_bit<>::value is non-zero can make use of these +//!operations to embed the bit in the pointer. +template +struct pointer_plus_bit +{ + static const bool value = false; +}; + +//!This is the specialization to embed an extra bit of information +//!in a raw pointer. The extra bit is stored in the lower bit of the pointer. +template +struct pointer_plus_bit +{ + typedef T* pointer; + + static pointer get_pointer(pointer n) + { return pointer(std::size_t(n) & ~std::size_t(1u)); } + + static void set_pointer(pointer &n, pointer p) + { + assert(0 == (std::size_t(p) & std::size_t(1u))); + n = pointer(std::size_t(p) | (std::size_t(n) & std::size_t(1u))); + } + + static bool get_bit(pointer n) + { return (std::size_t(n) & std::size_t(1u)) != 0; } + + static void set_bit(pointer &n, bool c) + { n = pointer(std::size_t(get_pointer(n)) | std::size_t(c)); } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP diff --git a/thirdparty/boost/intrusive/rbtree.hpp b/thirdparty/boost/intrusive/rbtree.hpp new file mode 100644 index 0000000..5d56c33 --- /dev/null +++ b/thirdparty/boost/intrusive/rbtree.hpp @@ -0,0 +1,1439 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_RBTREE_HPP +#define BOOST_INTRUSIVE_RBTREE_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct internal_default_set_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_set_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_set_hook +{ + typedef typename T::default_set_hook type; +}; + +template +struct setopt +{ + typedef ValueTraits value_traits; + typedef Compare compare; + typedef SizeType size_type; + static const bool constant_time_size = ConstantTimeSize; +}; + +template +struct set_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_set_hook::value + , get_default_set_hook + , detail::identity + >::type + > + , constant_time_size + , size_type + , compare > + >::type +{}; + +/// @endcond + +//! The class template rbtree is an intrusive red-black tree container, that +//! is used to construct intrusive set and multiset containers. The no-throw +//! guarantee holds only, if the value_compare object +//! doesn't throw. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class rbtree_impl +{ + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef value_type key_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef typename Config::compare value_compare; + typedef value_compare key_compare; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef rbtree_algorithms node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + + /// @cond + private: + typedef detail::size_holder size_traits; + + //noncopyable + rbtree_impl (const rbtree_impl&); + rbtree_impl operator =(const rbtree_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + struct header_plus_size : public size_traits + { node header_; }; + + struct node_plus_pred_t : public detail::ebo_functor_holder + { + node_plus_pred_t(const value_compare &comp) + : detail::ebo_functor_holder(comp) + {} + header_plus_size header_plus_size_; + }; + + struct data_t : public rbtree_impl::value_traits + { + typedef typename rbtree_impl::value_traits value_traits; + data_t(const value_compare & comp, const value_traits &val_traits) + : value_traits(val_traits), node_plus_pred_(comp) + {} + node_plus_pred_t node_plus_pred_; + } data_; + + const value_compare &priv_comp() const + { return data_.node_plus_pred_.get(); } + + value_compare &priv_comp() + { return data_.node_plus_pred_.get(); } + + const node &priv_header() const + { return data_.node_plus_pred_.header_plus_size_.header_; } + + node &priv_header() + { return data_.node_plus_pred_.header_plus_size_.header_; } + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(detail::get_pointer(ptr))); + } + + size_traits &priv_size_traits() + { return data_.node_plus_pred_.header_plus_size_; } + + const size_traits &priv_size_traits() const + { return data_.node_plus_pred_.header_plus_size_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + rbtree_impl( value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty tree and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + template + rbtree_impl( bool unique, Iterator b, Iterator e + , value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + ~rbtree_impl() + { this->clear(); } + + //! Effects: Returns an iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return cbegin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns an iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return iterator (node_ptr(&priv_header()), this); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return cend(); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return const_iterator (uncast(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + //! Precondition: end_iterator must be a valid end iterator + //! of rbtree. + //! + //! Effects: Returns a const reference to the rbtree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static rbtree_impl &container_from_end_iterator(iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of rbtree. + //! + //! Effects: Returns a const reference to the rbtree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the value_compare object used by the tree. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return priv_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return node_algorithms::unique(const_node_ptr(&priv_header())); } + + //! Effects: Returns the number of elements stored in the tree. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else{ + return (size_type)node_algorithms::size(const_node_ptr(&priv_header())); + } + } + + //! Effects: Swaps the contents of two multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(rbtree_impl& other) + { + //This can throw + using std::swap; + swap(priv_comp(), priv_comp()); + //These can't throw + node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header())); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree before the upper bound. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal_upper_bound + (node_ptr(&priv_header()), to_insert, key_node_comp), this); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal + (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the tree + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + iterator end(this->end()); + for (; b != e; ++b) + this->insert_equal(end, *b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree if the value + //! is not already present. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(value, commit_data); + if(!ret.second) + return ret; + return std::pair (insert_unique_commit(value, commit_data), true); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the tree, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(hint, value, commit_data); + if(!ret.second) + return ret.first; + return insert_unique_commit(value, commit_data); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the tree. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + if(this->empty()){ + iterator end(this->end()); + for (; b != e; ++b) + this->insert_unique(end, *b); + } + else{ + for (; b != e; ++b) + this->insert_unique(*b); + } + } + + std::pair insert_unique_check + (const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + std::pair insert_unique_check + (const_iterator hint, const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(hint, value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + node_algorithms::insert_unique_commit + (node_ptr(&priv_header()), to_insert, commit_data); + return iterator(to_insert, this); + } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { + iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + node_algorithms::erase(&priv_header(), to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret; + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { size_type n; return private_erase(b, e, n); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, priv_comp()); } + + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + return ret; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { size_type n; return private_erase(b, e, n, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { + std::pair p = this->equal_range(value); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Average complexity for is at most O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. Calls N times to disposer functor. + template + void clear_and_dispose(Disposer disposer) + { + node_algorithms::clear_and_dispose(node_ptr(&priv_header()) + , detail::node_disposer(disposer, this)); + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count(const_reference value) const + { return this->count(value, priv_comp()); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + return std::distance(ret.first, ret.second); + } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator lower_bound(const_reference value) + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator lower_bound(const_reference value) const + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator upper_bound(const_reference value) + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator upper_bound(const_reference value) const + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator find(const_reference value) + { return this->find(value, priv_comp()); } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator find(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator find(const_reference value) const + { return this->find(value, priv_comp()); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator find(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair equal_range(const_reference value) + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair + equal_range(const_reference value) const + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair + equal_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + node_algorithms::clone + (const_node_ptr(&src.priv_header()) + ,node_ptr(&this->priv_header()) + ,detail::node_cloner(cloner, this) + ,detail::node_disposer(disposer, this)); + this->priv_size_traits().set_size(src.priv_size_traits().get_size()); + } + } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { + node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance + (node_ptr(&priv_header()))); + if(!to_be_disposed) + return 0; + this->priv_size_traits().decrement(); + if(safemode_or_autounlink)//If this is commented does not work with normal_link + node_algorithms::init(to_be_disposed); + return get_real_value_traits().to_value_ptr(to_be_disposed); + } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + , node_ptr(&priv_header()) + , get_real_value_traits().to_node_ptr(with_this)); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return iterator (value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return iterator (value_traits::to_node_ptr(value), this); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } + + //! Requires: value shall not be in a tree. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + +/* + //! Effects: removes x from a tree of the appropriate type. It has no effect, + //! if x is not in such a tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This static function is only usable with the "safe mode" + //! hook and non-constant time size lists. Otherwise, the user must use + //! the non-static "erase(reference )" member. If the user calls + //! this function with a non "safe mode" or constant time size list + //! a compilation error will be issued. + template + static void remove_node(T& value) + { + //This function is only usable for safe mode hooks and non-constant + //time lists. + //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size))); + BOOST_STATIC_ASSERT((!constant_time_size)); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink_and_rebalance(to_remove); + if(safemode_or_autounlink) + node_algorithms::init(to_remove); + } +*/ + + /// @cond + private: + template + iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer) + { + for(n = 0; b != e; ++n) + this->erase_and_dispose(b++, disposer); + return b; + } + + iterator private_erase(iterator b, iterator e, size_type &n) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b; + } + /// @endcond + + private: + static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + header_plus_size *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + node_plus_pred_t *n = detail::parent_from_member + (r, &node_plus_pred_t::header_plus_size_); + data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); + rbtree_impl *rb = detail::parent_from_member(d, &rbtree_impl::data_); + return *rb; + } +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ + typedef rbtree_impl tree_type; + typedef typename tree_type::const_iterator const_iterator; + + if(tree_type::constant_time_size && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(tree_type::constant_time_size){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const rbtree_impl &x, const rbtree_impl &y) +#else +(const rbtree_impl &x, const rbtree_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(rbtree_impl &x, rbtree_impl &y) +#else +(rbtree_impl &x, rbtree_impl &y) +#endif +{ x.swap(y); } + +/// @cond +template +struct make_rbtree_opt +{ + typedef typename pack_options + < set_defaults, O1, O2, O3, O4>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + + typedef setopt + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > type; +}; +/// @endcond + +//! Helper metafunction to define a \c rbtree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_rbtree +{ + /// @cond + typedef rbtree_impl + < typename make_rbtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class rbtree + : public make_rbtree::type +{ + typedef typename make_rbtree + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + rbtree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + rbtree( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + static rbtree &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const rbtree &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_RBTREE_HPP diff --git a/thirdparty/boost/intrusive/rbtree_algorithms.hpp b/thirdparty/boost/intrusive/rbtree_algorithms.hpp new file mode 100644 index 0000000..c3f1ae5 --- /dev/null +++ b/thirdparty/boost/intrusive/rbtree_algorithms.hpp @@ -0,0 +1,841 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +// The internal implementation of red-black trees is based on that of SGI STL +// stl_tree.h file: +// +// Copyright (c) 1996,1997 +// Silicon Graphics Computer Systems, Inc. +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Silicon Graphics makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +// +// Copyright (c) 1994 +// Hewlett-Packard Company +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Hewlett-Packard Company makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +// The tree destruction algorithm is based on Julienne Walker and The EC Team code: +// +// This code is in the public domain. Anyone may use it or change it in any way that +// they see fit. The author assumes no responsibility for damages incurred through +// use of the original code or any variations thereof. +// +// It is requested, but not required, that due credit is given to the original author +// and anyone who has modified the code through a header comment, such as this one. + +#ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP + +#include + +#include +#include + +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +//! rbtree_algorithms provides basic algorithms to manipulate +//! nodes forming a red-black tree. The insertion and deletion algorithms are +//! based on those in Cormen, Leiserson, and Rivest, Introduction to Algorithms +//! (MIT Press, 1990), except that +//! +//! (1) the header node is maintained with links not only to the root +//! but also to the leftmost node of the tree, to enable constant time +//! begin(), and to the rightmost node of the tree, to enable linear time +//! performance when used with the generic set algorithms (set_union, +//! etc.); +//! +//! (2) when a node being deleted has two children its successor node is +//! relinked into its place, rather than copied, so that the only +//! pointers invalidated are those referring to the deleted node. +//! +//! rbtree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! color: The type that can store the color of a node +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +//! +//! static color get_color(const_node_ptr n); +//! +//! static void set_color(node_ptr n, color c); +//! +//! static color black(); +//! +//! static color red(); +template +class rbtree_algorithms +{ + public: + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef typename NodeTraits::color color; + + /// @cond + private: + + typedef typename NodeTraits::node node; + typedef detail::tree_algorithms tree_algorithms; + + template + struct rbtree_node_cloner + : private detail::ebo_functor_holder + { + typedef detail::ebo_functor_holder base_t; + + rbtree_node_cloner(F f) + : base_t(f) + {} + + node_ptr operator()(node_ptr p) + { + node_ptr n = base_t::get()(p); + NodeTraits::set_color(n, NodeTraits::get_color(p)); + return n; + } + }; + + struct rbtree_erase_fixup + { + void operator()(node_ptr to_erase, node_ptr successor) + { + //Swap color of y and z + color tmp(NodeTraits::get_color(successor)); + NodeTraits::set_color(successor, NodeTraits::get_color(to_erase)); + NodeTraits::set_color(to_erase, tmp); + } + }; + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + } + /// @endcond + + public: + static node_ptr begin_node(const_node_ptr header) + { return tree_algorithms::begin_node(header); } + + static node_ptr end_node(const_node_ptr header) + { return tree_algorithms::end_node(header); } + + //! This type is the information that will be + //! filled by insert_unique_check + typedef typename tree_algorithms::insert_commit_data insert_commit_data; + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) + { return tree_algorithms::swap_tree(header1, header2); } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) + { + if(node1 == node2) + return; + + node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + { + if(node1 == node2) return; + + tree_algorithms::swap_nodes(node1, header1, node2, header2); + //Swap color + color c = NodeTraits::get_color(node1); + NodeTraits::set_color(node1, NodeTraits::get_color(node2)); + NodeTraits::set_color(node2, c); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing and comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + { + tree_algorithms::replace_node(node_to_be_replaced, header, new_node); + NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); + } + + //! Requires: node is a tree node but not the header. + //! + //! Effects: Unlinks the node and rebalances the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + static void unlink(node_ptr node) + { + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, node); + } + } + + //! Requires: header is the header of a tree. + //! + //! Effects: Unlinks the leftmost node from the tree, and + //! updates the header link to the new leftmost node. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + { return tree_algorithms::unlink_leftmost_without_rebalance(header); } + + //! Requires: node is a node of the tree or an node initialized + //! by init(...). + //! + //! Effects: Returns true if the node is initialized by init(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + static bool unique(const_node_ptr node) + { return tree_algorithms::unique(node); } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr node) + { return tree_algorithms::count(node); } + + //! Requires: header is the header node of the tree. + //! + //! Effects: Returns the number of nodes above the header. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) + { return tree_algorithms::size(header); } + + //! Requires: p is a node from the tree except the header. + //! + //! Effects: Returns the next node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr next_node(node_ptr p) + { return tree_algorithms::next_node(p); } + + //! Requires: p is a node from the tree except the leftmost node. + //! + //! Effects: Returns the previous node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr prev_node(node_ptr p) + { return tree_algorithms::prev_node(p); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr node) + { tree_algorithms::init(node); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) + { + tree_algorithms::init_header(header); + NodeTraits::set_color(header, NodeTraits::red()); + } + + //! Requires: header must be the header of a tree, z a node + //! of that tree and z != header. + //! + //! Effects: Erases node "z" from the tree with header "header". + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static node_ptr erase(node_ptr header, node_ptr z) + { + typename tree_algorithms::data_for_rebalance info; + tree_algorithms::erase(header, z, rbtree_erase_fixup(), info); + node_ptr x = info.x; + node_ptr x_parent = info.x_parent; + + //Rebalance rbtree + if(NodeTraits::get_color(z) != NodeTraits::red()){ + rebalance_after_erasure(header, x, x_parent); + } + return z; + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Then, duplicates the entire tree pointed by "source_header" cloning each + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! are disposed using void disposer(node_ptr). + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { + rbtree_node_cloner new_cloner(cloner); + tree_algorithms::clone(source_header, target_header, new_cloner, disposer); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) + { tree_algorithms::clear_and_dispose(header, disposer); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::lower_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::upper_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::find(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if they there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::equal_range(header, key, comp); } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the upper bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal_upper_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the lower bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal_lower_bound(h, new_node, comp); + rebalance_after_insertion(h, new_node); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) + { + tree_algorithms::insert_equal(header, hint, new_node, comp); + rebalance_after_insertion(header, new_node); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { return tree_algorithms::insert_unique_check(header, key, comp, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! "hint" is node from the "header"'s tree. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" using "hint" as a hint to where it should be + //! inserted and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! If "hint" is the upper_bound the function has constant time + //! complexity (two comparisons in the worst case). + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic, but it is + //! amortized constant time if new_node should be inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, node_ptr hint, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + static void insert_unique_commit + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + { + tree_algorithms::insert_unique_commit(header, new_value, commit_data); + rebalance_after_insertion(header, new_value); + } + + /// @cond + private: + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_header(const_node_ptr p) + { + return NodeTraits::get_color(p) == NodeTraits::red() && + tree_algorithms::is_header(p); + //return NodeTraits::get_color(p) == NodeTraits::red() && + // NodeTraits::get_parent(NodeTraits::get_parent(p)) == p; + } + + static void rebalance_after_erasure(node_ptr header, node_ptr x, node_ptr x_parent) + { + while(x != NodeTraits::get_parent(header) && (x == 0 || NodeTraits::get_color(x) == NodeTraits::black())){ + if(x == NodeTraits::get_left(x_parent)){ + node_ptr w = NodeTraits::get_right(x_parent); + if(NodeTraits::get_color(w) == NodeTraits::red()){ + NodeTraits::set_color(w, NodeTraits::black()); + NodeTraits::set_color(x_parent, NodeTraits::red()); + tree_algorithms::rotate_left(x_parent, header); + w = NodeTraits::get_right(x_parent); + } + if((NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) && + (NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){ + NodeTraits::set_color(w, NodeTraits::red()); + x = x_parent; + x_parent = NodeTraits::get_parent(x_parent); + } + else { + if(NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){ + NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); + NodeTraits::set_color(w, NodeTraits::red()); + tree_algorithms::rotate_right(w, header); + w = NodeTraits::get_right(x_parent); + } + NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); + NodeTraits::set_color(x_parent, NodeTraits::black()); + if(NodeTraits::get_right(w)) + NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); + tree_algorithms::rotate_left(x_parent, header); + break; + } + } + else { + // same as above, with right_ <-> left_. + node_ptr w = NodeTraits::get_left(x_parent); + if(NodeTraits::get_color(w) == NodeTraits::red()){ + NodeTraits::set_color(w, NodeTraits::black()); + NodeTraits::set_color(x_parent, NodeTraits::red()); + tree_algorithms::rotate_right(x_parent, header); + w = NodeTraits::get_left(x_parent); + } + if((NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) && + (NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){ + NodeTraits::set_color(w, NodeTraits::red()); + x = x_parent; + x_parent = NodeTraits::get_parent(x_parent); + } + else { + if(NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){ + NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); + NodeTraits::set_color(w, NodeTraits::red()); + tree_algorithms::rotate_left(w, header); + w = NodeTraits::get_left(x_parent); + } + NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); + NodeTraits::set_color(x_parent, NodeTraits::black()); + if(NodeTraits::get_left(w)) + NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); + tree_algorithms::rotate_right(x_parent, header); + break; + } + } + } + if(x) + NodeTraits::set_color(x, NodeTraits::black()); + } + + + static void rebalance_after_insertion(node_ptr header, node_ptr p) + { + NodeTraits::set_color(p, NodeTraits::red()); + while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){ + node_ptr p_parent(NodeTraits::get_parent(p)); + node_ptr p_parent_parent(NodeTraits::get_parent(p_parent)); + if(tree_algorithms::is_left_child(p_parent)){ + node_ptr x = NodeTraits::get_right(p_parent_parent); + if(x && NodeTraits::get_color(x) == NodeTraits::red()){ + NodeTraits::set_color(p_parent, NodeTraits::black()); + NodeTraits::set_color(p_parent_parent, NodeTraits::red()); + NodeTraits::set_color(x, NodeTraits::black()); + p = p_parent_parent; + } + else { + if(!tree_algorithms::is_left_child(p)){ + p = p_parent; + tree_algorithms::rotate_left(p, header); + } + node_ptr new_p_parent(NodeTraits::get_parent(p)); + node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); + NodeTraits::set_color(new_p_parent, NodeTraits::black()); + NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); + tree_algorithms::rotate_right(new_p_parent_parent, header); + } + } + else{ + node_ptr x = NodeTraits::get_left(p_parent_parent); + if(x && NodeTraits::get_color(x) == NodeTraits::red()){ + NodeTraits::set_color(p_parent, NodeTraits::black()); + NodeTraits::set_color(p_parent_parent, NodeTraits::red()); + NodeTraits::set_color(x, NodeTraits::black()); + p = p_parent_parent; + } + else{ + if(tree_algorithms::is_left_child(p)){ + p = p_parent; + tree_algorithms::rotate_right(p, header); + } + node_ptr new_p_parent(NodeTraits::get_parent(p)); + node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); + NodeTraits::set_color(new_p_parent, NodeTraits::black()); + NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); + tree_algorithms::rotate_left(new_p_parent_parent, header); + } + } + } + NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black()); + } + /// @endcond +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/set.hpp b/thirdparty/boost/intrusive/set.hpp new file mode 100644 index 0000000..077bc44 --- /dev/null +++ b/thirdparty/boost/intrusive/set.hpp @@ -0,0 +1,2070 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SET_HPP +#define BOOST_INTRUSIVE_SET_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! The class template set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class set_impl +{ + /// @cond + typedef rbtree_impl tree_type; + //! This class is + //! non-copyable + set_impl (const set_impl&); + + //! This class is + //! non-assignable + set_impl &operator =(const set_impl&); + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the value_compare object throws. + set_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty set and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is std::distance(last, first). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + set_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(true, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~set_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of set. + //! + //! Effects: Returns a const reference to the set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static set_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &set_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of set. + //! + //! Effects: Returns a const reference to the set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const set_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &set_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the set. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two sets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(set_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const set_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert(reference value) + { return tree_.insert_unique(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to to insert x into the set, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: An iterator that points to the position where the + //! new element was inserted into the set. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_unique(hint, value); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the set. + template + std::pair insert_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(key, key_value_comp, commit_data); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the set, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the set. + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return tree_.insert_unique_commit(value, commit_data); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the set. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_unique(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size()) + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If the comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: If the internal value_compare ordering function throws. + //! + //! Complexity: O(log(size() + this->count(value)). Basic guarantee. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.find(value) != end(); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp) != end(); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a set/multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + /// @cond + friend bool operator==(const set_impl &x, const set_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const set_impl &x, const set_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const set_impl &x, const set_impl &y) +#else +(const set_impl &x, const set_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const set_impl &x, const set_impl &y) +#else +(const set_impl &x, const set_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const set_impl &x, const set_impl &y) +#else +(const set_impl &x, const set_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const set_impl &x, const set_impl &y) +#else +(const set_impl &x, const set_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(set_impl &x, set_impl &y) +#else +(set_impl &x, set_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_set +{ + /// @cond + typedef set_impl + < typename make_rbtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class set + : public make_set::type +{ + typedef typename make_set + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + set( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + set( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static set &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const set &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +//! The class template multiset is an intrusive container, that mimics most of +//! the interface of std::multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class multiset_impl +{ + /// @cond + typedef rbtree_impl tree_type; + + //Non-copyable and non-assignable + multiset_impl (const multiset_impl&); + multiset_impl &operator =(const multiset_impl&); + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + multiset_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty multiset and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + multiset_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(false, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~multiset_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of multiset. + //! + //! Effects: Returns a const reference to the multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static multiset_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &multiset_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of multiset. + //! + //! Effects: Returns a const reference to the multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const multiset_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &multiset_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the multiset. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(multiset_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(reference value) + { return tree_.insert_equal(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts x into the multiset, using pos as a hint to + //! where it will be inserted. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_equal(hint, value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_equal(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.count(value); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.count(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a set/multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + /// @cond + friend bool operator==(const multiset_impl &x, const multiset_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const multiset_impl &x, const multiset_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const multiset_impl &x, const multiset_impl &y) +#else +(const multiset_impl &x, const multiset_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const multiset_impl &x, const multiset_impl &y) +#else +(const multiset_impl &x, const multiset_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const multiset_impl &x, const multiset_impl &y) +#else +(const multiset_impl &x, const multiset_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const multiset_impl &x, const multiset_impl &y) +#else +(const multiset_impl &x, const multiset_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(multiset_impl &x, multiset_impl &y) +#else +(multiset_impl &x, multiset_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_multiset +{ + /// @cond + typedef multiset_impl + < typename make_rbtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class multiset + : public make_multiset::type +{ + typedef typename make_multiset + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + multiset( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + multiset( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static multiset &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const multiset &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SET_HPP diff --git a/thirdparty/boost/intrusive/set_hook.hpp b/thirdparty/boost/intrusive/set_hook.hpp new file mode 100644 index 0000000..8310364 --- /dev/null +++ b/thirdparty/boost/intrusive/set_hook.hpp @@ -0,0 +1,274 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SET_HOOK_HPP +#define BOOST_INTRUSIVE_SET_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_set_node_algo +{ + typedef rbtree_algorithms > type; +}; +/// @endcond + +//! Helper metafunction to define a \c set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_set_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_set_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::SetBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from set_base_hook in order to store objects in +//! in a set/multiset. set_base_hook holds the data necessary to maintain +//! the set/multiset and provides an appropriate value_traits class for set/multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class set_base_hook + : public make_set_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + set_base_hook(const set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + set_base_hook& operator=(const set_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_set_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_set_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member set_member_hook in order to store objects of this class in +//! a set/multiset. set_member_hook holds the data necessary for maintaining the +//! set/multiset and provides an appropriate value_traits class for set/multiset. +//! +//! The hook admits the following options: \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c optimize_size<> will tell the hook to optimize the hook for size instead +//! of speed. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class set_member_hook + : public make_set_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + set_member_hook(const set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + set_member_hook& operator=(const set_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SET_HOOK_HPP diff --git a/thirdparty/boost/intrusive/sg_set.hpp b/thirdparty/boost/intrusive/sg_set.hpp new file mode 100644 index 0000000..61b72e7 --- /dev/null +++ b/thirdparty/boost/intrusive/sg_set.hpp @@ -0,0 +1,2147 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SG_SET_HPP +#define BOOST_INTRUSIVE_SG_SET_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! The class template sg_set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class sg_set_impl +{ + /// @cond + typedef sgtree_impl tree_type; + //! This class is + //! non-copyable + sg_set_impl (const sg_set_impl&); + + //! This class is + //! non-assignable + sg_set_impl &operator =(const sg_set_impl&); + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the value_compare object throws. + sg_set_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty sg_set and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is std::distance(last, first). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + sg_set_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(true, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the sg_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~sg_set_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of sg_set. + //! + //! Effects: Returns a const reference to the sg_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static sg_set_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &sg_set_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of sg_set. + //! + //! Effects: Returns a const reference to the sg_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const sg_set_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &sg_set_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the sg_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the sg_set. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two sets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(sg_set_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const sg_set_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the sg_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert(reference value) + { return tree_.insert_unique(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to to insert x into the sg_set, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: An iterator that points to the position where the + //! new element was inserted into the sg_set. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_unique(hint, value); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an ascapegoatitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the sg_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the sg_set. + template + std::pair insert_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(key, key_value_comp, commit_data); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an ascapegoatitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the sg_set, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the sg_set. + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the sg_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the sg_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return tree_.insert_unique_commit(value, commit_data); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the sg_set. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_unique(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size()) + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If the comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: If the internal value_compare ordering function throws. + //! + //! Complexity: O(log(size() + this->count(value)). Basic guarantee. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.find(value) != end(); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp) != end(); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a sg_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the sg_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! sg_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the sg_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! sg_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a sg_set/sg_multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { tree_.rebalance(); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return tree_.rebalance_subtree(root); } + + //! Returns: The balance factor (alpha) used in this tree + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + float balance_factor() const + { return tree_.balance_factor(); } + + //! Requires: new_alpha must be a value between 0.5 and 1.0 + //! + //! Effects: Establishes a new balance factor (alpha) and rebalances + //! the tree if the new balance factor is stricter (less) than the old factor. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + void balance_factor(float new_alpha) + { tree_.balance_factor(new_alpha); } + + /// @cond + friend bool operator==(const sg_set_impl &x, const sg_set_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const sg_set_impl &x, const sg_set_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_set_impl &x, const sg_set_impl &y) +#else +(const sg_set_impl &x, const sg_set_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_set_impl &x, const sg_set_impl &y) +#else +(const sg_set_impl &x, const sg_set_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_set_impl &x, const sg_set_impl &y) +#else +(const sg_set_impl &x, const sg_set_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_set_impl &x, const sg_set_impl &y) +#else +(const sg_set_impl &x, const sg_set_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(sg_set_impl &x, sg_set_impl &y) +#else +(sg_set_impl &x, sg_set_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c sg_set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_sg_set +{ + /// @cond + typedef sg_set_impl + < typename make_sgtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class sg_set + : public make_sg_set::type +{ + typedef typename make_sg_set + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + sg_set( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + sg_set( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static sg_set &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const sg_set &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +//! The class template sg_multiset is an intrusive container, that mimics most of +//! the interface of std::sg_multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class sg_multiset_impl +{ + /// @cond + typedef sgtree_impl tree_type; + + //Non-copyable and non-assignable + sg_multiset_impl (const sg_multiset_impl&); + sg_multiset_impl &operator =(const sg_multiset_impl&); + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + sg_multiset_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty sg_multiset and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + sg_multiset_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(false, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the sg_multiset + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~sg_multiset_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of sg_multiset. + //! + //! Effects: Returns a const reference to the sg_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static sg_multiset_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &sg_multiset_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of sg_multiset. + //! + //! Effects: Returns a const reference to the sg_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const sg_multiset_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &sg_multiset_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the sg_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the sg_multiset. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two sg_multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(sg_multiset_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const sg_multiset_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the sg_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(reference value) + { return tree_.insert_equal(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts x into the sg_multiset, using pos as a hint to + //! where it will be inserted. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_equal(hint, value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the sg_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_equal(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) const + { return tree_.count(value); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) const + { return tree_.count(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound(const_reference value) const + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound(const_reference value) const + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find(const_reference value) const + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyValueCompare comp) const + { return tree_.find(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range(const_reference value) const + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range(key, comp); } + + //! Requires: value must be an lvalue and shall be in a sg_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the sg_multiset + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! sg_multiset that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the sg_multiset + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a sg_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! sg_multiset that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a sg_multiset/sg_multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { tree_.rebalance(); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return tree_.rebalance_subtree(root); } + + //! Returns: The balance factor (alpha) used in this tree + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + float balance_factor() const + { return tree_.balance_factor(); } + + //! Requires: new_alpha must be a value between 0.5 and 1.0 + //! + //! Effects: Establishes a new balance factor (alpha) and rebalances + //! the tree if the new balance factor is stricter (less) than the old factor. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + void balance_factor(float new_alpha) + { tree_.balance_factor(new_alpha); } + + /// @cond + friend bool operator==(const sg_multiset_impl &x, const sg_multiset_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const sg_multiset_impl &x, const sg_multiset_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#else +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#else +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#else +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#else +(const sg_multiset_impl &x, const sg_multiset_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(sg_multiset_impl &x, sg_multiset_impl &y) +#else +(sg_multiset_impl &x, sg_multiset_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c sg_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_sg_multiset +{ + /// @cond + typedef sg_multiset_impl + < typename make_sgtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class sg_multiset + : public make_sg_multiset::type +{ + typedef typename make_sg_multiset + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + sg_multiset( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + sg_multiset( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static sg_multiset &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const sg_multiset &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SG_SET_HPP diff --git a/thirdparty/boost/intrusive/sgtree.hpp b/thirdparty/boost/intrusive/sgtree.hpp new file mode 100644 index 0000000..807851b --- /dev/null +++ b/thirdparty/boost/intrusive/sgtree.hpp @@ -0,0 +1,1648 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +// +// The option that yields to non-floating point 1/sqrt(2) alpha is taken +// from the scapegoat tree implementation of the PSPP library. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SGTREE_HPP +#define BOOST_INTRUSIVE_SGTREE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +namespace detail{ + +//! Returns floor(log(n)/log(sqrt(2))) -> floor(2*log2(n)) +//! Undefined if N is 0. +//! +//! This function does not use float point operations. +inline std::size_t calculate_h_sqrt2 (std::size_t n) +{ + std::size_t f_log2 = detail::floor_log2(n); + return (2*f_log2) + (n >= detail::sqrt2_pow_2xplus1 (f_log2)); +} + +struct h_alpha_sqrt2_t +{ + h_alpha_sqrt2_t(void){} + std::size_t operator()(std::size_t n) const + { return calculate_h_sqrt2(n); } +}; + +struct alpha_0_75_by_max_size_t +{ + alpha_0_75_by_max_size_t(void){} + std::size_t operator()(std::size_t max_tree_size) const + { + const std::size_t max_tree_size_limit = ((~std::size_t(0))/std::size_t(3)); + return max_tree_size > max_tree_size_limit ? max_tree_size/4*3 : max_tree_size*3/4; + } +}; + +struct h_alpha_t +{ + h_alpha_t(float inv_minus_logalpha) + : inv_minus_logalpha_(inv_minus_logalpha) + {} + + std::size_t operator()(std::size_t n) const + { + //Returns floor(log1/alpha(n)) -> + // floor(log(n)/log(1/alpha)) -> + // floor(log(n)/(-log(alpha))) + //return static_cast(std::log(float(n))*inv_minus_logalpha_); + return static_cast(detail::fast_log2(float(n))*inv_minus_logalpha_); + } + + private: + //Since the function will be repeatedly called + //precalculate constant data to avoid repeated + //calls to log and division. + //This will store 1/(-std::log(alpha_)) + float inv_minus_logalpha_; +}; + +struct alpha_by_max_size_t +{ + alpha_by_max_size_t(float alpha) + : alpha_(alpha) + {} + + float operator()(std::size_t max_tree_size) const + { return float(max_tree_size)*alpha_; } + + private: + float alpha_; + float inv_minus_logalpha_; +}; + +template +struct alpha_holder +{ + typedef boost::intrusive::detail::h_alpha_t h_alpha_t; + typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t; + + alpha_holder() + { set_alpha(0.7f); } + + float get_alpha() const + { return alpha_; } + + void set_alpha(float alpha) + { + alpha_ = alpha; + inv_minus_logalpha_ = 1/(-detail::fast_log2(alpha)); + } + + h_alpha_t get_h_alpha_t() const + { return h_alpha_t(inv_minus_logalpha_); } + + multiply_by_alpha_t get_multiply_by_alpha_t() const + { return multiply_by_alpha_t(alpha_); } + + private: + float alpha_; + float inv_minus_logalpha_; +}; + +template<> +struct alpha_holder +{ + //This specialization uses alpha = 1/sqrt(2) + //without using floating point operations + //Downside: alpha CAN't be changed. + typedef boost::intrusive::detail::h_alpha_sqrt2_t h_alpha_t; + typedef boost::intrusive::detail::alpha_0_75_by_max_size_t multiply_by_alpha_t; + + float get_alpha() const + { return 0.70710677f; } + + void set_alpha(float) + { //alpha CAN't be changed. + assert(0); + } + + h_alpha_t get_h_alpha_t() const + { return h_alpha_t(); } + + multiply_by_alpha_t get_multiply_by_alpha_t() const + { return multiply_by_alpha_t(); } +}; + +} //namespace detail{ + +template +struct sg_setopt +{ + typedef ValueTraits value_traits; + typedef Compare compare; + typedef SizeType size_type; + static const bool floating_point = FloatingPoint; +}; + +template +struct sg_set_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_bs_set_hook::value + , get_default_bs_set_hook + , detail::identity + >::type + > + , floating_point + , size_type + , compare > + >::type +{}; + +/// @endcond + +//! The class template sgtree is an intrusive scapegoat tree container, that +//! is used to construct intrusive sg_set and sg_multiset containers. +//! The no-throw guarantee holds only, if the value_compare object +//! doesn't throw. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c floating_point<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class sgtree_impl +{ + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef value_type key_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef typename Config::compare value_compare; + typedef value_compare key_compare; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef sgtree_algorithms node_algorithms; + + static const bool floating_point = Config::floating_point; + static const bool constant_time_size = true; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + + /// @cond + private: + typedef detail::size_holder size_traits; + typedef detail::alpha_holder alpha_traits; + typedef typename alpha_traits::h_alpha_t h_alpha_t; + typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t; + + //noncopyable + sgtree_impl (const sgtree_impl&); + sgtree_impl operator =(const sgtree_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + BOOST_STATIC_ASSERT(((int)real_value_traits::link_mode != (int)auto_unlink)); + + //BOOST_STATIC_ASSERT(( + // (int)real_value_traits::link_mode != (int)auto_unlink || + // !floating_point + // )); + + struct header_plus_alpha : public alpha_traits + { node header_; }; + + struct node_plus_pred_t : public detail::ebo_functor_holder + { + node_plus_pred_t(const value_compare &comp) + : detail::ebo_functor_holder(comp) + {} + header_plus_alpha header_plus_alpha_; + size_traits size_traits_; + }; + + struct data_t : public sgtree_impl::value_traits + { + typedef typename sgtree_impl::value_traits value_traits; + data_t(const value_compare & comp, const value_traits &val_traits) + : value_traits(val_traits), node_plus_pred_(comp) + , max_tree_size_(0) + {} + node_plus_pred_t node_plus_pred_; + size_type max_tree_size_; + } data_; + + float priv_alpha() const + { return this->priv_alpha_traits().get_alpha(); } + + void priv_alpha(float alpha) + { return this->priv_alpha_traits().set_alpha(alpha); } + + const value_compare &priv_comp() const + { return data_.node_plus_pred_.get(); } + + value_compare &priv_comp() + { return data_.node_plus_pred_.get(); } + + const node &priv_header() const + { return data_.node_plus_pred_.header_plus_alpha_.header_; } + + node &priv_header() + { return data_.node_plus_pred_.header_plus_alpha_.header_; } + + static node_ptr uncast(const_node_ptr ptr) + { return node_ptr(const_cast(detail::get_pointer(ptr))); } + + size_traits &priv_size_traits() + { return data_.node_plus_pred_.size_traits_; } + + const size_traits &priv_size_traits() const + { return data_.node_plus_pred_.size_traits_; } + + alpha_traits &priv_alpha_traits() + { return data_.node_plus_pred_.header_plus_alpha_; } + + const alpha_traits &priv_alpha_traits() const + { return data_.node_plus_pred_.header_plus_alpha_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + h_alpha_t get_h_alpha_func() const + { return priv_alpha_traits().get_h_alpha_t(); } + + multiply_by_alpha_t get_alpha_by_max_size_func() const + { return priv_alpha_traits().get_multiply_by_alpha_t(); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + sgtree_impl( value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty tree and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + template + sgtree_impl( bool unique, Iterator b, Iterator e + , value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + ~sgtree_impl() + { this->clear(); } + + //! Effects: Returns an iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return cbegin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns an iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return iterator (node_ptr(&priv_header()), this); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return cend(); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return const_iterator (uncast(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + //! Precondition: end_iterator must be a valid end iterator + //! of sgtree. + //! + //! Effects: Returns a const reference to the sgtree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static sgtree_impl &container_from_end_iterator(iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of sgtree. + //! + //! Effects: Returns a const reference to the sgtree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the value_compare object used by the tree. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return priv_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return node_algorithms::unique(const_node_ptr(&priv_header())); } + + //! Effects: Returns the number of elements stored in the tree. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else{ + return (size_type)node_algorithms::size(const_node_ptr(&priv_header())); + } + } + + //! Effects: Swaps the contents of two multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(sgtree_impl& other) + { + //This can throw + using std::swap; + swap(priv_comp(), priv_comp()); + swap(priv_alpha_traits(), priv_alpha_traits()); + swap(data_.max_tree_size_, other.data_.max_tree_size_); + //These can't throw + node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header())); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree before the upper bound. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; + node_ptr p = node_algorithms::insert_equal_upper_bound + (node_ptr(&priv_header()), to_insert, key_node_comp + , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size); + data_.max_tree_size_ = (size_type)max_tree_size; + return iterator(p, this); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; + node_ptr p = node_algorithms::insert_equal + (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp + , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size); + data_.max_tree_size_ = (size_type)max_tree_size; + return iterator(p, this); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the tree + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + iterator end(this->end()); + for (; b != e; ++b) + this->insert_equal(end, *b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree if the value + //! is not already present. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(value, commit_data); + if(!ret.second) + return ret; + return std::pair (insert_unique_commit(value, commit_data), true); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the tree, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(hint, value, commit_data); + if(!ret.second) + return ret.first; + return insert_unique_commit(value, commit_data); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the tree. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + if(this->empty()){ + iterator end(this->end()); + for (; b != e; ++b) + this->insert_unique(end, *b); + } + else{ + for (; b != e; ++b) + this->insert_unique(*b); + } + } + + std::pair insert_unique_check + (const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + std::pair insert_unique_check + (const_iterator hint, const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(hint, value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; + node_algorithms::insert_unique_commit + ( node_ptr(&priv_header()), to_insert, commit_data + , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size); + data_.max_tree_size_ = (size_type)max_tree_size; + return iterator(to_insert, this); + } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { + iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + std::size_t max_tree_size = data_.max_tree_size_; + node_algorithms::erase + ( &priv_header(), to_erase, (std::size_t)this->size() + , max_tree_size, this->get_alpha_by_max_size_func()); + data_.max_tree_size_ = (size_type)max_tree_size; + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret; + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { size_type n; return private_erase(b, e, n); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, priv_comp()); } + + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + return ret; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { size_type n; return private_erase(b, e, n, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { + std::pair p = this->equal_range(value); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Average complexity for is at most O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. Calls N times to disposer functor. + template + void clear_and_dispose(Disposer disposer) + { + node_algorithms::clear_and_dispose(node_ptr(&priv_header()) + , detail::node_disposer(disposer, this)); + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count(const_reference value) const + { return this->count(value, priv_comp()); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + return std::distance(ret.first, ret.second); + } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator lower_bound(const_reference value) + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator lower_bound(const_reference value) const + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator upper_bound(const_reference value) + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator upper_bound(const_reference value) const + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator find(const_reference value) + { return this->find(value, priv_comp()); } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator find(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator find(const_reference value) const + { return this->find(value, priv_comp()); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator find(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair equal_range(const_reference value) + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair + equal_range(const_reference value) const + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair + equal_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + node_algorithms::clone + (const_node_ptr(&src.priv_header()) + ,node_ptr(&this->priv_header()) + ,detail::node_cloner(cloner, this) + ,detail::node_disposer(disposer, this)); + this->priv_size_traits().set_size(src.priv_size_traits().get_size()); + } + } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { + node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance + (node_ptr(&priv_header()))); + if(!to_be_disposed) + return 0; + this->priv_size_traits().decrement(); + if(safemode_or_autounlink)//If this is commented does not work with normal_link + node_algorithms::init(to_be_disposed); + return get_real_value_traits().to_value_ptr(to_be_disposed); + } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + , node_ptr(&priv_header()) + , get_real_value_traits().to_node_ptr(with_this)); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return iterator (value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return iterator (value_traits::to_node_ptr(value), this); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } + + //! Requires: value shall not be in a tree. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { node_algorithms::rebalance(node_ptr(&priv_header())); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this); } + + //! Returns: The balance factor (alpha) used in this tree + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + float balance_factor() const + { return this->priv_alpha(); } + + //! Requires: new_alpha must be a value between 0.5 and 1.0 + //! + //! Effects: Establishes a new balance factor (alpha) and rebalances + //! the tree if the new balance factor is stricter (less) than the old factor. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + void balance_factor(float new_alpha) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT((new_alpha > 0.5f && new_alpha < 1.0f)); + if(new_alpha < 0.5f && new_alpha >= 1.0f) return; + + //The alpha factor CAN't be changed if the fixed, floating operation-less + //1/sqrt(2) alpha factor option is activated + BOOST_STATIC_ASSERT((floating_point)); + float old_alpha = this->priv_alpha(); + this->priv_alpha(new_alpha); + + if(new_alpha < old_alpha){ + data_.max_tree_size_ = this->size(); + this->rebalance(); + } + } +/* + //! Effects: removes x from a tree of the appropriate type. It has no effect, + //! if x is not in such a tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This static function is only usable with the "safe mode" + //! hook and non-constant time size lists. Otherwise, the user must use + //! the non-static "erase(reference )" member. If the user calls + //! this function with a non "safe mode" or constant time size list + //! a compilation error will be issued. + template + static void remove_node(T& value) + { + //This function is only usable for safe mode hooks and non-constant + //time lists. + //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size))); + BOOST_STATIC_ASSERT((!constant_time_size)); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink_and_rebalance(to_remove); + if(safemode_or_autounlink) + node_algorithms::init(to_remove); + } +*/ + + /// @cond + private: + template + iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer) + { + for(n = 0; b != e; ++n) + this->erase_and_dispose(b++, disposer); + return b; + } + + iterator private_erase(iterator b, iterator e, size_type &n) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b; + } + /// @endcond + + private: + static sgtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + header_plus_alpha *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_alpha::header_); + node_plus_pred_t *n = detail::parent_from_member + (r, &node_plus_pred_t::header_plus_alpha_); + data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); + sgtree_impl *scapegoat = detail::parent_from_member(d, &sgtree_impl::data_); + return *scapegoat; + } +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ + typedef sgtree_impl tree_type; + typedef typename tree_type::const_iterator const_iterator; + + if(tree_type::constant_time_size && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(tree_type::constant_time_size){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const sgtree_impl &x, const sgtree_impl &y) +#else +(const sgtree_impl &x, const sgtree_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(sgtree_impl &x, sgtree_impl &y) +#else +(sgtree_impl &x, sgtree_impl &y) +#endif +{ x.swap(y); } + +/// @cond +template +struct make_sgtree_opt +{ + typedef typename pack_options + < sg_set_defaults, O1, O2, O3, O4>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + + typedef sg_setopt + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::floating_point + > type; +}; +/// @endcond + +//! Helper metafunction to define a \c sgtree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_sgtree +{ + /// @cond + typedef sgtree_impl + < typename make_sgtree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class sgtree + : public make_sgtree::type +{ + typedef typename make_sgtree + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + sgtree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + sgtree( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + static sgtree &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const sgtree &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SGTREE_HPP diff --git a/thirdparty/boost/intrusive/sgtree_algorithms.hpp b/thirdparty/boost/intrusive/sgtree_algorithms.hpp new file mode 100644 index 0000000..1d7c19a --- /dev/null +++ b/thirdparty/boost/intrusive/sgtree_algorithms.hpp @@ -0,0 +1,704 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +// +// Scapegoat tree algorithms are taken from the paper titled: +// "Scapegoat Trees" by Igal Galperin Ronald L. Rivest. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP + +#include + +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +//! sgtree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +template +class sgtree_algorithms +{ + public: + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + + /// @cond + private: + + typedef typename NodeTraits::node node; + typedef detail::tree_algorithms tree_algorithms; + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + } + /// @endcond + + public: + static node_ptr begin_node(const_node_ptr header) + { return tree_algorithms::begin_node(header); } + + static node_ptr end_node(const_node_ptr header) + { return tree_algorithms::end_node(header); } + + //! This type is the information that will be + //! filled by insert_unique_check + struct insert_commit_data + : tree_algorithms::insert_commit_data + { + std::size_t depth; + }; + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) + { return tree_algorithms::swap_tree(header1, header2); } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) + { + if(node1 == node2) + return; + + node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + { tree_algorithms::swap_nodes(node1, header1, node2, header2); } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing and comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + { tree_algorithms::replace_node(node_to_be_replaced, header, new_node); } + + //! Requires: node is a tree node but not the header. + //! + //! Effects: Unlinks the node and rebalances the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + static void unlink(node_ptr node) + { + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + tree_algorithms::erase(x, node); + } + } + + //! Requires: header is the header of a tree. + //! + //! Effects: Unlinks the leftmost node from the tree, and + //! updates the header link to the new leftmost node. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + { return tree_algorithms::unlink_leftmost_without_rebalance(header); } + + //! Requires: node is a node of the tree or an node initialized + //! by init(...). + //! + //! Effects: Returns true if the node is initialized by init(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + static bool unique(const_node_ptr node) + { return tree_algorithms::unique(node); } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr node) + { return tree_algorithms::count(node); } + + //! Requires: header is the header node of the tree. + //! + //! Effects: Returns the number of nodes above the header. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) + { return tree_algorithms::size(header); } + + //! Requires: p is a node from the tree except the header. + //! + //! Effects: Returns the next node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr next_node(node_ptr p) + { return tree_algorithms::next_node(p); } + + //! Requires: p is a node from the tree except the leftmost node. + //! + //! Effects: Returns the previous node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr prev_node(node_ptr p) + { return tree_algorithms::prev_node(p); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr node) + { tree_algorithms::init(node); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) + { tree_algorithms::init_header(header); } + + //! Requires: header must be the header of a tree, z a node + //! of that tree and z != header. + //! + //! Effects: Erases node "z" from the tree with header "header". + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + template + static node_ptr erase(node_ptr header, node_ptr z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize) + { + //typename tree_algorithms::data_for_rebalance info; + tree_algorithms::erase(header, z); + --tree_size; + if (tree_size > 0 && + tree_size < alpha_by_maxsize(max_tree_size)){ + tree_algorithms::rebalance(header); + max_tree_size = tree_size; + } + return z; + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Then, duplicates the entire tree pointed by "source_header" cloning each + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! are disposed using void disposer(node_ptr). + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { + tree_algorithms::clone(source_header, target_header, cloner, disposer); + } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) + { tree_algorithms::clear_and_dispose(header, disposer); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::lower_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::upper_bound(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::find(header, key, comp); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if they there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { return tree_algorithms::equal_range(header, key, comp); } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the upper bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_upper_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + { + std::size_t depth; + tree_algorithms::insert_equal_upper_bound(h, new_node, comp, &depth); + rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); + return new_node; + } + + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the lower bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal_lower_bound + (node_ptr h, node_ptr new_node, NodePtrCompare comp + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + { + std::size_t depth; + tree_algorithms::insert_equal_lower_bound(h, new_node, comp, &depth); + rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + { + std::size_t depth; + tree_algorithms::insert_equal(header, hint, new_node, comp, &depth); + rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); + return new_node; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { + std::size_t depth; + std::pair ret = + tree_algorithms::insert_unique_check(header, key, comp, commit_data, &depth); + commit_data.depth = depth; + return ret; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! "hint" is node from the "header"'s tree. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" using "hint" as a hint to where it should be + //! inserted and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! If "hint" is the upper_bound the function has constant time + //! complexity (two comparisons in the worst case). + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic, but it is + //! amortized constant time if new_node should be inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (const_node_ptr header, node_ptr hint, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { + std::size_t depth; + std::pair ret = + tree_algorithms::insert_unique_check + (header, hint, key, comp, commit_data, &depth); + commit_data.depth = depth; + return ret; + } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + template + static void insert_unique_commit + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + { + tree_algorithms::insert_unique_commit(header, new_value, commit_data); + rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size); + } + + //! Requires: header must be the header of a tree. + //! + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static void rebalance(node_ptr header) + { tree_algorithms::rebalance(header); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static node_ptr rebalance_subtree(node_ptr old_root) + { return tree_algorithms::rebalance_subtree(old_root); } + + /// @cond + private: + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_header(const_node_ptr p) + { return tree_algorithms::is_header(p); } + + template + static void rebalance_after_insertion + ( node_ptr x, std::size_t depth + , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + { + if(tree_size > max_tree_size) + max_tree_size = tree_size; + + if(tree_size != 1 && depth > h_alpha(tree_size)){ + //Find the first non height-balanced node + //as described in the section 4.2 of the paper. + //This method is the alternative method described + //in the paper. Authors claim that this method + //may tend to yield more balanced trees on the average + //than the weight balanced method. + node_ptr s = x; + std::size_t size = 1; + + for(std::size_t i = 1; true; ++i){ + bool rebalance = false; + if(i == depth){ + assert(tree_size == count(s)); + rebalance = true; + } + else if(i > h_alpha(size)){ + node_ptr s_parent = NodeTraits::get_parent(s); + node_ptr s_parent_left = NodeTraits::get_left(s_parent); + size += 1 + tree_algorithms::count + ( s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left ); + s = s_parent; + rebalance = true; + } + if(rebalance){ + rebalance_subtree(s); + break; + } + } + } + } + + /// @endcond +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/slist.hpp b/thirdparty/boost/intrusive/slist.hpp new file mode 100644 index 0000000..a7b0e11 --- /dev/null +++ b/thirdparty/boost/intrusive/slist.hpp @@ -0,0 +1,1858 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SLIST_HPP +#define BOOST_INTRUSIVE_SLIST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //std::size_t +#include //std::pair + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct internal_default_slist_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_slist_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_slist_hook +{ typedef typename T::default_slist_hook type; }; + +template +struct slistopt +{ + typedef ValueTraits value_traits; + typedef SizeType size_type; + static const bool constant_time_size = ConstantTimeSize; + static const bool linear = Linear; + static const bool cache_last = CacheLast; +}; + +template +struct root_plus_last +{ + Node root_; + NodePtr last_; +}; + +template +struct root_plus_last +{ + Node root_; +}; + +template +struct slist_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_slist_hook::value + , get_default_slist_hook + , detail::identity + >::type + > + , constant_time_size + , linear + , size_type + , cache_last + >::type +{}; + +/// @endcond + +//! The class template slist is an intrusive container, that encapsulates +//! a singly-linked list. You can use such a list to squeeze the last bit +//! of performance from your application. Unfortunately, the little gains +//! come with some huge drawbacks. A lot of member functions can't be +//! implemented as efficiently as for standard containers. To overcome +//! this limitation some other member functions with rather unusual semantics +//! have to be introduced. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<>, +//! \c linear<> and \c cache_last<>. +//! +//! The iterators of slist are forward iterators. slist provides a static +//! function called "previous" to compute the previous iterator of a given iterator. +//! This function has linear complexity. To improve the usability esp. with +//! the '*_after' functions, ++end() == begin() and previous(begin()) == end() +//! are defined. An new special function "before_begin()" is defined, which returns +//! an iterator that points one less the beginning of the list: ++before_begin() == begin() +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class slist_impl +{ + //Public typedefs + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef slist_iterator iterator; + typedef slist_iterator const_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef typename detail::if_c + < Config::linear + , linear_slist_algorithms + , circular_slist_algorithms + >::type node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + static const bool linear = Config::linear; + static const bool cache_last = Config::cache_last; + + /// @cond + private: + typedef detail::size_holder size_traits; + + //! This class is + //! non-copyable + slist_impl (const slist_impl&); + + //! This class is + //! non-asignable + slist_impl &operator =(const slist_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + //Linear singly linked lists are incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink))); + //A list with cached last node is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + node_ptr get_end_node() + { return node_ptr(linear ? 0 : this->get_root_node()); } + + const_node_ptr get_end_node() const + { return const_node_ptr(linear ? 0 : this->get_root_node()); } + + node_ptr get_root_node() + { return node_ptr(&data_.root_plus_size_.root_); } + + const_node_ptr get_root_node() const + { return const_node_ptr(&data_.root_plus_size_.root_); } + + node_ptr get_last_node() + { return this->get_last_node(detail::bool_()); } + + const_node_ptr get_last_node() const + { return this->get_last_node(detail::bool_()); } + + void set_last_node(node_ptr n) + { return this->set_last_node(n, detail::bool_()); } + + node_ptr get_last_node(detail::bool_) + { return node_ptr(0); } + + const_node_ptr get_last_node(detail::bool_) const + { return const_node_ptr(0); } + + void set_last_node(node_ptr, detail::bool_) + {} + + node_ptr get_last_node(detail::bool_) + { return node_ptr(data_.root_plus_size_.last_); } + + const_node_ptr get_last_node(detail::bool_) const + { return const_node_ptr(data_.root_plus_size_.last_); } + + void set_last_node(node_ptr n, detail::bool_) + { data_.root_plus_size_.last_ = n; } + + static node_ptr uncast(const_node_ptr ptr) + { return node_ptr(const_cast(detail::get_pointer(ptr))); } + + void set_default_constructed_state() + { + node_algorithms::init_header(this->get_root_node()); + this->priv_size_traits().set_size(size_type(0)); + if(cache_last){ + this->set_last_node(this->get_root_node()); + } + } + + struct root_plus_size + : public size_traits + , public root_plus_last + {}; + + struct data_t + : public slist_impl::value_traits + { + typedef typename slist_impl::value_traits value_traits; + data_t(const value_traits &val_traits) + : value_traits(val_traits) + {} + + root_plus_size root_plus_size_; + } data_; + + size_traits &priv_size_traits() + { return data_.root_plus_size_; } + + const size_traits &priv_size_traits() const + { return data_.root_plus_size_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + public: + //! Effects: constructs an empty list. + //! + //! Complexity: Constant + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + slist_impl(const value_traits &v_traits = value_traits()) + : data_(v_traits) + { this->set_default_constructed_state(); } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! + //! Effects: Constructs a list equal to [first,last). + //! + //! Complexity: Linear in std::distance(b, e). No copy constructors are called. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). + template + slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : data_(v_traits) + { + this->set_default_constructed_state(); + this->insert_after(this->before_begin(), b, e); + } + + //! Effects: If it's a safe-mode + //! or auto-unlink value, the destructor does nothing + //! (ie. no code is generated). Otherwise it detaches all elements from this. + //! In this case the objects in the list are not deleted (i.e. no destructors + //! are called), but the hooks according to the value_traits template parameter + //! are set to their default value. + //! + //! Complexity: Linear to the number of elements in the list, if + //! it's a safe-mode or auto-unlink value. Otherwise constant. + ~slist_impl() + { this->clear(); } + + //! Effects: Erases all the elements of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Note: Invalidates the iterators (but not the references) to the erased elements. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + this->set_default_constructed_state(); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of the list. + //! + //! Note: Invalidates the iterators to the erased elements. + template + void clear_and_dispose(Disposer disposer) + { + iterator it(this->begin()), itend(this->end()); + while(it != itend){ + node_ptr to_erase(it.pointed_node()); + ++it; + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + } + this->set_default_constructed_state(); + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the front of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + void push_front(reference value) + { + node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); + if(cache_last){ + if(this->empty()){ + this->set_last_node(to_insert); + } + } + node_algorithms::link_after(this->get_root_node(), to_insert); + this->priv_size_traits().increment(); + } + + //! Requires: value must be an lvalue. + //! + //! Effects: Inserts the value in the back of the list. + //! No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + //! This function is only available is cache_last<> is true. + void push_back(reference value) + { + BOOST_STATIC_ASSERT((cache_last != 0)); + this->insert_after(iterator(this->get_last_node(), this), value); + } + + //! Effects: Erases the first element of the list. + //! No destructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the erased element. + void pop_front() + { return this->pop_front_and_dispose(detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the first element of the list. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + void pop_front_and_dispose(Disposer disposer) + { + node_ptr to_erase = node_traits::get_next(this->get_root_node()); + node_algorithms::unlink_after(this->get_root_node()); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + if(cache_last){ + if(this->empty()){ + this->set_last_node(this->get_root_node()); + } + } + } + + //! Effects: Returns a reference to the first element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() + { return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } + + //! Effects: Returns a const_reference to the first element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const + { return *this->get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); } + + //! Effects: Returns a reference to the last element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + //! This function is only available is cache_last<> is true. + reference back() + { + BOOST_STATIC_ASSERT((cache_last != 0)); + return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); + } + + //! Effects: Returns a const_reference to the last element of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + //! This function is only available is cache_last<> is true. + const_reference back() const + { + BOOST_STATIC_ASSERT((cache_last != 0)); + return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); + } + + //! Effects: Returns an iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator begin() + { return iterator (node_traits::get_next(this->get_root_node()), this); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator begin() const + { return const_iterator (node_traits::get_next(this->get_root_node()), this); } + + //! Effects: Returns a const_iterator to the first element contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const + { return const_iterator(node_traits::get_next(this->get_root_node()), this); } + + //! Effects: Returns an iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator end() + { return iterator(this->get_end_node(), this); } + + //! Effects: Returns a const_iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator end() const + { return const_iterator(uncast(this->get_end_node()), this); } + + //! Effects: Returns a const_iterator to the end of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const + { return this->end(); } + + //! Effects: Returns an iterator that points to a position + //! before the first element. Equivalent to "end()" + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + iterator before_begin() + { return iterator(this->get_root_node(), this); } + + //! Effects: Returns an iterator that points to a position + //! before the first element. Equivalent to "end()" + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator before_begin() const + { return const_iterator(uncast(this->get_root_node()), this); } + + //! Effects: Returns an iterator that points to a position + //! before the first element. Equivalent to "end()" + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbefore_begin() const + { return this->before_begin(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of slist. + //! + //! Effects: Returns a const reference to the slist associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static slist_impl &container_from_end_iterator(iterator end_iterator) + { return slist_impl::priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of slist. + //! + //! Effects: Returns a const reference to the slist associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const slist_impl &container_from_end_iterator(const_iterator end_iterator) + { return slist_impl::priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the number of the elements contained in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements contained in the list. + //! if constant_time_size is false. Constant time otherwise. + //! + //! Note: Does not affect the validity of iterators and references. + size_type size() const + { + if(constant_time_size) + return this->priv_size_traits().get_size(); + else + return node_algorithms::count(this->get_root_node()) - 1; + } + + //! Effects: Returns true if the list contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + bool empty() const + { return node_algorithms::unique(this->get_root_node()); } + + //! Effects: Swaps the elements of x and *this. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements of both lists. + //! Constant-time if linear<> and/or cache_last<> options are used. + //! + //! Note: Does not affect the validity of iterators and references. + void swap(slist_impl& other) + { + if(cache_last){ + this->priv_swap_cache_last(other); + } + else{ + this->priv_swap_lists(this->get_root_node(), other.get_root_node(), detail::bool_()); + } + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Effects: Moves backwards all the elements, so that the first + //! element becomes the second, the second becomes the third... + //! the last element becomes the first one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number shifts. + //! + //! Note: Iterators Does not affect the validity of iterators and references. + void shift_backwards(size_type n = 1) + { this->priv_shift_backwards(n, detail::bool_()); } + + //! Effects: Moves forward all the elements, so that the second + //! element becomes the first, the third becomes the second... + //! the first element becomes the last one. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number shifts. + //! + //! Note: Does not affect the validity of iterators and references. + void shift_forward(size_type n = 1) + { this->priv_shift_forward(n, detail::bool_()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const slist_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + BOOST_INTRUSIVE_TRY{ + iterator prev(this->before_begin()); + const_iterator b(src.begin()), e(src.end()); + for(; b != e; ++b){ + prev = this->insert_after(prev, *cloner(*b)); + } + } + BOOST_INTRUSIVE_CATCH(...){ + this->clear_and_dispose(disposer); + BOOST_INTRUSIVE_RETHROW; + } + BOOST_INTRUSIVE_CATCH_END + } + + //! Requires: value must be an lvalue and prev_p must point to an element + //! contained by the list or to end(). + //! + //! Effects: Inserts the value after the position pointed by prev_p. + //! No copy constructor is called. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Does not affect the validity of iterators and references. + iterator insert_after(iterator prev_p, reference value) + { + node_ptr n = get_real_value_traits().to_node_ptr(value); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); + node_ptr prev_n(prev_p.pointed_node()); + node_algorithms::link_after(prev_n, n); + if(cache_last && (this->get_last_node() == prev_n)){ + this->set_last_node(n); + } + this->priv_size_traits().increment(); + return iterator (n, this); + } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type and prev_p must point to an element + //! contained by the list or to the end node. + //! + //! Effects: Inserts the [first, last) + //! after the position prev_p. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted. + //! + //! Note: Does not affect the validity of iterators and references. + template + void insert_after(iterator prev_p, Iterator first, Iterator last) + { + for (; first != last; ++first) + prev_p = this->insert_after(prev_p, *first); + } + + //! Requires: value must be an lvalue and p must point to an element + //! contained by the list or to end(). + //! + //! Effects: Inserts the value before the position pointed by p. + //! No copy constructor is called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before p. + //! Constant-time if cache_last<> is true and p == end(). + //! + //! Note: Does not affect the validity of iterators and references. + iterator insert(iterator p, reference value) + { return this->insert_after(this->previous(p), value); } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type and p must point to an element + //! contained by the list or to the end node. + //! + //! Effects: Inserts the pointed by b and e + //! before the position p. No copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus linear + //! to the elements before b. + //! Linear to the number of elements to insert if cache_last<> option is true and p == end(). + //! + //! Note: Does not affect the validity of iterators and references. + template + void insert(iterator p, Iterator b, Iterator e) + { return this->insert_after(this->previous(p), b, e); } + + //! Effects: Erases the element after the element pointed by prev of + //! the list. No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + iterator erase_after(iterator prev) + { return this->erase_after_and_dispose(prev, detail::null_disposer()); } + + //! Effects: Erases the range (before_first, last) from + //! the list. No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Lineal to the elements (last - before_first + 1). + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + iterator erase_after(iterator before_first, iterator last) + { return this->erase_after_and_dispose(before_first, last, detail::null_disposer()); } + + //! Effects: Erases the element pointed by i of the list. + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements before i. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + iterator erase(iterator i) + { return this->erase_after(this->previous(i)); } + + //! Requires: first and last must be valid iterator to elements in *this. + //! + //! Effects: Erases the range pointed by b and e. + //! No destructors are called. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements erased plus linear + //! to the elements before first. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased elements. + iterator erase(iterator first, iterator last) + { return this->erase_after(this->previous(first), last); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element after the element pointed by prev of + //! the list. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Invalidates the iterators to the erased element. + template + iterator erase_after_and_dispose(iterator prev, Disposer disposer) + { + iterator it(prev); + ++it; + node_ptr to_erase(it.pointed_node()); + ++it; + node_ptr prev_n(prev.pointed_node()); + node_algorithms::unlink_after(prev_n); + if(cache_last && (to_erase == this->get_last_node())){ + this->set_last_node(prev_n); + } + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + return it; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range (before_first, last) from + //! the list. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Lineal to the elements (last - before_first). + //! + //! Note: Invalidates the iterators to the erased element. + template + iterator erase_after_and_dispose(iterator before_first, iterator last, Disposer disposer) + { + node_ptr bfp(before_first.pointed_node()), lp(last.pointed_node()); + node_ptr fp(node_traits::get_next(bfp)); + node_algorithms::unlink_after(bfp, lp); + while(fp != lp){ + node_ptr to_erase(fp); + fp = node_traits::get_next(fp); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + this->priv_size_traits().decrement(); + } + if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){ + this->set_last_node(bfp); + } + return last; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed by i of the list. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Returns: the first element remaining beyond the removed element, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements before i. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased element. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return this->erase_after_and_dispose(this->previous(i), disposer); } + + //! Requires: first and last must be valid iterator to elements in *this. + //! Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed by b and e. + //! No destructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: the first element remaining beyond the removed elements, + //! or end() if no such element exists. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements erased plus linear + //! to the elements before first. + //! + //! Note: Invalidates the iterators (but not the references) to the + //! erased elements. + template + iterator erase_and_dispose(iterator first, iterator last, Disposer disposer) + { return this->erase_after_and_dispose(this->previous(first), last, disposer); } + + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list if it's a safe-mode + //! or auto-unlink value. + //! Linear to the number of elements inserted in the list otherwise. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void assign(Iterator b, Iterator e) + { + this->clear(); + this->insert_after(this->before_begin(), b, e); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Requires: Dereferencing iterator must yield + //! an lvalue of type value_type. + //! + //! Effects: Clears the list and inserts the range pointed by b and e. + //! No destructors or copy constructors are called. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements inserted plus + //! linear to the elements contained in the list. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. + template + void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) + { + this->clear_and_dispose(disposer); + this->insert_after(this->before_begin(), b, e, disposer); + } + + //! Requires: prev is an iterator to an element or x.end()/x.before_begin() in x. + //! + //! Effects: Transfers all the elements of list x to this list, after the + //! the element pointed by prev. No destructors or copy constructors are called. + //! + //! Returns: The last element inserted of x or prev if x is empty. + //! This iterator can be used as new "prev" iterator for a new splice_after call. + //! that will splice new values after the previously spliced values. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements contained in x. + //! Constant-time if cache_last<> option is true. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + iterator splice_after(iterator prev, slist_impl &x) + { + if (!x.empty()){ + iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active + node_ptr prev_n(prev.pointed_node()); + node_ptr last_x_n(last_x.pointed_node()); + if(cache_last && node_traits::get_next(prev_n) == this->get_end_node()){ + this->set_last_node(last_x_n); + } + node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n); + this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size()); + x.priv_size_traits().set_size(size_type(0)); + return last_x; + } + else{ + return prev; + } + } + + //! Requires: prev must point to an element contained by this list or + //! to the before_begin() element. prev_ele must point to an element contained in list + //! x or must be x.before_begin(). + //! + //! Effects: Transfers the element after prev_ele, from list x to this list, + //! after the element pointed by prev. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist_impl &x, iterator prev_ele) + { + iterator elem = prev_ele; + ++elem; + if (elem != prev_pos && prev_ele != prev_pos){ + this->splice_after(prev_pos, x, prev_ele, elem, 1); + } + } + + //! Requires: prev_pos must be a dereferenceable iterator in *this or be + //! before_begin(), and before_first and before_last belong to x and + //! ++before_first != x.end() && before_last != x.end(). + //! + //! Effects: Transfers the range (before_first, before_last] from list x to this + //! list, after the element pointed by prev_pos. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements transferred + //! if constant_time_size is true. Constant-time otherwise. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last) + { + if(constant_time_size) + this->splice_after(prev_pos, x, before_first, before_last, std::distance(before_first, before_last)); + else + this->priv_splice_after + (prev_pos.pointed_node(), x, before_first.pointed_node(), before_last.pointed_node()); + } + + //! Requires: prev_pos must be a dereferenceable iterator in *this or be + //! before_begin(), and before_first and before_last belong to x and + //! ++before_first != x.end() && before_last != x.end() and + //! n == std::distance(before_first, before_last). + //! + //! Effects: Transfers the range (before_first, before_last] from list x to this + //! list, after the element pointed by p. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last, difference_type n) + { + if(n){ + BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n); + this->priv_splice_after + (prev_pos.pointed_node(), x, before_first.pointed_node(), before_last.pointed_node()); + if(constant_time_size){ + this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n); + x.priv_size_traits().set_size(x.priv_size_traits().get_size() - n); + } + } + } + + //! Requires: it is an iterator to an element in x. + //! + //! Effects: Transfers all the elements of list x to this list, before the + //! the element pointed by it. No destructors or copy constructors are called. + //! + //! Returns: The last element inserted of x or the previous element + //! of it if x is empty. + //! This iterator can be used as new "prev" iterator for a new splice call. + //! that will splice new values after the previously spliced values. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements contained in x plus linear to + //! the elements before it. + //! Linear to the elements before it if cache_last<> option is true. + //! Constant-time if cache_last<> option is true and it == end(). + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + iterator splice(iterator it, slist_impl &x) + { return this->splice_after(this->previous(it), x); } + + //! Requires: it p must be a valid iterator of *this. + //! elem must point to an element contained in list + //! x. + //! + //! Effects: Transfers the element elem, from list x to this list, + //! before the element pointed by pos. No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements before pos and before elem. + //! Linear to the elements before elem if cache_last<> option is true and pos == end(). + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator pos, slist_impl &x, iterator elem) + { return this->splice_after(this->previous(pos), x, x.previous(elem)); } + + //! Requires: pos must be a dereferenceable iterator in *this + //! and first and last belong to x and first and last a valid range on x. + //! + //! Effects: Transfers the range [first, last) from list x to this + //! list, before the element pointed by pos. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the sum of elements before pos, first, and last + //! plus linear to the number of elements transferred if constant_time_size is true. + //! Linear to the sum of elements before first, and last + //! plus linear to the number of elements transferred if constant_time_size is true + //! if cache_last<> is true and pos == end() + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator pos, slist_impl &x, iterator first, iterator last) + { return this->splice_after(this->previous(pos), x, x.previous(first), x.previous(last)); } + + //! Requires: pos must be a dereferenceable iterator in *this + //! and first and last belong to x and first and last a valid range on x. + //! n == std::distance(first, last). + //! + //! Effects: Transfers the range [first, last) from list x to this + //! list, before the element pointed by pos. + //! No destructors or copy constructors are called. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the sum of elements before pos, first, and last. + //! Linear to the sum of elements before first and last + //! if cache_last<> is true and pos == end(). + //! + //! Note: Iterators of values obtained from list x now point to elements of this + //! list. Iterators of this list and all the references are not invalidated. + void splice(iterator pos, slist_impl &x, iterator first, iterator last, difference_type n) + { return this->splice_after(this->previous(pos), x, x.previous(first), x.previous(last), n); } + + //! Effects: This function sorts the list *this according to std::less. + //! The sort is stable, that is, the relative order of equivalent elements is preserved. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the predicate throws. Basic guarantee. + //! + //! Complexity: The number of comparisons is approximately N log N, where N + //! is the list's size. + //! + //! Note: Iterators and references are not invalidated + template + void sort(Predicate p) + { + if (node_traits::get_next(node_traits::get_next(this->get_root_node())) + != this->get_root_node()) { + slist_impl carry; + slist_impl counter[64]; + int fill = 0; + iterator last_inserted; + while(!this->empty()){ + last_inserted = this->begin(); + carry.splice_after(carry.before_begin(), *this, this->before_begin()); + int i = 0; + while(i < fill && !counter[i].empty()) { + last_inserted = carry.merge(counter[i++], p); + } + BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty()); + + node_ptr p = node_algorithms::get_previous_node + (last_inserted.pointed_node(), carry.end().pointed_node()); + iterator last_element(p, this); + if(constant_time_size){ + counter[i].splice_after( counter[i].before_begin(), carry + , carry.before_begin(), last_element + , carry.size()); + } + else{ + counter[i].splice_after( counter[i].before_begin(), carry + , carry.before_begin(), last_element); + } + if(i == fill) + ++fill; + } + + for (int i = 1; i < fill; ++i) + last_inserted = counter[i].merge(counter[i-1], p); + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty()); + + node_ptr p = node_algorithms::get_previous_node + (last_inserted.pointed_node(), counter[--fill].end().pointed_node()); + iterator last_element(p, this); + if(constant_time_size){ + this->splice_after( before_begin(), counter[fill], counter[fill].before_begin() + , last_element, counter[fill].size()); + } + else{ + this->splice_after( before_begin(), counter[fill], counter[fill].before_begin() + , last_element); + } + } + } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or std::less throws. Basic guarantee. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references are not invalidated. + void sort() + { this->sort(std::less()); } + + //! Requires: p must be a comparison function that induces a strict weak + //! ordering and both *this and x must be sorted according to that ordering + //! The lists x and *this must be distinct. + //! + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this. The merge is stable; that is, if an element from *this is + //! equivalent to one from x, then the element from *this will precede the one from x. + //! + //! Returns: An iterator to the last transferred value, end() is x is empty. + //! + //! Throws: If the predicate throws. Basic guarantee. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references are not invalidated. + template + iterator merge(slist_impl& x, Predicate p) + { + iterator a(before_begin()), e(end()), ax(x.before_begin()), ex(x.end()); + iterator last_inserted(e); + iterator a_next; + while(++(a_next = a) != e && !x.empty()) { + iterator ix(ax); + iterator cx; + size_type n(0); + while(++(cx = ix) != ex && p(*cx, *a_next)){ + ++ix; ++n; + } + if(ax != ix){ + this->splice_after(a, x, ax, ix, n); + last_inserted = ix; + } + a = a_next; + } + if (!x.empty()){ + last_inserted = this->splice_after(a, x); + } + return last_inserted; + } + + //! Effects: This function removes all of x's elements and inserts them + //! in order into *this according to std::less. The merge is stable; + //! that is, if an element from *this is equivalent to one from x, then the element + //! from *this will precede the one from x. + //! + //! Throws: if std::less throws. Basic guarantee. + //! + //! Complexity: This function is linear time: it performs at most + //! size() + x.size() - 1 comparisons. + //! + //! Note: Iterators and references are not invalidated + void merge(slist_impl& x) + { this->merge(x, std::less()); } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + //! + //! Note: Iterators and references are not invalidated + void reverse() + { + if(cache_last && !this->empty()){ + this->set_last_node(node_traits::get_next(this->get_root_node())); + } + this->priv_reverse(detail::bool_()); + } + + //! Effects: Removes all the elements that compare equal to value. + //! No destructors are called. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. This function is + //! linear time: it performs exactly size() comparisons for equality. + void remove(const_reference value) + { this->remove_if(detail::equal_to_value(value)); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements that compare equal to value. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_and_dispose(const_reference value, Disposer disposer) + { this->remove_and_dispose_if(detail::equal_to_value(value), disposer); } + + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. No destructors are called. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() calls to the predicate. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_if(Pred pred) + { this->remove_and_dispose_if(pred, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes all the elements for which a specified + //! predicate is satisfied. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If pred throws. Basic guarantee. + //! + //! Complexity: Linear time. It performs exactly size() comparisons for equality. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void remove_and_dispose_if(Pred pred, Disposer disposer) + { + iterator bcur(this->before_begin()), cur(this->begin()), e(this->end()); + + while(cur != e){ + if (pred(*cur)){ + cur = this->erase_after_and_dispose(bcur, disposer); + } + else{ + bcur = cur; + ++cur; + } + } + if(cache_last){ + this->set_last_node(bcur.pointed_node()); + } + } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that are equal from the list. No destructors are called. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons calls to pred()). + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + void unique() + { this->unique_and_dispose(std::equal_to(), detail::null_disposer()); } + + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! No destructors are called. + //! + //! Throws: If the predicate throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique(BinaryPredicate pred) + { this->unique_and_dispose(pred, detail::null_disposer()); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If std::equal_to throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(Disposer disposer) + { this->unique(std::equal_to(), disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Removes adjacent duplicate elements or adjacent + //! elements that satisfy some binary predicate from the list. + //! Disposer::operator()(pointer) is called for every removed element. + //! + //! Throws: If the predicate throws. Basic guarantee. + //! + //! Complexity: Linear time (size()-1) comparisons equality comparisons. + //! + //! Note: The relative order of elements that are not removed is unchanged, + //! and iterators to elements that are not removed remain valid. + template + void unique_and_dispose(BinaryPredicate pred, Disposer disposer) + { + iterator end_n(this->end()); + iterator bcur(this->begin()); + if(bcur != end_n){ + iterator cur(bcur); + ++cur; + while(cur != end_n) { + if (pred(*bcur, *cur)){ + cur = this->erase_after_and_dispose(bcur, disposer); + } + else{ + bcur = cur; + ++cur; + } + } + if(cache_last){ + this->set_last_node(bcur.pointed_node()); + } + } + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + //! This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); + return iterator (value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + //! This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be a reference to a value inserted in a list. + //! + //! Effects: This function returns a const_iterator pointing to the element + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + iterator iterator_to(reference value) + { + //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); + return iterator (value_traits::to_node_ptr(value), this); + } + + //! Requires: value must be a const reference to a value inserted in a list. + //! + //! Effects: This function returns an iterator pointing to the element. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: Iterators and references are not invalidated. + const_iterator iterator_to(const_reference value) const + { + //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); + } + + //! Returns: The iterator to the element before i in the list. + //! Returns the end-iterator, if either i is the begin-iterator or the + //! list is empty. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before i. + //! Constant if cache_last<> is true and i == end(). + iterator previous(iterator i) + { + if(cache_last && (i.pointed_node() == this->get_end_node())){ + return iterator(this->get_last_node(), this); + } + return iterator + (node_algorithms::get_previous_node + (this->before_begin().pointed_node(), i.pointed_node()), this); + } + + //! Returns: The const_iterator to the element before i in the list. + //! Returns the end-const_iterator, if either i is the begin-const_iterator or + //! the list is empty. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements before i. + //! Constant if cache_last<> is true and i == end(). + const_iterator previous(const_iterator i) const + { + if(cache_last && (i.pointed_node() == this->get_end_node())){ + return iterator(uncast(this->get_last_node()), this); + } + return const_iterator + (node_algorithms::get_previous_node + (this->before_begin().pointed_node(), i.pointed_node()), this); + } + + private: + void priv_splice_after(node_ptr prev_pos_n, slist_impl &x, node_ptr before_first_n, node_ptr before_last_n) + { + if(cache_last){ + if(node_traits::get_next(prev_pos_n) == this->get_end_node()){ + this->set_last_node(before_last_n); + } + if(node_traits::get_next(before_last_n) == x.get_end_node()){ + x.set_last_node(before_first_n); + } + } + node_algorithms::transfer_after(prev_pos_n, before_first_n, before_last_n); + } + + void priv_reverse(detail::bool_) + { node_algorithms::reverse(this->get_root_node()); } + + void priv_reverse(detail::bool_) + { + node_ptr new_first = node_algorithms::reverse + (node_traits::get_next(this->get_root_node())); + node_traits::set_next(this->get_root_node(), new_first); + } + + void priv_shift_backwards(size_type n, detail::bool_) + { + node_ptr last = node_algorithms::move_forward(this->get_root_node(), (std::size_t)n); + if(cache_last && last){ + this->set_last_node(last); + } + } + + void priv_shift_backwards(size_type n, detail::bool_) + { + std::pair ret( + node_algorithms::move_first_n_forward + (node_traits::get_next(this->get_root_node()), (std::size_t)n)); + if(ret.first){ + node_traits::set_next(this->get_root_node(), ret.first); + if(cache_last){ + this->set_last_node(ret.second); + } + } + } + + void priv_shift_forward(size_type n, detail::bool_) + { + node_ptr last = node_algorithms::move_backwards(this->get_root_node(), (std::size_t)n); + if(cache_last && last){ + this->set_last_node(last); + } + } + + void priv_shift_forward(size_type n, detail::bool_) + { + std::pair ret( + node_algorithms::move_first_n_backwards + (node_traits::get_next(this->get_root_node()), (std::size_t)n)); + if(ret.first){ + node_traits::set_next(this->get_root_node(), ret.first); + if(cache_last){ + this->set_last_node(ret.second); + } + } + } + + void priv_swap_cache_last(slist_impl &other) + { + node_ptr other_last(other.get_last_node()); + node_ptr this_last(this->get_last_node()); + node_ptr other_bfirst(other.get_root_node()); + node_ptr this_bfirst(this->get_root_node()); + node_algorithms::transfer_after(this_bfirst, other_bfirst, other_last); + node_algorithms::transfer_after(other_bfirst, other_last != other_bfirst? other_last : this_bfirst, this_last); + node_ptr tmp(this->get_last_node()); + this->set_last_node(other.get_last_node()); + other.set_last_node(tmp); + if(this->get_last_node() == other_bfirst){ + this->set_last_node(this_bfirst); + } + if(other.get_last_node() == this_bfirst){ + other.set_last_node(other_bfirst); + } + } + + //circular version + static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_) + { node_algorithms::swap_nodes(this_node, other_node); } + + //linear version + static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_) + { node_algorithms::swap_trailing_nodes(this_node, other_node); } + + static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + //Obtaining the container from the end iterator is not possible with linear + //singly linked lists (because "end" is represented by the null pointer) + BOOST_STATIC_ASSERT(!linear); + root_plus_size *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), (&root_plus_size::root_)); + data_t *d = detail::parent_from_member + ( r, &data_t::root_plus_size_); + slist_impl *s = detail::parent_from_member(d, &slist_impl::data_); + return *s; + } +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ + typedef slist_impl slist_type; + typedef typename slist_type::const_iterator const_iterator; + const bool C = slist_type::constant_time_size; + if(C && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(C){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const slist_impl &x, const slist_impl &y) +#else +(const slist_impl &x, const slist_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(slist_impl &x, slist_impl &y) +#else +(slist_impl &x, slist_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c slist that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_slist +{ + /// @cond + typedef typename pack_options + < slist_defaults, O1, O2, O3, O4, O5>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + typedef slist_impl + < + slistopt + < value_traits + , typename packed_options::size_type + , packed_options::constant_time_size + , packed_options::linear + , packed_options::cache_last + > + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class slist + : public make_slist::type +{ + typedef typename make_slist + ::type Base; + typedef typename Base::real_value_traits real_value_traits; + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + slist(const value_traits &v_traits = value_traits()) + : Base(v_traits) + {} + + template + slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + : Base(b, e, v_traits) + {} + + static slist &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const slist &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_HPP diff --git a/thirdparty/boost/intrusive/slist_hook.hpp b/thirdparty/boost/intrusive/slist_hook.hpp new file mode 100644 index 0000000..5598c78 --- /dev/null +++ b/thirdparty/boost/intrusive/slist_hook.hpp @@ -0,0 +1,268 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SLIST_HOOK_HPP +#define BOOST_INTRUSIVE_SLIST_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_slist_node_algo +{ + typedef circular_slist_algorithms > type; +}; + +/// @endcond + +//! Helper metafunction to define a \c slist_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_slist_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_slist_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::SlistBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from slist_base_hook in order to store objects in +//! in an list. slist_base_hook holds the data necessary to maintain the +//! list and provides an appropriate value_traits class for list. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class slist_base_hook + : public make_slist_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + slist_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + slist_base_hook(const slist_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + slist_base_hook& operator=(const slist_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an slist an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~slist_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(slist_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c slist::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c slist_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_slist_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_slist_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member slist_member_hook in order to store objects of this class in +//! an list. slist_member_hook holds the data necessary for maintaining the list and +//! provides an appropriate value_traits class for list. +//! +//! The hook admits the following options: \c void_pointer<> and +//! \c link_mode<>. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class slist_member_hook + : public make_slist_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + slist_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + slist_member_hook(const slist_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + slist_member_hook& operator=(const slist_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an slist an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~slist_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(slist_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c slist::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP diff --git a/thirdparty/boost/intrusive/splay_set.hpp b/thirdparty/boost/intrusive/splay_set.hpp new file mode 100644 index 0000000..5d8eb28 --- /dev/null +++ b/thirdparty/boost/intrusive/splay_set.hpp @@ -0,0 +1,2221 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SPLAY_SET_HPP +#define BOOST_INTRUSIVE_SPLAY_SET_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! The class template splay_set is an intrusive container, that mimics most of +//! the interface of std::set as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class splay_set_impl +{ + /// @cond + typedef splaytree_impl tree_type; + //! This class is + //! non-copyable + splay_set_impl (const splay_set_impl&); + + //! This class is + //! non-assignable + splay_set_impl &operator =(const splay_set_impl&); + + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor of the value_compare object throws. + splay_set_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty splay_set and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise amortized N * log N, where N is std::distance(last, first). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + splay_set_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(true, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the splay_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~splay_set_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of splay_set. + //! + //! Effects: Returns a const reference to the splay_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static splay_set_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &splay_set_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of splay_set. + //! + //! Effects: Returns a const reference to the splay_set associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const splay_set_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &splay_set_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the splay_set. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the splay_set. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two splay_sets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(splay_set_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const splay_set_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the splay_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert(reference value) + { return tree_.insert_unique(value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to to insert x into the splay_set, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: An iterator that points to the position where the + //! new element was inserted into the splay_set. + //! + //! Complexity: Amortized logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_unique(hint, value); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the splay_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the splay_set. + template + std::pair insert_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(key, key_value_comp, commit_data); } + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the splay_set, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Amortized logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the splay_set. + template + std::pair insert_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the splay_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the splay_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return tree_.insert_unique_commit(value, commit_data); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the splay_set. + //! + //! Complexity: Insert range is amortized O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_unique(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is amortized + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size()) + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(key, comp)). + //! + //! Throws: If the comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: If the internal value_compare ordering function throws. + //! + //! Complexity: Amortized O(log(size() + this->count(value)). Basic guarantee. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) + { return tree_.find(value) != end(); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp) != end(); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count_dont_splay(const_reference value)const + { return tree_.find_dont_splay(value) != end(); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count_dont_splay(const KeyType& key, KeyValueCompare comp)const + { return tree_.find_dont_splay(key, comp) != end(); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound_dont_splay(const_reference value) const + { return tree_.lower_bound_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound_dont_splay(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound_dont_splay(const_reference value) const + { return tree_.upper_bound_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound_dont_splay(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find_dont_splay(const_reference value) const + { return tree_.find_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.find_dont_splay(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range_dont_splay(const_reference value) const + { return tree_.equal_range_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range_dont_splay(key, comp); } + + //! Requires: value must be an lvalue and shall be in a splay_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the splay_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a splay_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! splay_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a splay_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the splay_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a splay_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! splay_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a splay_set/multisplay_set. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + //! Requires: i must be a valid iterator of *this. + //! + //! Effects: Rearranges the splay set so that the element pointed by i + //! is placed as the root of the tree, improving future searches of this value. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + void splay_up(iterator i) + { tree_.splay_up(i); } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. If the element is not present returns the last node compared with the key. + //! If the tree is empty, end() is returned. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the comparison functor throws. + template + iterator splay_down(const KeyType &key, KeyNodePtrCompare comp) + { return tree_.splay_down(key, comp); } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the predicate throws. + iterator splay_down(const value_type &value) + { return tree_.splay_down(value); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { tree_.rebalance(); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return tree_.rebalance_subtree(root); } + + /// @cond + friend bool operator==(const splay_set_impl &x, const splay_set_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const splay_set_impl &x, const splay_set_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_set_impl &x, const splay_set_impl &y) +#else +(const splay_set_impl &x, const splay_set_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_set_impl &x, const splay_set_impl &y) +#else +(const splay_set_impl &x, const splay_set_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_set_impl &x, const splay_set_impl &y) +#else +(const splay_set_impl &x, const splay_set_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_set_impl &x, const splay_set_impl &y) +#else +(const splay_set_impl &x, const splay_set_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(splay_set_impl &x, splay_set_impl &y) +#else +(splay_set_impl &x, splay_set_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c splay_set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_splay_set +{ + /// @cond + typedef splay_set_impl + < typename make_splaytree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class splay_set + : public make_splay_set::type +{ + typedef typename make_splay_set + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + splay_set( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + splay_set( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static splay_set &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const splay_set &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +//! The class template splay_multiset is an intrusive container, that mimics most of +//! the interface of std::multiset as described in the C++ standard. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class splay_multiset_impl +{ + /// @cond + typedef splaytree_impl tree_type; + + //Non-copyable and non-assignable + splay_multiset_impl (const splay_multiset_impl&); + splay_multiset_impl &operator =(const splay_multiset_impl&); + typedef tree_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + tree_type tree_; + /// @endcond + + public: + //! Effects: Constructs an empty splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + splay_multiset_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(cmp, v_traits) + {} + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty splay_multiset and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise amortized N * log N, where N is the distance between first and last. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. + template + splay_multiset_impl( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : tree_(false, b, e, cmp, v_traits) + {} + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~splay_multiset_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return tree_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return tree_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return tree_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return tree_.cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return tree_.rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return tree_.crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return tree_.rend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return tree_.crend(); } + + //! Precondition: end_iterator must be a valid end iterator + //! of splay_multiset. + //! + //! Effects: Returns a const reference to the splay_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static splay_multiset_impl &container_from_end_iterator(iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &splay_multiset_impl::tree_); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of splay_multiset. + //! + //! Effects: Returns a const reference to the splay_multiset associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const splay_multiset_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *detail::parent_from_member + ( &tree_type::container_from_end_iterator(end_iterator) + , &splay_multiset_impl::tree_); + } + + //! Effects: Returns the key_compare object used by the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If key_compare copy-constructor throws. + key_compare key_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns the value_compare object used by the splay_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return tree_.value_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return tree_.empty(); } + + //! Effects: Returns the number of elements stored in the splay_multiset. + //! + //! Complexity: Linear to elements contained in *this if, + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return tree_.size(); } + + //! Effects: Swaps the contents of two splay_multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison functor + //! found using ADL throws. Strong guarantee. + void swap(splay_multiset_impl& other) + { tree_.swap(other.tree_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const splay_multiset_impl &src, Cloner cloner, Disposer disposer) + { tree_.clone_from(src.tree_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the splay_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(reference value) + { return tree_.insert_equal(this->end(), value); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts x into the splay_multiset, using pos as a hint to + //! where it will be inserted. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Amortized logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(const_iterator hint, reference value) + { return tree_.insert_equal(hint, value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a range into the splay_multiset. + //! + //! Returns: An iterator that points to the position where the new + //! element was inserted. + //! + //! Complexity: Insert range is amortized O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { tree_.insert_equal(b, e); } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity is constant time. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { return tree_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Complexity: Average complexity for erase range is amortized + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { return tree_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return tree_.erase(value); } + + //! Effects: Erases all the elements that compare equal with + //! the given key and the given comparison functor. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { return tree_.erase(key, comp); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased element. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return tree_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Returns: An iterator to the element after the erased elements. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is amortized + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { return tree_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(value)). + //! + //! Throws: If the internal value_compare ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return tree_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + this->count(key, comp)). + //! + //! Throws: If comp ordering function throws. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { return tree_.erase_and_dispose(key, comp, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return tree_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return tree_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count(const_reference value) + { return tree_.count(value); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count(const KeyType& key, KeyValueCompare comp) + { return tree_.count(key, comp); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If the internal value_compare ordering function throws. + size_type count_dont_splay(const_reference value) const + { return tree_.count_dont_splay(value); } + + //! Effects: Returns the number of contained elements with the same key + //! compared with the given comparison functor. + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: If comp ordering function throws. + template + size_type count_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.count_dont_splay(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator lower_bound(const_reference value) + { return tree_.lower_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator lower_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.lower_bound(key, comp); } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator lower_bound_dont_splay(const_reference value) const + { return tree_.lower_bound_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is not less than k or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.lower_bound_dont_splay(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator upper_bound(const_reference value) + { return tree_.upper_bound(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns an iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator upper_bound(const KeyType& key, KeyValueCompare comp) + { return tree_.upper_bound(key, comp); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator upper_bound_dont_splay(const_reference value) const + { return tree_.upper_bound_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Returns a const_iterator to the first element whose + //! key according to the comparison functor is greater than key or + //! end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.upper_bound_dont_splay(key, comp); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + iterator find(const_reference value) + { return tree_.find(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyValueCompare comp) + { return tree_.find(key, comp); } + + //! Effects: Finds a const_iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + const_iterator find_dont_splay(const_reference value) const + { return tree_.find_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" according to the comparison functor or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.find_dont_splay(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair equal_range(const_reference value) + { return tree_.equal_range(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return tree_.equal_range(key, comp); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. + std::pair + equal_range_dont_splay(const_reference value) const + { return tree_.equal_range_dont_splay(value); } + + //! Requires: comp must imply the same element order as + //! value_compare. Usually key is the part of the value_type + //! that is used in the ordering functor. + //! + //! Effects: Finds a range containing all elements whose key is k + //! according to the comparison functor or an empty range + //! that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If comp ordering function throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const + { return tree_.equal_range_dont_splay(key, comp); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { return tree_type::s_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return tree_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return tree_.iterator_to(value); } + + //! Requires: value shall not be in a set/splay_multiset. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { tree_type::init_node(value); } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { return tree_.unlink_leftmost_without_rebalance(); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { tree_.replace_node(replace_this, with_this); } + + //! Requires: i must be a valid iterator of *this. + //! + //! Effects: Rearranges the splay set so that the element pointed by i + //! is placed as the root of the tree, improving future searches of this value. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + void splay_up(iterator i) + { tree_.splay_up(i); } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. If the element is not present returns the last node compared with the key. + //! If the tree is empty, end() is returned. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the comparison functor throws. + template + iterator splay_down(const KeyType &key, KeyNodePtrCompare comp) + { return tree_.splay_down(key, comp); } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the predicate throws. + iterator splay_down(const value_type &value) + { return tree_.splay_down(value); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { tree_.rebalance(); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return tree_.rebalance_subtree(root); } + + /// @cond + friend bool operator==(const splay_multiset_impl &x, const splay_multiset_impl &y) + { return x.tree_ == y.tree_; } + + friend bool operator<(const splay_multiset_impl &x, const splay_multiset_impl &y) + { return x.tree_ < y.tree_; } + /// @endcond +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#else +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#else +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#else +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#else +(const splay_multiset_impl &x, const splay_multiset_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(splay_multiset_impl &x, splay_multiset_impl &y) +#else +(splay_multiset_impl &x, splay_multiset_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c splay_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_splay_multiset +{ + /// @cond + typedef splay_multiset_impl + < typename make_splaytree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class splay_multiset + : public make_splay_multiset::type +{ + typedef typename make_splay_multiset + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + splay_multiset( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + splay_multiset( Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(b, e, cmp, v_traits) + {} + + static splay_multiset &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const splay_multiset &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SPLAY_SET_HPP diff --git a/thirdparty/boost/intrusive/splay_set_hook.hpp b/thirdparty/boost/intrusive/splay_set_hook.hpp new file mode 100644 index 0000000..43ef0c6 --- /dev/null +++ b/thirdparty/boost/intrusive/splay_set_hook.hpp @@ -0,0 +1,266 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP +#define BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond +template +struct get_splay_set_node_algo +{ + typedef splaytree_algorithms > type; +}; +/// @endcond + +//! Helper metafunction to define a \c splay_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_splay_set_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_splay_set_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::SplaySetBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from splay_set_base_hook in order to store objects in +//! in a splay_set/splay_multiset. splay_set_base_hook holds the data necessary to maintain +//! the splay_set/splay_multiset and provides an appropriate value_traits class for splay_set/splay_multiset. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class splay_set_base_hook + : public make_splay_set_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + splay_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + splay_set_base_hook(const splay_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + splay_set_base_hook& operator=(const splay_set_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~splay_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(splay_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +//! Helper metafunction to define a \c splay_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_splay_set_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3>::type packed_options; + + typedef detail::generic_hook + < get_splay_set_node_algo + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member splay_set_member_hook in order to store objects of this +//! class in a splay_set/splay_multiset. splay_set_member_hook holds the data +//! necessary for maintaining the splay_set/splay_multiset and provides an appropriate +//! value_traits class for splay_set/splay_multiset. +//! +//! The hook admits the following options: \c void_pointer<>, +//! \c link_mode<> and \c optimize_size<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class splay_set_member_hook + : public make_splay_set_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + splay_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + splay_set_member_hook(const splay_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + splay_set_member_hook& operator=(const splay_set_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in a set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~splay_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(splay_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP diff --git a/thirdparty/boost/intrusive/splaytree.hpp b/thirdparty/boost/intrusive/splaytree.hpp new file mode 100644 index 0000000..3f586b8 --- /dev/null +++ b/thirdparty/boost/intrusive/splaytree.hpp @@ -0,0 +1,1518 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_SPLAYTREE_HPP +#define BOOST_INTRUSIVE_SPLAYTREE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct internal_default_splay_set_hook +{ + template static detail::one test(...); + template static detail::two test(typename U::default_splay_set_hook* = 0); + static const bool value = sizeof(test(0)) == sizeof(detail::two); +}; + +template +struct get_default_splay_set_hook +{ + typedef typename T::default_splay_set_hook type; +}; + +template +struct splaysetopt +{ + typedef ValueTraits value_traits; + typedef Compare compare; + typedef SizeType size_type; + static const bool constant_time_size = ConstantTimeSize; +}; + +template +struct splay_set_defaults + : pack_options + < none + , base_hook + < typename detail::eval_if_c + < internal_default_splay_set_hook::value + , get_default_splay_set_hook + , detail::identity + >::type + > + , constant_time_size + , size_type + , compare > + >::type +{}; + +/// @endcond + +//! The class template splaytree is an intrusive splay tree container that +//! is used to construct intrusive splay_set and splay_multiset containers. The no-throw +//! guarantee holds only, if the value_compare object +//! doesn't throw. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class splaytree_impl +{ + public: + typedef typename Config::value_traits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_is_true::value; + typedef typename detail::eval_if_c + < external_value_traits + , detail::eval_value_traits + , detail::identity + >::type real_value_traits; + /// @endcond + typedef typename real_value_traits::pointer pointer; + typedef typename real_value_traits::const_pointer const_pointer; + typedef typename std::iterator_traits::value_type value_type; + typedef value_type key_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename Config::size_type size_type; + typedef typename Config::compare value_compare; + typedef value_compare key_compare; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + typedef splaytree_algorithms node_algorithms; + + static const bool constant_time_size = Config::constant_time_size; + static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value; + + /// @cond + private: + typedef detail::size_holder size_traits; + + //noncopyable + splaytree_impl (const splaytree_impl&); + splaytree_impl operator =(const splaytree_impl&); + + enum { safemode_or_autounlink = + (int)real_value_traits::link_mode == (int)auto_unlink || + (int)real_value_traits::link_mode == (int)safe_link }; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + struct header_plus_size : public size_traits + { node header_; }; + + struct node_plus_pred_t : public detail::ebo_functor_holder + { + node_plus_pred_t(const value_compare &comp) + : detail::ebo_functor_holder(comp) + {} + header_plus_size header_plus_size_; + }; + + struct data_t : public splaytree_impl::value_traits + { + typedef typename splaytree_impl::value_traits value_traits; + data_t(const value_compare & comp, const value_traits &val_traits) + : value_traits(val_traits), node_plus_pred_(comp) + {} + node_plus_pred_t node_plus_pred_; + } data_; + + const value_compare &priv_comp() const + { return data_.node_plus_pred_.get(); } + + value_compare &priv_comp() + { return data_.node_plus_pred_.get(); } + + const node &priv_header() const + { return data_.node_plus_pred_.header_plus_size_.header_; } + + node &priv_header() + { return data_.node_plus_pred_.header_plus_size_.header_; } + + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(detail::get_pointer(ptr))); + } + + size_traits &priv_size_traits() + { return data_.node_plus_pred_.header_plus_size_; } + + const size_traits &priv_size_traits() const + { return data_.node_plus_pred_.header_plus_size_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return data_.get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return data_.get_value_traits(*this); } + + /// @endcond + + public: + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + splaytree_impl( value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty tree and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise amortized N * log N, where N is the distance between first and last. + //! + //! Throws: Nothing unless the copy constructor of the value_compare object throws. + template + splaytree_impl( bool unique, Iterator b, Iterator e + , value_compare cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_(cmp, v_traits) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + ~splaytree_impl() + { this->clear(); } + + //! Effects: Returns an iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin() + { return iterator(node_algorithms::begin_node(&priv_header()), this); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const + { return cbegin(); } + + //! Effects: Returns a const_iterator pointing to the beginning of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return const_iterator(node_algorithms::begin_node(&priv_header()), this); } + + //! Effects: Returns an iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return iterator (node_ptr(&priv_header()), this); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return cend(); } + + //! Effects: Returns a const_iterator pointing to the end of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return const_iterator (uncast(const_node_ptr(&priv_header())), this); } + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend() + { return reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + //! Precondition: end_iterator must be a valid end iterator + //! of splaytree. + //! + //! Effects: Returns a const reference to the splaytree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static splaytree_impl &container_from_end_iterator(iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of splaytree. + //! + //! Effects: Returns a const reference to the splaytree associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator) + { return priv_container_from_end_iterator(end_iterator); } + + //! Effects: Returns the value_compare object used by the tree. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const + { return priv_comp(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const + { return this->cbegin() == this->cend(); } + + //! Effects: Returns the number of elements stored in the tree. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size){ + return this->priv_size_traits().get_size(); + } + else{ + return (size_type)node_algorithms::size(const_node_ptr(&priv_header())); + } + } + + //! Effects: Swaps the contents of two multisets. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(splaytree_impl& other) + { + //This can throw + using std::swap; + swap(priv_comp(), priv_comp()); + //These can't throw + node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header())); + if(constant_time_size){ + size_type backup = this->priv_size_traits().get_size(); + this->priv_size_traits().set_size(other.priv_size_traits().get_size()); + other.priv_size_traits().set_size(backup); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree before the lower bound. + //! + //! Complexity: Average complexity for insert element is amortized + //! logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal_lower_bound + (node_ptr(&priv_header()), to_insert, key_node_comp), this); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Amortized logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + detail::key_nodeptr_comp + key_node_comp(priv_comp(), this); + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + return iterator(node_algorithms::insert_equal + (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the tree + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general amortized O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + if(this->empty()){ + iterator end(this->end()); + for (; b != e; ++b) + this->insert_equal(end, *b); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the tree if the value + //! is not already present. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(value, commit_data); + if(!ret.second) + return ret; + return std::pair (insert_unique_commit(value, commit_data), true); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the tree, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Amortized logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = insert_unique_check(hint, value, commit_data); + if(!ret.second) + return ret.first; + return insert_unique_commit(value, commit_data); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the tree. + //! + //! Complexity: Insert range is in general amortized O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + for (; b != e; ++b) + this->insert_unique(*b); + } + + std::pair insert_unique_check + (const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + (node_algorithms::insert_unique_check + (node_ptr(&priv_header()), key, comp, commit_data)); + return std::pair(iterator(ret.first, this), ret.second); + } + + std::pair insert_unique_check + (const_iterator hint, const_reference value, insert_commit_data &commit_data) + { return insert_unique_check(hint, value, priv_comp(), commit_data); } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + comp(key_value_comp, this); + std::pair ret = + node_algorithms::insert_unique_check + (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data); + return std::pair(iterator(ret.first, this), ret.second); + } + + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->priv_size_traits().increment(); + node_algorithms::insert_unique_commit + (node_ptr(&priv_header()), to_insert, commit_data); + return iterator(to_insert, this); + } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator i) + { + iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + node_algorithms::erase(&priv_header(), to_erase); + this->priv_size_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret; + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is amortized + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(iterator b, iterator e) + { size_type n; return private_erase(b, e, n); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, priv_comp()); } + + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(get_real_value_traits().to_value_ptr(to_erase)); + return ret; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is amortized + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(iterator b, iterator e, Disposer disposer) + { size_type n; return private_erase(b, e, n, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { + std::pair p = this->equal_range(value); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Amortized O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer) + { + std::pair p = this->equal_range(key, comp); + size_type n; + private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Amortized O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. Calls N times to disposer functor. + template + void clear_and_dispose(Disposer disposer) + { + node_algorithms::clear_and_dispose(node_ptr(&priv_header()) + , detail::node_disposer(disposer, this)); + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(0); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count(const_reference value) + { return this->count(value, priv_comp()); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count(const KeyType &key, KeyValueCompare comp) + { + std::pair ret = this->equal_range(key, comp); + return std::distance(ret.first, ret.second); + } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count_dont_splay(const_reference value) const + { return this->count_dont_splay(value, priv_comp()); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Amortized logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count_dont_splay(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range_dont_splay(key, comp); + return std::distance(ret.first, ret.second); + } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + iterator lower_bound(const_reference value) + { return this->lower_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator lower_bound_dont_splay(const_reference value) const + { return this->lower_bound_dont_splay(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator lower_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::lower_bound + (const_node_ptr(&priv_header()), key, key_node_comp, false), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + iterator upper_bound(const_reference value) + { return this->upper_bound(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator(node_algorithms::upper_bound + (const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator upper_bound_dont_splay(const_reference value) const + { return this->upper_bound_dont_splay(value, priv_comp()); } + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator upper_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator(node_algorithms::upper_bound_dont_splay + (const_node_ptr(&priv_header()), key, key_node_comp, false), this); + } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + iterator find(const_reference value) + { return this->find(value, priv_comp()); } + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + template + iterator find(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator find_dont_splay(const_reference value) const + { return this->find_dont_splay(value, priv_comp()); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator find_dont_splay(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + return const_iterator + (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp, false), this); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + std::pair equal_range(const_reference value) + { return this->equal_range(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair + equal_range_dont_splay(const_reference value) const + { return this->equal_range_dont_splay(value, priv_comp()); } + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair + equal_range_dont_splay(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp, false)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const splaytree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + node_algorithms::clone + (const_node_ptr(&src.priv_header()) + ,node_ptr(&this->priv_header()) + ,detail::node_cloner(cloner, this) + ,detail::node_disposer(disposer, this)); + this->priv_size_traits().set_size(src.priv_size_traits().get_size()); + } + } + + //! Effects: Unlinks the leftmost node from the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the tree and the tree can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the tree. + pointer unlink_leftmost_without_rebalance() + { + node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance + (node_ptr(&priv_header()))); + if(!to_be_disposed) + return 0; + this->priv_size_traits().decrement(); + if(safemode_or_autounlink)//If this is commented does not work with normal_link + node_algorithms::init(to_be_disposed); + return get_real_value_traits().to_value_ptr(to_be_disposed); + } + + //! Requires: i must be a valid iterator of *this. + //! + //! Effects: Rearranges the splay set so that the element pointed by i + //! is placed as the root of the tree, improving future searches of this value. + //! + //! Complexity: Amortized logarithmic. + //! + //! Throws: Nothing. + void splay_up(iterator i) + { return node_algorithms::splay_up(i.pointed_node(), &priv_header()); } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. If the element is not present returns the last node compared with the key. + //! If the tree is empty, end() is returned. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the comparison functor throws. + template + iterator splay_down(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + node_ptr r = node_algorithms::splay_down(&priv_header(), key, key_node_comp); + return iterator(r, this); + } + + //! Effects: Rearranges the splay set so that if *this stores an element + //! with a key equivalent to value the element is placed as the root of the + //! tree. + //! + //! Complexity: Amortized logarithmic. + //! + //! Returns: An iterator to the new root of the tree, end() if the tree is empty. + //! + //! Throws: If the predicate throws. + iterator splay_down(const value_type &value) + { return this->splay_down(value, priv_comp()); } + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any tree. + //! + //! Effects: Replaces replace_this in its position in the + //! tree with with_this. The tree does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + , node_ptr(&priv_header()) + , get_real_value_traits().to_node_ptr(with_this)); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return iterator (value_traits::to_node_ptr(value), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value) + { return iterator (value_traits::to_node_ptr(value), this); } + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const + { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } + + //! Requires: value shall not be in a tree. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance() + { node_algorithms::rebalance(node_ptr(&priv_header())); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root) + { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this); } + +/* + //! Effects: removes x from a tree of the appropriate type. It has no effect, + //! if x is not in such a tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This static function is only usable with the "safe mode" + //! hook and non-constant time size lists. Otherwise, the user must use + //! the non-static "erase(reference )" member. If the user calls + //! this function with a non "safe mode" or constant time size list + //! a compilation error will be issued. + template + static void remove_node(T& value) + { + //This function is only usable for safe mode hooks and non-constant + //time lists. + //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size))); + BOOST_STATIC_ASSERT((!constant_time_size)); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink_and_rebalance(to_remove); + if(safemode_or_autounlink) + node_algorithms::init(to_remove); + } +*/ + + /// @cond + private: + template + iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer) + { + for(n = 0; b != e; ++n) + this->erase_and_dispose(b++, disposer); + return b; + } + + iterator private_erase(iterator b, iterator e, size_type &n) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b; + } + /// @endcond + + private: + static splaytree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + header_plus_size *r = detail::parent_from_member + ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + node_plus_pred_t *n = detail::parent_from_member + (r, &node_plus_pred_t::header_plus_size_); + data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); + splaytree_impl *rb = detail::parent_from_member(d, &splaytree_impl::data_); + return *rb; + } +}; + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator< +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +bool operator== +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ + typedef splaytree_impl tree_type; + typedef typename tree_type::const_iterator const_iterator; + + if(tree_type::constant_time_size && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(tree_type::constant_time_size){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator!= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ return !(x == y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator> +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ return y < x; } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator<= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ return !(y < x); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline bool operator>= +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(const splaytree_impl &x, const splaytree_impl &y) +#else +(const splaytree_impl &x, const splaytree_impl &y) +#endif +{ return !(x < y); } + +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +inline void swap +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +(splaytree_impl &x, splaytree_impl &y) +#else +(splaytree_impl &x, splaytree_impl &y) +#endif +{ x.swap(y); } + +/// @cond +template +struct make_splaytree_opt +{ + typedef typename pack_options + < splay_set_defaults, O1, O2, O3, O4>::type packed_options; + typedef typename detail::get_value_traits + ::type value_traits; + + typedef splaysetopt + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > type; +}; +/// @endcond + +//! Helper metafunction to define a \c splaytree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_splaytree +{ + /// @cond + typedef splaytree_impl + < typename make_splaytree_opt::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class splaytree + : public make_splaytree::type +{ + typedef typename make_splaytree + ::type Base; + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + splaytree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + splaytree( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + static splaytree &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const splaytree &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } +}; + +#endif + + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SPLAYTREE_HPP diff --git a/thirdparty/boost/intrusive/splaytree_algorithms.hpp b/thirdparty/boost/intrusive/splaytree_algorithms.hpp new file mode 100644 index 0000000..39ee9de --- /dev/null +++ b/thirdparty/boost/intrusive/splaytree_algorithms.hpp @@ -0,0 +1,855 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +// The implementation of splay trees is based on the article and code published +// in C++ Users Journal "Implementing Splay Trees in C++" (September 1, 2005). +// +// The code has been modified and (supposely) improved by Ion Gaztanaga. +// Here is the header of the file used as base code: +// +// splay_tree.h -- implementation of a STL complatible splay tree. +// +// Copyright (c) 2004 Ralf Mattethat +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// Please send questions, comments, complaints, performance data, etc to +// ralf.mattethat@teknologisk.dk +// +// Requirements for element type +// * must be copy-constructible +// * destructor must not throw exception +// +// Methods marked with note A only throws an exception if the evaluation of the +// predicate throws an exception. If an exception is thrown the call has no +// effect on the containers state +// +// Methods marked with note B only throws an exception if the coppy constructor +// or assignment operator of the predicate throws an exception. If an exception +// is thrown the call has no effect on the containers state +// +// iterators are only invalidated, if the element pointed to by the iterator +// is deleted. The same goes for element references +// + +#ifndef BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! A splay tree is an implementation of a binary search tree. The tree is +//! self balancing using the splay algorithm as described in +//! +//! "Self-Adjusting Binary Search Trees +//! by Daniel Dominic Sleator and Robert Endre Tarjan +//! AT&T Bell Laboratories, Murray Hill, NJ +//! Journal of the ACM, Vol 32, no 3, July 1985, pp 652-686 + +//! splaytree_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_parent(const_node_ptr n); +//! +//! static void set_parent(node_ptr n, node_ptr parent); +//! +//! static node_ptr get_left(const_node_ptr n); +//! +//! static void set_left(node_ptr n, node_ptr left); +//! +//! static node_ptr get_right(const_node_ptr n); +//! +//! static void set_right(node_ptr n, node_ptr right); +template +class splaytree_algorithms +{ + /// @cond + private: + typedef typename NodeTraits::node node; + typedef detail::tree_algorithms tree_algorithms; + /// @endcond + + public: + typedef NodeTraits node_traits; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + + //! This type is the information that will be + //! filled by insert_unique_check + typedef typename tree_algorithms::insert_commit_data insert_commit_data; + + /// @cond + private: + static node_ptr uncast(const_node_ptr ptr) + { + return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + } + /// @endcond + + public: + static node_ptr begin_node(const_node_ptr header) + { return tree_algorithms::begin_node(header); } + + static node_ptr end_node(const_node_ptr header) + { return tree_algorithms::end_node(header); } + + //! Requires: node is a node of the tree or an node initialized + //! by init(...). + //! + //! Effects: Returns true if the node is initialized by init(). + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + static bool unique(const_node_ptr node) + { return tree_algorithms::unique(node); } + + static void unlink(node_ptr node) + { tree_algorithms::unlink(node); } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr node2) + { + if(node1 == node2) + return; + + node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); + swap_nodes(node1, header1, node2, header2); + } + + //! Requires: node1 and node2 can't be header nodes + //! of two trees with header header1 and header2. + //! + //! Effects: Swaps two nodes. After the function node1 will be inserted + //! in the position node2 before the function. node2 will be inserted in the + //! position node1 had before the function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! node1 and node2 are not equivalent according to the ordering rules. + //! + //!Experimental function + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + { tree_algorithms::swap_nodes(node1, header1, node2, header2); } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing and comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + { + if(node_to_be_replaced == new_node) + return; + replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); + } + + //! Requires: node_to_be_replaced must be inserted in a tree + //! with header "header" and new_node must not be inserted in a tree. + //! + //! Effects: Replaces node_to_be_replaced in its position in the + //! tree with new_node. The tree does not need to be rebalanced + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! new_node is not equivalent to node_to_be_replaced according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + //! + //!Experimental function + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + { tree_algorithms::replace_node(node_to_be_replaced, header, new_node); } + + //! Requires: p is a node from the tree except the header. + //! + //! Effects: Returns the next node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr next_node(node_ptr p) + { return tree_algorithms::next_node(p); } + + //! Requires: p is a node from the tree except the leftmost node. + //! + //! Effects: Returns the previous node of the tree. + //! + //! Complexity: Average constant time. + //! + //! Throws: Nothing. + static node_ptr prev_node(node_ptr p) + { return tree_algorithms::prev_node(p); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: After the function unique(node) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init(node_ptr node) + { tree_algorithms::init(node); } + + //! Requires: node must not be part of any tree. + //! + //! Effects: Initializes the header to represent an empty tree. + //! unique(header) == true. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Nodes: If node is inserted in a tree, this function corrupts the tree. + static void init_header(node_ptr header) + { tree_algorithms::init_header(header); } + + //! Requires: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! Effects: Empties the target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clear_and_dispose(node_ptr header, Disposer disposer) + { tree_algorithms::clear_and_dispose(header, disposer); } + + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t count(const_node_ptr node) + { return tree_algorithms::count(node); } + + //! Requires: header is the header node of the tree. + //! + //! Effects: Returns the number of nodes above the header. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t size(const_node_ptr header) + { return tree_algorithms::size(header); } + + //! Requires: header1 and header2 must be the header nodes + //! of two trees. + //! + //! Effects: Swaps two trees. After the function header1 will contain + //! links to the second tree and header2 will have links to the first tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static void swap_tree(node_ptr header1, node_ptr header2) + { return tree_algorithms::swap_tree(header1, header2); } + + //! Requires: "header" must be the header node of a tree. + //! "commit_data" must have been obtained from a previous call to + //! "insert_unique_check". No objects should have been inserted or erased + //! from the set between the "insert_unique_check" that filled "commit_data" + //! and the call to "insert_commit". + //! + //! + //! Effects: Inserts new_node in the set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_unique_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + static void insert_unique_commit + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + { tree_algorithms::insert_unique_commit(header, new_value, commit_data); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. + template + static std::pair insert_unique_check + (node_ptr header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { + splay_down(header, key, comp); + return tree_algorithms::insert_unique_check(header, key, comp, commit_data); + } + + template + static std::pair insert_unique_check + (node_ptr header, node_ptr hint, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data) + { + splay_down(header, key, comp); + return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); + } + + static bool is_header(const_node_ptr p) + { return tree_algorithms::is_header(p); } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the element that is equivalent to + //! "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr find + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true) + { + if(splay) + splay_down(uncast(header), key, comp); + node_ptr end = uncast(header); + node_ptr y = lower_bound(header, key, comp, false); + node_ptr r = (y == end || comp(key, y)) ? end : y; + return r; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! all elements that are equivalent to "key" according to "comp" or an + //! empty range that indicates the position where those elements would be + //! if they there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair equal_range + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true) + { + //if(splay) + //splay_down(uncast(header), key, comp); + std::pair ret = + tree_algorithms::equal_range(header, key, comp); + + if(splay) + splay_up(ret.first, uncast(header)); + return ret; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is + //! not less than "key" according to "comp" or "header" if that element does + //! not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr lower_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true) + { + //if(splay) + //splay_down(uncast(header), key, comp); + node_ptr y = tree_algorithms::lower_bound(header, key, comp); + if(splay) + splay_up(y, uncast(header)); + return y; + } + + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an node_ptr to the first element that is greater + //! than "key" according to "comp" or "header" if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static node_ptr upper_bound + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true) + { + //if(splay) + //splay_down(uncast(header), key, comp); + node_ptr y = tree_algorithms::upper_bound(header, key, comp); + if(splay) + splay_up(y, uncast(header)); + return y; + } + + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + template + static node_ptr insert_equal + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) + { + splay_down(header, new_node, comp); + return tree_algorithms::insert_equal(header, hint, new_node, comp); + } + + template + static node_ptr insert_equal_upper_bound + (node_ptr header, node_ptr new_node, NodePtrCompare comp) + { + splay_down(header, new_node, comp); + return tree_algorithms::insert_equal_upper_bound(header, new_node, comp); + } + + template + static node_ptr insert_equal_lower_bound + (node_ptr header, node_ptr new_node, NodePtrCompare comp) + { + splay_down(header, new_node, comp); + return tree_algorithms::insert_equal_lower_bound(header, new_node, comp); + } + + //! Requires: "cloner" must be a function + //! object taking a node_ptr and returning a new cloned node of it. "disposer" must + //! take a node_ptr and shouldn't throw. + //! + //! Effects: First empties target tree calling + //! void disposer::operator()(node_ptr) for every node of the tree + //! except the header. + //! + //! Then, duplicates the entire tree pointed by "source_header" cloning each + //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! the nodes of the target tree. If "cloner" throws, the cloned target nodes + //! are disposed using void disposer(node_ptr). + //! + //! Complexity: Linear to the number of element of the source tree plus the. + //! number of elements of tree target tree when calling this function. + //! + //! Throws: If cloner functor throws. If this happens target nodes are disposed. + template + static void clone + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + { tree_algorithms::clone(source_header, target_header, cloner, disposer); } + + // delete node | complexity : constant | exception : nothrow + static void erase(node_ptr header, node_ptr z, bool splay = true) + { +// node_base* n = t->right; +// if( t->left != 0 ){ +// node_base* l = t->previous(); +// splay_up( l , t ); +// n = t->left; +// n->right = t->right; +// if( n->right != 0 ) +// n->right->parent = n; +// } +// +// if( n != 0 ) +// n->parent = t->parent; +// +// if( t->parent->left == t ) +// t->parent->left = n; +// else // must be ( t->parent->right == t ) +// t->parent->right = n; +// +// if( data_->parent == t ) +// data_->parent = find_leftmost(); + //posibility 1 + if(splay && NodeTraits::get_left(z) != 0 ){ + node_ptr l = prev_node(z); + splay_up(l, header); + } + /* + //possibility 2 + if(splay && NodeTraits::get_left(z) != 0 ){ + node_ptr l = NodeTraits::get_left(z); + splay_up(l, header); + }*//* + if(splay && NodeTraits::get_left(z) != 0 ){ + node_ptr l = prev_node(z); + splay_up_impl(l, z); + }*/ + /* + //possibility 4 + if(splay){ + splay_up(z, header); + }*/ + + //if(splay) + //splay_up(z, header); + tree_algorithms::erase(header, z); + } + + // bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow + static void splay_up(node_ptr n, node_ptr header) + { + if(n == header){ // do a splay for the right most node instead + // this is to boost performance of equal_range/count on equivalent containers in the case + // where there are many equal elements at the end + n = NodeTraits::get_right(header); + } + + node_ptr t = header; + + if( n == t ) return; + + for( ;; ){ + node_ptr p = NodeTraits::get_parent(n); + node_ptr g = NodeTraits::get_parent(p); + + if( p == t ) break; + + if( g == t ){ + // zig + rotate(n); + } + else if ((NodeTraits::get_left(p) == n && NodeTraits::get_left(g) == p) || + (NodeTraits::get_right(p) == n && NodeTraits::get_right(g) == p) ){ + // zig-zig + rotate(p); + rotate(n); + } + else{ + // zig-zag + rotate(n); + rotate(n); + } + } + } + + // top-down splay | complexity : logarithmic | exception : strong, note A + template + static node_ptr splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + { + if(!NodeTraits::get_parent(header)) + return header; + //Most splay tree implementations use a dummy/null node to implement. + //this function. This has some problems for a generic library like Intrusive: + // + // * The node might not have a default constructor. + // * The default constructor could throw. + // + //We already have a header node. Leftmost and rightmost nodes of the tree + //are not changed when splaying (because the invariants of the tree don't + //change) We can back up them, use the header as the null node and + //reassign old values after the function has been completed. + node_ptr t = NodeTraits::get_parent(header); + //Check if tree has a single node + if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t)) + return t; + //Backup leftmost/rightmost + node_ptr leftmost = NodeTraits::get_left(header); + node_ptr rightmost = NodeTraits::get_right(header); + + try{ + node_ptr null = header; + node_ptr l = null; + node_ptr r = null; + + for( ;; ){ + if(comp(key, t)){ + if(NodeTraits::get_left(t) == 0 ) + break; + if(comp(key, NodeTraits::get_left(t))){ + t = tree_algorithms::rotate_right(t); + + if(NodeTraits::get_left(t) == 0) + break; + link_right(t, r); + } + else if(comp(NodeTraits::get_left(t), key)){ + link_right(t, r); + + if(NodeTraits::get_right(t) == 0 ) + break; + link_left(t, l); + } + else{ + link_right(t, r); + } + } + else if(comp(t, key)){ + if(NodeTraits::get_right(t) == 0 ) + break; + + if(comp(NodeTraits::get_right(t), key)){ + t = tree_algorithms::rotate_left( t ); + + if(NodeTraits::get_right(t) == 0 ) + break; + link_left(t, l); + } + else if(comp(key, NodeTraits::get_right(t))){ + link_left(t, l); + + if(NodeTraits::get_left(t) == 0) + break; + + link_right(t, r); + } + else{ + link_left(t, l); + } + } + else{ + break; + } + } + + assemble(t, l, r, null); + } + catch(...){ + //Exception can only be thrown by comp, but + //tree invariants still hold. t is the current root + //so link it to the header. + NodeTraits::set_parent(t, header); + NodeTraits::set_parent(header, t); + //Recover leftmost/rightmost pointers + NodeTraits::set_left (header, leftmost); + NodeTraits::set_right(header, rightmost); + throw; + } + //t is the current root + NodeTraits::set_parent(header, t); + NodeTraits::set_parent(t, header); + //Recover leftmost/rightmost pointers + NodeTraits::set_left (header, leftmost); + NodeTraits::set_right(header, rightmost); + return t; + } + + //! Requires: header must be the header of a tree. + //! + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static void rebalance(node_ptr header) + { tree_algorithms::rebalance(header); } + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static node_ptr rebalance_subtree(node_ptr old_root) + { return tree_algorithms::rebalance_subtree(old_root); } + + private: + + /// @cond + + // assemble the three sub-trees into new tree pointed to by t | complexity : constant | exception : nothrow + static void assemble( node_ptr t, node_ptr l, node_ptr r, const_node_ptr null_node ) + { + NodeTraits::set_right(l, NodeTraits::get_left(t)); + NodeTraits::set_left(r, NodeTraits::get_right(t)); + + if(NodeTraits::get_right(l) != 0){ + NodeTraits::set_parent(NodeTraits::get_right(l), l); + } + + if(NodeTraits::get_left(r) != 0){ + NodeTraits::set_parent(NodeTraits::get_left(r), r); + } + + NodeTraits::set_left (t, NodeTraits::get_right(null_node)); + NodeTraits::set_right(t, NodeTraits::get_left(null_node)); + + if( NodeTraits::get_left(t) != 0 ){ + NodeTraits::set_parent(NodeTraits::get_left(t), t); + } + + if( NodeTraits::get_right(t) ){ + NodeTraits::set_parent(NodeTraits::get_right(t), t); + } + } + + // break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow + static void link_left(node_ptr& t, node_ptr& l) + { + NodeTraits::set_right(l, t); + NodeTraits::set_parent(t, l); + l = t; + t = NodeTraits::get_right(t); + } + + // break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow + static void link_right(node_ptr& t, node_ptr& r) + { + NodeTraits::set_left(r, t); + NodeTraits::set_parent(t, r); + r = t; + t = NodeTraits::get_left(t); + } + + // rotate n with its parent | complexity : constant | exception : nothrow + static void rotate(node_ptr n) + { + node_ptr p = NodeTraits::get_parent(n); + node_ptr g = NodeTraits::get_parent(p); + //Test if g is header before breaking tree + //invariants that would make is_header invalid + bool g_is_header = is_header(g); + + if(NodeTraits::get_left(p) == n){ + NodeTraits::set_left(p, NodeTraits::get_right(n)); + if(NodeTraits::get_left(p) != 0) + NodeTraits::set_parent(NodeTraits::get_left(p), p); + NodeTraits::set_right(n, p); + } + else{ // must be ( p->right == n ) + NodeTraits::set_right(p, NodeTraits::get_left(n)); + if(NodeTraits::get_right(p) != 0) + NodeTraits::set_parent(NodeTraits::get_right(p), p); + NodeTraits::set_left(n, p); + } + + NodeTraits::set_parent(p, n); + NodeTraits::set_parent(n, g); + + if(g_is_header){ + if(NodeTraits::get_parent(g) == p) + NodeTraits::set_parent(g, n); + else{//must be ( g->right == p ) + assert(0); + NodeTraits::set_right(g, n); + } + } + else{ + if(NodeTraits::get_left(g) == p) + NodeTraits::set_left(g, n); + else //must be ( g->right == p ) + NodeTraits::set_right(g, n); + } + } + + /// @endcond +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP diff --git a/thirdparty/boost/intrusive/trivial_value_traits.hpp b/thirdparty/boost/intrusive/trivial_value_traits.hpp new file mode 100644 index 0000000..982213e --- /dev/null +++ b/thirdparty/boost/intrusive/trivial_value_traits.hpp @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP + +#include + +namespace boost { +namespace intrusive { + +//!This value traits template is used to create value traits +//!from user defined node traits where value_traits::value_type and +//!node_traits::node should be equal +template +struct trivial_value_traits +{ + typedef NodeTraits node_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename node_traits::node value_type; + typedef node_ptr pointer; + typedef const_node_ptr const_pointer; + static const link_mode_type link_mode = LinkMode; + static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); } + static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); } + static pointer to_value_ptr(node_ptr n) { return pointer(n); } + static const_pointer to_value_ptr(const_node_ptr n) { return const_pointer(n); } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP diff --git a/thirdparty/boost/intrusive/unordered_set.hpp b/thirdparty/boost/intrusive/unordered_set.hpp new file mode 100644 index 0000000..58d22ca --- /dev/null +++ b/thirdparty/boost/intrusive/unordered_set.hpp @@ -0,0 +1,1953 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP +#define BOOST_INTRUSIVE_UNORDERED_SET_HPP + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +//! The class template unordered_set is an intrusive container, that mimics most of +//! the interface of std::tr1::unordered_set as described in the C++ TR1. +//! +//! unordered_set is a pseudo-intrusive container: each object to be stored in the +//! container must contain a proper hook, but the container also needs +//! additional auxiliary memory to work: unordered_set needs a pointer to an array +//! of type `bucket_type` to be passed in the constructor. This bucket array must +//! have at least the same lifetime as the container. This makes the use of +//! unordered_set more complicated than purely intrusive containers. +//! `bucket_type` is default-constructible, copyable and assignable +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> . +//! +//! unordered_set only provides forward iterators but it provides 4 iterator types: +//! iterator and const_iterator to navigate through the whole container and +//! local_iterator and const_local_iterator to navigate through the values +//! stored in a single bucket. Local iterators are faster and smaller. +//! +//! It's not recommended to use non constant-time size unordered_sets because several +//! key functions, like "empty()", become non-constant time functions. Non +//! constant-time size unordered_sets are mainly provided to support auto-unlink hooks. +//! +//! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor +//! offers functions related to a load factor. Rehashing can be explicitly requested +//! and the user must provide a new bucket array that will be used from that moment. +//! +//! Since no automatic rehashing is done, iterators are never invalidated when +//! inserting or erasing elements. Iterators are only invalidated when rehasing. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class unordered_set_impl +{ + /// @cond + private: + typedef hashtable_impl table_type; + + //! This class is + //! non-copyable + unordered_set_impl (const unordered_set_impl&); + + //! This class is + //! non-assignable + unordered_set_impl &operator =(const unordered_set_impl&); + + typedef table_type implementation_defined; + /// @endcond + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::bucket_traits bucket_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::key_equal key_equal; + typedef typename implementation_defined::hasher hasher; + typedef typename implementation_defined::bucket_type bucket_type; + typedef typename implementation_defined::bucket_ptr bucket_ptr; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::local_iterator local_iterator; + typedef typename implementation_defined::const_local_iterator const_local_iterator; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + table_type table_; + /// @endcond + + public: + + //! Requires: buckets must not be being used by any other resource. + //! + //! Effects: Constructs an empty unordered_set_impl, storing a reference + //! to the bucket array and copies of the hasher and equal functors. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of Hash or Equal throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + unordered_set_impl( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : table_(b_traits, hash_func, equal_func, v_traits) + {} + + //! Requires: buckets must not be being used by any other resource + //! and Dereferencing iterator must yield an lvalue of type value_type. + //! + //! Effects: Constructs an empty unordered_set and inserts elements from + //! [b, e). + //! + //! Complexity: If N is std::distance(b, e): Average case is O(N) + //! (with a good hash function and with buckets_len >= N),worst case O(N2). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of hasher or key_equal throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + template + unordered_set_impl( Iterator b + , Iterator e + , const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : table_(b_traits, hash_func, equal_func, v_traits) + { table_.insert_unique(b, e); } + + //! Effects: Detaches all elements from this. The objects in the unordered_set + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements in the unordered_set, if + //! it's a safe-mode or auto-unlink value. Otherwise constant. + //! + //! Throws: Nothing. + ~unordered_set_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + iterator begin() + { return table_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator begin() const + { return table_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_set. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_set): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return table_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return table_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return table_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return table_.cend(); } + + //! Effects: Returns the hasher object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If hasher copy-constructor throws. + hasher hash_function() const + { return table_.hash_function(); } + + //! Effects: Returns the key_equal object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If key_equal copy-constructor throws. + key_equal key_eq() const + { return table_.key_eq(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: if constant-time size option is disabled, average constant time + //! (worst case, with empty() == true): O(this->bucket_count()). + //! Otherwise constant. + //! + //! Throws: Nothing. + bool empty() const + { return table_.empty(); } + + //! Effects: Returns the number of elements stored in the unordered_set. + //! + //! Complexity: Linear to elements contained in *this if + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return table_.size(); } + + //! Requires: the hasher and the equality function unqualified swap + //! call should not throw. + //! + //! Effects: Swaps the contents of two unordered_sets. + //! Swaps also the contained bucket array and equality and hasher functors. + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison or hash functors + //! found using ADL throw. Basic guarantee. + void swap(unordered_set_impl& other) + { table_.swap(other.table_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. Basic guarantee. + template + void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer) + { table_.clone_from(src.table_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Tries to inserts value into the unordered_set. + //! + //! Returns: If the value + //! is not already present inserts it and returns a pair containing the + //! iterator to the new value and true. If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert(reference value) + { return table_.insert_unique(value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Equivalent to this->insert(t) for each element in [b, e). + //! + //! Complexity: Average case O(N), where N is std::distance(b, e). + //! Worst case O(N*this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { table_.insert_unique(b, e); } + + //! Requires: "hasher" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hasher" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the unordered_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hasher or key_value_equal throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the hash or the equality is much cheaper to + //! construct than the value_type and this function offers the possibility to + //! use that the part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the unordered_set. + //! + //! After a successful rehashing insert_commit_data remains valid. + template + std::pair insert_check + (const KeyType &key, KeyHasher hasher, KeyValueEqual key_value_equal, insert_commit_data &commit_data) + { return table_.insert_unique_check(key, hasher, key_value_equal, commit_data); } + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the unordered_set between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the unordered_set using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + //! + //! After a successful rehashing insert_commit_data remains valid. + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return table_.insert_unique_commit(value, commit_data); } + + //! Effects: Erases the element pointed to by i. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased element. No destructors are called. + void erase(const_iterator i) + { table_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void erase(const_iterator b, const_iterator e) + { table_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return table_.erase(value); } + + //! Requires: "hasher" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hasher" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Erases all the elements that have the same hash and + //! compare equal with the given key. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.erase(key, hash_func, equal_func); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by i. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(const_iterator i, Disposer disposer) + { return table_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { return table_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return table_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "equal_func". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer) + { return table_.erase_and_dispose(key, hash_func, equal_func, disposer); } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return table_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return table_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + size_type count(const_reference value) const + { return table_.find(value) != end(); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + template + size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.find(key, hash_func, equal_func) != end(); } + + //! Effects: Finds an iterator to the first element is equal to + //! "value" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + iterator find(const_reference value) + { return table_.find(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.find(key, hash_func, equal_func); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + const_iterator find(const_reference value) const + { return table_.find(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.find(key, hash_func, equal_func); } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair equal_range(const_reference value) + { return table_.equal_range(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, hash_func)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or the equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.equal_range(key, hash_func, equal_func); } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair + equal_range(const_reference value) const + { return table_.equal_range(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "equal_func" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "equal_func" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If the hash_func or equal_func throw. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.equal_range(key, hash_func, equal_func); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + iterator iterator_to(reference value) + { return table_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator belonging to the + //! unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the internal hash function throws. + const_iterator iterator_to(const_reference value) const + { return table_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static local_iterator s_local_iterator_to(reference value) + { return table_type::s_local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_local_iterator s_local_iterator_to(const_reference value) + { return table_type::s_local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + local_iterator local_iterator_to(reference value) + { return table_.local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_local_iterator local_iterator_to(const_reference value) const + { return table_.local_iterator_to(value); } + + //! Effects: Returns the number of buckets passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_count() const + { return table_.bucket_count(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns the number of elements in the nth bucket. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_size(size_type n) const + { return table_.bucket_size(n); } + + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If the hash functor throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + size_type bucket(const value_type& k) const + { return table_.bucket(k); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If hash_func throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + template + size_type bucket(const KeyType& k, KeyHasher hash_func) const + { return table_.bucket(k, hash_func); } + + //! Effects: Returns the bucket array pointer passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bucket_ptr bucket_pointer() const + { return table_.bucket_pointer(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator begin(size_type n) + { return table_.begin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator begin(size_type n) const + { return table_.begin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cbegin(size_type n) const + { return table_.cbegin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator end(size_type n) + { return table_.end(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator end(size_type n) const + { return table_.end(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cend(size_type n) const + { return table_.cend(n); } + + //! Requires: new_buckets must be a pointer to a new bucket array + //! or the same as the old bucket array. new_size is the length of the + //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer() + //! n can be bigger or smaller than this->bucket_count(). + //! + //! Effects: Updates the internal reference with the new bucket erases + //! the values from the old bucket and inserts then in the new one. + //! + //! Complexity: Average case linear in this->size(), worst case quadratic. + //! + //! Throws: If the hasher functor throws. Basic guarantee. + void rehash(const bucket_traits &new_bucket_traits) + { table_.rehash(new_bucket_traits); } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is bigger than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! higher possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_upper_bucket_count(size_type n) + { return table_type::suggested_upper_bucket_count(n); } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is smaller than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! lower possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_lower_bucket_count(size_type n) + { return table_type::suggested_lower_bucket_count(n); } +}; + +//! Helper metafunction to define an \c unordered_set that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_unordered_set +{ + /// @cond + typedef unordered_set_impl + < typename make_hashtable_opt + ::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class unordered_set + : public make_unordered_set::type +{ + typedef typename make_unordered_set + ::type Base; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::bucket_traits bucket_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::bucket_ptr bucket_ptr; + typedef typename Base::size_type size_type; + typedef typename Base::hasher hasher; + typedef typename Base::key_equal key_equal; + + unordered_set ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b_traits, hash_func, equal_func, v_traits) + {} + + template + unordered_set ( Iterator b + , Iterator e + , const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b, e, b_traits, hash_func, equal_func, v_traits) + {} +}; + +#endif + + +//! The class template unordered_multiset is an intrusive container, that mimics most of +//! the interface of std::tr1::unordered_multiset as described in the C++ TR1. +//! +//! unordered_multiset is a pseudo-intrusive container: each object to be stored in the +//! container must contain a proper hook, but the container also needs +//! additional auxiliary memory to work: unordered_multiset needs a pointer to an array +//! of type `bucket_type` to be passed in the constructor. This bucket array must +//! have at least the same lifetime as the container. This makes the use of +//! unordered_multiset more complicated than purely intrusive containers. +//! `bucket_type` is default-constructible, copyable and assignable +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> . +//! +//! unordered_multiset only provides forward iterators but it provides 4 iterator types: +//! iterator and const_iterator to navigate through the whole container and +//! local_iterator and const_local_iterator to navigate through the values +//! stored in a single bucket. Local iterators are faster and smaller. +//! +//! It's not recommended to use non constant-time size unordered_multisets because several +//! key functions, like "empty()", become non-constant time functions. Non +//! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks. +//! +//! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor +//! offers functions related to a load factor. Rehashing can be explicitly requested +//! and the user must provide a new bucket array that will be used from that moment. +//! +//! Since no automatic rehashing is done, iterators are never invalidated when +//! inserting or erasing elements. Iterators are only invalidated when rehasing. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class unordered_multiset_impl +{ + /// @cond + private: + typedef hashtable_impl table_type; + /// @endcond + + //! This class is + //! non-copyable + unordered_multiset_impl (const unordered_multiset_impl&); + + //! This class is + //! non-assignable + unordered_multiset_impl &operator =(const unordered_multiset_impl&); + + typedef table_type implementation_defined; + + public: + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::value_traits value_traits; + typedef typename implementation_defined::bucket_traits bucket_traits; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::key_equal key_equal; + typedef typename implementation_defined::hasher hasher; + typedef typename implementation_defined::bucket_type bucket_type; + typedef typename implementation_defined::bucket_ptr bucket_ptr; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::insert_commit_data insert_commit_data; + typedef typename implementation_defined::local_iterator local_iterator; + typedef typename implementation_defined::const_local_iterator const_local_iterator; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; + + /// @cond + private: + table_type table_; + /// @endcond + + public: + + //! Requires: buckets must not be being used by any other resource. + //! + //! Effects: Constructs an empty unordered_multiset, storing a reference + //! to the bucket array and copies of the hasher and equal functors. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of Hash or Equal throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + unordered_multiset_impl ( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : table_(b_traits, hash_func, equal_func, v_traits) + {} + + //! Requires: buckets must not be being used by any other resource + //! and Dereferencing iterator must yield an lvalue of type value_type. + //! + //! Effects: Constructs an empty unordered_multiset and inserts elements from + //! [b, e). + //! + //! Complexity: If N is std::distance(b, e): Average case is O(N) + //! (with a good hash function and with buckets_len >= N),worst case O(N2). + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor or invocation of hasher or key_equal throws. + //! + //! Notes: buckets array must be disposed only after + //! *this is disposed. + template + unordered_multiset_impl ( Iterator b + , Iterator e + , const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : table_(b_traits, hash_func, equal_func, v_traits) + { table_.insert_equal(b, e); } + + //! Effects: Detaches all elements from this. The objects in the unordered_multiset + //! are not deleted (i.e. no destructors are called). + //! + //! Complexity: Linear to the number of elements in the unordered_multiset, if + //! it's a safe-mode or auto-unlink value. Otherwise constant. + //! + //! Throws: Nothing. + ~unordered_multiset_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the unordered_multiset. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_multiset): O(this->bucket_count()) + //! + //! Throws: Nothing. + iterator begin() + { return table_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_multiset. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_multiset): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator begin() const + { return table_.begin(); } + + //! Effects: Returns a const_iterator pointing to the beginning + //! of the unordered_multiset. + //! + //! Complexity: Amortized constant time. + //! Worst case (empty unordered_multiset): O(this->bucket_count()) + //! + //! Throws: Nothing. + const_iterator cbegin() const + { return table_.cbegin(); } + + //! Effects: Returns an iterator pointing to the end of the unordered_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end() + { return table_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const + { return table_.end(); } + + //! Effects: Returns a const_iterator pointing to the end of the unordered_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const + { return table_.cend(); } + + //! Effects: Returns the hasher object used by the unordered_set. + //! + //! Complexity: Constant. + //! + //! Throws: If hasher copy-constructor throws. + hasher hash_function() const + { return table_.hash_function(); } + + //! Effects: Returns the key_equal object used by the unordered_multiset. + //! + //! Complexity: Constant. + //! + //! Throws: If key_equal copy-constructor throws. + key_equal key_eq() const + { return table_.key_eq(); } + + //! Effects: Returns true is the container is empty. + //! + //! Complexity: if constant-time size option is disabled, average constant time + //! (worst case, with empty() == true): O(this->bucket_count()). + //! Otherwise constant. + //! + //! Throws: Nothing. + bool empty() const + { return table_.empty(); } + + //! Effects: Returns the number of elements stored in the unordered_multiset. + //! + //! Complexity: Linear to elements contained in *this if + //! constant-time size option is enabled. Constant-time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { return table_.size(); } + + //! Requires: the hasher and the equality function unqualified swap + //! call should not throw. + //! + //! Effects: Swaps the contents of two unordered_multisets. + //! Swaps also the contained bucket array and equality and hasher functors. + //! + //! + //! Complexity: Constant. + //! + //! Throws: If the swap() call for the comparison or hash functors + //! found using ADL throw. Basic guarantee. + void swap(unordered_multiset_impl& other) + { table_.swap(other.table_); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws. + template + void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer) + { table_.clone_from(src.table_, cloner, disposer); } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the unordered_multiset. + //! + //! Returns: An iterator to the new inserted value. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert(reference value) + { return table_.insert_equal(value); } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Equivalent to this->insert(t) for each element in [b, e). + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert(Iterator b, Iterator e) + { table_.insert_equal(b, e); } + + //! Effects: Erases the element pointed to by i. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased element. No destructors are called. + void erase(const_iterator i) + { table_.erase(i); } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void erase(const_iterator b, const_iterator e) + { table_.erase(b, e); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return table_.erase(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Erases all the elements that have the same hash and + //! compare equal with the given key. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the hash_func or the equal_func functors throws. + //! Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.erase(key, hash_func, equal_func); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by i. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + void erase_and_dispose(const_iterator i, Disposer disposer) + { table_.erase_and_dispose(i, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average case O(std::distance(b, e)), + //! worst case O(this->size()). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { table_.erase_and_dispose(b, e, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. Basic guarantee. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { return table_.erase_and_dispose(value, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "equal_func". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: Average case O(this->count(value)). + //! Worst case O(this->size()). + //! + //! Throws: If hash_func or equal_func throw. Basic guarantee. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer) + { return table_.erase_and_dispose(key, hash_func, equal_func, disposer); } + + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { return table_.clear(); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements of the container. + //! + //! Complexity: Linear to the number of elements on the container. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + void clear_and_dispose(Disposer disposer) + { return table_.clear_and_dispose(disposer); } + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + size_type count(const_reference value) const + { return table_.count(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + template + size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.count(key, hash_func, equal_func); } + + //! Effects: Finds an iterator to the first element whose value is + //! "value" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + iterator find(const_reference value) + { return table_.find(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.find(key, hash_func, equal_func); } + + //! Effects: Finds a const_iterator to the first element whose key is + //! "key" or end() if that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + const_iterator find(const_reference value) const + { return table_.find(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Finds an iterator to the first element whose key is + //! "key" according to the given hasher and equality functor or end() if + //! that element does not exist. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.find(key, hash_func, equal_func); } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair equal_range(const_reference value) + { return table_.equal_range(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair equal_range + (const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) + { return table_.equal_range(key, hash_func, equal_func); } + + //! Effects: Returns a range containing all elements with values equivalent + //! to value. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(value)). Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + std::pair + equal_range(const_reference value) const + { return table_.equal_range(value); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! "key_value_equal" must be a equality function that induces + //! the same equality as key_equal. The difference is that + //! "key_value_equal" compares an arbitrary key with the contained values. + //! + //! Effects: Returns a range containing all elements with equivalent + //! keys. Returns std::make_pair(this->end(), this->end()) if no such + //! elements exist. + //! + //! Complexity: Average case O(this->count(key, hash_func, equal_func)). + //! Worst case O(this->size()). + //! + //! Throws: If the internal hasher or the equality functor throws. + //! + //! Note: This function is used when constructing a value_type + //! is expensive and the value_type can be compared with a cheaper + //! key type. Usually this key is part of the value_type. + template + std::pair + equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const + { return table_.equal_range(key, hash_func, equal_func); } + + //! Requires: value must be an lvalue and shall be in a unordered_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator belonging to the unordered_multiset + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the hash function throws. + iterator iterator_to(reference value) + { return table_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_multiset of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator belonging to the + //! unordered_multiset that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: If the hash function throws. + const_iterator iterator_to(const_reference value) const + { return table_.iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static local_iterator s_local_iterator_to(reference value) + { return table_type::s_local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_local_iterator s_local_iterator_to(const_reference value) + { return table_type::s_local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid local_iterator belonging to the unordered_set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + local_iterator local_iterator_to(reference value) + { return table_.local_iterator_to(value); } + + //! Requires: value must be an lvalue and shall be in a unordered_set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_local_iterator belonging to + //! the unordered_set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_local_iterator local_iterator_to(const_reference value) const + { return table_.local_iterator_to(value); } + + //! Effects: Returns the number of buckets passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_count() const + { return table_.bucket_count(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns the number of elements in the nth bucket. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + size_type bucket_size(size_type n) const + { return table_.bucket_size(n); } + + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If the hash functor throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + size_type bucket(const value_type& k) const + { return table_.bucket(k); } + + //! Requires: "hash_func" must be a hash function that induces + //! the same hash values as the stored hasher. The difference is that + //! "hash_func" hashes the given key instead of the value_type. + //! + //! Effects: Returns the index of the bucket in which elements + //! with keys equivalent to k would be found, if any such element existed. + //! + //! Complexity: Constant. + //! + //! Throws: If the hash functor throws. + //! + //! Note: the return value is in the range [0, this->bucket_count()). + template + size_type bucket(const KeyType& k, const KeyHasher &hash_func) const + { return table_.bucket(k, hash_func); } + + //! Effects: Returns the bucket array pointer passed in the constructor + //! or the last rehash function. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bucket_ptr bucket_pointer() const + { return table_.bucket_pointer(); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator begin(size_type n) + { return table_.begin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator begin(size_type n) const + { return table_.begin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the beginning + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cbegin(size_type n) const + { return table_.cbegin(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + local_iterator end(size_type n) + { return table_.end(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator end(size_type n) const + { return table_.end(n); } + + //! Requires: n is in the range [0, this->bucket_count()). + //! + //! Effects: Returns a const_local_iterator pointing to the end + //! of the sequence stored in the bucket n. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: [this->begin(n), this->end(n)) is a valid range + //! containing all of the elements in the nth bucket. + const_local_iterator cend(size_type n) const + { return table_.cend(n); } + + //! Requires: new_buckets must be a pointer to a new bucket array + //! or the same as the old bucket array. new_size is the length of the + //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer() + //! n can be bigger or smaller than this->bucket_count(). + //! + //! Effects: Updates the internal reference with the new bucket erases + //! the values from the old bucket and inserts then in the new one. + //! + //! Complexity: Average case linear in this->size(), worst case quadratic. + //! + //! Throws: If the hasher functor throws. + void rehash(const bucket_traits &new_bucket_traits) + { table_.rehash(new_bucket_traits); } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is bigger than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! higher possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_upper_bucket_count(size_type n) + { return table_type::suggested_upper_bucket_count(n); } + + //! Effects: Returns the nearest new bucket count optimized for + //! the container that is smaller than n. This suggestion can be used + //! to create bucket arrays with a size that will usually improve + //! container's performance. If such value does not exist, the + //! lower possible value is returned. + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static size_type suggested_lower_bucket_count(size_type n) + { return table_type::suggested_lower_bucket_count(n); } +}; + +//! Helper metafunction to define an \c unordered_multiset that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_unordered_multiset +{ + /// @cond + typedef unordered_multiset_impl + < typename make_hashtable_opt + ::type + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +class unordered_multiset + : public make_unordered_multiset::type +{ + typedef typename make_unordered_multiset + ::type Base; + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + public: + typedef typename Base::value_traits value_traits; + typedef typename Base::bucket_traits bucket_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::bucket_ptr bucket_ptr; + typedef typename Base::size_type size_type; + typedef typename Base::hasher hasher; + typedef typename Base::key_equal key_equal; + + unordered_multiset( const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b_traits, hash_func, equal_func, v_traits) + {} + + template + unordered_multiset( Iterator b + , Iterator e + , const bucket_traits &b_traits + , const hasher & hash_func = hasher() + , const key_equal &equal_func = key_equal() + , const value_traits &v_traits = value_traits()) + : Base(b, e, b_traits, hash_func, equal_func, v_traits) + {} +}; + +#endif + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP diff --git a/thirdparty/boost/intrusive/unordered_set_hook.hpp b/thirdparty/boost/intrusive/unordered_set_hook.hpp new file mode 100644 index 0000000..b9a5cd9 --- /dev/null +++ b/thirdparty/boost/intrusive/unordered_set_hook.hpp @@ -0,0 +1,318 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP +#define BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +template +struct slist_node_plus_hash +{ + typedef typename boost::pointer_to_other + ::type node_ptr; + node_ptr next_; + std::size_t hash_; +}; + +// slist_node_traits can be used with circular_slist_algorithms and supplies +// a slist_node holding the pointers needed for a singly-linked list +// it is used by slist_base_hook and slist_member_hook +template +struct slist_node_traits_plus_hash +{ + typedef slist_node_plus_hash node; + typedef typename boost::pointer_to_other + ::type node_ptr; + typedef typename boost::pointer_to_other + ::type const_node_ptr; + + static const bool store_hash = true; + + static node_ptr get_next(const_node_ptr n) + { return n->next_; } + + static void set_next(node_ptr n, node_ptr next) + { n->next_ = next; } + + static std::size_t get_hash(const_node_ptr n) + { return n->hash_; } + + static void set_hash(node_ptr n, std::size_t h) + { n->hash_ = h; } +}; + +template +struct get_uset_node_algo +{ + typedef typename detail::if_c + < StoreHash + , slist_node_traits_plus_hash + , slist_node_traits + >::type node_traits_type; + typedef circular_slist_algorithms type; +}; +/// @endcond + +//! Helper metafunction to define a \c unordered_set_base_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_unordered_set_base_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_uset_node_algo + , typename packed_options::tag + , packed_options::link_mode + , detail::UsetBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Derive a class from unordered_set_base_hook in order to store objects in +//! in an unordered_set/unordered_multi_set. unordered_set_base_hook holds the data necessary to maintain +//! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set. +//! +//! The hook admits the following options: \c tag<>, \c void_pointer<>, +//! \c link_mode<> and \c store_hash<>. +//! +//! \c tag<> defines a tag to identify the node. +//! The same tag value can be used in different classes, but if a class is +//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its +//! unique tag. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c store_hash<> will tell the hook to store the hash of the value +//! to speed up rehashings. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class unordered_set_base_hook + : public make_unordered_set_base_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + unordered_set_base_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + unordered_set_base_hook(const unordered_set_base_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + unordered_set_base_hook& operator=(const unordered_set_base_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an unordered_set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~unordered_set_base_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(unordered_set_base_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c unordered_set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + + +//! Helper metafunction to define a \c unordered_set_member_hook that yields to the same +//! type when the same options (either explicitly or implicitly) are used. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +struct make_unordered_set_member_hook +{ + /// @cond + typedef typename pack_options + < hook_defaults, O1, O2, O3, O4>::type packed_options; + + typedef detail::generic_hook + < get_uset_node_algo< typename packed_options::void_pointer + , packed_options::store_hash + > + , member_tag + , packed_options::link_mode + , detail::NoBaseHook + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +//! Put a public data member unordered_set_member_hook in order to store objects of this class in +//! an unordered_set/unordered_multi_set. unordered_set_member_hook holds the data necessary for maintaining the +//! unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set. +//! +//! The hook admits the following options: \c void_pointer<>, +//! \c link_mode<> and \c store_hash<>. +//! +//! \c void_pointer<> is the pointer type that will be used internally in the hook +//! and the the container configured to use this hook. +//! +//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, +//! \c auto_unlink or \c safe_link). +//! +//! \c store_hash<> will tell the hook to store the hash of the value +//! to speed up rehashings. +#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED +template +#else +template +#endif +class unordered_set_member_hook + : public make_unordered_set_member_hook::type +{ + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. + //! + //! Throws: Nothing. + unordered_set_member_hook(); + + //! Effects: If link_mode is \c auto_unlink or \c safe_link + //! initializes the node to an unlinked state. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing a copy-constructor + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + unordered_set_member_hook(const unordered_set_member_hook& ); + + //! Effects: Empty function. The argument is ignored. + //! + //! Throws: Nothing. + //! + //! Rationale: Providing an assignment operator + //! makes classes using the hook STL-compliant without forcing the + //! user to do some additional work. \c swap can be used to emulate + //! move-semantics. + unordered_set_member_hook& operator=(const unordered_set_member_hook& ); + + //! Effects: If link_mode is \c normal_link, the destructor does + //! nothing (ie. no code is generated). If link_mode is \c safe_link and the + //! object is stored in an unordered_set an assertion is raised. If link_mode is + //! \c auto_unlink and \c is_linked() is true, the node is unlinked. + //! + //! Throws: Nothing. + ~unordered_set_member_hook(); + + //! Effects: Swapping two nodes swaps the position of the elements + //! related to those nodes in one or two containers. That is, if the node + //! this is part of the element e1, the node x is part of the element e2 + //! and both elements are included in the containers s1 and s2, then after + //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 + //! at the position of e1. If one element is not in a container, then + //! after the swap-operation the other element is not in a container. + //! Iterators to e1 and e2 related to those nodes are invalidated. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + void swap_nodes(unordered_set_member_hook &other); + + //! Precondition: link_mode must be \c safe_link or \c auto_unlink. + //! + //! Returns: true, if the node belongs to a container, false + //! otherwise. This function can be used to test whether \c unordered_set::iterator_to + //! will return a valid iterator. + //! + //! Complexity: Constant + bool is_linked() const; + + //! Effects: Removes the node if it's inserted in a container. + //! This function is only allowed if link_mode is \c auto_unlink. + //! + //! Throws: Nothing. + void unlink(); + #endif +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP diff --git a/thirdparty/boost/intrusive_ptr.hpp b/thirdparty/boost/intrusive_ptr.hpp new file mode 100644 index 0000000..fdaac0d --- /dev/null +++ b/thirdparty/boost/intrusive_ptr.hpp @@ -0,0 +1,284 @@ +#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED +#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED + +// +// intrusive_ptr.hpp +// +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation. +// + +#include + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +#include +#include + +#include // for std::less +#include // for std::basic_ostream + + +namespace boost +{ + +// +// intrusive_ptr +// +// A smart pointer that uses intrusive reference counting. +// +// Relies on unqualified calls to +// +// void intrusive_ptr_add_ref(T * p); +// void intrusive_ptr_release(T * p); +// +// (p != 0) +// +// The object is responsible for destroying itself. +// + +template class intrusive_ptr +{ +private: + + typedef intrusive_ptr this_type; + +public: + + typedef T element_type; + + intrusive_ptr(): p_(0) + { + } + + intrusive_ptr(T * p, bool add_ref = true): p_(p) + { + if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.get()) + { + if(p_ != 0) intrusive_ptr_add_ref(p_); + } + +#endif + + intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_) + { + if(p_ != 0) intrusive_ptr_add_ref(p_); + } + + ~intrusive_ptr() + { + if(p_ != 0) intrusive_ptr_release(p_); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + +#endif + + intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + intrusive_ptr & operator=(T * rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + void reset( T * rhs ) + { + this_type( rhs ).swap( *this ); + } + + T * get() const + { + return p_; + } + + T & operator*() const + { + BOOST_ASSERT( p_ != 0 ); + return *p_; + } + + T * operator->() const + { + BOOST_ASSERT( p_ != 0 ); + return p_; + } + +#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) + + operator bool () const + { + return p_ != 0; + } + +#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return p_ == 0? 0: &this_type::get; + } + +#else + + typedef T * this_type::*unspecified_bool_type; + + operator unspecified_bool_type () const + { + return p_ == 0? 0: &this_type::p_; + } + +#endif + + // operator! is a Borland-specific workaround + bool operator! () const + { + return p_ == 0; + } + + void swap(intrusive_ptr & rhs) + { + T * tmp = p_; + p_ = rhs.p_; + rhs.p_ = tmp; + } + +private: + + T * p_; +}; + +template inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator==(intrusive_ptr const & a, U * b) +{ + return a.get() == b; +} + +template inline bool operator!=(intrusive_ptr const & a, U * b) +{ + return a.get() != b; +} + +template inline bool operator==(T * a, intrusive_ptr const & b) +{ + return a == b.get(); +} + +template inline bool operator!=(T * a, intrusive_ptr const & b) +{ + return a != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() != b.get(); +} + +#endif + +template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) +{ + lhs.swap(rhs); +} + +// mem_fn support + +template T * get_pointer(intrusive_ptr const & p) +{ + return p.get(); +} + +template intrusive_ptr static_pointer_cast(intrusive_ptr const & p) +{ + return static_cast(p.get()); +} + +template intrusive_ptr const_pointer_cast(intrusive_ptr const & p) +{ + return const_cast(p.get()); +} + +template intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) +{ + return dynamic_cast(p.get()); +} + +// operator<< + +#if defined(__GNUC__) && (__GNUC__ < 3) + +template std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + +// in STLport's no-iostreams mode no iostream symbols can be used +#ifndef _STLP_NO_IOSTREAMS + +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) +# else +template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) +# endif +{ + os << p.get(); + return os; +} + +#endif // _STLP_NO_IOSTREAMS + +#endif // __GNUC__ < 3 + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED diff --git a/thirdparty/boost/io/ios_state.hpp b/thirdparty/boost/io/ios_state.hpp new file mode 100644 index 0000000..848e6fd --- /dev/null +++ b/thirdparty/boost/io/ios_state.hpp @@ -0,0 +1,431 @@ +// Boost io/ios_state.hpp header file --------------------------------------// + +// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_IO_IOS_STATE_HPP +#define BOOST_IO_IOS_STATE_HPP + +#include // self include +#include + +#include // for std::ios_base, std::basic_ios, etc. +#ifndef BOOST_NO_STD_LOCALE +#include // for std::locale +#endif +#include // for std::basic_ostream +#include // for std::basic_streambuf +#include // for std::char_traits + + +namespace boost +{ +namespace io +{ + + +// Basic stream state saver class declarations -----------------------------// + +class ios_flags_saver +{ +public: + typedef ::std::ios_base state_type; + typedef ::std::ios_base::fmtflags aspect_type; + + explicit ios_flags_saver( state_type &s ) + : s_save_( s ), a_save_( s.flags() ) + {} + ios_flags_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.flags(a) ) + {} + ~ios_flags_saver() + { this->restore(); } + + void restore() + { s_save_.flags( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; + + ios_flags_saver& operator=(const ios_flags_saver&); +}; + +class ios_precision_saver +{ +public: + typedef ::std::ios_base state_type; + typedef ::std::streamsize aspect_type; + + explicit ios_precision_saver( state_type &s ) + : s_save_( s ), a_save_( s.precision() ) + {} + ios_precision_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.precision(a) ) + {} + ~ios_precision_saver() + { this->restore(); } + + void restore() + { s_save_.precision( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; + + ios_precision_saver& operator=(const ios_precision_saver&); +}; + +class ios_width_saver +{ +public: + typedef ::std::ios_base state_type; + typedef ::std::streamsize aspect_type; + + explicit ios_width_saver( state_type &s ) + : s_save_( s ), a_save_( s.width() ) + {} + ios_width_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.width(a) ) + {} + ~ios_width_saver() + { this->restore(); } + + void restore() + { s_save_.width( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; + ios_width_saver& operator=(const ios_width_saver&); +}; + + +// Advanced stream state saver class template declarations -----------------// + +template < typename Ch, class Tr > +class basic_ios_iostate_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef ::std::ios_base::iostate aspect_type; + + explicit basic_ios_iostate_saver( state_type &s ) + : s_save_( s ), a_save_( s.rdstate() ) + {} + basic_ios_iostate_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.rdstate() ) + { s.clear(a); } + ~basic_ios_iostate_saver() + { this->restore(); } + + void restore() + { s_save_.clear( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +template < typename Ch, class Tr > +class basic_ios_exception_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef ::std::ios_base::iostate aspect_type; + + explicit basic_ios_exception_saver( state_type &s ) + : s_save_( s ), a_save_( s.exceptions() ) + {} +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + basic_ios_exception_saver( state_type &s, aspect_type a ) +#else + basic_ios_exception_saver( state_type &s, aspect_type const &a ) +#endif + : s_save_( s ), a_save_( s.exceptions() ) + { s.exceptions(a); } + ~basic_ios_exception_saver() + { this->restore(); } + + void restore() + { s_save_.exceptions( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +template < typename Ch, class Tr > +class basic_ios_tie_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef ::std::basic_ostream * aspect_type; + + explicit basic_ios_tie_saver( state_type &s ) + : s_save_( s ), a_save_( s.tie() ) + {} + basic_ios_tie_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.tie(a) ) + {} + ~basic_ios_tie_saver() + { this->restore(); } + + void restore() + { s_save_.tie( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +template < typename Ch, class Tr > +class basic_ios_rdbuf_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef ::std::basic_streambuf * aspect_type; + + explicit basic_ios_rdbuf_saver( state_type &s ) + : s_save_( s ), a_save_( s.rdbuf() ) + {} + basic_ios_rdbuf_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.rdbuf(a) ) + {} + ~basic_ios_rdbuf_saver() + { this->restore(); } + + void restore() + { s_save_.rdbuf( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +template < typename Ch, class Tr > +class basic_ios_fill_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef typename state_type::char_type aspect_type; + + explicit basic_ios_fill_saver( state_type &s ) + : s_save_( s ), a_save_( s.fill() ) + {} + basic_ios_fill_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.fill(a) ) + {} + ~basic_ios_fill_saver() + { this->restore(); } + + void restore() + { s_save_.fill( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; + +#ifndef BOOST_NO_STD_LOCALE +template < typename Ch, class Tr > +class basic_ios_locale_saver +{ +public: + typedef ::std::basic_ios state_type; + typedef ::std::locale aspect_type; + + explicit basic_ios_locale_saver( state_type &s ) + : s_save_( s ), a_save_( s.getloc() ) + {} + basic_ios_locale_saver( state_type &s, aspect_type const &a ) + : s_save_( s ), a_save_( s.imbue(a) ) + {} + ~basic_ios_locale_saver() + { this->restore(); } + + void restore() + { s_save_.imbue( a_save_ ); } + +private: + state_type & s_save_; + aspect_type const a_save_; +}; +#endif + + +// User-defined stream state saver class declarations ----------------------// + +class ios_iword_saver +{ +public: + typedef ::std::ios_base state_type; + typedef int index_type; + typedef long aspect_type; + + explicit ios_iword_saver( state_type &s, index_type i ) + : s_save_( s ), a_save_( s.iword(i) ), i_save_( i ) + {} + ios_iword_saver( state_type &s, index_type i, aspect_type const &a ) + : s_save_( s ), a_save_( s.iword(i) ), i_save_( i ) + { s.iword(i) = a; } + ~ios_iword_saver() + { this->restore(); } + + void restore() + { s_save_.iword( i_save_ ) = a_save_; } + +private: + state_type & s_save_; + aspect_type const a_save_; + index_type const i_save_; + + ios_iword_saver& operator=(const ios_iword_saver&); +}; + +class ios_pword_saver +{ +public: + typedef ::std::ios_base state_type; + typedef int index_type; + typedef void * aspect_type; + + explicit ios_pword_saver( state_type &s, index_type i ) + : s_save_( s ), a_save_( s.pword(i) ), i_save_( i ) + {} + ios_pword_saver( state_type &s, index_type i, aspect_type const &a ) + : s_save_( s ), a_save_( s.pword(i) ), i_save_( i ) + { s.pword(i) = a; } + ~ios_pword_saver() + { this->restore(); } + + void restore() + { s_save_.pword( i_save_ ) = a_save_; } + +private: + state_type & s_save_; + aspect_type const a_save_; + index_type const i_save_; + + ios_pword_saver operator=(const ios_pword_saver&); +}; + + +// Combined stream state saver class (template) declarations ---------------// + +class ios_base_all_saver +{ +public: + typedef ::std::ios_base state_type; + + explicit ios_base_all_saver( state_type &s ) + : s_save_( s ), a1_save_( s.flags() ), a2_save_( s.precision() ) + , a3_save_( s.width() ) + {} + + ~ios_base_all_saver() + { this->restore(); } + + void restore() + { + s_save_.width( a3_save_ ); + s_save_.precision( a2_save_ ); + s_save_.flags( a1_save_ ); + } + +private: + state_type & s_save_; + state_type::fmtflags const a1_save_; + ::std::streamsize const a2_save_; + ::std::streamsize const a3_save_; + + ios_base_all_saver& operator=(const ios_base_all_saver&); +}; + +template < typename Ch, class Tr > +class basic_ios_all_saver +{ +public: + typedef ::std::basic_ios state_type; + + explicit basic_ios_all_saver( state_type &s ) + : s_save_( s ), a1_save_( s.flags() ), a2_save_( s.precision() ) + , a3_save_( s.width() ), a4_save_( s.rdstate() ) + , a5_save_( s.exceptions() ), a6_save_( s.tie() ) + , a7_save_( s.rdbuf() ), a8_save_( s.fill() ) + #ifndef BOOST_NO_STD_LOCALE + , a9_save_( s.getloc() ) + #endif + {} + + ~basic_ios_all_saver() + { this->restore(); } + + void restore() + { + #ifndef BOOST_NO_STD_LOCALE + s_save_.imbue( a9_save_ ); + #endif + s_save_.fill( a8_save_ ); + s_save_.rdbuf( a7_save_ ); + s_save_.tie( a6_save_ ); + s_save_.exceptions( a5_save_ ); + s_save_.clear( a4_save_ ); + s_save_.width( a3_save_ ); + s_save_.precision( a2_save_ ); + s_save_.flags( a1_save_ ); + } + +private: + state_type & s_save_; + typename state_type::fmtflags const a1_save_; + ::std::streamsize const a2_save_; + ::std::streamsize const a3_save_; + typename state_type::iostate const a4_save_; + typename state_type::iostate const a5_save_; + ::std::basic_ostream * const a6_save_; + ::std::basic_streambuf * const a7_save_; + typename state_type::char_type const a8_save_; + #ifndef BOOST_NO_STD_LOCALE + ::std::locale const a9_save_; + #endif +}; + +class ios_all_word_saver +{ +public: + typedef ::std::ios_base state_type; + typedef int index_type; + + ios_all_word_saver( state_type &s, index_type i ) + : s_save_( s ), i_save_( i ), a1_save_( s.iword(i) ) + , a2_save_( s.pword(i) ) + {} + + ~ios_all_word_saver() + { this->restore(); } + + void restore() + { + s_save_.pword( i_save_ ) = a2_save_; + s_save_.iword( i_save_ ) = a1_save_; + } + +private: + state_type & s_save_; + index_type const i_save_; + long const a1_save_; + void * const a2_save_; + + ios_all_word_saver& operator=(const ios_all_word_saver&); +}; + + +} // namespace io +} // namespace boost + + +#endif // BOOST_IO_IOS_STATE_HPP diff --git a/thirdparty/boost/io_fwd.hpp b/thirdparty/boost/io_fwd.hpp new file mode 100644 index 0000000..0ed46ea --- /dev/null +++ b/thirdparty/boost/io_fwd.hpp @@ -0,0 +1,67 @@ +// Boost io_fwd.hpp header file --------------------------------------------// + +// Copyright 2002 Daryle Walker. Use, modification, and distribution are subject +// to the Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_IO_FWD_HPP +#define BOOST_IO_FWD_HPP + +#include // for std::char_traits (declaration) + + +namespace boost +{ +namespace io +{ + + +// From -------------------------------------------// + +class ios_flags_saver; +class ios_precision_saver; +class ios_width_saver; +class ios_base_all_saver; + +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_iostate_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_exception_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_tie_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_rdbuf_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_fill_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_locale_saver; +template < typename Ch, class Tr = ::std::char_traits > + class basic_ios_all_saver; + +typedef basic_ios_iostate_saver ios_iostate_saver; +typedef basic_ios_iostate_saver wios_iostate_saver; +typedef basic_ios_exception_saver ios_exception_saver; +typedef basic_ios_exception_saver wios_exception_saver; +typedef basic_ios_tie_saver ios_tie_saver; +typedef basic_ios_tie_saver wios_tie_saver; +typedef basic_ios_rdbuf_saver ios_rdbuf_saver; +typedef basic_ios_rdbuf_saver wios_rdbuf_saver; +typedef basic_ios_fill_saver ios_fill_saver; +typedef basic_ios_fill_saver wios_fill_saver; +typedef basic_ios_locale_saver ios_locale_saver; +typedef basic_ios_locale_saver wios_locale_saver; +typedef basic_ios_all_saver ios_all_saver; +typedef basic_ios_all_saver wios_all_saver; + +class ios_iword_saver; +class ios_pword_saver; +class ios_all_word_saver; + + +} // namespace io +} // namespace boost + + +#endif // BOOST_IO_FWD_HPP diff --git a/thirdparty/boost/iostreams/categories.hpp b/thirdparty/boost/iostreams/categories.hpp new file mode 100644 index 0000000..2c8b83b --- /dev/null +++ b/thirdparty/boost/iostreams/categories.hpp @@ -0,0 +1,175 @@ +// (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 category and mode tags for classifying filters, devices and +// standard stream and stream buffers types. + +#ifndef BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED +#define BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +namespace boost { namespace iostreams { + +//------------------Tags for dispatch according to i/o mode-------------------// + +struct any_tag { }; +namespace detail { struct two_sequence : virtual any_tag { }; } +namespace detail { struct random_access : virtual any_tag { }; } +namespace detail { struct one_head : virtual any_tag { }; } +namespace detail { struct two_head : virtual any_tag { }; } +struct input : virtual any_tag { }; +struct output : virtual any_tag { }; +struct bidirectional : virtual input, virtual output, detail::two_sequence { }; +struct dual_use : virtual input, virtual output { }; // Pseudo-mode. +struct input_seekable : virtual input, virtual detail::random_access { }; +struct output_seekable : virtual output, virtual detail::random_access { }; +struct seekable + : virtual input_seekable, + virtual output_seekable, + detail::one_head + { }; +struct dual_seekable + : virtual input_seekable, + virtual output_seekable, + detail::two_head + { }; +struct bidirectional_seekable + : input_seekable, output_seekable, + bidirectional, detail::two_head + { }; + +//------------------Tags for use as i/o categories----------------------------// + +struct device_tag : virtual any_tag { }; +struct filter_tag : virtual any_tag { }; + + // + // Tags for optional behavior. + // + +struct peekable_tag : virtual any_tag { }; // Devices. +struct closable_tag : virtual any_tag { }; +struct flushable_tag : virtual any_tag { }; +struct localizable_tag : virtual any_tag { }; +struct optimally_buffered_tag : virtual any_tag { }; +struct direct_tag : virtual any_tag { }; // Devices. +struct multichar_tag : virtual any_tag { }; // Filters. + +struct source_tag : device_tag, input { }; +struct sink_tag : device_tag, output { }; +struct bidirectional_device_tag : device_tag, bidirectional { }; +struct seekable_device_tag : virtual device_tag, seekable { }; + +struct input_filter_tag : filter_tag, input { }; +struct output_filter_tag : filter_tag, output { }; +struct bidirectional_filter_tag : filter_tag, bidirectional { }; +struct seekable_filter_tag : filter_tag, seekable { }; +struct dual_use_filter_tag : filter_tag, dual_use { }; + +struct multichar_input_filter_tag + : multichar_tag, + input_filter_tag + { }; +struct multichar_output_filter_tag + : multichar_tag, + output_filter_tag + { }; +struct multichar_bidirectional_filter_tag + : multichar_tag, + bidirectional_filter_tag + { }; +struct multichar_seekable_filter_tag + : multichar_tag, + seekable_filter_tag + { }; +struct multichar_dual_use_filter_tag + : filter_tag, + dual_use + { }; + + // + // Tags for standard streams and streambufs. + // + +struct std_io_tag : virtual localizable_tag { }; +struct istream_tag + : virtual device_tag, + virtual peekable_tag, + virtual std_io_tag + { }; +struct ostream_tag + : virtual device_tag, + virtual std_io_tag + { }; +struct iostream_tag + : istream_tag, + ostream_tag + { }; +struct streambuf_tag + : device_tag, + peekable_tag, + std_io_tag + { }; +struct ifstream_tag + : input_seekable, + closable_tag, + istream_tag + { }; +struct ofstream_tag + : output_seekable, + closable_tag, + ostream_tag + { }; +struct fstream_tag + : seekable, + closable_tag, + iostream_tag + { }; +struct filebuf_tag + : seekable, + closable_tag, + streambuf_tag + { }; +struct istringstream_tag + : input_seekable, + istream_tag + { }; +struct ostringstream_tag + : output_seekable, + ostream_tag + { }; +struct stringstream_tag + : dual_seekable, + iostream_tag + { }; +struct stringbuf_tag + : dual_seekable, + streambuf_tag + { }; +struct generic_istream_tag + : input_seekable, + istream_tag + { }; +struct generic_ostream_tag + : output_seekable, + ostream_tag + { }; +struct generic_iostream_tag + : seekable, + iostream_tag + { }; +struct generic_streambuf_tag + : seekable, + streambuf_tag + { }; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/chain.hpp b/thirdparty/boost/iostreams/chain.hpp new file mode 100644 index 0000000..d96dab7 --- /dev/null +++ b/thirdparty/boost/iostreams/chain.hpp @@ -0,0 +1,585 @@ +// (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) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include // unary_function. +#include // advance. +#include +#include // allocator, auto_ptr. +#include +#include // logic_error, out_of_range. +#include +#include // BOOST_MSVC, template friends, +#include // BOOST_NESTED_TEMPLATE +#include +#include +#include +#include +#include // pubsync. +#include +#include +#include +#include // is_filter. +#include +#include +#include +#include +#include +#include +#include // VC6.5 requires this +#if BOOST_WORKAROUND(BOOST_MSVC, < 1310) // #include order +# include +#endif + +// Sometimes type_info objects must be compared by name. Borrowed from +// Boost.Python and Boost.Function. +#if (defined(__GNUC__) && __GNUC__ >= 3) || \ + 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 +#define BOOST_IOSTREAMS_COMPONENT_TYPE(chain, index) \ + chain.component_type( index ) \ + /**/ + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) +# define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \ + chain.component< target >( index ) \ + /**/ +#else +# define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \ + chain.component( index, ::boost::type< target >() ) \ + /**/ +#endif + +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 send 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: + + //----------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(int 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(int 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(int 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 std::type_info& component_type(int n) const + { + if (static_cast(n) >= size()) + throw std::out_of_range("bad chain offset"); + return (*boost::next(list().begin(), n))->component_type(); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) + // Deprecated. + template + const std::type_info& 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); } +#endif + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) + private: +#endif + template + T* component(int n, boost::type) const + { + if (static_cast(n) >= size()) + throw std::out_of_range("bad chain offset"); + streambuf_type* link = *boost::next(list().begin(), n); + if (BOOST_IOSTREAMS_COMPARE_TYPE_ID(link->component_type(), 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, int buffer_size = -1, int pback_size = -1) + { + typedef typename iostreams::category_of::type category; + typedef typename unwrap_ios::type policy_type; + typedef stream_buffer< + policy_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()) + throw 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_; + std::auto_ptr + buf(new streambuf_t(t, buffer_size, pback_size)); + 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 : public std::unary_function { + 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(); 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_; + int 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) { *this = 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 std::type_info& component_type(int n) const + { return chain_->component_type(n); } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) + // Deprecated. + template + const std::type_info& 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(); } +#else + template + T* component(int n, boost::type t) const + { return chain_->component(n, t); } +#endif + + 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() { 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(__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() +{ + 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/thirdparty/boost/iostreams/char_traits.hpp b/thirdparty/boost/iostreams/char_traits.hpp new file mode 100644 index 0000000..107a576 --- /dev/null +++ b/thirdparty/boost/iostreams/char_traits.hpp @@ -0,0 +1,73 @@ +// (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_CHAR_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include // EOF. +#include // std::char_traits. +#include +#include +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +# include +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::wint_t; } +#endif + +namespace boost { namespace iostreams { + +// Dinkumware that comes with QNX Momentics 6.3.0, 4.0.2, incorrectly defines +// the EOF and WEOF macros to not std:: qualify the wint_t type (and so does +// Sun C++ 5.8 + STLport 4). Fix by placing the def in this scope. +// NOTE: Use BOOST_WORKAROUND? +#if (defined(__QNX__) && defined(BOOST_DINKUMWARE_STDLIB)) \ + || defined(__SUNPRO_CC) +using ::std::wint_t; +#endif + +const int WOULD_BLOCK = (int) (EOF - 1); + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +const std::wint_t WWOULD_BLOCK = (std::wint_t) (WEOF - 1); +#endif + +template +struct char_traits; + +template<> +struct char_traits : BOOST_IOSTREAMS_CHAR_TRAITS(char) { + static char newline() { return '\n'; } + static int good() { return '\n'; } + static int would_block() { return WOULD_BLOCK; } + static bool is_good(int c) { return c != EOF && c != WOULD_BLOCK; } + static bool is_eof(int c) { return c == EOF; } + static bool would_block(int c) { return c == WOULD_BLOCK; } +}; + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +template<> +struct char_traits : std::char_traits { + static wchar_t newline() { return L'\n'; } + static std::wint_t good() { return L'\n'; } + static std::wint_t would_block() { return WWOULD_BLOCK; } + static bool is_good(std::wint_t c) { return c != WEOF && c != WWOULD_BLOCK; } + static bool is_eof(std::wint_t c) { return c == WEOF; } + static bool would_block(std::wint_t c) { return c == WWOULD_BLOCK; } +}; +#endif + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/checked_operations.hpp b/thirdparty/boost/iostreams/checked_operations.hpp new file mode 100644 index 0000000..2d26fe2 --- /dev/null +++ b/thirdparty/boost/iostreams/checked_operations.hpp @@ -0,0 +1,151 @@ +// (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. + +// Contains implementations of get, read, put, write and seek which +// check a device's mode at runtime instead of compile time. + +#ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct read_write_if_impl; + +template +struct seek_if_impl; + +} // End namespace detail. + +template +typename int_type_of::type get_if(T& t) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::get(t); +} + +template +inline std::streamsize +read_if(T& t, typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::read(t, s, n); +} + +template +bool put_if(T& t, typename char_type_of::type c) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::put(t, c); +} + +template +inline std::streamsize write_if + (T& t, const typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::write(t, s, n); +} + +template +inline std::streampos +seek_if( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + typedef typename dispatch::type tag; + return seek_if_impl::seek(t, off, way, which); +} + +namespace detail { + +//------------------Specializations of read_write_if_impl---------------------// + +template<> +struct read_write_if_impl { + template + static typename int_type_of::type get(T& t) + { return iostreams::get(t); } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return iostreams::read(t, s, n); } + + template + static bool put(T&, typename char_type_of::type) + { throw cant_write(); } + + template + static std::streamsize + write(T&, const typename char_type_of::type*, std::streamsize) + { throw cant_write(); } +}; + +template<> +struct read_write_if_impl { + template + static typename int_type_of::type get(T&) + { throw cant_read(); } + + template + static std::streamsize + read(T&, typename char_type_of::type*, std::streamsize) + { throw cant_read(); } + + template + static bool put(T& t, typename char_type_of::type c) + { return iostreams::put(t, c); } + + template + static std::streamsize + write( T& t, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(t, s, n); } +}; + +//------------------Specializations of seek_if_impl---------------------------// + +template<> +struct seek_if_impl { + template + static std::streampos + seek( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return iostreams::seek(t, off, way, which); } +}; + +template<> +struct seek_if_impl { + template + static std::streampos + seek(T&, stream_offset, BOOST_IOS::seekdir, BOOST_IOS::openmode) + { throw cant_seek(); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/close.hpp b/thirdparty/boost/iostreams/close.hpp new file mode 100644 index 0000000..e778932 --- /dev/null +++ b/thirdparty/boost/iostreams/close.hpp @@ -0,0 +1,260 @@ +// (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_CLOSE_HPP_INCLUDED +#define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // BOOST_IOS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +template +void close(T& t); + +template +void close(T& t, BOOST_IOS::openmode which); + +template +void close(T& t, Sink& snk, BOOST_IOS::openmode which); + +namespace detail { + +template +void close_all(T& t) +{ + try { + boost::iostreams::close(t, BOOST_IOS::in); + } catch (...) { + try { + boost::iostreams::close(t, BOOST_IOS::out); + } catch (...) { } + throw; + } + boost::iostreams::close(t, BOOST_IOS::out); +} + +template +void close_all(T& t, Sink& snk) +{ + try { + boost::iostreams::close(t, snk, BOOST_IOS::in); + } catch (...) { + try { + boost::iostreams::close(t, snk, BOOST_IOS::out); + } catch (...) { } + throw; + } + boost::iostreams::close(t, snk, BOOST_IOS::out); +} + +} // End namespaces detail. + +} } // End namespaces iostreams, boost. + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------// +# include +#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------// + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct close_impl; + +} // End namespace detail. + +template +void close(T& t) { detail::close_all(t); } + +template +void close(T& t, BOOST_IOS::openmode which) +{ +#ifdef BOOST_IOSTREAMS_STRICT + assert(which == BOOST_IOS::in || which == BOOST_IOS::out); +#else + if (which == (BOOST_IOS::in | BOOST_IOS::out)) { + detail::close_all(t); + return; + } +#endif + detail::close_impl::close(detail::unwrap(t), which); +} + +template +void close(T& t, Sink& snk, BOOST_IOS::openmode which) +{ +#ifdef BOOST_IOSTREAMS_STRICT + assert(which == BOOST_IOS::in || which == BOOST_IOS::out); +#else + if (which == (BOOST_IOS::in | BOOST_IOS::out)) { + detail::close_all(t, snk); + return; + } +#endif + detail::close_impl::close(detail::unwrap(t), snk, which); +} + +namespace detail { + +//------------------Definition of close_impl----------------------------------// + +struct close_boost_stream { }; +struct close_filtering_stream { }; + +template +struct close_tag { + typedef typename category_of::type category; + typedef typename detail::unwrapped_type::type unwrapped; + typedef typename + iostreams::select< + mpl::not_< is_convertible >, + any_tag, + mpl::or_< + is_boost_stream, + is_boost_stream_buffer + >, + close_boost_stream, + mpl::or_< + is_filtering_stream, + is_filtering_streambuf + >, + close_filtering_stream, + mpl::or_< + is_convertible, + is_convertible + >, + two_sequence, + else_, + closable_tag + >::type type; +}; + +template +struct close_impl + : mpl::if_< + is_custom, + operations, + close_impl::type> + >::type + { }; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) + iostreams::flush(t); + } + + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) { + non_blocking_adapter nb(snk); + iostreams::flush(t, nb); + } + } +}; + +template<> +struct close_impl { + template + static void close(T& t) + { + t.close(); + } + template + static void close(T& t, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) + t.close(); + } +}; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in) && t.is_complete()) + t.pop(); + } +}; + +#include // Borland. +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) + t.close(); + } + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) { + non_blocking_adapter nb(snk); + t.close(nb); + } + } +}; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) { t.close(which); } + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + non_blocking_adapter nb(snk); + t.close(nb, which); + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------// + +#include + +#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/code_converter.hpp b/thirdparty/boost/iostreams/code_converter.hpp new file mode 100644 index 0000000..a562932 --- /dev/null +++ b/thirdparty/boost/iostreams/code_converter.hpp @@ -0,0 +1,422 @@ +// (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) && (_MSC_VER >= 1020) +# 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. +#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 policy_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 (...) { /* */ } + } + + void open(const Device& dev, int buffer_size) + { + if (flags_ & f_open) + throw BOOST_IOSTREAMS_FAILURE("already open"); + if (buffer_size == -1) + buffer_size = default_filter_buffer_size; + int 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;} + + policy_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() , int 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::policy_type policy_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() { } +#if BOOST_WORKAROUND(__GNUC__, < 3) + code_converter(code_converter& rhs) + : code_converter_base(rhs) + { } + code_converter(const code_converter& rhs) + : code_converter_base(rhs) + { } +#endif + 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(); } + policy_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(); + throw 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; // Fall through. + 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(); + throw code_conversion_error(); + } + } + return total; +} + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Borland 5.x + +#endif // #ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/combine.hpp b/thirdparty/boost/iostreams/combine.hpp new file mode 100644 index 0000000..c82c5c2 --- /dev/null +++ b/thirdparty/boost/iostreams/combine.hpp @@ -0,0 +1,249 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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 { +public: + typedef typename char_type_of::type char_type; + struct category + : bidirectional, + device_tag, + closable_tag, + localizable_tag + { }; + 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: + typedef typename char_type_of::type sink_char_type; + BOOST_STATIC_ASSERT((is_same::value)); + Source src_; + Sink sink_; +}; + +// +// Template name: combined_filter. +// Description: Model of Device defined in terms of a Source/Sink pair. +// Template paramters: +// 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; +public: + typedef typename char_type_of::type char_type; + struct category + : multichar_bidirectional_filter_tag, + closable_tag, + localizable_tag + { }; + 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: + typedef typename char_type_of::type output_char_type; + BOOST_STATIC_ASSERT((is_same::value)); + 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 Reource or Filter which performs input using the first member +// of the pair and output using the second member of the pair. +// Template paramters: +// 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/thirdparty/boost/iostreams/compose.hpp b/thirdparty/boost/iostreams/compose.hpp new file mode 100644 index 0000000..471ec53 --- /dev/null +++ b/thirdparty/boost/iostreams/compose.hpp @@ -0,0 +1,490 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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; +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 paramters: +// 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) + ); +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(__BORLANDC__, < 0x600) && \ + !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \ + !defined(__GNUC__) // ---------------------------------------------------// + +template +composite +compose (const Filter& filter, FilterOrDevice& fod) +{ return composite(filter, fod); } + +# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------// +#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/thirdparty/boost/iostreams/concepts.hpp b/thirdparty/boost/iostreams/concepts.hpp new file mode 100644 index 0000000..1e11929 --- /dev/null +++ b/thirdparty/boost/iostreams/concepts.hpp @@ -0,0 +1,129 @@ +// (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_CONCEPTS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC +#include +#include +#include +#include // openmode. +#include +#include +#include + +namespace boost { namespace iostreams { + +//--------------Definitions of helper templates for device concepts-----------// + +template +struct device { + typedef Ch char_type; + struct category + : Mode, + device_tag, + closable_tag, + localizable_tag + { }; + + void close() + { + using namespace detail; + BOOST_STATIC_ASSERT((!is_convertible::value)); + } + + void close(BOOST_IOS::openmode) + { + using namespace detail; + BOOST_STATIC_ASSERT((is_convertible::value)); + } + + template + void imbue(const Locale&) { } +}; + +template +struct wdevice : device { }; + +typedef device source; +typedef wdevice wsource; +typedef device sink; +typedef wdevice wsink; + +//--------------Definitions of helper templates for simple filter concepts----// + +template +struct filter { + typedef Ch char_type; + struct category + : Mode, + filter_tag, + closable_tag, + localizable_tag + { }; + + template + void close(Device&) + { + using namespace detail; + BOOST_STATIC_ASSERT((!is_convertible::value)); + BOOST_STATIC_ASSERT((!is_convertible::value)); + } + + template + void close(Device&, BOOST_IOS::openmode) + { + using namespace detail; + BOOST_STATIC_ASSERT( + (is_convertible::value) || + (is_convertible::value) + ); + } + + template + void imbue(const Locale&) { } +}; + +template +struct wfilter : filter { }; + +typedef filter input_filter; +typedef wfilter input_wfilter; +typedef filter output_filter; +typedef wfilter output_wfilter; +typedef filter seekable_filter; +typedef wfilter seekable_wfilter; +typedef filter dual_use_filter; +typedef wfilter dual_use_wfilter; + +//------Definitions of helper templates for multi-character filter cncepts----// + +template +struct multichar_filter : filter { + struct category : filter::category, multichar_tag { }; +}; + +template +struct multichar_wfilter : multichar_filter { }; + +typedef multichar_filter multichar_input_filter; +typedef multichar_wfilter multichar_input_wfilter; +typedef multichar_filter multichar_output_filter; +typedef multichar_wfilter multichar_output_wfilter; +typedef multichar_filter multichar_dual_use_filter; +typedef multichar_wfilter multichar_dual_use_wfilter; + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/constants.hpp b/thirdparty/boost/iostreams/constants.hpp new file mode 100644 index 0000000..dda7f35 --- /dev/null +++ b/thirdparty/boost/iostreams/constants.hpp @@ -0,0 +1,42 @@ +// (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 constants used by library. + +#ifndef BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE 4096 +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE 128 +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE 4 +#endif + +#include // streamsize. + +namespace boost { namespace iostreams { + +const std::streamsize default_device_buffer_size = + BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE; +const std::streamsize default_filter_buffer_size = + BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE; +const std::streamsize default_pback_buffer_size = + BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/copy.hpp b/thirdparty/boost/iostreams/copy.hpp new file mode 100644 index 0000000..fc9a61b --- /dev/null +++ b/thirdparty/boost/iostreams/copy.hpp @@ -0,0 +1,252 @@ +// (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) && (_MSC_VER >= 1020) +# 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 +#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 ); +} + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + +// 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); +} + +#endif // #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //-----------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/absolute_path.hpp b/thirdparty/boost/iostreams/detail/absolute_path.hpp new file mode 100644 index 0000000..9d5729a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/absolute_path.hpp @@ -0,0 +1,46 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) + * + * 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/thirdparty/boost/iostreams/detail/access_control.hpp b/thirdparty/boost/iostreams/detail/access_control.hpp new file mode 100644 index 0000000..a1c53a5 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/access_control.hpp @@ -0,0 +1,87 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/adapter/concept_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/concept_adapter.hpp new file mode 100644 index 0000000..1b21975 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/concept_adapter.hpp @@ -0,0 +1,278 @@ +// (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_CONCEPT_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED + +#include // SFINAE. +#include +#include +#include +#include +#include +#include +#include +#include // pubsync. +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +template struct device_wrapper_impl; +template struct flt_wrapper_impl; + +template +class concept_adapter { +private: + typedef typename detail::value_type::type value_type; + typedef typename dispatch::type input_tag; + typedef typename dispatch::type output_tag; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type input_impl; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type output_impl; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type any_impl; +public: + typedef typename char_type_of::type char_type; + typedef typename category_of::type category; + + explicit concept_adapter(const reference_wrapper& ref) : t_(ref.get()) + { BOOST_STATIC_ASSERT(is_std_io::value); } + explicit concept_adapter(const T& t) : t_(t) + { BOOST_STATIC_ASSERT(!is_std_io::value); } + + T& operator*() { return t_; } + T* operator->() { return &t_; } + + std::streamsize read(char_type* s, std::streamsize n) + { return this->read(s, n, (basic_null_source*) 0); } + + template + std::streamsize read(char_type* s, std::streamsize n, Source* src) + { return input_impl::read(t_, src, s, n); } + + std::streamsize write(const char_type* s, std::streamsize n) + { return this->write(s, n, (basic_null_sink*) 0); } + + template + std::streamsize write(const char_type* s, std::streamsize n, Sink* snk) + { return output_impl::write(t_, snk, s, n); } + + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + return this->seek( off, way, which, + (basic_null_device*) 0); + } + + template + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which, Device* dev ) + { return any_impl::seek(t_, dev, off, way, which); } + + void close(BOOST_IOS::openmode which) + { this->close(which, (basic_null_device*) 0); } + + template + void close(BOOST_IOS::openmode which, Device* dev) + { any_impl::close(t_, dev, which); } + + bool flush( BOOST_IOSTREAMS_BASIC_STREAMBUF(char_type, + BOOST_IOSTREAMS_CHAR_TRAITS(char_type))* sb ) + { + bool result = any_impl::flush(t_, sb); + if (sb && sb->BOOST_IOSTREAMS_PUBSYNC() == -1) + result = false; + return result; + } + + 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: + concept_adapter& operator=(const concept_adapter&); + value_type t_; +}; + +//------------------Specializations of device_wrapper_impl--------------------// + +template<> +struct device_wrapper_impl { + template + static std::streampos + seek( Device& dev, Dummy*, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { + typedef typename category_of::type category; + return seek(dev, off, way, which, category()); + } + + template + static std::streampos + seek( Device&, stream_offset, BOOST_IOS::seekdir, + BOOST_IOS::openmode, any_tag ) + { + throw cant_seek(); + } + + template + static std::streampos + seek( Device& dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access ) + { + return iostreams::seek(dev, off, way, which); + } + + template + static void close(Device& dev, Dummy*, BOOST_IOS::openmode which) + { iostreams::close(dev, which); } + + template + static bool flush(Device& dev, Dummy*) + { return iostreams::flush(dev); } +}; + + +template<> +struct device_wrapper_impl : device_wrapper_impl { + template + static std::streamsize + read( Device& dev, Dummy*, typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::read(dev, s, n); } + + template + static std::streamsize + write( Device&, Dummy*, const typename char_type_of::type*, + std::streamsize ) + { throw cant_write(); } +}; + +template<> +struct device_wrapper_impl { + template + static std::streamsize + read(Device&, Dummy*, typename char_type_of::type*, std::streamsize) + { throw cant_read(); } + + template + static std::streamsize + write( Device& dev, Dummy*, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(dev, s, n); } +}; + +//------------------Specializations of flt_wrapper_impl--------------------// + +template<> +struct flt_wrapper_impl { + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { + typedef typename category_of::type category; + return seek(f, dev, off, way, which, category()); + } + + template + static std::streampos + seek( Filter&, Device*, stream_offset, + BOOST_IOS::seekdir, BOOST_IOS::openmode, any_tag ) + { throw cant_seek(); } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access tag ) + { + typedef typename category_of::type category; + return seek(f, dev, off, way, which, tag, category()); + } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode, + random_access, any_tag ) + { return f.seek(*dev, off, way); } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access, two_sequence ) + { return f.seek(*dev, off, way, which); } + + template + static void close(Filter& f, Device* dev, BOOST_IOS::openmode which) + { iostreams::close(f, *dev, which); } + + template + static bool flush(Filter& f, Device* dev) + { return iostreams::flush(f, *dev); } +}; + +template<> +struct flt_wrapper_impl { + template + static std::streamsize + read( Filter& f, Source* src, typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::read(f, *src, s, n); } + + template + static std::streamsize + write( Filter&, Sink*, const typename char_type_of::type*, + std::streamsize ) + { throw cant_write(); } +}; + +template<> +struct flt_wrapper_impl { + template + static std::streamsize + read(Filter&, Source*, typename char_type_of::type*,std::streamsize) + { throw cant_read(); } + + template + static std::streamsize + write( Filter& f, Sink* snk, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(f, *snk, s, n); } +}; + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/adapter/device_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/device_adapter.hpp new file mode 100644 index 0000000..6e9dffe --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/device_adapter.hpp @@ -0,0 +1,67 @@ +/* + * 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/thirdparty/boost/iostreams/detail/adapter/direct_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/direct_adapter.hpp new file mode 100644 index 0000000..f0b50ab --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/direct_adapter.hpp @@ -0,0 +1,280 @@ +// (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) && (_MSC_VER >= 1020) +# 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 + +// 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 { + 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)) + throw 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) + throw 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 + throw 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 + throw 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/thirdparty/boost/iostreams/detail/adapter/filter_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/filter_adapter.hpp new file mode 100644 index 0000000..1fea16a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/filter_adapter.hpp @@ -0,0 +1,69 @@ +/* + * 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/thirdparty/boost/iostreams/detail/adapter/mode_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/mode_adapter.hpp new file mode 100644 index 0000000..5c7f709 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/mode_adapter.hpp @@ -0,0 +1,123 @@ +// (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_MODE_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// Contains the definition of the class template mode_adapter, which allows +// a filter or device to function as if it has a different i/o mode than that +// deduced by the metafunction mode_of. + +#include // BOOST_MSVC. +#include +#include +#include // openmode, seekdir, int types. +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class mode_adapter { +private: + struct empty_base { }; +public: + typedef typename wrapped_type::type policy_type; + typedef typename char_type_of::type char_type; + struct category + : Mode, + device_tag, + mpl::if_, filter_tag, device_tag>, + mpl::if_, multichar_tag, empty_base>, + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + closable_tag, // VC6 can't see member close()! + #endif + localizable_tag + { }; + explicit mode_adapter(const policy_type& t) : t_(t) { } + + // Device member functions. + + 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 ); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + void close(); + void close(BOOST_IOS::openmode which); +#endif + + // Filter member functions. + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { return iostreams::read(t_, src, s, n); } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { return iostreams::write(t_, snk, s, n); } + + template + std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way) + { return iostreams::seek(t_, dev, off, way); } + + template + std::streampos seek( Device& dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { return iostreams::seek(t_, dev, off, way, which); } + + 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 imbue(const Locale& loc) + { iostreams::imbue(t_, loc); } +private: + policy_type t_; +}; + +//------------------Implementation of mode_adapter----------------------------// + +template +std::streamsize mode_adapter::read + (char_type* s, std::streamsize n) +{ return boost::iostreams::read(t_, s, n); } + +template +std::streamsize mode_adapter::write + (const char_type* s, std::streamsize n) +{ return boost::iostreams::write(t_, s, n); } + +template +std::streampos mode_adapter::seek + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return boost::iostreams::seek(t_, off, way, which); } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + void mode_adapter::close() + { detail::close_all(t_); } + + template + void mode_adapter::close(BOOST_IOS::openmode which) + { iostreams::close(t_, which); } +#endif + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED //-----// diff --git a/thirdparty/boost/iostreams/detail/adapter/non_blocking_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/non_blocking_adapter.hpp new file mode 100644 index 0000000..1e09926 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/non_blocking_adapter.hpp @@ -0,0 +1,59 @@ +// (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_NON_BLOCKING_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED + +#include // streamsize, seekdir, openmode. +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +template +class non_blocking_adapter { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, device_tag + { }; + explicit non_blocking_adapter(Device& dev) : device_(dev) { } + std::streamsize read(char_type* s, std::streamsize n) + { + std::streamsize result = 0; + while (result < n) { + std::streamsize amt = iostreams::read(device_, s, n); + if (amt == -1) + break; + result += amt; + } + return result != 0 ? result : -1; + } + std::streamsize write(const char_type* s, std::streamsize n) + { + std::streamsize result = 0; + while (result < n) { + std::streamsize amt = + iostreams::write(device_, s + result, n - result); + result += amt; + } + return result; + } + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { return iostreams::seek(device_, off, way, which); } +public: + non_blocking_adapter& operator=(const non_blocking_adapter&); + Device& device_; +}; + +} } // End namespace iostreams. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/adapter/output_iterator_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/output_iterator_adapter.hpp new file mode 100644 index 0000000..a2eef37 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/output_iterator_adapter.hpp @@ -0,0 +1,41 @@ +// (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_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // copy. +#include // streamsize. +#include // tags. +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class output_iterator_adapter { +public: + BOOST_STATIC_ASSERT((is_convertible::value)); + typedef Ch char_type; + typedef sink_tag category; + explicit output_iterator_adapter(OutIt out) : out_(out) { } + std::streamsize write(const char_type* s, std::streamsize n) + { + std::copy(s, s + n, out_); + return n; + } +private: + OutIt out_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED //-----// diff --git a/thirdparty/boost/iostreams/detail/adapter/range_adapter.hpp b/thirdparty/boost/iostreams/detail/adapter/range_adapter.hpp new file mode 100644 index 0000000..e010d16 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/adapter/range_adapter.hpp @@ -0,0 +1,183 @@ +// (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_RANGE_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // min. +#include +#include // ptrdiff_t. +#include // streamsize, streamoff. +#include // boost::iterator_traits. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +// Used for simulated tag dispatch. +template struct range_adapter_impl; + +// +// Template name: range_adapter +// Description: Device based on an instance of boost::iterator_range. +// Template paramters: +// Mode - A mode tag. +// Range - An instance of iterator_range. +// +template +class range_adapter { +private: + typedef typename Range::iterator iterator; + typedef boost::detail::iterator_traits iter_traits; + typedef typename iter_traits::iterator_category iter_cat; +public: + typedef typename Range::value_type char_type; + struct category : Mode, device_tag { }; + typedef typename + mpl::if_< + is_convertible< + iter_cat, + std::random_access_iterator_tag + >, + std::random_access_iterator_tag, + std::forward_iterator_tag + >::type tag; + typedef range_adapter_impl impl; + + explicit range_adapter(const Range& rng); + range_adapter(iterator first, iterator last); + 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: + iterator first_, cur_, last_; +}; + +//------------------Implementation of range_adapter---------------------------// + +template +range_adapter::range_adapter(const Range& rng) + : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { } + +template +range_adapter::range_adapter(iterator first, iterator last) + : first_(first), cur_(first), last_(last) { } + +template +inline std::streamsize range_adapter::read + (char_type* s, std::streamsize n) +{ return impl::read(cur_, last_, s, n); } + +template +inline std::streamsize range_adapter::write + (const char_type* s, std::streamsize n) +{ return impl::write(cur_, last_, s, n); } + + +template +std::streampos range_adapter::seek + (stream_offset off, BOOST_IOS::seekdir way) +{ + impl::seek(first_, cur_, last_, off, way); + return offset_to_position(cur_ - first_); +} + +//------------------Implementation of range_adapter_impl----------------------// + +template<> +struct range_adapter_impl { + template + static std::streamsize read + (Iter& cur, Iter& last, Ch* s,std::streamsize n) + { + std::streamsize rem = n; // No. of chars remaining. + while (cur != last && rem-- > 0) *s++ = *cur++; + return n - rem != 0 ? n - rem : -1; + } + + template + static std::streamsize write + (Iter& cur, Iter& last, const Ch* s, std::streamsize n) + { + while (cur != last && n-- > 0) *cur++ = *s++; + if (cur == last && n > 0) + throw write_area_exhausted(); + return n; + } +}; + +template<> +struct range_adapter_impl { + template + static std::streamsize read + (Iter& cur, Iter& last, Ch* s,std::streamsize n) + { + std::streamsize result = + (std::min)(static_cast(last - cur), n); + if (result) + std::copy(cur, cur + result, s); + cur += result; + return result != 0 ? result : -1; + } + + template + static std::streamsize write + (Iter& cur, Iter& last, const Ch* s, std::streamsize n) + { + std::streamsize count = + (std::min)(static_cast(last - cur), n); + std::copy(s, s + count, cur); + cur += count; + if (count < n) + throw write_area_exhausted(); + return n; + } + + template + static void seek + ( Iter& first, Iter& cur, Iter& last, stream_offset off, + BOOST_IOS::seekdir way ) + { + using namespace std; + switch (way) { + case BOOST_IOS::beg: + if (off > last - first || off < 0) throw bad_seek(); + cur = first + off; + break; + case BOOST_IOS::cur: + { + std::ptrdiff_t newoff = cur - first + off; + if (newoff > last - first || newoff < 0) throw bad_seek(); + cur += off; + break; + } + case BOOST_IOS::end: + if (last - first + off < 0 || off > 0) throw bad_seek(); + cur = last + off; + break; + default: + assert(0); + } + } +}; + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------// diff --git a/thirdparty/boost/iostreams/detail/add_facet.hpp b/thirdparty/boost/iostreams/detail/add_facet.hpp new file mode 100644 index 0000000..3a2244e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/add_facet.hpp @@ -0,0 +1,49 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/bool_trait_def.hpp b/thirdparty/boost/iostreams/detail/bool_trait_def.hpp new file mode 100644 index 0000000..a120a19 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/bool_trait_def.hpp @@ -0,0 +1,49 @@ +// (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_BOOL_TRAIT_DEF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED + +#include // BOOST_STATIC_CONSTANT. +#include +#include +#include +#include +#include +#include + +// +// Macro name: BOOST_IOSTREAMS_BOOL_TRAIT_DEF +// Description: Used to generate the traits classes is_istream, is_ostream, +// etc. +// +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) +# define BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) +#else +# define BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) BOOST_PP_CAT(trait, _impl_):: +#endif +#define BOOST_IOSTREAMS_BOOL_TRAIT_DEF(trait, type, arity) \ + namespace BOOST_PP_CAT(trait, _impl_) { \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, T) \ + type_traits::yes_type helper \ + (const volatile type BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)*); \ + type_traits::no_type helper(...); \ + template \ + struct impl { \ + BOOST_STATIC_CONSTANT(bool, value = \ + (sizeof(BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) \ + helper(static_cast(0))) == \ + sizeof(type_traits::yes_type))); \ + }; \ + } \ + template \ + struct trait \ + : mpl::bool_::value> \ + { BOOST_MPL_AUX_LAMBDA_SUPPORT(1, trait, (T)) }; \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/broken_overload_resolution/forward.hpp b/thirdparty/boost/iostreams/detail/broken_overload_resolution/forward.hpp new file mode 100644 index 0000000..f97267e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/broken_overload_resolution/forward.hpp @@ -0,0 +1,31 @@ +// (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_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED + +#include // BOOST_STATIC_CONSANT. +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct forward_impl { + BOOST_STATIC_CONSTANT(bool, value = + ( !is_same< U, Device >::value && + !is_same< U, reference_wrapper >::value )); +}; + +template +struct forward + : mpl::bool_::value> + { }; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream.hpp b/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream.hpp new file mode 100644 index 0000000..8daf05b --- /dev/null +++ b/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream.hpp @@ -0,0 +1,185 @@ +// (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_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED + +#include + +namespace boost { namespace iostreams { + +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +struct stream : detail::stream_base { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, + closable_tag, + detail::stream_traits::stream_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename + detail::stream_traits< + Device, Tr + >::stream_type stream_type; + typedef Device policy_type; +public: + stream() { } + template + stream(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + stream(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + bool is_open() const { return this->member.is_open(); } + void close() { this->member.close(); } + bool auto_close() const { return this->member.auto_close(); } + void set_auto_close(bool close) { this->member.set_auto_close(close); } + bool strict_sync() { return this->member.strict_sync(); } + Device& operator*() { return *this->member; } + Device* operator->() { return &*this->member; } +private: + template + void open_impl(mpl::false_, const U0& u0) + { + this->clear(); + this->member.open(u0); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::false_, U0& u0) + { + this->clear(); + this->member.open(detail::wrap(u0)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::true_, const U0& u0) + { + this->clear(); + this->member.open(Device(const_cast(u0))); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0) + { + this->clear(); + this->member.open(Device(u0)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1) + { + this->clear(); + this->member.open(u0, u1); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1) + { + this->clear(); + this->member.open(Device(const_cast(u0), u1)); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1) + { + this->clear(); + this->member.open(Device(u0, u1)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(u0, u1, u2); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(Device(const_cast(u0), u1, u2)); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(Device(u0, u1, u2)); + } +#endif +}; + +} } // End namespaces iostreams, boost. + +#endif BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp b/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp new file mode 100644 index 0000000..78404d1 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp @@ -0,0 +1,189 @@ +// (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_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED + +#include + +namespace boost { namespace iostreams { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Mode = BOOST_DEDUCED_TYPENAME mode_of::type > +class stream_buffer + : public detail::stream_buffer_traits::type +{ +private: + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, Mode + >::value + )); + typedef typename + detail::stream_buffer_traits< + T, Tr, Alloc, Mode + >::type base_type; + typedef T policy_type; +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + closable_tag, + streambuf_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) + stream_buffer() { } + ~stream_buffer() + { + try { + if (this->is_open() && this->auto_close()) + this->close(); + } catch (...) { } + } + template + stream_buffer(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream_buffer(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream_buffer(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + stream_buffer(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream_buffer(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream_buffer(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + T& operator*() { return *this->component(); } + T* operator->() { return this->component(); } +private: + template + void open_impl(mpl::false_, const U0& u0) + { + base_type::open(const_cast(u0), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::false_, U0& u0) + { + base_type::open(detail::wrap(u0), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::true_, const U0& u0) + { + base_type::open(T(const_cast(u0)), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0) + { + base_type::open(T(u0), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1) + { + base_type::open(u0, u1, -1); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1) + { + base_type::open(T(const_cast(u0), u1), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1) + { + base_type::open(T(u0, u1), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2) + { + base_type::open(u0, u1, u2); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2) + { + base_type::open(T(const_cast(u0), u1, u2), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2) + { + base_type::open(T(u0, u1, u2), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + void check_open() + { + if (this->is_open()) + throw BOOST_IOSTREAMS_FAILURE("already open"); + } +}; + +} } // End namespaces iostreams, boost. + +#endif // BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/buffer.hpp b/thirdparty/boost/iostreams/detail/buffer.hpp new file mode 100644 index 0000000..c67e440 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/buffer.hpp @@ -0,0 +1,200 @@ +// (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_BUFFERS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // swap. +#include // allocator. +#include // member templates. +#include +#include // streamsize. +#include +#include // int_type_of. +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +//----------------Buffers-----------------------------------------------------// + +// +// Template name: buffer +// Description: Character buffer. +// Template paramters: +// Ch - The character type. +// Alloc - The Allocator type. +// +template< typename Ch, + typename Alloc = std::allocator > +class basic_buffer { +private: +#ifndef BOOST_NO_STD_ALLOCATOR + typedef typename Alloc::template rebind::other allocator_type; +#else + typedef std::allocator allocator_type; +#endif +public: + basic_buffer(); + basic_buffer(int buffer_size); + ~basic_buffer(); + void resize(int buffer_size); + Ch* begin() const { return buf_; } + Ch* end() const { return buf_ + size_; } + Ch* data() const { return buf_; } + std::streamsize size() const { return size_; } + void swap(basic_buffer& rhs); +private: + // Disallow copying and assignment. + basic_buffer(const basic_buffer&); + basic_buffer& operator=(const basic_buffer&); + Ch* buf_; + std::streamsize size_; +}; + +template +void swap(basic_buffer& lhs, basic_buffer& rhs) +{ lhs.swap(rhs); } + +// +// Template name: buffer +// Description: Character buffer with two pointers accessible via ptr() and +// eptr(). +// Template paramters: +// Ch - A character type. +// +template< typename Ch, + typename Alloc = std::allocator > +class buffer : public basic_buffer { +private: + typedef basic_buffer base; +public: + typedef iostreams::char_traits traits_type; + using base::resize; + using base::data; + using base::size; + typedef Ch* const const_pointer; + buffer(int buffer_size); + Ch* & ptr() { return ptr_; } + const_pointer& ptr() const { return ptr_; } + Ch* & eptr() { return eptr_; } + const_pointer& eptr() const { return eptr_; } + void set(std::streamsize ptr, std::streamsize end); + void swap(buffer& rhs); + + // Returns an int_type as a status code. + template + typename int_type_of::type fill(Source& src) + { + using namespace std; + std::streamsize keep; + if ((keep = static_cast(eptr_ - ptr_)) > 0) + traits_type::move(this->data(), ptr_, keep); + set(0, keep); + std::streamsize result = + iostreams::read(src, this->data() + keep, this->size() - keep); + if (result != -1) + this->set(0, keep + result); + //return result == this->size() - keep ? + // traits_type::good() : + // keep == -1 ? + // traits_type::eof() : + // traits_type::would_block(); + return result == -1 ? + traits_type::eof() : + result == 0 ? + traits_type::would_block() : + traits_type::good(); + + } + + // Returns true if one or more characters were written. + template + bool flush(Sink& dest) + { + using namespace std; + std::streamsize amt = static_cast(eptr_ - ptr_); + std::streamsize result = iostreams::write_if(dest, ptr_, amt); + if (result < amt) { + traits_type::move( this->data(), + ptr_ + result, + amt - result ); + } + this->set(0, amt - result); + return result != 0; + } +private: + Ch *ptr_, *eptr_; +}; + +template +void swap(buffer& lhs, buffer& rhs) +{ lhs.swap(rhs); } + +//--------------Implementation of basic_buffer--------------------------------// + +template +basic_buffer::basic_buffer() : buf_(0), size_(0) { } + +template +basic_buffer::basic_buffer(int buffer_size) + : buf_(static_cast(allocator_type().allocate(buffer_size, 0))), + size_(buffer_size) // Cast for SunPro 5.3. + { } + +template +inline basic_buffer::~basic_buffer() +{ if (buf_) allocator_type().deallocate(buf_, size_); } + +template +inline void basic_buffer::resize(int buffer_size) +{ + if (size_ != buffer_size) { + basic_buffer temp(buffer_size); + std::swap(size_, temp.size_); + std::swap(buf_, temp.buf_); + } +} + +template +void basic_buffer::swap(basic_buffer& rhs) +{ + std::swap(buf_, rhs.buf_); + std::swap(size_, rhs.size_); +} + +//--------------Implementation of buffer--------------------------------------// + +template +buffer::buffer(int buffer_size) + : basic_buffer(buffer_size) { } + +template +inline void buffer::set(std::streamsize ptr, std::streamsize end) +{ + ptr_ = data() + ptr; + eptr_ = data() + end; +} + +template +inline void buffer::swap(buffer& rhs) +{ + base::swap(rhs); + std::swap(ptr_, rhs.ptr_); + std::swap(eptr_, rhs.eptr_); +} + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/call_traits.hpp b/thirdparty/boost/iostreams/detail/call_traits.hpp new file mode 100644 index 0000000..3a6b1ff --- /dev/null +++ b/thirdparty/boost/iostreams/detail/call_traits.hpp @@ -0,0 +1,32 @@ +// (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_VALUE_TYPE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct param_type { + typedef typename mpl::if_, T&, const T&>::type type; +}; + +template +struct value_type { + typedef typename mpl::if_, T&, T>::type type; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED //-----------// diff --git a/thirdparty/boost/iostreams/detail/char_traits.hpp b/thirdparty/boost/iostreams/detail/char_traits.hpp new file mode 100644 index 0000000..734599e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/char_traits.hpp @@ -0,0 +1,63 @@ +// (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.) + +// Provides std::char_traits for libraries without templated streams. Should not +// be confused with , which defines the +// template boost::iostreams::char_traits. + +// See http://www.boost.org/libs/iostreams for documentation. + +#ifndef BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include // Make sure size_t is in std. +# include +# include +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// +# define BOOST_IOSTREAMS_CHAR_TRAITS(ch) std::char_traits< ch > +#else +# define BOOST_IOSTREAMS_CHAR_TRAITS(ch) boost::iostreams::detail::char_traits + +namespace boost { namespace iostreams { namespace detail { + +struct char_traits { + typedef char char_type; + typedef int int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + + // Note: this may not be not conforming, since it treats chars as unsigned, + // but is only used to test for equality. + static int compare(const char* lhs, const char* rhs, std::size_t n) + { return std::strncmp(lhs, rhs, n); } + static char* copy(char *dest, const char *src, std::size_t n) + { return static_cast(std::memcpy(dest, src, n)); } + static char* move(char *dest, const char *src, std::size_t n) + { return static_cast(std::memmove(dest, src, n)); } + static const char* find(const char* s, std::size_t n, const char& c) + { return (const char*) (const void*) std::memchr(s, c, n); } + static char to_char_type(const int& c) { return c; } + static int to_int_type(const char& c) { return c; } + static bool eq_int_type(const int& lhs, const int& rhs) + { return lhs == rhs; } + static int eof() { return EOF; } + static int not_eof(const int& c) { return c != EOF ? c : '\n'; } +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/codecvt_helper.hpp b/thirdparty/boost/iostreams/detail/codecvt_helper.hpp new file mode 100644 index 0000000..b363543 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/codecvt_helper.hpp @@ -0,0 +1,238 @@ +// (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) && (_MSC_VER >= 1020) +# 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& state, Extern* first2, Extern* last2, + Extern*& next2 ) 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& 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) \ + /**/ +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# 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) \ + namespace std { \ + template<> \ + class codecvt \ + : public ::boost::iostreams::detail::codecvt_impl< \ + wchar_t, char, state \ + > \ + { \ + public: \ + codecvt(std::size_t refs = 0) \ + : ::boost::iostreams::detail::codecvt_impl< \ + wchar_t, char, state \ + >(refs) \ + { } \ + static std::locale::id id; \ + }; \ + template<> \ + std::locale::id codecvt::id; \ + } \ + /**/ +# endif +#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/thirdparty/boost/iostreams/detail/codecvt_holder.hpp b/thirdparty/boost/iostreams/detail/codecvt_holder.hpp new file mode 100644 index 0000000..a0b730a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/codecvt_holder.hpp @@ -0,0 +1,63 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/config/auto_link.hpp b/thirdparty/boost/iostreams/detail/config/auto_link.hpp new file mode 100644 index 0000000..6806e82 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/auto_link.hpp @@ -0,0 +1,49 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(BOOST_EXTERNAL_LIB_NAME) +# if defined(BOOST_MSVC) \ + || defined(__BORLANDC__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + /**/ +# pragma comment(lib, BOOST_EXTERNAL_LIB_NAME) +# endif +# undef BOOST_EXTERNAL_LIB_NAME +#endif + +//------------------Enable automatic library variant selection----------------// + +#if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_iostreams + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +#endif // auto-linking disabled + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/bzip2.hpp b/thirdparty/boost/iostreams/detail/config/bzip2.hpp new file mode 100644 index 0000000..9fc8548 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/bzip2.hpp @@ -0,0 +1,48 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(BOOST_BZIP2_BINARY) +# if defined(BOOST_MSVC) || \ + defined(__BORLANDC__) || \ + (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + /**/ + +// Specify the name of the .lib file. +# pragma comment(lib, BOOST_STRINGIZE(BOOST_BZIP2_BINARY)) +# endif +#else +# if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_bzip2 + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/codecvt.hpp b/thirdparty/boost/iostreams/detail/config/codecvt.hpp new file mode 100644 index 0000000..7bb1307 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/codecvt.hpp @@ -0,0 +1,80 @@ +// (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_CONFIG_CODECVT_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED + +#include +#include +#include +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +//------------------Support for codecvt with user-defined state types---------// + +#if defined(__MSL_CPP__) || defined(__LIBCOMO__) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \ + /**/ +# define BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION +#endif + +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, > 0x450) \ + /**/ +# define BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION +#endif + +//------------------Check for codecvt ctor taking a reference count-----------// + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, < 0x461) \ + /**/ +# define BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T +#endif + +//------------------Normalize codecvt::length---------------------------------// + +#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) && \ + (!defined(BOOST_RWSTD_VER) || BOOST_RWSTD_VER < 0x04010300) && \ + (!defined(__MACH__) || !defined(__INTEL_COMPILER)) + /**/ +# define BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER const +#else +# define BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER +#endif + +//------------------Check for codecvt::max_length-----------------------------// + +#if BOOST_WORKAROUND(_STLPORT_VERSION, < 0x461) +# define BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH +#endif + +//------------------Put mbstate_t and codecvt in std--------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +# include +#endif + +// From Robert Ramey's version of utf8_codecvt_facet. +namespace std { + +#if defined(__LIBCOMO__) + using ::mbstate_t; +#elif defined(BOOST_DINKUMWARE_STDLIB) && !defined(__BORLANDC__) + using ::mbstate_t; +#elif defined(__SGI_STL_PORT) +#elif defined(BOOST_NO_STDC_NAMESPACE) + using ::codecvt; + using ::mbstate_t; +#endif + +} // End namespace std. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/disable_warnings.hpp b/thirdparty/boost/iostreams/detail/config/disable_warnings.hpp new file mode 100644 index 0000000..3241e27 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/disable_warnings.hpp @@ -0,0 +1,27 @@ +// (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. + +#include // BOOST_MSVC. +#include // BOOST_WORKAROUND. + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4127) // Conditional expression is constant. +# pragma warning(disable:4130) // Logical operation on address of string constant. +# pragma warning(disable:4224) // Parameter previously defined as type. +# pragma warning(disable:4244) // Conversion: possible loss of data. +# pragma warning(disable:4512) // Assignment operator could not be generated. +# pragma warning(disable:4706) // Assignment within conditional expression. +#else +# if BOOST_WORKAROUND(__BORLANDC__, < 0x600) +# pragma warn -8008 // Condition always true/false. +# pragma warn -8066 // Unreachable code. +# pragma warn -8071 // Conversion may lose significant digits. +# pragma warn -8072 // Suspicious pointer arithmetic. +# pragma warn -8080 // identifier declared but never used. +# endif +#endif diff --git a/thirdparty/boost/iostreams/detail/config/dyn_link.hpp b/thirdparty/boost/iostreams/detail/config/dyn_link.hpp new file mode 100644 index 0000000..d41b64f --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/dyn_link.hpp @@ -0,0 +1,37 @@ +// (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. + +// Adapted from http://www.boost.org/more/separate_compilation.html, by +// John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +//------------------Enable dynamic linking on windows-------------------------// + +#ifdef BOOST_HAS_DECLSPEC +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# ifdef BOOST_IOSTREAMS_SOURCE +# define BOOST_IOSTREAMS_DECL __declspec(dllexport) +# else +# define BOOST_IOSTREAMS_DECL __declspec(dllimport) +# endif +# endif +#endif + +#ifndef BOOST_IOSTREAMS_DECL +# define BOOST_IOSTREAMS_DECL +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/enable_warnings.hpp b/thirdparty/boost/iostreams/detail/config/enable_warnings.hpp new file mode 100644 index 0000000..3e039df --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/enable_warnings.hpp @@ -0,0 +1,18 @@ +// (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. + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#else +# if BOOST_WORKAROUND(__BORLANDC__, < 0x600) +# pragma warn .8008 // Condition always true/false. +# pragma warn .8066 // Unreachable code. +# pragma warn .8071 // Conversion may lose significant digits. +# pragma warn .8072 // Suspicious pointer arithmetic. +# pragma warn .8080 // identifier declared but never used. +# endif +#endif diff --git a/thirdparty/boost/iostreams/detail/config/fpos.hpp b/thirdparty/boost/iostreams/detail/config/fpos.hpp new file mode 100644 index 0000000..0bb4f52 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/fpos.hpp @@ -0,0 +1,31 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(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 preprocessor symbol BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS for + * platforms that use the implementation of std::fpos from the Dinkumware + * Standard Library. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +# if (defined(_YVALS) || defined(_CPPLIB_VER)) && !defined(__SGI_STL_PORT) && \ + !defined(_STLPORT_VERSION) && !defined(__QNX__) + /**/ +# define BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS +# endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/gcc.hpp b/thirdparty/boost/iostreams/detail/config/gcc.hpp new file mode 100644 index 0000000..4eab94c --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/gcc.hpp @@ -0,0 +1,24 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_INTEL. + +#if defined(__GNUC__) && !defined(BOOST_INTEL) +# define BOOST_IOSTREAMS_GCC (__GNUC__ * 100 + __GNUC_MINOR__) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/limits.hpp b/thirdparty/boost/iostreams/detail/config/limits.hpp new file mode 100644 index 0000000..3f8c3cd --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/limits.hpp @@ -0,0 +1,19 @@ +// (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_CONFIG_LIMITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED + +#ifndef BOOST_IOSTREAMS_MAX_FORWARDING_ARITY +# define BOOST_IOSTREAMS_MAX_FORWARDING_ARITY 3 +#endif + +#ifndef BOOST_IOSTREAMS_MAX_EXECUTE_ARITY +# define BOOST_IOSTREAMS_MAX_EXECUTE_ARITY 5 +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/overload_resolution.hpp b/thirdparty/boost/iostreams/detail/config/overload_resolution.hpp new file mode 100644 index 0000000..f16fa7a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/overload_resolution.hpp @@ -0,0 +1,32 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include + +#if !defined(BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION) +# if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) || \ + BOOST_WORKAROUND(__BORLANDC__, < 0x600) || \ + BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || \ + BOOST_WORKAROUND(BOOST_IOSTREAMS_GCC, <= 295) \ + /**/ +# define BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/rtl.hpp b/thirdparty/boost/iostreams/detail/config/rtl.hpp new file mode 100644 index 0000000..e5fd7f4 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/rtl.hpp @@ -0,0 +1,68 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) + * + * See http://www.boost.org/libs/iostreams for documentation. + * + * Defines preprocessor symbols expanding to the names of functions in the + * C runtime library used to access file descriptors and to the type used + * to store file offsets for seeking. + * + * File: boost/iostreams/detail/config/rtl.hpp + * Date: Wed Dec 26 11:58:11 MST 2007 + * + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED + +#include +#include + +// Handle open, close, read, and write +#ifdef __BORLANDC__ +# define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_rtl_, x) +#elif defined BOOST_IOSTREAMS_WINDOWS +# define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_, x) +#else +# define BOOST_IOSTREAMS_RTL(x) ::x // Distinguish from member function named x +#endif +#define BOOST_IOSTREAMS_FD_OPEN BOOST_IOSTREAMS_RTL(open) +#define BOOST_IOSTREAMS_FD_CLOSE BOOST_IOSTREAMS_RTL(close) +#define BOOST_IOSTREAMS_FD_READ BOOST_IOSTREAMS_RTL(read) +#define BOOST_IOSTREAMS_FD_WRITE BOOST_IOSTREAMS_RTL(write) + +// Handle lseek, off_t, ftruncate, and stat +#ifdef BOOST_IOSTREAMS_WINDOWS +# if defined(BOOST_MSVC) || defined(__MSVCRT__) // MSVC, MinGW +# define BOOST_IOSTREAMS_FD_SEEK _lseeki64 +# define BOOST_IOSTREAMS_FD_OFFSET __int64 +# else // Borland, Metrowerks, ... +# define BOOST_IOSTREAMS_FD_SEEK lseek +# define BOOST_IOSTREAMS_FD_OFFSET long +# endif +#else // Non-windows +# if defined(_LARGEFILE64_SOURCE) && \ + (!defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64) || \ + defined(_AIX) && !defined(_LARGE_FILES) || \ + defined(BOOST_IOSTREAMS_HAS_LARGE_FILE_EXTENSIONS) + /**/ + + /* Systems with transitional extensions for large file support */ + +# define BOOST_IOSTREAMS_FD_SEEK lseek64 +# define BOOST_IOSTREAMS_FD_TRUNCATE ftruncate64 +# define BOOST_IOSTREAMS_FD_STAT stat64 +# define BOOST_IOSTREAMS_FD_OFFSET off64_t +# else +# define BOOST_IOSTREAMS_FD_SEEK lseek +# define BOOST_IOSTREAMS_FD_TRUNCATE ftruncate +# define BOOST_IOSTREAMS_FD_STAT stat +# define BOOST_IOSTREAMS_FD_OFFSET off_t +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/wide_streams.hpp b/thirdparty/boost/iostreams/detail/config/wide_streams.hpp new file mode 100644 index 0000000..274590b --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/wide_streams.hpp @@ -0,0 +1,55 @@ +// (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. + +// Adapted from http://www.boost.org/more/separate_compilation.html, by +// John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED + +#include +#include +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +//------------------Templated stream support----------------------------------// + +// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for cray patch. +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# if defined(__STL_CONFIG_H) && \ + !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \ + /**/ +# define BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + +//------------------Wide stream support---------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +# if defined(BOOST_IOSTREAMS_NO_STREAM_TEMPLATES) || \ + defined (BOOST_NO_STD_WSTREAMBUF) && \ + ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \ + /**/ +# define BOOST_IOSTREAMS_NO_WIDE_STREAMS +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS + +//------------------Locale support--------------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +# if defined(BOOST_NO_STD_LOCALE) || \ + defined(__CYGWIN__) && \ + ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \ + /**/ +# define BOOST_IOSTREAMS_NO_LOCALE +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_LOCALE + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/windows_posix.hpp b/thirdparty/boost/iostreams/detail/config/windows_posix.hpp new file mode 100644 index 0000000..8873339 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/windows_posix.hpp @@ -0,0 +1,25 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-2007 Jonathan Turkanis +// (C) Copyright 2002, 2003 Beman Dawes Boost.Filesystem +// Distributed under the Boost Software License, Version 1.0. (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_CONFIG_WINDOWS_POSIX_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED + +//------------------From boost/libs/filesystem/src/path_posix_windows.cpp-----// + +// BOOST_IOSTREAMS_POSIX or BOOST_IOSTREAMS_WINDOWS specify which API to use. +#if !defined( BOOST_IOSTREAMS_WINDOWS ) && !defined( BOOST_IOSTREAMS_POSIX ) +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \ + !defined(__CYGWIN__) \ + /**/ +# define BOOST_IOSTREAMS_WINDOWS +# else +# define BOOST_IOSTREAMS_POSIX +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/config/zlib.hpp b/thirdparty/boost/iostreams/detail/config/zlib.hpp new file mode 100644 index 0000000..db8ba6e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/config/zlib.hpp @@ -0,0 +1,50 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_STRINGIZE. + +#if defined(BOOST_ZLIB_BINARY) +# if defined(BOOST_MSVC) || \ + defined(__BORLANDC__) || \ + (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + /**/ + +// Specify the name of the .lib file. +# pragma comment(lib, BOOST_STRINGIZE(BOOST_ZLIB_BINARY)) +# endif +#else +# if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_zlib + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/counted_array.hpp b/thirdparty/boost/iostreams/detail/counted_array.hpp new file mode 100644 index 0000000..a2c5ba1 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/counted_array.hpp @@ -0,0 +1,64 @@ +// (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 +#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) + { + std::streamsize result = (std::min)(n, end_ - ptr_); + BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy + (s, buf_ + ptr_, 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) + { + std::streamsize result = (std::min)(n, end_ - ptr_); + BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy + (buf_ + ptr_, s, 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/thirdparty/boost/iostreams/detail/current_directory.hpp b/thirdparty/boost/iostreams/detail/current_directory.hpp new file mode 100644 index 0000000..930b7ed --- /dev/null +++ b/thirdparty/boost/iostreams/detail/current_directory.hpp @@ -0,0 +1,60 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(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 + +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. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/default_arg.hpp b/thirdparty/boost/iostreams/detail/default_arg.hpp new file mode 100644 index 0000000..0d09a68 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/default_arg.hpp @@ -0,0 +1,25 @@ +// (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_DEFAULT_ARG_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +# include +# define BOOST_IOSTREAMS_DEFAULT_ARG(arg) mpl::identity< arg >::type +#else +# define BOOST_IOSTREAMS_DEFAULT_ARG(arg) arg +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/dispatch.hpp b/thirdparty/boost/iostreams/detail/dispatch.hpp new file mode 100644 index 0000000..1ececca --- /dev/null +++ b/thirdparty/boost/iostreams/detail/dispatch.hpp @@ -0,0 +1,41 @@ +// (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_DISPATCH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_DEDUCED_TYPENAME. +#include +#include // category_of. +#include +#include + +namespace boost { namespace iostreams {namespace detail { + +template< typename T, typename Tag1, typename Tag2, + typename Tag3 = mpl::void_, typename Tag4 = mpl::void_, + typename Tag5 = mpl::void_, typename Tag6 = mpl::void_, + typename Category = + BOOST_DEDUCED_TYPENAME category_of::type > +struct dispatch + : iostreams::select< // Disambiguation for Tru64. + is_convertible, Tag1, + is_convertible, Tag2, + is_convertible, Tag3, + is_convertible, Tag4, + is_convertible, Tag5, + is_convertible, Tag6 + > + { }; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/double_object.hpp b/thirdparty/boost/iostreams/detail/double_object.hpp new file mode 100644 index 0000000..6c96803 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/double_object.hpp @@ -0,0 +1,114 @@ +// (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. + +// Contains the definition of the class template +// boost::iostreams::detail::double_object, which is similar to compressed pair +// except that both members of the pair have the same type, and +// compression occurs only if requested using a boolean template +// parameter. + +#ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // swap. +#include +#include +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) +# include +#else +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +template +class single_object_holder { +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + single_object_holder() { } + single_object_holder(param_type t) : first_(t) { } + reference first() { return first_; } + const_reference first() const { return first_; } + reference second() { return first_; } + const_reference second() const { return first_; } + void swap(single_object_holder& o) + { std::swap(first_, o.first_); } +private: + T first_; +}; + +template +struct double_object_holder { +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + double_object_holder() { } + double_object_holder(param_type t1, param_type t2) + : first_(t1), second_(t2) { } + reference first() { return first_; } + const_reference first() const { return first_; } + reference second() { return second_; } + const_reference second() const { return second_; } + void swap(double_object_holder& d) + { + std::swap(first_, d.first_); + std::swap(second_, d.second_); + } +private: + T first_, second_; +}; + +template +class double_object + : public mpl::if_< + IsDouble, + double_object_holder, + single_object_holder + >::type +{ +private: + typedef typename + mpl::if_< + IsDouble, + double_object_holder, + single_object_holder + >::type base_type; +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + double_object() : base_type() {} + double_object(param_type t1, param_type t2) + : base_type(t1, t2) { } + bool is_double() const { return IsDouble::value; } +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/enable_if_stream.hpp b/thirdparty/boost/iostreams/detail/enable_if_stream.hpp new file mode 100644 index 0000000..5f0076e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/enable_if_stream.hpp @@ -0,0 +1,32 @@ +// (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_ENABLE_IF_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_NO_SFINAE. +#include +#include // is_std_io. + +#if !defined(BOOST_NO_SFINAE) && \ + !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) +# define BOOST_IOSTREAMS_ENABLE_IF_STREAM(T) \ + , typename boost::enable_if< boost::iostreams::is_std_io >::type* = 0 \ + /**/ +# define BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) \ + , typename boost::disable_if< boost::iostreams::is_std_io >::type* = 0 \ + /**/ +#else +# define BOOST_IOSTREAMS_ENABLE_IF_STREAM(T) +# define BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/error.hpp b/thirdparty/boost/iostreams/detail/error.hpp new file mode 100644 index 0000000..d5b9a3b --- /dev/null +++ b/thirdparty/boost/iostreams/detail/error.hpp @@ -0,0 +1,45 @@ +// (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_ERROR_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // failure. + +namespace boost { namespace iostreams { namespace detail { + +inline BOOST_IOSTREAMS_FAILURE cant_read() +{ return BOOST_IOSTREAMS_FAILURE("no read access"); } + +inline BOOST_IOSTREAMS_FAILURE cant_write() +{ return BOOST_IOSTREAMS_FAILURE("no write access"); } + +inline BOOST_IOSTREAMS_FAILURE cant_seek() +{ return BOOST_IOSTREAMS_FAILURE("no random access"); } + +inline BOOST_IOSTREAMS_FAILURE bad_read() +{ return BOOST_IOSTREAMS_FAILURE("bad read"); } + +inline BOOST_IOSTREAMS_FAILURE bad_putback() +{ return BOOST_IOSTREAMS_FAILURE("putback buffer full"); } + +inline BOOST_IOSTREAMS_FAILURE bad_write() +{ return BOOST_IOSTREAMS_FAILURE("bad write"); } + +inline BOOST_IOSTREAMS_FAILURE write_area_exhausted() +{ return BOOST_IOSTREAMS_FAILURE("write area exhausted"); } + +inline BOOST_IOSTREAMS_FAILURE bad_seek() +{ return BOOST_IOSTREAMS_FAILURE("bad seek"); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/execute.hpp b/thirdparty/boost/iostreams/detail/execute.hpp new file mode 100644 index 0000000..8e7f166 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/execute.hpp @@ -0,0 +1,135 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(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 overloaded function template + * boost::iostreams::detail::execute_all() and the function template + * boost::iostreams::detail::execute_foreach(). + * + * execute_all() invokes a primary operation and performs a sequence of cleanup + * operations, returning the result of the primary operation if no exceptions + * are thrown. If one of the operations throws an exception, performs the + * remaining operations and rethrows the initial exception. + * + * execute_foreach() is a variant of std::foreach which invokes a function + * object for each item in a sequence, catching all execptions and rethrowing + * the first caught exception after the function object has been invoked on each + * item. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include // MAX_EXECUTE_ARITY +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +// Helper for class template execute_traits. +template +struct execute_traits_impl { + typedef Result result_type; + template + static Result execute(Op op) { return op(); } +}; + +// Specialization for void return. For simplicity, execute() returns int +// for operations returning void. This could be avoided with additional work. +template<> +struct execute_traits_impl { + typedef int result_type; + template + static int execute(Op op) { op(); return 0; } +}; + +// Deduces the result type of Op and allows uniform treatment of operations +// returning void and non-void. +template< typename Op, + typename Result = // VC6.5 workaround. + #if !defined(BOOST_NO_RESULT_OF) && \ + !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) + typename boost::result_of::type + #else + BOOST_DEDUCED_TYPENAME Op::result_type + #endif + > +struct execute_traits + : execute_traits_impl + { }; + +// Implementation with no cleanup operations. +template +typename execute_traits::result_type +execute_all(Op op) +{ + return execute_traits::execute(op); +} + +// Implementation with one or more cleanup operations +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + typename execute_traits::result_type \ + execute_all(Op op, BOOST_PP_ENUM_BINARY_PARAMS(n, C, c)) \ + { \ + typename execute_traits::result_type r; \ + try { \ + r = boost::iostreams::detail::execute_all( \ + op BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(n), c) \ + ); \ + } catch (...) { \ + try { \ + BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ + } catch (...) { } \ + throw; \ + } \ + BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ + return r; \ + } \ + /**/ + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_MAX_EXECUTE_ARITY) +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO + +template +Op execute_foreach(InIt first, InIt last, Op op) +{ + if (first == last) + return op; + try { + op(*first); + } catch (...) { + try { + ++first; + boost::iostreams::detail::execute_foreach(first, last, op); + } catch (...) { } + throw; + } + ++first; + return boost::iostreams::detail::execute_foreach(first, last, op); +} + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/forward.hpp b/thirdparty/boost/iostreams/detail/forward.hpp new file mode 100644 index 0000000..6feb5cc --- /dev/null +++ b/thirdparty/boost/iostreams/detail/forward.hpp @@ -0,0 +1,102 @@ +// (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_FORWARD_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------Macros for defining forwarding constructors and open overloads--------// + +// +// Macro: BOOST_IOSTREAMS_DEFINE_FORWARDING_FUNCTIONS(mode, name, helper). +// Description: Defines constructors and overloads of 'open' which construct +// a device using the given argument list and pass it to 'open_impl'. +// Assumes that 'policy_type' is an alias for the device type. +// Not supported on Intel 7.1 and VC6.5. +// +#define BOOST_IOSTREAMS_FORWARD(class, impl, policy, params, args) \ + class(const policy& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + class(policy& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + class(const ::boost::reference_wrapper& ref params()) \ + { this->impl(ref args()); } \ + void open(const policy& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + void open(policy& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + void open(const ::boost::reference_wrapper& ref params()) \ + { this->impl(ref args()); } \ + BOOST_PP_REPEAT_FROM_TO( \ + 1, BOOST_PP_INC(BOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \ + BOOST_IOSTREAMS_FORWARDING_CTOR, (class, impl, policy) \ + ) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1, BOOST_PP_INC(BOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \ + BOOST_IOSTREAMS_FORWARDING_FN, (class, impl, policy) \ + ) \ + /**/ +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) +# define BOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple) \ + template< typename U100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), typename U) > \ + BOOST_PP_TUPLE_ELEM(3, 0, tuple) \ + ( U100& u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_DEC(n), const U, &u)) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + ( u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), u)) ); } \ + /**/ +# define BOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) \ + template< typename U100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), typename U) > \ + void open \ + ( U100& u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_DEC(n), const U, &u)) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), u) ); } \ + /**/ +#else +# define BOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple) +# define BOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) +#endif +#define BOOST_IOSTREAMS_FORWARDING_CTOR(z, n, tuple) \ + template \ + BOOST_PP_TUPLE_ELEM(3, 0, tuple) \ + (BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u)) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + (BOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \ + BOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple) \ + /**/ +#define BOOST_IOSTREAMS_FORWARDING_FN(z, n, tuple) \ + template \ + void open(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u)) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + (BOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \ + BOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/fstream.hpp b/thirdparty/boost/iostreams/detail/fstream.hpp new file mode 100644 index 0000000..f2ef8c1 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/fstream.hpp @@ -0,0 +1,33 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/functional.hpp b/thirdparty/boost/iostreams/detail/functional.hpp new file mode 100644 index 0000000..cec322a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/functional.hpp @@ -0,0 +1,189 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) + * + * See http://www.boost.org/libs/iostreams for documentation. + + * File: boost/iostreams/detail/functional.hpp + * Date: Sun Dec 09 05:38:03 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + + * Defines several function objects and object generators for use with + * execute_all() + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // BOOST_IOS + +namespace boost { namespace iostreams { namespace detail { + + // Function objects and object generators for invoking + // boost::iostreams::close + +template +class device_close_operation { +public: + typedef void result_type; + device_close_operation(T& t, BOOST_IOS::openmode which) + : t_(t), which_(which) + { } + void operator()() const { boost::iostreams::close(t_, which_); } +private: + device_close_operation& operator=(const device_close_operation&); + T& t_; + BOOST_IOS::openmode which_; +}; + +template +class filter_close_operation { +public: + typedef void result_type; + filter_close_operation(T& t, Sink& snk, BOOST_IOS::openmode which) + : t_(t), snk_(snk), which_(which) + { } + void operator()() const { boost::iostreams::close(t_, snk_, which_); } +private: + filter_close_operation& operator=(const filter_close_operation&); + T& t_; + Sink& snk_; + BOOST_IOS::openmode which_; +}; + +template +device_close_operation +call_close(T& t, BOOST_IOS::openmode which) +{ return device_close_operation(t, which); } + +template +filter_close_operation +call_close(T& t, Sink& snk, BOOST_IOS::openmode which) +{ return filter_close_operation(t, snk, which); } + + // Function objects and object generators for invoking + // boost::iostreams::detail::close_all + +template +class device_close_all_operation { +public: + typedef void result_type; + device_close_all_operation(T& t) : t_(t) { } + void operator()() const { detail::close_all(t_); } +private: + device_close_all_operation& operator=(const device_close_all_operation&); + T& t_; +}; + +template +class filter_close_all_operation { +public: + typedef void result_type; + filter_close_all_operation(T& t, Sink& snk) : t_(t), snk_(snk) { } + void operator()() const { detail::close_all(t_, snk_); } +private: + filter_close_all_operation& operator=(const filter_close_all_operation&); + T& t_; + Sink& snk_; +}; + +template +device_close_all_operation call_close_all(T& t) +{ return device_close_all_operation(t); } + +template +filter_close_all_operation +call_close_all(T& t, Sink& snk) +{ return filter_close_all_operation(t, snk); } + + // Function object and object generator for invoking a + // member function void close(std::ios_base::openmode) + +template +class member_close_operation { +public: + typedef void result_type; + member_close_operation(T& t, BOOST_IOS::openmode which) + : t_(t), which_(which) + { } + void operator()() const { t_.close(which_); } +private: + member_close_operation& operator=(const member_close_operation&); + T& t_; + BOOST_IOS::openmode which_; +}; + +template +member_close_operation call_member_close(T& t, BOOST_IOS::openmode which) +{ return member_close_operation(t, which); } + + // Function object and object generator for invoking a + // member function void reset() + +template +class reset_operation { +public: + reset_operation(T& t) : t_(t) { } + void operator()() const { t_.reset(); } +private: + reset_operation& operator=(const reset_operation&); + T& t_; +}; + +template +reset_operation call_reset(T& t) { return reset_operation(t); } + + // Function object and object generator for clearing a flag + +template +class clear_flags_operation { +public: + typedef void result_type; + clear_flags_operation(T& t) : t_(t) { } + void operator()() const { t_ = 0; } +private: + clear_flags_operation& operator=(const clear_flags_operation&); + T& t_; +}; + +template +clear_flags_operation clear_flags(T& t) +{ return clear_flags_operation(t); } + + // Function object and generator for flushing a buffer + +// Function object for use with execute_all() +template +class flush_buffer_operation { +public: + typedef void result_type; + flush_buffer_operation(Buffer& buf, Device& dev, bool flush) + : buf_(buf), dev_(dev), flush_(flush) + { } + void operator()() const + { + if (flush_) + buf_.flush(dev_); + } +private: + flush_buffer_operation& operator=(const flush_buffer_operation&); + Buffer& buf_; + Device& dev_; + bool flush_; +}; + +template +flush_buffer_operation +flush_buffer(Buffer& buf, Device& dev, bool flush) +{ return flush_buffer_operation(buf, dev, flush); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/ios.hpp b/thirdparty/boost/iostreams/detail/ios.hpp new file mode 100644 index 0000000..cde8c97 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/ios.hpp @@ -0,0 +1,66 @@ +// (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_IOS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +# include +# else +# include +# include +# endif +#else +# include +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// +# define BOOST_IOSTREAMS_BASIC_IOS(ch, tr) std::basic_ios< ch, tr > +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) && \ + !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ + /**/ + +#define BOOST_IOS std::ios +#define BOOST_IOSTREAMS_FAILURE std::ios::failure + +# else + +#define BOOST_IOS std::ios_base +#define BOOST_IOSTREAMS_FAILURE std::ios_base::failure + +# endif +#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +#define BOOST_IOS std::ios +#define BOOST_IOSTREAMS_BASIC_IOS(ch, tr) std::ios +#define BOOST_IOSTREAMS_FAILURE boost::iostreams::detail::failure + +class failure : std::exception { +public: + explicit failure(const std::string& what_arg) : what_(what_arg) { } + const char* what() const { return what_.c_str(); } +private: + std::string what_; +}; + +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------// + +} } } // End namespace failure, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/iostream.hpp b/thirdparty/boost/iostreams/detail/iostream.hpp new file mode 100644 index 0000000..3679868 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/iostream.hpp @@ -0,0 +1,34 @@ +// (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_IOSTREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include +# include +#else +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::basic_istream< ch, tr > +# define BOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::basic_ostream< ch, tr > +# define BOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::basic_iostream< ch, tr > +#else +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf +# define BOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::istream +# define BOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::ostream +# define BOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::iostream +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/is_dereferenceable.hpp b/thirdparty/boost/iostreams/detail/is_dereferenceable.hpp new file mode 100644 index 0000000..84ee19b --- /dev/null +++ b/thirdparty/boost/iostreams/detail/is_dereferenceable.hpp @@ -0,0 +1,85 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-2007 Jonathan Turkanis +// (C) Copyright David Abrahams 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/iostreams for documentation. + +#ifndef BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace iostreams { namespace detail { + +// is_dereferenceable metafunction +// +// Requires: Given x of type T&, if the expression *x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_dereferenceable_ +{ + // a type returned from operator* when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator* less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator* for when none other is found + tag operator*(any const&); + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ + || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + + // two check overloads help us identify which operator++ was picked + char (& check(tag) )[2]; + + template + char check(T const&); + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_dereferenceable_::check(BOOST_comma(*x,0))) == 1 + ); + }; +} + +# undef BOOST_comma + +template +struct is_dereferenceable + BOOST_TT_AUX_BOOL_C_BASE(is_dereferenceable_::impl::value) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(is_dereferenceable_::impl::value) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_dereferenceable,(T)) +}; + +} } + +BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::iostreams::detail::is_dereferenceable) + +} // End namespaces detail, iostreams, boost. + +#endif // BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/is_iterator_range.hpp b/thirdparty/boost/iostreams/detail/is_iterator_range.hpp new file mode 100644 index 0000000..66e47f4 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/is_iterator_range.hpp @@ -0,0 +1,42 @@ +// (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_IS_ITERATOR_RANGE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED + +#include + +namespace boost { + +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + +// We avoid dependence on Boost.Range by using a forward declaration. +template +class iterator_range; + +namespace iostreams { + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iterator_range, boost::iterator_range, 1) + +} // End namespace iostreams. + +# else // # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //-----------------------// + +namespace iostreams { + + template + struct is_iterator_range { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + +} // End namespace iostreams. + +# endif // # if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) //----------------------// + +} // End namespace boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/newline.hpp b/thirdparty/boost/iostreams/detail/newline.hpp new file mode 100644 index 0000000..c7f39b1 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/newline.hpp @@ -0,0 +1,32 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/optional.hpp b/thirdparty/boost/iostreams/detail/optional.hpp new file mode 100644 index 0000000..144f790 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/optional.hpp @@ -0,0 +1,114 @@ +// (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. + +// Recent changes to Boost.Optional involving assigment broke Boost.Iostreams, +// in a way which could be remedied only by relying on the deprecated reset +// functions; with VC6, even reset didn't work. Until this problem is +// understood, Iostreams will use a private version of optional with a smart +// pointer interface. + +#ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +// Taken from . +template +class aligned_storage +{ + // Borland ICEs if unnamed unions are used for this! + union dummy_u + { + char data[ sizeof(T) ]; + BOOST_DEDUCED_TYPENAME type_with_alignment< + ::boost::alignment_of::value >::type aligner_; + } dummy_ ; + + public: + + void const* address() const { return &dummy_.data[0]; } + void * address() { return &dummy_.data[0]; } +}; + +template +class optional { +public: + typedef T element_type; + optional() : initialized_(false) { } + optional(const T& t) : initialized_(false) { reset(t); } + ~optional() { reset(); } + T& operator*() + { + assert(initialized_); + return *static_cast(address()); + } + const T& operator*() const + { + assert(initialized_); + return *static_cast(address()); + } + T* operator->() + { + assert(initialized_); + return static_cast(address()); + } + const T* operator->() const + { + assert(initialized_); + return static_cast(address()); + } + T* get() + { + assert(initialized_); + return static_cast(address()); + } + const T* get() const + { + assert(initialized_); + return static_cast(address()); + } + void reset() + { + if (initialized_) { + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ + /**/ + T* t = static_cast(address()); + t->~T(); + #else + static_cast(address())->T::~T(); + #endif + initialized_ = false; + } + } + void reset(const T& t) + { + reset(); + new (address()) T(t); + initialized_ = true; + } +private: + optional(const optional&); + optional& operator=(const optional&); + void* address() { return &storage_; } + const void* address() const { return &storage_; } + aligned_storage storage_; + bool initialized_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/param_type.hpp b/thirdparty/boost/iostreams/detail/param_type.hpp new file mode 100644 index 0000000..7f85916 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/param_type.hpp @@ -0,0 +1,27 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/push.hpp b/thirdparty/boost/iostreams/detail/push.hpp new file mode 100644 index 0000000..390e104 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/push.hpp @@ -0,0 +1,154 @@ +// (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_PUSH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Macro: BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper). +// Description: Defines overloads with name 'name' which forward to a function +// 'helper' which takes a filter or devide by const reference. +// +#define BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper) \ + BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 0, ?) \ + /**/ + +// +// Macro: BOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper). +// Description: Defines constructors which forward to a function +// 'helper' which takes a filter or device by const reference. +// +#define BOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper) \ + BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 1, void) \ + /**/ + +//--------------------Definition of BOOST_IOSTREAMS_DEFINE_PUSH_IMPL----------// + +#define BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, arg, helper, has_return) \ + this->helper( ::boost::iostreams::detail::resolve(arg) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); \ + /**/ + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \ + !BOOST_WORKAROUND(__BORLANDC__, < 0x600) \ + /**/ +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_streambuf& sb BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_istream& is BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_ostream& os BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_iostream& io BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const iterator_range& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_PP_EXPR_IF(has_return, return) \ + this->helper( ::boost::iostreams::detail::range_adapter< \ + mode, iterator_range \ + >(rng) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const ::boost::iostreams::pipeline& p) \ + { p.push(*this); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS() BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + /**/ +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::streambuf& sb BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::istream& is BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::ostream& os BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::iostream& io BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const iterator_range& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_PP_EXPR_IF(has_return, return) \ + this->helper( ::boost::iostreams::detail::range_adapter< \ + mode, iterator_range \ + >(rng) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const ::boost::iostreams::pipeline& p) \ + { p.push(*this); } \ + template \ + BOOST_PP_EXPR_IF(has_return, result) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS() BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + /**/ +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +#else // #if VC6, VC7.0, Borland 5.x +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + template \ + void BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::mpl::true_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \ + { t.push(*this); } \ + template \ + void BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::mpl::false_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { \ + this->BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::iostreams::detail::is_pipeline(), \ + t BOOST_IOSTREAMS_PUSH_ARGS() ); \ + } \ + /**/ +#endif // #if VC6, VC7.0, Borland 5.x + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/push_params.hpp b/thirdparty/boost/iostreams/detail/push_params.hpp new file mode 100644 index 0000000..1f2e41e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/push_params.hpp @@ -0,0 +1,21 @@ +// (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_PUSH_PARAMS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#define BOOST_IOSTREAMS_PUSH_PARAMS() \ + , int buffer_size = -1 , int pback_size = -1 \ + /**/ + +#define BOOST_IOSTREAMS_PUSH_ARGS() , buffer_size, pback_size + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/resolve.hpp b/thirdparty/boost/iostreams/detail/resolve.hpp new file mode 100644 index 0000000..26763a7 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/resolve.hpp @@ -0,0 +1,234 @@ +// (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_RESOLVE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // partial spec, put size_t in std. +#include // std::size_t. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // true_. +#include +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# include +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +#include + +// Must come last. +#include // VC7.1 C4224. + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of resolve-------------------------------------// + +#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------// + +template +struct resolve_traits { + typedef typename + mpl::if_< + boost::detail::is_incrementable, + output_iterator_adapter, + const T& + >::type type; +}; + +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// + +template +typename resolve_traits::type +resolve( const T& t + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) + + // I suspect that the compilers which require this workaround may + // be correct, but I'm not sure why :( + #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) ||\ + BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) || \ + BOOST_WORKAROUND(BOOST_IOSTREAMS_GCC, BOOST_TESTED_AT(400)) \ + /**/ + , typename disable_if< is_iterator_range >::type* = 0 + #endif + ) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +mode_adapter< Mode, std::basic_streambuf > +resolve(std::basic_streambuf& sb) +{ return mode_adapter< Mode, std::basic_streambuf >(wrap(sb)); } + +template +mode_adapter< Mode, std::basic_istream > +resolve(std::basic_istream& is) +{ return mode_adapter< Mode, std::basic_istream >(wrap(is)); } + +template +mode_adapter< Mode, std::basic_ostream > +resolve(std::basic_ostream& os) +{ return mode_adapter< Mode, std::basic_ostream >(wrap(os)); } + +template +mode_adapter< Mode, std::basic_iostream > +resolve(std::basic_iostream& io) +{ return mode_adapter< Mode, std::basic_iostream >(wrap(io)); } + +template +array_adapter resolve(Ch (&array)[N]) +{ return array_adapter(array); } + +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + template + range_adapter< Mode, boost::iterator_range > + resolve(const boost::iterator_range& rng) + { return range_adapter< Mode, boost::iterator_range >(rng); } +# endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// + +template +typename resolve_traits::type +resolve( const T& t + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) + #if defined(__GNUC__) + , typename disable_if< is_iterator_range >::type* = 0 + #endif + ) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +mode_adapter +resolve(std::streambuf& sb) +{ return mode_adapter(wrap(sb)); } + +template +mode_adapter +resolve(std::istream& is) +{ return mode_adapter(wrap(is)); } + +template +mode_adapter +resolve(std::ostream& os) +{ return mode_adapter(wrap(os)); } + +template +mode_adapter +resolve(std::iostream& io) +{ return mode_adapter(wrap(io)); } + +template +array_adapter resolve(Ch (&array)[N]) +{ return array_adapter(array); } + +template +range_adapter< Mode, boost::iterator_range > +resolve(const boost::iterator_range& rng) +{ return range_adapter< Mode, boost::iterator_range >(rng); } + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// +#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------// + +template +struct resolve_traits { + // Note: test for is_iterator_range must come before test for output + // iterator. + typedef typename + iostreams::select< // Disambiguation for Tru64. + is_std_io, + mode_adapter, + is_iterator_range, + range_adapter, + is_dereferenceable, + output_iterator_adapter, + is_array, + array_adapter, + else_, + #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) + const T& + #else + T + #endif + >::type type; +}; + +template +typename resolve_traits::type +resolve(const T& t, mpl::true_) +{ // Bad overload resolution. + typedef typename resolve_traits::type return_type; + return return_type(wrap(const_cast(t))); +} + +template +typename resolve_traits::type +resolve(const T& t, mpl::false_) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +typename resolve_traits::type +resolve(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) +{ return resolve(t, is_std_io()); } + +# if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \ + !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \ + !defined(__GNUC__) // ---------------------------------------------------// + +template +typename resolve_traits::type +resolve(T& t, mpl::true_) +{ + typedef typename resolve_traits::type return_type; + return return_type(wrap(t)); +} + +template +typename resolve_traits::type +resolve(T& t, mpl::false_) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +typename resolve_traits::type +resolve(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) +{ return resolve(t, is_std_io()); } + +# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------// +#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // VC7.1 4224. + +#endif // BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/restrict_impl.hpp b/thirdparty/boost/iostreams/detail/restrict_impl.hpp new file mode 100644 index 0000000..0b7332a --- /dev/null +++ b/thirdparty/boost/iostreams/detail/restrict_impl.hpp @@ -0,0 +1,474 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(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 + +namespace boost { namespace iostreams { + +namespace detail { + +// +// Template name: restricted_indirect_device. +// Description: Provides an restricted view of an indirect Device. +// Template paramters: +// 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 paramters: +// 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 paramters: +// 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_) + 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_) + bad_seek(); + return offset_to_position(pos_ - beg_); + } + if (next < beg_ || end_ != -1 && next >= end_) + 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) + throw 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_) + 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_) + bad_seek(); + return offset_to_position(pos_ - beg_); + } + if (next < beg_ || end_ != -1 && next >= end_) + 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 ) + { + throw 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) + throw 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(__BORLANDC__, < 0x600) && \ + !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \ + !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, VC6-7.0 or GCC 2.9x //-------------------------------// +# endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------// + +} } // End namespaces iostreams, boost. + +#endif // #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ... diff --git a/thirdparty/boost/iostreams/detail/select.hpp b/thirdparty/boost/iostreams/detail/select.hpp new file mode 100644 index 0000000..556531e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/select.hpp @@ -0,0 +1,86 @@ +// (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 metafunction select, which mimics the effect of a chain of +// nested mpl if_'s. +// +// ----------------------------------------------------------------------------- +// +// Usage: +// +// typedef typename select< +// case1, type1, +// case2, type2, +// ... +// true_, typen +// >::type selection; +// +// Here case1, case2, ... are models of MPL::IntegralConstant with value type +// bool, and n <= 12. + +#ifndef BOOST_IOSTREAMS_SELECT_HPP_INCLUDED +#define BOOST_IOSTREAMS_SELECT_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +typedef mpl::true_ else_; + +template< typename Case1 = mpl::true_, + typename Type1 = mpl::void_, + typename Case2 = mpl::true_, + typename Type2 = mpl::void_, + typename Case3 = mpl::true_, + typename Type3 = mpl::void_, + typename Case4 = mpl::true_, + typename Type4 = mpl::void_, + typename Case5 = mpl::true_, + typename Type5 = mpl::void_, + typename Case6 = mpl::true_, + typename Type6 = mpl::void_, + typename Case7 = mpl::true_, + typename Type7 = mpl::void_, + typename Case8 = mpl::true_, + typename Type8 = mpl::void_, + typename Case9 = mpl::true_, + typename Type9 = mpl::void_, + typename Case10 = mpl::true_, + typename Type10 = mpl::void_, + typename Case11 = mpl::true_, + typename Type11 = mpl::void_, + typename Case12 = mpl::true_, + typename Type12 = mpl::void_ > +struct select { + typedef typename + mpl::eval_if< + Case1, mpl::identity, mpl::eval_if< + Case2, mpl::identity, mpl::eval_if< + Case3, mpl::identity, mpl::eval_if< + Case4, mpl::identity, mpl::eval_if< + Case5, mpl::identity, mpl::eval_if< + Case6, mpl::identity, mpl::eval_if< + Case7, mpl::identity, mpl::eval_if< + Case8, mpl::identity, mpl::eval_if< + Case9, mpl::identity, mpl::eval_if< + Case10, mpl::identity, mpl::eval_if< + Case11, mpl::identity, mpl::if_< + Case12, Type12, mpl::void_ > > > > > > > > > > > + >::type type; +}; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_SELECT_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/select_by_size.hpp b/thirdparty/boost/iostreams/detail/select_by_size.hpp new file mode 100644 index 0000000..2d0cf06 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/select_by_size.hpp @@ -0,0 +1,160 @@ +// (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. + +// +// Intended as an alternative to type_traits::yes_type and type_traits::no_type. +// Provides an arbitrary number of types (case_<0>, case_<1>, ...) for +// determining the results of overload resultion using 'sizeof', plus a uniform +// means of using the result. yes_type and no_type are typedefs for case_<1> +// and case_<0>. A single case with negative argument, case_<-1>, is also +// provided, for convenience. +// +// This header may be included any number of times, with +// BOOST_SELECT_BY_SIZE_MAX_CASE defined to be the largest N such that case_ +// is needed for a particular application. It defaults to 20. +// +// This header depends only on Boost.Config and Boost.Preprocessor. Dependence +// on Type Traits or MPL was intentionally avoided, to leave open the +// possibility that select_by_size could be used by these libraries. +// +// Example usage: +// +// #define BOOST_SELECT_BY_SIZE_MAX_CASE 7 // (Needed when default was 2) +// #include +// +// using namespace boost::utility; +// +// case_<0> helper(bool); +// case_<1> helper(int); +// case_<2> helper(unsigned); +// case_<3> helper(long); +// case_<4> helper(unsigned long); +// case_<5> helper(float); +// case_<6> helper(double); +// case_<7> helper(const char*); +// +// struct test { +// static const int value = +// select_by_size< sizeof(helper(9876UL)) >::value; +// BOOST_STATIC_ASSERT(value == 4); +// }; +// +// For compilers with integral constant expression problems, e.g. Borland 5.x, +// one can also write +// +// struct test { +// BOOST_SELECT_BY_SIZE(int, value, helper(9876UL)); +// }; +// +// to define a static integral constant 'value' equal to +// +// select_by_size< sizeof(helper(9876UL)) >::value. +// + +// Include guards surround all contents of this header except for explicit +// specializations of select_by_size for case_ with N > 2. + +#ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED + +// The lowest N for which select_by_size< sizeof(case_) > has not been +// specialized. +#define SELECT_BY_SIZE_MAX_SPECIALIZED 20 + +#include // BOOST_STATIC_CONSTANT. +#include +#include + +/* Alternative implementation using max_align. + +#include +#include + +namespace boost { namespace utility { + +template +struct case_ { char c[(N + 1) * alignment_of::value]; }; + +template +struct select_by_size { + BOOST_STATIC_CONSTANT(int, value = + (Size / alignment_of::value - 1)); +}; + +} } // End namespaces utility, boost. + +*/ // End alternate implementation. + +namespace boost { namespace iostreams { namespace detail { + +//--------------Definition of case_-------------------------------------------// + +template struct case_ { char c1; case_ c2; }; +template<> struct case_<-1> { char c; }; +typedef case_ yes_type; +typedef case_ no_type; + +//--------------Declaration of select_by_size---------------------------------// + +template struct select_by_size; + +} } } // End namespaces detail, iostreams, boost. + +//--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------// + +// Sepecializes select_by_size for sizeof(case). The decrement is used +// here because the preprocessor library doesn't handle negative integers. +#define SELECT_BY_SIZE_SPEC(n) \ + namespace boost { namespace iostreams { namespace detail { \ + static const int BOOST_PP_CAT(sizeof_case_, n) = sizeof(case_); \ + template<> \ + struct select_by_size< BOOST_PP_CAT(sizeof_case_, n) > { \ + struct type { BOOST_STATIC_CONSTANT(int, value = n - 1); }; \ + BOOST_STATIC_CONSTANT(int, value = type::value); \ + }; \ + } } } \ + /**/ + +//--------------Default specializations of select_by_size---------------------// + +#define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n) +#define BOOST_PP_LOCAL_LIMITS (0, 20) +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO + +//--------------Definition of SELECT_BY_SIZE----------------------------------// + +#define BOOST_SELECT_BY_SIZE(type_, name, expr) \ + BOOST_STATIC_CONSTANT( \ + unsigned, \ + BOOST_PP_CAT(boost_select_by_size_temp_, name) = sizeof(expr) \ + ); \ + BOOST_STATIC_CONSTANT( \ + type_, \ + name = \ + ( ::boost::iostreams::detail::select_by_size< \ + BOOST_PP_CAT(boost_select_by_size_temp_, name) \ + >::value ) \ + ) \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED + +//----------Specializations of SELECT_BY_SIZE (outside main inclued guards)---// + +#if BOOST_SELECT_BY_SIZE_MAX_CASE > SELECT_BY_SIZE_MAX_SPECIALIZED + +#define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n) +#define BOOST_PP_LOCAL_LIMITS \ + (SELECT_BY_SIZE_MAX_SPECIALIZED, BOOST_SELECT_BY_SIZE_MAX_CASE) \ + /**/ +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO +#undef SELECT_BY_SIZE_MAX_SPECIALIZED +#define SELECT_BY_SIZE_MAX_SPECIALIZED BOOST_SELECT_BY_SIZE_MAX_CASE + +#endif diff --git a/thirdparty/boost/iostreams/detail/streambuf.hpp b/thirdparty/boost/iostreams/detail/streambuf.hpp new file mode 100644 index 0000000..53d811c --- /dev/null +++ b/thirdparty/boost/iostreams/detail/streambuf.hpp @@ -0,0 +1,34 @@ +// (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_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include +#else +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::basic_streambuf< ch, tr > +# define BOOST_IOSTREAMS_PUBSYNC pubsync +# define BOOST_IOSTREAMS_PUBSEEKOFF pubseekoff +# define BOOST_IOSTREAMS_PUBSEEKPOS pubseekpos +#else +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf +# define BOOST_IOSTREAMS_PUBSYNC sync +# define BOOST_IOSTREAMS_PUBSEEKOFF seekoff +# define BOOST_IOSTREAMS_PUBSEEKPOS seekpos +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/streambuf/chainbuf.hpp b/thirdparty/boost/iostreams/detail/streambuf/chainbuf.hpp new file mode 100644 index 0000000..82ad4bd --- /dev/null +++ b/thirdparty/boost/iostreams/detail/streambuf/chainbuf.hpp @@ -0,0 +1,116 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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; +//#if !BOOST_WORKAROUND(__GNUC__, == 2) +// BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type) +//#endif +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/thirdparty/boost/iostreams/detail/streambuf/direct_streambuf.hpp b/thirdparty/boost/iostreams/detail/streambuf/direct_streambuf.hpp new file mode 100644 index 0000000..0c257cf --- /dev/null +++ b/thirdparty/boost/iostreams/detail/streambuf/direct_streambuf.hpp @@ -0,0 +1,306 @@ +// (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_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include // pair. +#include // BOOST_DEDUCED_TYPENAME, +#include // member template friends. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +namespace detail { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ) > +class direct_streambuf + : public linked_streambuf::type, Tr> +{ +public: + typedef typename char_type_of::type char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef linked_streambuf base_type; + typedef typename category_of::type category; + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF( + char_type, traits_type + ) streambuf_type; +public: // stream needs access. + void open(const T& t, int buffer_size, int pback_size); + bool is_open() const; + void close(); + bool auto_close() const { return auto_close_; } + void set_auto_close(bool close) { auto_close_ = close; } + bool strict_sync() { return true; } + + // Declared in linked_streambuf. + T* component() { return storage_.get(); } +protected: +#if !BOOST_WORKAROUND(__GNUC__, == 2) + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type) +#endif + direct_streambuf(); + + //--------------Virtual functions-----------------------------------------// + + // Declared in linked_streambuf. + void close_impl(BOOST_IOS::openmode m); + const std::type_info& component_type() const { return typeid(T); } + void* component_impl() { return component(); } +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + public: +#endif + + // Declared in basic_streambuf. + int_type underflow(); + int_type pbackfail(int_type c); + int_type overflow(int_type c); + pos_type seekoff( off_type off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + pos_type seekpos(pos_type sp, BOOST_IOS::openmode which); +private: + pos_type seek_impl( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + void init_input(any_tag) { } + void init_input(input); + void init_output(any_tag) { } + void init_output(output); + void init_get_area(); + void init_put_area(); + bool one_head() const; + bool two_head() const; + optional storage_; + char_type *ibeg_, *iend_, *obeg_, *oend_; + bool auto_close_; +}; + +//------------------Implementation of direct_streambuf------------------------// + +template +direct_streambuf::direct_streambuf() + : ibeg_(0), iend_(0), obeg_(0), oend_(0), auto_close_(true) +{ this->set_true_eof(true); } + +template +void direct_streambuf::open(const T& t, int, int) +{ + storage_.reset(t); + init_input(category()); + init_output(category()); + setg(0, 0, 0); + setp(0, 0); +} + +template +bool direct_streambuf::is_open() const +{ return ibeg_ != 0 || obeg_ != 0; } + +template +void direct_streambuf::close() +{ + base_type* self = this; + detail::execute_all( detail::call_member_close(*self, BOOST_IOS::in), + detail::call_member_close(*self, BOOST_IOS::out), + detail::call_reset(storage_) ); +} + +template +typename direct_streambuf::int_type +direct_streambuf::underflow() +{ + if (!ibeg_) + throw cant_read(); + if (!gptr()) + init_get_area(); + return gptr() != iend_ ? + traits_type::to_int_type(*gptr()) : + traits_type::eof(); +} + +template +typename direct_streambuf::int_type +direct_streambuf::pbackfail(int_type c) +{ + using namespace std; + if (!ibeg_) + throw cant_read(); + if (gptr() != 0 && gptr() != ibeg_) { + gbump(-1); + if (!traits_type::eq_int_type(c, traits_type::eof())) + *gptr() = traits_type::to_char_type(c); + return traits_type::not_eof(c); + } + throw bad_putback(); +} + +template +typename direct_streambuf::int_type +direct_streambuf::overflow(int_type c) +{ + using namespace std; + if (!obeg_) throw BOOST_IOSTREAMS_FAILURE("no write access"); + if (!pptr()) init_put_area(); + if (!traits_type::eq_int_type(c, traits_type::eof())) { + if (pptr() == oend_) + throw BOOST_IOSTREAMS_FAILURE("write area exhausted"); + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + return traits_type::not_eof(c); +} + +template +inline typename direct_streambuf::pos_type +direct_streambuf::seekoff + (off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return seek_impl(off, way, which); } + +template +inline typename direct_streambuf::pos_type +direct_streambuf::seekpos + (pos_type sp, BOOST_IOS::openmode which) +{ + return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); +} + +template +void direct_streambuf::close_impl(BOOST_IOS::openmode which) +{ + if (which == BOOST_IOS::in && ibeg_ != 0) { + setg(0, 0, 0); + ibeg_ = iend_ = 0; + } + if (which == BOOST_IOS::out && obeg_ != 0) { + sync(); + setp(0, 0); + obeg_ = oend_ = 0; + } + boost::iostreams::close(*storage_, which); +} + +template +typename direct_streambuf::pos_type direct_streambuf::seek_impl + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ + using namespace std; + BOOST_IOS::openmode both = BOOST_IOS::in | BOOST_IOS::out; + if (two_head() && (which & both) == both) + throw bad_seek(); + stream_offset result = -1; + bool one = one_head(); + if (one && (pptr() != 0 || gptr()== 0)) + init_get_area(); // Switch to input mode, for code reuse. + if (one || (which & BOOST_IOS::in) != 0 && ibeg_ != 0) { + if (!gptr()) setg(ibeg_, ibeg_, iend_); + ptrdiff_t next = 0; + switch (way) { + case BOOST_IOS::beg: next = off; break; + case BOOST_IOS::cur: next = (gptr() - ibeg_) + off; break; + case BOOST_IOS::end: next = (iend_ - ibeg_) + off; break; + default: assert(0); + } + if (next < 0 || next > (iend_ - ibeg_)) + throw bad_seek(); + setg(ibeg_, ibeg_ + next, iend_); + result = next; + } + if (!one && (which & BOOST_IOS::out) != 0 && obeg_ != 0) { + if (!pptr()) setp(obeg_, oend_); + ptrdiff_t next = 0; + switch (way) { + case BOOST_IOS::beg: next = off; break; + case BOOST_IOS::cur: next = (pptr() - obeg_) + off; break; + case BOOST_IOS::end: next = (oend_ - obeg_) + off; break; + default: assert(0); + } + if (next < 0 || next > (oend_ - obeg_)) + throw bad_seek(); + pbump(static_cast(next - (pptr() - obeg_))); + result = next; + } + return offset_to_position(result); +} + +template +void direct_streambuf::init_input(input) +{ + std::pair p = input_sequence(*storage_); + ibeg_ = p.first; + iend_ = p.second; +} + +template +void direct_streambuf::init_output(output) +{ + std::pair p = output_sequence(*storage_); + obeg_ = p.first; + oend_ = p.second; +} + +template +void direct_streambuf::init_get_area() +{ + setg(ibeg_, ibeg_, iend_); + if (one_head() && pptr()) { + gbump(static_cast(pptr() - obeg_)); + setp(0, 0); + } +} + +template +void direct_streambuf::init_put_area() +{ + setp(obeg_, oend_); + if (one_head() && gptr()) { + pbump(static_cast(gptr() - ibeg_)); + setg(0, 0, 0); + } +} + +template +inline bool direct_streambuf::one_head() const +{ return ibeg_ && obeg_ && ibeg_ == obeg_; } + +template +inline bool direct_streambuf::two_head() const +{ return ibeg_ && obeg_ && ibeg_ != obeg_; } + +//----------------------------------------------------------------------------// + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include // MSVC + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/streambuf/indirect_streambuf.hpp b/thirdparty/boost/iostreams/detail/streambuf/indirect_streambuf.hpp new file mode 100644 index 0000000..23b590e --- /dev/null +++ b/thirdparty/boost/iostreams/detail/streambuf/indirect_streambuf.hpp @@ -0,0 +1,430 @@ +// (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. + +// This material is heavily indebted to the discussion and code samples in +// A. Langer and K. Kreft, "Standard C++ IOStreams and Locales", +// Addison-Wesley, 2000, pp. 228-43. + +// User "GMSB" provided an optimization for small seeks. + +#ifndef BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED + +#include // min, max. +#include +#include +#include +#include // Member template friends. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC, BCC 5.x + +namespace boost { namespace iostreams { namespace detail { + +// +// Description: The implementation of basic_streambuf used by chains. +// +template +class indirect_streambuf + : public linked_streambuf::type, Tr> +{ +public: + typedef typename char_type_of::type char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename category_of::type category; + typedef concept_adapter wrapper; + typedef detail::basic_buffer buffer_type; + typedef indirect_streambuf my_type; + typedef detail::linked_streambuf base_type; + typedef linked_streambuf streambuf_type; +public: + indirect_streambuf(); + + void open(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()); + bool is_open() const; + void close(); + bool auto_close() const; + void set_auto_close(bool close); + bool strict_sync(); + + // Declared in linked_streambuf. + T* component() { return &*obj(); } +protected: +#if !BOOST_WORKAROUND(__GNUC__, == 2) + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type) +#endif + + //----------virtual functions---------------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE + void imbue(const std::locale& loc); +#endif +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + public: +#endif + int_type underflow(); + int_type pbackfail(int_type c); + int_type overflow(int_type c); + int sync(); + pos_type seekoff( off_type off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + pos_type seekpos(pos_type sp, BOOST_IOS::openmode which); + + // Declared in linked_streambuf. + void set_next(streambuf_type* next); + void close_impl(BOOST_IOS::openmode m); + const std::type_info& component_type() const { return typeid(T); } + void* component_impl() { return component(); } +private: + + //----------Accessor functions--------------------------------------------// + + wrapper& obj() { return *storage_; } + streambuf_type* next() const { return next_; } + buffer_type& in() { return buffer_.first(); } + buffer_type& out() { return buffer_.second(); } + bool can_read() const { return is_convertible::value; } + bool can_write() const { return is_convertible::value; } + bool output_buffered() const { return (flags_ & f_output_buffered) != 0; } + bool shared_buffer() const { return is_convertible::value; } + void set_flags(int f) { flags_ = f; } + + //----------State changing functions--------------------------------------// + + virtual void init_get_area(); + virtual void init_put_area(); + + //----------Utility function----------------------------------------------// + + pos_type seek_impl( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + void sync_impl(); + + enum flag_type { + f_open = 1, + f_output_buffered = f_open << 1, + f_auto_close = f_output_buffered << 1 + }; + + optional storage_; + streambuf_type* next_; + double_object< + buffer_type, + is_convertible< + Mode, + two_sequence + > + > buffer_; + std::streamsize pback_size_; + int flags_; +}; + +//--------------Implementation of indirect_streambuf--------------------------// + +template +indirect_streambuf::indirect_streambuf() + : next_(0), pback_size_(0), flags_(f_auto_close) { } + +//--------------Implementation of open, is_open and close---------------------// + +template +void indirect_streambuf::open + (const T& t, int buffer_size, int pback_size) +{ + using namespace std; + + // Normalize buffer sizes. + buffer_size = + (buffer_size != -1) ? + buffer_size : + iostreams::optimal_buffer_size(t); + pback_size = + (pback_size != -1) ? + pback_size : + default_pback_buffer_size; + + // Construct input buffer. + if (can_read()) { + pback_size_ = (std::max)(2, pback_size); // STLPort needs 2. + std::streamsize size = + pback_size_ + + ( buffer_size ? buffer_size: 1 ); + in().resize(size); + if (!shared_buffer()) + init_get_area(); + } + + // Construct output buffer. + if (can_write() && !shared_buffer()) { + if (buffer_size != 0) + out().resize(buffer_size); + init_put_area(); + } + + storage_.reset(wrapper(t)); + flags_ |= f_open; + if (can_write() && buffer_size > 1) + flags_ |= f_output_buffered; + this->set_true_eof(false); +} + +template +inline bool indirect_streambuf::is_open() const +{ return (flags_ & f_open) != 0; } + +template +void indirect_streambuf::close() +{ + using namespace std; + base_type* self = this; + detail::execute_all( + detail::call_member_close(*self, BOOST_IOS::in), + detail::call_member_close(*self, BOOST_IOS::out), + detail::call_reset(storage_), + detail::clear_flags(flags_) + ); +} + +template +bool indirect_streambuf::auto_close() const +{ return (flags_ & f_auto_close) != 0; } + +template +void indirect_streambuf::set_auto_close(bool close) +{ flags_ = (flags_ & ~f_auto_close) | (close ? f_auto_close : 0); } + +//--------------Implementation virtual functions------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +template +void indirect_streambuf::imbue(const std::locale& loc) +{ + if (is_open()) { + obj().imbue(loc); + if (next_) + next_->pubimbue(loc); + } +} +#endif + +template +typename indirect_streambuf::int_type +indirect_streambuf::underflow() +{ + using namespace std; + if (!gptr()) init_get_area(); + buffer_type& buf = in(); + if (gptr() < egptr()) return traits_type::to_int_type(*gptr()); + + // Fill putback buffer. + std::streamsize keep = + (std::min)( static_cast(gptr() - eback()), + pback_size_ ); + if (keep) + traits_type::move( buf.data() + (pback_size_ - keep), + gptr() - keep, keep ); + + // Set pointers to reasonable values in case read throws. + setg( buf.data() + pback_size_ - keep, + buf.data() + pback_size_, + buf.data() + pback_size_ ); + + // Read from source. + std::streamsize chars = + obj().read(buf.data() + pback_size_, buf.size() - pback_size_, next_); + if (chars == -1) { + this->set_true_eof(true); + chars = 0; + } + setg(eback(), gptr(), buf.data() + pback_size_ + chars); + return chars != 0 ? + traits_type::to_int_type(*gptr()) : + traits_type::eof(); +} + +template +typename indirect_streambuf::int_type +indirect_streambuf::pbackfail(int_type c) +{ + if (gptr() != eback()) { + gbump(-1); + if (!traits_type::eq_int_type(c, traits_type::eof())) + *gptr() = traits_type::to_char_type(c); + return traits_type::not_eof(c); + } else { + throw bad_putback(); + } +} + +template +typename indirect_streambuf::int_type +indirect_streambuf::overflow(int_type c) +{ + if ( output_buffered() && pptr() == 0 || + shared_buffer() && gptr() != 0 ) + { + init_put_area(); + } + if (!traits_type::eq_int_type(c, traits_type::eof())) { + if (output_buffered()) { + if (pptr() == epptr()) { + sync_impl(); + if (pptr() == epptr()) + return traits_type::eof(); + } + *pptr() = traits_type::to_char_type(c); + pbump(1); + } else { + char_type d = traits_type::to_char_type(c); + if (obj().write(&d, 1, next_) != 1) + return traits_type::eof(); + } + } + return traits_type::not_eof(c); +} + +template +int indirect_streambuf::sync() +{ + try { // sync() is no-throw. + sync_impl(); + obj().flush(next_); + return 0; + } catch (...) { return -1; } +} + +template +bool indirect_streambuf::strict_sync() +{ + try { // sync() is no-throw. + sync_impl(); + return obj().flush(next_); + } catch (...) { return false; } +} + +template +inline typename indirect_streambuf::pos_type +indirect_streambuf::seekoff + (off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return seek_impl(off, way, which); } + +template +inline typename indirect_streambuf::pos_type +indirect_streambuf::seekpos + (pos_type sp, BOOST_IOS::openmode which) +{ + return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); +} + +template +typename indirect_streambuf::pos_type +indirect_streambuf::seek_impl + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ + if ( gptr() != 0 && way == BOOST_IOS::cur && which == BOOST_IOS::in && + eback() - gptr() <= off && off <= egptr() - gptr() ) + { // Small seek optimization + gbump(off); + return obj().seek(0, BOOST_IOS::cur, BOOST_IOS::in, next_) - + static_cast(egptr() - gptr()); + } + if (pptr() != 0) + this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6. + if (way == BOOST_IOS::cur && gptr()) + off -= static_cast(egptr() - gptr()); + setg(0, 0, 0); + setp(0, 0); + return obj().seek(off, way, which, next_); +} + +template +inline void indirect_streambuf::set_next + (streambuf_type* next) +{ next_ = next; } + +template +inline void indirect_streambuf::close_impl + (BOOST_IOS::openmode which) +{ + if (which == BOOST_IOS::in && is_convertible::value) { + setg(0, 0, 0); + } + if (which == BOOST_IOS::out && is_convertible::value) { + sync(); + setp(0, 0); + } + if ( !is_convertible::value || + is_convertible::value == (which == BOOST_IOS::in) ) + { + obj().close(which, next_); + } +} + +//----------State changing functions------------------------------------------// + +template +void indirect_streambuf::sync_impl() +{ + std::streamsize avail, amt; + if ((avail = static_cast(pptr() - pbase())) > 0) { + if ((amt = obj().write(pbase(), avail, next())) == avail) + setp(out().begin(), out().end()); + else { + const char_type* ptr = pptr(); + setp(out().begin() + amt, out().end()); + pbump(ptr - pptr()); + } + } +} + +template +void indirect_streambuf::init_get_area() +{ + if (shared_buffer() && pptr() != 0) { + sync_impl(); + setp(0, 0); + } + setg(in().begin(), in().begin(), in().begin()); +} + +template +void indirect_streambuf::init_put_area() +{ + using namespace std; + if (shared_buffer() && gptr() != 0) + setg(0, 0, 0); + if (output_buffered()) + setp(out().begin(), out().end()); + else + setp(0, 0); +} + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC, BCC 5.x + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/streambuf/linked_streambuf.hpp b/thirdparty/boost/iostreams/detail/streambuf/linked_streambuf.hpp new file mode 100644 index 0000000..c167e31 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/streambuf/linked_streambuf.hpp @@ -0,0 +1,114 @@ +// (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_LINKED_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // member template friends. +#include +#include // openmode. +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +template +class chain_base; + +template class chainbuf; + +#define BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base) \ + using base::eback; using base::gptr; using base::egptr; \ + using base::setg; using base::gbump; using base::pbase; \ + using base::pptr; using base::epptr; using base::setp; \ + using base::pbump; using base::underflow; using base::pbackfail; \ + using base::xsgetn; using base::overflow; using base::xsputn; \ + using base::sync; using base::seekoff; using base::seekpos; \ + /**/ + +template +class linked_streambuf : public BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) { +protected: + linked_streambuf() : flags_(0) { } + void set_true_eof(bool eof) + { + flags_ = (flags_ & ~f_true_eof) | (eof ? f_true_eof : 0); + } +public: + + // Should be called only after receiving an ordinary EOF indication, + // to confirm that it represents EOF rather than WOULD_BLOCK. + bool true_eof() const { return (flags_ & f_true_eof) != 0; } +protected: + + //----------grant friendship to chain_base and chainbuf-------------------// + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + template< typename Self, typename ChT, typename TrT, + typename Alloc, typename Mode > + friend class chain_base; + template + friend class chainbuf; + template + friend class member_close_operation; +#else + public: + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) base; + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base) +#endif + void close(BOOST_IOS::openmode which) + { + if ( which == BOOST_IOS::in && + (flags_ & f_input_closed) == 0 ) + { + flags_ |= f_input_closed; + close_impl(which); + } + if ( which == BOOST_IOS::out && + (flags_ & f_output_closed) == 0 ) + { + flags_ |= f_output_closed; + close_impl(which); + } + } + void set_needs_close() + { + flags_ &= ~(f_input_closed | f_output_closed); + } + virtual void set_next(linked_streambuf* /* next */) { } + virtual void close_impl(BOOST_IOS::openmode) = 0; + virtual bool auto_close() const = 0; + virtual void set_auto_close(bool) = 0; + virtual bool strict_sync() = 0; + virtual const std::type_info& component_type() const = 0; + virtual void* component_impl() = 0; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + private: +#else + public: +#endif +private: + enum flag_type { + f_true_eof = 1, + f_input_closed = f_true_eof << 1, + f_output_closed = f_input_closed << 1 + }; + int flags_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/system_failure.hpp b/thirdparty/boost/iostreams/detail/system_failure.hpp new file mode 100644 index 0000000..197a73c --- /dev/null +++ b/thirdparty/boost/iostreams/detail/system_failure.hpp @@ -0,0 +1,83 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-2007 Jonathan Turkanis +// (C) Copyright Jonathan Graehl 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/iostreams for documentation. + +// Used by mapped_file.cpp. + +#ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include // failure. + +#if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__) +namespace std { using ::strlen; } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS +# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +# include +#else +# include +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +inline BOOST_IOSTREAMS_FAILURE system_failure(const char* msg) +{ + std::string result; +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD err; + LPVOID lpMsgBuf; + if ( (err = ::GetLastError()) != NO_ERROR && + ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &lpMsgBuf, + 0, + NULL ) != 0 ) + { + result.reserve(std::strlen(msg) + 2 + std::strlen((LPSTR)lpMsgBuf)); + result.append(msg); + result.append(": "); + result.append((LPSTR) lpMsgBuf); + ::LocalFree(lpMsgBuf); + } else { + result += msg; + } +#else + const char* system_msg = errno ? strerror(errno) : ""; + result.reserve(std::strlen(msg) + 2 + std::strlen(system_msg)); + result.append(msg); + result.append(": "); + result.append(system_msg); +#endif + return BOOST_IOSTREAMS_FAILURE(result); +} + +inline BOOST_IOSTREAMS_FAILURE system_failure(const std::string& msg) +{ return system_failure(msg.c_str()); } + +inline void throw_system_failure(const char* msg) +{ throw system_failure(msg); } + +inline void throw_system_failure(const std::string& msg) +{ throw system_failure(msg); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/template_params.hpp b/thirdparty/boost/iostreams/detail/template_params.hpp new file mode 100644 index 0000000..54f426b --- /dev/null +++ b/thirdparty/boost/iostreams/detail/template_params.hpp @@ -0,0 +1,26 @@ +// (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_TEMPLATE_PARAMS_HPP_INCLUDED + +#include +#include +#include + +#define BOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, param) \ + BOOST_PP_EXPR_IF(arity, template<) \ + BOOST_PP_ENUM_PARAMS(arity, typename param) \ + BOOST_PP_EXPR_IF(arity, >) \ + /**/ + +#define BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, param) \ + BOOST_PP_EXPR_IF(arity, <) \ + BOOST_PP_ENUM_PARAMS(arity, param) \ + BOOST_PP_EXPR_IF(arity, >) \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/detail/translate_int_type.hpp b/thirdparty/boost/iostreams/detail/translate_int_type.hpp new file mode 100644 index 0000000..f5fa317 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/translate_int_type.hpp @@ -0,0 +1,62 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/detail/vc6/close.hpp b/thirdparty/boost/iostreams/detail/vc6/close.hpp new file mode 100644 index 0000000..921225f --- /dev/null +++ b/thirdparty/boost/iostreams/detail/vc6/close.hpp @@ -0,0 +1,129 @@ +// (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. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct close_impl; + +} // End namespace detail. + +template +void close(T& t) { detail::close_all(t); } + +template +void close(T& t, BOOST_IOS::openmode which) +{ + typedef typename detail::unwrapped_type::type unwrapped; + detail::close_impl::inner::close(detail::unwrap(t), which); +} + +template +void close(T& t, Sink& snk, BOOST_IOS::openmode which) +{ + typedef typename detail::unwrapped_type::type unwrapped; + detail::close_impl::inner::close(detail::unwrap(t), snk, which); +} + +namespace detail { + +//------------------Definition of close_impl----------------------------------// + +template +struct close_tag { + typedef typename category_of::type category; + typedef typename + mpl::eval_if< + is_convertible, + mpl::if_< + mpl::or_< + is_convertible, + is_convertible + >, + two_sequence, + closable_tag + >, + mpl::identity + >::type type; +}; + +template +struct close_impl + : mpl::if_< + is_custom, + operations, + close_impl::type> + >::type + { }; + +template<> +struct close_impl { + template + struct inner { + static void close(T& t, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) + iostreams::flush(t); + } + + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) { + non_blocking_adapter nb(snk); + iostreams::flush(t, nb); + } + } + }; +}; + +template<> +struct close_impl { + template + struct inner { + static void close(T& t, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) + t.close(); + } + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) { + non_blocking_adapter nb(snk); + t.close(nb); + } + } + }; +}; + +template<> +struct close_impl { + template + struct inner { + static void close(T& t, BOOST_IOS::openmode which) { t.close(which); } + + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + non_blocking_adapter nb(snk); + t.close(nb, which); + } + }; +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. diff --git a/thirdparty/boost/iostreams/detail/vc6/read.hpp b/thirdparty/boost/iostreams/detail/vc6/read.hpp new file mode 100644 index 0000000..518f70f --- /dev/null +++ b/thirdparty/boost/iostreams/detail/vc6/read.hpp @@ -0,0 +1,238 @@ +// (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. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct read_device_impl; + +template +struct read_filter_impl; + +} // End namespace detail. + +template +typename int_type_of::type get(T& t) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::read_device_impl::inner::get(detail::unwrap(t)); +} + +template +inline std::streamsize +read(T& t, typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::read_device_impl::inner::read(detail::unwrap(t), s, n); +} + +template +std::streamsize +read(T& t, Source& src, typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::read_filter_impl::inner::read(detail::unwrap(t), src, s, n); +} + +template +bool putback(T& t, typename char_type_of::type c) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::read_device_impl::inner::putback(detail::unwrap(t), c); +} + +//----------------------------------------------------------------------------// + +namespace detail { + +// Helper function for adding -1 as EOF indicator. +inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; } + +// Helper templates for reading from streambufs. +template +struct true_eof_impl; + +template<> +struct true_eof_impl { + template + static bool true_eof(T& t) { return t.true_eof(); } +}; + +template<> +struct true_eof_impl { + template + static bool true_eof(T& t) { return true; } +}; + +template +inline bool true_eof(T& t) +{ + const bool linked = is_linked::value; + return true_eof_impl::true_eof(t); +} + +//------------------Definition of read_device_impl----------------------------// + +template +struct read_device_impl + : mpl::if_< + detail::is_custom, + operations, + read_device_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, istream_tag, streambuf_tag, input + >::type + > + >::type + { }; + +template<> +struct read_device_impl { + template + struct inner { + static typename int_type_of::type get(T& t) + { return t.get(); } + + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return check_eof(t.rdbuf()->sgetn(s, n)); } + + static bool putback(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c), + traits_type::eof() ); + } + }; +}; + +template<> +struct read_device_impl { + template + struct inner { + static typename int_type_of::type + get(T& t) + { + typedef typename char_type_of::type char_type; + typedef char_traits traits_type; + typename int_type_of::type c; + return !traits_type::is_eof(c = t.sbumpc()) || + detail::true_eof(t) + ? + c : traits_type::would_block(); + } + + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { + std::streamsize amt; + return (amt = t.sgetn(s, n)) != 0 ? + amt : + detail::true_eof(t) ? + -1 : + 0; + } + + static bool putback(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef char_traits traits_type; + return !traits_type::is_eof(t.sputbackc(c)); + } + }; +}; + +template<> +struct read_device_impl { + template + struct inner { + static typename int_type_of::type + get(T& t) + { + typedef typename char_type_of::type char_type; + typedef char_traits traits_type; + char_type c; + std::streamsize amt; + return (amt = t.read(&c, 1)) == 1 ? + traits_type::to_int_type(c) : + amt == -1 ? + traits_type::eof() : + traits_type::would_block(); + } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return t.read(s, n); } + + template + static bool putback(T& t, typename char_type_of::type c) + { // T must be Peekable. + return t.putback(c); + } + }; +}; + +//------------------Definition of read_filter_impl----------------------------// + +template +struct read_filter_impl + : mpl::if_< + detail::is_custom, + operations, + read_filter_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct read_filter_impl { + template + struct inner { + template + static std::streamsize read + ( T& t, Source& src, typename char_type_of::type* s, + std::streamsize n ) + { return t.read(src, s, n); } + }; +}; + +template<> +struct read_filter_impl { + template + struct inner { + template + static std::streamsize read + ( T& t, Source& src, typename char_type_of::type* s, + std::streamsize n ) + { + typedef typename char_type_of::type char_type; + typedef char_traits traits_type; + for (std::streamsize off = 0; off < n; ++off) { + typename traits_type::int_type c = t.get(src); + if (traits_type::is_eof(c)) + return check_eof(off); + if (traits_type::would_block(c)) + return off; + s[off] = traits_type::to_char_type(c); + } + return n; + } + }; +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. diff --git a/thirdparty/boost/iostreams/detail/vc6/write.hpp b/thirdparty/boost/iostreams/detail/vc6/write.hpp new file mode 100644 index 0000000..692ea28 --- /dev/null +++ b/thirdparty/boost/iostreams/detail/vc6/write.hpp @@ -0,0 +1,159 @@ +// (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. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct write_device_impl; + +template +struct write_filter_impl; + +} // End namespace detail. + +template +bool put(T& t, typename char_type_of::type c) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::write_device_impl::inner::put(detail::unwrap(t), c); +} + +template +inline std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::write_device_impl::inner::write(detail::unwrap(t), s, n); +} + +template +inline std::streamsize +write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) +{ + typedef typename detail::unwrapped_type::type unwrapped; + return detail::write_filter_impl::inner::write(detail::unwrap(t), snk, s, n); +} + +namespace detail { + +//------------------Definition of write_device_impl---------------------------// + +template +struct write_device_impl + : mpl::if_< + is_custom, + operations, + write_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, ostream_tag, streambuf_tag, output + >::type + > + >::type + { }; + +template<> +struct write_device_impl { + template + struct inner { + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->s.sputc(), + traits_type::eof() ); + } + + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.rdbuf()->sputn(s, n); } + }; +}; + +template<> +struct write_device_impl { + template + struct inner { + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type(t.sputc(c), traits_type::eof()); + } + + template + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.sputn(s, n); } + }; +}; + +template<> +struct write_device_impl { + template + struct inner { + static bool put(T& t, typename char_type_of::type c) + { return t.write(&c, 1) == 1; } + + template + static std::streamsize + write(T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.write(s, n); } + }; +}; + +//------------------Definition of write_filter_impl---------------------------// + +template +struct write_filter_impl + : mpl::if_< + is_custom, + operations, + write_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct write_filter_impl { + template + struct inner { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { return t.write(snk, s, n); } + }; +}; + +template<> +struct write_filter_impl { + template + struct inner { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { + for (std::streamsize off = 0; off < n; ++off) + if (!t.put(snk, s[off])) + return off; + return n; + } + }; +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. diff --git a/thirdparty/boost/iostreams/detail/wrap_unwrap.hpp b/thirdparty/boost/iostreams/detail/wrap_unwrap.hpp new file mode 100644 index 0000000..ceedd0f --- /dev/null +++ b/thirdparty/boost/iostreams/detail/wrap_unwrap.hpp @@ -0,0 +1,127 @@ +// (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_WRAP_UNWRAP_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // SFINAE, MSVC. +#include +#include +#include // is_std_io. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of wrap/unwrap traits--------------------------// + +template +struct wrapped_type + : mpl::if_, reference_wrapper, T> + { }; + +template +struct unwrapped_type + : unwrap_reference + { }; + +template +struct unwrap_ios + : mpl::eval_if< + is_std_io, + unwrap_reference, + mpl::identity + > + { }; + +//------------------Definition of wrap----------------------------------------// + +#ifndef BOOST_NO_SFINAE //----------------------------------------------------// + template + inline T wrap(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) + { return t; } + + template + inline typename wrapped_type::type + wrap(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) { return boost::ref(t); } +#else // #ifndef BOOST_NO_SFINAE //-------------------------------------------// + template + inline typename wrapped_type::type // BCC 5.x needs namespace qualification. + wrap_impl(const T& t, mpl::true_) { return boost::ref(const_cast(t)); } + + template + inline typename wrapped_type::type // BCC 5.x needs namespace qualification. + wrap_impl(T& t, mpl::true_) { return boost::ref(t); } + + template + inline typename wrapped_type::type + wrap_impl(const T& t, mpl::false_) { return t; } + + template + inline typename wrapped_type::type + wrap_impl(T& t, mpl::false_) { return t; } + + template + inline typename wrapped_type::type + wrap(const T& t) { return wrap_impl(t, is_std_io()); } + + template + inline typename wrapped_type::type + wrap(T& t) { return wrap_impl(t, is_std_io()); } +#endif // #ifndef BOOST_NO_SFINAE //------------------------------------------// + +//------------------Definition of unwrap--------------------------------------// + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //----------------------------------// + +template +typename unwrapped_type::type& +unwrap(const reference_wrapper& ref) { return ref.get(); } + +template +typename unwrapped_type::type& unwrap(T& t) { return t; } + +template +const typename unwrapped_type::type& unwrap(const T& t) { return t; } + +#else // #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //-------------------------// + +// Since unwrap is a potential bottleneck, we avoid runtime tag dispatch. +template +struct unwrap_impl; + +template<> +struct unwrap_impl { + template + static typename unwrapped_type::type& unwrap(const T& t) + { return t.get(); } +}; + +template<> +struct unwrap_impl { + template + static typename unwrapped_type::type& unwrap(const T& t) + { return const_cast(t); } +}; + +template +typename unwrapped_type::type& +unwrap(const T& t) +{ return unwrap_impl::value>::unwrap(t); } + +#endif // #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/array.hpp b/thirdparty/boost/iostreams/device/array.hpp new file mode 100644 index 0000000..55363f0 --- /dev/null +++ b/thirdparty/boost/iostreams/device/array.hpp @@ -0,0 +1,144 @@ +// (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_ARRAY_HPP_INCLUDED +#define BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC, make sure size_t is in std. +#include +#include // std::size_t. +#include // pair. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +class array_adapter { +public: + typedef Ch char_type; + typedef std::pair pair_type; + struct category + : public Mode, + public device_tag, + public direct_tag + { }; + array_adapter(char_type* begin, char_type* end); + array_adapter(char_type* begin, std::size_t length); + array_adapter(const char_type* begin, const char_type* end); + array_adapter(const char_type* begin, std::size_t length); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + array_adapter(char_type (&ar)[N]) + : begin_(ar), end_(ar + N) + { } +#endif + pair_type input_sequence(); + pair_type output_sequence(); +private: + char_type* begin_; + char_type* end_; +}; + +} // End namespace detail. + +// Local macros, #undef'd below. +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_IOSTREAMS_ARRAY_CTOR(name, ch) \ + template \ + BOOST_PP_CAT(basic_, name)(ch (&ar)[N]) \ + : base_type(ar) { } \ + /**/ +#else +# define BOOST_IOSTREAMS_ARRAY_CTOR(name, ch) +#endif +#define BOOST_IOSTREAMS_ARRAY(name, mode) \ + template \ + struct BOOST_PP_CAT(basic_, name) : detail::array_adapter { \ + private: \ + typedef detail::array_adapter base_type; \ + public: \ + typedef typename base_type::char_type char_type; \ + typedef typename base_type::category category; \ + BOOST_PP_CAT(basic_, name)(char_type* begin, char_type* end) \ + : base_type(begin, end) { } \ + BOOST_PP_CAT(basic_, name)(char_type* begin, std::size_t length) \ + : base_type(begin, length) { } \ + BOOST_PP_CAT(basic_, name)(const char_type* begin, const char_type* end) \ + : base_type(begin, end) { } \ + BOOST_PP_CAT(basic_, name)(const char_type* begin, std::size_t length) \ + : base_type(begin, length) { } \ + BOOST_IOSTREAMS_ARRAY_CTOR(name, Ch) \ + }; \ + typedef BOOST_PP_CAT(basic_, name) name; \ + typedef BOOST_PP_CAT(basic_, name) BOOST_PP_CAT(w, name); \ + /**/ +BOOST_IOSTREAMS_ARRAY(array_source, input_seekable) +BOOST_IOSTREAMS_ARRAY(array_sink, output_seekable) +BOOST_IOSTREAMS_ARRAY(array, seekable) +#undef BOOST_IOSTREAMS_ARRAY_CTOR +#undef BOOST_IOSTREAMS_ARRAY + + +//------------------Implementation of array_adapter---------------------------// + +namespace detail { + +template +array_adapter::array_adapter + (char_type* begin, char_type* end) + : begin_(begin), end_(end) + { } + +template +array_adapter::array_adapter + (char_type* begin, std::size_t length) + : begin_(begin), end_(begin + length) + { } + +template +array_adapter::array_adapter + (const char_type* begin, const char_type* end) + : begin_(const_cast(begin)), // Treated as read-only. + end_(const_cast(end)) // Treated as read-only. +{ BOOST_STATIC_ASSERT((!is_convertible::value)); } + +template +array_adapter::array_adapter + (const char_type* begin, std::size_t length) + : begin_(const_cast(begin)), // Treated as read-only. + end_(const_cast(begin) + length) // Treated as read-only. +{ BOOST_STATIC_ASSERT((!is_convertible::value)); } + +template +typename array_adapter::pair_type +array_adapter::input_sequence() +{ BOOST_STATIC_ASSERT((is_convertible::value)); + return pair_type(begin_, end_); } + +template +typename array_adapter::pair_type +array_adapter::output_sequence() +{ BOOST_STATIC_ASSERT((is_convertible::value)); + return pair_type(begin_, end_); } + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/back_inserter.hpp b/thirdparty/boost/iostreams/device/back_inserter.hpp new file mode 100644 index 0000000..0d32c34 --- /dev/null +++ b/thirdparty/boost/iostreams/device/back_inserter.hpp @@ -0,0 +1,41 @@ +// (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_BACK_INSERTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // streamsize. +#include + +namespace boost { namespace iostreams { + +template +class back_insert_device { +public: + typedef typename Container::value_type char_type; + typedef sink_tag category; + back_insert_device(Container& cnt) : container(&cnt) { } + std::streamsize write(const char_type* s, std::streamsize n) + { + container->insert(container->end(), s, s + n); + return n; + } +protected: + Container* container; +}; + +template +back_insert_device back_inserter(Container& cnt) +{ return back_insert_device(cnt); } + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/file.hpp b/thirdparty/boost/iostreams/device/file.hpp new file mode 100644 index 0000000..d47dea4 --- /dev/null +++ b/thirdparty/boost/iostreams/device/file.hpp @@ -0,0 +1,183 @@ +// (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 wrappers for standard file buffers, together +// with convenience typedefs: +// - basic_file_source +// - basic_file_sink +// - basic_file +// + +#ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# 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 + { }; + 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); + 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(); +#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::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 + { }; + using basic_file::write; + using basic_file::seek; + using basic_file::is_open; + using basic_file::close; + 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 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(); } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // MSVC + +#endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/file_descriptor.hpp b/thirdparty/boost/iostreams/device/file_descriptor.hpp new file mode 100644 index 0000000..1020730 --- /dev/null +++ b/thirdparty/boost/iostreams/device/file_descriptor.hpp @@ -0,0 +1,186 @@ +// (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. + +// Inspired by fdstream.hpp, (C) Copyright Nicolai M. Josuttis 2001, +// available at http://www.josuttis.com/cppcode/fdstream.html. + +#ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // file pathnames. +#include // intmax_t. +#include // tags. +#include +#include +#include +#include // openmode, seekdir, int types. +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +class BOOST_IOSTREAMS_DECL file_descriptor { +public: +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* handle_type; // A.k.a HANDLE +#else + typedef int handle_type; +#endif + typedef char char_type; + struct category + : seekable_device_tag, + closable_tag + { }; + file_descriptor(); + explicit file_descriptor(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor(int fd, bool close_on_exit = false); +#endif + explicit file_descriptor( 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 ); + explicit file_descriptor( const char* path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + BOOST_IOS::openmode base_mode = + BOOST_IOS::in | BOOST_IOS::out ); + void open( const std::string& path, + BOOST_IOS::openmode = + BOOST_IOS::in | BOOST_IOS::out, + BOOST_IOS::openmode base_mode = + BOOST_IOS::in | BOOST_IOS::out ); + void open( const char* path, + BOOST_IOS::openmode = + BOOST_IOS::in | BOOST_IOS::out, + BOOST_IOS::openmode base_mode = + BOOST_IOS::in | BOOST_IOS::out ); + bool is_open() const { return pimpl_->flags_ != 0; } + 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); + void close(); + handle_type handle() const { return pimpl_->handle_; } +private: + struct impl { + impl() : + #ifdef BOOST_IOSTREAMS_WINDOWS + handle_(reinterpret_cast(-1)), + #else + handle_(-1), + #endif + flags_(0) + { } + impl(handle_type fd, bool close_on_exit) + : handle_(fd), flags_(0) + { if (close_on_exit) flags_ |= impl::close_on_exit; } + ~impl() + { if (flags_ & close_on_exit) close_impl(*this); } + enum flags { + close_on_exit = 1, + append = 4 + }; + handle_type handle_; + int flags_; + }; + friend struct impl; + + static void close_impl(impl&); +#ifdef BOOST_IOSTREAMS_WINDOWS + static handle_type int_to_handle(int fd); +#endif + + shared_ptr pimpl_; +}; + +struct file_descriptor_source : private file_descriptor { +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* handle_type; // A.k.a HANDLE +#else + typedef int handle_type; +#endif + typedef char char_type; + struct category + : input_seekable, + device_tag, + closable_tag + { }; + using file_descriptor::read; + using file_descriptor::seek; + using file_descriptor::open; + using file_descriptor::is_open; + using file_descriptor::close; + using file_descriptor::handle; + file_descriptor_source() { } + explicit file_descriptor_source(handle_type fd, bool close_on_exit = false) + : file_descriptor(fd, close_on_exit) + { } +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor_source(int fd, bool close_on_exit = false) + : file_descriptor(fd, close_on_exit) + { } +#endif + explicit file_descriptor_source( const std::string& path, + BOOST_IOS::openmode m = BOOST_IOS::in ) + : file_descriptor(path, m & ~BOOST_IOS::out, BOOST_IOS::in) + { } + explicit file_descriptor_source( const char* path, + BOOST_IOS::openmode m = BOOST_IOS::in ) + : file_descriptor(path, m & ~BOOST_IOS::out, BOOST_IOS::in) + { } +}; + +struct file_descriptor_sink : private file_descriptor { +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* handle_type; // A.k.a HANDLE +#else + typedef int handle_type; +#endif + typedef char char_type; + struct category + : output_seekable, + device_tag, + closable_tag + { }; + using file_descriptor::write; + using file_descriptor::seek; + using file_descriptor::open; + using file_descriptor::is_open; + using file_descriptor::close; + using file_descriptor::handle; + file_descriptor_sink() { } + explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false) + : file_descriptor(fd, close_on_exit) + { } +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor_sink(int fd, bool close_on_exit = false) + : file_descriptor(fd, close_on_exit) + { } +#endif + explicit file_descriptor_sink( const std::string& path, + BOOST_IOS::openmode m = BOOST_IOS::out ) + : file_descriptor(path, m & ~BOOST_IOS::in, BOOST_IOS::out) + { } + explicit file_descriptor_sink( const char* path, + BOOST_IOS::openmode m = BOOST_IOS::out ) + : file_descriptor(path, m & ~BOOST_IOS::in, BOOST_IOS::out) + { } +}; + +} } // End namespaces iostreams, boost. + +#include // pops abi_suffix.hpp pragmas + +#endif // #ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/mapped_file.hpp b/thirdparty/boost/iostreams/device/mapped_file.hpp new file mode 100644 index 0000000..11150e2 --- /dev/null +++ b/thirdparty/boost/iostreams/device/mapped_file.hpp @@ -0,0 +1,285 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2003-2007 Jonathan Turkanis +// (C) Copyright Craig Henderson 2002. 'boost/memmap.hpp' from sandbox +// Distributed under the Boost Software License, Version 1.0. (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. + +// +// This header and its accompanying source file libs/iostreams/memmap.cpp are +// an adaptation of Craig Henderson's memmory mapped file library. The +// interface has been revised significantly, but the underlying OS-specific +// code is essentially the same, with some code from Boost.Filesystem +// mixed in. (See notations in source.) +// +// The following changes have been made: +// +// 1. OS-specific code put in a .cpp file. +// 2. Name of main class changed to mapped_file. +// 3. mapped_file given an interface similar to std::fstream (open(), +// is_open(), close()) and std::string (data(), size(), begin(), end()). +// 4. An additional class readonly_mapped_file has been provided as a +// convenience. +// 5. [Obsolete: Error states are reported using filesystem::error_code.] +// 6. Read-only or read-write states are specified using ios_base::openmode. +// 7. Access to the underlying file handles and to security parameters +// has been removed. +// + +#ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED +#define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // make sure size_t is in std. +#include // size_t. +#include // pathnames. +#include // pair. +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include // openmode. +#include +#include +#include + +// Must come last. +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +struct mapped_file_impl; + +} // End namespace detail. + +struct mapped_file_params { + explicit mapped_file_params() + #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) && defined(BOOST_RWSTD_VER) || \ + defined(__BORLANDC__) && defined(_CPPLIB_VER) + /**/ + : mode(std::ios_base::openmode(0)), + #else + : mode(), + #endif + offset(0), length(static_cast(-1)), + new_file_size(0), hint(0) + { } + explicit mapped_file_params(const std::string& path) + : path(path), + #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) && defined(BOOST_RWSTD_VER) || \ + defined(__BORLANDC__) && defined(_CPPLIB_VER) + mode(std::ios_base::openmode(0)), + #else + mode(), + #endif + offset(0), length(static_cast(-1)), + new_file_size(0), hint(0) + { } + std::string path; + BOOST_IOS::openmode mode; + stream_offset offset; + std::size_t length; + stream_offset new_file_size; + const char* hint; +}; + +//------------------Definition of mapped_file_source--------------------------// + +class BOOST_IOSTREAMS_DECL mapped_file_source { +private: + struct safe_bool_helper { int x; }; // From Bronek Kozicki. + typedef int safe_bool_helper::* safe_bool; + friend struct operations; +public: + typedef char char_type; + struct category + : public source_tag, + public direct_tag, + public closable_tag + { }; + typedef std::size_t size_type; + typedef const char* iterator; + BOOST_STATIC_CONSTANT(size_type, max_length = static_cast(-1)); + + mapped_file_source() { } + explicit mapped_file_source(mapped_file_params); + explicit mapped_file_source( const std::string& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); + + //--------------Stream interface------------------------------------------// + + void open(mapped_file_params params); + void open( const std::string& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); + bool is_open() const; + void close(); + + operator safe_bool() const; + bool operator!() const; + BOOST_IOS::openmode mode() const; + + //--------------Container interface---------------------------------------// + + size_type size() const; + const char* data() const; + iterator begin() const; + iterator end() const; + + //--------------Query admissible offsets----------------------------------// + + // Returns the allocation granularity for virtual memory. Values passed + // as offsets must be multiples of this value. + static int alignment(); +private: + friend class mapped_file; + typedef detail::mapped_file_impl impl_type; + void open_impl(mapped_file_params); + + boost::shared_ptr pimpl_; +}; + +//------------------Definition of mapped_file---------------------------------// + +class BOOST_IOSTREAMS_DECL mapped_file { +private: + typedef mapped_file_source delegate_type; + delegate_type delegate_; + friend struct operations; +public: + typedef char char_type; + struct category + : public seekable_device_tag, + public direct_tag, + public closable_tag + { }; + typedef mapped_file_source::size_type size_type; + typedef char* iterator; + typedef const char* const_iterator; + BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length); + mapped_file() { } + explicit mapped_file(mapped_file_params p); + explicit mapped_file( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + size_type length = max_length, + stream_offset offset = 0 ); + + //--------------Conversion to readonly_mapped_file------------------------// + + operator mapped_file_source&() { return delegate_; } + operator const mapped_file_source&() const { return delegate_; } + + //--------------Stream interface------------------------------------------// + + void open(mapped_file_params p); + void open( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + size_type length = max_length, + stream_offset offset = 0 ); + bool is_open() const { return delegate_.is_open(); } + void close() { delegate_.close(); } + operator delegate_type::safe_bool() const { return delegate_; } + bool operator!() const { return !is_open(); } + BOOST_IOS::openmode mode() const { return delegate_.mode(); } + + //--------------Container interface---------------------------------------// + + size_type size() const { return delegate_.size(); } + char* data() const + { + return (mode() & BOOST_IOS::out) ? + const_cast(delegate_.data()) : + 0; + } + const char* const_data() const { return delegate_.data(); } + iterator begin() const { return data(); } + const_iterator const_begin() const { return data(); } + iterator end() const { return data() + size(); } + const_iterator const_end() const { return data() + size(); } + + //--------------Query admissible offsets----------------------------------// + + // Returns the allocation granularity for virtual memory. Values passed + // as offsets must be multiples of this value. + static int alignment() { return mapped_file_source::alignment(); } +}; + +struct BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file { + friend struct operations; + typedef char char_type; + struct category + : public sink_tag, + public direct_tag, + public closable_tag + { }; + using mapped_file::close; + using mapped_file::size; + explicit mapped_file_sink(mapped_file_params p); + explicit mapped_file_sink( const std::string& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); + void open(mapped_file_params p); + void open( const std::string& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); +}; + +//------------------Specialization of direct_impl-----------------------------// + +template<> +struct operations + : detail::close_impl +{ + static std::pair + input_sequence(boost::iostreams::mapped_file_source& src) + { + return std::make_pair( const_cast(src.begin()), + const_cast(src.end()) ); + } +}; + +template<> +struct operations + : detail::close_impl +{ + static std::pair + output_sequence(boost::iostreams::mapped_file_sink& sink) + { + return std::make_pair(sink.begin(), sink.end()); + } +}; + +template<> +struct operations + : detail::close_impl +{ + static std::pair + input_sequence(boost::iostreams::mapped_file& file) + { + return std::make_pair(file.begin(), file.end()); + } + static std::pair + output_sequence(boost::iostreams::mapped_file& file) + { + return std::make_pair(file.begin(), file.end()); + } +}; + +} } // End namespaces iostreams, boost. + +#include // pops abi_suffix.hpp pragmas +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/device/null.hpp b/thirdparty/boost/iostreams/device/null.hpp new file mode 100644 index 0000000..fcae14a --- /dev/null +++ b/thirdparty/boost/iostreams/device/null.hpp @@ -0,0 +1,66 @@ +// (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. + +// Inspired by Daryle Walker's nullbuf from his More I/O submission. + +#ifndef BOOST_IOSTREAMS_NULL_HPP_INCLUDED +#define BOOST_IOSTREAMS_NULL_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // openmode, streamsize. +#include + +namespace boost { namespace iostreams { + +template +class basic_null_device { +public: + typedef Ch char_type; + struct category + : public Mode, + public device_tag, + public closable_tag + { }; + std::streamsize read(Ch*, std::streamsize) { return 0; } + std::streamsize write(const Ch*, std::streamsize n) { return n; } + std::streampos seek( stream_offset, BOOST_IOS::seekdir, + BOOST_IOS::openmode = + BOOST_IOS::in | BOOST_IOS::out ) + { return -1; } + void close() { } + void close(BOOST_IOS::openmode) { } +}; + +template +struct basic_null_source : private basic_null_device { + typedef Ch char_type; + typedef source_tag category; + using basic_null_device::read; + using basic_null_device::close; +}; + +typedef basic_null_source null_source; +typedef basic_null_source wnull_source; + +template +struct basic_null_sink : private basic_null_device { + typedef Ch char_type; + typedef sink_tag category; + using basic_null_device::write; + using basic_null_device::close; +}; + +typedef basic_null_sink null_sink; +typedef basic_null_sink wnull_sink; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_NULL_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/filter/aggregate.hpp b/thirdparty/boost/iostreams/filter/aggregate.hpp new file mode 100644 index 0000000..6ff9c56 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/aggregate.hpp @@ -0,0 +1,168 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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; + 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) + { + 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* 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* s, std::streamsize n, mpl::true_) + { iostreams::write(sink, s, n); } + + template + void do_write(Sink&, const char*, 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/thirdparty/boost/iostreams/filter/bzip2.hpp b/thirdparty/boost/iostreams/filter/bzip2.hpp new file mode 100644 index 0000000..565475a --- /dev/null +++ b/thirdparty/boost/iostreams/filter/bzip2.hpp @@ -0,0 +1,397 @@ +// (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: custom allocators are not supported on VC6, since that compiler +// had trouble finding the function zlib_base::do_init. + +#ifndef BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED +#define BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // allocator. +#include // bad_alloc. +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include +#include // buffer size. +#include +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4231 4660) +#endif +#include + +// Temporary fix. +#undef small + +namespace boost { namespace iostreams { + +namespace bzip2 { + + // Typedefs. + +typedef void* (*alloc_func)(void*, int, int); +typedef void (*free_func)(void*, void*); + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int ok; +BOOST_IOSTREAMS_DECL extern const int run_ok; +BOOST_IOSTREAMS_DECL extern const int flush_ok; +BOOST_IOSTREAMS_DECL extern const int finish_ok; +BOOST_IOSTREAMS_DECL extern const int stream_end; +BOOST_IOSTREAMS_DECL extern const int sequence_error; +BOOST_IOSTREAMS_DECL extern const int param_error; +BOOST_IOSTREAMS_DECL extern const int mem_error; +BOOST_IOSTREAMS_DECL extern const int data_error; +BOOST_IOSTREAMS_DECL extern const int data_error_magic; +BOOST_IOSTREAMS_DECL extern const int io_error; +BOOST_IOSTREAMS_DECL extern const int unexpected_eof; +BOOST_IOSTREAMS_DECL extern const int outbuff_full; +BOOST_IOSTREAMS_DECL extern const int config_error; + + // Action codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int run; + + // Default values + +const int default_block_size = 9; +const int default_work_factor = 30; +const bool default_small = false; + +} // End namespace bzip2. + +// +// Class name: bzip2_params. +// Description: Encapsulates the parameters passed to deflateInit2 +// to customize compression. +// +struct bzip2_params { + + // Non-explicit constructor for compression. + bzip2_params( int block_size = bzip2::default_block_size, + int work_factor = bzip2::default_work_factor ) + : block_size(block_size), work_factor(work_factor) + { } + + // Constructor for decompression. + bzip2_params(bool small) + : small(small), work_factor(0) + { } + + union { + int block_size; // For compression. + bool small; // For decompression. + }; + int work_factor; +}; + +// +// Class name: bzip2_error. +// Description: Subclass of std::ios_base::failure thrown to indicate +// bzip2 errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL bzip2_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit bzip2_error(int error); + int error() const { return error_; } + static void check(int error); +private: + int error_; +}; + +namespace detail { + +template +struct bzip2_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR + typedef typename Alloc::template rebind::other type; +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME bzip2_allocator_traits::type > +struct bzip2_allocator : private Base { +private: + typedef typename Base::size_type size_type; +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename bzip2_allocator_traits::type allocator_type; + static void* allocate(void* self, int items, int size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL bzip2_base { +public: + typedef char char_type; +protected: + bzip2_base(const bzip2_params& params); + ~bzip2_base(); + bzip2_params& params() { return params_; } + bool& ready() { return ready_; } + template + void init( bool compress, + bzip2_allocator& alloc ) + { + bool custom = bzip2_allocator::custom; + do_init( compress, + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + custom ? bzip2_allocator::allocate : 0, + custom ? bzip2_allocator::deallocate : 0, + #endif + custom ? &alloc : 0 ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after(const char*& src_begin, char*& dest_begin); + int compress(int action); + int decompress(); + void end(bool compress); +private: + void do_init( bool compress, + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + bzip2::alloc_func, + bzip2::free_func, + #endif + void* derived ); + bzip2_params params_; + void* stream_; // Actual type: bz_stream*. + bool ready_; +}; + +// +// Template name: bzip2_compressor_impl +// Description: Model of SymmetricFilter implementing compression by +// delegating to the libbzip2 function BZ_bzCompress. +// +template > +class bzip2_compressor_impl + : public bzip2_base, + #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) + public + #endif + bzip2_allocator +{ +public: + bzip2_compressor_impl(const bzip2_params&); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +private: + void init(); +}; + +// +// Template name: bzip2_compressor +// Description: Model of SymmetricFilter implementing decompression by +// delegating to the libbzip2 function BZ_bzDecompress. +// +template > +class bzip2_decompressor_impl + : public bzip2_base, + #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) + public + #endif + bzip2_allocator +{ +public: + bzip2_decompressor_impl(bool small = bzip2::default_small); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); +private: + void init(); + bool eof_; // Guard to make sure filter() isn't called after it returns false. +}; + +} // End namespace detail. + +// +// Template name: bzip2_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using libbzip2. +// +template > +struct basic_bzip2_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::bzip2_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_bzip2_compressor( const bzip2_params& = bzip2::default_block_size, + int buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_bzip2_compressor, 1) + +typedef basic_bzip2_compressor<> bzip2_compressor; + +// +// Template name: bzip2_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using libbzip2. +// +template > +struct basic_bzip2_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::bzip2_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_bzip2_decompressor( bool small = bzip2::default_small, + int buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_bzip2_decompressor, 1) + +typedef basic_bzip2_decompressor<> bzip2_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of bzip2_allocator-------------------------// + +namespace detail { + +template +void* bzip2_allocator::allocate(void* self, int items, int size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void bzip2_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of bzip2_compressor_impl-------------------// + +template +bzip2_compressor_impl::bzip2_compressor_impl(const bzip2_params& p) + : bzip2_base(p) { } + +template +bool bzip2_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + if (!ready()) init(); + before(src_begin, src_end, dest_begin, dest_end); + int result = compress(flush ? bzip2::finish : bzip2::run); + after(src_begin, dest_begin); + bzip2_error::check(result); + return result != bzip2::stream_end; +} + +template +void bzip2_compressor_impl::close() +{ + end(true); +} + +template +inline void bzip2_compressor_impl::init() +{ bzip2_base::init(true, static_cast&>(*this)); } + +//------------------Implementation of bzip2_decompressor_impl-----------------// + +template +bzip2_decompressor_impl::bzip2_decompressor_impl(bool small) + : bzip2_base(bzip2_params(small)), eof_(false) { } + +template +bool bzip2_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool /* flush */ ) +{ + if (!ready()) + init(); + if (eof_) + return false; + before(src_begin, src_end, dest_begin, dest_end); + int result = decompress(); + after(src_begin, dest_begin); + bzip2_error::check(result); + return !(eof_ = result == bzip2::stream_end); +} + +template +void bzip2_decompressor_impl::close() +{ + try { + end(false); + } catch (...) { + eof_ = false; + throw; + } + eof_ = false; +} + +template +inline void bzip2_decompressor_impl::init() +{ bzip2_base::init(false, static_cast&>(*this)); } +} // End namespace detail. + +//------------------Implementation of bzip2_decompressor----------------------// + +template +basic_bzip2_compressor::basic_bzip2_compressor + (const bzip2_params& p, int buffer_size) + : base_type(buffer_size, p) + { } + +//------------------Implementation of bzip2_decompressor----------------------// + +template +basic_bzip2_decompressor::basic_bzip2_decompressor + (bool small, int buffer_size) + : base_type(buffer_size, small) + { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/filter/counter.hpp b/thirdparty/boost/iostreams/filter/counter.hpp new file mode 100644 index 0000000..b8365b2 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/counter.hpp @@ -0,0 +1,82 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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/thirdparty/boost/iostreams/filter/gzip.hpp b/thirdparty/boost/iostreams/filter/gzip.hpp new file mode 100644 index 0000000..14d3667 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/gzip.hpp @@ -0,0 +1,604 @@ +// (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 definitions of the class templates gzip_compressor and +// gzip_decompressor for reading and writing files in the gzip file format +// (RFC 1952). Based in part on work of Jonathan de Halleux; see [...] + +#ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED +#define BOOST_IOSTREAMS_GZIP_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // STATIC_CONSTANT, STDC_NAMESPACE, + // DINKUMWARE_STDLIB, __STL_CONFIG_H. +#include // min. +#include // EOF. +#include // size_t. +#include // std::time_t. +#include // allocator. +#include // Put size_t in std. +#include +#include // uint8_t, uint32_t. +#include // buffer size. +#include +#include +#include +#include // failure. +#include +#include +#include +#include + +// Must come last. +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4309) // Truncation of constant value. +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::time_t; } +#endif + +namespace boost { namespace iostreams { + +namespace gzip { + +using namespace boost::iostreams::zlib; + + // Error codes used by gzip_error. + +const int zlib_error = 1; +const int bad_crc = 2; // Recorded crc doesn't match data. +const int bad_length = 3; // Recorded length doesn't match data. +const int bad_header = 4; // Malformed header. +const int bad_footer = 5; // Malformed footer. + +namespace magic { + + // Magic numbers used by gzip header. + +const int id1 = 0x1f; +const int id2 = 0x8b; + +} // End namespace magic. + +namespace method { + + // Codes used for the 'CM' byte of the gzip header. + +const int deflate = 8; + +} // End namespace method. + +namespace flags { + + // Codes used for the 'FLG' byte of the gzip header. + +const int text = 1; +const int header_crc = 2; +const int extra = 4; +const int name = 8; +const int comment = 16; + +} // End namespace flags. + +namespace extra_flags { + + // Codes used for the 'XFL' byte of the gzip header. + +const int best_compression = 2; +const int best_speed = 4; + +} // End namespace extra_flags. + + // Codes used for the 'OS' byte of the gzip header. + +const int os_fat = 0; +const int os_amiga = 1; +const int os_vms = 2; +const int os_unix = 3; +const int os_vm_cms = 4; +const int os_atari = 5; +const int os_hpfs = 6; +const int os_macintosh = 7; +const int os_z_system = 8; +const int os_cp_m = 9; +const int os_tops_20 = 10; +const int os_ntfs = 11; +const int os_qdos = 12; +const int os_acorn = 13; +const int os_unknown = 255; + +} // End namespace gzip. + +// +// Class name: gzip_params. +// Description: Subclass of zlib_params with an additional field +// representing a file name. +// +struct gzip_params : zlib_params { + + // Non-explicit constructor. + gzip_params( int level = gzip::default_compression, + int method = gzip::deflated, + int window_bits = gzip::default_window_bits, + int mem_level = gzip::default_mem_level, + int strategy = gzip::default_strategy, + std::string file_name = "", + std::string comment = "", + std::time_t mtime = 0 ) + : zlib_params(level, method, window_bits, mem_level, strategy), + file_name(file_name), comment(comment), mtime(mtime) + { } + std::string file_name; + std::string comment; + std::time_t mtime; +}; + +// +// Class name: gzip_error. +// Description: Subclass of std::ios_base::failure thrown to indicate +// zlib errors other than out-of-memory conditions. +// +class gzip_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit gzip_error(int error) + : BOOST_IOSTREAMS_FAILURE("gzip error"), + error_(error), zlib_error_code_(zlib::okay) { } + explicit gzip_error(const zlib_error& e) + : BOOST_IOSTREAMS_FAILURE("gzip error"), + error_(gzip::zlib_error), zlib_error_code_(e.error()) + { } + int error() const { return error_; } + int zlib_error_code() const { return zlib_error_code_; } +private: + int error_; + int zlib_error_code_; +}; + +// +// Template name: gzip_compressor +// Description: Model of OutputFilter implementing compression in the +// gzip format. +// +template > +class basic_gzip_compressor : basic_zlib_compressor { +private: + typedef basic_zlib_compressor base_type; +public: + typedef char char_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + basic_gzip_compressor( const gzip_params& = gzip::default_compression, + int buffer_size = default_device_buffer_size ); + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + std::streamsize result = 0; + + // Read header. + if (!(flags_ & f_header_done)) + result += read_string(s, n, header_); + + // Read body. + if (!(flags_ & f_body_done)) { + + // Read from basic_zlib_filter. + std::streamsize amt = base_type::read(src, s + result, n - result); + if (amt != -1) { + result += amt; + if (amt < n - result) { // Double-check for EOF. + amt = base_type::read(src, s + result, n - result); + if (amt != -1) + result += amt; + } + } + if (amt == -1) + prepare_footer(); + } + + // Read footer. + if ((flags_ & f_body_done) != 0 && result < n) + result += read_string(s + result, n - result, footer_); + + return result != 0 ? result : -1; + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + if (!(flags_ & f_header_done)) { + std::streamsize amt = + static_cast(header_.size() - offset_); + offset_ += boost::iostreams::write(snk, header_.data() + offset_, amt); + if (offset_ == header_.size()) + flags_ |= f_header_done; + else + return 0; + } + return base_type::write(snk, s, n); + } + + template + void close(Sink& snk, BOOST_IOS::openmode m) + { + if (m == BOOST_IOS::out) { + try { + + // Close zlib compressor. + base_type::close(snk, BOOST_IOS::out); + + if (flags_ & f_header_done) { + + // Write final fields of gzip file format. + write_long(this->crc(), snk); + write_long(this->total_in(), snk); + } + + } catch (...) { + close_impl(); + throw; + } + close_impl(); + } else { + close_impl(); + } + } +private: + static gzip_params normalize_params(gzip_params p); + void prepare_footer(); + std::streamsize read_string(char* s, std::streamsize n, std::string& str); + + template + static void write_long(long n, Sink& next) + { + boost::iostreams::put(next, static_cast(0xFF & n)); + boost::iostreams::put(next, static_cast(0xFF & (n >> 8))); + boost::iostreams::put(next, static_cast(0xFF & (n >> 16))); + boost::iostreams::put(next, static_cast(0xFF & (n >> 24))); + } + + void close_impl() + { + #if BOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \ + BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) \ + /**/ + footer_.erase(0, std::string::npos); + #else + footer_.clear(); + #endif + offset_ = 0; + flags_ = 0; + } + + enum flag_type { + f_header_done = 1, + f_body_done = f_header_done << 1, + f_footer_done = f_body_done << 1 + }; + std::string header_; + std::string footer_; + std::size_t offset_; + int flags_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1) + +typedef basic_gzip_compressor<> gzip_compressor; + +// +// Template name: basic_gzip_decompressor +// Description: Model of InputFilter implementing compression in the +// gzip format. +// +template > +class basic_gzip_decompressor : basic_zlib_decompressor { +public: + typedef char char_type; + struct category + : multichar_input_filter_tag, + closable_tag + { }; + basic_gzip_decompressor( int window_bits = gzip::default_window_bits, + int buffer_size = default_device_buffer_size ); + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + if ((flags_ & f_header_read) == 0) { + non_blocking_adapter nb(src); + read_header(nb); + flags_ |= f_header_read; + } + + if ((flags_ & f_footer_read) != 0) + return -1; + + try { + std::streamsize result = 0; + std::streamsize amt; + if ((amt = base_type::read(src, s, n)) != -1) { + result += amt; + if (amt < n) { // Double check for EOF. + amt = base_type::read(src, s + result, n - result); + if (amt != -1) + result += amt; + } + } + if (amt == -1) { + non_blocking_adapter nb(src); + read_footer(nb); + flags_ |= f_footer_read; + } + return result; + } catch (const zlib_error& e) { + throw gzip_error(e); + } + } + + template + void close(Source& src) + { + try { + base_type::close(src, BOOST_IOS::in); + } catch (const zlib_error& e) { + flags_ = 0; + throw gzip_error(e); + } + flags_ = 0; + } + + std::string file_name() const { return file_name_; } + std::string comment() const { return comment_; } + bool text() const { return (flags_ & gzip::flags::text) != 0; } + int os() const { return os_; } + std::time_t mtime() const { return mtime_; } +private: + typedef basic_zlib_decompressor base_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char) traits_type; + static bool is_eof(int c) { return traits_type::eq_int_type(c, EOF); } + static gzip_params make_params(int window_bits); + + template + static uint8_t read_uint8(Source& src, int error) + { + int c; + if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK) + throw gzip_error(error); + return static_cast(traits_type::to_char_type(c)); + } + + template + static uint32_t read_uint32(Source& src, int error) + { + uint8_t b1 = read_uint8(src, error); + uint8_t b2 = read_uint8(src, error); + uint8_t b3 = read_uint8(src, error); + uint8_t b4 = read_uint8(src, error); + return b1 + (b2 << 8) + (b3 << 16) + (b4 << 24); + } + + template + std::string read_string(Source& src) + { + std::string result; + while (true) { + int c; + if (is_eof(c = boost::iostreams::get(src))) + throw gzip_error(gzip::bad_header); + else if (c == 0) + return result; + else + result += static_cast(c); + } + } + + template + void read_header(Source& src) // Source is non-blocking. + { + // Reset saved values. + #if BOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \ + BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) \ + /**/ + file_name_.erase(0, std::string::npos); + comment_.erase(0, std::string::npos); + #else + file_name_.clear(); + comment_.clear(); + #endif + os_ = gzip::os_unknown; + mtime_ = 0; + + int flags; + + // Read header, without checking header crc. + if ( boost::iostreams::get(src) != gzip::magic::id1 || // ID1. + boost::iostreams::get(src) != gzip::magic::id2 || // ID2. + is_eof(boost::iostreams::get(src)) || // CM. + is_eof(flags = boost::iostreams::get(src)) ) // FLG. + { + throw gzip_error(gzip::bad_header); + } + mtime_ = read_uint32(src, gzip::bad_header); // MTIME. + read_uint8(src, gzip::bad_header); // XFL. + os_ = read_uint8(src, gzip::bad_header); // OS. + if (flags & boost::iostreams::gzip::flags::text) + flags_ |= f_text; + + // Skip extra field. (From J. Halleaux; see note at top.) + if (flags & gzip::flags::extra) { + int length = + static_cast( + read_uint8(src, gzip::bad_header) + + (read_uint8(src, gzip::bad_header) << 8) + ); + // length is garbage if EOF but the loop below will quit anyway. + do { } + while (length-- != 0 && !is_eof(boost::iostreams::get(src))); + } + + if (flags & gzip::flags::name) // Read file name. + file_name_ = read_string(src); + if (flags & gzip::flags::comment) // Read comment. + comment_ = read_string(src); + if (flags & gzip::flags::header_crc) { // Skip header crc. + read_uint8(src, gzip::bad_header); + read_uint8(src, gzip::bad_header); + } + } + + template + void read_footer(Source& src) + { + typename base_type::string_type footer = + this->unconsumed_input(); + int c; + while (!is_eof(c = boost::iostreams::get(src))) + footer += c; + detail::range_adapter + rng(footer.begin(), footer.end()); + if (read_uint32(rng, gzip::bad_footer) != this->crc()) + throw gzip_error(gzip::bad_crc); + if (static_cast(read_uint32(rng, gzip::bad_footer)) != this->total_out()) + throw gzip_error(gzip::bad_length); + } + enum flag_type { + f_header_read = 1, + f_footer_read = f_header_read << 1, + f_text = f_footer_read << 1 + }; + std::string file_name_; + std::string comment_; + int os_; + std::time_t mtime_; + int flags_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1) + +typedef basic_gzip_decompressor<> gzip_decompressor; + +//------------------Implementation of gzip_compressor-------------------------// + +template +basic_gzip_compressor::basic_gzip_compressor + (const gzip_params& p, int buffer_size) + : base_type(normalize_params(p), buffer_size), + offset_(0), flags_(0) +{ + // Calculate gzip header. + bool has_name = !p.file_name.empty(); + bool has_comment = !p.comment.empty(); + + std::string::size_type length = + 10 + + (has_name ? p.file_name.size() + 1 : 0) + + (has_comment ? p.comment.size() + 1 : 0); + // + 2; // Header crc confuses gunzip. + int flags = + //gzip::flags::header_crc + + (has_name ? gzip::flags::name : 0) + + (has_comment ? gzip::flags::comment : 0); + int extra_flags = + ( p.level == zlib::best_compression ? + gzip::extra_flags::best_compression : + 0 ) + + ( p.level == zlib::best_speed ? + gzip::extra_flags::best_speed : + 0 ); + header_.reserve(length); + header_ += gzip::magic::id1; // ID1. + header_ += gzip::magic::id2; // ID2. + header_ += gzip::method::deflate; // CM. + header_ += static_cast(flags); // FLG. + header_ += static_cast(0xFF & p.mtime); // MTIME. + header_ += static_cast(0xFF & (p.mtime >> 8)); + header_ += static_cast(0xFF & (p.mtime >> 16)); + header_ += static_cast(0xFF & (p.mtime >> 24)); + header_ += static_cast(extra_flags); // XFL. + header_ += static_cast(gzip::os_unknown); // OS. + if (has_name) { + header_ += p.file_name; + header_ += '\0'; + } + if (has_comment) { + header_ += p.comment; + header_ += '\0'; + } +} + +template +gzip_params basic_gzip_compressor::normalize_params(gzip_params p) +{ + p.noheader = true; + p.calculate_crc = true; + return p; +} + +template +void basic_gzip_compressor::prepare_footer() +{ + boost::iostreams::back_insert_device out(footer_); + write_long(this->crc(), out); + write_long(this->total_in(), out); + flags_ |= f_body_done; + offset_ = 0; +} + +template +std::streamsize basic_gzip_compressor::read_string + (char* s, std::streamsize n, std::string& str) +{ + std::streamsize avail = + static_cast(str.size() - offset_); + std::streamsize amt = (std::min)(avail, n); + std::copy( str.data() + offset_, + str.data() + offset_ + amt, + s ); + offset_ += amt; + if ( !(flags_ & f_header_done) && + offset_ == static_cast(str.size()) ) + { + flags_ |= f_header_done; + } + return amt; +} + +//------------------Implementation of gzip_decompressor-----------------------// + +template +basic_gzip_decompressor::basic_gzip_decompressor + (int window_bits, int buffer_size) + : base_type(make_params(window_bits), buffer_size), + os_(gzip::os_unknown), mtime_(0), flags_(0) + { } + +template +gzip_params basic_gzip_decompressor::make_params(int window_bits) +{ + gzip_params p; + p.window_bits = window_bits; + p.noheader = true; + p.calculate_crc = true; + return p; +} + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/filter/line.hpp b/thirdparty/boost/iostreams/filter/line.hpp new file mode 100644 index 0000000..2955494 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/line.hpp @@ -0,0 +1,220 @@ +// (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) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // min. +#include +#include // allocator. +#include +#include // BOOST_STATIC_CONSTANT. +#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 paramters: +// Ch - The character type. +// Alloc - The allocator type. +// Description: Filter which processes data one line at a time. +// +template< typename Ch, + typename Alloc = + #if BOOST_WORKAROUND(__GNUC__, < 3) + typename std::basic_string::allocator_type + #else + std::allocator + #endif + > +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() : pos_(string_type::npos), state_(0) { } +public: + virtual ~basic_line_filter() { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + assert(!(state_ & f_write)); + state_ |= 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 test, 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; + assert(!(state_ & f_read)); + state_ |= 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 ((state_ & f_read) && which == BOOST_IOS::in) + close_impl(); + + if ((state_ & 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()) + 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_) + traits_type::newline(); + std::streamsize amt = static_cast(line.size()); + bool result = iostreams::write(snk, line.data(), amt) == amt; + if (result) + clear(); + return result; + } + + void close_impl() + { + clear(); + state_ = 0; + } + + void clear() + { + cur_line_.erase(); + pos_ = string_type::npos; + } + + enum flag_type { + f_read = 1, + f_write = f_read << 1 + }; + + string_type cur_line_; + typename string_type::size_type pos_; + int state_; +}; +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/thirdparty/boost/iostreams/filter/newline.hpp b/thirdparty/boost/iostreams/filter/newline.hpp new file mode 100644 index 0000000..4503e70 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/newline.hpp @@ -0,0 +1,441 @@ +// (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) && (_MSC_VER >= 1020) +# 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 + +// Must come last. +#include + +#define BOOST_IOSTREAMS_ASSERT_UNREACHABLE(val) \ + (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 != newline::posix && + target != newline::dos && + target != newline::mac ) + { + throw std::logic_error("bad flags"); + } + } + + template + int get(Source& src) + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + 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; + if ((d = iostreams::get(src)) == 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; + + 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 which) + { + typedef typename iostreams::category_of::type category; + 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_ & newline::platform_mask) { + case newline::posix: + return LF; + case newline::mac: + return CR; + case 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_ & newline::platform_mask) { + case newline::posix: + success = boost::iostreams::put(dest, LF); + break; + case newline::mac: + success = boost::iostreams::put(dest, CR); + break; + case newline::dos: + if ((flags_ & f_has_LF) != 0) { + if ((success = boost::iostreams::put(dest, LF))) + flags_ &= ~f_has_LF; + } else if (boost::iostreams::put(dest, CR)) { + if (!(success = boost::iostreams::put(dest, LF))) + 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 which) + { + 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() { throw 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/thirdparty/boost/iostreams/filter/regex.hpp b/thirdparty/boost/iostreams/filter/regex.hpp new file mode 100644 index 0000000..7fa3f64 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/regex.hpp @@ -0,0 +1,98 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/filter/stdio.hpp b/thirdparty/boost/iostreams/filter/stdio.hpp new file mode 100644 index 0000000..d4b92a4 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/stdio.hpp @@ -0,0 +1,84 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/filter/symmetric.hpp b/thirdparty/boost/iostreams/filter/symmetric.hpp new file mode 100644 index 0000000..132c2a6 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/symmetric.hpp @@ -0,0 +1,304 @@ +// (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 definitions of the class templates symmetric_filter, +// which models DualUseFilter based on a model of the Symmetric Filter. + +// +// Roughly, a Symmetric Filter is a class type with the following interface: +// +// struct symmetric_filter { +// typedef xxx char_type; +// +// bool filter( const char*& begin_in, const char* end_in, +// char*& begin_out, char* end_out, bool flush ) +// { +// // Consume as many characters as possible from the interval +// // [begin_in, end_in), without exhausting the output range +// // [begin_out, end_out). If flush is true, write as mush output +// // as possible. +// // A return value of true indicates that filter should be called +// // again. More precisely, if flush is false, a return value of +// // false indicates that the natural end of stream has been reached +// // and that all filtered data has been forwarded; if flush is +// // true, a return value of false indicates that all filtered data +// // has been forwarded. +// } +// void close() { /* Reset filter's state. */ } +// }; +// +// Symmetric Filter filters need not be CopyConstructable. +// + +#ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // allocator, auto_ptr. +#include // BOOST_DEDUCED_TYPENAME. +#include +#include // buffer size. +#include +#include +#include +#include +#include +#include // read, write. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +template< typename SymmetricFilter, + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +class symmetric_filter { +public: + typedef typename char_type_of::type char_type; + typedef std::basic_string string_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + + // Expands to a sequence of ctors which forward to impl. + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \ + explicit symmetric_filter( \ + int buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \ + : pimpl_(new impl(buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n, t))) \ + { } \ + /**/ + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) + #include BOOST_PP_LOCAL_ITERATE() + #undef BOOST_PP_LOCAL_MACRO + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + if (!(state() & f_read)) + begin_read(); + + buffer_type& buf = pimpl_->buf_; + int status = (state() & f_eof) != 0 ? f_eof : f_good; + char_type *next_s = s, + *end_s = s + n; + while (true) + { + // Invoke filter if there are unconsumed characters in buffer or if + // filter must be flushed. + bool flush = status == f_eof; + if (buf.ptr() != buf.eptr() || flush) { + const char_type* next = buf.ptr(); + bool done = + !filter().filter(next, buf.eptr(), next_s, end_s, flush); + buf.ptr() = buf.data() + (next - buf.data()); + if (done) + return detail::check_eof( + static_cast(next_s - s) + ); + } + + // If no more characters are available without blocking, or + // if read request has been satisfied, return. + if ( status == f_would_block && buf.ptr() == buf.eptr() || + next_s == end_s ) + { + return static_cast(next_s - s); + } + + // Fill buffer. + if (status == f_good) + status = fill(src); + } + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + if (!(state() & f_write)) + begin_write(); + + buffer_type& buf = pimpl_->buf_; + const char_type *next_s, *end_s; + for (next_s = s, end_s = s + n; next_s != end_s; ) { + if (buf.ptr() == buf.eptr() && !flush(snk)) + break; + filter().filter(next_s, end_s, buf.ptr(), buf.eptr(), false); + } + return static_cast(next_s - s); + } + + template + void close(Sink& snk, BOOST_IOS::openmode which) + { + if ((state() & f_write) != 0) { + + // Repeatedly invoke filter() with no input. + try { + buffer_type& buf = pimpl_->buf_; + char dummy; + const char* end = &dummy; + bool again = true; + while (again) { + if (buf.ptr() != buf.eptr()) + again = filter().filter( end, end, buf.ptr(), + buf.eptr(), true ); + flush(snk); + } + } catch (...) { + try { close_impl(); } catch (...) { } + throw; + } + close_impl(); + } else { + close_impl(); + } + } + SymmetricFilter& filter() { return *pimpl_; } + string_type unconsumed_input() const; + +// Give impl access to buffer_type on Tru64 +#if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + private: +#endif + typedef detail::buffer buffer_type; +private: + buffer_type& buf() { return pimpl_->buf_; } + const buffer_type& buf() const { return pimpl_->buf_; } + int& state() { return pimpl_->state_; } + void begin_read(); + void begin_write(); + + template + int fill(Source& src) + { + std::streamsize amt = iostreams::read(src, buf().data(), buf().size()); + if (amt == -1) { + state() |= f_eof; + return f_eof; + } + buf().set(0, amt); + return amt == buf().size() ? f_good : f_would_block; + } + + // Attempts to write the contents of the buffer the given Sink. + // Returns true if at least on character was written. + template + bool flush(Sink& snk) + { + typedef typename iostreams::category_of::type category; + typedef is_convertible can_write; + return flush(snk, can_write()); + } + + template + bool flush(Sink& snk, mpl::true_) + { + typedef char_traits traits_type; + std::streamsize amt = + static_cast(buf().ptr() - buf().data()); + std::streamsize result = + boost::iostreams::write(snk, buf().data(), amt); + if (result < amt && result > 0) + traits_type::move(buf().data(), buf().data() + result, amt - result); + buf().set(amt - result, buf().size()); + return result != 0; + } + + template + bool flush(Sink&, mpl::false_) { return true;} + + void close_impl(); + + enum flag_type { + f_read = 1, + f_write = f_read << 1, + f_eof = f_write << 1, + f_good, + f_would_block + }; + + struct impl : SymmetricFilter { + + // Expands to a sequence of ctors which forward to SymmetricFilter. + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \ + impl( int buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \ + : SymmetricFilter(BOOST_PP_ENUM_PARAMS(n, t)), \ + buf_(buffer_size), state_(0) \ + { } \ + /**/ + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) + #include BOOST_PP_LOCAL_ITERATE() + #undef BOOST_PP_LOCAL_MACRO + + buffer_type buf_; + int state_; + }; + + shared_ptr pimpl_; +}; +BOOST_IOSTREAMS_PIPABLE(symmetric_filter, 2) + +//------------------Implementation of symmetric_filter----------------// + +template +void symmetric_filter::begin_read() +{ + assert(!(state() & f_write)); + state() |= f_read; + buf().set(0, 0); +} + +template +void symmetric_filter::begin_write() +{ + assert(!(state() & f_read)); + state() |= f_write; + buf().set(0, buf().size()); +} + +template +void symmetric_filter::close_impl() +{ + state() = 0; + buf().set(0, 0); + filter().close(); +} + +template +typename symmetric_filter::string_type +symmetric_filter::unconsumed_input() const +{ return string_type(buf().ptr(), buf().eptr()); } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/filter/test.hpp b/thirdparty/boost/iostreams/filter/test.hpp new file mode 100644 index 0000000..c54abf3 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/test.hpp @@ -0,0 +1,278 @@ +// (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) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC,put size_t in std. +#include +#include // min. +#include // size_t. +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || \ + BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ +# include // rand. +#endif +#include // memcpy, strlen. +#include +#include +#include +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \ + !BOOST_WORKAROUND(__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_MSVC, <= 1300) || \ + BOOST_WORKAROUND(__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_MSVC, <= 1300) && \ + !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ + std::streamsize rand(int inc) + { + static rand48 random_gen; + static uniform_smallint random_dist(0, inc); + return random_dist(random_gen); + } +#else + std::streamsize rand(int 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) + { + if (pos_ == static_cast(data_.size())) + return -1; + std::streamsize avail = + (std::min) (n, static_cast(data_.size() - pos_)); + std::streamsize amt = (std::min) (rand(inc_), avail); + if (amt) + std::memcpy(s, data_.c_str() + pos_, amt); + pos_ += amt; + return amt; + } + + bool putback(char c) + { + if (pos_ > 0) { + data_[--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; + } + 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/thirdparty/boost/iostreams/filter/zlib.hpp b/thirdparty/boost/iostreams/filter/zlib.hpp new file mode 100644 index 0000000..ca24686 --- /dev/null +++ b/thirdparty/boost/iostreams/filter/zlib.hpp @@ -0,0 +1,416 @@ +// (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: custom allocators are not supported on VC6, since that compiler +// had trouble finding the function zlib_base::do_init. + +#ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED +#define BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // streamsize. +#include // allocator, bad_alloc. +#include +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include +#include // buffer size. +#include +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4231 4660) // Dependencies not exported. +#endif +#include + +namespace boost { namespace iostreams { + +namespace zlib { + // Typedefs + +typedef unsigned int uint; +typedef unsigned char byte; +typedef unsigned long ulong; + +typedef void* (*alloc_func)(void*, zlib::uint, zlib::uint); +typedef void (*free_func)(void*, void*); + + // Compression levels + +BOOST_IOSTREAMS_DECL extern const int no_compression; +BOOST_IOSTREAMS_DECL extern const int best_speed; +BOOST_IOSTREAMS_DECL extern const int best_compression; +BOOST_IOSTREAMS_DECL extern const int default_compression; + + // Compression methods + +BOOST_IOSTREAMS_DECL extern const int deflated; + + // Compression strategies + +BOOST_IOSTREAMS_DECL extern const int default_strategy; +BOOST_IOSTREAMS_DECL extern const int filtered; +BOOST_IOSTREAMS_DECL extern const int huffman_only; + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int okay; +BOOST_IOSTREAMS_DECL extern const int stream_end; +BOOST_IOSTREAMS_DECL extern const int stream_error; +BOOST_IOSTREAMS_DECL extern const int version_error; +BOOST_IOSTREAMS_DECL extern const int data_error; +BOOST_IOSTREAMS_DECL extern const int mem_error; +BOOST_IOSTREAMS_DECL extern const int buf_error; + + // Flush codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int no_flush; +BOOST_IOSTREAMS_DECL extern const int sync_flush; + + // Code for current OS + +//BOOST_IOSTREAMS_DECL extern const int os_code; + + // Null pointer constant. + +const int null = 0; + + // Default values + +const int default_window_bits = 15; +const int default_mem_level = 8; +const bool default_crc = false; +const bool default_noheader = false; + +} // End namespace zlib. + +// +// Class name: zlib_params. +// Description: Encapsulates the parameters passed to deflateInit2 +// and inflateInit2 to customize compression and decompression. +// +struct zlib_params { + + // Non-explicit constructor. + zlib_params( int level = zlib::default_compression, + int method = zlib::deflated, + int window_bits = zlib::default_window_bits, + int mem_level = zlib::default_mem_level, + int strategy = zlib::default_strategy, + bool noheader = zlib::default_noheader, + bool calculate_crc = zlib::default_crc ) + : level(level), method(method), window_bits(window_bits), + mem_level(mem_level), strategy(strategy), + noheader(noheader), calculate_crc(calculate_crc) + { } + int level; + int method; + int window_bits; + int mem_level; + int strategy; + bool noheader; + bool calculate_crc; +}; + +// +// Class name: zlib_error. +// Description: Subclass of std::ios::failure thrown to indicate +// zlib errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL zlib_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit zlib_error(int error); + int error() const { return error_; } + static void check(int error); +private: + int error_; +}; + +namespace detail { + +template +struct zlib_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR + typedef typename Alloc::template rebind::other type; +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME zlib_allocator_traits::type > +struct zlib_allocator : private Base { +private: + typedef typename Base::size_type size_type; +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename zlib_allocator_traits::type allocator_type; + static void* allocate(void* self, zlib::uint items, zlib::uint size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL zlib_base { +public: + typedef char char_type; +protected: + zlib_base(); + ~zlib_base(); + void* stream() { return stream_; } + template + void init( const zlib_params& p, + bool compress, + zlib_allocator& zalloc ) + { + bool custom = zlib_allocator::custom; + do_init( p, compress, + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + custom ? zlib_allocator::allocate : 0, + custom ? zlib_allocator::deallocate : 0, + #endif + &zalloc ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after( const char*& src_begin, char*& dest_begin, + bool compress ); + int deflate(int flush); + int inflate(int flush); + void reset(bool compress, bool realloc); +public: + zlib::ulong crc() const { return crc_; } + int total_in() const { return total_in_; } + int total_out() const { return total_out_; } +private: + void do_init( const zlib_params& p, bool compress, + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + zlib::alloc_func, + zlib::free_func, + #endif + void* derived ); + void* stream_; // Actual type: z_stream*. + bool calculate_crc_; + zlib::ulong crc_; + int total_in_; + int total_out_; +}; + +// +// Template name: zlib_compressor_impl +// Description: Model of C-Style Filte implementing compression by +// delegating to the zlib function deflate. +// +template > +class zlib_compressor_impl : public zlib_base, public zlib_allocator { +public: + zlib_compressor_impl(const zlib_params& = zlib::default_compression); + ~zlib_compressor_impl(); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +}; + +// +// Template name: zlib_compressor +// Description: Model of C-Style Filte implementing decompression by +// delegating to the zlib function inflate. +// +template > +class zlib_decompressor_impl : public zlib_base, public zlib_allocator { +public: + zlib_decompressor_impl(const zlib_params&); + zlib_decompressor_impl(int window_bits = zlib::default_window_bits); + ~zlib_decompressor_impl(); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); +}; + +} // End namespace detail. + +// +// Template name: zlib_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using zlib. +// +template > +struct basic_zlib_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zlib_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zlib_compressor( const zlib_params& = zlib::default_compression, + int buffer_size = default_device_buffer_size ); + zlib::ulong crc() { return this->filter().crc(); } + int total_in() { return this->filter().total_in(); } +}; +BOOST_IOSTREAMS_PIPABLE(basic_zlib_compressor, 1) + +typedef basic_zlib_compressor<> zlib_compressor; + +// +// Template name: zlib_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using zlib. +// +template > +struct basic_zlib_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zlib_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zlib_decompressor( int window_bits = zlib::default_window_bits, + int buffer_size = default_device_buffer_size ); + basic_zlib_decompressor( const zlib_params& p, + int buffer_size = default_device_buffer_size ); + zlib::ulong crc() { return this->filter().crc(); } + int total_out() { return this->filter().total_out(); } +}; +BOOST_IOSTREAMS_PIPABLE(basic_zlib_decompressor, 1) + +typedef basic_zlib_decompressor<> zlib_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of zlib_allocator--------------------------// + +namespace detail { + +template +void* zlib_allocator::allocate + (void* self, zlib::uint items, zlib::uint size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void zlib_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of zlib_compressor_impl--------------------// + +template +zlib_compressor_impl::zlib_compressor_impl(const zlib_params& p) +{ init(p, true, static_cast&>(*this)); } + +template +zlib_compressor_impl::~zlib_compressor_impl() +{ reset(true, false); } + +template +bool zlib_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = deflate(flush ? zlib::finish : zlib::no_flush); + after(src_begin, dest_begin, true); + zlib_error::check(result); + return result != zlib::stream_end; +} + +template +void zlib_compressor_impl::close() { reset(true, true); } + +//------------------Implementation of zlib_decompressor_impl------------------// + +template +zlib_decompressor_impl::zlib_decompressor_impl(const zlib_params& p) +{ init(p, false, static_cast&>(*this)); } + +template +zlib_decompressor_impl::~zlib_decompressor_impl() +{ reset(false, false); } + +template +zlib_decompressor_impl::zlib_decompressor_impl(int window_bits) +{ + zlib_params p; + p.window_bits = window_bits; + init(p, false, static_cast&>(*this)); +} + +template +bool zlib_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool /* flush */ ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = inflate(zlib::sync_flush); + after(src_begin, dest_begin, false); + zlib_error::check(result); + return result != zlib::stream_end; +} + +template +void zlib_decompressor_impl::close() { reset(false, true); } + +} // End namespace detail. + +//------------------Implementation of zlib_decompressor-----------------------// + +template +basic_zlib_compressor::basic_zlib_compressor + (const zlib_params& p, int buffer_size) + : base_type(buffer_size, p) { } + +//------------------Implementation of zlib_decompressor-----------------------// + +template +basic_zlib_decompressor::basic_zlib_decompressor + (int window_bits, int buffer_size) + : base_type(buffer_size, window_bits) { } + +template +basic_zlib_decompressor::basic_zlib_decompressor + (const zlib_params& p, int buffer_size) + : base_type(buffer_size, p) { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/filtering_stream.hpp b/thirdparty/boost/iostreams/filtering_stream.hpp new file mode 100644 index 0000000..f71969c --- /dev/null +++ b/thirdparty/boost/iostreams/filtering_stream.hpp @@ -0,0 +1,166 @@ +// (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) && (_MSC_VER >= 1020) +# 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; +}; + +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_; +}; + +} // 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()); } \ + }; \ + /**/ +BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char) +BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(wfiltering_stream, boost::iostreams::chain, wchar_t) + +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/thirdparty/boost/iostreams/filtering_streambuf.hpp b/thirdparty/boost/iostreams/filtering_streambuf.hpp new file mode 100644 index 0000000..08d97fe --- /dev/null +++ b/thirdparty/boost/iostreams/filtering_streambuf.hpp @@ -0,0 +1,70 @@ +// (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) && (_MSC_VER >= 1020) +# 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/thirdparty/boost/iostreams/flush.hpp b/thirdparty/boost/iostreams/flush.hpp new file mode 100644 index 0000000..2f2849e --- /dev/null +++ b/thirdparty/boost/iostreams/flush.hpp @@ -0,0 +1,125 @@ +// (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_FLUSH_HPP_INCLUDED +#define BOOST_IOSTREAMS_FLUSH_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct flush_device_impl; + +template +struct flush_filter_impl; + +} // End namespace detail. + +template +bool flush(T& t) +{ return detail::flush_device_impl::flush(detail::unwrap(t)); } + +template +bool flush(T& t, Sink& snk) +{ return detail::flush_filter_impl::flush(detail::unwrap(t), snk); } + +namespace detail { + +//------------------Definition of flush_device_impl---------------------------// + +template +struct flush_device_impl + : mpl::if_< + is_custom, + operations, + flush_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, ostream_tag, streambuf_tag, flushable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) + { return t.rdbuf()->BOOST_IOSTREAMS_PUBSYNC() == 0; } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) + { return t.BOOST_IOSTREAMS_PUBSYNC() == 0; } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) { return t.flush(); } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T&) { return true; } +}; + +//------------------Definition of flush_filter_impl---------------------------// + +template +struct flush_filter_impl + : mpl::if_< + is_custom, + operations, + flush_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, flushable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct flush_filter_impl { + template + static bool flush(T& t, Sink& snk) { return t.flush(snk); } +}; + +template<> +struct flush_filter_impl { + template + static bool flush(T&, Sink&) { return false; } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_FLUSH_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/get.hpp b/thirdparty/boost/iostreams/get.hpp new file mode 100644 index 0000000..c6efbc3 --- /dev/null +++ b/thirdparty/boost/iostreams/get.hpp @@ -0,0 +1,17 @@ +// (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_GET_HPP_INCLUDED +#define BOOST_IOSTREAMS_GET_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_GET_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/imbue.hpp b/thirdparty/boost/iostreams/imbue.hpp new file mode 100644 index 0000000..33c3261 --- /dev/null +++ b/thirdparty/boost/iostreams/imbue.hpp @@ -0,0 +1,82 @@ +// (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_IMBUE_HPP_INCLUDED +#define BOOST_IOSTREAMS_IMBUE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +// Implementation templates for simulated tag dispatch. +template +struct imbue_impl; + +} // End namespace detail. + +template +void imbue(T& t, const Locale& loc) +{ detail::imbue_impl::imbue(detail::unwrap(t), loc); } + +namespace detail { + +//------------------Definition of imbue_impl----------------------------------// + +template +struct imbue_impl + : mpl::if_< + is_custom, + operations, + imbue_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, streambuf_tag, localizable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct imbue_impl { + template + static void imbue(T&, const Locale&) { } +}; + +template<> +struct imbue_impl { + template + static void imbue(T& t, const Locale& loc) { t.pubimbue(loc); } +}; + +template<> +struct imbue_impl { + template + static void imbue(T& t, const Locale& loc) { t.imbue(loc); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_IMBUE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/input_sequence.hpp b/thirdparty/boost/iostreams/input_sequence.hpp new file mode 100644 index 0000000..c733646 --- /dev/null +++ b/thirdparty/boost/iostreams/input_sequence.hpp @@ -0,0 +1,72 @@ +// (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_INPUT_SEQUENCE_HPP_INCLUDED +#define BOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // pair. +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include // is_custom +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct input_sequence_impl; + +} // End namespace detail. + +template +inline std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* +> +input_sequence(T& t) +{ return detail::input_sequence_impl::input_sequence(t); } + +namespace detail { + +//------------------Definition of direct_impl-------------------------------// + +template +struct input_sequence_impl + : mpl::if_< + detail::is_custom, + operations, + input_sequence_impl + >::type + { }; + +template<> +struct input_sequence_impl { + template + static std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* + > + input_sequence(U& u) { return u.input_sequence(); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/invert.hpp b/thirdparty/boost/iostreams/invert.hpp new file mode 100644 index 0000000..da81f04 --- /dev/null +++ b/thirdparty/boost/iostreams/invert.hpp @@ -0,0 +1,166 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// Filter - A model of InputFilter or OutputFilter. +// Description: Generates an InputFilter from an OutputFilter or +// vice versa. +// +template +class inverse { +private: + 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* s, std::streamsize n) + { + typedef detail::counted_array_sink array_sink; + typedef composite filtered_array_sink; + + 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* s, std::streamsize n) + { + typedef detail::counted_array_source array_source; + typedef composite filtered_array_source; + + 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 paramters: +// 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/thirdparty/boost/iostreams/operations.hpp b/thirdparty/boost/iostreams/operations.hpp new file mode 100644 index 0000000..5c45c4c --- /dev/null +++ b/thirdparty/boost/iostreams/operations.hpp @@ -0,0 +1,26 @@ +// (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_OPERATIONS_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef BOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/operations_fwd.hpp b/thirdparty/boost/iostreams/operations_fwd.hpp new file mode 100644 index 0000000..6bbd161 --- /dev/null +++ b/thirdparty/boost/iostreams/operations_fwd.hpp @@ -0,0 +1,41 @@ +// (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_OPERATIONS_FWD_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +namespace boost { namespace iostreams { + +template +struct operations; + +namespace detail { + +struct custom_tag { }; + +template +struct is_custom + : mpl::not_< + is_base_and_derived< custom_tag, operations > + > + { }; + +} // End namespace detail. + +template +struct operations : detail::custom_tag { }; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED //--------------// diff --git a/thirdparty/boost/iostreams/optimal_buffer_size.hpp b/thirdparty/boost/iostreams/optimal_buffer_size.hpp new file mode 100644 index 0000000..585021a --- /dev/null +++ b/thirdparty/boost/iostreams/optimal_buffer_size.hpp @@ -0,0 +1,87 @@ +// (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_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include // constants. +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct optimal_buffer_size_impl; + +} // End namespace detail. + +template +std::streamsize optimal_buffer_size(const T& t) +{ + typedef detail::optimal_buffer_size_impl impl; + return impl::optimal_buffer_size(detail::unwrap(t)); +} + +namespace detail { + +//------------------Definition of optimal_buffer_size_impl--------------------// + +template +struct optimal_buffer_size_impl + : mpl::if_< + is_custom, + operations, + optimal_buffer_size_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, optimally_buffered_tag, device_tag, filter_tag + >::type + > + >::type + { }; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T& t) + { return t.optimal_buffer_size(); } +}; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T&) + { return default_device_buffer_size; } +}; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T&) + { return default_filter_buffer_size; } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/output_sequence.hpp b/thirdparty/boost/iostreams/output_sequence.hpp new file mode 100644 index 0000000..80ffebb --- /dev/null +++ b/thirdparty/boost/iostreams/output_sequence.hpp @@ -0,0 +1,72 @@ +// (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_OUTPUT_SEQUENCE_HPP_INCLUDED +#define BOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // pair. +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include // is_custom +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct output_sequence_impl; + +} // End namespace detail. + +template +inline std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* +> +output_sequence(T& t) +{ return detail::output_sequence_impl::output_sequence(t); } + +namespace detail { + +//------------------Definition of output_sequence_impl------------------------// + +template +struct output_sequence_impl + : mpl::if_< + detail::is_custom, + operations, + output_sequence_impl + >::type + { }; + +template<> +struct output_sequence_impl { + template + static std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* + > + output_sequence(U& u) { return u.output_sequence(); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/pipeline.hpp b/thirdparty/boost/iostreams/pipeline.hpp new file mode 100644 index 0000000..4636dc4 --- /dev/null +++ b/thirdparty/boost/iostreams/pipeline.hpp @@ -0,0 +1,128 @@ +// (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_PIPABLE_HPP_INCLUDED +#define BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include +#include +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +# include +#endif + +#define BOOST_IOSTREAMS_PIPABLE(filter, arity) \ + template< BOOST_PP_ENUM_PARAMS(arity, typename T) \ + BOOST_PP_COMMA_IF(arity) typename Component> \ + ::boost::iostreams::pipeline< \ + ::boost::iostreams::detail::pipeline_segment< \ + filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ + >, \ + Component \ + > operator|( const filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)& f, \ + const Component& c ) \ + { \ + typedef ::boost::iostreams::detail::pipeline_segment< \ + filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ + > segment; \ + return ::boost::iostreams::pipeline \ + (segment(f), c); \ + } \ + /**/ + +namespace boost { namespace iostreams { + +template +struct pipeline; + +namespace detail { + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + struct pipeline_base { }; + + template + struct is_pipeline + : is_base_and_derived + { }; +#endif +#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) + template + struct is_pipeline : mpl::false_ { }; + + template + struct is_pipeline< pipeline > : mpl::true_ { }; +#endif + +template +class pipeline_segment +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + : pipeline_base +#endif +{ +public: + pipeline_segment(const Component& component) + : component_(component) + { } + template + void for_each(Fn fn) const { fn(component_); } + template + void push(Chain& chn) const { chn.push(component_); } +private: + pipeline_segment operator=(const pipeline_segment&); + const Component& component_; +}; + +} // End namespace detail. + +//------------------Definition of Pipeline------------------------------------// + +template +struct pipeline : Pipeline { + typedef Pipeline pipeline_type; + typedef Component component_type; + pipeline(const Pipeline& p, const Component& component) + : Pipeline(p), component_(component) + { } + template + void for_each(Fn fn) const + { + Pipeline::for_each(fn); + fn(component_); + } + template + void push(Chain& chn) const + { + Pipeline::push(chn); + chn.push(component_); + } + const Pipeline& tail() const { return *this; } + const Component& head() const { return component_; } +private: + pipeline operator=(const pipeline&); + const Component& component_; +}; + +template +pipeline, Component> +operator|(const pipeline& p, const Component& cmp) +{ + BOOST_STATIC_ASSERT(is_filter::value); + return pipeline, Component>(p, cmp); +} + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/positioning.hpp b/thirdparty/boost/iostreams/positioning.hpp new file mode 100644 index 0000000..ade7189 --- /dev/null +++ b/thirdparty/boost/iostreams/positioning.hpp @@ -0,0 +1,115 @@ +// (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. + +// Thanks to Gareth Sylvester-Bradley for the Dinkumware versions of the +// positioning functions. + +#ifndef BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED +#define BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include // mbstate_t. +#include +#include // streamoff, streampos. + +// Must come last. +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::fpos_t; } +#endif + +namespace boost { namespace iostreams { + +//------------------Definition of stream_offset-------------------------------// + +typedef boost::intmax_t stream_offset; + +//------------------Definition of stream_offset_to_streamoff------------------// + +inline std::streamoff stream_offset_to_streamoff(stream_offset off) +{ return static_cast(off); } + +//------------------Definition of offset_to_position--------------------------// + +# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline std::streampos offset_to_position(stream_offset off) { return off; } + +# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline std::streampos offset_to_position(stream_offset off) +{ return std::streampos(std::mbstate_t(), off); } + +# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +//------------------Definition of position_to_offset--------------------------// + +// Hande custom pos_type's +template +inline stream_offset position_to_offset(PosType pos) +{ return std::streamoff(pos); } + +# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline stream_offset position_to_offset(std::streampos pos) { return pos; } + +# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +// In the Dinkumware standard library, a std::streampos consists of two stream +// offsets -- _Fpos, of type std::fpos_t, and _Myoff, of type std::streamoff -- +// together with a conversion state. A std::streampos is converted to a +// boost::iostreams::stream_offset by extracting the two stream offsets and +// summing them. The value of _Fpos can be extracted using the implementation- +// defined member functions seekpos() or get_fpos_t(), depending on the +// Dinkumware version. The value of _Myoff cannot be extracted directly, but can +// be calculated as the difference between the result of converting the +// std::fpos to a std::streamoff and the result of converting the member _Fpos +// to a long. The latter operation is accomplished with the macro _FPOSOFF, +// which works correctly on platforms where std::fpos_t is an integral type and +// platforms where it is a struct + +// Converts a std::fpos_t to a stream_offset +inline stream_offset fpos_t_to_offset(std::fpos_t pos) +{ +# if defined(_POSIX_) || (_INTEGRAL_MAX_BITS >= 64) || defined(__IBMCPP__) + return pos; +# else + return _FPOSOFF(pos); +# endif +} + +// Extracts the member _Fpos from a std::fpos +inline std::fpos_t streampos_to_fpos_t(std::streampos pos) +{ +# if defined (_CPPLIB_VER) || defined(__IBMCPP__) + return pos.seekpos(); +# else + return pos.get_fpos_t(); +# endif +} + +inline stream_offset position_to_offset(std::streampos pos) +{ + return fpos_t_to_offset(streampos_to_fpos_t(pos)) + + static_cast(static_cast(pos)) - + static_cast(_FPOSOFF(streampos_to_fpos_t(pos))); +} + +# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/put.hpp b/thirdparty/boost/iostreams/put.hpp new file mode 100644 index 0000000..4cdc65a --- /dev/null +++ b/thirdparty/boost/iostreams/put.hpp @@ -0,0 +1,17 @@ +// (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_PUT_HPP_INCLUDED +#define BOOST_IOSTREAMS_PUT_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_PUT_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/putback.hpp b/thirdparty/boost/iostreams/putback.hpp new file mode 100644 index 0000000..242440b --- /dev/null +++ b/thirdparty/boost/iostreams/putback.hpp @@ -0,0 +1,17 @@ +// (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_PUTBACK_HPP_INCLUDED +#define BOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/read.hpp b/thirdparty/boost/iostreams/read.hpp new file mode 100644 index 0000000..7656a1b --- /dev/null +++ b/thirdparty/boost/iostreams/read.hpp @@ -0,0 +1,247 @@ +// (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_READ_HPP_INCLUDED +#define BOOST_IOSTREAMS_READ_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // streamsize. +#include +#include +#include +#include + +// Must come last. +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------// +# include +#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------// + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct read_device_impl; + +template +struct read_filter_impl; + +} // End namespace detail. + +template +typename int_type_of::type get(T& t) +{ return detail::read_device_impl::get(detail::unwrap(t)); } + +template +inline std::streamsize +read(T& t, typename char_type_of::type* s, std::streamsize n) +{ return detail::read_device_impl::read(detail::unwrap(t), s, n); } + +template +std::streamsize +read(T& t, Source& src, typename char_type_of::type* s, std::streamsize n) +{ return detail::read_filter_impl::read(detail::unwrap(t), src, s, n); } + +template +bool putback(T& t, typename char_type_of::type c) +{ return detail::read_device_impl::putback(detail::unwrap(t), c); } + +//----------------------------------------------------------------------------// + +namespace detail { + +// Helper function for adding -1 as EOF indicator. +inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; } + +// Helper templates for reading from streambufs. +template +struct true_eof_impl; + +template<> +struct true_eof_impl { + template + static bool true_eof(T& t) { return t.true_eof(); } +}; + +template<> +struct true_eof_impl { + template + static bool true_eof(T&) { return true; } +}; + +template +inline bool true_eof(T& t) +{ + const bool linked = is_linked::value; + return true_eof_impl::true_eof(t); +} + +//------------------Definition of read_device_impl----------------------------// + +template +struct read_device_impl + : mpl::if_< + detail::is_custom, + operations, + read_device_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, istream_tag, streambuf_tag, input + >::type + > + >::type + { }; + +template<> +struct read_device_impl { + template + static typename int_type_of::type get(T& t) + { return t.get(); } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return check_eof(t.rdbuf()->sgetn(s, n)); } + + template + static bool putback(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c), + traits_type::eof() ); + } +}; + +template<> +struct read_device_impl { + template + static typename int_type_of::type + get(T& t) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + typename int_type_of::type c; + return !traits_type::is_eof(c = t.sbumpc()) || + detail::true_eof(t) + ? + c : traits_type::would_block(); + } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { + std::streamsize amt; + return (amt = t.sgetn(s, n)) != 0 ? + amt : + detail::true_eof(t) ? + -1 : + 0; + } + + template + static bool putback(T& t, typename char_type_of::type c) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + return !traits_type::is_eof(t.sputbackc(c)); + } +}; + +template<> +struct read_device_impl { + template + static typename int_type_of::type + get(T& t) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + char_type c; + std::streamsize amt; + return (amt = t.read(&c, 1)) == 1 ? + traits_type::to_int_type(c) : + amt == -1 ? + traits_type::eof() : + traits_type::would_block(); + } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return t.read(s, n); } + + template + static bool putback(T& t, typename char_type_of::type c) + { // T must be Peekable. + return t.putback(c); + } +}; + +//------------------Definition of read_filter_impl----------------------------// + +template +struct read_filter_impl + : mpl::if_< + detail::is_custom, + operations, + read_filter_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct read_filter_impl { + template + static std::streamsize read + (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) + { return t.read(src, s, n); } +}; + +template<> +struct read_filter_impl { + template + static std::streamsize read + (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + for (std::streamsize off = 0; off < n; ++off) { + typename traits_type::int_type c = t.get(src); + if (traits_type::is_eof(c)) + return check_eof(off); + if (traits_type::would_block(c)) + return off; + s[off] = traits_type::to_char_type(c); + } + return n; + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------// + +#include + +#endif // #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/restrict.hpp b/thirdparty/boost/iostreams/restrict.hpp new file mode 100644 index 0000000..b456829 --- /dev/null +++ b/thirdparty/boost/iostreams/restrict.hpp @@ -0,0 +1,26 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(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/thirdparty/boost/iostreams/seek.hpp b/thirdparty/boost/iostreams/seek.hpp new file mode 100644 index 0000000..7d5bc9f --- /dev/null +++ b/thirdparty/boost/iostreams/seek.hpp @@ -0,0 +1,180 @@ +// (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_SEEK_HPP_INCLUDED +#define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include // streamsize, seekdir, openmode. +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct seek_device_impl; + +template +struct seek_filter_impl; + +} // End namespace detail. + +template +inline std::streampos +seek( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + return seek_device_impl::seek(detail::unwrap(t), off, way, which); +} + +template +inline std::streampos +seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + return seek_filter_impl::seek(detail::unwrap(t), dev, off, way, which); +} + +namespace detail { + +//------------------Definition of seek_device_impl----------------------------// + +template +struct seek_device_impl + : mpl::if_< + is_custom, + operations, + seek_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, iostream_tag, istream_tag, ostream_tag, + streambuf_tag, two_head, any_tag + >::type + > + >::type + { }; + +struct seek_impl_basic_ios { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + if ( way == BOOST_IOS::beg && + ( off < integer_traits::const_min || + off > integer_traits::const_max ) ) + { + return t.rdbuf()->pubseekpos(offset_to_position(off)); + } else { + return t.rdbuf()->pubseekoff(off, way, which); + } + } +}; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + if ( way == BOOST_IOS::beg && + ( off < integer_traits::const_min || + off > integer_traits::const_max ) ) + { + return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off)); + } else { + return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which); + } + } +}; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return t.seek(off, way, which); } +}; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode ) + { return t.seek(off, way); } +}; + +//------------------Definition of seek_filter_impl----------------------------// + +template +struct seek_filter_impl + : mpl::if_< + is_custom, + operations, + seek_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch::type + > + >::type + { }; + +template<> +struct seek_filter_impl { + template + static std::streampos seek( T& t, Device& d, + stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return t.seek(d, off, way, which); } +}; + +template<> +struct seek_filter_impl { + template + static std::streampos seek( T& t, Device& d, + stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode ) + { return t.seek(d, off, way); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/skip.hpp b/thirdparty/boost/iostreams/skip.hpp new file mode 100644 index 0000000..2307d61 --- /dev/null +++ b/thirdparty/boost/iostreams/skip.hpp @@ -0,0 +1,111 @@ +// (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) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include // failure. +#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))) + throw 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) + throw 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/thirdparty/boost/iostreams/slice.hpp b/thirdparty/boost/iostreams/slice.hpp new file mode 100644 index 0000000..72c9db9 --- /dev/null +++ b/thirdparty/boost/iostreams/slice.hpp @@ -0,0 +1,28 @@ +/* + * Distributed under the Boost Software License, Version 1.0.(See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) + * + * 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/thirdparty/boost/iostreams/stream.hpp b/thirdparty/boost/iostreams/stream.hpp new file mode 100644 index 0000000..e849e47 --- /dev/null +++ b/thirdparty/boost/iostreams/stream.hpp @@ -0,0 +1,152 @@ +// (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_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_STREAM_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include // standard streams. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct stream_traits { + typedef typename char_type_of::type char_type; + typedef Tr traits_type; + typedef typename category_of::type mode; + typedef typename + iostreams::select< // Dismbiguation required for Tru64. + mpl::and_< + is_convertible, + is_convertible + >, + BOOST_IOSTREAMS_BASIC_IOSTREAM(char_type, traits_type), + is_convertible, + BOOST_IOSTREAMS_BASIC_ISTREAM(char_type, traits_type), + else_, + BOOST_IOSTREAMS_BASIC_OSTREAM(char_type, traits_type) + >::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; +}; + +// By encapsulating initialization in a base, we can define the macro +// BOOST_IOSTREAMS_DEFINE_FORWARDING_FUNCTIONS to generate constuctors +// without base member initializer lists. +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Base = // VC6 Workaround. + BOOST_DEDUCED_TYPENAME + detail::stream_traits::stream_type > +class stream_base + : protected base_from_member< stream_buffer >, + public Base +{ +private: + typedef base_from_member< stream_buffer > pbase_type; + typedef typename stream_traits::stream_type stream_type; +protected: + using pbase_type::member; // Avoid warning about 'this' in initializer list. +public: + stream_base() : pbase_type(), stream_type(&member) { } +}; + +} } } // End namespaces detail, iostreams, boost. + +#ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# include +#else + +namespace boost { namespace iostreams { + +// +// Template name: stream. +// Description: A iostream which reads from and writes to an instance of a +// designated device type. +// Template paramters: +// Device - A device type. +// Alloc - The allocator type. +// +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +struct stream : detail::stream_base { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, + closable_tag, + detail::stream_traits::stream_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename + detail::stream_traits< + Device, Tr + >::stream_type stream_type; + typedef Device policy_type; +public: + stream() { } + BOOST_IOSTREAMS_FORWARD( stream, open_impl, Device, + BOOST_IOSTREAMS_PUSH_PARAMS, + BOOST_IOSTREAMS_PUSH_ARGS ) + bool is_open() const { return this->member.is_open(); } + void close() { this->member.close(); } + bool auto_close() const { return this->member.auto_close(); } + void set_auto_close(bool close) { this->member.set_auto_close(close); } + bool strict_sync() { return this->member.strict_sync(); } + Device& operator*() { return *this->member; } + Device* operator->() { return &*this->member; } + Device* component() { return this->member.component(); } +private: + void open_impl(const Device& dev BOOST_IOSTREAMS_PUSH_PARAMS()) // For forwarding. + { + this->clear(); + this->member.open(dev BOOST_IOSTREAMS_PUSH_ARGS()); + } +}; + +} } // End namespaces iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION + +#endif // #ifndef BOOST_IOSTREAMS_stream_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/stream_buffer.hpp b/thirdparty/boost/iostreams/stream_buffer.hpp new file mode 100644 index 0000000..8c2ea83 --- /dev/null +++ b/thirdparty/boost/iostreams/stream_buffer.hpp @@ -0,0 +1,114 @@ +// (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_STREAM_BUFFER_HPP_INCLUDED +#define BOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // allocator. +#include // BOOST_DEDUCED_TYPENAME. +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +template +struct stream_buffer_traits { + typedef typename + mpl::if_< + is_convertible< + BOOST_DEDUCED_TYPENAME category_of::type, + direct_tag + >, + direct_streambuf, + indirect_streambuf + >::type type; +}; + +} } } // End namespaces detail, iostreams, boost + +#ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# include +#else + +namespace boost { namespace iostreams { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Mode = BOOST_DEDUCED_TYPENAME mode_of::type > +class stream_buffer + : public detail::stream_buffer_traits::type +{ +private: + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, Mode + >::value + )); + typedef typename + detail::stream_buffer_traits< + T, Tr, Alloc, Mode + >::type base_type; + typedef T policy_type; +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + closable_tag, + streambuf_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +public: + stream_buffer() { } + ~stream_buffer() + { + try { + if (this->is_open() && this->auto_close()) + this->close(); + } catch (...) { } + } + BOOST_IOSTREAMS_FORWARD( stream_buffer, open_impl, T, + BOOST_IOSTREAMS_PUSH_PARAMS, + BOOST_IOSTREAMS_PUSH_ARGS ) + T& operator*() { return *this->component(); } + T* operator->() { return this->component(); } +private: + void open_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) + { // Used for forwarding. + if (this->is_open()) + BOOST_IOSTREAMS_FAILURE("already open"); + base_type::open(t BOOST_IOSTREAMS_PUSH_ARGS()); + } +}; + +} } // End namespaces iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/tee.hpp b/thirdparty/boost/iostreams/tee.hpp new file mode 100644 index 0000000..0d8c36a --- /dev/null +++ b/thirdparty/boost/iostreams/tee.hpp @@ -0,0 +1,173 @@ +// (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) && (_MSC_VER >= 1020) +# 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 paramters: +// 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 + : multichar_output_filter_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + + 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 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. + assert(result == result2); + return result; + } + + template + void close(Next&) + { + 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 paramters: +// Sink1 - A blocking Sink. +// Sink2 - A blocking Sink. +// +template +class tee_device { +public: + typedef typename detail::param_type::type param_type1; + typedef typename detail::param_type::type param_type2; + typedef typename detail::value_type::type value_type1; + typedef typename detail::value_type::type value_type2; + typedef typename char_type_of::type char_type; + BOOST_STATIC_ASSERT(( + is_same< + char_type, + BOOST_DEDUCED_TYPENAME char_type_of::type + >::value + )); + BOOST_STATIC_ASSERT(( + is_convertible< // Using mode_of causes failures on VC6-7.0. + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output + >::value + )); + BOOST_STATIC_ASSERT(( + is_convertible< // Using mode_of causes failures on VC6-7.0. + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output + >::value + )); + struct category + : output, + device_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + tee_device(param_type1 sink1, param_type2 sink2) + : sink1_(sink1), sink2_(sink2) + { } + std::streamsize write(const char_type* s, std::streamsize n) + { + std::streamsize result1 = iostreams::write(sink1_, s, n); + std::streamsize result2 = iostreams::write(sink2_, s, n); + (void) result1; // Suppress 'unused variable' warning. + (void) result2; + assert(result1 == n && result2 == n); + return n; + } + void close() + { + detail::execute_all( detail::call_close_all(sink1_), + detail::call_close_all(sink2_) ); + } + bool flush() + { + bool r1 = iostreams::flush(sink1_); + bool r2 = iostreams::flush(sink2_); + return r1 && r2; + } + template + void imbue(const Locale& loc) + { + iostreams::imbue(sink1_, loc); + iostreams::imbue(sink2_, loc); + } + std::streamsize optimal_buffer_size() const + { + return (std::max) ( iostreams::optimal_buffer_size(sink1_), + iostreams::optimal_buffer_size(sink2_) ); + } +private: + value_type1 sink1_; + value_type2 sink2_; +}; + +template +tee_filter tee(const Sink& snk) +{ return tee_filter(snk); } + +template +tee_device tee(const Sink1& sink1, const Sink2& sink2) +{ return tee_device(sink1, sink2); } + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/traits.hpp b/thirdparty/boost/iostreams/traits.hpp new file mode 100644 index 0000000..47a584d --- /dev/null +++ b/thirdparty/boost/iostreams/traits.hpp @@ -0,0 +1,364 @@ +// (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 metafunctions char_type_of, category_of and mode_of used for +// deducing the i/o category and i/o mode of a model of Filter or Device. +// +// Also contains several utility metafunctions, functions and macros. +// + +#ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // stream types, char_traits. +#include // partial spec, deduced typename. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# include +# include +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +#include + +namespace boost { namespace iostreams { + +//----------Definitions of predicates for streams and stream buffers----------// + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3) + +#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0) + +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------// + +template +struct is_std_io + : mpl::or_< is_istream, is_ostream, is_streambuf > + { }; + +template +struct is_std_file_device + : mpl::or_< + is_ifstream, + is_ofstream, + is_fstream, + is_filebuf + > + { }; + +template +struct is_std_string_device + : mpl::or_< + is_istringstream, + is_ostringstream, + is_stringstream, + is_stringbuf + > + { }; + +template +struct stream; + +template +class stream_buffer; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_stream; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class wfiltering_stream; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_streambuf; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_wstreambuf; + +namespace detail { + +template +class linked_streambuf; + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream, + boost::iostreams::stream, + 3 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer, + boost::iostreams::stream_buffer, + 4 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl, + boost::iostreams::filtering_stream, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl, + boost::iostreams::wfiltering_stream, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl, + boost::iostreams::filtering_streambuf, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl, + boost::iostreams::filtering_wstreambuf, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2) + +template +struct is_filtering_stream + : mpl::or_< + is_filtering_stream_impl, + is_filtering_wstream_impl + > + { }; + +template +struct is_filtering_streambuf + : mpl::or_< + is_filtering_streambuf_impl, + is_filtering_wstreambuf_impl + > + { }; + +template +struct is_boost + : mpl::or_< + is_boost_stream, + is_boost_stream_buffer, + is_filtering_stream, + is_filtering_streambuf + > + { }; + +} // End namespace detail. + +//------------------Definitions of char_type_of-------------------------------// + +namespace detail { + +template +struct member_char_type { typedef typename T::char_type type; }; + +} // End namespace detail. + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------// +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// + +template +struct char_type_of + : detail::member_char_type< + typename detail::unwrapped_type::type + > + { }; + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// + +template +struct char_type_of { + typedef typename detail::unwrapped_type::type U; + typedef typename + mpl::eval_if< + is_std_io, + mpl::identity, + detail::member_char_type + >::type type; +}; + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// + +template +struct char_type_of< iterator_range > { + typedef typename iterator_value::type type; +}; + +#else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------// + +template +struct char_type_of { + template + struct get_value_type { + #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename range_value::type type; + #endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + }; + typedef typename + mpl::eval_if< + is_iterator_range, + get_value_type, + detail::member_char_type< + BOOST_DEDUCED_TYPENAME detail::unwrapped_type::type + > + >::type type; +}; + +#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------// + +//------------------Definitions of category_of--------------------------------// + +namespace detail { + +template +struct member_category { typedef typename T::category type; }; + +} // End namespace detail. + +template +struct category_of { + template + struct member_category { + typedef typename U::category type; + }; + typedef typename detail::unwrapped_type::type U; + typedef typename + mpl::eval_if< + mpl::and_< + is_std_io, + mpl::not_< detail::is_boost > + >, + iostreams::select< // Disambiguation for Tru64 + is_filebuf, filebuf_tag, + is_ifstream, ifstream_tag, + is_ofstream, ofstream_tag, + is_fstream, fstream_tag, + is_stringbuf, stringbuf_tag, + is_istringstream, istringstream_tag, + is_ostringstream, ostringstream_tag, + is_stringstream, stringstream_tag, + is_streambuf, generic_streambuf_tag, + is_iostream, generic_iostream_tag, + is_istream, generic_istream_tag, + is_ostream, generic_ostream_tag + >, + detail::member_category + >::type type; +}; + +//------------------Definition of get_category--------------------------------// + +// +// Returns an object of type category_of::type. +// +template +inline typename category_of::type get_category(const T&) +{ typedef typename category_of::type category; return category(); } + +//------------------Definition of int_type_of---------------------------------// + +template +struct int_type_of { +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + typedef std::char_traits< + BOOST_DEDUCED_TYPENAME char_type_of::type + > traits_type; + typedef typename traits_type::int_type type; +#else + typedef int type; +#endif +}; + +//------------------Definition of mode----------------------------------------// + +namespace detail { + +template struct io_mode_impl; + +#define BOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \ + case_ io_mode_impl_helper(tag_); \ + template<> struct io_mode_impl { typedef tag_ type; }; \ + /**/ +BOOST_IOSTREAMS_MODE_HELPER(input, 1) +BOOST_IOSTREAMS_MODE_HELPER(output, 2) +BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3) +BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4) +BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5) +BOOST_IOSTREAMS_MODE_HELPER(seekable, 6) +BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7) +BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8) +BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9) +#undef BOOST_IOSTREAMS_MODE_HELPER + +template +struct io_mode_id { + typedef typename category_of::type category; + BOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category())); +}; + +} // End namespace detail. + +template // Borland 5.6.4 requires this circumlocution. +struct mode_of : detail::io_mode_impl< detail::io_mode_id::value > { }; + +//------------------Definition of is_device, is_filter and is_direct----------// + +namespace detail { + +template +struct has_trait_impl { + typedef typename category_of::type category; + BOOST_STATIC_CONSTANT(bool, value = (is_convertible::value)); +}; + +template +struct has_trait + : mpl::bool_::value> + { }; + +} // End namespace detail. + +template +struct is_device : detail::has_trait { }; + +template +struct is_filter : detail::has_trait { }; + +template +struct is_direct : detail::has_trait { }; + +//------------------Definition of BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------// + +#define BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ + typedef Tr traits_type; \ + typedef typename traits_type::int_type int_type; \ + typedef typename traits_type::off_type off_type; \ + typedef typename traits_type::pos_type pos_type; \ + /**/ + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/traits_fwd.hpp b/thirdparty/boost/iostreams/traits_fwd.hpp new file mode 100644 index 0000000..57ba5c2 --- /dev/null +++ b/thirdparty/boost/iostreams/traits_fwd.hpp @@ -0,0 +1,111 @@ +// (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. + +// Forward declarations of templates defined in traits.hpp. + +#ifndef BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED +#define BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // stream types, char_traits. + +namespace boost { namespace iostreams { + +template +struct is_istream; + +template +struct is_ostream; + +template +struct is_iostream; + +template +struct is_streambuf; + +template +struct is_istringstream; + +template +struct is_ostringstream; + +template +struct is_stringstream; + +template +struct is_stringbuf; + +template +struct is_ifstream; + +template +struct is_ofstream; + +template +struct is_fstream; + +template +struct is_filebuf; + +template +struct is_std_io; + +template +struct is_std_file_device; + +template +struct is_std_string_device; + +template +struct char_type_of; + +template +struct category_of; + +template +struct int_type_of; + +template +struct mode_of; + +template +struct is_device; + +template +struct is_filter; + +template +struct is_direct; + +namespace detail { + +template +struct is_boost_stream; + +template +struct is_boost_stream_buffer; + +template +struct is_filtering_stream; + +template +struct is_filtering_streambuf; + +template +struct is_linked; + +template +struct is_boost; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED diff --git a/thirdparty/boost/iostreams/write.hpp b/thirdparty/boost/iostreams/write.hpp new file mode 100644 index 0000000..6097e5e --- /dev/null +++ b/thirdparty/boost/iostreams/write.hpp @@ -0,0 +1,171 @@ +// (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_WRITE_HPP_INCLUDED +#define BOOST_IOSTREAMS_WRITE_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // streamsize. +#include +#include +#include +#include +#include + +// Must come last. +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------// +# include +#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------// + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct write_device_impl; + +template +struct write_filter_impl; + +} // End namespace detail. + +template +bool put(T& t, typename char_type_of::type c) +{ return detail::write_device_impl::put(detail::unwrap(t), c); } + +template +inline std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) +{ return detail::write_device_impl::write(detail::unwrap(t), s, n); } + +template +inline std::streamsize +write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) +{ return detail::write_filter_impl::write(detail::unwrap(t), snk, s, n); } + +namespace detail { + +//------------------Definition of write_device_impl---------------------------// + +template +struct write_device_impl + : mpl::if_< + is_custom, + operations, + write_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, ostream_tag, streambuf_tag, output + >::type + > + >::type + { }; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->s.sputc(), + traits_type::eof() ); + } + + template + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.rdbuf()->sputn(s, n); } +}; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type(t.sputc(c), traits_type::eof()); + } + + template + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.sputn(s, n); } +}; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { return t.write(&c, 1) == 1; } + + template + static std::streamsize + write(T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.write(s, n); } +}; + +//------------------Definition of write_filter_impl---------------------------// + +template +struct write_filter_impl + : mpl::if_< + is_custom, + operations, + write_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct write_filter_impl { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { return t.write(snk, s, n); } +}; + +template<> +struct write_filter_impl { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { + for (std::streamsize off = 0; off < n; ++off) + if (!t.put(snk, s[off])) + return off; + return n; + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------// + +#include + +#endif // #ifndef BOOST_IOSTREAMS_WRITE_HPP_INCLUDED diff --git a/thirdparty/boost/is_placeholder.hpp b/thirdparty/boost/is_placeholder.hpp new file mode 100644 index 0000000..cd061cb --- /dev/null +++ b/thirdparty/boost/is_placeholder.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED +#define BOOST_IS_PLACEHOLDER_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined( _MSC_VER ) && ( _MSC_VER >= 1020 ) +# pragma once +#endif + + +// is_placeholder.hpp - TR1 is_placeholder metafunction +// +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +namespace boost +{ + +template< class T > struct is_placeholder +{ + enum _vt { value = 0 }; +}; + +} // namespace boost + +#endif // #ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED diff --git a/thirdparty/boost/iterator.hpp b/thirdparty/boost/iterator.hpp new file mode 100644 index 0000000..8d54784 --- /dev/null +++ b/thirdparty/boost/iterator.hpp @@ -0,0 +1,59 @@ +// interator.hpp workarounds for non-conforming standard libraries ---------// + +// (C) Copyright Beman Dawes 2000. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/utility for documentation. + +// Revision History +// 12 Jan 01 added for std::ptrdiff_t (Jens Maurer) +// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams) +// 26 Jun 00 Initial version (Jeremy Siek) + +#ifndef BOOST_ITERATOR_HPP +#define BOOST_ITERATOR_HPP + +#include +#include // std::ptrdiff_t +#include + +namespace boost +{ +# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR) + template + struct iterator + { + typedef T value_type; + typedef Distance difference_type; + typedef Pointer pointer; + typedef Reference reference; + typedef Category iterator_category; + }; +# else + + // declare iterator_base in namespace detail to work around MSVC bugs which + // prevent derivation from an identically-named class in a different namespace. + namespace detail { + template +# if !defined(BOOST_MSVC_STD_ITERATOR) + struct iterator_base : std::iterator {}; +# else + struct iterator_base : std::iterator + { + typedef Reference reference; + typedef Pointer pointer; + typedef Distance difference_type; + }; +# endif + } + + template + struct iterator : boost::detail::iterator_base {}; +# endif +} // namespace boost + +#endif // BOOST_ITERATOR_HPP diff --git a/thirdparty/boost/iterator/counting_iterator.hpp b/thirdparty/boost/iterator/counting_iterator.hpp new file mode 100644 index 0000000..09fc5a7 --- /dev/null +++ b/thirdparty/boost/iterator/counting_iterator.hpp @@ -0,0 +1,215 @@ +// Copyright David Abrahams 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) +#ifndef COUNTING_ITERATOR_DWA200348_HPP +# define COUNTING_ITERATOR_DWA200348_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { + +template < + class Incrementable + , class CategoryOrTraversal + , class Difference +> +class counting_iterator; + +namespace detail +{ + // Try to detect numeric types at compile time in ways compatible + // with the limitations of the compiler and library. + template + struct is_numeric_impl + { + // For a while, this wasn't true, but we rely on it below. This is a regression assert. + BOOST_STATIC_ASSERT(::boost::is_integral::value); + +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + + BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits::is_specialized); + +# else + +# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + BOOST_STATIC_CONSTANT( + bool, value = ( + boost::is_convertible::value + && boost::is_convertible::value + )); +# else + BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic::value); +# endif + +# endif + }; + + template + struct is_numeric + : mpl::bool_<(::boost::detail::is_numeric_impl::value)> + {}; + +# if defined(BOOST_HAS_LONG_LONG) + template <> + struct is_numeric< ::boost::long_long_type> + : mpl::true_ {}; + + template <> + struct is_numeric< ::boost::ulong_long_type> + : mpl::true_ {}; +# endif + + // Some compilers fail to have a numeric_limits specialization + template <> + struct is_numeric + : mpl::true_ {}; + + template + struct numeric_difference + { + typedef typename boost::detail::numeric_traits::difference_type type; + }; + + BOOST_STATIC_ASSERT(is_numeric::value); + + template + struct counting_iterator_base + { + typedef typename detail::ia_dflt_help< + CategoryOrTraversal + , mpl::eval_if< + is_numeric + , mpl::identity + , iterator_traversal + > + >::type traversal; + + typedef typename detail::ia_dflt_help< + Difference + , mpl::eval_if< + is_numeric + , numeric_difference + , iterator_difference + > + >::type difference; + + typedef iterator_adaptor< + counting_iterator // self + , Incrementable // Base + , Incrementable // Value +# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + const // MSVC won't strip this. Instead we enable Thomas' + // criterion (see boost/iterator/detail/facade_iterator_category.hpp) +# endif + , traversal + , Incrementable const& // reference + , difference + > type; + }; + + // Template class distance_policy_select -- choose a policy for computing the + // distance between counting_iterators at compile-time based on whether or not + // the iterator wraps an integer or an iterator, using "poor man's partial + // specialization". + + template struct distance_policy_select; + + // A policy for wrapped iterators + template + struct iterator_distance + { + static Difference distance(Incrementable1 x, Incrementable2 y) + { + return y - x; + } + }; + + // A policy for wrapped numbers + template + struct number_distance + { + static Difference distance(Incrementable1 x, Incrementable2 y) + { + return numeric_distance(x, y); + } + }; +} + +template < + class Incrementable + , class CategoryOrTraversal = use_default + , class Difference = use_default +> +class counting_iterator + : public detail::counting_iterator_base< + Incrementable, CategoryOrTraversal, Difference + >::type +{ + typedef typename detail::counting_iterator_base< + Incrementable, CategoryOrTraversal, Difference + >::type super_t; + + friend class iterator_core_access; + + public: + typedef typename super_t::difference_type difference_type; + + counting_iterator() { } + + counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {} + + counting_iterator(Incrementable x) + : super_t(x) + { + } + +# if 0 + template + counting_iterator( + counting_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()) + {} +# endif + + private: + + typename super_t::reference dereference() const + { + return this->base_reference(); + } + + template + difference_type + distance_to(counting_iterator const& y) const + { + typedef typename mpl::if_< + detail::is_numeric + , detail::number_distance + , detail::iterator_distance + >::type d; + + return d::distance(this->base(), y.base()); + } +}; + +// Manufacture a counting iterator for an arbitrary incrementable type +template +inline counting_iterator +make_counting_iterator(Incrementable x) +{ + typedef counting_iterator result_t; + return result_t(x); +} + + +} // namespace boost::iterator + +#endif // COUNTING_ITERATOR_DWA200348_HPP diff --git a/thirdparty/boost/iterator/detail/any_conversion_eater.hpp b/thirdparty/boost/iterator/detail/any_conversion_eater.hpp new file mode 100644 index 0000000..ce9e043 --- /dev/null +++ b/thirdparty/boost/iterator/detail/any_conversion_eater.hpp @@ -0,0 +1,19 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP +# define ANY_CONVERSION_EATER_DWA20031117_HPP + +namespace boost { namespace detail { + +// This type can be used in traits to "eat" up the one user-defined +// implicit conversion allowed. +struct any_conversion_eater +{ + template + any_conversion_eater(T const&); +}; + +}} // namespace boost::detail + +#endif // ANY_CONVERSION_EATER_DWA20031117_HPP diff --git a/thirdparty/boost/iterator/detail/config_def.hpp b/thirdparty/boost/iterator/detail/config_def.hpp new file mode 100644 index 0000000..a6cb3b5 --- /dev/null +++ b/thirdparty/boost/iterator/detail/config_def.hpp @@ -0,0 +1,135 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 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) + +// no include guard multiple inclusion intended + +// +// This is a temporary workaround until the bulk of this is +// available in boost config. +// 23/02/03 thw +// + +#include // for prior +#include + +#ifdef BOOST_ITERATOR_CONFIG_DEF +# error you have nested config_def #inclusion. +#else +# define BOOST_ITERATOR_CONFIG_DEF +#endif + +// We enable this always now. Otherwise, the simple case in +// libs/iterator/test/constant_iterator_arrow.cpp fails to compile +// because the operator-> return is improperly deduced as a non-const +// pointer. +#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) + +// Recall that in general, compilers without partial specialization +// can't strip constness. Consider counting_iterator, which normally +// passes a const Value to iterator_facade. As a result, any code +// which makes a std::vector of the iterator's value_type will fail +// when its allocator declares functions overloaded on reference and +// const_reference (the same type). +// +// Furthermore, Borland 5.5.1 drops constness in enough ways that we +// end up using a proxy for operator[] when we otherwise shouldn't. +// Using reference constness gives it an extra hint that it can +// return the value_type from operator[] directly, but is not +// strictly necessary. Not sure how best to resolve this one. + +# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1 + +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \ + || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \ + || BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) +# define BOOST_NO_LVALUE_RETURN_DETECTION + +# if 0 // test code + struct v {}; + + typedef char (&no)[3]; + + template + no foo(T const&, ...); + + template + char foo(T&, int); + + + struct value_iterator + { + v operator*() const; + }; + + template + struct lvalue_deref_helper + { + static T& x; + enum { value = (sizeof(foo(*x,0)) == 1) }; + }; + + int z2[(lvalue_deref_helper::value == 1) ? 1 : -1]; + int z[(lvalue_deref_helper::value) == 1 ? -1 : 1 ]; +# endif + +#endif + +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) +# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types" +#endif + +#if BOOST_WORKAROUND(__GNUC__, == 2) \ + || BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile: + +# if 0 // test code + #include + template + struct foo + { + foo(T); + + template + foo(foo const& other) : p(other.p) { } + + T p; + }; + + bool x = boost::is_convertible, foo >::value; +# endif + +#endif + + +#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE)) +# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY +#endif + +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_ARG_DEPENDENT_TYPENAME typename +# else +# define BOOST_ARG_DEPENDENT_TYPENAME +# endif + +# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +// GCC-2.95 eagerly instantiates templated constructors and conversion +// operators in convertibility checks, causing premature errors. +// +// Borland's problems are harder to diagnose due to lack of an +// instantiation stack backtrace. They may be due in part to the fact +// that it drops cv-qualification willy-nilly in templates. +# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP +# endif + +// no include guard; multiple inclusion intended diff --git a/thirdparty/boost/iterator/detail/config_undef.hpp b/thirdparty/boost/iterator/detail/config_undef.hpp new file mode 100644 index 0000000..9b04775 --- /dev/null +++ b/thirdparty/boost/iterator/detail/config_undef.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Thomas Witt 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) + +// no include guard multiple inclusion intended + +// +// This is a temporary workaround until the bulk of this is +// available in boost config. +// 23/02/03 thw +// + +#undef BOOST_NO_IS_CONVERTIBLE +#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE +#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY +#undef BOOST_ARG_DEPENDENT_TYPENAME +#undef BOOST_NO_LVALUE_RETURN_DETECTION +#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP + +#ifdef BOOST_ITERATOR_CONFIG_DEF +# undef BOOST_ITERATOR_CONFIG_DEF +#else +# error missing or nested #include config_def +#endif diff --git a/thirdparty/boost/iterator/detail/enable_if.hpp b/thirdparty/boost/iterator/detail/enable_if.hpp new file mode 100644 index 0000000..2c261f8 --- /dev/null +++ b/thirdparty/boost/iterator/detail/enable_if.hpp @@ -0,0 +1,86 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ENABLE_IF_23022003THW_HPP +#define BOOST_ENABLE_IF_23022003THW_HPP + +#include +#include + +#include + +// +// Boost iterators uses its own enable_if cause we need +// special semantics for deficient compilers. +// 23/02/03 thw +// + +namespace boost +{ + + namespace iterators + { + // + // Base machinery for all kinds of enable if + // + template + struct enabled + { + template + struct base + { + typedef T type; + }; + }; + + // + // For compilers that don't support "Substitution Failure Is Not An Error" + // enable_if falls back to always enabled. See comments + // on operator implementation for consequences. + // + template<> + struct enabled + { + template + struct base + { +#ifdef BOOST_NO_SFINAE + + typedef T type; + + // This way to do it would give a nice error message containing + // invalid overload, but has the big disadvantage that + // there is no reference to user code in the error message. + // + // struct invalid_overload; + // typedef invalid_overload type; + // +#endif + }; + }; + + + template + struct enable_if +# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE) + : enabled<(Cond::value)>::template base +# else + : mpl::identity +# endif + { +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + typedef Return type; +# endif + }; + + } // namespace iterators + +} // namespace boost + +#include + +#endif // BOOST_ENABLE_IF_23022003THW_HPP diff --git a/thirdparty/boost/iterator/detail/facade_iterator_category.hpp b/thirdparty/boost/iterator/detail/facade_iterator_category.hpp new file mode 100644 index 0000000..2c528d8 --- /dev/null +++ b/thirdparty/boost/iterator/detail/facade_iterator_category.hpp @@ -0,0 +1,200 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP +# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP + +# include + +# include // used in iterator_tag inheritance logic +# include +# include +# include +# include +# include + +# include +# include +# include +# include + +# include + +# include // try to keep this last + +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY +# include +# endif + +// +// iterator_category deduction for iterator_facade +// + +// forward declaration +namespace boost { struct use_default; } + +namespace boost { namespace detail { + +struct input_output_iterator_tag + : std::input_iterator_tag +{ + // Using inheritance for only input_iterator_tag helps to avoid + // ambiguities when a stdlib implementation dispatches on a + // function which is overloaded on both input_iterator_tag and + // output_iterator_tag, as STLPort does, in its __valid_range + // function. I claim it's better to avoid the ambiguity in these + // cases. + operator std::output_iterator_tag() const + { + return std::output_iterator_tag(); + } +}; + +// +// True iff the user has explicitly disabled writability of this +// iterator. Pass the iterator_facade's Value parameter and its +// nested ::reference type. +// +template +struct iterator_writability_disabled +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? + : mpl::or_< + is_const + , boost::detail::indirect_traits::is_reference_to_const + , is_const + > +# else + : is_const +# endif +{}; + + +// +// Convert an iterator_facade's traversal category, Value parameter, +// and ::reference type to an appropriate old-style category. +// +// If writability has been disabled per the above metafunction, the +// result will not be convertible to output_iterator_tag. +// +// Otherwise, if Traversal == single_pass_traversal_tag, the following +// conditions will result in a tag that is convertible both to +// input_iterator_tag and output_iterator_tag: +// +// 1. Reference is a reference to non-const +// 2. Reference is not a reference and is convertible to Value +// +template +struct iterator_facade_default_category + : mpl::eval_if< + mpl::and_< + is_reference + , is_convertible + > + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::if_< + is_convertible + , std::bidirectional_iterator_tag + , std::forward_iterator_tag + > + > + , typename mpl::eval_if< + mpl::and_< + is_convertible + + // check for readability + , is_convertible + > + , mpl::identity + , mpl::identity + > + > +{ +}; + +// True iff T is convertible to an old-style iterator category. +template +struct is_iterator_category + : mpl::or_< + is_convertible + , is_convertible + > +{ +}; + +template +struct is_iterator_traversal + : is_convertible +{}; + +// +// A composite iterator_category tag convertible to Category (a pure +// old-style category) and Traversal (a pure traversal tag). +// Traversal must be a strict increase of the traversal power given by +// Category. +// +template +struct iterator_category_with_traversal + : Category, Traversal +{ +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // Make sure this isn't used to build any categories where + // convertibility to Traversal is redundant. Should just use the + // Category element in that case. + BOOST_MPL_ASSERT_NOT(( + is_convertible< + typename iterator_category_to_traversal::type + , Traversal + >)); + + BOOST_MPL_ASSERT((is_iterator_category)); + BOOST_MPL_ASSERT_NOT((is_iterator_category)); + BOOST_MPL_ASSERT_NOT((is_iterator_traversal)); +# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) + BOOST_MPL_ASSERT((is_iterator_traversal)); +# endif +# endif +}; + +// Computes an iterator_category tag whose traversal is Traversal and +// which is appropriate for an iterator +template +struct facade_iterator_category_impl +{ +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_MPL_ASSERT_NOT((is_iterator_category)); +# endif + + typedef typename iterator_facade_default_category< + Traversal,ValueParam,Reference + >::type category; + + typedef typename mpl::if_< + is_same< + Traversal + , typename iterator_category_to_traversal::type + > + , category + , iterator_category_with_traversal + >::type type; +}; + +// +// Compute an iterator_category for iterator_facade +// +template +struct facade_iterator_category + : mpl::eval_if< + is_iterator_category + , mpl::identity // old-style categories are fine as-is + , facade_iterator_category_impl + > +{ +}; + +}} // namespace boost::detail + +# include + +#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP diff --git a/thirdparty/boost/iterator/detail/minimum_category.hpp b/thirdparty/boost/iterator/detail/minimum_category.hpp new file mode 100644 index 0000000..804f918 --- /dev/null +++ b/thirdparty/boost/iterator/detail/minimum_category.hpp @@ -0,0 +1,116 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef MINIMUM_CATEGORY_DWA20031119_HPP +# define MINIMUM_CATEGORY_DWA20031119_HPP + +# include +# include + +# include + +namespace boost { namespace detail { +// +// Returns the minimum category type or error_type +// if T1 and T2 are unrelated. +// +// For compilers not supporting is_convertible this only +// works with the new boost return and traversal category +// types. The exact boost _types_ are required. No derived types +// will work. +// +// +template +struct minimum_category_impl +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +{ + template struct apply + { + typedef T2 type; + }; + typedef void type; +} +# endif +; + +template +struct error_not_related_by_convertibility; + +template <> +struct minimum_category_impl +{ + template struct apply + { + typedef T2 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + { + typedef T1 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + { + BOOST_STATIC_ASSERT((is_same::value)); + typedef T1 type; + }; +}; + +template <> +struct minimum_category_impl +{ + template struct apply + : error_not_related_by_convertibility + { + }; +}; + +template +struct minimum_category +{ + typedef minimum_category_impl< +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + is_same::value || +# endif + ::boost::is_convertible::value + , ::boost::is_convertible::value +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + || is_same::value +# endif + > outer; + + typedef typename outer::template apply inner; + typedef typename inner::type type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2)) +}; + +template <> +struct minimum_category +{ + template + struct apply : minimum_category + {}; + + BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) +}; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround +template <> +struct minimum_category +{ + typedef int type; +}; +# endif + +}} // namespace boost::detail + +#endif // MINIMUM_CATEGORY_DWA20031119_HPP diff --git a/thirdparty/boost/iterator/filter_iterator.hpp b/thirdparty/boost/iterator/filter_iterator.hpp new file mode 100644 index 0000000..84bd054 --- /dev/null +++ b/thirdparty/boost/iterator/filter_iterator.hpp @@ -0,0 +1,135 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP +#define BOOST_FILTER_ITERATOR_23022003THW_HPP + +#include +#include +#include + +#include +#include + +namespace boost +{ + template + class filter_iterator; + + namespace detail + { + template + struct filter_iterator_base + { + typedef iterator_adaptor< + filter_iterator + , Iterator + , use_default + , typename mpl::if_< + is_convertible< + typename iterator_traversal::type + , random_access_traversal_tag + > + , bidirectional_traversal_tag + , use_default + >::type + > type; + }; + } + + template + class filter_iterator + : public detail::filter_iterator_base::type + { + typedef typename detail::filter_iterator_base< + Predicate, Iterator + >::type super_t; + + friend class iterator_core_access; + + public: + filter_iterator() { } + + filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator()) + : super_t(x), m_predicate(f), m_end(end_) + { + satisfy_predicate(); + } + + filter_iterator(Iterator x, Iterator end_ = Iterator()) + : super_t(x), m_predicate(), m_end(end_) + { + // Pro8 is a little too aggressive about instantiating the + // body of this function. +#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + // Don't allow use of this constructor if Predicate is a + // function pointer type, since it will be 0. + BOOST_STATIC_ASSERT(is_class::value); +#endif + satisfy_predicate(); + } + + template + filter_iterator( + filter_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {} + + Predicate predicate() const { return m_predicate; } + + Iterator end() const { return m_end; } + + private: + void increment() + { + ++(this->base_reference()); + satisfy_predicate(); + } + + void decrement() + { + while(!this->m_predicate(*--(this->base_reference()))){}; + } + + void satisfy_predicate() + { + while (this->base() != this->m_end && !this->m_predicate(*this->base())) + ++(this->base_reference()); + } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + Predicate m_predicate; + Iterator m_end; + }; + + template + filter_iterator + make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) + { + return filter_iterator(f,x,end); + } + + template + filter_iterator + make_filter_iterator( + typename iterators::enable_if< + is_class + , Iterator + >::type x + , Iterator end = Iterator() +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + , Predicate* = 0 +#endif + ) + { + return filter_iterator(x,end); + } + +} // namespace boost + +#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP diff --git a/thirdparty/boost/iterator/indirect_iterator.hpp b/thirdparty/boost/iterator/indirect_iterator.hpp new file mode 100644 index 0000000..cff79a5 --- /dev/null +++ b/thirdparty/boost/iterator/indirect_iterator.hpp @@ -0,0 +1,139 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP +#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef BOOST_MPL_CFG_NO_HAS_XXX +# include +# include +# include +# include +#endif + +#include // must be last #include + +namespace boost +{ + template + class indirect_iterator; + + namespace detail + { + template + struct indirect_base + { + typedef typename iterator_traits::value_type dereferenceable; + + typedef iterator_adaptor< + indirect_iterator + , Iter + , typename ia_dflt_help< + Value, pointee + >::type + , Category + , typename ia_dflt_help< + Reference + , mpl::eval_if< + is_same + , indirect_reference + , add_reference + > + >::type + , Difference + > type; + }; + + template <> + struct indirect_base {}; + } // namespace detail + + + template < + class Iterator + , class Value = use_default + , class Category = use_default + , class Reference = use_default + , class Difference = use_default + > + class indirect_iterator + : public detail::indirect_base< + Iterator, Value, Category, Reference, Difference + >::type + { + typedef typename detail::indirect_base< + Iterator, Value, Category, Reference, Difference + >::type super_t; + + friend class iterator_core_access; + + public: + indirect_iterator() {} + + indirect_iterator(Iterator iter) + : super_t(iter) {} + + template < + class Iterator2, class Value2, class Category2 + , class Reference2, class Difference2 + > + indirect_iterator( + indirect_iterator< + Iterator2, Value2, Category2, Reference2, Difference2 + > const& y + , typename enable_if_convertible::type* = 0 + ) + : super_t(y.base()) + {} + + private: + typename super_t::reference dereference() const + { +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + return const_cast(**this->base()); +# else + return **this->base(); +# endif + } + }; + + template + inline + indirect_iterator make_indirect_iterator(Iter x) + { + return indirect_iterator(x); + } + + template + inline + indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) + { + return indirect_iterator(x); + } + +} // namespace boost + +#include + +#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP diff --git a/thirdparty/boost/iterator/interoperable.hpp b/thirdparty/boost/iterator/interoperable.hpp new file mode 100644 index 0000000..08b29c3 --- /dev/null +++ b/thirdparty/boost/iterator/interoperable.hpp @@ -0,0 +1,50 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_INTEROPERABLE_23022003THW_HPP +# define BOOST_INTEROPERABLE_23022003THW_HPP + +# include +# include + +# include + +# include // must appear last + +namespace boost +{ + + // + // Meta function that determines whether two + // iterator types are considered interoperable. + // + // Two iterator types A,B are considered interoperable if either + // A is convertible to B or vice versa. + // This interoperability definition is in sync with the + // standards requirements on constant/mutable container + // iterators (23.1 [lib.container.requirements]). + // + // For compilers that don't support is_convertible + // is_interoperable gives false positives. See comments + // on operator implementation for consequences. + // + template + struct is_interoperable +# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY + : mpl::true_ +# else + : mpl::or_< + is_convertible< A, B > + , is_convertible< B, A > > +# endif + { + }; + +} // namespace boost + +# include + +#endif // BOOST_INTEROPERABLE_23022003THW_HPP diff --git a/thirdparty/boost/iterator/is_lvalue_iterator.hpp b/thirdparty/boost/iterator/is_lvalue_iterator.hpp new file mode 100644 index 0000000..1db6ee4 --- /dev/null +++ b/thirdparty/boost/iterator/is_lvalue_iterator.hpp @@ -0,0 +1,150 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP +# define IS_LVALUE_ITERATOR_DWA2003112_HPP + +#include + +#include +#include + +#include + +// should be the last #includes +#include +#include + +#ifndef BOOST_NO_IS_CONVERTIBLE + +namespace boost { + +namespace detail +{ +#ifndef BOOST_NO_LVALUE_RETURN_DETECTION + // Calling lvalue_preserver( , 0 ) returns a reference + // to the expression's result if is an lvalue, or + // not_an_lvalue() otherwise. + struct not_an_lvalue {}; + + template + T& lvalue_preserver(T&, int); + + template + not_an_lvalue lvalue_preserver(U const&, ...); + +# define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0) + +#else + +# define BOOST_LVALUE_PRESERVER(expr) expr + +#endif + + // Guts of is_lvalue_iterator. Value is the iterator's value_type + // and the result is computed in the nested rebind template. + template + struct is_lvalue_iterator_impl + { + // Eat implicit conversions so we don't report true for things + // convertible to Value const& + struct conversion_eater + { + conversion_eater(Value&); + }; + + static char tester(conversion_eater, int); + static char (& tester(any_conversion_eater, ...) )[2]; + + template + struct rebind + { + static It& x; + + BOOST_STATIC_CONSTANT( + bool + , value = ( + sizeof( + is_lvalue_iterator_impl::tester( + BOOST_LVALUE_PRESERVER(*x), 0 + ) + ) == 1 + ) + ); + }; + }; + +#undef BOOST_LVALUE_PRESERVER + + // + // void specializations to handle std input and output iterators + // + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; +#endif + + // + // This level of dispatching is required for Borland. We might save + // an instantiation by removing it for others. + // + template + struct is_readable_lvalue_iterator_impl + : is_lvalue_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type const + >::template rebind + {}; + + template + struct is_non_const_lvalue_iterator_impl + : is_lvalue_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type + >::template rebind + {}; +} // namespace detail + +// Define the trait with full mpl lambda capability and various broken +// compiler workarounds +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl::value) + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl::value) + +} // namespace boost + +#endif + +#include +#include + +#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP diff --git a/thirdparty/boost/iterator/is_readable_iterator.hpp b/thirdparty/boost/iterator/is_readable_iterator.hpp new file mode 100644 index 0000000..036585e --- /dev/null +++ b/thirdparty/boost/iterator/is_readable_iterator.hpp @@ -0,0 +1,108 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP +# define IS_READABLE_ITERATOR_DWA2003112_HPP + +#include +#include + +#include +#include + +// should be the last #include +#include + +#ifndef BOOST_NO_IS_CONVERTIBLE + +namespace boost { + +namespace detail +{ + // Guts of is_readable_iterator. Value is the iterator's value_type + // and the result is computed in the nested rebind template. + template + struct is_readable_iterator_impl + { + static char tester(Value&, int); + static char (& tester(any_conversion_eater, ...) )[2]; + + template + struct rebind + { + static It& x; + + BOOST_STATIC_CONSTANT( + bool + , value = ( + sizeof( + is_readable_iterator_impl::tester(*x, 1) + ) == 1 + ) + ); + }; + }; + +#undef BOOST_READABLE_PRESERVER + + // + // void specializations to handle std input and output iterators + // + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; +#endif + + // + // This level of dispatching is required for Borland. We might save + // an instantiation by removing it for others. + // + template + struct is_readable_iterator_impl2 + : is_readable_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type const + >::template rebind + {}; +} // namespace detail + +// Define the trait with full mpl lambda capability and various broken +// compiler workarounds +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2::value) + +} // namespace boost + +#endif + +#include + +#endif // IS_READABLE_ITERATOR_DWA2003112_HPP diff --git a/thirdparty/boost/iterator/iterator_adaptor.hpp b/thirdparty/boost/iterator/iterator_adaptor.hpp new file mode 100644 index 0000000..d9c290d --- /dev/null +++ b/thirdparty/boost/iterator/iterator_adaptor.hpp @@ -0,0 +1,366 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP +#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY +# include +#else +# include +#endif + +#include + +#include + +namespace boost +{ + // Used as a default template argument internally, merely to + // indicate "use the default", this can also be passed by users + // explicitly in order to specify that the default should be used. + struct use_default; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // the incompleteness of use_default causes massive problems for + // is_convertible (naturally). This workaround is fortunately not + // needed for vc6/vc7. + template + struct is_convertible + : mpl::false_ {}; +# endif + + namespace detail + { + + // + // Result type used in enable_if_convertible meta function. + // This can be an incomplete type, as only pointers to + // enable_if_convertible< ... >::type are used. + // We could have used void for this, but conversion to + // void* is just to easy. + // + struct enable_type; + } + + + // + // enable_if for use in adapted iterators constructors. + // + // In order to provide interoperability between adapted constant and + // mutable iterators, adapted iterators will usually provide templated + // conversion constructors of the following form + // + // template + // class adapted_iterator : + // public iterator_adaptor< adapted_iterator, Iterator > + // { + // public: + // + // ... + // + // template + // adapted_iterator( + // OtherIterator const& it + // , typename enable_if_convertible::type* = 0); + // + // ... + // }; + // + // enable_if_convertible is used to remove those overloads from the overload + // set that cannot be instantiated. For all practical purposes only overloads + // for constant/mutable interaction will remain. This has the advantage that + // meta functions like boost::is_convertible do not return false positives, + // as they can only look at the signature of the conversion constructor + // and not at the actual instantiation. + // + // enable_if_interoperable can be safely used in user code. It falls back to + // always enabled for compilers that don't support enable_if or is_convertible. + // There is no need for compiler specific workarounds in user code. + // + // The operators implementation relies on boost::is_convertible not returning + // false positives for user/library defined iterator types. See comments + // on operator implementation for consequences. + // +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + + template + struct enable_if_convertible + { + typedef typename mpl::if_< + mpl::or_< + is_same + , is_convertible + > + , boost::detail::enable_type + , int& + >::type type; + }; + +# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) + + template + struct enable_if_convertible + { + typedef boost::detail::enable_type type; + }; + +# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300 + + // For some reason vc7.1 needs us to "cut off" instantiation + // of is_convertible in a few cases. + template + struct enable_if_convertible + : iterators::enable_if< + mpl::or_< + is_same + , is_convertible + > + , boost::detail::enable_type + > + {}; + +# else + + template + struct enable_if_convertible + : iterators::enable_if< + is_convertible + , boost::detail::enable_type + > + {}; + +# endif + + // + // Default template argument handling for iterator_adaptor + // + namespace detail + { + // If T is use_default, return the result of invoking + // DefaultNullaryFn, otherwise return T. + template + struct ia_dflt_help + : mpl::eval_if< + is_same + , DefaultNullaryFn + , mpl::identity + > + { + }; + + // A metafunction which computes an iterator_adaptor's base class, + // a specialization of iterator_facade. + template < + class Derived + , class Base + , class Value + , class Traversal + , class Reference + , class Difference + > + struct iterator_adaptor_base + { + typedef iterator_facade< + Derived + +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + , typename boost::detail::ia_dflt_help< + Value + , mpl::eval_if< + is_same + , iterator_value + , remove_reference + > + >::type +# else + , typename boost::detail::ia_dflt_help< + Value, iterator_value + >::type +# endif + + , typename boost::detail::ia_dflt_help< + Traversal + , iterator_traversal + >::type + + , typename boost::detail::ia_dflt_help< + Reference + , mpl::eval_if< + is_same + , iterator_reference + , add_reference + > + >::type + + , typename boost::detail::ia_dflt_help< + Difference, iterator_difference + >::type + > + type; + }; + + // workaround for aC++ CR JAGaf33512 + template + inline void iterator_adaptor_assert_traversal () + { + BOOST_STATIC_ASSERT((is_convertible::value)); + } + } + + // + // Iterator Adaptor + // + // The parameter ordering changed slightly with respect to former + // versions of iterator_adaptor The idea is that when the user needs + // to fiddle with the reference type it is highly likely that the + // iterator category has to be adjusted as well. Any of the + // following four template arguments may be ommitted or explicitly + // replaced by use_default. + // + // Value - if supplied, the value_type of the resulting iterator, unless + // const. If const, a conforming compiler strips constness for the + // value_type. If not supplied, iterator_traits::value_type is used + // + // Category - the traversal category of the resulting iterator. If not + // supplied, iterator_traversal::type is used. + // + // Reference - the reference type of the resulting iterator, and in + // particular, the result type of operator*(). If not supplied but + // Value is supplied, Value& is used. Otherwise + // iterator_traits::reference is used. + // + // Difference - the difference_type of the resulting iterator. If not + // supplied, iterator_traits::difference_type is used. + // + template < + class Derived + , class Base + , class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + > + class iterator_adaptor + : public boost::detail::iterator_adaptor_base< + Derived, Base, Value, Traversal, Reference, Difference + >::type + { + friend class iterator_core_access; + + protected: + typedef typename boost::detail::iterator_adaptor_base< + Derived, Base, Value, Traversal, Reference, Difference + >::type super_t; + public: + iterator_adaptor() {} + + explicit iterator_adaptor(Base const &iter) + : m_iterator(iter) + { + } + + typedef Base base_type; + + Base const& base() const + { return m_iterator; } + + protected: + // for convenience in derived classes + typedef iterator_adaptor iterator_adaptor_; + + // + // lvalue access to the Base object for Derived + // + Base const& base_reference() const + { return m_iterator; } + + Base& base_reference() + { return m_iterator; } + + private: + // + // Core iterator interface for iterator_facade. This is private + // to prevent temptation for Derived classes to use it, which + // will often result in an error. Derived classes should use + // base_reference(), above, to get direct access to m_iterator. + // + typename super_t::reference dereference() const + { return *m_iterator; } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class D + > + bool equal(iterator_adaptor const& x) const + { + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference::value) + // ); + return m_iterator == x.base(); + } + + typedef typename iterator_category_to_traversal< + typename super_t::iterator_category + >::type my_traversal; + +# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \ + boost::detail::iterator_adaptor_assert_traversal(); + + void advance(typename super_t::difference_type n) + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) + m_iterator += n; + } + + void increment() { ++m_iterator; } + + void decrement() + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag) + --m_iterator; + } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class D + > + typename super_t::difference_type distance_to( + iterator_adaptor const& y) const + { + BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) + // Maybe readd with same_distance + // BOOST_STATIC_ASSERT( + // (detail::same_category_and_difference::value) + // ); + return y.base() - m_iterator; + } + +# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL + + private: // data members + Base m_iterator; + }; + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP diff --git a/thirdparty/boost/iterator/iterator_archetypes.hpp b/thirdparty/boost/iterator/iterator_archetypes.hpp new file mode 100644 index 0000000..74b250b --- /dev/null +++ b/thirdparty/boost/iterator/iterator_archetypes.hpp @@ -0,0 +1,515 @@ +// (C) Copyright Jeremy Siek 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ITERATOR_ARCHETYPES_HPP +#define BOOST_ITERATOR_ARCHETYPES_HPP + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { + +template +struct access_archetype; + +template +struct traversal_archetype; + +namespace iterator_archetypes +{ + enum { + readable_iterator_bit = 1 + , writable_iterator_bit = 2 + , swappable_iterator_bit = 4 + , lvalue_iterator_bit = 8 + }; + + // Not quite tags, since dispatching wouldn't work. + typedef mpl::int_::type readable_iterator_t; + typedef mpl::int_::type writable_iterator_t; + + typedef mpl::int_< + (readable_iterator_bit|writable_iterator_bit) + >::type readable_writable_iterator_t; + + typedef mpl::int_< + (readable_iterator_bit|lvalue_iterator_bit) + >::type readable_lvalue_iterator_t; + + typedef mpl::int_< + (lvalue_iterator_bit|writable_iterator_bit) + >::type writable_lvalue_iterator_t; + + typedef mpl::int_::type swappable_iterator_t; + typedef mpl::int_::type lvalue_iterator_t; + + template + struct has_access + : mpl::equal_to< + mpl::bitand_ + , Base + > + {}; +} + +namespace detail +{ + template + struct assign_proxy + { + assign_proxy& operator=(T) { return *this; } + }; + + template + struct read_proxy + { + operator T() { return static_object::get(); } + }; + + template + struct read_write_proxy + : read_proxy // Use to inherit from assign_proxy, but that doesn't work. -JGS + { + read_write_proxy& operator=(T) { return *this; } + }; + + template + struct arrow_proxy + { + T const* operator->() const { return 0; } + }; + + struct no_operator_brackets {}; + + template + struct readable_operator_brackets + { + read_proxy operator[](std::ptrdiff_t n) const { return read_proxy(); } + }; + + template + struct writable_operator_brackets + { + read_write_proxy operator[](std::ptrdiff_t n) const { return read_write_proxy(); } + }; + + template + struct operator_brackets + : mpl::aux::msvc_eti_base< + typename mpl::eval_if< + is_convertible + , mpl::eval_if< + iterator_archetypes::has_access< + AccessCategory + , iterator_archetypes::writable_iterator_t + > + , mpl::identity > + , mpl::if_< + iterator_archetypes::has_access< + AccessCategory + , iterator_archetypes::readable_iterator_t + > + , readable_operator_brackets + , no_operator_brackets + > + > + , mpl::identity + >::type + >::type + {}; + + template + struct traversal_archetype_impl + { + template struct archetype; + }; + + // Constructor argument for those iterators that + // are not default constructible + struct ctor_arg {}; + + template + struct traversal_archetype_ + : mpl::aux::msvc_eti_base< + typename traversal_archetype_impl::template archetype + >::type + { + typedef typename + traversal_archetype_impl::template archetype + base; + + traversal_archetype_() {} + + traversal_archetype_(ctor_arg arg) + : base(arg) + {} + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + { + explicit archetype(ctor_arg) {} + + struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS + typedef bogus difference_type; + + Derived& operator++() { return (Derived&)static_object::get(); } + Derived operator++(int) const { return (Derived&)static_object::get(); } + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public equality_comparable< traversal_archetype_ >, + public traversal_archetype_ + { + explicit archetype(ctor_arg arg) + : traversal_archetype_(arg) + {} + + typedef std::ptrdiff_t difference_type; + }; + }; + + template + bool operator==(traversal_archetype_ const&, + traversal_archetype_ const&) { return true; } + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // doesn't seem to pick up != from equality_comparable + template + bool operator!=(traversal_archetype_ const&, + traversal_archetype_ const&) { return true; } +#endif + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + archetype() + : traversal_archetype_(ctor_arg()) + {} + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + Derived& operator--() { return static_object::get(); } + Derived operator--(int) const { return static_object::get(); } + }; + }; + + template <> + struct traversal_archetype_impl + { + template + struct archetype + : public traversal_archetype_ + { + Derived& operator+=(std::ptrdiff_t) { return static_object::get(); } + Derived& operator-=(std::ptrdiff_t) { return static_object::get(); } + }; + }; + + template + Derived& operator+(traversal_archetype_ const&, + std::ptrdiff_t) { return static_object::get(); } + + template + Derived& operator+(std::ptrdiff_t, + traversal_archetype_ const&) + { return static_object::get(); } + + template + Derived& operator-(traversal_archetype_ const&, + std::ptrdiff_t) + { return static_object::get(); } + + template + std::ptrdiff_t operator-(traversal_archetype_ const&, + traversal_archetype_ const&) + { return 0; } + + template + bool operator<(traversal_archetype_ const&, + traversal_archetype_ const&) + { return true; } + + template + bool operator>(traversal_archetype_ const&, + traversal_archetype_ const&) + { return true; } + + template + bool operator<=(traversal_archetype_ const&, + traversal_archetype_ const&) + { return true; } + + template + bool operator>=(traversal_archetype_ const&, + traversal_archetype_ const&) + { return true; } + + struct bogus_type; + + template + struct convertible_type + : mpl::if_< is_const, + typename remove_const::type, + bogus_type > + {}; + +} // namespace detail + + +template struct undefined; + +template +struct iterator_access_archetype_impl +{ + template struct archetype; +}; + +template +struct iterator_access_archetype + : mpl::aux::msvc_eti_base< + typename iterator_access_archetype_impl< + AccessCategory + >::template archetype + >::type +{ +}; + +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::readable_iterator_t +> +{ + template + struct archetype + { + typedef typename remove_cv::type value_type; + typedef Value reference; + typedef Value* pointer; + + value_type operator*() const { return static_object::get(); } + + detail::arrow_proxy operator->() const { return detail::arrow_proxy(); } + }; +}; + +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::writable_iterator_t +> +{ + template + struct archetype + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT(!is_const::value); +# endif + typedef void value_type; + typedef void reference; + typedef void pointer; + + detail::assign_proxy operator*() const { return detail::assign_proxy(); } + }; +}; + +template <> +struct iterator_access_archetype_impl< + iterator_archetypes::readable_writable_iterator_t +> +{ + template + struct archetype + : public virtual iterator_access_archetype< + Value, iterator_archetypes::readable_iterator_t + > + { + typedef detail::read_write_proxy reference; + + detail::read_write_proxy operator*() const { return detail::read_write_proxy(); } + }; +}; + +template <> +struct iterator_access_archetype_impl +{ + template + struct archetype + : public virtual iterator_access_archetype< + Value, iterator_archetypes::readable_iterator_t + > + { + typedef Value& reference; + + Value& operator*() const { return static_object::get(); } + Value* operator->() const { return 0; } + }; +}; + +template <> +struct iterator_access_archetype_impl +{ + template + struct archetype + : public virtual iterator_access_archetype< + Value, iterator_archetypes::readable_lvalue_iterator_t + > + { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT((!is_const::value)); +# endif + }; +}; + + +template +struct iterator_archetype; + +template +struct traversal_archetype_base + : detail::operator_brackets< + typename remove_cv::type + , AccessCategory + , TraversalCategory + > + , detail::traversal_archetype_< + iterator_archetype + , Value + , TraversalCategory + > +{ +}; + +namespace detail +{ + template + struct iterator_archetype_base + : iterator_access_archetype + , traversal_archetype_base + { + typedef iterator_access_archetype access; + + typedef typename detail::facade_iterator_category< + TraversalCategory + , typename mpl::eval_if< + iterator_archetypes::has_access< + AccessCategory, iterator_archetypes::writable_iterator_t + > + , remove_const + , add_const + >::type + , typename access::reference + >::type iterator_category; + + // Needed for some broken libraries (see below) + typedef boost::iterator< + iterator_category + , Value + , typename traversal_archetype_base< + Value, AccessCategory, TraversalCategory + >::difference_type + , typename access::pointer + , typename access::reference + > workaround_iterator_base; + }; +} + +template +struct iterator_archetype + : public detail::iterator_archetype_base + + // These broken libraries require derivation from std::iterator + // (or related magic) in order to handle iter_swap and other + // iterator operations +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \ + || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101)) + , public detail::iterator_archetype_base< + Value, AccessCategory, TraversalCategory + >::workaround_iterator_base +# endif +{ + // Derivation from std::iterator above caused references to nested + // types to be ambiguous, so now we have to redeclare them all + // here. +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \ + || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101)) + + typedef detail::iterator_archetype_base< + Value,AccessCategory,TraversalCategory + > base; + + typedef typename base::value_type value_type; + typedef typename base::reference reference; + typedef typename base::pointer pointer; + typedef typename base::difference_type difference_type; + typedef typename base::iterator_category iterator_category; +# endif + + iterator_archetype() { } + iterator_archetype(iterator_archetype const& x) + : detail::iterator_archetype_base< + Value + , AccessCategory + , TraversalCategory + >(x) + {} + + iterator_archetype& operator=(iterator_archetype const&) + { return *this; } + +# if 0 + // Optional conversion from mutable + iterator_archetype( + iterator_archetype< + typename detail::convertible_type::type + , AccessCategory + , TraversalCategory> const& + ); +# endif +}; + +} // namespace boost + + +#endif // BOOST_ITERATOR_ARCHETYPES_HPP diff --git a/thirdparty/boost/iterator/iterator_categories.hpp b/thirdparty/boost/iterator/iterator_categories.hpp new file mode 100644 index 0000000..9a0be36 --- /dev/null +++ b/thirdparty/boost/iterator/iterator_categories.hpp @@ -0,0 +1,188 @@ +// (C) Copyright Jeremy Siek 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ITERATOR_CATEGORIES_HPP +# define BOOST_ITERATOR_CATEGORIES_HPP + +# include +# include +# include + +# include + +# include +# include +# include +# include + +# include + +# include + +namespace boost { + +// +// Traversal Categories +// + +struct no_traversal_tag {}; + +struct incrementable_traversal_tag + : no_traversal_tag +{ +// incrementable_traversal_tag() {} +// incrementable_traversal_tag(std::output_iterator_tag const&) {}; +}; + +struct single_pass_traversal_tag + : incrementable_traversal_tag +{ +// single_pass_traversal_tag() {} +// single_pass_traversal_tag(std::input_iterator_tag const&) {}; +}; + +struct forward_traversal_tag + : single_pass_traversal_tag +{ +// forward_traversal_tag() {} +// forward_traversal_tag(std::forward_iterator_tag const&) {}; +}; + +struct bidirectional_traversal_tag + : forward_traversal_tag +{ +// bidirectional_traversal_tag() {}; +// bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {}; +}; + +struct random_access_traversal_tag + : bidirectional_traversal_tag +{ +// random_access_traversal_tag() {}; +// random_access_traversal_tag(std::random_access_iterator_tag const&) {}; +}; + +namespace detail +{ + // + // Convert a "strictly old-style" iterator category to a traversal + // tag. This is broken out into a separate metafunction to reduce + // the cost of instantiating iterator_category_to_traversal, below, + // for new-style types. + // + template + struct old_category_to_traversal + : mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , void + > + > + > + > + > + {}; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template <> + struct old_category_to_traversal + { + typedef int type; + }; +# endif + + template + struct pure_traversal_tag + : mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , mpl::eval_if< + is_convertible + , mpl::identity + , void + > + > + > + > + > + { + }; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template <> + struct pure_traversal_tag + { + typedef int type; + }; +# endif + +} // namespace detail + + +// +// Convert an iterator category into a traversal tag +// +template +struct iterator_category_to_traversal + : mpl::eval_if< // if already convertible to a traversal tag, we're done. + is_convertible + , mpl::identity + , boost::detail::old_category_to_traversal + > +{}; + +// Trait to get an iterator's traversal category +template +struct iterator_traversal + : iterator_category_to_traversal< + typename boost::detail::iterator_traits::iterator_category + > +{}; + +# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT +// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work +// out well. Instantiating the nested apply template also +// requires instantiating iterator_traits on the +// placeholder. Instead we just specialize it as a metafunction +// class. +template <> +struct iterator_traversal +{ + template + struct apply : iterator_traversal + {}; +}; +template <> +struct iterator_traversal + : iterator_traversal +{}; +# endif + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_CATEGORIES_HPP diff --git a/thirdparty/boost/iterator/iterator_concepts.hpp b/thirdparty/boost/iterator/iterator_concepts.hpp new file mode 100644 index 0000000..732ad88 --- /dev/null +++ b/thirdparty/boost/iterator/iterator_concepts.hpp @@ -0,0 +1,284 @@ +// (C) Copyright Jeremy Siek 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ITERATOR_CONCEPTS_HPP +#define BOOST_ITERATOR_CONCEPTS_HPP + +#include +#include + +// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. +#include + +#include +#include + +#include +#include +#include +#include + +#include + +// Use boost/limits to work around missing limits headers on some compilers +#include +#include + +#include + +#include + +namespace boost_concepts +{ + // Used a different namespace here (instead of "boost") so that the + // concept descriptions do not take for granted the names in + // namespace boost. + + //=========================================================================== + // Iterator Access Concepts + + BOOST_concept(ReadableIterator,(Iterator)) + : boost::Assignable + , boost::CopyConstructible + + { + typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type value_type; + typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference reference; + + BOOST_CONCEPT_USAGE(ReadableIterator) + { + + value_type v = *i; + boost::ignore_unused_variable_warning(v); + } + private: + Iterator i; + }; + + template < + typename Iterator + , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type + > + struct WritableIterator + : boost::CopyConstructible + { + BOOST_CONCEPT_USAGE(WritableIterator) + { + *i = v; + } + private: + ValueType v; + Iterator i; + }; + + template < + typename Iterator + , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type + > + struct WritableIteratorConcept : WritableIterator {}; + + BOOST_concept(SwappableIterator,(Iterator)) + { + BOOST_CONCEPT_USAGE(SwappableIterator) + { + std::iter_swap(i1, i2); + } + private: + Iterator i1; + Iterator i2; + }; + + BOOST_concept(LvalueIterator,(Iterator)) + { + typedef typename boost::detail::iterator_traits::value_type value_type; + + BOOST_CONCEPT_USAGE(LvalueIterator) + { + value_type& r = const_cast(*i); + boost::ignore_unused_variable_warning(r); + } + private: + Iterator i; + }; + + + //=========================================================================== + // Iterator Traversal Concepts + + BOOST_concept(IncrementableIterator,(Iterator)) + : boost::Assignable + , boost::CopyConstructible + { + typedef typename boost::iterator_traversal::type traversal_category; + + BOOST_CONCEPT_ASSERT(( + boost::Convertible< + traversal_category + , boost::incrementable_traversal_tag + >)); + + BOOST_CONCEPT_USAGE(IncrementableIterator) + { + ++i; + (void)i++; + } + private: + Iterator i; + }; + + BOOST_concept(SinglePassIterator,(Iterator)) + : IncrementableIterator + , boost::EqualityComparable + + { + BOOST_CONCEPT_ASSERT(( + boost::Convertible< + BOOST_DEDUCED_TYPENAME SinglePassIterator::traversal_category + , boost::single_pass_traversal_tag + > )); + }; + + BOOST_concept(ForwardTraversal,(Iterator)) + : SinglePassIterator + , boost::DefaultConstructible + { + typedef typename boost::detail::iterator_traits::difference_type difference_type; + + BOOST_MPL_ASSERT((boost::is_integral)); + BOOST_MPL_ASSERT_RELATION(std::numeric_limits::is_signed, ==, true); + + BOOST_CONCEPT_ASSERT(( + boost::Convertible< + BOOST_DEDUCED_TYPENAME ForwardTraversal::traversal_category + , boost::forward_traversal_tag + > )); + }; + + BOOST_concept(BidirectionalTraversal,(Iterator)) + : ForwardTraversal + { + BOOST_CONCEPT_ASSERT(( + boost::Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalTraversal::traversal_category + , boost::bidirectional_traversal_tag + > )); + + BOOST_CONCEPT_USAGE(BidirectionalTraversal) + { + --i; + (void)i--; + } + private: + Iterator i; + }; + + BOOST_concept(RandomAccessTraversal,(Iterator)) + : BidirectionalTraversal + { + BOOST_CONCEPT_ASSERT(( + boost::Convertible< + BOOST_DEDUCED_TYPENAME RandomAccessTraversal::traversal_category + , boost::random_access_traversal_tag + > )); + + BOOST_CONCEPT_USAGE(RandomAccessTraversal) + { + i += n; + i = i + n; + i = n + i; + i -= n; + i = i - n; + n = i - j; + } + + private: + typename BidirectionalTraversal::difference_type n; + Iterator i, j; + }; + + //=========================================================================== + // Iterator Interoperability + + namespace detail + { + template + void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2) + { + bool b; + b = i1 == i2; + b = i1 != i2; + + b = i2 == i1; + b = i2 != i1; + boost::ignore_unused_variable_warning(b); + } + + template + void interop_rand_access_constraints( + Iterator1 const& i1, Iterator2 const& i2, + boost::random_access_traversal_tag, boost::random_access_traversal_tag) + { + bool b; + typename boost::detail::iterator_traits::difference_type n; + b = i1 < i2; + b = i1 <= i2; + b = i1 > i2; + b = i1 >= i2; + n = i1 - i2; + + b = i2 < i1; + b = i2 <= i1; + b = i2 > i1; + b = i2 >= i1; + n = i2 - i1; + boost::ignore_unused_variable_warning(b); + boost::ignore_unused_variable_warning(n); + } + + template + void interop_rand_access_constraints( + Iterator1 const&, Iterator2 const&, + boost::single_pass_traversal_tag, boost::single_pass_traversal_tag) + { } + + } // namespace detail + + BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator)) + { + private: + typedef typename boost::detail::pure_traversal_tag< + typename boost::iterator_traversal< + Iterator + >::type + >::type traversal_category; + + typedef typename boost::detail::pure_traversal_tag< + typename boost::iterator_traversal< + ConstIterator + >::type + >::type const_traversal_category; + + public: + BOOST_CONCEPT_ASSERT((SinglePassIterator)); + BOOST_CONCEPT_ASSERT((SinglePassIterator)); + + BOOST_CONCEPT_USAGE(InteroperableIterator) + { + detail::interop_single_pass_constraints(i, ci); + detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category()); + + ci = i; + } + + private: + Iterator i; + ConstIterator ci; + }; + +} // namespace boost_concepts + +#include + +#endif // BOOST_ITERATOR_CONCEPTS_HPP diff --git a/thirdparty/boost/iterator/iterator_facade.hpp b/thirdparty/boost/iterator/iterator_facade.hpp new file mode 100644 index 0000000..8344f3e --- /dev/null +++ b/thirdparty/boost/iterator/iterator_facade.hpp @@ -0,0 +1,879 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP +#define BOOST_ITERATOR_FACADE_23022003THW_HPP + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include // this goes last + +namespace boost +{ + // This forward declaration is required for the friend declaration + // in iterator_core_access + template class iterator_facade; + + namespace detail + { + // A binary metafunction class that always returns bool. VC6 + // ICEs on mpl::always, probably because of the default + // parameters. + struct always_bool2 + { + template + struct apply + { + typedef bool type; + }; + }; + + // + // enable if for use in operator implementation. + // + template < + class Facade1 + , class Facade2 + , class Return + > + struct enable_if_interoperable +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + { + typedef typename mpl::if_< + mpl::or_< + is_convertible + , is_convertible + > + , Return + , int[3] + >::type type; + }; +#else + : ::boost::iterators::enable_if< + mpl::or_< + is_convertible + , is_convertible + > + , Return + > + {}; +#endif + + // + // Generates associated types for an iterator_facade with the + // given parameters. + // + template < + class ValueParam + , class CategoryOrTraversal + , class Reference + , class Difference + > + struct iterator_facade_types + { + typedef typename facade_iterator_category< + CategoryOrTraversal, ValueParam, Reference + >::type iterator_category; + + typedef typename remove_const::type value_type; + + typedef typename mpl::eval_if< + boost::detail::iterator_writability_disabled + , add_pointer + , add_pointer + >::type pointer; + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ + || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310) + + // To interoperate with some broken library/compiler + // combinations, user-defined iterators must be derived from + // std::iterator. It is possible to implement a standard + // library for broken compilers without this limitation. +# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1 + + typedef + iterator + base; +# endif + }; + + // iterators whose dereference operators reference the same value + // for all iterators into the same sequence (like many input + // iterators) need help with their postfix ++: the referenced + // value must be read and stored away before the increment occurs + // so that *a++ yields the originally referenced element and not + // the next one. + template + class postfix_increment_proxy + { + typedef typename iterator_value::type value_type; + public: + explicit postfix_increment_proxy(Iterator const& x) + : stored_value(*x) + {} + + // Returning a mutable reference allows nonsense like + // (*r++).mutate(), but it imposes fewer assumptions about the + // behavior of the value_type. In particular, recall taht + // (*r).mutate() is legal if operator* returns by value. + value_type& + operator*() const + { + return this->stored_value; + } + private: + mutable value_type stored_value; + }; + + // + // In general, we can't determine that such an iterator isn't + // writable -- we also need to store a copy of the old iterator so + // that it can be written into. + template + class writable_postfix_increment_proxy + { + typedef typename iterator_value::type value_type; + public: + explicit writable_postfix_increment_proxy(Iterator const& x) + : stored_value(*x) + , stored_iterator(x) + {} + + // Dereferencing must return a proxy so that both *r++ = o and + // value_type(*r++) can work. In this case, *r is the same as + // *r++, and the conversion operator below is used to ensure + // readability. + writable_postfix_increment_proxy const& + operator*() const + { + return *this; + } + + // Provides readability of *r++ + operator value_type&() const + { + return stored_value; + } + + // Provides writability of *r++ + template + T const& operator=(T const& x) const + { + *this->stored_iterator = x; + return x; + } + + // This overload just in case only non-const objects are writable + template + T& operator=(T& x) const + { + *this->stored_iterator = x; + return x; + } + + // Provides X(r++) + operator Iterator const&() const + { + return stored_iterator; + } + + private: + mutable value_type stored_value; + Iterator stored_iterator; + }; + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct is_non_proxy_reference_impl + { + static Reference r; + + template + static typename mpl::if_< + is_convertible< + R const volatile* + , Value const volatile* + > + , char[1] + , char[2] + >::type& helper(R const&); + + BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1); + }; + + template + struct is_non_proxy_reference + : mpl::bool_< + is_non_proxy_reference_impl::value + > + {}; +# else + template + struct is_non_proxy_reference + : is_convertible< + typename remove_reference::type + const volatile* + , Value const volatile* + > + {}; +# endif + + // A metafunction to choose the result type of postfix ++ + // + // Because the C++98 input iterator requirements say that *r++ has + // type T (value_type), implementations of some standard + // algorithms like lexicographical_compare may use constructions + // like: + // + // *r++ < *s++ + // + // If *r++ returns a proxy (as required if r is writable but not + // multipass), this sort of expression will fail unless the proxy + // supports the operator<. Since there are any number of such + // operations, we're not going to try to support them. Therefore, + // even if r++ returns a proxy, *r++ will only return a proxy if + // *r also returns a proxy. + template + struct postfix_increment_result + : mpl::eval_if< + mpl::and_< + // A proxy is only needed for readable iterators + is_convertible + + // No multipass iterator can have values that disappear + // before positions can be re-visited + , mpl::not_< + is_convertible< + typename iterator_category_to_traversal::type + , forward_traversal_tag + > + > + > + , mpl::if_< + is_non_proxy_reference + , postfix_increment_proxy + , writable_postfix_increment_proxy + > + , mpl::identity + > + {}; + + // operator->() needs special support for input iterators to strictly meet the + // standard's requirements. If *i is not a reference type, we must still + // produce a lvalue to which a pointer can be formed. We do that by + // returning an instantiation of this special proxy class template. + template + struct operator_arrow_proxy + { + operator_arrow_proxy(T const* px) : m_value(*px) {} + T* operator->() const { return &m_value; } + // This function is needed for MWCW and BCC, which won't call operator-> + // again automatically per 13.3.1.2 para 8 + operator T*() const { return &m_value; } + mutable T m_value; + }; + + // A metafunction that gets the result type for operator->. Also + // has a static function make() which builds the result from a + // Reference + template + struct operator_arrow_result + { + // CWPro8.3 won't accept "operator_arrow_result::type", and we + // need that type below, so metafunction forwarding would be a + // losing proposition here. + typedef typename mpl::if_< + is_reference + , Pointer + , operator_arrow_proxy + >::type type; + + static type make(Reference x) + { + return implicit_cast(&x); + } + }; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // Deal with ETI + template<> + struct operator_arrow_result + { + typedef int type; + }; +# endif + + // A proxy return type for operator[], needed to deal with + // iterators that may invalidate referents upon destruction. + // Consider the temporary iterator in *(a + n) + template + class operator_brackets_proxy + { + // Iterator is actually an iterator_facade, so we do not have to + // go through iterator_traits to access the traits. + typedef typename Iterator::reference reference; + typedef typename Iterator::value_type value_type; + + public: + operator_brackets_proxy(Iterator const& iter) + : m_iter(iter) + {} + + operator reference() const + { + return *m_iter; + } + + operator_brackets_proxy& operator=(value_type const& val) + { + *m_iter = val; + return *this; + } + + private: + Iterator m_iter; + }; + + // A metafunction that determines whether operator[] must return a + // proxy, or whether it can simply return a copy of the value_type. + template + struct use_operator_brackets_proxy + : mpl::not_< + mpl::and_< + // Really we want an is_copy_constructible trait here, + // but is_POD will have to suffice in the meantime. + boost::is_POD + , iterator_writability_disabled + > + > + {}; + + template + struct operator_brackets_result + { + typedef typename mpl::if_< + use_operator_brackets_proxy + , operator_brackets_proxy + , Value + >::type type; + }; + + template + operator_brackets_proxy make_operator_brackets_result(Iterator const& iter, mpl::true_) + { + return operator_brackets_proxy(iter); + } + + template + typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_) + { + return *iter; + } + + struct choose_difference_type + { + template + struct apply + : +# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP + iterator_difference +# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300) + mpl::if_< + is_convertible + , typename I1::difference_type + , typename I2::difference_type + > +# else + mpl::eval_if< + is_convertible + , iterator_difference + , iterator_difference + > +# endif + {}; + + }; + } // namespace detail + + + // Macros which describe the declarations of binary operators +# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY +# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ + template < \ + class Derived1, class V1, class TC1, class Reference1, class Difference1 \ + , class Derived2, class V2, class TC2, class Reference2, class Difference2 \ + > \ + prefix typename mpl::apply2::type \ + operator op( \ + iterator_facade const& lhs \ + , iterator_facade const& rhs) +# else +# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ + template < \ + class Derived1, class V1, class TC1, class Reference1, class Difference1 \ + , class Derived2, class V2, class TC2, class Reference2, class Difference2 \ + > \ + prefix typename boost::detail::enable_if_interoperable< \ + Derived1, Derived2 \ + , typename mpl::apply2::type \ + >::type \ + operator op( \ + iterator_facade const& lhs \ + , iterator_facade const& rhs) +# endif + +# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ + template \ + prefix Derived operator+ args + + // + // Helper class for granting access to the iterator core interface. + // + // The simple core interface is used by iterator_facade. The core + // interface of a user/library defined iterator type should not be made public + // so that it does not clutter the public interface. Instead iterator_core_access + // should be made friend so that iterator_facade can access the core + // interface through iterator_core_access. + // + class iterator_core_access + { +# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + // Tasteless as this may seem, making all members public allows member templates + // to work in the absence of member template friends. + public: +# else + + template friend class iterator_facade; + +# define BOOST_ITERATOR_FACADE_RELATION(op) \ + BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::detail::always_bool2); + + BOOST_ITERATOR_FACADE_RELATION(==) + BOOST_ITERATOR_FACADE_RELATION(!=) + + BOOST_ITERATOR_FACADE_RELATION(<) + BOOST_ITERATOR_FACADE_RELATION(>) + BOOST_ITERATOR_FACADE_RELATION(<=) + BOOST_ITERATOR_FACADE_RELATION(>=) +# undef BOOST_ITERATOR_FACADE_RELATION + + BOOST_ITERATOR_FACADE_INTEROP_HEAD( + friend, -, boost::detail::choose_difference_type) + ; + + BOOST_ITERATOR_FACADE_PLUS_HEAD( + friend inline + , (iterator_facade const& + , typename Derived::difference_type) + ) + ; + + BOOST_ITERATOR_FACADE_PLUS_HEAD( + friend inline + , (typename Derived::difference_type + , iterator_facade const&) + ) + ; + +# endif + + template + static typename Facade::reference dereference(Facade const& f) + { + return f.dereference(); + } + + template + static void increment(Facade& f) + { + f.increment(); + } + + template + static void decrement(Facade& f) + { + f.decrement(); + } + + template + static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_) + { + return f1.equal(f2); + } + + template + static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_) + { + return f2.equal(f1); + } + + template + static void advance(Facade& f, typename Facade::difference_type n) + { + f.advance(n); + } + + template + static typename Facade1::difference_type distance_from( + Facade1 const& f1, Facade2 const& f2, mpl::true_) + { + return -f1.distance_to(f2); + } + + template + static typename Facade2::difference_type distance_from( + Facade1 const& f1, Facade2 const& f2, mpl::false_) + { + return f2.distance_to(f1); + } + + // + // Curiously Recurring Template interface. + // + template + static I& derived(iterator_facade& facade) + { + return *static_cast(&facade); + } + + template + static I const& derived(iterator_facade const& facade) + { + return *static_cast(&facade); + } + + private: + // objects of this class are useless + iterator_core_access(); //undefined + }; + + // + // iterator_facade - use as a public base class for defining new + // standard-conforming iterators. + // + template < + class Derived // The derived iterator type being constructed + , class Value + , class CategoryOrTraversal + , class Reference = Value& + , class Difference = std::ptrdiff_t + > + class iterator_facade +# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE + : public boost::detail::iterator_facade_types< + Value, CategoryOrTraversal, Reference, Difference + >::base +# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE +# endif + { + private: + // + // Curiously Recurring Template interface. + // + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } + + typedef boost::detail::iterator_facade_types< + Value, CategoryOrTraversal, Reference, Difference + > associated_types; + + protected: + // For use by derived classes + typedef iterator_facade iterator_facade_; + + public: + + typedef typename associated_types::value_type value_type; + typedef Reference reference; + typedef Difference difference_type; + typedef typename associated_types::pointer pointer; + typedef typename associated_types::iterator_category iterator_category; + + reference operator*() const + { + return iterator_core_access::dereference(this->derived()); + } + + typename boost::detail::operator_arrow_result< + value_type + , reference + , pointer + >::type + operator->() const + { + return boost::detail::operator_arrow_result< + value_type + , reference + , pointer + >::make(*this->derived()); + } + + typename boost::detail::operator_brackets_result::type + operator[](difference_type n) const + { + typedef boost::detail::use_operator_brackets_proxy use_proxy; + + return boost::detail::make_operator_brackets_result( + this->derived() + n + , use_proxy() + ); + } + + Derived& operator++() + { + iterator_core_access::increment(this->derived()); + return this->derived(); + } + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + typename boost::detail::postfix_increment_result::type + operator++(int) + { + typename boost::detail::postfix_increment_result::type + tmp(this->derived()); + ++*this; + return tmp; + } +# endif + + Derived& operator--() + { + iterator_core_access::decrement(this->derived()); + return this->derived(); + } + + Derived operator--(int) + { + Derived tmp(this->derived()); + --*this; + return tmp; + } + + Derived& operator+=(difference_type n) + { + iterator_core_access::advance(this->derived(), n); + return this->derived(); + } + + Derived& operator-=(difference_type n) + { + iterator_core_access::advance(this->derived(), -n); + return this->derived(); + } + + Derived operator-(difference_type x) const + { + Derived result(this->derived()); + return result -= x; + } + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // There appears to be a bug which trashes the data of classes + // derived from iterator_facade when they are assigned unless we + // define this assignment operator. This bug is only revealed + // (so far) in STLPort debug mode, but it's clearly a codegen + // problem so we apply the workaround for all MSVC6. + iterator_facade& operator=(iterator_facade const&) + { + return *this; + } +# endif + }; + +# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + inline typename boost::detail::postfix_increment_result::type + operator++( + iterator_facade& i + , int + ) + { + typename boost::detail::postfix_increment_result::type + tmp(*static_cast(&i)); + + ++i; + + return tmp; + } +# endif + + + // + // Comparison operator implementation. The library supplied operators + // enables the user to provide fully interoperable constant/mutable + // iterator types. I.e. the library provides all operators + // for all mutable/constant iterator combinations. + // + // Note though that this kind of interoperability for constant/mutable + // iterators is not required by the standard for container iterators. + // All the standard asks for is a conversion mutable -> constant. + // Most standard library implementations nowadays provide fully interoperable + // iterator implementations, but there are still heavily used implementations + // that do not provide them. (Actually it's even worse, they do not provide + // them for only a few iterators.) + // + // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should + // enable the user to turn off mixed type operators + // + // The library takes care to provide only the right operator overloads. + // I.e. + // + // bool operator==(Iterator, Iterator); + // bool operator==(ConstIterator, Iterator); + // bool operator==(Iterator, ConstIterator); + // bool operator==(ConstIterator, ConstIterator); + // + // ... + // + // In order to do so it uses c++ idioms that are not yet widely supported + // by current compiler releases. The library is designed to degrade gracefully + // in the face of compiler deficiencies. In general compiler + // deficiencies result in less strict error checking and more obscure + // error messages, functionality is not affected. + // + // For full operation compiler support for "Substitution Failure Is Not An Error" + // (aka. enable_if) and boost::is_convertible is required. + // + // The following problems occur if support is lacking. + // + // Pseudo code + // + // --------------- + // AdaptorA a1; + // AdaptorA a2; + // + // // This will result in a no such overload error in full operation + // // If enable_if or is_convertible is not supported + // // The instantiation will fail with an error hopefully indicating that + // // there is no operator== for Iterator1, Iterator2 + // // The same will happen if no enable_if is used to remove + // // false overloads from the templated conversion constructor + // // of AdaptorA. + // + // a1 == a2; + // ---------------- + // + // AdaptorA a; + // AdaptorB b; + // + // // This will result in a no such overload error in full operation + // // If enable_if is not supported the static assert used + // // in the operator implementation will fail. + // // This will accidently work if is_convertible is not supported. + // + // a == b; + // ---------------- + // + +# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP +# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_() +# else +# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible() +# endif + +# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \ + BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \ + { \ + /* For those compilers that do not support enable_if */ \ + BOOST_STATIC_ASSERT(( \ + is_interoperable< Derived1, Derived2 >::value \ + )); \ + return_prefix iterator_core_access::base_op( \ + *static_cast(&lhs) \ + , *static_cast(&rhs) \ + , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \ + ); \ + } + +# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \ + BOOST_ITERATOR_FACADE_INTEROP( \ + op \ + , boost::detail::always_bool2 \ + , return_prefix \ + , base_op \ + ) + + BOOST_ITERATOR_FACADE_RELATION(==, return, equal) + BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal) + + BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from) + BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from) + BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from) + BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from) +# undef BOOST_ITERATOR_FACADE_RELATION + + // operator- requires an additional part in the static assertion + BOOST_ITERATOR_FACADE_INTEROP( + - + , boost::detail::choose_difference_type + , return + , distance_from + ) +# undef BOOST_ITERATOR_FACADE_INTEROP +# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD + +# define BOOST_ITERATOR_FACADE_PLUS(args) \ + BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \ + { \ + Derived tmp(static_cast(i)); \ + return tmp += n; \ + } + +BOOST_ITERATOR_FACADE_PLUS(( + iterator_facade const& i + , typename Derived::difference_type n +)) + +BOOST_ITERATOR_FACADE_PLUS(( + typename Derived::difference_type n + , iterator_facade const& i +)) +# undef BOOST_ITERATOR_FACADE_PLUS +# undef BOOST_ITERATOR_FACADE_PLUS_HEAD + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP diff --git a/thirdparty/boost/iterator/iterator_traits.hpp b/thirdparty/boost/iterator/iterator_traits.hpp new file mode 100644 index 0000000..986b08f --- /dev/null +++ b/thirdparty/boost/iterator/iterator_traits.hpp @@ -0,0 +1,92 @@ +// Copyright David Abrahams 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) +#ifndef ITERATOR_TRAITS_DWA200347_HPP +# define ITERATOR_TRAITS_DWA200347_HPP + +# include +# include + +namespace boost { + +// Unfortunately, g++ 2.95.x chokes when we define a class template +// iterator_category which has the same name as its +// std::iterator_category() function, probably due in part to the +// "std:: is visible globally" hack it uses. Use +// BOOST_ITERATOR_CATEGORY to write code that's portable to older +// GCCs. + +# if BOOST_WORKAROUND(__GNUC__, <= 2) +# define BOOST_ITERATOR_CATEGORY iterator_category_ +# else +# define BOOST_ITERATOR_CATEGORY iterator_category +# endif + + +template +struct iterator_value +{ + typedef typename boost::detail::iterator_traits::value_type type; +}; + +template +struct iterator_reference +{ + typedef typename boost::detail::iterator_traits::reference type; +}; + + +template +struct iterator_pointer +{ + typedef typename boost::detail::iterator_traits::pointer type; +}; + +template +struct iterator_difference +{ + typedef typename boost::detail::iterator_traits::difference_type type; +}; + +template +struct BOOST_ITERATOR_CATEGORY +{ + typedef typename boost::detail::iterator_traits::iterator_category type; +}; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +template <> +struct iterator_value +{ + typedef void type; +}; + +template <> +struct iterator_reference +{ + typedef void type; +}; + +template <> +struct iterator_pointer +{ + typedef void type; +}; + +template <> +struct iterator_difference +{ + typedef void type; +}; + +template <> +struct BOOST_ITERATOR_CATEGORY +{ + typedef void type; +}; +# endif + +} // namespace boost::iterator + +#endif // ITERATOR_TRAITS_DWA200347_HPP diff --git a/thirdparty/boost/iterator/new_iterator_tests.hpp b/thirdparty/boost/iterator/new_iterator_tests.hpp new file mode 100644 index 0000000..a6a95eb --- /dev/null +++ b/thirdparty/boost/iterator/new_iterator_tests.hpp @@ -0,0 +1,264 @@ +#ifndef BOOST_NEW_ITERATOR_TESTS_HPP +# define BOOST_NEW_ITERATOR_TESTS_HPP + +// +// Copyright (c) David Abrahams 2001. +// Copyright (c) Jeremy Siek 2001-2003. +// Copyright (c) Thomas Witt 2002. +// +// Use, modification and distribution is subject to the +// Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// This is meant to be the beginnings of a comprehensive, generic +// test suite for STL concepts such as iterators and containers. +// +// Revision History: +// 28 Oct 2002 Started update for new iterator categories +// (Jeremy Siek) +// 28 Apr 2002 Fixed input iterator requirements. +// For a == b a++ == b++ is no longer required. +// See 24.1.1/3 for details. +// (Thomas Witt) +// 08 Feb 2001 Fixed bidirectional iterator test so that +// --i is no longer a precondition. +// (Jeremy Siek) +// 04 Feb 2001 Added lvalue test, corrected preconditions +// (David Abrahams) + +# include +# include +# include +# include // for detail::dummy_constructor +# include +# include +# include +# include + +# include +# include +# include + +namespace boost { + + +// Do separate tests for *i++ so we can treat, e.g., smart pointers, +// as readable and/or writable iterators. +template +void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_) +{ + T v2(*i1++); + BOOST_TEST(v == v2); +} + +template +void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) +{} + +template +void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_) +{ + ++i1; // we just wrote into that position + *i1++ = v; + Iterator x(i1++); + (void)x; +} + +template +void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_) +{} + + +// Preconditions: *i == v +template +void readable_iterator_test(const Iterator i1, T v) +{ + Iterator i2(i1); // Copy Constructible + typedef typename detail::iterator_traits::reference ref_t; + ref_t r1 = *i1; + ref_t r2 = *i2; + T v1 = r1; + T v2 = r2; + BOOST_TEST(v1 == v); + BOOST_TEST(v2 == v); + +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable()); + + // I think we don't really need this as it checks the same things as + // the above code. + BOOST_STATIC_ASSERT(is_readable_iterator::value); +# endif +} + +template +void writable_iterator_test(Iterator i, T v, T v2) +{ + Iterator i2(i); // Copy Constructible + *i2 = v; + +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + writable_iterator_traversal_test( + i, v2, mpl::and_< + detail::is_incrementable + , detail::is_postfix_incrementable + >()); +# endif +} + +template +void swappable_iterator_test(Iterator i, Iterator j) +{ + Iterator i2(i), j2(j); + typename detail::iterator_traits::value_type bi = *i, bj = *j; + iter_swap(i2, j2); + typename detail::iterator_traits::value_type ai = *i, aj = *j; + BOOST_TEST(bi == aj && bj == ai); +} + +template +void constant_lvalue_iterator_test(Iterator i, T v1) +{ + Iterator i2(i); + typedef typename detail::iterator_traits::value_type value_type; + typedef typename detail::iterator_traits::reference reference; + BOOST_STATIC_ASSERT((is_same::value)); + const T& v2 = *i2; + BOOST_TEST(v1 == v2); +# ifndef BOOST_NO_LVALUE_RETURN_DETECTION + BOOST_STATIC_ASSERT(is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator::value); +# endif +} + +template +void non_const_lvalue_iterator_test(Iterator i, T v1, T v2) +{ + Iterator i2(i); + typedef typename detail::iterator_traits::value_type value_type; + typedef typename detail::iterator_traits::reference reference; + BOOST_STATIC_ASSERT((is_same::value)); + T& v3 = *i2; + BOOST_TEST(v1 == v3); + + // A non-const lvalue iterator is not neccessarily writable, but we + // are assuming the value_type is assignable here + *i = v2; + + T& v4 = *i2; + BOOST_TEST(v2 == v4); +# ifndef BOOST_NO_LVALUE_RETURN_DETECTION + BOOST_STATIC_ASSERT(is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator::value); +# endif +} + +template +void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2) +{ + Iterator i2; + Iterator i3(i); + i2 = i; + BOOST_TEST(i2 == i3); + BOOST_TEST(i != j); + BOOST_TEST(i2 != j); + readable_iterator_test(i, val1); + readable_iterator_test(i2, val1); + readable_iterator_test(i3, val1); + + BOOST_TEST(i == i2++); + BOOST_TEST(i != ++i3); + + readable_iterator_test(i2, val2); + readable_iterator_test(i3, val2); + + readable_iterator_test(i, val1); +} + +template +void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2) +{ + forward_readable_iterator_test(i, j, val1, val2); + Iterator i2 = i; + ++i2; + swappable_iterator_test(i, i2); +} + +// bidirectional +// Preconditions: *i == v1, *++i == v2 +template +void bidirectional_readable_iterator_test(Iterator i, T v1, T v2) +{ + Iterator j(i); + ++j; + forward_readable_iterator_test(i, j, v1, v2); + ++i; + + Iterator i1 = i, i2 = i; + + BOOST_TEST(i == i1--); + BOOST_TEST(i != --i2); + + readable_iterator_test(i, v2); + readable_iterator_test(i1, v1); + readable_iterator_test(i2, v1); + + --i; + BOOST_TEST(i == i1); + BOOST_TEST(i == i2); + ++i1; + ++i2; + + readable_iterator_test(i, v1); + readable_iterator_test(i1, v2); + readable_iterator_test(i2, v2); +} + +// random access +// Preconditions: [i,i+N) is a valid range +template +void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals) +{ + bidirectional_readable_iterator_test(i, vals[0], vals[1]); + const Iterator j = i; + int c; + + for (c = 0; c < N-1; ++c) + { + BOOST_TEST(i == j + c); + BOOST_TEST(*i == vals[c]); + typename detail::iterator_traits::value_type x = j[c]; + BOOST_TEST(*i == x); + BOOST_TEST(*i == *(j + c)); + BOOST_TEST(*i == *(c + j)); + ++i; + BOOST_TEST(i > j); + BOOST_TEST(i >= j); + BOOST_TEST(j <= i); + BOOST_TEST(j < i); + } + + Iterator k = j + N - 1; + for (c = 0; c < N-1; ++c) + { + BOOST_TEST(i == k - c); + BOOST_TEST(*i == vals[N - 1 - c]); + typename detail::iterator_traits::value_type x = j[N - 1 - c]; + BOOST_TEST(*i == x); + Iterator q = k - c; + BOOST_TEST(*i == *q); + BOOST_TEST(i > j); + BOOST_TEST(i >= j); + BOOST_TEST(j <= i); + BOOST_TEST(j < i); + --i; + } +} + +} // namespace boost + +# include + +#endif // BOOST_NEW_ITERATOR_TESTS_HPP diff --git a/thirdparty/boost/iterator/permutation_iterator.hpp b/thirdparty/boost/iterator/permutation_iterator.hpp new file mode 100644 index 0000000..05c740d --- /dev/null +++ b/thirdparty/boost/iterator/permutation_iterator.hpp @@ -0,0 +1,72 @@ +// (C) Copyright Toon Knapen 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Roland Richter 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) + +#ifndef BOOST_PERMUTATION_ITERATOR_HPP +#define BOOST_PERMUTATION_ITERATOR_HPP + +#include + +#include + + +namespace boost +{ + +template< class ElementIterator + , class IndexIterator> +class permutation_iterator + : public iterator_adaptor< + permutation_iterator + , IndexIterator, typename detail::iterator_traits::value_type + , use_default, typename detail::iterator_traits::reference> +{ + typedef iterator_adaptor< + permutation_iterator + , IndexIterator, typename detail::iterator_traits::value_type + , use_default, typename detail::iterator_traits::reference> super_t; + + friend class iterator_core_access; + +public: + permutation_iterator() : m_elt_iter() {} + + explicit permutation_iterator(ElementIterator x, IndexIterator y) + : super_t(y), m_elt_iter(x) {} + + template + permutation_iterator( + permutation_iterator const& r + , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()), m_elt_iter(r.m_elt_iter) + {} + +private: + typename super_t::reference dereference() const + { return *(m_elt_iter + *this->base()); } + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + template friend class permutation_iterator; +#else + public: +#endif + ElementIterator m_elt_iter; +}; + + +template +permutation_iterator +make_permutation_iterator( ElementIterator e, IndexIterator i ) +{ + return permutation_iterator( e, i ); +} + + +} // namespace boost + +#endif diff --git a/thirdparty/boost/iterator/reverse_iterator.hpp b/thirdparty/boost/iterator/reverse_iterator.hpp new file mode 100644 index 0000000..59bbbc0 --- /dev/null +++ b/thirdparty/boost/iterator/reverse_iterator.hpp @@ -0,0 +1,69 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP +#define BOOST_REVERSE_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + + // + // + // + template + class reverse_iterator + : public iterator_adaptor< reverse_iterator, Iterator > + { + typedef iterator_adaptor< reverse_iterator, Iterator > super_t; + + friend class iterator_core_access; + + public: + reverse_iterator() {} + + explicit reverse_iterator(Iterator x) + : super_t(x) {} + + template + reverse_iterator( + reverse_iterator const& r + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()) + {} + + private: + typename super_t::reference dereference() const { return *boost::prior(this->base()); } + + void increment() { --this->base_reference(); } + void decrement() { ++this->base_reference(); } + + void advance(typename super_t::difference_type n) + { + this->base_reference() += -n; + } + + template + typename super_t::difference_type + distance_to(reverse_iterator const& y) const + { + return this->base_reference() - y.base(); + } + }; + + template + reverse_iterator make_reverse_iterator(BidirectionalIterator x) + { + return reverse_iterator(x); + } + +} // namespace boost + +#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP diff --git a/thirdparty/boost/iterator/transform_iterator.hpp b/thirdparty/boost/iterator/transform_iterator.hpp new file mode 100644 index 0000000..ce168cd --- /dev/null +++ b/thirdparty/boost/iterator/transform_iterator.hpp @@ -0,0 +1,188 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP +#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) +# include + +#endif +#include + + +namespace boost +{ + template + class transform_iterator; + + namespace detail + { + + template + struct function_object_result + { + typedef typename UnaryFunc::result_type type; + }; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct function_object_result + { + typedef Return type; + }; +#endif + + // Compute the iterator_adaptor instantiation to be used for transform_iterator + template + struct transform_iterator_base + { + private: + // By default, dereferencing the iterator yields the same as + // the function. Do we need to adjust the way + // function_object_result is computed for the standard + // proposal (e.g. using Doug's result_of)? + typedef typename ia_dflt_help< + Reference + , function_object_result + >::type reference; + + // To get the default for Value: remove any reference on the + // result type, but retain any constness to signal + // non-writability. Note that if we adopt Thomas' suggestion + // to key non-writability *only* on the Reference argument, + // we'd need to strip constness here as well. + typedef typename ia_dflt_help< + Value + , remove_reference + >::type cv_value_type; + + public: + typedef iterator_adaptor< + transform_iterator + , Iterator + , cv_value_type + , use_default // Leave the traversal category alone + , reference + > type; + }; + } + + template + class transform_iterator + : public boost::detail::transform_iterator_base::type + { + typedef typename + boost::detail::transform_iterator_base::type + super_t; + + friend class iterator_core_access; + + public: + transform_iterator() { } + + transform_iterator(Iterator const& x, UnaryFunc f) + : super_t(x), m_f(f) { } + + explicit transform_iterator(Iterator const& x) + : super_t(x) + { + // Pro8 is a little too aggressive about instantiating the + // body of this function. +#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + // don't provide this constructor if UnaryFunc is a + // function pointer type, since it will be 0. Too dangerous. + BOOST_STATIC_ASSERT(is_class::value); +#endif + } + + template< + class OtherUnaryFunction + , class OtherIterator + , class OtherReference + , class OtherValue> + transform_iterator( + transform_iterator const& t + , typename enable_if_convertible::type* = 0 +#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) + , typename enable_if_convertible::type* = 0 +#endif + ) + : super_t(t.base()), m_f(t.functor()) + {} + + UnaryFunc functor() const + { return m_f; } + + private: + typename super_t::reference dereference() const + { return m_f(*this->base()); } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + UnaryFunc m_f; + }; + + template + transform_iterator + make_transform_iterator(Iterator it, UnaryFunc fun) + { + return transform_iterator(it, fun); + } + + // Version which allows explicit specification of the UnaryFunc + // type. + // + // This generator is not provided if UnaryFunc is a function + // pointer type, because it's too dangerous: the default-constructed + // function pointer in the iterator be 0, leading to a runtime + // crash. + template +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typename mpl::if_< +#else + typename iterators::enable_if< +#endif + is_class // We should probably find a cheaper test than is_class<> + , transform_iterator +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + , int[3] +#endif + >::type + make_transform_iterator(Iterator it) + { + return transform_iterator(it, UnaryFunc()); + } + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + transform_iterator< Return (*)(Argument), Iterator, Return> + make_transform_iterator(Iterator it, Return (*fun)(Argument)) + { + return transform_iterator(it, fun); + } +#endif + +} // namespace boost + +#include + +#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP diff --git a/thirdparty/boost/iterator/zip_iterator.hpp b/thirdparty/boost/iterator/zip_iterator.hpp new file mode 100644 index 0000000..edc7e09 --- /dev/null +++ b/thirdparty/boost/iterator/zip_iterator.hpp @@ -0,0 +1,585 @@ +// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed +// under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ +# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ + +#include +#include +#include +#include +#include // for enable_if_convertible +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + + // Zip iterator forward declaration for zip_iterator_base + template + class zip_iterator; + + // One important design goal of the zip_iterator is to isolate all + // functionality whose implementation relies on the current tuple + // implementation. This goal has been achieved as follows: Inside + // the namespace detail there is a namespace tuple_impl_specific. + // This namespace encapsulates all functionality that is specific + // to the current Boost tuple implementation. More precisely, the + // namespace tuple_impl_specific provides the following tuple + // algorithms and meta-algorithms for the current Boost tuple + // implementation: + // + // tuple_meta_transform + // tuple_meta_accumulate + // tuple_transform + // tuple_for_each + // + // If the tuple implementation changes, all that needs to be + // replaced is the implementation of these four (meta-)algorithms. + + namespace detail + { + + // Functors to be used with tuple algorithms + // + template + class advance_iterator + { + public: + advance_iterator(DiffType step) : m_step(step) {} + + template + void operator()(Iterator& it) const + { it += m_step; } + + private: + DiffType m_step; + }; + // + struct increment_iterator + { + template + void operator()(Iterator& it) + { ++it; } + }; + // + struct decrement_iterator + { + template + void operator()(Iterator& it) + { --it; } + }; + // + struct dereference_iterator + { + template + struct apply + { + typedef typename + iterator_traits::reference + type; + }; + + template + typename apply::type operator()(Iterator const& it) + { return *it; } + }; + + + // The namespace tuple_impl_specific provides two meta- + // algorithms and two algorithms for tuples. + // + namespace tuple_impl_specific + { + // Meta-transform algorithm for tuples + // + template + struct tuple_meta_transform; + + template + struct tuple_meta_transform_impl + { + typedef tuples::cons< + typename mpl::apply1< + typename mpl::lambda::type + , typename Tuple::head_type + >::type + , typename tuple_meta_transform< + typename Tuple::tail_type + , UnaryMetaFun + >::type + > type; + }; + + template + struct tuple_meta_transform + : mpl::eval_if< + boost::is_same + , mpl::identity + , tuple_meta_transform_impl + > + { + }; + + // Meta-accumulate algorithm for tuples. Note: The template + // parameter StartType corresponds to the initial value in + // ordinary accumulation. + // + template + struct tuple_meta_accumulate; + + template< + typename Tuple + , class BinaryMetaFun + , typename StartType + > + struct tuple_meta_accumulate_impl + { + typedef typename mpl::apply2< + typename mpl::lambda::type + , typename Tuple::head_type + , typename tuple_meta_accumulate< + typename Tuple::tail_type + , BinaryMetaFun + , StartType + >::type + >::type type; + }; + + template< + typename Tuple + , class BinaryMetaFun + , typename StartType + > + struct tuple_meta_accumulate + : mpl::eval_if< +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + mpl::or_< +#endif + boost::is_same +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + , boost::is_same + > +#endif + , mpl::identity + , tuple_meta_accumulate_impl< + Tuple + , BinaryMetaFun + , StartType + > + > + { + }; + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + || ( \ + BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER) \ + ) +// Not sure why intel's partial ordering fails in this case, but I'm +// assuming int's an MSVC bug-compatibility feature. + +# define BOOST_TUPLE_ALGO_DISPATCH +# define BOOST_TUPLE_ALGO(algo) algo##_impl +# define BOOST_TUPLE_ALGO_TERMINATOR , int +# define BOOST_TUPLE_ALGO_RECURSE , ... +#else +# define BOOST_TUPLE_ALGO(algo) algo +# define BOOST_TUPLE_ALGO_TERMINATOR +# define BOOST_TUPLE_ALGO_RECURSE +#endif + + // transform algorithm for tuples. The template parameter Fun + // must be a unary functor which is also a unary metafunction + // class that computes its return type based on its argument + // type. For example: + // + // struct to_ptr + // { + // template + // struct apply + // { + // typedef Arg* type; + // } + // + // template + // Arg* operator()(Arg x); + // }; + template + tuples::null_type BOOST_TUPLE_ALGO(tuple_transform) + (tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR) + { return tuples::null_type(); } + + template + typename tuple_meta_transform< + Tuple + , Fun + >::type + + BOOST_TUPLE_ALGO(tuple_transform)( + const Tuple& t, + Fun f + BOOST_TUPLE_ALGO_RECURSE + ) + { + typedef typename tuple_meta_transform< + BOOST_DEDUCED_TYPENAME Tuple::tail_type + , Fun + >::type transformed_tail_type; + + return tuples::cons< + BOOST_DEDUCED_TYPENAME mpl::apply1< + Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type + >::type + , transformed_tail_type + >( + f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f) + ); + } + +#ifdef BOOST_TUPLE_ALGO_DISPATCH + template + typename tuple_meta_transform< + Tuple + , Fun + >::type + + tuple_transform( + const Tuple& t, + Fun f + ) + { + return tuple_transform_impl(t, f, 1); + } +#endif + + // for_each algorithm for tuples. + // + template + Fun BOOST_TUPLE_ALGO(tuple_for_each)( + tuples::null_type + , Fun f BOOST_TUPLE_ALGO_TERMINATOR + ) + { return f; } + + + template + Fun BOOST_TUPLE_ALGO(tuple_for_each)( + Tuple& t + , Fun f BOOST_TUPLE_ALGO_RECURSE) + { + f( t.get_head() ); + return tuple_for_each(t.get_tail(), f); + } + +#ifdef BOOST_TUPLE_ALGO_DISPATCH + template + Fun + tuple_for_each( + Tuple& t, + Fun f + ) + { + return tuple_for_each_impl(t, f, 1); + } +#endif + + // Equality of tuples. NOTE: "==" for tuples currently (7/2003) + // has problems under some compilers, so I just do my own. + // No point in bringing in a bunch of #ifdefs here. This is + // going to go away with the next tuple implementation anyway. + // + inline bool tuple_equal(tuples::null_type, tuples::null_type) + { return true; } + + template + bool tuple_equal( + Tuple1 const& t1, + Tuple2 const& t2 + ) + { + return t1.get_head() == t2.get_head() && + tuple_equal(t1.get_tail(), t2.get_tail()); + } + } + // + // end namespace tuple_impl_specific + + template + struct iterator_reference + { + typedef typename iterator_traits::reference type; + }; + +#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT + // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work + // out well. Instantiating the nested apply template also + // requires instantiating iterator_traits on the + // placeholder. Instead we just specialize it as a metafunction + // class. + template<> + struct iterator_reference + { + template + struct apply : iterator_reference {}; + }; +#endif + + // Metafunction to obtain the type of the tuple whose element types + // are the reference types of an iterator tuple. + // + template + struct tuple_of_references + : tuple_impl_specific::tuple_meta_transform< + IteratorTuple, + iterator_reference + > + { + }; + + // Metafunction to obtain the minimal traversal tag in a tuple + // of iterators. + // + template + struct minimum_traversal_category_in_iterator_tuple + { + typedef typename tuple_impl_specific::tuple_meta_transform< + IteratorTuple + , iterator_traversal<> + >::type tuple_of_traversal_tags; + + typedef typename tuple_impl_specific::tuple_meta_accumulate< + tuple_of_traversal_tags + , minimum_category<> + , random_access_traversal_tag + >::type type; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + template <> + struct minimum_traversal_category_in_iterator_tuple + { + typedef int type; + }; +#endif + + // We need to call tuple_meta_accumulate with mpl::and_ as the + // accumulating functor. To this end, we need to wrap it into + // a struct that has exactly two arguments (that is, template + // parameters) and not five, like mpl::and_ does. + // + template + struct and_with_two_args + : mpl::and_ + { + }; + +# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT + // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work + // out well. In this case I think it's an MPL bug + template<> + struct and_with_two_args + { + template + struct apply : mpl::and_ + {}; + }; +# endif + + /////////////////////////////////////////////////////////////////// + // + // Class zip_iterator_base + // + // Builds and exposes the iterator facade type from which the zip + // iterator will be derived. + // + template + struct zip_iterator_base + { + private: + // Reference type is the type of the tuple obtained from the + // iterators' reference types. + typedef typename + detail::tuple_of_references::type reference; + + // Value type is the same as reference type. + typedef reference value_type; + + // Difference type is the first iterator's difference type + typedef typename iterator_traits< + typename tuples::element<0, IteratorTuple>::type + >::difference_type difference_type; + + // Traversal catetgory is the minimum traversal category in the + // iterator tuple. + typedef typename + detail::minimum_traversal_category_in_iterator_tuple< + IteratorTuple + >::type traversal_category; + public: + + // The iterator facade type from which the zip iterator will + // be derived. + typedef iterator_facade< + zip_iterator, + value_type, + traversal_category, + reference, + difference_type + > type; + }; + + template <> + struct zip_iterator_base + { + typedef int type; + }; + } + + ///////////////////////////////////////////////////////////////////// + // + // zip_iterator class definition + // + template + class zip_iterator : + public detail::zip_iterator_base::type + { + + // Typedef super_t as our base class. + typedef typename + detail::zip_iterator_base::type super_t; + + // iterator_core_access is the iterator's best friend. + friend class iterator_core_access; + + public: + + // Construction + // ============ + + // Default constructor + zip_iterator() { } + + // Constructor from iterator tuple + zip_iterator(IteratorTuple iterator_tuple) + : m_iterator_tuple(iterator_tuple) + { } + + // Copy constructor + template + zip_iterator( + const zip_iterator& other, + typename enable_if_convertible< + OtherIteratorTuple, + IteratorTuple + >::type* = 0 + ) : m_iterator_tuple(other.get_iterator_tuple()) + {} + + // Get method for the iterator tuple. + const IteratorTuple& get_iterator_tuple() const + { return m_iterator_tuple; } + + private: + + // Implementation of Iterator Operations + // ===================================== + + // Dereferencing returns a tuple built from the dereferenced + // iterators in the iterator tuple. + typename super_t::reference dereference() const + { + return detail::tuple_impl_specific::tuple_transform( + get_iterator_tuple(), + detail::dereference_iterator() + ); + } + + // Two zip iterators are equal if all iterators in the iterator + // tuple are equal. NOTE: It should be possible to implement this + // as + // + // return get_iterator_tuple() == other.get_iterator_tuple(); + // + // but equality of tuples currently (7/2003) does not compile + // under several compilers. No point in bringing in a bunch + // of #ifdefs here. + // + template + bool equal(const zip_iterator& other) const + { + return detail::tuple_impl_specific::tuple_equal( + get_iterator_tuple(), + other.get_iterator_tuple() + ); + } + + // Advancing a zip iterator means to advance all iterators in the + // iterator tuple. + void advance(typename super_t::difference_type n) + { + detail::tuple_impl_specific::tuple_for_each( + m_iterator_tuple, + detail::advance_iterator(n) + ); + } + // Incrementing a zip iterator means to increment all iterators in + // the iterator tuple. + void increment() + { + detail::tuple_impl_specific::tuple_for_each( + m_iterator_tuple, + detail::increment_iterator() + ); + } + + // Decrementing a zip iterator means to decrement all iterators in + // the iterator tuple. + void decrement() + { + detail::tuple_impl_specific::tuple_for_each( + m_iterator_tuple, + detail::decrement_iterator() + ); + } + + // Distance is calculated using the first iterator in the tuple. + template + typename super_t::difference_type distance_to( + const zip_iterator& other + ) const + { + return boost::tuples::get<0>(other.get_iterator_tuple()) - + boost::tuples::get<0>(this->get_iterator_tuple()); + } + + // Data Members + // ============ + + // The iterator tuple. + IteratorTuple m_iterator_tuple; + + }; + + // Make function for zip iterator + // + template + zip_iterator + make_zip_iterator(IteratorTuple t) + { return zip_iterator(t); } + +} + +#endif diff --git a/thirdparty/boost/iterator_adaptors.hpp b/thirdparty/boost/iterator_adaptors.hpp new file mode 100644 index 0000000..51b0fe2 --- /dev/null +++ b/thirdparty/boost/iterator_adaptors.hpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 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 www.boost.org/libs/iterator for documentation. + +#ifndef ITERATOR_ADAPTORS_DWA2004725_HPP +# define ITERATOR_ADAPTORS_DWA2004725_HPP + +#define BOOST_ITERATOR_ADAPTORS_VERSION 0x0200 +#include + +#endif // ITERATOR_ADAPTORS_DWA2004725_HPP diff --git a/thirdparty/boost/lambda/algorithm.hpp b/thirdparty/boost/lambda/algorithm.hpp new file mode 100644 index 0000000..850fc9b --- /dev/null +++ b/thirdparty/boost/lambda/algorithm.hpp @@ -0,0 +1,1377 @@ +// -- algorithm.hpp -- Boost Lambda Library ----------------------------------- +// Copyright (C) 2002 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 2002 Gary Powell (gwpowell@hotmail.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) +// +// For more information, see http://www.boost.org + +#ifndef BOOST_LAMBDA_ALGORITHM_HPP +#define BOOST_LAMBDA_ALGORITHM_HPP + +#include "boost/lambda/core.hpp" + +#include +#include // for iterator_traits +#include // for std::pair + +namespace boost { + namespace lambda { + +namespace ll { + +// for_each --------------------------------- + +struct for_each { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::for_each(a, b, c); } +}; + +// find --------------------------------- + +struct find { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, const C& c) const + { return ::std::find(a, b, c); } +}; + + +// find_if --------------------------------- + +struct find_if { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c) const + { return ::std::find_if(a, b, c); } +}; + +// find_end --------------------------------- + +struct find_end { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c, C d) const + { return ::std::find_end(a, b, c, d); } + + template + A + operator()(A a, A b, C c, C d, E e) const + { return ::std::find_end(a, b, c, d, e); } + +}; + +// find_first_of --------------------------------- + +struct find_first_of { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c, C d) const + { return ::std::find_first_of(a, b, c, d); } + + template + A + operator()(A a, A b, C c, C d, E e) const + { return ::std::find_first_of(a, b, c, d, e); } + +}; + +// adjacent_find --------------------------------- + +struct adjacent_find { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b) const + { return ::std::adjacent_find(a, b); } + + template + A + operator()(A a, A b, C c) const + { return ::std::adjacent_find(a, b, c); } + +}; + +// count --------------------------------- + +struct count { + + template + struct sig { + typedef typename ::std::iterator_traits< + typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type + >::difference_type type; + }; + + template + typename ::std::iterator_traits::difference_type + operator()(A a, A b, const C& c) const + { return ::std::count(a, b, c); } +}; + +// count_if --------------------------------- + +struct count_if { + + template + struct sig { + typedef typename ::std::iterator_traits< + typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type + >::difference_type type; + }; + + template + typename ::std::iterator_traits::difference_type + operator()(A a, A b, C c) const + { return ::std::count_if(a, b, c); } +}; + + +// mismatch --------------------------------- + +struct mismatch { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type element1_type; + + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type element2_type; + + typedef ::std::pair< element1_type, element2_type > type; + }; + + template + ::std::pair + operator()(A a, A b, C c) const + { return ::std::mismatch(a, b, c); } + + template + ::std::pair + operator()(A a, A b, C c, D d) const + { return ::std::mismatch(a, b, c, d); } + +}; + +// equal --------------------------------- + +struct equal { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b, C c) const + { return ::std::equal(a, b, c); } + + template + bool + operator()(A a, A b, C c, D d) const + { return ::std::equal(a, b, c, d); } + +}; + +// search -------------------------------- + +struct search { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c, C d) const + { return std::search(a, b, c, d);} + + template + A + operator()(A a, A b, C c, C d, E e) const + { return std::search(a, b, c, d, e);} + +}; + +// copy --------------------------------- + +struct copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::copy(a, b, c); } + +}; + +// copy_backward --------------------------------- + +struct copy_backward { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::copy_backward(a, b, c); } + +}; + +// swap --------------------------------- + +struct swap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::swap(a, b); } + +}; + +// swap_ranges --------------------------------- + +struct swap_ranges { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::swap_ranges(a, b, c); } + +}; + +// iter_swap --------------------------------- + +struct iter_swap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::iter_swap(a, b); } + +}; + + +// transform -------------------------------- + +struct transform { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element< + boost::tuples::length::value - 2, + Args + >::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, D d) const + { return std::transform(a, b, c, d);} + + template + D + operator()(A a, A b, C c, D d, E e) const + { return std::transform(a, b, c, d, e);} + +}; + +// replace --------------------------------- + +struct replace { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, const C& c, const C& d) const + { ::std::replace(a, b, c, d); } + +}; + +// replace_if --------------------------------- + +struct replace_if { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, C c, const D& d) const + { ::std::replace_if(a, b, c, d); } + +}; + +// replace_copy --------------------------------- + +struct replace_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, const D& d, const D& e) const + { return ::std::replace_copy(a, b, c, d, e); } + +}; + +// replace_copy_if --------------------------------- + +struct replace_copy_if { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, D d, const E& e) const + { return ::std::replace_copy_if(a, b, c, d, e); } + +}; + +// fill --------------------------------- + +struct fill { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, const C& c) const + { ::std::fill(a, b, c); } + +}; + +// fill_n --------------------------------- + +struct fill_n { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, B b, const C& c) const + { ::std::fill_n(a, b, c); } + +}; + +// generate --------------------------------- + +struct generate { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, C c) const + { ::std::generate(a, b, c); } + +}; + +// generate_n --------------------------------- + +struct generate_n { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, B b, C c) const + { ::std::generate_n(a, b, c); } + +}; + +// remove --------------------------------- + +struct remove { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, const C& c) const + { return ::std::remove(a, b, c); } +}; + +// remove_if --------------------------------- + +struct remove_if { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c) const + { return ::std::remove_if(a, b, c); } +}; + +// remove_copy --------------------------------- + +struct remove_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, const D& d) const + { return ::std::remove_copy(a, b, c, d); } +}; + +// remove_copy_if --------------------------------- + +struct remove_copy_if { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, D d) const + { return ::std::remove_copy_if(a, b, c, d); } +}; + +// unique --------------------------------- + +struct unique { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b) const + { return ::std::unique(a, b); } + + template + A + operator()(A a, A b, C c) const + { return ::std::unique(a, b, c); } + +}; + +// unique_copy --------------------------------- + +struct unique_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::unique_copy(a, b, c); } + + template + C + operator()(A a, A b, C c, D d) const + { return ::std::unique_copy(a, b, c, d); } + +}; + +// reverse --------------------------------- + +struct reverse { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::reverse(a, b); } + +}; + +// reverse_copy --------------------------------- + +struct reverse_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c) const + { return ::std::reverse_copy(a, b, c); } + +}; + +// rotate --------------------------------- + +struct rotate { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, A c) const + { ::std::rotate(a, b, c); } + +}; + +// rotate_copy --------------------------------- + +struct rotate_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + D + operator()(A a, A b, A c, D d) const + { return ::std::rotate_copy(a, b, c, d); } + +}; + +// random_shuffle --------------------------------- + +struct random_shuffle { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::random_shuffle(a, b); } + + template + void + operator()(A a, A b, const C& c) const + { ::std::random_shuffle(a, b, c); } + +}; + + +// partition --------------------------------- + +struct partition { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c) const + { return ::std::partition(a, b, c); } + +}; + +// stable_partition --------------------------------- + +struct stable_partition { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, C c) const + { return ::std::stable_partition(a, b, c); } + +}; + +// sort --------------------------------- + +struct sort { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::sort(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::sort(a, b, c); } + +}; + +// stable_sort --------------------------------- + +struct stable_sort { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::stable_sort(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::stable_sort(a, b, c); } + +}; + +// partial_sort --------------------------------- + +struct partial_sort { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, A c) const + { ::std::partial_sort(a, b, c); } + + template + void + operator()(A a, A b, A c, D d) const + { ::std::partial_sort(a, b, c, d); } + +}; + +// partial_sort_copy --------------------------------- + +struct partial_sort_copy { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<3, Args>::type + >::type type; + }; + + template + C + operator()(A a, A b, C c, C d) const + { return ::std::partial_sort_copy(a, b, c, d); } + + template + C + operator()(A a, A b, C c, C d, E e) const + { return ::std::partial_sort_copy(a, b, c, d, e); } +}; + +// nth_element --------------------------------- + +struct nth_element { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, A c) const + { ::std::nth_element(a, b, c); } + + template + void + operator()(A a, A b, A c, D d) const + { ::std::nth_element(a, b, c, d); } + +}; + +// lower_bound --------------------------------- + +struct lower_bound { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, const C& c) const + { return ::std::lower_bound(a, b, c); } + + template + A + operator()(A a, A b, const C& c, D d) const + { return ::std::lower_bound(a, b, c, d); } + +}; + +// upper_bound --------------------------------- + +struct upper_bound { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b, const C& c) const + { return ::std::upper_bound(a, b, c); } + + template + A + operator()(A a, A b, const C& c, D d) const + { return ::std::upper_bound(a, b, c, d); } + +}; + +// equal_range --------------------------------- + +struct equal_range { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type element_type; + + typedef ::std::pair< element_type, element_type > type; + }; + + template + ::std::pair + operator()(A a, A b, const C& c) const + { return ::std::equal_range(a, b, c); } + + template + ::std::pair + operator()(A a, A b, const C& c, D d) const + { return ::std::equal_range(a, b, c, d); } + +}; + +// binary_search --------------------------------- + +struct binary_search { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b, const C& c) const + { return ::std::binary_search(a, b, c); } + + template + bool + operator()(A a, A b, const C& c, D d) const + { return ::std::binary_search(a, b, c, d); } + +}; + +// merge -------------------------------- + +struct merge { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<5, Args>::type + >::type type; + }; + + template + E + operator()(A a, A b, C c, C d, E e) const + { return std::merge(a, b, c, d, e);} + + template + E + operator()(A a, A b, C c, C d, E e, F f) const + { return std::merge(a, b, c, d, e, f);} + +}; + +// inplace_merge --------------------------------- + +struct inplace_merge { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b, A c) const + { ::std::inplace_merge(a, b, c); } + + template + void + operator()(A a, A b, A c, D d) const + { ::std::inplace_merge(a, b, c, d); } + +}; + +// includes --------------------------------- + +struct includes { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b, C c, C d) const + { return ::std::includes(a, b, c, d); } + + template + bool + operator()(A a, A b, C c, C d, E e) const + { return ::std::includes(a, b, c, d, e); } + +}; + +// set_union -------------------------------- + +struct set_union { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<5, Args>::type + >::type type; + }; + + template + E + operator()(A a, A b, C c, C d, E e) const + { return std::set_union(a, b, c, d, e);} + + template + E + operator()(A a, A b, C c, C d, E e, F f) const + { return std::set_union(a, b, c, d, e, f);} + +}; + +// set_intersection -------------------------------- + +struct set_intersection { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<5, Args>::type + >::type type; + }; + + template + E + operator()(A a, A b, C c, C d, E e) const + { return std::set_intersection(a, b, c, d, e);} + + template + E + operator()(A a, A b, C c, C d, E e, F f) const + { return std::set_intersection(a, b, c, d, e, f);} + +}; + +// set_difference -------------------------------- + +struct set_difference { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<5, Args>::type + >::type type; + }; + + template + E + operator()(A a, A b, C c, C d, E e) const + { return std::set_difference(a, b, c, d, e);} + + template + E + operator()(A a, A b, C c, C d, E e, F f) const + { return std::set_difference(a, b, c, d, e, f);} + +}; + + +// set_symmetric_difference -------------------------------- + +struct set_symmetric_difference { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<5, Args>::type + >::type type; + }; + + template + E + operator()(A a, A b, C c, C d, E e) const + { return std::set_symmetric_difference(a, b, c, d, e);} + + template + E + operator()(A a, A b, C c, C d, E e, F f) const + { return std::set_symmetric_difference(a, b, c, d, e, f);} + +}; + +// push_heap --------------------------------- + +struct push_heap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::push_heap(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::push_heap(a, b, c); } + +}; + +// pop_heap --------------------------------- + +struct pop_heap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::pop_heap(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::pop_heap(a, b, c); } + +}; + + +// make_heap --------------------------------- + +struct make_heap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::make_heap(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::make_heap(a, b, c); } + +}; + +// sort_heap --------------------------------- + +struct sort_heap { + + template + struct sig { + typedef void type; + }; + + template + void + operator()(A a, A b) const + { ::std::sort_heap(a, b); } + + template + void + operator()(A a, A b, C c) const + { ::std::sort_heap(a, b, c); } + +}; + +// min --------------------------------- + +struct min { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(const A& a, const A& b) const + { return (::std::min)(a, b); } + + template + A + operator()(const A& a, const A& b, C c) const + { return (::std::min)(a, b, c); } + +}; + +// max --------------------------------- + +struct max { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(const A& a, const A& b) const + { return (::std::max)(a, b); } + + template + A + operator()(const A& a, const A& b, C c) const + { return (::std::max)(a, b, c); } + +}; + +struct min_element { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b) const + { return ::std::min_element(a, b); } + + template + A + operator()(A a, A b, C c) const + { return ::std::min_element(a, b, c); } + +}; + +// max_element --------------------------------- + +struct max_element { + + template + struct sig { + typedef typename boost::remove_const< + typename boost::tuples::element<1, Args>::type + >::type type; + }; + + template + A + operator()(A a, A b) const + { return ::std::max_element(a, b); } + + template + A + operator()(A a, A b, C c) const + { return ::std::max_element(a, b, c); } + +}; + + +// lexicographical_compare --------------------------------- + +struct lexicographical_compare { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b, C c, C d) const + { return ::std::lexicographical_compare(a, b, c, d); } + + template + bool + operator()(A a, A b, C c, C d, E e) const + { return ::std::lexicographical_compare(a, b, c, d, e); } + +}; + +// next_permutation --------------------------------- + +struct next_permutation { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b) const + { return ::std::next_permutation(a, b); } + + template + bool + operator()(A a, A b, C c) const + { return ::std::next_permutation(a, b, c); } + +}; + +// prev_permutation --------------------------------- + +struct prev_permutation { + + template + struct sig { + typedef bool type; + }; + + template + bool + operator()(A a, A b) const + { return ::std::prev_permutation(a, b); } + + template + bool + operator()(A a, A b, C c) const + { return ::std::prev_permutation(a, b, c); } + +}; + + + + + +} // end of ll namespace + +// There is no good way to call an overloaded member function in a +// lambda expression. +// The macro below defines a function object class for calling a +// const_iterator returning member function of a container. + +#define CALL_MEMBER(X) \ +struct call_##X { \ +template \ + struct sig { \ + typedef typename boost::remove_const< \ + typename boost::tuples::element<1, Args>::type \ + >::type::const_iterator type; \ + }; \ + \ + template \ + typename T::const_iterator \ + operator()(const T& t) const \ + { \ + return t.X(); \ + } \ +}; + +// create call_begin and call_end classes +CALL_MEMBER(begin) +CALL_MEMBER(end) + +#undef CALL_MEMBER + +} // end of lambda namespace +} // end of boost namespace + + + +#endif diff --git a/thirdparty/boost/lambda/bind.hpp b/thirdparty/boost/lambda/bind.hpp new file mode 100644 index 0000000..7b18b4d --- /dev/null +++ b/thirdparty/boost/lambda/bind.hpp @@ -0,0 +1,19 @@ +// -- bind.hpp -- Boost Lambda Library -------------------------------------- + +// Copyright (C) 1999-2001 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// Gary Powell (gwpowell@hotmail.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) +// +// For more information, see http://www.boost.org + +#ifndef BOOST_LAMBDA_BIND_HPP +#define BOOST_LAMBDA_BIND_HPP + +#include "boost/lambda/core.hpp" + +#include "boost/lambda/detail/bind_functions.hpp" + +#endif diff --git a/thirdparty/boost/lambda/casts.hpp b/thirdparty/boost/lambda/casts.hpp new file mode 100644 index 0000000..b970094 --- /dev/null +++ b/thirdparty/boost/lambda/casts.hpp @@ -0,0 +1,219 @@ +// - casts.hpp -- BLambda Library ------------- +// +// Copyright (C) 2000 Gary Powell (powellg@amazon.com) +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org + +// ----------------------------------------------- + +#if !defined(BOOST_LAMBDA_CASTS_HPP) +#define BOOST_LAMBDA_CASTS_HPP + +#include + +namespace boost { +namespace lambda { + +template class cast_action; + +template class static_cast_action; +template class dynamic_cast_action; +template class const_cast_action; +template class reinterpret_cast_action; + +class typeid_action; +class sizeof_action; + +// Cast actions + +template class cast_action > +{ +public: + template + static RET apply(Arg1 &a1) { + return static_cast(a1); + } +}; + +template class cast_action > { +public: + template + static RET apply(Arg1 &a1) { + return dynamic_cast(a1); + } +}; + +template class cast_action > { +public: + template + static RET apply(Arg1 &a1) { + return const_cast(a1); + } +}; + +template class cast_action > { +public: + template + static RET apply(Arg1 &a1) { + return reinterpret_cast(a1); + } +}; + + // typedid action +class typeid_action { +public: + template + static RET apply(Arg1 &a1) { + return typeid(a1); + } +}; + +// sizeof action +class sizeof_action +{ +public: + template + static RET apply(Arg1 &a1) { + return sizeof(a1); + } +}; + + +// return types of casting lambda_functors (all "T" type.) + +template